forked from OSchip/llvm-project
[ELF] Merge Symbol::needs* into uint16_t flags. NFC
Split off from D133003 ([ELF] Parallelize relocation scanning) to make its diff smaller.
This commit is contained in:
parent
5758c824da
commit
bd16ffb389
|
@ -856,11 +856,11 @@ void AArch64BtiPac::writePlt(uint8_t *buf, const Symbol &sym,
|
||||||
};
|
};
|
||||||
const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
|
const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop
|
||||||
|
|
||||||
// needsCopy indicates a non-ifunc canonical PLT entry whose address may
|
// NEEDS_COPY indicates a non-ifunc canonical PLT entry whose address may
|
||||||
// escape to shared objects. isInIplt indicates a non-preemptible ifunc. Its
|
// escape to shared objects. isInIplt indicates a non-preemptible ifunc. Its
|
||||||
// address may escape if referenced by a direct relocation. The condition is
|
// address may escape if referenced by a direct relocation. The condition is
|
||||||
// conservative.
|
// conservative.
|
||||||
bool hasBti = btiHeader && (sym.needsCopy || sym.isInIplt);
|
bool hasBti = btiHeader && (sym.hasFlag(NEEDS_COPY) || sym.isInIplt);
|
||||||
if (hasBti) {
|
if (hasBti) {
|
||||||
memcpy(buf, btiData, sizeof(btiData));
|
memcpy(buf, btiData, sizeof(btiData));
|
||||||
buf += sizeof(btiData);
|
buf += sizeof(btiData);
|
||||||
|
|
|
@ -59,7 +59,7 @@ static std::vector<Defined *> getSymbols() {
|
||||||
for (Symbol *b : file->getSymbols())
|
for (Symbol *b : file->getSymbols())
|
||||||
if (auto *dr = dyn_cast<Defined>(b))
|
if (auto *dr = dyn_cast<Defined>(b))
|
||||||
if (!dr->isSection() && dr->section && dr->section->isLive() &&
|
if (!dr->isSection() && dr->section && dr->section->isLive() &&
|
||||||
(dr->file == file || dr->needsCopy || dr->section->bss))
|
(dr->file == file || dr->hasFlag(NEEDS_COPY) || dr->section->bss))
|
||||||
v.push_back(dr);
|
v.push_back(dr);
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
|
@ -306,7 +306,8 @@ static void replaceWithDefined(Symbol &sym, SectionBase &sec, uint64_t value,
|
||||||
sym.exportDynamic = true;
|
sym.exportDynamic = true;
|
||||||
sym.isUsedInRegularObj = true;
|
sym.isUsedInRegularObj = true;
|
||||||
// A copy relocated alias may need a GOT entry.
|
// A copy relocated alias may need a GOT entry.
|
||||||
sym.needsGot = old.needsGot;
|
if (old.hasFlag(NEEDS_GOT))
|
||||||
|
sym.setFlags(NEEDS_GOT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reserve space in .bss or .bss.rel.ro for copy relocation.
|
// Reserve space in .bss or .bss.rel.ro for copy relocation.
|
||||||
|
@ -1100,7 +1101,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
|
||||||
" against symbol '" + toString(*ss) +
|
" against symbol '" + toString(*ss) +
|
||||||
"'; recompile with -fPIC or remove '-z nocopyreloc'" +
|
"'; recompile with -fPIC or remove '-z nocopyreloc'" +
|
||||||
getLocation(*sec, sym, offset));
|
getLocation(*sec, sym, offset));
|
||||||
sym.needsCopy = true;
|
sym.setFlags(NEEDS_COPY);
|
||||||
}
|
}
|
||||||
sec->relocations.push_back({expr, type, offset, addend, &sym});
|
sec->relocations.push_back({expr, type, offset, addend, &sym});
|
||||||
return;
|
return;
|
||||||
|
@ -1138,8 +1139,7 @@ void RelocationScanner::processAux(RelExpr expr, RelType type, uint64_t offset,
|
||||||
errorOrWarn("symbol '" + toString(sym) +
|
errorOrWarn("symbol '" + toString(sym) +
|
||||||
"' cannot be preempted; recompile with -fPIE" +
|
"' cannot be preempted; recompile with -fPIE" +
|
||||||
getLocation(*sec, sym, offset));
|
getLocation(*sec, sym, offset));
|
||||||
sym.needsCopy = true;
|
sym.setFlags(NEEDS_COPY | NEEDS_PLT);
|
||||||
sym.needsPlt = true;
|
|
||||||
sec->relocations.push_back({expr, type, offset, addend, &sym});
|
sec->relocations.push_back({expr, type, offset, addend, &sym});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1193,7 +1193,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
|
||||||
R_TLSDESC_GOTPLT>(expr) &&
|
R_TLSDESC_GOTPLT>(expr) &&
|
||||||
config->shared) {
|
config->shared) {
|
||||||
if (expr != R_TLSDESC_CALL) {
|
if (expr != R_TLSDESC_CALL) {
|
||||||
sym.needsTlsDesc = true;
|
sym.setFlags(NEEDS_TLSDESC);
|
||||||
c.relocations.push_back({expr, type, offset, addend, &sym});
|
c.relocations.push_back({expr, type, offset, addend, &sym});
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -1247,7 +1247,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
|
||||||
// Local-Dynamic sequence where offset of tls variable relative to dynamic
|
// Local-Dynamic sequence where offset of tls variable relative to dynamic
|
||||||
// thread pointer is stored in the got. This cannot be relaxed to Local-Exec.
|
// thread pointer is stored in the got. This cannot be relaxed to Local-Exec.
|
||||||
if (expr == R_TLSLD_GOT_OFF) {
|
if (expr == R_TLSLD_GOT_OFF) {
|
||||||
sym.needsGotDtprel = true;
|
sym.setFlags(NEEDS_GOT_DTPREL);
|
||||||
c.relocations.push_back({expr, type, offset, addend, &sym});
|
c.relocations.push_back({expr, type, offset, addend, &sym});
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1255,7 +1255,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
|
||||||
if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,
|
if (oneof<R_AARCH64_TLSDESC_PAGE, R_TLSDESC, R_TLSDESC_CALL, R_TLSDESC_PC,
|
||||||
R_TLSDESC_GOTPLT, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC>(expr)) {
|
R_TLSDESC_GOTPLT, R_TLSGD_GOT, R_TLSGD_GOTPLT, R_TLSGD_PC>(expr)) {
|
||||||
if (!toExecRelax) {
|
if (!toExecRelax) {
|
||||||
sym.needsTlsGd = true;
|
sym.setFlags(NEEDS_TLSGD);
|
||||||
c.relocations.push_back({expr, type, offset, addend, &sym});
|
c.relocations.push_back({expr, type, offset, addend, &sym});
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1263,7 +1263,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
|
||||||
// Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
|
// Global-Dynamic relocs can be relaxed to Initial-Exec or Local-Exec
|
||||||
// depending on the symbol being locally defined or not.
|
// depending on the symbol being locally defined or not.
|
||||||
if (sym.isPreemptible) {
|
if (sym.isPreemptible) {
|
||||||
sym.needsTlsGdToIe = true;
|
sym.setFlags(NEEDS_TLSGD_TO_IE);
|
||||||
c.relocations.push_back(
|
c.relocations.push_back(
|
||||||
{target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_IE), type, offset,
|
{target->adjustTlsExpr(type, R_RELAX_TLS_GD_TO_IE), type, offset,
|
||||||
addend, &sym});
|
addend, &sym});
|
||||||
|
@ -1283,7 +1283,7 @@ static unsigned handleTlsRelocation(RelType type, Symbol &sym,
|
||||||
c.relocations.push_back(
|
c.relocations.push_back(
|
||||||
{R_RELAX_TLS_IE_TO_LE, type, offset, addend, &sym});
|
{R_RELAX_TLS_IE_TO_LE, type, offset, addend, &sym});
|
||||||
} else if (expr != R_TLSIE_HINT) {
|
} else if (expr != R_TLSIE_HINT) {
|
||||||
sym.needsTlsIe = true;
|
sym.setFlags(NEEDS_TLSIE);
|
||||||
// R_GOT needs a relative relocation for PIC on i386 and Hexagon.
|
// R_GOT needs a relative relocation for PIC on i386 and Hexagon.
|
||||||
if (expr == R_GOT && config->isPic && !target->usesOnlyLowPageBits(type))
|
if (expr == R_GOT && config->isPic && !target->usesOnlyLowPageBits(type))
|
||||||
addRelativeReloc(c, offset, sym, addend, expr, type);
|
addRelativeReloc(c, offset, sym, addend, expr, type);
|
||||||
|
@ -1438,12 +1438,12 @@ template <class ELFT, class RelTy> void RelocationScanner::scanOne(RelTy *&i) {
|
||||||
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
|
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
|
||||||
in.mipsGot->addEntry(*sec->file, sym, addend, expr);
|
in.mipsGot->addEntry(*sec->file, sym, addend, expr);
|
||||||
} else {
|
} else {
|
||||||
sym.needsGot = true;
|
sym.setFlags(NEEDS_GOT);
|
||||||
}
|
}
|
||||||
} else if (needsPlt(expr)) {
|
} else if (needsPlt(expr)) {
|
||||||
sym.needsPlt = true;
|
sym.setFlags(NEEDS_PLT);
|
||||||
} else if (LLVM_UNLIKELY(isIfunc)) {
|
} else if (LLVM_UNLIKELY(isIfunc)) {
|
||||||
sym.hasDirectReloc = true;
|
sym.setFlags(HAS_DIRECT_RELOC);
|
||||||
}
|
}
|
||||||
|
|
||||||
processAux(expr, type, offset, sym, addend);
|
processAux(expr, type, offset, sym, addend);
|
||||||
|
@ -1543,7 +1543,7 @@ template <class ELFT> void elf::scanRelocations() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool handleNonPreemptibleIfunc(Symbol &sym) {
|
static bool handleNonPreemptibleIfunc(Symbol &sym, uint16_t flags) {
|
||||||
// Handle a reference to a non-preemptible ifunc. These are special in a
|
// Handle a reference to a non-preemptible ifunc. These are special in a
|
||||||
// few ways:
|
// few ways:
|
||||||
//
|
//
|
||||||
|
@ -1587,7 +1587,7 @@ static bool handleNonPreemptibleIfunc(Symbol &sym) {
|
||||||
if (!sym.isGnuIFunc() || sym.isPreemptible || config->zIfuncNoplt)
|
if (!sym.isGnuIFunc() || sym.isPreemptible || config->zIfuncNoplt)
|
||||||
return false;
|
return false;
|
||||||
// Skip unreferenced non-preemptible ifunc.
|
// Skip unreferenced non-preemptible ifunc.
|
||||||
if (!(sym.needsGot || sym.needsPlt || sym.hasDirectReloc))
|
if (!(flags & (NEEDS_GOT | NEEDS_PLT | HAS_DIRECT_RELOC)))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
sym.isInIplt = true;
|
sym.isInIplt = true;
|
||||||
|
@ -1603,7 +1603,7 @@ static bool handleNonPreemptibleIfunc(Symbol &sym) {
|
||||||
sym.allocateAux();
|
sym.allocateAux();
|
||||||
symAux.back().pltIdx = symAux[directSym->auxIdx].pltIdx;
|
symAux.back().pltIdx = symAux[directSym->auxIdx].pltIdx;
|
||||||
|
|
||||||
if (sym.hasDirectReloc) {
|
if (flags & HAS_DIRECT_RELOC) {
|
||||||
// Change the value to the IPLT and redirect all references to it.
|
// Change the value to the IPLT and redirect all references to it.
|
||||||
auto &d = cast<Defined>(sym);
|
auto &d = cast<Defined>(sym);
|
||||||
d.section = in.iplt.get();
|
d.section = in.iplt.get();
|
||||||
|
@ -1613,9 +1613,9 @@ static bool handleNonPreemptibleIfunc(Symbol &sym) {
|
||||||
// don't try to call the PLT as if it were an ifunc resolver.
|
// don't try to call the PLT as if it were an ifunc resolver.
|
||||||
d.type = STT_FUNC;
|
d.type = STT_FUNC;
|
||||||
|
|
||||||
if (sym.needsGot)
|
if (flags & NEEDS_GOT)
|
||||||
addGotEntry(sym);
|
addGotEntry(sym);
|
||||||
} else if (sym.needsGot) {
|
} else if (flags & NEEDS_GOT) {
|
||||||
// Redirect GOT accesses to point to the Igot.
|
// Redirect GOT accesses to point to the Igot.
|
||||||
sym.gotInIgot = true;
|
sym.gotInIgot = true;
|
||||||
}
|
}
|
||||||
|
@ -1624,30 +1624,31 @@ static bool handleNonPreemptibleIfunc(Symbol &sym) {
|
||||||
|
|
||||||
void elf::postScanRelocations() {
|
void elf::postScanRelocations() {
|
||||||
auto fn = [](Symbol &sym) {
|
auto fn = [](Symbol &sym) {
|
||||||
if (handleNonPreemptibleIfunc(sym))
|
auto flags = sym.flags;
|
||||||
|
if (handleNonPreemptibleIfunc(sym, flags))
|
||||||
return;
|
return;
|
||||||
if (!sym.needsDynReloc())
|
if (!sym.needsDynReloc())
|
||||||
return;
|
return;
|
||||||
sym.allocateAux();
|
sym.allocateAux();
|
||||||
|
|
||||||
if (sym.needsGot)
|
if (flags & NEEDS_GOT)
|
||||||
addGotEntry(sym);
|
addGotEntry(sym);
|
||||||
if (sym.needsPlt)
|
if (flags & NEEDS_PLT)
|
||||||
addPltEntry(*in.plt, *in.gotPlt, *in.relaPlt, target->pltRel, sym);
|
addPltEntry(*in.plt, *in.gotPlt, *in.relaPlt, target->pltRel, sym);
|
||||||
if (sym.needsCopy) {
|
if (flags & NEEDS_COPY) {
|
||||||
if (sym.isObject()) {
|
if (sym.isObject()) {
|
||||||
invokeELFT(addCopyRelSymbol, cast<SharedSymbol>(sym));
|
invokeELFT(addCopyRelSymbol, cast<SharedSymbol>(sym));
|
||||||
// needsCopy is cleared for sym and its aliases so that in later
|
// NEEDS_COPY is cleared for sym and its aliases so that in
|
||||||
// iterations aliases won't cause redundant copies.
|
// later iterations aliases won't cause redundant copies.
|
||||||
assert(!sym.needsCopy);
|
assert(!sym.hasFlag(NEEDS_COPY));
|
||||||
} else {
|
} else {
|
||||||
assert(sym.isFunc() && sym.needsPlt);
|
assert(sym.isFunc() && sym.hasFlag(NEEDS_PLT));
|
||||||
if (!sym.isDefined()) {
|
if (!sym.isDefined()) {
|
||||||
replaceWithDefined(sym, *in.plt,
|
replaceWithDefined(sym, *in.plt,
|
||||||
target->pltHeaderSize +
|
target->pltHeaderSize +
|
||||||
target->pltEntrySize * sym.getPltIdx(),
|
target->pltEntrySize * sym.getPltIdx(),
|
||||||
0);
|
0);
|
||||||
sym.needsCopy = true;
|
sym.setFlags(NEEDS_COPY);
|
||||||
if (config->emachine == EM_PPC) {
|
if (config->emachine == EM_PPC) {
|
||||||
// PPC32 canonical PLT entries are at the beginning of .glink
|
// PPC32 canonical PLT entries are at the beginning of .glink
|
||||||
cast<Defined>(sym).value = in.plt->headerSize;
|
cast<Defined>(sym).value = in.plt->headerSize;
|
||||||
|
@ -1662,13 +1663,13 @@ void elf::postScanRelocations() {
|
||||||
return;
|
return;
|
||||||
bool isLocalInExecutable = !sym.isPreemptible && !config->shared;
|
bool isLocalInExecutable = !sym.isPreemptible && !config->shared;
|
||||||
|
|
||||||
if (sym.needsTlsDesc) {
|
if (flags & NEEDS_TLSDESC) {
|
||||||
in.got->addTlsDescEntry(sym);
|
in.got->addTlsDescEntry(sym);
|
||||||
mainPart->relaDyn->addAddendOnlyRelocIfNonPreemptible(
|
mainPart->relaDyn->addAddendOnlyRelocIfNonPreemptible(
|
||||||
target->tlsDescRel, *in.got, in.got->getTlsDescOffset(sym), sym,
|
target->tlsDescRel, *in.got, in.got->getTlsDescOffset(sym), sym,
|
||||||
target->tlsDescRel);
|
target->tlsDescRel);
|
||||||
}
|
}
|
||||||
if (sym.needsTlsGd) {
|
if (flags & NEEDS_TLSGD) {
|
||||||
in.got->addDynTlsEntry(sym);
|
in.got->addDynTlsEntry(sym);
|
||||||
uint64_t off = in.got->getGlobalDynOffset(sym);
|
uint64_t off = in.got->getGlobalDynOffset(sym);
|
||||||
if (isLocalInExecutable)
|
if (isLocalInExecutable)
|
||||||
|
@ -1689,18 +1690,18 @@ void elf::postScanRelocations() {
|
||||||
in.got->relocations.push_back(
|
in.got->relocations.push_back(
|
||||||
{R_ABS, target->tlsOffsetRel, offsetOff, 0, &sym});
|
{R_ABS, target->tlsOffsetRel, offsetOff, 0, &sym});
|
||||||
}
|
}
|
||||||
if (sym.needsTlsGdToIe) {
|
if (flags & NEEDS_TLSGD_TO_IE) {
|
||||||
in.got->addEntry(sym);
|
in.got->addEntry(sym);
|
||||||
mainPart->relaDyn->addSymbolReloc(target->tlsGotRel, *in.got,
|
mainPart->relaDyn->addSymbolReloc(target->tlsGotRel, *in.got,
|
||||||
sym.getGotOffset(), sym);
|
sym.getGotOffset(), sym);
|
||||||
}
|
}
|
||||||
if (sym.needsGotDtprel) {
|
if (flags & NEEDS_GOT_DTPREL) {
|
||||||
in.got->addEntry(sym);
|
in.got->addEntry(sym);
|
||||||
in.got->relocations.push_back(
|
in.got->relocations.push_back(
|
||||||
{R_ABS, target->tlsOffsetRel, sym.getGotOffset(), 0, &sym});
|
{R_ABS, target->tlsOffsetRel, sym.getGotOffset(), 0, &sym});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sym.needsTlsIe && !sym.needsTlsGdToIe)
|
if ((flags & NEEDS_TLSIE) && !(flags & NEEDS_TLSGD_TO_IE))
|
||||||
addTpOffsetGotEntry(sym);
|
addTpOffsetGotEntry(sym);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ static uint64_t getSymVA(const Symbol &sym, int64_t addend) {
|
||||||
// field etc) do the same trick as compiler uses to mark microMIPS
|
// field etc) do the same trick as compiler uses to mark microMIPS
|
||||||
// for CPU - set the less-significant bit.
|
// for CPU - set the less-significant bit.
|
||||||
if (config->emachine == EM_MIPS && isMicroMips() &&
|
if (config->emachine == EM_MIPS && isMicroMips() &&
|
||||||
((sym.stOther & STO_MIPS_MICROMIPS) || sym.needsCopy))
|
((sym.stOther & STO_MIPS_MICROMIPS) || sym.hasFlag(NEEDS_COPY)))
|
||||||
va |= 1;
|
va |= 1;
|
||||||
|
|
||||||
if (d.isTls() && !config->relocatable) {
|
if (d.isTls() && !config->relocatable) {
|
||||||
|
|
|
@ -39,6 +39,20 @@ class Undefined;
|
||||||
class LazyObject;
|
class LazyObject;
|
||||||
class InputFile;
|
class InputFile;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
NEEDS_GOT = 1 << 0,
|
||||||
|
NEEDS_PLT = 1 << 1,
|
||||||
|
HAS_DIRECT_RELOC = 1 << 2,
|
||||||
|
// True if this symbol needs a canonical PLT entry, or (during
|
||||||
|
// postScanRelocations) a copy relocation.
|
||||||
|
NEEDS_COPY = 1 << 3,
|
||||||
|
NEEDS_TLSDESC = 1 << 4,
|
||||||
|
NEEDS_TLSGD = 1 << 5,
|
||||||
|
NEEDS_TLSGD_TO_IE = 1 << 6,
|
||||||
|
NEEDS_GOT_DTPREL = 1 << 7,
|
||||||
|
NEEDS_TLSIE = 1 << 8,
|
||||||
|
};
|
||||||
|
|
||||||
// Some index properties of a symbol are stored separately in this auxiliary
|
// Some index properties of a symbol are stored separately in this auxiliary
|
||||||
// struct to decrease sizeof(SymbolUnion) in the majority of cases.
|
// struct to decrease sizeof(SymbolUnion) in the majority of cases.
|
||||||
struct SymbolAux {
|
struct SymbolAux {
|
||||||
|
@ -252,10 +266,7 @@ protected:
|
||||||
inDynamicList(false), referenced(false), referencedAfterWrap(false),
|
inDynamicList(false), referenced(false), referencedAfterWrap(false),
|
||||||
traced(false), hasVersionSuffix(false), isInIplt(false),
|
traced(false), hasVersionSuffix(false), isInIplt(false),
|
||||||
gotInIgot(false), folded(false), needsTocRestore(false),
|
gotInIgot(false), folded(false), needsTocRestore(false),
|
||||||
scriptDefined(false), dsoProtected(false), needsCopy(false),
|
scriptDefined(false), dsoProtected(false) {}
|
||||||
needsGot(false), needsPlt(false), needsTlsDesc(false),
|
|
||||||
needsTlsGd(false), needsTlsGdToIe(false), needsGotDtprel(false),
|
|
||||||
needsTlsIe(false), hasDirectReloc(false) {}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// True if this symbol is in the Iplt sub-section of the Plt and the Igot
|
// True if this symbol is in the Iplt sub-section of the Plt and the Igot
|
||||||
|
@ -282,20 +293,9 @@ public:
|
||||||
// True if defined in a DSO as protected visibility.
|
// True if defined in a DSO as protected visibility.
|
||||||
uint8_t dsoProtected : 1;
|
uint8_t dsoProtected : 1;
|
||||||
|
|
||||||
// True if this symbol needs a canonical PLT entry, or (during
|
|
||||||
// postScanRelocations) a copy relocation.
|
|
||||||
uint8_t needsCopy : 1;
|
|
||||||
|
|
||||||
// Temporary flags used to communicate which symbol entries need PLT and GOT
|
// Temporary flags used to communicate which symbol entries need PLT and GOT
|
||||||
// entries during postScanRelocations();
|
// entries during postScanRelocations();
|
||||||
uint8_t needsGot : 1;
|
uint16_t flags = 0;
|
||||||
uint8_t needsPlt : 1;
|
|
||||||
uint8_t needsTlsDesc : 1;
|
|
||||||
uint8_t needsTlsGd : 1;
|
|
||||||
uint8_t needsTlsGdToIe : 1;
|
|
||||||
uint8_t needsGotDtprel : 1;
|
|
||||||
uint8_t needsTlsIe : 1;
|
|
||||||
uint8_t hasDirectReloc : 1;
|
|
||||||
|
|
||||||
// A symAux index used to access GOT/PLT entry indexes. This is allocated in
|
// A symAux index used to access GOT/PLT entry indexes. This is allocated in
|
||||||
// postScanRelocations().
|
// postScanRelocations().
|
||||||
|
@ -308,9 +308,18 @@ public:
|
||||||
// Version definition index.
|
// Version definition index.
|
||||||
uint16_t versionId;
|
uint16_t versionId;
|
||||||
|
|
||||||
|
void setFlags(uint16_t bits) {
|
||||||
|
flags |= bits;
|
||||||
|
}
|
||||||
|
bool hasFlag(uint16_t bit) const {
|
||||||
|
assert(bit && (bit & (bit - 1)) == 0 && "bit must be a power of 2");
|
||||||
|
return flags & bit;
|
||||||
|
}
|
||||||
|
|
||||||
bool needsDynReloc() const {
|
bool needsDynReloc() const {
|
||||||
return needsCopy || needsGot || needsPlt || needsTlsDesc || needsTlsGd ||
|
return flags &
|
||||||
needsTlsGdToIe || needsGotDtprel || needsTlsIe;
|
(NEEDS_COPY | NEEDS_GOT | NEEDS_PLT | NEEDS_TLSDESC | NEEDS_TLSGD |
|
||||||
|
NEEDS_TLSGD_TO_IE | NEEDS_GOT_DTPREL | NEEDS_TLSIE);
|
||||||
}
|
}
|
||||||
void allocateAux() {
|
void allocateAux() {
|
||||||
assert(auxIdx == uint32_t(-1));
|
assert(auxIdx == uint32_t(-1));
|
||||||
|
|
|
@ -2175,8 +2175,8 @@ static BssSection *getCommonSec(Symbol *sym) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static uint32_t getSymSectionIndex(Symbol *sym) {
|
static uint32_t getSymSectionIndex(Symbol *sym) {
|
||||||
assert(!(sym->needsCopy && sym->isObject()));
|
assert(!(sym->hasFlag(NEEDS_COPY) && sym->isObject()));
|
||||||
if (!isa<Defined>(sym) || sym->needsCopy)
|
if (!isa<Defined>(sym) || sym->hasFlag(NEEDS_COPY))
|
||||||
return SHN_UNDEF;
|
return SHN_UNDEF;
|
||||||
if (const OutputSection *os = sym->getOutputSection())
|
if (const OutputSection *os = sym->getOutputSection())
|
||||||
return os->sectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
|
return os->sectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX
|
||||||
|
@ -2236,7 +2236,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
|
||||||
|
|
||||||
for (SymbolTableEntry &ent : symbols) {
|
for (SymbolTableEntry &ent : symbols) {
|
||||||
Symbol *sym = ent.sym;
|
Symbol *sym = ent.sym;
|
||||||
if (sym->isInPlt() && sym->needsCopy)
|
if (sym->isInPlt() && sym->hasFlag(NEEDS_COPY))
|
||||||
eSym->st_other |= STO_MIPS_PLT;
|
eSym->st_other |= STO_MIPS_PLT;
|
||||||
if (isMicroMips()) {
|
if (isMicroMips()) {
|
||||||
// We already set the less-significant bit for symbols
|
// We already set the less-significant bit for symbols
|
||||||
|
@ -2247,7 +2247,7 @@ template <class ELFT> void SymbolTableSection<ELFT>::writeTo(uint8_t *buf) {
|
||||||
// like `objdump` will be able to deal with a correct
|
// like `objdump` will be able to deal with a correct
|
||||||
// symbol position.
|
// symbol position.
|
||||||
if (sym->isDefined() &&
|
if (sym->isDefined() &&
|
||||||
((sym->stOther & STO_MIPS_MICROMIPS) || sym->needsCopy)) {
|
((sym->stOther & STO_MIPS_MICROMIPS) || sym->hasFlag(NEEDS_COPY))) {
|
||||||
if (!strTabSec.isDynamic())
|
if (!strTabSec.isDynamic())
|
||||||
eSym->st_value &= ~1;
|
eSym->st_value &= ~1;
|
||||||
eSym->st_other |= STO_MIPS_MICROMIPS;
|
eSym->st_other |= STO_MIPS_MICROMIPS;
|
||||||
|
|
Loading…
Reference in New Issue