[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
Fri May 26 04:02:07 PDT 2017
peter.smith updated this revision to Diff 100385.
peter.smith added a comment.
The inputSectionRanges() was previously defined in https://reviews.llvm.org/D33496, I've removed it from that review to use Script->getCmd() instead. Sorry for the confusion.
I've now put it back here using an OutputSection* and getCmd() instead of StringRef, I've also started the search for the InputSection that precedes the Sentinel from the end as the sections are sorted in ascending order.
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
@@ -2181,13 +2181,29 @@
// 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 = 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();
+ InputSection *Highest = nullptr;
+ std::vector<std::vector<InputSection *> *> Ranges =
+ Script->inputSectionRanges(OutSec);
+ // The Sections are sorted in order of ascending PREL31 address with the
+ // sentinel last. We need to find the InputSection that precedes the
+ // sentinel, this may not be in the same Range.
+ for (auto Range = Ranges.rbegin(); Range != Ranges.rend(); ++Range) {
+ auto NonSentinel = std::find_if(
+ (*Range)->rbegin(), (*Range)->rend(),
+ [](InputSection *IS) { return !isa<SyntheticSection>(IS); });
+ if (NonSentinel != (*Range)->rend()) {
+ Highest = *NonSentinel;
+ break;
+ }
+ }
+ assert(Highest != nullptr);
+ InputSection *LS = cast<InputSection>(Highest->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
@@ -258,6 +258,8 @@
std::vector<OutputSection *> *OutputSections;
void fabricateDefaultCommands();
+ std::vector<std::vector<InputSection *> *>
+ inputSectionRanges(OutputSection* OS);
void addOrphanSections(OutputSectionFactory &Factory);
void removeEmptyCommands();
void adjustSectionsBeforeSorting();
Index: ELF/LinkerScript.cpp
===================================================================
--- ELF/LinkerScript.cpp
+++ ELF/LinkerScript.cpp
@@ -480,6 +480,22 @@
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(OutputSection *OS) {
+ std::vector<std::vector<InputSection *> *> Ranges;
+ OutputSectionCommand *OutCmd = getCmd(OS);
+ if (!OutCmd)
+ return Ranges;
+ 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.100385.patch
Type: text/x-patch
Size: 3291 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170526/45e8c481/attachment.bin>
More information about the llvm-commits
mailing list