diff options
author | 2024-08-05 15:15:54 +0100 | |
---|---|---|
committer | 2024-08-06 21:59:24 +0200 | |
commit | 27c785dc7cff2f8ed87feeaf15a44da41ac7fb2b (patch) | |
tree | 6494cf618f261c89fc9fc0e445932108d7e5acef | |
parent | Apply a similar libiberty fix as in 7d53105d for libopcodes and libgprofng (diff) | |
download | binutils-gdb-27c785dc7cff2f8ed87feeaf15a44da41ac7fb2b.tar.gz binutils-gdb-27c785dc7cff2f8ed87feeaf15a44da41ac7fb2b.tar.bz2 binutils-gdb-27c785dc7cff2f8ed87feeaf15a44da41ac7fb2b.zip |
LoongArch: Fix DT_RELR and relaxation interaction
(cherry picked from commit 7999dae69612295e1bbffe64aff87044372a0059)
-rw-r--r-- | bfd/elfnn-loongarch.c | 17 | ||||
-rw-r--r-- | ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 1 | ||||
-rw-r--r-- | ld/testsuite/ld-loongarch-elf/relr-got-start.d | 7 | ||||
-rw-r--r-- | ld/testsuite/ld-loongarch-elf/relr-got-start.s | 5 |
4 files changed, 29 insertions, 1 deletions
diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c index db6d419a052..731af6a79a6 100644 --- a/bfd/elfnn-loongarch.c +++ b/bfd/elfnn-loongarch.c @@ -121,6 +121,12 @@ struct loongarch_elf_link_hash_table /* Layout recomputation count. */ bfd_size_type relr_layout_iter; + + /* In BFD DT_RELR is implemented as a "relaxation." If in a relax trip + size_relative_relocs is updating the layout, relax_section may see + a partially updated state (some sections have vma updated but the + others do not), and it's unsafe to do the normal relaxation. */ + bool layout_mutating_for_relr; }; struct loongarch_elf_section_data @@ -2212,6 +2218,8 @@ loongarch_elf_size_relative_relocs (struct bfd_link_info *info, *need_layout = false; } } + + htab->layout_mutating_for_relr = *need_layout; return true; } @@ -4133,7 +4141,8 @@ loongarch_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info, bfd_link_pic (info), h) && bfd_link_pic (info) - && LARCH_REF_LOCAL (info, h)) + && LARCH_REF_LOCAL (info, h) + && !info->enable_dt_relr) { Elf_Internal_Rela rela; rela.r_offset = sec_addr (got) + got_off; @@ -5259,6 +5268,12 @@ loongarch_elf_relax_section (bfd *abfd, asection *sec, *again = false; bfd_vma max_alignment = 0; + /* It may happen that some sections have updated vma but the others do + not. Go to the next relax trip (size_relative_relocs should have + been demending another relax trip anyway). */ + if (htab->layout_mutating_for_relr) + return true; + if (bfd_link_relocatable (info) || sec->sec_flg0 || (sec->flags & SEC_RELOC) == 0 diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp index fb34eeb80cb..09c4c9fd5b2 100644 --- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp +++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp @@ -149,6 +149,7 @@ if [istarget "loongarch64-*-*"] { run_dump_test "relr-data-pie" run_dump_test "relr-discard-pie" run_dump_test "relr-got-pie" + run_dump_test "relr-got-start" run_dump_test "relr-text-pie" run_dump_test "abssym_pie" } diff --git a/ld/testsuite/ld-loongarch-elf/relr-got-start.d b/ld/testsuite/ld-loongarch-elf/relr-got-start.d new file mode 100644 index 00000000000..0b1a5b9810d --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-got-start.d @@ -0,0 +1,7 @@ +#source: relr-got-start.s +#ld: -pie -z pack-relative-relocs -T relr-relocs.ld +#readelf: -rW + +Relocation section '\.relr\.dyn' at offset 0x[a-z0-f]+ contains 1 entry which relocates 1 location: +Index: Entry Address Symbolic Address +0000: 0000000000020008 0000000000020008 _GLOBAL_OFFSET_TABLE_ \+ 0x8 diff --git a/ld/testsuite/ld-loongarch-elf/relr-got-start.s b/ld/testsuite/ld-loongarch-elf/relr-got-start.s new file mode 100644 index 00000000000..c89fb42527f --- /dev/null +++ b/ld/testsuite/ld-loongarch-elf/relr-got-start.s @@ -0,0 +1,5 @@ +.globl _start +_start: + pcalau12i $r5,%got_pc_hi20(_start) + ld.d $r5,$r5,%got_pc_lo12(_start) + ret |