[PATCH] D32223: [LLD][ELF] Add InputSectionDescriptions for Orphan Sections

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Apr 19 06:46:20 PDT 2017


peter.smith created this revision.
Herald added subscribers: rengolin, aemerson.

Orphan input sections are sections that do not match any InputSectionDescription, these are either placed in existing OutputSections if their name matches for example

  .text : { *(.text) }

will match all orphans with a prefix of .text. However an orphan that does not match the name of an existing OutputSection will have an OutputSection created. The orphan input sections are added to OutputSections, and are handled by the flush() function when doing address assignment. These orphan sections will be invisible to Thunk creation and the ordering of .ARM.exidx sections as they won't appear on any InputSection description.

      

This change fabricates InputSectionDescriptions to cover the inserted orphan sections. I've checked that this matches the behavior of GNU ld when there is a symbol definition at the end of an existing InputSectionDescription. For example:

  .text : { *(.text) SYM = .; } 

The orphans are added after SYM is defined.

It will now be possible for createThunks to insert thunks into orphan InputSectionDescriptions and for .ARM.exidx section sorting to work with linker scripts that have orphan Sections. For example the InputSectionDescription:

  .ARM.exidx : { *(.ARM.exidx) } 

Will only match sections with a name of .ARM.exidx, sections such as .ARM.exidx.text.foo will not match the InputSectionDescription, but will match the OutputSection as an orphan.

Note that the .ARM.exidx ordering code in OutputSections currently works on OutputSections::Sections, so it is likely to be wrong when there is a linker script. I've put a temporary FIXME in that makes the script ordering work. I have a full fix that rewrites the .ARM.exidx ordering code that I'll post in a separate review.


https://reviews.llvm.org/D32223

Files:
  ELF/LinkerScript.cpp


Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -465,9 +465,39 @@
 
 // Add sections that didn't match any sections command.
 void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
+  std::map<OutputSection *, std::vector<InputSectionBase *>> Orphanage;
   for (InputSectionBase *S : InputSections)
-    if (S->Live && !S->OutSec)
+    if (S->Live && !S->OutSec) {
       Factory.addInputSec(S, getOutputSectionName(S->Name));
+      Orphanage[S->OutSec].push_back(S);
+    }
+
+  // For each OutputSection that already has an OutputSectionCmd, add an
+  // InputSectionDescription at the end for the OrphanSections. This matches
+  // GNU ld behavior for scripts such as .text : { *(.text) SYM = .; } the
+  // orphan sections such as .text.suffix are added after the symbol assignment
+  for (auto &KV : Orphanage) {
+    OutputSection *OS = KV.first;
+    auto Pos = std::find_if(Opt.Commands.begin(), Opt.Commands.end(),
+                            [&](BaseCommand *Base) {
+                              auto *Cmd = dyn_cast<OutputSectionCommand>(Base);
+                              return Cmd && Cmd->Name == OS->Name;
+                            });
+    if (Pos == Opt.Commands.end())
+      // A new OutputSection, we handle this case in placeOrphanSections()
+      continue;
+    auto *OSCmd = cast<OutputSectionCommand>(*Pos);
+    if (KV.second.front()->Name.startswith(".ARM.exidx"))
+      // .ARM.exidx sections must be handled in one InputSectionDescription
+      // FIXME: OutputSections still sorts the OutputSection::Sections so we
+      // can give the wrong answer when the order of the input objects does
+      // not match the address assignment.
+      continue;
+
+    auto *ISD = make<InputSectionDescription>("");
+    OSCmd->Commands.push_back(ISD);
+    ISD->Sections = std::move(KV.second);
+  }
 }
 
 static bool isTbss(OutputSection *Sec) {
@@ -828,6 +858,16 @@
       auto *Cmd = make<OutputSectionCommand>(Name);
       Cmd->Sec = Sec;
       Opt.Commands.insert(CmdIter, Cmd);
+
+      // Create an InputSectionDescription for orphan input sections
+      if (!Sec->Sections.empty() && (Sec->Flags & SHF_ALLOC)) {
+        auto *ISD = make<InputSectionDescription>("");
+        Cmd->Commands.push_back(ISD);
+        for (InputSection *ISec : Sec->Sections) {
+          ISD->Sections.push_back(ISec);
+          ISec->Assigned = true;
+        }
+      }
       ++CmdIndex;
       continue;
     }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D32223.95731.patch
Type: text/x-patch
Size: 2559 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170419/8d871214/attachment.bin>


More information about the llvm-commits mailing list