Page MenuHomePhabricator

D61666.diff
No OneTemporary

File Metadata

Created
Mon, Sep 16, 4:03 PM

D61666.diff

Index: ELF/Relocations.h
===================================================================
--- ELF/Relocations.h
+++ ELF/Relocations.h
@@ -129,7 +129,7 @@
ThunkSection *getISDThunkSec(OutputSection *OS, InputSection *IS,
InputSectionDescription *ISD, uint32_t Type,
- uint64_t Src);
+ uint64_t Src, unsigned &ThunkSecIdx);
ThunkSection *getISThunkSec(InputSection *IS);
Index: ELF/Relocations.cpp
===================================================================
--- ELF/Relocations.cpp
+++ ELF/Relocations.cpp
@@ -1240,10 +1240,9 @@
for (auto I = Rels.begin(), End = Rels.end(); I != End;)
scanReloc<ELFT>(Sec, GetOffset, I, End);
- // Sort relocations by offset for more efficient searching for
- // R_RISCV_PCREL_HI20 and R_PPC64_ADDR64.
- if (Config->EMachine == EM_RISCV ||
- (Config->EMachine == EM_PPC64 && Sec.Name == ".toc"))
+ // Efficient searching for R_RISCV_PCREL_HI20 and R_PPC64_ADDR64, and targets
+ // need thunks require relocations sorted by offset.
+ if (Target->NeedsThunks || Config->EMachine == EM_RISCV)
llvm::stable_sort(Sec.Relocations,
[](const Relocation &LHS, const Relocation &RHS) {
return LHS.Offset < RHS.Offset;
@@ -1441,13 +1440,20 @@
// linker script section pattern such as { .text .text.* }.
ThunkSection *ThunkCreator::getISDThunkSec(OutputSection *OS, InputSection *IS,
InputSectionDescription *ISD,
- uint32_t Type, uint64_t Src) {
- for (std::pair<ThunkSection *, uint32_t> TP : ISD->ThunkSections) {
- ThunkSection *TS = TP.first;
+ uint32_t Type, uint64_t Src,
+ unsigned &ThunkSecIdx) {
+ for (unsigned E = ISD->ThunkSections.size(); ThunkSecIdx != E;
+ ++ThunkSecIdx) {
+ ThunkSection *TS = ISD->ThunkSections[ThunkSecIdx].first;
uint64_t TSBase = OS->Addr + TS->OutSecOff;
uint64_t TSLimit = TSBase + TS->getSize();
if (Target->inBranchRange(Type, Src, (Src > TSLimit) ? TSBase : TSLimit))
return TS;
+ if (Src < TSLimit)
+ break;
+
+ // If we reach here, we know ThunkSecIdx cannot satisfy any subsequent
+ // relocation, which has a larger offset. Thus we skip it (++ThunkSecIdx).
}
// No suitable ThunkSection exists. This can happen when there is a branch
@@ -1634,6 +1640,7 @@
// InputSectionDescription as the caller.
forEachInputSectionDescription(
OutputSections, [&](OutputSection *OS, InputSectionDescription *ISD) {
+ unsigned ThunkSecIdx = 0;
for (InputSection *IS : ISD->Sections)
for (Relocation &Rel : IS->Relocations) {
uint64_t Src = IS->getVA(Rel.Offset);
@@ -1658,7 +1665,7 @@
if (auto *TIS = T->getTargetInputSection())
TS = getISThunkSec(TIS);
else
- TS = getISDThunkSec(OS, IS, ISD, Rel.Type, Src);
+ TS = getISDThunkSec(OS, IS, ISD, Rel.Type, Src, ThunkSecIdx);
TS->addThunk(T);
Thunks[T->getThunkTargetSym()] = T;
}

Event Timeline