Delete DefinedAbsolute.

There are 3 symbol types that a .bc can provide during lto: defined,
undefined, common.

Defined and undefined symbols have already been refactored. I was
working on common and noticed that absolute symbols would become an
oddity: They would be the only symbol type present in a .o but not in
a.bc.

Looking a bit more, other than the special section number they were only
used for special rules for computing values. In that way they are
similar to TLS, and we don't have a DefinedTLS.

This patch deletes it. With it we have a reasonable rule of the thumb
for having a symbol kind: It exists if it has special resolution
semantics.

llvm-svn: 256383
This commit is contained in:
Rafael Espindola 2015-12-24 14:22:24 +00:00
parent 59d35f1415
commit 02ce26a1b4
9 changed files with 69 additions and 82 deletions

View File

@ -279,7 +279,7 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) {
// so that it points to an absolute address which is relative to GOT.
// See "Global Data Symbols" in Chapter 6 in the following document:
// ftp://www.linux-mips.org/pub/linux/mips/doc/ABI/mipsabi.pdf
Symtab.addAbsolute("_gp", DefinedAbsolute<ELFT>::MipsGp);
Symtab.addAbsolute("_gp", DefinedRegular<ELFT>::MipsGp);
}
for (std::unique_ptr<InputFile> &F : Files)

View File

@ -65,7 +65,7 @@ uint32_t ELFFileBase<ELFT>::getSectionIndex(const Elf_Sym &Sym) const {
if (I == ELF::SHN_XINDEX)
return this->ELFObj.getExtendedSymbolTableIndex(&Sym, this->Symtab,
SymtabSHNDX);
if (I >= ELF::SHN_LORESERVE)
if (I >= ELF::SHN_LORESERVE || I == ELF::SHN_ABS)
return 0;
return I;
}
@ -283,8 +283,6 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
StringRef Name = *NameOrErr;
switch (Sym->st_shndx) {
case SHN_ABS:
return new (this->Alloc) DefinedAbsolute<ELFT>(Name, *Sym);
case SHN_UNDEF:
return new (this->Alloc) UndefinedElf<ELFT>(Name, *Sym);
case SHN_COMMON:
@ -300,7 +298,7 @@ SymbolBody *elf2::ObjectFile<ELFT>::createSymbolBody(StringRef StringTable,
InputSectionBase<ELFT> *Sec = getSection(*Sym);
if (Sec == &InputSection<ELFT>::Discarded)
return new (this->Alloc) UndefinedElf<ELFT>(Name, *Sym);
return new (this->Alloc) DefinedRegular<ELFT>(Name, *Sym, *Sec);
return new (this->Alloc) DefinedRegular<ELFT>(Name, *Sym, Sec);
}
}
}

View File

@ -71,7 +71,7 @@ InputSectionBase<ELFT>::getRelocTarget(const Elf_Rel &Rel) {
uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL);
if (SymbolBody *B = File->getSymbolBody(SymIndex))
if (auto *D = dyn_cast<DefinedRegular<ELFT>>(B->repl()))
return &D->Section;
return D->Section;
// Local symbol
if (const Elf_Sym *Sym = File->getLocalSymbol(SymIndex))
if (InputSectionBase<ELFT> *Sec = File->getSection(*Sym))

View File

