diff options
-rw-r--r-- | lld/ELF/InputFiles.cpp | 12 | ||||
-rw-r--r-- | lld/ELF/InputSection.cpp | 8 | ||||
-rw-r--r-- | lld/ELF/OutputSections.cpp | 4 | ||||
-rw-r--r-- | lld/ELF/Symbols.cpp | 51 | ||||
-rw-r--r-- | lld/ELF/Symbols.h | 34 | ||||
-rw-r--r-- | lld/ELF/Writer.cpp | 2 |
6 files changed, 41 insertions, 70 deletions
diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 30e2c701b13..53f066efb1b 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -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() { diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 746ee0ba04b..8b0536fe432 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -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; } diff --git a/lld/ELF/OutputSections.cpp b/lld/ELF/OutputSections.cpp index 5d74a6678fc..a9964b729a9 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -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; } diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index e2fa00585ee..30179e4a3bf 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -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) {} diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index d874203be26..5cbe21dd9f1 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -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) {} diff --git a/lld/ELF/Writer.cpp b/lld/ELF/Writer.cpp index 8c1a50ceac1..40963b098db 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -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)) |