diff options
-rw-r--r-- | lld/ELF/Driver.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/InputFiles.cpp | 6 | ||||
-rw-r--r-- | lld/ELF/InputSection.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/MarkLive.cpp | 2 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 25 | ||||
-rw-r--r-- | lld/ELF/SymbolTable.cpp | 4 | ||||
-rw-r--r-- | lld/ELF/Symbols.cpp | 6 | ||||
-rw-r--r-- | lld/ELF/Symbols.h | 84 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 20 |
9 files changed, 69 insertions, 82 deletions
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 8ac35d66934..9402c2d182d 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -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) diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 3c7f5ba4d82..2edcb70023b 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -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); } } } diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 71078cfb6db..a2ee588f4e1 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -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)) diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp index cc7387b4da4..1ad9b01af4e 100644 --- a/lld/ELF/MarkLive.cpp +++ b/lld/ELF/MarkLive.cpp @@ -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. diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index b48538c103f..3801629cfeb 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -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; } diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 4d7c163a9c6..826d6eff01f 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -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; } diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 5c659522dac..c3515d18ca6 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -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() { diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 2ce4fe86070..0b70f5e2962 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -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 diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 6f32d3d825c..2a258a81453 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -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. |