[lld] a031871 - [ELF] Rename adjustSectionsBeforeSorting to adjustOutputSections and make it affect INSERT commands

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 1 10:16:16 PST 2022


Author: Fangrui Song
Date: 2022-02-01T10:16:12-08:00
New Revision: a0318711c8cfcb0ecdd956eb400916c5c2b08d3c

URL: https://github.com/llvm/llvm-project/commit/a0318711c8cfcb0ecdd956eb400916c5c2b08d3c
DIFF: https://github.com/llvm/llvm-project/commit/a0318711c8cfcb0ecdd956eb400916c5c2b08d3c.diff

LOG: [ELF] Rename adjustSectionsBeforeSorting to adjustOutputSections and make it affect INSERT commands

adjustSectionsBeforeSorting updates some output section attributes
(alignment/flags) and removes discardable empty sections. When it is called,
INSERT commands have not been processed. Therefore the flags propagation rule
may not affect output sections defined in an INSERT command properly.

Fix this by moving processInsertCommands before adjustSectionsBeforeSorting.

adjustSectionsBeforeSorting is somewhat misnamed. The order between it and
sortInputSections does not matter. With the pass shuffle, the name of
adjustSectionsBeforeSorting becomes wrong. Therefore rename it. The new
name is not set into stone. The function mixes several tasks and the
code may be refactored in a way that we may give them more meaningful
names.

With this patch, I think the behavior of attribute propagation becomes more
reasonable. In particular, in the absence of non-INSERT SECTIONS,
inserting a section after a SHF_ALLOC one will give us a SHF_ALLOC section,
not a non-SHF_ALLOC one (see linkerscript/insert-after.test).

Reviewed By: peter.smith, bluca

Differential Revision: https://reviews.llvm.org/D118529

Added: 
    

Modified: 
    lld/ELF/LinkerScript.cpp
    lld/ELF/LinkerScript.h
    lld/ELF/Writer.cpp
    lld/test/ELF/linkerscript/insert-after.test
    lld/test/ELF/linkerscript/insert-before.test

Removed: 
    


