elf: Don't merge sections with different SHF_LINK_ORDER
authorH.J. Lu <hjl.tools@gmail.com>
Wed, 30 Aug 2023 17:24:56 +0000 (10:24 -0700)
committerH.J. Lu <hjl.tools@gmail.com>
Thu, 31 Aug 2023 00:17:31 +0000 (17:17 -0700)
For relocatable link, don't merge 2 SHF_LINK_ORDER sections if output
sections of their linked to sections are different.

* ldelf.c (elf_orphan_compatible): Don't merge sections with
different SHF_LINK_ORDER.
* testsuite/ld-elf/pr30791a.d: New file.
* testsuite/ld-elf/pr30791a.s: Likewise.
* testsuite/ld-elf/pr30791b.d: Likewise.
* testsuite/ld-elf/pr30791b.s: Likewise.
* testsuite/ld-elf/pr30791c.s: Likewise.
* testsuite/ld-elf/pr30791d.s: Likewise.

ld/ldelf.c
ld/testsuite/ld-elf/pr30791a.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr30791a.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr30791b.d [new file with mode: 0644]
ld/testsuite/ld-elf/pr30791b.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr30791c.s [new file with mode: 0644]
ld/testsuite/ld-elf/pr30791d.s [new file with mode: 0644]

index 4212075a0e2b97878c896daa2a48cd5d4c23df64..d74354a96222b050d49445fdd03e7d7f82b9e682 100644 (file)
@@ -2080,9 +2080,14 @@ elf_orphan_compatible (asection *in, asection *out)
     return false;
   /* We can't merge with a member of an output section group or merge
      two sections with differing SHF_EXCLUDE or other processor and OS
-     specific flags when doing a relocatable link.  */
+     specific flags or with different SHF_LINK_ORDER when doing a
+     relocatable link.  */
   if (bfd_link_relocatable (&link_info)
       && (elf_next_in_group (out) != NULL
+         || ((elf_section_flags (in) & SHF_LINK_ORDER) != 0
+             && (elf_section_flags (out) & SHF_LINK_ORDER) != 0
+             && (elf_linked_to_section (in)->output_section
+                 != elf_linked_to_section (out)->output_section))
          || ((elf_section_flags (out) ^ elf_section_flags (in))
              & (SHF_MASKPROC | SHF_MASKOS)) != 0))
     return false;
diff --git a/ld/testsuite/ld-elf/pr30791a.d b/ld/testsuite/ld-elf/pr30791a.d
new file mode 100644 (file)
index 0000000..2446b52
--- /dev/null
@@ -0,0 +1,16 @@
+#source: pr30791a.s
+#source: pr30791b.s
+#ld: -r
+#readelf: -S --wide
+
+#...
+Section Headers:
+#...
+  \[[ 0-9]+\] __patchable_function_entries[ \t]+PROGBITS[ \t0-9a-f]+WAL.*
+#...
+  \[[ 0-9]+\] __patchable_function_entries[ \t]+PROGBITS[ \t0-9a-f]+WAL.*
+#...
+  \[[ 0-9]+\] __patchable_function_entries[ \t]+PROGBITS[ \t0-9a-f]+WAL.*
+#...
+  \[[ 0-9]+\] __patchable_function_entries[ \t]+PROGBITS[ \t0-9a-f]+WAL.*
+#pass
diff --git a/ld/testsuite/ld-elf/pr30791a.s b/ld/testsuite/ld-elf/pr30791a.s
new file mode 100644 (file)
index 0000000..44b75db
--- /dev/null
@@ -0,0 +1,20 @@
+       .section        .text.a,"ax",%progbits
+       .globl  a
+       .type   a, %function
+a:
+.LFB0:
+       .section        __patchable_function_entries,"awo",%progbits,.LPFE0
+       .dc.a   .LPFE0
+       .section        .text.a
+.LPFE0:
+       .byte   0
+       .section        .text.b,"ax",%progbits
+       .globl  b
+       .type   b, %function
+b:
+.LFB1:
+       .section        __patchable_function_entries,"awo",%progbits,.LPFE1
+       .dc.a   .LPFE1
+       .section        .text.b
+.LPFE1:
+       .byte   0
diff --git a/ld/testsuite/ld-elf/pr30791b.d b/ld/testsuite/ld-elf/pr30791b.d
new file mode 100644 (file)
index 0000000..5013c24
--- /dev/null
@@ -0,0 +1,11 @@
+#source: pr30791c.s
+#source: pr30791d.s
+#ld: -r
+#readelf: -S --wide
+
+#failif
+#...
+  \[[ 0-9]+\] __patchable_function_entries[ \t]+PROGBITS[ \t0-9a-f]+WAL.*
+#...
+  \[[ 0-9]+\] __patchable_function_entries[ \t]+PROGBITS[ \t0-9a-f]+WAL.*
+#...
diff --git a/ld/testsuite/ld-elf/pr30791b.s b/ld/testsuite/ld-elf/pr30791b.s
new file mode 100644 (file)
index 0000000..3f97f6c
--- /dev/null
@@ -0,0 +1,20 @@
+       .section        .text.c,"ax",%progbits
+       .globl  c
+       .type   c, %function
+c:
+.LFB0:
+       .section        __patchable_function_entries,"awo",%progbits,.LPFE0
+       .dc.a   .LPFE0
+       .section        .text.c
+.LPFE0:
+       .byte   0
+       .section        .text.d,"ax",%progbits
+       .globl  d
+       .type   d, %function
+d:
+.LFB1:
+       .section        __patchable_function_entries,"awo",%progbits,.LPFE1
+       .dc.a   .LPFE1
+       .section        .text.d
+.LPFE1:
+       .byte   0
diff --git a/ld/testsuite/ld-elf/pr30791c.s b/ld/testsuite/ld-elf/pr30791c.s
new file mode 100644 (file)
index 0000000..71ef77b
--- /dev/null
@@ -0,0 +1,20 @@
+       .text
+       .globl  a
+       .type   a, %function
+a:
+.LFB0:
+       .section        __patchable_function_entries,"awo",%progbits,.LPFE0
+       .dc.a   .LPFE0
+       .text
+.LPFE0:
+       .byte   0
+       .text
+       .globl  b
+       .type   b, %function
+b:
+.LFB1:
+       .section        __patchable_function_entries,"awo",%progbits,.LPFE1
+       .dc.a   .LPFE1
+       .text
+.LPFE1:
+       .byte   0
diff --git a/ld/testsuite/ld-elf/pr30791d.s b/ld/testsuite/ld-elf/pr30791d.s
new file mode 100644 (file)
index 0000000..5ca1c60
--- /dev/null
@@ -0,0 +1,20 @@
+       .text
+       .globl  c
+       .type   c, %function
+c:
+.LFB0:
+       .section        __patchable_function_entries,"awo",%progbits,.LPFE0
+       .dc.a   .LPFE0
+       .text
+.LPFE0:
+       .byte   0
+       .text
+       .globl  d
+       .type   d, %function
+d:
+.LFB1:
+       .section        __patchable_function_entries,"awo",%progbits,.LPFE1
+       .dc.a   .LPFE1
+       .text
+.LPFE1:
+       .byte   0