[PATCH] D33500: [LLD][ELF] .ARM.exidx sentinel section writeTo() should use InputSectionDescriptions.

Peter Smith via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed May 24 08:44:10 PDT 2017


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

This change converts the writing of the .ARM.exidx sentinel section to use the InputSectionDescriptions instead of OutputSection::Sections this is in preparation for the retirement of OutputSection::Sections.

      

To use the InputSectionDescriptions we need a way of obtaining them from the OutputSection. I've chosen to add member function to extract a vector of the InputSectionDescriptions. For this particular use case it might be better to offer a more functional Script->forEachInputSection(OutSecName, lambda) interface. However some
other use cases such as processing Thunks may need to insert directly into InputSections so I've used the interface that exposes these.

I've split this out from https://reviews.llvm.org/D33239 as it is a logical intermediate step towards converting the SHF_LINK_ORDER processing to use InputSectionDescriptions.


https://reviews.llvm.org/D33500

Files:
  ELF/LinkerScript.cpp
  ELF/LinkerScript.h
  ELF/SyntheticSections.cpp


Index: ELF/SyntheticSections.cpp
===================================================================
--- ELF/SyntheticSections.cpp
+++ ELF/SyntheticSections.cpp
@@ -2192,13 +2192,19 @@
 // This section will have been sorted last in the .ARM.exidx table.
 // This table entry will have the form:
 // | PREL31 upper bound of code that has exception tables | EXIDX_CANTUNWIND |
+// The sentinel must have the PREL31 value of an address higher than any
+// address described by any other table entry.
 void ARMExidxSentinelSection::writeTo(uint8_t *Buf) {
-  // Get the InputSection before us, we are by definition last
-  auto RI = cast<OutputSection>(this->OutSec)->Sections.rbegin();
-  InputSection *LE = *(++RI);
-  InputSection *LC = cast<InputSection>(LE->getLinkOrderDep());
-  uint64_t S = LC->OutSec->Addr + LC->getOffset(LC->getSize());
-  uint64_t P = this->getVA();
+  uint64_t S = 0;
+  uint64_t P = getVA();
+  std::vector<std::vector<InputSection *> *> Ranges =
+    Script->inputSectionRanges(OutSec->Name);
+  for (std::vector<InputSection*> *Range : Ranges)
+    for (InputSection* IS : *Range)
+      if (IS->kind() != InputSectionBase::Synthetic) {
+        InputSection *LS = cast<InputSection>(IS->getLinkOrderDep());
+        S = std::max(S, LS->OutSec->Addr + LS->getOffset(LS->getSize()));
+      }
   Target->relocateOne(Buf, R_ARM_PREL31, S - P);
   write32le(Buf + 4, 0x1);
 }
Index: ELF/LinkerScript.h
===================================================================
--- ELF/LinkerScript.h
+++ ELF/LinkerScript.h
@@ -255,6 +255,8 @@
 
   std::vector<OutputSection *> *OutputSections;
   void fabricateDefaultCommands();
+  std::vector<std::vector<InputSection *> *>
+  inputSectionRanges(StringRef S);
   void addOrphanSections(OutputSectionFactory &Factory);
   void removeEmptyCommands();
   void adjustSectionsBeforeSorting();
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -469,6 +469,28 @@
   Opt.Commands = std::move(Commands);
 }
 
+// For an OutputSection S, return the InputSectionDescriptions that are
+// associated with S. The intention is that callers can iterate over
+// InputSectionDescription::Sections and insert sections such as Thunks.
+std::vector<std::vector<InputSection *> *>
+LinkerScript::inputSectionRanges(StringRef S) {
+  std::vector<std::vector<InputSection *> *> Ranges;
+  auto OutCmdPos = std::find_if(
+      Opt.Commands.begin(), Opt.Commands.end(), [=](BaseCommand *Cmd) {
+        if (auto *OSCmd = dyn_cast<OutputSectionCommand>(Cmd))
+          return (OSCmd->Name == S);
+        return false;
+      });
+  if (OutCmdPos == Opt.Commands.end())
+    return Ranges;
+  auto *OutCmd = cast<OutputSectionCommand>(*OutCmdPos);
+  for (auto *BaseCmd : OutCmd->Commands) {
+    if (auto *ISD = dyn_cast<InputSectionDescription>(BaseCmd))
+      Ranges.push_back(&ISD->Sections);
+  }
+  return Ranges;
+}
+
 // Add sections that didn't match any sections command.
 void LinkerScript::addOrphanSections(OutputSectionFactory &Factory) {
   for (InputSectionBase *S : InputSections) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D33500.100100.patch
Type: text/x-patch
Size: 3148 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170524/97b584dd/attachment.bin>


More information about the llvm-commits mailing list