LoongArch: Fix linker generate PLT entry for data symbol
With old "medium" code model, we call a function with a pair of PCALAU12I and JIRL instructions. The assembler produces something like: 8: 1a00000c pcalau12i $t0, 0 8: R_LARCH_PCALA_HI20 g c: 4c000181 jirl $ra, $t0, 0 c: R_LARCH_PCALA_LO12 g The linker generates a "PLT entry" for data without any diagnostic. If "g" is a data symbol and ld with -shared option, it may load two instructions in the PLT. Without -shared option, loongarch_elf_adjust_dynamic_symbol can delete PLT entry. For R_LARCH_PCALA_HI20 relocation, linker only generate PLT entry for STT_FUNC and STT_GNU_IFUNC symbols.
This commit is contained in:
parent
b7a5722ebd
commit
e493ba6255
@ -891,8 +891,12 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
|
|||||||
h->non_got_ref = 1;
|
h->non_got_ref = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* For normal cmodel, pcalau12i + addi.d/w used to data.
|
||||||
|
For first version medium cmodel, pcalau12i + jirl are used to
|
||||||
|
function call, it need to creat PLT entry for STT_FUNC and
|
||||||
|
STT_GNU_IFUNC type symbol. */
|
||||||
case R_LARCH_PCALA_HI20:
|
case R_LARCH_PCALA_HI20:
|
||||||
if (h != NULL)
|
if (h != NULL && (STT_FUNC == h->type || STT_GNU_IFUNC == h->type))
|
||||||
{
|
{
|
||||||
/* For pcalau12i + jirl. */
|
/* For pcalau12i + jirl. */
|
||||||
h->needs_plt = 1;
|
h->needs_plt = 1;
|
||||||
|
20
ld/testsuite/ld-loongarch-elf/data-plt.s
Normal file
20
ld/testsuite/ld-loongarch-elf/data-plt.s
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# The first version medium codel model function call is: pcalau12i + jirl.
|
||||||
|
# R_LARCH_PCALA_HI20 only need to generate PLT entry for function symbols.
|
||||||
|
.text
|
||||||
|
.globl a
|
||||||
|
|
||||||
|
.data
|
||||||
|
.align 2
|
||||||
|
.type a, @object
|
||||||
|
.size a, 4
|
||||||
|
a:
|
||||||
|
.word 1
|
||||||
|
|
||||||
|
.text
|
||||||
|
.align 2
|
||||||
|
.globl test
|
||||||
|
.type test, @function
|
||||||
|
test:
|
||||||
|
pcalau12i $r12,%pc_hi20(a)
|
||||||
|
ld.w $r12,$r12,%pc_lo12(a)
|
||||||
|
.size test, .-test
|
@ -59,6 +59,30 @@ if [istarget "loongarch64-*-*"] {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# loongarch*-elf target do not support -shared option
|
||||||
|
if [check_shared_lib_support] {
|
||||||
|
run_ld_link_tests \
|
||||||
|
[list \
|
||||||
|
[list \
|
||||||
|
"data plt" \
|
||||||
|
"-shared" "" \
|
||||||
|
"" \
|
||||||
|
{data-plt.s} \
|
||||||
|
{} \
|
||||||
|
"data-plt.so" \
|
||||||
|
] \
|
||||||
|
]
|
||||||
|
|
||||||
|
if [file exist "tmpdir/data-plt.so"] {
|
||||||
|
set objdump_output [run_host_cmd "objdump" "-d tmpdir/data-plt.so"]
|
||||||
|
if { [ regexp "<a@plt>" $objdump_output] } {
|
||||||
|
fail "data plt"
|
||||||
|
} {
|
||||||
|
pass "data plt"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
run_ld_link_tests \
|
run_ld_link_tests \
|
||||||
[list \
|
[list \
|
||||||
[list \
|
[list \
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
|
.type func @function
|
||||||
pcalau12i $r12, %pc_hi20(func)
|
pcalau12i $r12, %pc_hi20(func)
|
||||||
jirl $r1,$r12, %pc_lo12(func)
|
jirl $r1,$r12, %pc_lo12(func)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user