@ -93,7 +93,7 @@ template <class ELFT> void lld::elf2::markLive(SymbolTable<ELFT> *Symtab) {
auto MarkSymbol = [&](SymbolBody *Sym) {
if (Sym)
if (auto *D = dyn_cast<DefinedRegular<ELFT>>(Sym->repl()))
Enqueue(&D->Section);
Enqueue(D->Section);
};
// Add GC root symbols.

View File

@ -789,15 +789,15 @@ typename ELFFile<ELFT>::uintX_t lld::elf2::getSymVA(const SymbolBody &S) {
auto &D = cast<DefinedSynthetic<ELFT>>(S);
return D.Section.getVA() + D.Value;
}
case SymbolBody::DefinedAbsoluteKind:
return cast<DefinedAbsolute<ELFT>>(S).Sym.st_value;
case SymbolBody::DefinedRegularKind: {
const auto &DR = cast<DefinedRegular<ELFT>>(S);
InputSectionBase<ELFT> &SC = DR.Section;
InputSectionBase<ELFT> *SC = DR.Section;
if (!SC)
return DR.Sym.st_value;
if (DR.Sym.getType() == STT_TLS)
return SC.OutSec->getVA() + SC.getOffset(DR.Sym) -
return SC->OutSec->getVA() + SC->getOffset(DR.Sym) -
Out<ELFT>::TlsPhdr->p_vaddr;
return SC.OutSec->getVA() + SC.getOffset(DR.Sym);
return SC->OutSec->getVA() + SC->getOffset(DR.Sym);
}
case SymbolBody::DefinedCommonKind:
return Out<ELFT>::Bss->getVA() + cast<DefinedCommon<ELFT>>(S).OffsetInBSS;
@ -1341,9 +1341,11 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
break;
case SymbolBody::DefinedRegularKind: {
auto *Sym = cast<DefinedRegular<ELFT>>(Body->repl());
if (!Sym->Section.isLive())
continue;
OutSec = Sym->Section.OutSec;
if (InputSectionBase<ELFT> *Sec = Sym->Section) {
if (!Sec->isLive())
continue;
OutSec = Sec->OutSec;
}
break;
}
case SymbolBody::DefinedCommonKind:
@ -1356,7 +1358,6 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
}
case SymbolBody::UndefinedElfKind:
case SymbolBody::UndefinedKind:
case SymbolBody::DefinedAbsoluteKind:
case SymbolBody::LazyKind:
break;
}
@ -1376,10 +1377,10 @@ void SymbolTableSection<ELFT>::writeGlobalSymbols(uint8_t *Buf) {
ESym->setVisibility(Body->getVisibility());
ESym->st_value = getSymVA<ELFT>(*Body);
if (isa<DefinedAbsolute<ELFT>>(Body))
ESym->st_shndx = SHN_ABS;
else if (OutSec)
if (OutSec)
ESym->st_shndx = OutSec->SectionIndex;
else if (isa<DefinedRegular<ELFT>>(Body))
ESym->st_shndx = SHN_ABS;
++ESym;
}

View File