################################################################################
diff  --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp
index bfb583453735e..7188ce58376d9 100644
--- a/lld/ELF/LinkerScript.cpp
+++ b/lld/ELF/LinkerScript.cpp
@@ -310,7 +310,7 @@ void LinkerScript::processInsertCommands() {
   for (const InsertCommand &cmd : insertCommands) {
     for (StringRef name : cmd.names) {
       // If base is empty, it may have been discarded by
-      // adjustSectionsBeforeSorting(). We do not handle such output sections.
+      // adjustOutputSections(). We do not handle such output sections.
       auto from = llvm::find_if(sectionCommands, [&](SectionCommand *subCmd) {
         return isa<OutputSection>(subCmd) &&
                cast<OutputSection>(subCmd)->name == name;
@@ -1114,7 +1114,7 @@ static void maybePropagatePhdrs(OutputSection &sec,
   }
 }
 
-void LinkerScript::adjustSectionsBeforeSorting() {
+void LinkerScript::adjustOutputSections() {
   // If the output section contains only symbol assignments, create a
   // corresponding output section. The issue is what to do with linker script
   // like ".foo : { symbol = 42; }". One option would be to convert it to

diff  --git a/lld/ELF/LinkerScript.h b/lld/ELF/LinkerScript.h
index d2a6f5e9acb1e..24c2c632f93b6 100644
--- a/lld/ELF/LinkerScript.h
+++ b/lld/ELF/LinkerScript.h
@@ -319,7 +319,7 @@ class LinkerScript final {
 
   void addOrphanSections();
   void diagnoseOrphanHandling() const;
-  void adjustSectionsBeforeSorting();
+  void adjustOutputSections();
   void adjustSectionsAfterSorting();
 
   SmallVector<PhdrEntry *, 0> createPhdrs();

diff  --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp
index a3140c98dbf70..9383ac46c8e72 100644
--- a/lld/ELF/Writer.cpp
+++ b/lld/ELF/Writer.cpp
@@ -1429,22 +1429,19 @@ template <class ELFT> void Writer<ELFT>::sortInputSections() {
 
 template <class ELFT> void Writer<ELFT>::sortSections() {
   llvm::TimeTraceScope timeScope("Sort sections");
-  script->adjustSectionsBeforeSorting();
 
   // Don't sort if using -r. It is not necessary and we want to preserve the
   // relative order for SHF_LINK_ORDER sections.
-  if (config->relocatable)
+  if (config->relocatable) {
+    script->adjustOutputSections();
     return;
+  }
 
   sortInputSections();
 
-  for (SectionCommand *cmd : script->sectionCommands) {
-    auto *os = dyn_cast<OutputSection>(cmd);
-    if (!os)
-      continue;
-    os->sortRank = getSectionRank(os);
-  }
-
+  for (SectionCommand *cmd : script->sectionCommands)
+    if (auto *osec = dyn_cast_or_null<OutputSection>(cmd))
+      osec->sortRank = getSectionRank(osec);
   if (!script->hasSectionsCommand) {
     // We know that all the OutputSections are contiguous in this case.
     auto isSection = [](SectionCommand *cmd) {
@@ -1454,14 +1451,15 @@ template <class ELFT> void Writer<ELFT>::sortSections() {
         llvm::find_if(script->sectionCommands, isSection),
         llvm::find_if(llvm::reverse(script->sectionCommands), isSection).base(),
         compareSections);
-
-    // Process INSERT commands. From this point onwards the order of
-    // script->sectionCommands is fixed.
-    script->processInsertCommands();
-    return;
   }
 
+  // Process INSERT commands and update output section attributes. From this
+  // point onwards the order of script->sectionCommands is fixed.
   script->processInsertCommands();
+  script->adjustOutputSections();
+
+  if (!script->hasSectionsCommand)
+    return;
 
   // Orphan sections are sections present in the input files which are
   // not explicitly placed into the output file by the linker script.

diff  --git a/lld/test/ELF/linkerscript/insert-after.test b/lld/test/ELF/linkerscript/insert-after.test
index b438389c795fe..4b25ff36806cf 100644
--- a/lld/test/ELF/linkerscript/insert-after.test
+++ b/lld/test/ELF/linkerscript/insert-after.test
@@ -31,7 +31,7 @@
 # CHECK2-NEXT: .foo.text PROGBITS [[#%x,]]           [[#%x,]] 000008 00  AX
 # CHECK2-NEXT: .data     PROGBITS [[#%x,]]           [[#%x,]] 000008 00  WA
 # CHECK2-NEXT: .foo.data PROGBITS [[#%x,]]           [[#%x,]] 000008 00  WA
-# CHECK2-NEXT: .byte     PROGBITS [[#%x,]]           [[#%x,]] 000001 00     0
+# CHECK2-NEXT: .byte     PROGBITS [[#%x,]]           [[#%x,]] 000001 00  WA
 # CHECK2:      Type      {{.*}} Flg Align
 # CHECK2-NEXT: PHDR      {{.*}} R   0x8
 # CHECK2-NEXT: LOAD      {{.*}} R   0x1000

diff  --git a/lld/test/ELF/linkerscript/insert-before.test b/lld/test/ELF/linkerscript/insert-before.test
index ff407464e3f53..f9611538c013b 100644
--- a/lld/test/ELF/linkerscript/insert-before.test
+++ b/lld/test/ELF/linkerscript/insert-before.test
@@ -11,7 +11,7 @@
 # CHECK-NEXT:           NULL
 # CHECK-NEXT: .foo.text PROGBITS 0000000000000000 001000 000008 00  AX
 # CHECK-NEXT: .text     PROGBITS 0000000000000008 001008 000008 00  AX
-# CHECK-NEXT: .byte     PROGBITS 0000000000000010 001010 000001 00  WA
+# CHECK-NEXT: .byte     PROGBITS 0000000000000010 001010 000001 00  AX
 # CHECK-NEXT: .foo.data PROGBITS 0000000000000011 001011 000008 00  WA
 # CHECK-NEXT: .data     PROGBITS 0000000000000019 001019 000008 00  WA
 # CHECK:      Type
@@ -29,7 +29,7 @@
 # CHECK2-NEXT:           NULL
 # CHECK2-NEXT: .foo.text PROGBITS 000000000020{{.*}} [[#%x,]] 000008 00  AX
 # CHECK2-NEXT: .text     PROGBITS [[#%x,]]           [[#%x,]] 000008 00  AX
-# CHECK2-NEXT: .byte     PROGBITS [[#%x,]]           [[#%x,]] 000001 00     0
+# CHECK2-NEXT: .byte     PROGBITS [[#%x,]]           [[#%x,]] 000001 00  WA
 # CHECK2-NEXT: .foo.data PROGBITS [[#%x,]]           [[#%x,]] 000008 00  WA
 # CHECK2-NEXT: .data     PROGBITS [[#%x,]]           [[#%x,]] 000008 00  WA
 # CHECK2:      Type      {{.*}} Flg Align


        


More information about the llvm-commits mailing list