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)
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);
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(),
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) {
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;
// 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);
}
if (IsNew) {
Sym = (Symbol *)make<SymbolUnion>();
Sym->InVersionScript = false;
- Sym->Binding = STB_WEAK;
Sym->Visibility = STV_DEFAULT;
Sym->IsUsedInRegularObj = false;
Sym->ExportDynamic = false;
}
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);
}
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;
// 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) {
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;
}
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.
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);
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);
// 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;
+ }
}
}
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;
// 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);
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>();
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,
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;
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.
// 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(); }
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; }
};
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
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
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;
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;
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);
}
// 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
// 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