Skip to content

Commit 36896a0

Browse files
committed
Rebased on #150813
Created using spr 1.3.5
2 parents ddcb9ee + 75fb98c commit 36896a0

File tree

8 files changed

+65
-90
lines changed

8 files changed

+65
-90
lines changed

lld/ELF/Arch/Mips.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,10 @@ template <class ELFT> class MIPS final : public TargetInfo {
4040
};
4141
} // namespace
4242

43+
uint64_t elf::getMipsPageAddr(uint64_t addr) {
44+
return (addr + 0x8000) & ~0xffff;
45+
}
46+
4347
template <class ELFT> MIPS<ELFT>::MIPS(Ctx &ctx) : TargetInfo(ctx) {
4448
gotPltHeaderEntriesNum = 2;
4549
defaultMaxPageSize = 65536;

lld/ELF/InputSection.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -861,6 +861,11 @@ uint64_t InputSectionBase::getRelocTargetVA(Ctx &ctx, const Relocation &r,
861861
return ctx.in.mipsGot->getVA() +
862862
ctx.in.mipsGot->getPageEntryOffset(file, *r.sym, a) -
863863
ctx.in.mipsGot->getGp(file);
864+
case RE_MIPS_OSEC_LOCAL_PAGE:
865+
// This is used by the MIPS multi-GOT implementation. It relocates
866+
// addresses of 64kb pages that lie inside the output section that sym is
867+
// a representative for.
868+
return getMipsPageAddr(r.sym->getOutputSection()->addr) + a;
864869
case RE_MIPS_GOT_OFF:
865870
case RE_MIPS_GOT_OFF32:
866871
// In case of MIPS if a GOT relocation has non-zero addend this addend

lld/ELF/Relocations.cpp

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -886,11 +886,11 @@ static void addPltEntry(Ctx &ctx, PltSection &plt, GotPltSection &gotPlt,
886886
plt.addEntry(sym);
887887
gotPlt.addEntry(sym);
888888
if (sym.isPreemptible)
889-
rel.addReloc({type, &gotPlt, sym.getGotPltOffset(ctx),
890-
DynamicReloc::AgainstSymbol, sym, 0, R_ADDEND});
889+
rel.addReloc(
890+
{type, &gotPlt, sym.getGotPltOffset(ctx), true, sym, 0, R_ADDEND});
891891
else
892-
rel.addReloc({type, &gotPlt, sym.getGotPltOffset(ctx),
893-
DynamicReloc::AddendOnly, sym, 0, R_ABS});
892+
rel.addReloc(
893+
{type, &gotPlt, sym.getGotPltOffset(ctx), false, sym, 0, R_ABS});
894894
}
895895

896896
void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
@@ -899,9 +899,8 @@ void elf::addGotEntry(Ctx &ctx, Symbol &sym) {
899899

900900
// If preemptible, emit a GLOB_DAT relocation.
901901
if (sym.isPreemptible) {
902-
ctx.mainPart->relaDyn->addReloc({ctx.target->gotRel, ctx.in.got.get(), off,
903-
DynamicReloc::AgainstSymbol, sym, 0,
904-
R_ADDEND});
902+
ctx.mainPart->relaDyn->addReloc(
903+
{ctx.target->gotRel, ctx.in.got.get(), off, true, sym, 0, R_ADDEND});
905904
return;
906905
}
907906

@@ -922,15 +921,13 @@ static void addGotAuthEntry(Ctx &ctx, Symbol &sym) {
922921
// If preemptible, emit a GLOB_DAT relocation.
923922
if (sym.isPreemptible) {
924923
ctx.mainPart->relaDyn->addReloc({R_AARCH64_AUTH_GLOB_DAT, ctx.in.got.get(),
925-
off, DynamicReloc::AgainstSymbol, sym, 0,
926-
R_ADDEND});
924+
off, true, sym, 0, R_ADDEND});
927925
return;
928926
}
929927

930928
// Signed GOT requires dynamic relocation.
931929
ctx.in.got->getPartition(ctx).relaDyn->addReloc(
932-
{R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off, DynamicReloc::AddendOnly,
933-
sym, 0, R_ABS});
930+
{R_AARCH64_AUTH_RELATIVE, ctx.in.got.get(), off, false, sym, 0, R_ABS});
934931
}
935932

