[binutils-gdb] LoongArch: Fix assertion failure with DT_RELR

liu & zhensong liuzhensong@sourceware.org
Wed Aug 14 09:45:45 GMT 2024


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=91e0b4655109a38b631baba310cb93a49f94c434

commit 91e0b4655109a38b631baba310cb93a49f94c434
Author: Xi Ruoyao <xry111@xry111.site>
Date:   Mon Aug 12 18:23:46 2024 +0800

    LoongArch: Fix assertion failure with DT_RELR
    
    In the DT_RELR implementation I missed a code path emiting relative
    reloc entries.  Then the already packed relative reloc entries will be
    (unnecessarily) pushed into .rela.dyn but we've not allocated the space
    for them, triggering an assertion failure.
    
    Unfortunately I failed to notice the issue until profiled bootstrapping
    GCC with LTO and -Wl,-z,pack-relative-relocs.  The failure can be easily
    triggered by linking a "hello world" program with -fprofile-generate and
    LTO:
    
        $ PATH=$HOME/ld-test:$PATH gcc hw.c -fprofile-generate -Wl,-z,pack-relative-relocs -flto
        /home/xry111/git-repos/binutils-build/TEST/ld: BFD (GNU Binutils) 2.43.50.20240802 assertion fail ../../binutils-gdb/bfd/elfnn-loongarch.c:2628
        /home/xry111/git-repos/binutils-build/TEST/ld: BFD (GNU Binutils) 2.43.50.20240802 assertion fail ../../binutils-gdb/bfd/elfnn-loongarch.c:2628
        collect2: error: ld returned 1 exit status
    
    And the reduced test case is just incredibly simple (included in the
    patch) so it seems I'm just stupid enough to fail to detect it before.
    Let's fix it now anyway.
    
    Signed-off-by: Xi Ruoyao <xry111@xry111.site>

Diff:
---
 bfd/elfnn-loongarch.c                              | 3 ++-
 ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp | 1 +
 ld/testsuite/ld-loongarch-elf/relr-got-start.d     | 7 +++++++
 ld/testsuite/ld-loongarch-elf/relr-got-start.s     | 5 +++++
 4 files changed, 15 insertions(+), 1 deletion(-)

diff --git a/bfd/elfnn-loongarch.c b/bfd/elfnn-loongarch.c
index af8cb2575e7..eecf7a800e8 100644
--- a/bfd/elfnn-loongarch.c
+++ b/bfd/elfnn-loongarch.c
@@ -4131,7 +4131,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;
diff --git a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
index 16d89cd5a43..d80014d9563 100644
--- a/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
+++ b/ld/testsuite/ld-loongarch-elf/ld-loongarch-elf.exp
@@ -161,6 +161,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


More information about the Binutils-cvs mailing list