Represent local symbols with DefinedRegular.

llvm-svn: 263237
This commit is contained in:
Rafael Espindola
2016-03-11 14:21:37 +00:00
parent 019049fca9
commit 1f5b70f64f
6 changed files with 41 additions and 70 deletions

View File

@@ -291,8 +291,12 @@ elf::ObjectFile<ELFT>::getSection(const Elf_Sym &Sym) const {
template <class ELFT>
SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
unsigned char Binding = Sym->getBinding();
if (Binding == STB_LOCAL)
return new (Alloc) LocalSymbol<ELFT>(*Sym, getSection(*Sym));
InputSectionBase<ELFT> *Sec = getSection(*Sym);
if (Binding == STB_LOCAL) {
if (Sec == InputSection<ELFT>::Discarded)
Sec = nullptr;
return new (Alloc) DefinedRegular<ELFT>("", *Sym, Sec);
}
StringRef Name = check(Sym->getName(this->StringTable));
@@ -310,13 +314,11 @@ SymbolBody *elf::ObjectFile<ELFT>::createSymbolBody(const Elf_Sym *Sym) {
fatal("Unexpected binding");
case STB_GLOBAL:
case STB_WEAK:
case STB_GNU_UNIQUE: {
InputSectionBase<ELFT> *Sec = getSection(*Sym);
case STB_GNU_UNIQUE:
if (Sec == InputSection<ELFT>::Discarded)
return new (Alloc) UndefinedElf<ELFT>(Name, *Sym);
return new (Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec);
}
}
}
void ArchiveFile::parse() {

View File

@@ -78,11 +78,11 @@ InputSectionBase<ELFT>::getRelocTarget(const Elf_Rel &Rel) const {
// Global symbol
uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
SymbolBody &B = File->getSymbolBody(SymIndex).repl();
InputSectionBase<ELFT> *S = nullptr;
if (auto *D = dyn_cast<DefinedRegular<ELFT>>(&B))
return D->Section->Repl;
if (auto *L = dyn_cast<LocalSymbol<ELFT>>(&B))
if (InputSectionBase<ELFT> *Sec = File->getSection(L->Sym))
return Sec;
S = D->Section;
if (S)
return S->Repl;
return nullptr;
}

View File

@@ -1146,7 +1146,7 @@ void EHOutputSection<ELFT>::addSectionAux(
if (!HasReloc)
fatal("FDE doesn't reference another section");
InputSectionBase<ELFT> *Target = S->getRelocTarget(*RelI);
if (Target != InputSection<ELFT>::Discarded && Target->Live) {
if (Target && Target->Live) {
uint32_t CieOffset = Offset + 4 - ID;
auto I = OffsetToIndex.find(CieOffset);
if (I == OffsetToIndex.end())
@@ -1513,8 +1513,6 @@ SymbolTableSection<ELFT>::getOutputSection(SymbolBody *Sym) {
break;
case SymbolBody::DefinedBitcodeKind:
llvm_unreachable("Should have been replaced");
case SymbolBody::DefinedLocalKind:
llvm_unreachable("Should not be used");
}
return nullptr;
}

View File

@@ -46,12 +46,17 @@ getSymVA(const SymbolBody &Body, typename ELFFile<ELFT>::uintX_t &Addend) {
// This is an absolute symbol.
if (!SC)
return D.Sym.st_value;
assert(SC->Live);
if (D.Sym.getType() == STT_TLS)
return SC->OutSec->getVA() + SC->getOffset(D.Sym) -
Out<ELFT>::TlsPhdr->p_vaddr;
return SC->OutSec->getVA() + SC->getOffset(D.Sym);
const Elf_Sym &Sym = D.Sym;
uintX_t Offset = Sym.st_value;
if (Sym.getType() == STT_SECTION) {
Offset += Addend;
Addend = 0;
}
uintX_t VA = SC->OutSec->getVA() + SC->getOffset(Offset);
if (Sym.getType() == STT_TLS)
return VA - Out<ELFT>::TlsPhdr->p_vaddr;
return VA;
}
case SymbolBody::DefinedCommonKind:
return Out<ELFT>::Bss->getVA() + cast<DefinedCommon>(Body).OffsetInBss;
@@ -72,27 +77,6 @@ getSymVA(const SymbolBody &Body, typename ELFFile<ELFT>::uintX_t &Addend) {
return 0;
case SymbolBody::DefinedBitcodeKind:
llvm_unreachable("Should have been replaced");
case SymbolBody::DefinedLocalKind: {
auto &L = cast<LocalSymbol<ELFT>>(Body);
InputSectionBase<ELFT> *SC = L.Section;
// According to the ELF spec reference to a local symbol from outside the
// group are not allowed. Unfortunately .eh_frame breaks that rule and must
// be treated specially. For now we just replace the symbol with 0.
if (SC == InputSection<ELFT>::Discarded || !SC->Live)
return 0;
const Elf_Sym &Sym = L.Sym;
uintX_t Offset = Sym.st_value;
if (Sym.getType() == STT_TLS)
return (SC->OutSec->getVA() + SC->getOffset(Sym) + Addend) -
Out<ELFT>::TlsPhdr->p_vaddr;
if (Sym.getType() == STT_SECTION) {
Offset += Addend;
Addend = 0;
}
return SC->OutSec->getVA() + SC->getOffset(Offset);
}
}
llvm_unreachable("Invalid symbol kind");
}
@@ -181,12 +165,13 @@ template <class ELFT> int SymbolBody::compare(SymbolBody *Other) {
return isCommon() ? -1 : 1;
}
Defined::Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,
uint8_t Type)
: SymbolBody(K, Name, IsWeak, Visibility, Type) {}
Defined::Defined(Kind K, StringRef Name, bool IsWeak, bool IsLocal,
uint8_t Visibility, uint8_t Type)
: SymbolBody(K, Name, IsWeak, IsLocal, Visibility, Type) {}
DefinedBitcode::DefinedBitcode(StringRef Name, bool IsWeak, uint8_t Visibility)
: Defined(DefinedBitcodeKind, Name, IsWeak, Visibility, 0 /* Type */) {}
: Defined(DefinedBitcodeKind, Name, IsWeak, false, Visibility,
0 /* Type */) {}
bool DefinedBitcode::classof(const SymbolBody *S) {
return S->kind() == DefinedBitcodeKind;
@@ -194,7 +179,7 @@ bool DefinedBitcode::classof(const SymbolBody *S) {
Undefined::Undefined(SymbolBody::Kind K, StringRef N, bool IsWeak,
uint8_t Visibility, uint8_t Type)
: SymbolBody(K, N, IsWeak, Visibility, Type),
: SymbolBody(K, N, IsWeak, false, Visibility, Type),
CanKeepUndefined(false) {}
Undefined::Undefined(StringRef N, bool IsWeak, uint8_t Visibility,
@@ -214,13 +199,13 @@ template <typename ELFT>
DefinedSynthetic<ELFT>::DefinedSynthetic(StringRef N, uintX_t Value,
OutputSectionBase<ELFT> &Section,
uint8_t Visibility)
: Defined(SymbolBody::DefinedSyntheticKind, N, false, Visibility,
: Defined(SymbolBody::DefinedSyntheticKind, N, false, false, Visibility,
0 /* Type */),
Value(Value), Section(Section) {}
DefinedCommon::DefinedCommon(StringRef N, uint64_t Size, uint64_t Alignment,
bool IsWeak, uint8_t Visibility)
: Defined(SymbolBody::DefinedCommonKind, N, IsWeak, Visibility,
: Defined(SymbolBody::DefinedCommonKind, N, IsWeak, false, Visibility,
0 /* Type */),
Alignment(Alignment), Size(Size) {}

View File

@@ -59,8 +59,7 @@ public:
DefinedFirst,
DefinedRegularKind = DefinedFirst,
SharedKind,
DefinedLocalKind,
DefinedElfLast = DefinedLocalKind,
DefinedElfLast = SharedKind,
DefinedCommonKind,
DefinedBitcodeKind,
DefinedSyntheticKind,
@@ -80,7 +79,7 @@ public:
bool isCommon() const { return SymbolKind == DefinedCommonKind; }
bool isLazy() const { return SymbolKind == LazyKind; }
bool isShared() const { return SymbolKind == SharedKind; }
bool isLocal() const { return SymbolKind == DefinedLocalKind; }
bool isLocal() const { return IsLocal; }
bool isUsedInRegularObj() const { return IsUsedInRegularObj; }
// Returns the symbol name.
@@ -125,9 +124,9 @@ public:
template <class ELFT> int compare(SymbolBody *Other);
protected:
SymbolBody(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,
uint8_t Type)
: SymbolKind(K), IsWeak(IsWeak), Visibility(Visibility),
SymbolBody(Kind K, StringRef Name, bool IsWeak, bool IsLocal,
uint8_t Visibility, uint8_t Type)
: SymbolKind(K), IsWeak(IsWeak), IsLocal(IsLocal), Visibility(Visibility),
MustBeInDynSym(false), NeedsCopyOrPltAddr(false), Name(Name) {
IsFunc = Type == llvm::ELF::STT_FUNC;
IsTls = Type == llvm::ELF::STT_TLS;
@@ -136,6 +135,7 @@ protected:
const unsigned SymbolKind : 8;
unsigned IsWeak : 1;
unsigned IsLocal : 1;
unsigned Visibility : 2;
// True if the symbol was used for linking and thus need to be
@@ -163,7 +163,7 @@ protected:
// The base class for any defined symbols.
class Defined : public SymbolBody {
public:
Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility,
Defined(Kind K, StringRef Name, bool IsWeak, bool IsLocal, uint8_t Visibility,
uint8_t Type);
static bool classof(const SymbolBody *S) { return S->isDefined(); }
};
@@ -176,7 +176,8 @@ protected:
public:
DefinedElf(Kind K, StringRef N, const Elf_Sym &Sym)
: Defined(K, N, Sym.getBinding() == llvm::ELF::STB_WEAK,
Sym.getVisibility(), Sym.getType()),
Sym.getBinding() == llvm::ELF::STB_LOCAL, Sym.getVisibility(),
Sym.getType()),
Sym(Sym) {}
const Elf_Sym &Sym;
@@ -307,21 +308,6 @@ public:
bool needsCopy() const { return this->NeedsCopyOrPltAddr && !this->IsFunc; }
};
template <class ELFT> class LocalSymbol : public DefinedElf<ELFT> {
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
public:
LocalSymbol(const Elf_Sym &Sym, InputSectionBase<ELFT> *Section)
: DefinedElf<ELFT>(SymbolBody::DefinedLocalKind, "", Sym),
Section(Section) {}
static bool classof(const SymbolBody *S) {
return S->kind() == SymbolBody::DefinedLocalKind;
}
InputSectionBase<ELFT> *Section;
};
// This class represents a symbol defined in an archive file. It is
// created from an archive file header, and it knows how to load an
// object file from an archive to replace itself with a defined
@@ -330,7 +316,7 @@ public:
class Lazy : public SymbolBody {
public:
Lazy(ArchiveFile *F, const llvm::object::Archive::Symbol S)
: SymbolBody(LazyKind, S.getName(), false, llvm::ELF::STV_DEFAULT,
: SymbolBody(LazyKind, S.getName(), false, false, llvm::ELF::STV_DEFAULT,
/* Type */ 0),
File(F), Sym(S) {}

View File

@@ -548,7 +548,7 @@ template <class ELFT> void Writer<ELFT>::copyLocalSymbols() {
return;
for (const std::unique_ptr<ObjectFile<ELFT>> &F : Symtab.getObjectFiles()) {
for (SymbolBody *B : F->getLocalSymbols()) {
auto *L = cast<LocalSymbol<ELFT>>(B);
auto *L = cast<DefinedRegular<ELFT>>(B);
const Elf_Sym &Sym = L->Sym;
StringRef SymName = check(Sym.getName(F->getStringTable()));
if (!shouldKeepInSymtab<ELFT>(*F, SymName, Sym))