936933
static void addTpOffsetGotEntry(Ctx &ctx, Symbol &sym) {
@@ -1161,9 +1158,8 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
11611158
sec->addReloc({expr, type, offset, addend, &sym});
11621159
part.relrAuthDyn->relocs.push_back({sec, sec->relocs().size() - 1});
11631160
} else {
1164-
part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset,
1165-
DynamicReloc::AddendOnly, sym, addend,
1166-
R_ABS});
1161+
part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, sec, offset, false,
1162+
sym, addend, R_ABS});
11671163
}
11681164
return;
11691165
}

lld/ELF/Relocations.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ enum RelExpr {
110110
RE_MIPS_GOT_LOCAL_PAGE,
111111
RE_MIPS_GOT_OFF,
112112
RE_MIPS_GOT_OFF32,
113+
RE_MIPS_OSEC_LOCAL_PAGE,
113114
RE_MIPS_TLSGD,
114115
RE_MIPS_TLSLD,
115116
RE_PPC32_PLTREL,

lld/ELF/SyntheticSections.cpp

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -769,10 +769,6 @@ void GotSection::writeTo(uint8_t *buf) {
769769
}
770770
}
771771

772-
static uint64_t getMipsPageAddr(uint64_t addr) {
773-
return (addr + 0x8000) & ~0xffff;
774-
}
775-
776772
static uint64_t getMipsPageCount(uint64_t size) {
777773
return (size + 0xfffe) / 0xffff + 1;
778774
}
@@ -786,7 +782,7 @@ void MipsGotSection::addEntry(InputFile &file, Symbol &sym, int64_t addend,
786782
FileGot &g = getGot(file);
787783
if (expr == RE_MIPS_GOT_LOCAL_PAGE) {
788784
if (const OutputSection *os = sym.getOutputSection())
789-
g.pagesMap.insert({os, {}});
785+
g.pagesMap.insert({os, {&sym}});
790786
else
791787
g.local16.insert({{nullptr, getMipsPageAddr(sym.getVA(ctx, addend))}, 0});
792788
} else if (sym.isTls())
@@ -1114,15 +1110,16 @@ void MipsGotSection::build() {
11141110
size_t pageCount = l.second.count;
11151111
for (size_t pi = 0; pi < pageCount; ++pi) {
11161112
uint64_t offset = (l.second.firstIndex + pi) * ctx.arg.wordsize;
1117-
ctx.mainPart->relaDyn->addReloc({ctx.target->relativeRel, this, offset,
1118-
l.first, int64_t(pi * 0x10000)});
1113+
ctx.mainPart->relaDyn->addReloc(
1114+
{ctx.target->relativeRel, this, offset, false, *l.second.repSym,
1115+
int64_t(pi * 0x10000), RE_MIPS_OSEC_LOCAL_PAGE});
11191116
}
11201117
}
11211118
for (const std::pair<GotEntry, size_t> &p : got.local16) {
11221119
uint64_t offset = p.second * ctx.arg.wordsize;
11231120
ctx.mainPart->relaDyn->addReloc({ctx.target->relativeRel, this, offset,
1124-
DynamicReloc::AddendOnly, *p.first.first,
1125-
p.first.second, R_ABS});
1121+
false, *p.first.first, p.first.second,
1122+
R_ABS});
11261123
}
11271124
}
11281125
}
@@ -1647,20 +1644,10 @@ uint64_t DynamicReloc::getOffset() const {
16471644
}
16481645

