[lld] [ELF] Orphan placement: remove hasInputSections condition (PR #93761)

via llvm-commits llvm-commits at lists.llvm.org
Wed May 29 20:15:00 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld

@llvm/pr-subscribers-lld-elf

Author: Fangrui Song (MaskRay)

<details>
<summary>Changes</summary>

https://reviews.llvm.org/D60131 (Change default output section type to
SHT_PROGBITS) caused a orphan placement regression for Fuchsia
`zircon.elf`: #<!-- -->40998 The orphan section `code_patch_table` was placed
before the first output section description `.text.boot0`, breaking the
address requirement.

https://reviews.llvm.org/D61197 (Fix getRankProximity to "ignore" not
live sections) fixed the regression by adding a `Live` condition (which
later became `hasInputSections`).

This condition added complexity, which turns out to be unneeded after
3bdc90e3ff4c9a18caeb3e6ad40fa5d15bbf9d5e and
f639b57f7993cadb82ee9c36f04703ae4430ed85. The new orphan placement rule
is slightly different (orphans can be placed after an output section
that does not contain input sections), but simpler and probably more
reasonable.

* nobits-offset.s: `.sec1 (NOLOAD) : { . += 1; }`
* orphan-live-only.s: `.pad : { QUAD(0); } :exec`
* memory-nonalloc-no-warn.test: `.nonalloc`, `.dat`, and `.intvec[012]_out` have the same rank.
  `.comment` was previously placed after `.nonalloc` and now after `.intvec2_out`.


---
Full diff: https://github.com/llvm/llvm-project/pull/93761.diff


6 Files Affected:

- (modified) lld/ELF/Writer.cpp (+6-12) 
- (modified) lld/test/ELF/linkerscript/memory-nonalloc-no-warn.test (+9-10) 
- (modified) lld/test/ELF/linkerscript/nobits-offset.s (+1-1) 
- (modified) lld/test/ELF/linkerscript/orphan-live-only.s (+3-3) 
- (modified) lld/test/ELF/linkerscript/symbol-only-align.test (+6-5) 
- (modified) lld/test/ELF/linkerscript/tls-nobits-offset.s (+1-1) 


