aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authormengqinggang <mengqinggang@loongson.cn>2022-12-01 17:23:14 +0800
committerliuzhensong <liuzhensong@loongson.cn>2024-01-04 19:08:53 +0800
commite493ba6255aec08885affbb68ddc0a025583d528 (patch)
tree907c8311ad1cef9bf1233eb73685c9e10dfbb657 /bfd
parentb7a5722ebdd24a0d15d56e96d30a649ea1d7b0ee (diff)
downloadbinutils-e493ba6255aec08885affbb68ddc0a025583d528.zip
binutils-e493ba6255aec08885affbb68ddc0a025583d528.tar.gz
binutils-e493ba6255aec08885affbb68ddc0a025583d528.tar.bz2
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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/elfnn-loongarch.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index add916e..2a79e00 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -891,8 +891,12 @@ loongarch_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
h->non_got_ref = 1;
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:
- if (h != NULL)
+ if (h != NULL && (STT_FUNC == h->type || STT_GNU_IFUNC == h->type))
{
/* For pcalau12i + jirl. */
h->needs_plt = 1;