diff --git a/lld/ELF/Arch/AArch64.cpp b/lld/ELF/Arch/AArch64.cpp --- a/lld/ELF/Arch/AArch64.cpp +++ b/lld/ELF/Arch/AArch64.cpp @@ -690,11 +690,11 @@ }; const uint8_t nopData[] = { 0x1f, 0x20, 0x03, 0xd5 }; // nop - // needsPltAddr indicates a non-ifunc canonical PLT entry whose address may + // needsCopy indicates a non-ifunc canonical PLT entry whose address may // escape to shared objects. isInIplt indicates a non-preemptible ifunc. Its // address may escape if referenced by a direct relocation. The condition is // conservative. - bool hasBti = btiHeader && (sym.needsPltAddr || sym.isInIplt); + bool hasBti = btiHeader && (sym.needsCopy || sym.isInIplt); if (hasBti) { memcpy(buf, btiData, sizeof(btiData)); buf += sizeof(btiData); diff --git a/lld/ELF/MapFile.cpp b/lld/ELF/MapFile.cpp --- a/lld/ELF/MapFile.cpp +++ b/lld/ELF/MapFile.cpp @@ -58,7 +58,7 @@ for (Symbol *b : file->getSymbols()) if (auto *dr = dyn_cast(b)) if (!dr->isSection() && dr->section && dr->section->isLive() && - (dr->file == file || dr->needsPltAddr || dr->section->bss)) + (dr->file == file || dr->needsCopy || dr->section->bss)) v.push_back(dr); return v; } diff --git a/lld/ELF/Relocations.cpp b/lld/ELF/Relocations.cpp --- a/lld/ELF/Relocations.cpp +++ b/lld/ELF/Relocations.cpp @@ -1615,12 +1615,16 @@ if (sym.needsCopy) { if (sym.isObject()) { addCopyRelSymbol(cast(sym)); + // needsCopy is cleared for sym and its aliases so that in later + // iterations aliases won't cause redundant copies. + assert(!sym.needsCopy); } else { assert(sym.isFunc() && sym.needsPlt); if (!sym.isDefined()) { replaceWithDefined( sym, in.plt, target->pltHeaderSize + target->pltEntrySize * sym.pltIndex, 0); + sym.needsCopy = true; if (config->emachine == EM_PPC) { // PPC32 canonical PLT entries are at the beginning of .glink cast(sym).value = in.plt->headerSize; @@ -1628,7 +1632,6 @@ cast(in.plt)->canonical_plts.push_back(&sym); } } - sym.needsPltAddr = true; } } }; diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -245,17 +245,12 @@ type(type), stOther(stOther), symbolKind(k), visibility(stOther & 3), isUsedInRegularObj(!file || file->kind() == InputFile::ObjKind), exportDynamic(isExportDynamic(k, visibility)), inDynamicList(false), - canInline(false), referenced(false), traced(false), needsPltAddr(false), - isInIplt(false), gotInIgot(false), isPreemptible(false), - used(!config->gcSections), needsTocRestore(false), scriptDefined(false), - needsGot(false), needsPlt(false), needsCopy(false), - hasDirectReloc(false) {} + canInline(false), referenced(false), traced(false), isInIplt(false), + gotInIgot(false), isPreemptible(false), used(!config->gcSections), + needsTocRestore(false), scriptDefined(false), needsGot(false), + needsPlt(false), needsCopy(false), hasDirectReloc(false) {} public: - // True the symbol should point to its PLT entry. - // For SharedSymbol only. - uint8_t needsPltAddr : 1; - // True if this symbol is in the Iplt sub-section of the Plt and the Igot // sub-section of the .got.plt or .got. uint8_t isInIplt : 1; diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -120,7 +120,7 @@ // field etc) do the same trick as compiler uses to mark microMIPS // for CPU - set the less-significant bit. if (config->emachine == EM_MIPS && isMicroMips() && - ((sym.stOther & STO_MIPS_MICROMIPS) || sym.needsPltAddr)) + ((sym.stOther & STO_MIPS_MICROMIPS) || sym.needsCopy)) va |= 1; if (d.isTls() && !config->relocatable) { diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -2175,7 +2175,8 @@ static uint32_t getSymSectionIndex(Symbol *sym) { if (getCommonSec(sym)) return SHN_COMMON; - if (!isa(sym) || sym->needsPltAddr) + assert(!(sym->needsCopy && sym->isObject())); + if (!isa(sym) || sym->needsCopy) return SHN_UNDEF; if (const OutputSection *os = sym->getOutputSection()) return os->sectionIndex >= SHN_LORESERVE ? (uint32_t)SHN_XINDEX @@ -2250,7 +2251,7 @@ for (SymbolTableEntry &ent : symbols) { Symbol *sym = ent.sym; - if (sym->isInPlt() && sym->needsPltAddr) + if (sym->isInPlt() && sym->needsCopy) eSym->st_other |= STO_MIPS_PLT; if (isMicroMips()) { // We already set the less-significant bit for symbols @@ -2261,7 +2262,7 @@ // like `objdump` will be able to deal with a correct // symbol position. if (sym->isDefined() && - ((sym->stOther & STO_MIPS_MICROMIPS) || sym->needsPltAddr)) { + ((sym->stOther & STO_MIPS_MICROMIPS) || sym->needsCopy)) { if (!strTabSec.isDynamic()) eSym->st_value &= ~1; eSym->st_other |= STO_MIPS_MICROMIPS;