Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -1338,9 +1338,8 @@ Bss->File = S->File; Bss->Live = !Config->GcSections; InputSections.push_back(Bss); - replaceSymbol(S, Defined{S->File, S->getName(), S->Binding, S->StOther, - S->Type, - /*Value=*/0, S->Size, Bss}); + S->replace(Defined{S->File, S->getName(), S->Binding, S->StOther, S->Type, + /*Value=*/0, S->Size, Bss}); } } @@ -1355,8 +1354,7 @@ continue; bool Used = S->Used; - replaceSymbol( - S, Undefined{nullptr, S->getName(), STB_WEAK, S->StOther, S->Type}); + S->replace(Undefined{nullptr, S->getName(), STB_WEAK, S->StOther, S->Type}); S->Used = Used; } } Index: lld/trunk/ELF/LTO.cpp =================================================================== --- lld/trunk/ELF/LTO.cpp +++ lld/trunk/ELF/LTO.cpp @@ -196,8 +196,8 @@ !(DR->Section == nullptr && (!Sym->File || Sym->File->isElf())); if (R.Prevailing) - replaceSymbol(Sym, Undefined{nullptr, Sym->getName(), STB_GLOBAL, - STV_DEFAULT, Sym->Type}); + Sym->replace(Undefined{nullptr, Sym->getName(), STB_GLOBAL, STV_DEFAULT, + Sym->Type}); // We tell LTO to not apply interprocedural optimization for wrapped // (with --wrap) symbols because otherwise LTO would inline them while Index: lld/trunk/ELF/LinkerScript.cpp =================================================================== --- lld/trunk/ELF/LinkerScript.cpp +++ lld/trunk/ELF/LinkerScript.cpp @@ -188,7 +188,7 @@ Symbol *Sym = Symtab->insert(Cmd->Name); mergeSymbolProperties(Sym, New); - replaceSymbol(Sym, New); + Sym->replace(New); Cmd->Sym = cast(Sym); } @@ -205,7 +205,7 @@ // We can't calculate final value right now. Symbol *Sym = Symtab->insert(Cmd->Name); mergeSymbolProperties(Sym, New); - replaceSymbol(Sym, New); + Sym->replace(New); Cmd->Sym = cast(Sym); Cmd->Provide = false; Index: lld/trunk/ELF/Relocations.cpp =================================================================== --- lld/trunk/ELF/Relocations.cpp +++ lld/trunk/ELF/Relocations.cpp @@ -530,8 +530,8 @@ uint64_t Size) { Symbol Old = Sym; - replaceSymbol(&Sym, Defined{Sym.File, Sym.getName(), Sym.Binding, Sym.StOther, - Sym.Type, Value, Size, Sec}); + Sym.replace(Defined{Sym.File, Sym.getName(), Sym.Binding, Sym.StOther, + Sym.Type, Value, Size, Sec}); Sym.PltIndex = Old.PltIndex; Sym.GotIndex = Old.GotIndex; Index: lld/trunk/ELF/SymbolTable.cpp =================================================================== --- lld/trunk/ELF/SymbolTable.cpp +++ lld/trunk/ELF/SymbolTable.cpp @@ -136,7 +136,7 @@ // An undefined symbol with non default visibility must be satisfied // in the same DSO. if (Old->isShared() && New.Visibility != STV_DEFAULT) { - replaceSymbol(Old, New); + Old->replace(New); return; } @@ -284,7 +284,7 @@ return; if (Cmp > 0) { - replaceSymbol(Old, New); + Old->replace(New); return; } @@ -335,7 +335,7 @@ static void addDefined(Symbol *Old, const Defined &New) { int Cmp = compare(Old, &New); if (Cmp > 0) - replaceSymbol(Old, New); + Old->replace(New); else if (Cmp == 0) reportDuplicate(Old, New.File, dyn_cast_or_null(New.Section), New.Value); @@ -346,7 +346,7 @@ // An undefined symbol with non default visibility must be satisfied // in the same DSO. uint8_t Binding = Old->Binding; - replaceSymbol(Old, New); + Old->replace(New); Old->Binding = Binding; } } @@ -368,7 +368,7 @@ // Symbols.h for the details. if (Old->isWeak()) { uint8_t Type = Old->Type; - replaceSymbol(Old, New); + Old->replace(New); Old->Type = Type; Old->Binding = STB_WEAK; return; @@ -578,7 +578,7 @@ mergeSymbolProperties(Old, New); if (Old->isPlaceholder()) { - replaceSymbol(Old, New); + Old->replace(New); return; } Index: lld/trunk/ELF/Symbols.h =================================================================== --- lld/trunk/ELF/Symbols.h +++ lld/trunk/ELF/Symbols.h @@ -83,7 +83,7 @@ // An index into the .branch_lt section on PPC64. uint16_t PPC64BranchltIndex = -1; - // Symbol binding. This is not overwritten by replaceSymbol to track + // Symbol binding. This is not overwritten by replace() to track // changes during resolution. In particular: // - An undefined weak is still weak when it resolves to a shared library. // - An undefined weak will not fetch archive members, but we have to @@ -120,6 +120,8 @@ // True if this symbol is specified by --trace-symbol option. unsigned Traced : 1; + inline void replace(const Symbol &New); + bool includeInDynsym() const; uint8_t computeBinding() const; bool isWeak() const { return Binding == llvm::ELF::STB_WEAK; } @@ -179,6 +181,8 @@ return Config->Shared || Config->ExportDynamic; } + inline size_t getSymbolSize() const; + protected: Symbol(Kind K, InputFile *File, StringRefZ Name, uint8_t Binding, uint8_t StOther, uint8_t Type) @@ -427,27 +431,30 @@ void printTraceSymbol(Symbol *Sym); -static size_t getSymbolSize(const Symbol &Sym) { - switch (Sym.kind()) { - case Symbol::CommonKind: +size_t Symbol::getSymbolSize() const { + switch (kind()) { + case CommonKind: return sizeof(CommonSymbol); - case Symbol::DefinedKind: + case DefinedKind: return sizeof(Defined); - case Symbol::LazyArchiveKind: + case LazyArchiveKind: return sizeof(LazyArchive); - case Symbol::LazyObjectKind: + case LazyObjectKind: return sizeof(LazyObject); - case Symbol::SharedKind: + case SharedKind: return sizeof(SharedSymbol); - case Symbol::UndefinedKind: + case UndefinedKind: return sizeof(Undefined); - case Symbol::PlaceholderKind: + case PlaceholderKind: return sizeof(Symbol); } llvm_unreachable("unknown symbol kind"); } -inline void replaceSymbol(Symbol *Sym, const Symbol &New) { +// replace() replaces "this" object with a given symbol by memcpy'ing +// it over to "this". This function is called as a result of name +// resolution, e.g. to replace an undefind symbol with a defined symbol. +void Symbol::replace(const Symbol &New) { using llvm::ELF::STT_TLS; // Symbols representing thread-local variables must be referenced by @@ -455,31 +462,30 @@ // non-TLS relocations, so there's a clear distinction between TLS // and non-TLS symbols. It is an error if the same symbol is defined // as a TLS symbol in one file and as a non-TLS symbol in other file. - if (Sym->SymbolKind != Symbol::PlaceholderKind && !Sym->isLazy() && - !New.isLazy()) { - bool TlsMismatch = (Sym->Type == STT_TLS && New.Type != STT_TLS) || - (Sym->Type != STT_TLS && New.Type == STT_TLS); + if (SymbolKind != PlaceholderKind && !isLazy() && !New.isLazy()) { + bool TlsMismatch = (Type == STT_TLS && New.Type != STT_TLS) || + (Type != STT_TLS && New.Type == STT_TLS); if (TlsMismatch) - error("TLS attribute mismatch: " + toString(*Sym) + "\n>>> defined in " + - toString(New.File) + "\n>>> defined in " + toString(Sym->File)); + error("TLS attribute mismatch: " + toString(*this) + "\n>>> defined in " + + toString(New.File) + "\n>>> defined in " + toString(File)); } - Symbol Old = *Sym; - memcpy(Sym, &New, getSymbolSize(New)); + Symbol Old = *this; + memcpy(this, &New, New.getSymbolSize()); - Sym->VersionId = Old.VersionId; - Sym->Visibility = Old.Visibility; - Sym->IsUsedInRegularObj = Old.IsUsedInRegularObj; - Sym->ExportDynamic = Old.ExportDynamic; - Sym->CanInline = Old.CanInline; - Sym->Traced = Old.Traced; - Sym->IsPreemptible = Old.IsPreemptible; - Sym->ScriptDefined = Old.ScriptDefined; + VersionId = Old.VersionId; + Visibility = Old.Visibility; + IsUsedInRegularObj = Old.IsUsedInRegularObj; + ExportDynamic = Old.ExportDynamic; + CanInline = Old.CanInline; + Traced = Old.Traced; + IsPreemptible = Old.IsPreemptible; + ScriptDefined = Old.ScriptDefined; // Print out a log message if --trace-symbol was specified. // This is for debugging. - if (Sym->Traced) - printTraceSymbol(Sym); + if (Traced) + printTraceSymbol(this); } void maybeWarnUnorderableSymbol(const Symbol *Sym);