diff options
-rw-r--r-- | lld/ELF/InputFiles.cpp | 19 | ||||
-rw-r--r-- | lld/ELF/LTO.cpp | 4 | ||||
-rw-r--r-- | lld/ELF/LinkerScript.cpp | 3 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 59 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.h | 5 | ||||
-rw-r--r-- | lld/ELF/Symbols.h | 29 | ||||
-rw-r--r-- | lld/ELF/SyntheticSections.cpp | 4 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 8 |
8 files changed, 61 insertions, 70 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 1a5a09c8cdd..c8ff74a7101 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -591,18 +591,16 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) { StringRefZ Name = this->StringTable.data() + Sym->st_name; if (Sym->st_shndx == SHN_UNDEF) - return make<Undefined>(Name, /*IsLocal=*/true, StOther, Type); + return make<Undefined>(Name, Binding, StOther, Type); - return make<Defined>(Name, /*IsLocal=*/true, StOther, Type, Value, Size, - Sec); + return make<Defined>(Name, Binding, StOther, Type, Value, Size, Sec); } StringRef Name = check(Sym->getName(this->StringTable), toString(this)); switch (Sym->st_shndx) { case SHN_UNDEF: - return Symtab->addUndefined<ELFT>(Name, /*IsLocal=*/false, Binding, StOther, - Type, + return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type, /*CanOmitFromDynSym=*/false, this); case SHN_COMMON: if (Value == 0 || Value >= UINT32_MAX) @@ -618,8 +616,7 @@ template <class ELFT> Symbol *ObjFile<ELFT>::createSymbol(const Elf_Sym *Sym) { case STB_WEAK: case STB_GNU_UNIQUE: if (Sec == &InputSection::Discarded) - return Symtab->addUndefined<ELFT>(Name, /*IsLocal=*/false, Binding, - StOther, Type, + return Symtab->addUndefined<ELFT>(Name, Binding, StOther, Type, /*CanOmitFromDynSym=*/false, this); return Symtab->addRegular<ELFT>(Name, StOther, Type, Value, Size, Binding, Sec, this); @@ -907,12 +904,12 @@ static Symbol *createBitcodeSymbol(const std::vector<bool> &KeptComdats, int C = ObjSym.getComdatIndex(); if (C != -1 && !KeptComdats[C]) - return Symtab->addUndefined<ELFT>(NameRef, /*IsLocal=*/false, Binding, - Visibility, Type, CanOmitFromDynSym, F); + return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type, + CanOmitFromDynSym, F); if (ObjSym.isUndefined()) - return Symtab->addUndefined<ELFT>(NameRef, /*IsLocal=*/false, Binding, - Visibility, Type, CanOmitFromDynSym, F); + return Symtab->addUndefined<ELFT>(NameRef, Binding, Visibility, Type, + CanOmitFromDynSym, F); if (ObjSym.isCommon()) return Symtab->addCommon(NameRef, ObjSym.getCommonSize(), diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index f6f61fa0f0d..7ff8b1882da 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -119,8 +119,8 @@ BitcodeCompiler::BitcodeCompiler() : LTOObj(createLTO()) { BitcodeCompiler::~BitcodeCompiler() = default; static void undefine(Symbol *S) { - replaceSymbol<Undefined>(S, nullptr, S->getName(), /*IsLocal=*/false, - STV_DEFAULT, S->Type); + replaceSymbol<Undefined>(S, nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT, + S->Type); } void BitcodeCompiler::add(BitcodeFile &F) { diff --git a/lld/ELF/LinkerScript.cpp b/lld/ELF/LinkerScript.cpp index 9434bcef1c3..0f4b0f978e7 100644 --- a/lld/ELF/LinkerScript.cpp +++ b/lld/ELF/LinkerScript.cpp @@ -132,7 +132,6 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) { std::tie(Sym, std::ignore) = Symtab->insert(Cmd->Name, /*Type*/ 0, Visibility, /*CanOmitFromDynSym*/ false, /*File*/ nullptr); - Sym->Binding = STB_GLOBAL; ExprValue Value = Cmd->Expression(); SectionBase *Sec = Value.isAbsolute() ? nullptr : Value.Sec; @@ -149,7 +148,7 @@ void LinkerScript::addSymbol(SymbolAssignment *Cmd) { // write expressions like this: `alignment = 16; . = ALIGN(., alignment)`. uint64_t SymValue = Value.Sec ? 0 : Value.getValue(); - replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, /*IsLocal=*/false, Visibility, + replaceSymbol<Defined>(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, SymValue, 0, Sec); Cmd->Sym = cast<Defined>(Sym); } diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 8a3632d94c5..c1bd2d1dc1d 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -236,7 +236,6 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name) { if (IsNew) { Sym = (Symbol *)make<SymbolUnion>(); Sym->InVersionScript = false; - Sym->Binding = STB_WEAK; Sym->Visibility = STV_DEFAULT; Sym->IsUsedInRegularObj = false; Sym->ExportDynamic = false; @@ -279,7 +278,7 @@ std::pair<Symbol *, bool> SymbolTable::insert(StringRef Name, uint8_t Type, } template <class ELFT> Symbol *SymbolTable::addUndefined(StringRef Name) { - return addUndefined<ELFT>(Name, /*IsLocal=*/false, STB_GLOBAL, STV_DEFAULT, + return addUndefined<ELFT>(Name, STB_GLOBAL, STV_DEFAULT, /*Type*/ 0, /*CanOmitFromDynSym*/ false, /*File*/ nullptr); } @@ -287,7 +286,7 @@ template <class ELFT> Symbol *SymbolTable::addUndefined(StringRef Name) { static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; } template <class ELFT> -Symbol *SymbolTable::addUndefined(StringRef Name, bool IsLocal, uint8_t Binding, +Symbol *SymbolTable::addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther, uint8_t Type, bool CanOmitFromDynSym, InputFile *File) { Symbol *S; @@ -298,8 +297,7 @@ Symbol *SymbolTable::addUndefined(StringRef Name, bool IsLocal, uint8_t Binding, // An undefined symbol with non default visibility must be satisfied // in the same DSO. if (WasInserted || (isa<SharedSymbol>(S) && Visibility != STV_DEFAULT)) { - S->Binding = Binding; - replaceSymbol<Undefined>(S, File, Name, IsLocal, StOther, Type); + replaceSymbol<Undefined>(S, File, Name, Binding, StOther, Type); return S; } if (Binding != STB_WEAK) { @@ -311,10 +309,12 @@ Symbol *SymbolTable::addUndefined(StringRef Name, bool IsLocal, uint8_t Binding, if (auto *L = dyn_cast<Lazy>(S)) { // An undefined weak will not fetch archive members. See comment on Lazy in // Symbols.h for the details. - if (S->isWeak()) + if (Binding == STB_WEAK) { L->Type = Type; - else if (InputFile *F = L->fetch()) + L->Binding = STB_WEAK; + } else if (InputFile *F = L->fetch()) { addFile<ELFT>(F); + } } return S; } @@ -359,11 +359,8 @@ static int compareDefined(Symbol *S, bool WasInserted, uint8_t Binding, static int compareDefinedNonCommon(Symbol *S, bool WasInserted, uint8_t Binding, bool IsAbsolute, uint64_t Value, StringRef Name) { - if (int Cmp = compareDefined(S, WasInserted, Binding, Name)) { - if (Cmp > 0) - S->Binding = Binding; + if (int Cmp = compareDefined(S, WasInserted, Binding, Name)) return Cmp; - } if (auto *R = dyn_cast<Defined>(S)) { if (R->Section && isa<BssSection>(R->Section)) { // Non-common symbols take precedence over common symbols. @@ -392,9 +389,7 @@ Symbol *SymbolTable::addCommon(StringRef N, uint64_t Size, uint32_t Alignment, Bss->Live = !Config->GcSections; InputSections.push_back(Bss); - S->Binding = Binding; - replaceSymbol<Defined>(S, File, N, /*IsLocal=*/false, StOther, Type, 0, - Size, Bss); + replaceSymbol<Defined>(S, File, N, Binding, StOther, Type, 0, Size, Bss); } else if (Cmp == 0) { auto *D = cast<Defined>(S); auto *Bss = dyn_cast_or_null<BssSection>(D->Section); @@ -473,8 +468,8 @@ Symbol *SymbolTable::addRegular(StringRef Name, uint8_t StOther, uint8_t Type, int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr, Value, Name); if (Cmp > 0) - replaceSymbol<Defined>(S, File, Name, /*IsLocal=*/false, StOther, Type, - Value, Size, Section); + replaceSymbol<Defined>(S, File, Name, Binding, StOther, Type, Value, Size, + Section); else if (Cmp == 0) reportDuplicate<ELFT>(S, dyn_cast_or_null<InputSectionBase>(Section), Value); @@ -500,10 +495,14 @@ void SymbolTable::addShared(StringRef Name, SharedFile<ELFT> *File, // in the same DSO. if (WasInserted || ((S->isUndefined() || S->isLazy()) && S->getVisibility() == STV_DEFAULT)) { + uint8_t Binding = S->Binding; replaceSymbol<SharedSymbol>(S, File, Name, Sym.st_other, Sym.getType(), Sym.st_value, Sym.st_size, Alignment, Verdef); - if (!S->isWeak()) - File->IsUsed = true; + if (!WasInserted) { + S->Binding = Binding; + if (!S->isWeak()) + File->IsUsed = true; + } } } @@ -517,8 +516,7 @@ Symbol *SymbolTable::addBitcode(StringRef Name, uint8_t Binding, int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, /*IsAbs*/ false, /*Value*/ 0, Name); if (Cmp > 0) - replaceSymbol<Defined>(S, F, Name, /*IsLocal=*/false, StOther, Type, 0, 0, - nullptr); + replaceSymbol<Defined>(S, F, Name, Binding, StOther, Type, 0, 0, nullptr); else if (Cmp == 0) reportDuplicate(S, F); return S; @@ -550,6 +548,7 @@ Symbol *SymbolTable::addLazyArchive(StringRef Name, ArchiveFile *F, // Symbols.h for the details. if (S->isWeak()) { replaceSymbol<LazyArchive>(S, F, Sym, S->Type); + S->Binding = STB_WEAK; return S; } std::pair<MemoryBufferRef, uint64_t> MBInfo = F->getMember(&Sym); @@ -784,18 +783,14 @@ template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef); template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef); template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef); -template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, bool, uint8_t, - uint8_t, uint8_t, bool, - InputFile *); -template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, bool, uint8_t, - uint8_t, uint8_t, bool, - InputFile *); -template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef, bool, uint8_t, - uint8_t, uint8_t, bool, - InputFile *); -template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef, bool, uint8_t, - uint8_t, uint8_t, bool, - InputFile *); +template Symbol *SymbolTable::addUndefined<ELF32LE>(StringRef, uint8_t, uint8_t, + uint8_t, bool, InputFile *); +template Symbol *SymbolTable::addUndefined<ELF32BE>(StringRef, uint8_t, uint8_t, + uint8_t, bool, InputFile *); +template Symbol *SymbolTable::addUndefined<ELF64LE>(StringRef, uint8_t, uint8_t, + uint8_t, bool, InputFile *); +template Symbol *SymbolTable::addUndefined<ELF64BE>(StringRef, uint8_t, uint8_t, + uint8_t, bool, InputFile *); template void SymbolTable::addCombinedLTOObject<ELF32LE>(); template void SymbolTable::addCombinedLTOObject<ELF32BE>(); diff --git a/lld/ELF/SymbolTable.h b/lld/ELF/SymbolTable.h index bfab5a5c9c4..cb80e31e4b7 100644 --- a/lld/ELF/SymbolTable.h +++ b/lld/ELF/SymbolTable.h @@ -47,9 +47,8 @@ public: template <class ELFT> Symbol *addUndefined(StringRef Name); template <class ELFT> - Symbol *addUndefined(StringRef Name, bool IsLocal, uint8_t Binding, - uint8_t StOther, uint8_t Type, bool CanOmitFromDynSym, - InputFile *File); + Symbol *addUndefined(StringRef Name, uint8_t Binding, uint8_t StOther, + uint8_t Type, bool CanOmitFromDynSym, InputFile *File); template <class ELFT> Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size, uint8_t Binding, diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index cd9a0b818e1..4eab44e2816 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -94,7 +94,7 @@ public: bool isUndefined() const { return SymbolKind == UndefinedKind; } bool isDefined() const { return SymbolKind == DefinedKind; } bool isShared() const { return SymbolKind == SharedKind; } - bool isLocal() const { return IsLocal; } + bool isLocal() const { return Binding == llvm::ELF::STB_LOCAL; } bool isLazy() const { return SymbolKind == LazyArchiveKind || SymbolKind == LazyObjectKind; @@ -130,17 +130,15 @@ public: uint32_t GlobalDynIndex = -1; protected: - Symbol(Kind K, StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type) - : SymbolKind(K), IsLocal(IsLocal), NeedsPltAddr(false), + Symbol(Kind K, StringRefZ Name, uint8_t Binding, uint8_t StOther, + uint8_t Type) + : Binding(Binding), SymbolKind(K), NeedsPltAddr(false), IsInGlobalMipsGot(false), Is32BitMipsGot(false), IsInIplt(false), IsInIgot(false), IsPreemptible(false), Type(Type), StOther(StOther), Name(Name) {} const unsigned SymbolKind : 8; - // True if this is a local symbol. - unsigned IsLocal : 1; - public: // True the symbol should point to its PLT entry. // For SharedSymbol only. @@ -184,10 +182,12 @@ protected: // Represents a symbol that is defined in the current output file. class Defined : public Symbol { public: - Defined(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type, + Defined(StringRefZ Name, uint8_t Binding, uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size, SectionBase *Section) - : Symbol(DefinedKind, Name, IsLocal, StOther, Type), Value(Value), - Size(Size), Section(Section) {} + : Symbol(DefinedKind, Name, Binding, StOther, Type), Value(Value), + Size(Size), Section(Section) { + this->Binding = Binding; + } static bool classof(const Symbol *S) { return S->isDefined(); } @@ -198,8 +198,10 @@ public: class Undefined : public Symbol { public: - Undefined(StringRefZ Name, bool IsLocal, uint8_t StOther, uint8_t Type) - : Symbol(UndefinedKind, Name, IsLocal, StOther, Type) {} + Undefined(StringRefZ Name, uint8_t Binding, uint8_t StOther, uint8_t Type) + : Symbol(UndefinedKind, Name, Binding, StOther, Type) { + this->Binding = Binding; + } static bool classof(const Symbol *S) { return S->kind() == UndefinedKind; } }; @@ -210,7 +212,7 @@ public: SharedSymbol(StringRef Name, uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size, uint32_t Alignment, const void *Verdef) - : Symbol(SharedKind, Name, /*IsLocal=*/false, StOther, Type), + : Symbol(SharedKind, Name, llvm::ELF::STB_WEAK, StOther, Type), Verdef(Verdef), Value(Value), Size(Size), Alignment(Alignment) { // GNU ifunc is a mechanism to allow user-supplied functions to // resolve PLT slot values at load-time. This is contrary to the @@ -266,7 +268,7 @@ public: protected: Lazy(Kind K, StringRef Name, uint8_t Type) - : Symbol(K, Name, /*IsLocal=*/false, llvm::ELF::STV_DEFAULT, Type) {} + : Symbol(K, Name, llvm::ELF::STB_GLOBAL, llvm::ELF::STV_DEFAULT, Type) {} }; // This class represents a symbol defined in an archive file. It is @@ -354,7 +356,6 @@ void replaceSymbol(Symbol *S, InputFile *File, ArgT &&... Arg) { new (S) T(std::forward<ArgT>(Arg)...); S->File = File; - S->Binding = Sym.Binding; S->VersionId = Sym.VersionId; S->Visibility = Sym.Visibility; S->IsUsedInRegularObj = Sym.IsUsedInRegularObj; diff --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp index e446667d110..74b446f913e 100644 --- a/lld/ELF/SyntheticSections.cpp +++ b/lld/ELF/SyntheticSections.cpp @@ -275,8 +275,8 @@ InputSection *elf::createInterpSection() { Symbol *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, uint64_t Size, InputSectionBase *Section) { - auto *S = make<Defined>(Name, /*IsLocal*/ true, STV_DEFAULT, Type, Value, - Size, Section); + auto *S = + make<Defined>(Name, STB_LOCAL, STV_DEFAULT, Type, Value, Size, Section); if (InX::SymTab) InX::SymTab->addSymbol(S); return S; diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 95921695d18..f44185812eb 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -500,7 +500,7 @@ template <class ELFT> void Writer<ELFT>::addSectionSymbols() { if (isa<SyntheticSection>(IS) && !(IS->Flags & SHF_MERGE)) continue; - auto *Sym = make<Defined>("", /*IsLocal=*/true, /*StOther=*/0, STT_SECTION, + auto *Sym = make<Defined>("", STB_LOCAL, /*StOther=*/0, STT_SECTION, /*Value=*/0, /*Size=*/0, IS); InX::SymTab->addSymbol(Sym); } @@ -780,13 +780,13 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() { // to GOT. Default offset is 0x7ff0. // See "Global Data Symbols" in Chapter 6 in the following document: // ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf - ElfSym::MipsGp = Symtab->addAbsolute<ELFT>("_gp", STV_HIDDEN, STB_LOCAL); + ElfSym::MipsGp = Symtab->addAbsolute<ELFT>("_gp", STV_HIDDEN, STB_GLOBAL); // On MIPS O32 ABI, _gp_disp is a magic symbol designates offset between // start of function and 'gp' pointer into GOT. if (Symtab->find("_gp_disp")) ElfSym::MipsGpDisp = - Symtab->addAbsolute<ELFT>("_gp_disp", STV_HIDDEN, STB_LOCAL); + Symtab->addAbsolute<ELFT>("_gp_disp", STV_HIDDEN, STB_GLOBAL); // The __gnu_local_gp is a magic symbol equal to the current value of 'gp' // pointer. This symbol is used in the code generated by .cpload pseudo-op @@ -794,7 +794,7 @@ template <class ELFT> void Writer<ELFT>::addReservedSymbols() { // https://sourceware.org/ml/binutils/2004-12/msg00094.html if (Symtab->find("__gnu_local_gp")) ElfSym::MipsLocalGp = - Symtab->addAbsolute<ELFT>("__gnu_local_gp", STV_HIDDEN, STB_LOCAL); + Symtab->addAbsolute<ELFT>("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL); } // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to |