Index: ELF/InputFiles.cpp =================================================================== --- ELF/InputFiles.cpp +++ ELF/InputFiles.cpp @@ -591,18 +591,16 @@ StringRefZ Name = this->StringTable.data() + Sym->st_name; if (Sym->st_shndx == SHN_UNDEF) - return make(Name, /*IsLocal=*/true, StOther, Type); + return make(Name, Binding, StOther, Type); - return make(Name, /*IsLocal=*/true, StOther, Type, Value, Size, - Sec); + return make(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(Name, /*IsLocal=*/false, Binding, StOther, - Type, + return Symtab->addUndefined(Name, Binding, StOther, Type, /*CanOmitFromDynSym=*/false, this); case SHN_COMMON: if (Value == 0 || Value >= UINT32_MAX) @@ -618,8 +616,7 @@ case STB_WEAK: case STB_GNU_UNIQUE: if (Sec == &InputSection::Discarded) - return Symtab->addUndefined(Name, /*IsLocal=*/false, Binding, - StOther, Type, + return Symtab->addUndefined(Name, Binding, StOther, Type, /*CanOmitFromDynSym=*/false, this); return Symtab->addRegular(Name, StOther, Type, Value, Size, Binding, Sec, this); @@ -907,12 +904,12 @@ int C = ObjSym.getComdatIndex(); if (C != -1 && !KeptComdats[C]) - return Symtab->addUndefined(NameRef, /*IsLocal=*/false, Binding, - Visibility, Type, CanOmitFromDynSym, F); + return Symtab->addUndefined(NameRef, Binding, Visibility, Type, + CanOmitFromDynSym, F); if (ObjSym.isUndefined()) - return Symtab->addUndefined(NameRef, /*IsLocal=*/false, Binding, - Visibility, Type, CanOmitFromDynSym, F); + return Symtab->addUndefined(NameRef, Binding, Visibility, Type, + CanOmitFromDynSym, F); if (ObjSym.isCommon()) return Symtab->addCommon(NameRef, ObjSym.getCommonSize(), Index: ELF/LTO.cpp =================================================================== --- ELF/LTO.cpp +++ ELF/LTO.cpp @@ -119,8 +119,8 @@ BitcodeCompiler::~BitcodeCompiler() = default; static void undefine(Symbol *S) { - replaceSymbol(S, nullptr, S->getName(), /*IsLocal=*/false, - STV_DEFAULT, S->Type); + replaceSymbol(S, nullptr, S->getName(), STB_GLOBAL, STV_DEFAULT, + S->Type); } void BitcodeCompiler::add(BitcodeFile &F) { Index: ELF/LinkerScript.cpp =================================================================== --- ELF/LinkerScript.cpp +++ ELF/LinkerScript.cpp @@ -132,7 +132,6 @@ 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 @@ // write expressions like this: `alignment = 16; . = ALIGN(., alignment)`. uint64_t SymValue = Value.Sec ? 0 : Value.getValue(); - replaceSymbol(Sym, nullptr, Cmd->Name, /*IsLocal=*/false, Visibility, + replaceSymbol(Sym, nullptr, Cmd->Name, STB_GLOBAL, Visibility, STT_NOTYPE, SymValue, 0, Sec); Cmd->Sym = cast(Sym); } Index: ELF/SymbolTable.h =================================================================== --- ELF/SymbolTable.h +++ ELF/SymbolTable.h @@ -47,9 +47,8 @@ template Symbol *addUndefined(StringRef Name); template - 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 Symbol *addRegular(StringRef Name, uint8_t StOther, uint8_t Type, uint64_t Value, uint64_t Size, uint8_t Binding, Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -236,7 +236,6 @@ if (IsNew) { Sym = (Symbol *)make(); Sym->InVersionScript = false; - Sym->Binding = STB_WEAK; Sym->Visibility = STV_DEFAULT; Sym->IsUsedInRegularObj = false; Sym->ExportDynamic = false; @@ -279,7 +278,7 @@ } template Symbol *SymbolTable::addUndefined(StringRef Name) { - return addUndefined(Name, /*IsLocal=*/false, STB_GLOBAL, STV_DEFAULT, + return addUndefined(Name, STB_GLOBAL, STV_DEFAULT, /*Type*/ 0, /*CanOmitFromDynSym*/ false, /*File*/ nullptr); } @@ -287,7 +286,7 @@ static uint8_t getVisibility(uint8_t StOther) { return StOther & 3; } template -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 @@ // An undefined symbol with non default visibility must be satisfied // in the same DSO. if (WasInserted || (isa(S) && Visibility != STV_DEFAULT)) { - S->Binding = Binding; - replaceSymbol(S, File, Name, IsLocal, StOther, Type); + replaceSymbol(S, File, Name, Binding, StOther, Type); return S; } if (Binding != STB_WEAK) { @@ -311,10 +309,12 @@ if (auto *L = dyn_cast(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(F); + } } return S; } @@ -359,11 +359,8 @@ 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(S)) { if (R->Section && isa(R->Section)) { // Non-common symbols take precedence over common symbols. @@ -392,9 +389,7 @@ Bss->Live = !Config->GcSections; InputSections.push_back(Bss); - S->Binding = Binding; - replaceSymbol(S, File, N, /*IsLocal=*/false, StOther, Type, 0, - Size, Bss); + replaceSymbol(S, File, N, Binding, StOther, Type, 0, Size, Bss); } else if (Cmp == 0) { auto *D = cast(S); auto *Bss = dyn_cast_or_null(D->Section); @@ -473,8 +468,8 @@ int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, Section == nullptr, Value, Name); if (Cmp > 0) - replaceSymbol(S, File, Name, /*IsLocal=*/false, StOther, Type, - Value, Size, Section); + replaceSymbol(S, File, Name, Binding, StOther, Type, Value, Size, + Section); else if (Cmp == 0) reportDuplicate(S, dyn_cast_or_null(Section), Value); @@ -500,10 +495,14 @@ // in the same DSO. if (WasInserted || ((S->isUndefined() || S->isLazy()) && S->getVisibility() == STV_DEFAULT)) { + uint8_t Binding = S->Binding; replaceSymbol(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 @@ int Cmp = compareDefinedNonCommon(S, WasInserted, Binding, /*IsAbs*/ false, /*Value*/ 0, Name); if (Cmp > 0) - replaceSymbol(S, F, Name, /*IsLocal=*/false, StOther, Type, 0, 0, - nullptr); + replaceSymbol(S, F, Name, Binding, StOther, Type, 0, 0, nullptr); else if (Cmp == 0) reportDuplicate(S, F); return S; @@ -550,6 +548,7 @@ // Symbols.h for the details. if (S->isWeak()) { replaceSymbol(S, F, Sym, S->Type); + S->Binding = STB_WEAK; return S; } std::pair MBInfo = F->getMember(&Sym); @@ -784,18 +783,14 @@ template Symbol *SymbolTable::addUndefined(StringRef); template Symbol *SymbolTable::addUndefined(StringRef); -template Symbol *SymbolTable::addUndefined(StringRef, bool, uint8_t, - uint8_t, uint8_t, bool, - InputFile *); -template Symbol *SymbolTable::addUndefined(StringRef, bool, uint8_t, - uint8_t, uint8_t, bool, - InputFile *); -template Symbol *SymbolTable::addUndefined(StringRef, bool, uint8_t, - uint8_t, uint8_t, bool, - InputFile *); -template Symbol *SymbolTable::addUndefined(StringRef, bool, uint8_t, - uint8_t, uint8_t, bool, - InputFile *); +template Symbol *SymbolTable::addUndefined(StringRef, uint8_t, uint8_t, + uint8_t, bool, InputFile *); +template Symbol *SymbolTable::addUndefined(StringRef, uint8_t, uint8_t, + uint8_t, bool, InputFile *); +template Symbol *SymbolTable::addUndefined(StringRef, uint8_t, uint8_t, + uint8_t, bool, InputFile *); +template Symbol *SymbolTable::addUndefined(StringRef, uint8_t, uint8_t, + uint8_t, bool, InputFile *); template void SymbolTable::addCombinedLTOObject(); template void SymbolTable::addCombinedLTOObject(); Index: ELF/Symbols.h =================================================================== --- ELF/Symbols.h +++ ELF/Symbols.h @@ -94,7 +94,7 @@ 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 @@ 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 @@ // 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 @@ 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 @@ 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 @@ 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 @@ new (S) T(std::forward(Arg)...); S->File = File; - S->Binding = Sym.Binding; S->VersionId = Sym.VersionId; S->Visibility = Sym.Visibility; S->IsUsedInRegularObj = Sym.IsUsedInRegularObj; Index: ELF/SyntheticSections.cpp =================================================================== --- ELF/SyntheticSections.cpp +++ ELF/SyntheticSections.cpp @@ -275,8 +275,8 @@ Symbol *elf::addSyntheticLocal(StringRef Name, uint8_t Type, uint64_t Value, uint64_t Size, InputSectionBase *Section) { - auto *S = make(Name, /*IsLocal*/ true, STV_DEFAULT, Type, Value, - Size, Section); + auto *S = + make(Name, STB_LOCAL, STV_DEFAULT, Type, Value, Size, Section); if (InX::SymTab) InX::SymTab->addSymbol(S); return S; Index: ELF/Writer.cpp =================================================================== --- ELF/Writer.cpp +++ ELF/Writer.cpp @@ -500,7 +500,7 @@ if (isa(IS) && !(IS->Flags & SHF_MERGE)) continue; - auto *Sym = make("", /*IsLocal=*/true, /*StOther=*/0, STT_SECTION, + auto *Sym = make("", STB_LOCAL, /*StOther=*/0, STT_SECTION, /*Value=*/0, /*Size=*/0, IS); InX::SymTab->addSymbol(Sym); } @@ -780,13 +780,13 @@ // 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("_gp", STV_HIDDEN, STB_LOCAL); + ElfSym::MipsGp = Symtab->addAbsolute("_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("_gp_disp", STV_HIDDEN, STB_LOCAL); + Symtab->addAbsolute("_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 @@ // https://sourceware.org/ml/binutils/2004-12/msg00094.html if (Symtab->find("__gnu_local_gp")) ElfSym::MipsLocalGp = - Symtab->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_LOCAL); + Symtab->addAbsolute("__gnu_local_gp", STV_HIDDEN, STB_GLOBAL); } // The _GLOBAL_OFFSET_TABLE_ symbol is defined by target convention to