``````````diff
diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index c498153f3348b..4add995c93458 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -890,9 +890,7 @@ template <class ELFT> void Writer<ELFT>::setReservedSymbolSections() {
 // countLeadingZeros.
 static int getRankProximity(OutputSection *a, SectionCommand *b) {
   auto *osd = dyn_cast<OutputDesc>(b);
-  return (osd && osd->osec.hasInputSections)
-             ? llvm::countl_zero(a->sortRank ^ osd->osec.sortRank)
-             : -1;
+  return osd ? llvm::countl_zero(a->sortRank ^ osd->osec.sortRank) : -1;
 }
 
 // When placing orphan sections, we want to place them after symbol assignments
@@ -958,20 +956,16 @@ findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
     sortRank = std::max(sortRank, foundSec->sortRank);
   for (; i != e; ++i) {
     auto *curSecDesc = dyn_cast<OutputDesc>(*i);
-    if (!curSecDesc || !curSecDesc->osec.hasInputSections)
+    if (!curSecDesc)
       continue;
     if (getRankProximity(sec, curSecDesc) != proximity ||
         sortRank < curSecDesc->osec.sortRank)
       break;
   }
 
-  auto isOutputSecWithInputSections = [](SectionCommand *cmd) {
-    auto *osd = dyn_cast<OutputDesc>(cmd);
-    return osd && osd->osec.hasInputSections;
-  };
-  auto j =
-      std::find_if(std::make_reverse_iterator(i), std::make_reverse_iterator(b),
-                   isOutputSecWithInputSections);
+  auto isOutputSec = [](SectionCommand *cmd) { return isa<OutputDesc>(cmd); };
+  auto j = std::find_if(std::make_reverse_iterator(i),
+                        std::make_reverse_iterator(b), isOutputSec);
   i = j.base();
 
   // As a special case, if the orphan section is the last section, put
@@ -979,7 +973,7 @@ findOrphanPos(SmallVectorImpl<SectionCommand *>::iterator b,
   // This matches bfd's behavior and is convenient when the linker script fully
   // specifies the start of the file, but doesn't care about the end (the non
   // alloc sections for example).
-  auto nextSec = std::find_if(i, e, isOutputSecWithInputSections);
+  auto nextSec = std::find_if(i, e, isOutputSec);
   if (nextSec == e)
     return e;
 
diff --git a/lld/test/ELF/linkerscript/memory-nonalloc-no-warn.test b/lld/test/ELF/linkerscript/memory-nonalloc-no-warn.test
index 2dcd0f8d6ce2f..9c6111008c818 100644
--- a/lld/test/ELF/linkerscript/memory-nonalloc-no-warn.test
+++ b/lld/test/ELF/linkerscript/memory-nonalloc-no-warn.test
@@ -16,22 +16,21 @@
 ## The output file must include all sections.
 # RUN: llvm-readelf -S %t/a.elf | FileCheck %s
 
-# CHECK:      There are 12 section headers, starting at offset 0x2140:
+# CHECK:      There are 12 section headers, starting at offset 0x2138:
 # CHECK:      [Nr] Name         Type      Address          Off    Size   ES Flg Lk Inf Al
 # CHECK-NEXT: [ 0]              NULL      0000000000000000 000000 000000 00     0  0   0
 # CHECK-NEXT: [ 1] .nonalloc    PROGBITS  0000000000000000 001064 001000 00 W   0  0   1
-# CHECK-NEXT: [ 2] .comment     PROGBITS  0000000000000000 {{.*}} {{.*}} 01 MS  0  0   1
-# CHECK-NEXT: [ 3] .symtab      SYMTAB    0000000000000000 {{.*}} {{.*}} 18     5  1   8
-# CHECK-NEXT: [ 4] .shstrtab    STRTAB    0000000000000000 {{.*}} {{.*}} 00     0  0   1
-# CHECK-NEXT: [ 5] .strtab      STRTAB    0000000000000000 {{.*}} {{.*}} 00     0  0   1
-# CHECK-NEXT: [ 6] .dat         PROGBITS  0000000000000000 002137 000004 00 W   0  0   1
-# CHECK-NEXT: [ 7] .intvec0_out PROGBITS  0000000000000000 00213b 000000 00 W   0  0   1
-# CHECK-NEXT: [ 8] .intvec1_out PROGBITS  0000000000000000 00213b 000000 00 W   0  0   1
-# CHECK-NEXT: [ 9] .intvec2_out PROGBITS  0000000000000000 00213b 000000 00 W   0  0   1
+# CHECK-NEXT: [ 2] .dat         PROGBITS  0000000000000000 002064 000004 00 W   0  0   1
+# CHECK-NEXT: [ 3] .intvec0_out PROGBITS  0000000000000000 002068 000000 00 W   0  0   1
+# CHECK-NEXT: [ 4] .intvec1_out PROGBITS  0000000000000000 002068 000000 00 W   0  0   1
+# CHECK-NEXT: [ 5] .intvec2_out PROGBITS  0000000000000000 002068 000000 00 W   0  0   1
+# CHECK-NEXT: [ 6] .comment     PROGBITS  0000000000000000 {{.*}} {{.*}} 01 MS  0  0   1
+# CHECK-NEXT: [ 7] .symtab      SYMTAB    0000000000000000 {{.*}} {{.*}} 18     9  1   8
+# CHECK-NEXT: [ 8] .shstrtab    STRTAB    0000000000000000 {{.*}} {{.*}} 00     0  0   1
+# CHECK-NEXT: [ 9] .strtab      STRTAB    0000000000000000 {{.*}} {{.*}} 00     0  0   1
 # CHECK-NEXT: [10] .intvec3_out PROGBITS  00000000803fe060 001060 000004 00 AX  0  0   1
 # CHECK-NEXT: [11] .text        PROGBITS  00000000803fe064 001064 000000 00 AX  0  0   4
 
-
 #--- a.s
 .global _start
 .text
diff --git a/lld/test/ELF/linkerscript/nobits-offset.s b/lld/test/ELF/linkerscript/nobits-offset.s
index 387eaed4cb146..b305cec6fb699 100644
--- a/lld/test/ELF/linkerscript/nobits-offset.s
+++ b/lld/test/ELF/linkerscript/nobits-offset.s
@@ -14,8 +14,8 @@
 
 # CHECK:      Name  Type     Address          Off     Size
 # CHECK-NEXT:       NULL     0000000000000000 000000  000000
-# CHECK-NEXT: .text PROGBITS 0000000000000000 000190  000000
 # CHECK-NEXT: .sec1 NOBITS   0000000000000000 001000  000001
+# CHECK-NEXT: .text PROGBITS 0000000000000004 001000  000000
 # CHECK-NEXT: .bss  NOBITS   0000000000000400 001400  000001
 
 # CHECK:      Type Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align
diff --git a/lld/test/ELF/linkerscript/orphan-live-only.s b/lld/test/ELF/linkerscript/orphan-live-only.s
index 500005173a866..900532e0eab61 100644
--- a/lld/test/ELF/linkerscript/orphan-live-only.s
+++ b/lld/test/ELF/linkerscript/orphan-live-only.s
@@ -20,14 +20,14 @@
 
 # CHECK: Section Headers
 # CHECK: .pad
+# CHECK-NEXT: .orphan1
 # CHECK-NEXT: .text
 # CHECK-NEXT: .orphan2
 # CHECK-NEXT: .ro
-# CHECK-NEXT: .orphan1
 
 # CHECK: Segment Sections
-# CHECK-NEXT: .pad .text .orphan2
-# CHECK-NEXT: .ro .orphan1
+# CHECK-NEXT: .pad .orphan1 .text .orphan2
+# CHECK-NEXT: .ro
 
 .section .text,"ax"
  ret
diff --git a/lld/test/ELF/linkerscript/symbol-only-align.test b/lld/test/ELF/linkerscript/symbol-only-align.test
index f4ecf275ec0bd..c553e8138b5eb 100644
--- a/lld/test/ELF/linkerscript/symbol-only-align.test
+++ b/lld/test/ELF/linkerscript/symbol-only-align.test
@@ -23,13 +23,14 @@ SECTIONS {
 ## offset and addresses match.
 
 # CHECK: Section Headers
-# CHECK:      foo   PROGBITS 0000000000[[ADDR:[0-9a-f]*]] [[ADDR]]
-# CHECK-NEXT: .data PROGBITS 0000000000[[ADDR]] [[ADDR]]
+# CHECK:      .text     PROGBITS
+# CHECK-NEXT: foo       PROGBITS 0000000000001000 001000 000000
+# CHECK-NEXT: .dynsym   DYNSYM   0000000000001000 001000
 
 # CHECK: Program Headers
 # CHECK:      LOAD
-# CHECK-NEXT: LOAD 0x[[ADDR]] 0x0000000000[[ADDR]] 0x0000000000[[ADDR]]
+# CHECK-NEXT: LOAD 0x001000   0x0000000000001000   0x0000000000001000
 
 # CHECK: Symbol table
-# CHECK: 0000000000[[ADDR]] 0 NOTYPE GLOBAL DEFAULT {{[0-9]+}} __start_foo
-# CHECK: 0000000000[[ADDR]] 0 NOTYPE GLOBAL DEFAULT {{[0-9]+}} __end_foo
+# CHECK: 0000000000001000   0 NOTYPE GLOBAL DEFAULT [[#]] __start_foo
+# CHECK: 0000000000001000   0 NOTYPE GLOBAL DEFAULT [[#]] __end_foo
diff --git a/lld/test/ELF/linkerscript/tls-nobits-offset.s b/lld/test/ELF/linkerscript/tls-nobits-offset.s
index 9aab32317be4c..7830b457e1b4d 100644
--- a/lld/test/ELF/linkerscript/tls-nobits-offset.s
+++ b/lld/test/ELF/linkerscript/tls-nobits-offset.s
@@ -14,8 +14,8 @@
 
 # CHECK:      Name  Type     Address          Off     Size
 # CHECK-NEXT:       NULL     0000000000000000 000000  000000
-# CHECK-NEXT: .text PROGBITS 0000000000000000 000190  000000
 # CHECK-NEXT: .sec1 PROGBITS 0000000000000000 001000  000001
+# CHECK-NEXT: .text PROGBITS 0000000000000004 001004  000000
 # CHECK-NEXT: .tbss NOBITS   0000000000000400 001400  000001
 
 # CHECK:      Type Offset   VirtAddr           PhysAddr           FileSiz  MemSiz   Flg Align

``````````

</details>


https://github.com/llvm/llvm-project/pull/93761


More information about the llvm-commits mailing list