16491646
int64_t DynamicReloc::computeAddend(Ctx &ctx) const {
1650-
switch (kind) {
1651-
case Computed:
1652-
llvm_unreachable("addend already computed");
1653-
case AddendOnly:
1654-
case AgainstSymbol: {
1655-
uint64_t ca = inputSec->getRelocTargetVA(
1656-
ctx, Relocation{expr, type, 0, addend, sym}, getOffset());
1657-
return ctx.arg.is64 ? ca : SignExtend64<32>(ca);
1658-
}
1659-
case MipsMultiGotPage:
1660-
assert(sym == nullptr);
1661-
return getMipsPageAddr(outputSec->addr) + addend;
1662-
}
1663-
llvm_unreachable("Unknown DynamicReloc::Kind enum");
1647+
assert(!isFinal && "addend already computed");
1648+
uint64_t ca = inputSec->getRelocTargetVA(
1649+
ctx, Relocation{expr, type, 0, addend, sym}, getOffset());
1650+
return ctx.arg.is64 ? ca : SignExtend64<32>(ca);
16641651
}
16651652

16661653
uint32_t DynamicReloc::getSymIndex(SymbolTableBaseSection *symTab) const {
@@ -1688,20 +1675,18 @@ RelocationBaseSection::RelocationBaseSection(Ctx &ctx, StringRef name,
16881675
void RelocationBaseSection::addSymbolReloc(
16891676
RelType dynType, InputSectionBase &isec, uint64_t offsetInSec, Symbol &sym,
16901677
int64_t addend, std::optional<RelType> addendRelType) {
1691-
addReloc(DynamicReloc::AgainstSymbol, dynType, isec, offsetInSec, sym, addend,
1692-
R_ADDEND, addendRelType ? *addendRelType : ctx.target->noneRel);
1678+
addReloc(true, dynType, isec, offsetInSec, sym, addend, R_ADDEND,
1679+
addendRelType ? *addendRelType : ctx.target->noneRel);
16931680
}
16941681

16951682
void RelocationBaseSection::addAddendOnlyRelocIfNonPreemptible(
16961683
RelType dynType, InputSectionBase &isec, uint64_t offsetInSec, Symbol &sym,
16971684
RelType addendRelType) {
16981685
// No need to write an addend to the section for preemptible symbols.
16991686
if (sym.isPreemptible)
1700-
addReloc({dynType, &isec, offsetInSec, DynamicReloc::AgainstSymbol, sym, 0,
1701-
R_ADDEND});
1687+
addReloc({dynType, &isec, offsetInSec, true, sym, 0, R_ADDEND});
17021688
else
1703-
addReloc(DynamicReloc::AddendOnly, dynType, isec, offsetInSec, sym, 0,
1704-
R_ABS, addendRelType);
1689+
addReloc(false, dynType, isec, offsetInSec, sym, 0, R_ABS, addendRelType);
17051690
}
17061691

17071692
void RelocationBaseSection::mergeRels() {
@@ -1741,17 +1726,17 @@ void RelocationBaseSection::finalizeContents() {
17411726
}
17421727
}
17431728

1744-
void DynamicReloc::computeRaw(Ctx &ctx, SymbolTableBaseSection *symt) {
1729+
void DynamicReloc::finalize(Ctx &ctx, SymbolTableBaseSection *symt) {
17451730
r_offset = getOffset();
17461731
r_sym = getSymIndex(symt);
17471732
addend = computeAddend(ctx);
1748-
kind = Computed; // Catch errors
1733+
isFinal = true; // Catch errors
17491734
}
17501735

17511736
void RelocationBaseSection::computeRels() {
17521737
SymbolTableBaseSection *symTab = getPartition(ctx).dynSymTab.get();
17531738
parallelForEach(relocs, [&ctx = ctx, symTab](DynamicReloc &rel) {
1754-
rel.computeRaw(ctx, symTab);
1739+
rel.finalize(ctx, symTab);
17551740
});
17561741

17571742
auto irelative = std::stable_partition(

lld/ELF/SyntheticSections.h

Lines changed: 25 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -327,9 +327,11 @@ class MipsGotSection final : public SyntheticSection {
327327
size_t startIndex = 0;
328328

329329
struct PageBlock {
330+
Symbol *repSym; // Representative symbol for the OutputSection
330331
size_t firstIndex;
331332
size_t count;
332-
PageBlock() : firstIndex(0), count(0) {}
333+
PageBlock(Symbol *repSym = nullptr)
334+
: repSym(repSym), firstIndex(0), count(0) {}
333335
};
334336

335337
// Map output sections referenced by MIPS GOT relocations
@@ -418,59 +420,31 @@ class StringTableSection final : public SyntheticSection {
418420

419421
class DynamicReloc {
420422
public:
421-
enum Kind {
422-
/// The resulting dynamic relocation has already had its addend computed.
423-
/// Calling computeAddend() is an error. Only for internal use.
424-
Computed,
425-
/// The resulting dynamic relocation will not reference a symbol: #sym is
426-
/// only used to compute the addend with InputSection::getRelocTargetVA().
427-
/// Useful for various relative and TLS relocations (e.g. R_X86_64_TPOFF64).
428-
AddendOnly,
429-
/// The resulting dynamic relocation references symbol #sym from the dynamic
430-
/// symbol table and uses InputSection::getRelocTargetVA() for the final
431-
/// addend.
432-
AgainstSymbol,
433-
/// This is used by the MIPS multi-GOT implementation. It relocates
434-
/// addresses of 64kb pages that lie inside the output section.
435-
MipsMultiGotPage,
436-
};
437423
/// This constructor records a normal relocation.
438424
DynamicReloc(RelType type, const InputSectionBase *inputSec,
439-
uint64_t offsetInSec, Kind kind, Symbol &sym, int64_t addend,
440-
RelExpr expr)
425+
uint64_t offsetInSec, bool isAgainstSymbol, Symbol &sym,
426+
int64_t addend, RelExpr expr)
441427
: sym(&sym), inputSec(inputSec), offsetInSec(offsetInSec), type(type),
442-
addend(addend), kind(kind), expr(expr) {}
428+
addend(addend), isAgainstSymbol(isAgainstSymbol), isFinal(false),
429+
expr(expr) {}
443430
/// This constructor records a relative relocation with no symbol.
444431
DynamicReloc(RelType type, const InputSectionBase *inputSec,
445432
uint64_t offsetInSec, int64_t addend = 0)
446-
: sym(inputSec->getCtx().dummySym), inputSec(inputSec),
447-
offsetInSec(offsetInSec), type(type), addend(addend), kind(AddendOnly),
448-
expr(R_ADDEND) {}
449-
/// This constructor records dynamic relocation settings used by the MIPS
450-
/// multi-GOT implementation.
451-
DynamicReloc(RelType type, const InputSectionBase *inputSec,
452-
uint64_t offsetInSec, const OutputSection *outputSec,
453-
int64_t addend)
454-
: sym(nullptr), outputSec(outputSec), inputSec(inputSec),
455-
offsetInSec(offsetInSec), type(type), addend(addend),
456-
kind(MipsMultiGotPage), expr(R_ADDEND) {}
433+
: DynamicReloc(type, inputSec, offsetInSec, false,
434+
*inputSec->getCtx().dummySym, addend, R_ADDEND) {}
457435

458436
uint64_t getOffset() const;
459437
uint32_t getSymIndex(SymbolTableBaseSection *symTab) const;
460-
bool needsDynSymIndex() const {
461-
assert(kind != Computed && "cannot check kind after computeRaw");
462-
return kind == AgainstSymbol;
463-
}
438+
bool needsDynSymIndex() const { return isAgainstSymbol; }
464439

465440
/// Computes the addend of the dynamic relocation. Note that this is not the
466441
/// same as the #addend member variable as it may also include the symbol
467442
/// address/the address of the corresponding GOT entry/etc.
468443
int64_t computeAddend(Ctx &) const;
469444

470-
void computeRaw(Ctx &, SymbolTableBaseSection *symt);
445+
void finalize(Ctx &, SymbolTableBaseSection *symt);
471446

472447
Symbol *sym;
473-
const OutputSection *outputSec = nullptr;
474448
const InputSectionBase *inputSec;
475449
uint64_t offsetInSec;
476450
uint64_t r_offset;
@@ -481,7 +455,15 @@ class DynamicReloc {
481455
int64_t addend;
482456

483457
private:
484-
Kind kind;
458+
/// Whether this was constructed with a Kind of AgainstSymbol.
459+
LLVM_PREFERRED_TYPE(bool)
460+
uint8_t isAgainstSymbol : 1;
461+
462+
/// The resulting dynamic relocation has already had its addend computed.
463+
/// Calling computeAddend() is an error.
464+
LLVM_PREFERRED_TYPE(bool)
465+
uint8_t isFinal : 1;
466+
485467
// The kind of expression used to calculate the added (required e.g. for
486468
// relative GOT relocations).
487469
RelExpr expr;
@@ -526,8 +508,8 @@ class RelocationBaseSection : public SyntheticSection {
526508
uint64_t offsetInSec, Symbol &sym, int64_t addend,
527509
RelType addendRelType, RelExpr expr) {
528510
assert(expr != R_ADDEND && "expected non-addend relocation expression");
529-
addReloc<shard>(DynamicReloc::AddendOnly, dynType, isec, offsetInSec, sym,
530-
addend, expr, addendRelType);
511+
addReloc<shard>(false, dynType, isec, offsetInSec, sym, addend, expr,
512+
addendRelType);
531513
}
532514
/// Add a dynamic relocation using the target address of \p sym as the addend
533515
/// if \p sym is non-preemptible. Otherwise add a relocation against \p sym.
@@ -536,14 +518,15 @@ class RelocationBaseSection : public SyntheticSection {
536518
uint64_t offsetInSec, Symbol &sym,
537519
RelType addendRelType);
538520
template <bool shard = false>
539-
void addReloc(DynamicReloc::Kind kind, RelType dynType, InputSectionBase &sec,
521+
void addReloc(bool isAgainstSymbol, RelType dynType, InputSectionBase &sec,
540522
uint64_t offsetInSec, Symbol &sym, int64_t addend, RelExpr expr,
541523
RelType addendRelType) {
542524
// Write the addends to the relocated address if required. We skip
543525
// it if the written value would be zero.
544526
if (ctx.arg.writeAddends && (expr != R_ADDEND || addend != 0))
545527
sec.addReloc({expr, addendRelType, offsetInSec, addend, &sym});
546-
addReloc<shard>({dynType, &sec, offsetInSec, kind, sym, addend, expr});
528+
addReloc<shard>(
529+
{dynType, &sec, offsetInSec, isAgainstSymbol, sym, addend, expr});
547530
}
548531
bool isNeeded() const override {
549532
return !relocs.empty() ||

lld/ELF/Target.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ void processArmCmseSymbols(Ctx &);
214214
template <class ELFT> uint32_t calcMipsEFlags(Ctx &);
215215
uint8_t getMipsFpAbiFlag(Ctx &, InputFile *file, uint8_t oldFlag,
216216
uint8_t newFlag);
217+
uint64_t getMipsPageAddr(uint64_t addr);
217218
bool isMipsN32Abi(Ctx &, const InputFile &f);
218219
bool isMicroMips(Ctx &);
219220
bool isMipsR6(Ctx &);

lld/ELF/Writer.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1573,8 +1573,8 @@ template <class ELFT> void Writer<ELFT>::finalizeAddressDependentContent() {
15731573
if (isInt<32>(reloc.sym->getVA(ctx, reloc.addend)))
15741574
return false;
15751575
part.relaDyn->addReloc({R_AARCH64_AUTH_RELATIVE, elem.inputSec,
1576-
reloc.offset, DynamicReloc::AddendOnly,
1577-
*reloc.sym, reloc.addend, R_ABS});
1576+
reloc.offset, false, *reloc.sym,
1577+
reloc.addend, R_ABS});
15781578
return true;
15791579
});
15801580
changed |= (it != part.relrAuthDyn->relocs.end());

0 commit comments

Comments
 (0)