@ -98,7 +98,7 @@ SymbolBody *SymbolTable<ELFT>::addUndefinedOpt(StringRef Name) {
template <class ELFT>
void SymbolTable<ELFT>::addAbsolute(StringRef Name,
typename ELFFile<ELFT>::Elf_Sym &ESym) {
resolve(new (Alloc) DefinedAbsolute<ELFT>(Name, ESym));
resolve(new (Alloc) DefinedRegular<ELFT>(Name, ESym, nullptr));
}
template <class ELFT>
@ -112,7 +112,7 @@ void SymbolTable<ELFT>::addSynthetic(StringRef Name,
template <class ELFT>
SymbolBody *SymbolTable<ELFT>::addIgnored(StringRef Name) {
auto *Sym = new (Alloc)
DefinedAbsolute<ELFT>(Name, DefinedAbsolute<ELFT>::IgnoreUndef);
DefinedRegular<ELFT>(Name, DefinedRegular<ELFT>::IgnoreUndef, nullptr);
resolve(Sym);
return Sym;
}

View File

@ -113,9 +113,9 @@ std::unique_ptr<InputFile> Lazy::getMember() {
}
template <class ELFT> static void doInitSymbols() {
DefinedAbsolute<ELFT>::End.setBinding(STB_GLOBAL);
DefinedAbsolute<ELFT>::IgnoreUndef.setBinding(STB_WEAK);
DefinedAbsolute<ELFT>::IgnoreUndef.setVisibility(STV_HIDDEN);
DefinedRegular<ELFT>::End.setBinding(STB_GLOBAL);
DefinedRegular<ELFT>::IgnoreUndef.setBinding(STB_WEAK);
DefinedRegular<ELFT>::IgnoreUndef.setVisibility(STV_HIDDEN);
}
void lld::elf2::initSymbols() {

View File

@ -57,7 +57,6 @@ public:
enum Kind {
DefinedFirst,
DefinedRegularKind = DefinedFirst,
DefinedAbsoluteKind,
DefinedCommonKind,
SharedKind,
DefinedElfLast = SharedKind,
@ -131,7 +130,7 @@ protected:
Symbol *Backref = nullptr;
};
// The base class for any defined symbols, including absolute symbols, etc.
// The base class for any defined symbols.
class Defined : public SymbolBody {
public:
Defined(Kind K, StringRef Name, bool IsWeak, uint8_t Visibility, bool IsTls);
@ -155,50 +154,6 @@ public:
}
};
template <class ELFT> class DefinedAbsolute : public DefinedElf<ELFT> {
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
public:
static Elf_Sym IgnoreUndef;
// The following symbols must be added early to reserve their places
// in symbol tables. The value of the symbols are set when all sections
// are finalized and their addresses are determined.
// The content for _end and end symbols.
static Elf_Sym End;
// The content for _gp symbol for MIPS target.
static Elf_Sym MipsGp;
// __rel_iplt_start/__rel_iplt_end for signaling
// where R_[*]_IRELATIVE relocations do live.
static Elf_Sym RelaIpltStart;
static Elf_Sym RelaIpltEnd;
DefinedAbsolute(StringRef N, const Elf_Sym &Sym)
: DefinedElf<ELFT>(SymbolBody::DefinedAbsoluteKind, N, Sym) {}
static bool classof(const SymbolBody *S) {
return S->kind() == SymbolBody::DefinedAbsoluteKind;
}
};
template <class ELFT>
typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::IgnoreUndef;
template <class ELFT>
typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::End;
template <class ELFT>
typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::MipsGp;
template <class ELFT>
typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::RelaIpltStart;
template <class ELFT>
typename DefinedAbsolute<ELFT>::Elf_Sym DefinedAbsolute<ELFT>::RelaIpltEnd;
template <class ELFT> class DefinedCommon : public DefinedElf<ELFT> {
typedef typename llvm::object::ELFFile<ELFT>::Elf_Sym Elf_Sym;
@ -227,7 +182,7 @@ template <class ELFT> class DefinedRegular : public DefinedElf<ELFT> {
public:
DefinedRegular(StringRef N, const Elf_Sym &Sym,
InputSectionBase<ELFT> &Section)
InputSectionBase<ELFT> *Section)
: DefinedElf<ELFT>(SymbolBody::DefinedRegularKind, N, Sym),
Section(Section) {}
@ -235,9 +190,42 @@ public:
return S->kind() == SymbolBody::DefinedRegularKind;
}
InputSectionBase<ELFT> &Section;
// If this is null, the symbol is absolute.
InputSectionBase<ELFT> *Section;
static Elf_Sym IgnoreUndef;
// The following symbols must be added early to reserve their places
// in symbol tables. The value of the symbols are set when all sections
// are finalized and their addresses are determined.
// The content for _end and end symbols.
static Elf_Sym End;
// The content for _gp symbol for MIPS target.
static Elf_Sym MipsGp;
// __rel_iplt_start/__rel_iplt_end for signaling
// where R_[*]_IRELATIVE relocations do live.
static Elf_Sym RelaIpltStart;
static Elf_Sym RelaIpltEnd;
};
template <class ELFT>
typename DefinedRegular<ELFT>::Elf_Sym DefinedRegular<ELFT>::IgnoreUndef;
template <class ELFT>
typename DefinedRegular<ELFT>::Elf_Sym DefinedRegular<ELFT>::End;
template <class ELFT>
typename DefinedRegular<ELFT>::Elf_Sym DefinedRegular<ELFT>::MipsGp;
template <class ELFT>
typename DefinedRegular<ELFT>::Elf_Sym DefinedRegular<ELFT>::RelaIpltStart;
template <class ELFT>
typename DefinedRegular<ELFT>::Elf_Sym DefinedRegular<ELFT>::RelaIpltEnd;
// DefinedSynthetic is a class to represent linker-generated ELF symbols.
// The difference from the regular symbol is that DefinedSynthetic symbols
// don't belong to any input files or sections. Thus, its constructor

View File

@ -590,9 +590,9 @@ static void addIRelocMarkers(SymbolTable<ELFT> &Symtab, bool IsDynamic) {
Symtab.addAbsolute(Name, Sym);
};
AddMarker(IsRela ? "__rela_iplt_start" : "__rel_iplt_start",
DefinedAbsolute<ELFT>::RelaIpltStart);
DefinedRegular<ELFT>::RelaIpltStart);
AddMarker(IsRela ? "__rela_iplt_end" : "__rel_iplt_end",
DefinedAbsolute<ELFT>::RelaIpltEnd);
DefinedRegular<ELFT>::RelaIpltEnd);
}
template <class ELFT> static bool includeInSymtab(const SymbolBody &B) {
@ -600,8 +600,8 @@ template <class ELFT> static bool includeInSymtab(const SymbolBody &B) {
return false;
// Don't include synthetic symbols like __init_array_start in every output.
if (auto *U = dyn_cast<DefinedAbsolute<ELFT>>(&B))
if (&U->Sym == &DefinedAbsolute<ELFT>::IgnoreUndef)
if (auto *U = dyn_cast<DefinedRegular<ELFT>>(&B))
if (&U->Sym == &DefinedRegular<ELFT>::IgnoreUndef)
return false;
return true;
@ -726,14 +726,14 @@ template <class ELFT> void Writer<ELFT>::createSections() {
// So, if this symbol is referenced, we just add the placeholder here
// and update its value later.
if (Symtab.find("_end"))
Symtab.addAbsolute("_end", DefinedAbsolute<ELFT>::End);
Symtab.addAbsolute("_end", DefinedRegular<ELFT>::End);
// If there is an undefined symbol "end", we should initialize it
// with the same value as "_end". In any other case it should stay intact,
// because it is an allowable name for a user symbol.
if (SymbolBody *B = Symtab.find("end"))
if (B->isUndefined())
Symtab.addAbsolute("end", DefinedAbsolute<ELFT>::End);
Symtab.addAbsolute("end", DefinedRegular<ELFT>::End);
// Scan relocations. This must be done after every symbol is declared so that
// we can correctly decide if a dynamic relocation is needed.
@ -1038,20 +1038,20 @@ template <class ELFT> void Writer<ELFT>::assignAddresses() {
// Update "_end" and "end" symbols so that they
// point to the end of the data segment.
DefinedAbsolute<ELFT>::End.st_value = VA;
DefinedRegular<ELFT>::End.st_value = VA;
// Update __rel_iplt_start/__rel_iplt_end to wrap the
// rela.plt section.
if (Out<ELFT>::RelaPlt) {
uintX_t Start = Out<ELFT>::RelaPlt->getVA();
DefinedAbsolute<ELFT>::RelaIpltStart.st_value = Start;
DefinedAbsolute<ELFT>::RelaIpltEnd.st_value =
DefinedRegular<ELFT>::RelaIpltStart.st_value = Start;
DefinedRegular<ELFT>::RelaIpltEnd.st_value =
Start + Out<ELFT>::RelaPlt->getSize();
}
// Update MIPS _gp absolute symbol so that it points to the static data.
if (Config->EMachine == EM_MIPS)
DefinedAbsolute<ELFT>::MipsGp.st_value = getMipsGpAddr<ELFT>();
DefinedRegular<ELFT>::MipsGp.st_value = getMipsGpAddr<ELFT>();
}
// Returns the number of PHDR entries.