From: Rafael Espindola Date: Fri, 11 Mar 2016 14:21:37 +0000 (+0000) Subject: Represent local symbols with DefinedRegular. X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1f5b70f64f927cd3bc53134df6a934cc7ed854b2;p=platform%2Fupstream%2Fllvm.git Represent local symbols with DefinedRegular. llvm-svn: 263237 --- diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 30e2c70..53f066e 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -291,8 +291,12 @@ elf::ObjectFile::getSection(const Elf_Sym &Sym) const { template SymbolBody *elf::ObjectFile::createSymbolBody(const Elf_Sym *Sym) { unsigned char Binding = Sym->getBinding(); - if (Binding == STB_LOCAL) - return new (Alloc) LocalSymbol(*Sym, getSection(*Sym)); + InputSectionBase *Sec = getSection(*Sym); + if (Binding == STB_LOCAL) { + if (Sec == InputSection::Discarded) + Sec = nullptr; + return new (Alloc) DefinedRegular("", *Sym, Sec); + } StringRef Name = check(Sym->getName(this->StringTable)); @@ -310,13 +314,11 @@ SymbolBody *elf::ObjectFile::createSymbolBody(const Elf_Sym *Sym) { fatal("Unexpected binding"); case STB_GLOBAL: case STB_WEAK: - case STB_GNU_UNIQUE: { - InputSectionBase *Sec = getSection(*Sym); + case STB_GNU_UNIQUE: if (Sec == InputSection::Discarded) return new (Alloc) UndefinedElf(Name, *Sym); return new (Alloc) DefinedRegular(Name, *Sym, Sec); } - } } void ArchiveFile::parse() { diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp index 746ee0b..8b0536f 100644 --- a/lld/ELF/InputSection.cpp +++ b/lld/ELF/InputSection.cpp @@ -78,11 +78,11 @@ InputSectionBase::getRelocTarget(const Elf_Rel &Rel) const { // Global symbol uint32_t SymIndex = Rel.getSymbol(Config->Mips64EL); SymbolBody &B = File->getSymbolBody(SymIndex).repl(); + InputSectionBase *S = nullptr; if (auto *D = dyn_cast>(&B)) - return D->Section->Repl; - if (auto *L = dyn_cast>(&B)) - if (InputSectionBase *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 5d74a66..a9964b7 100644 --- a/lld/ELF/OutputSections.cpp +++ b/lld/ELF/OutputSections.cpp @@ -1146,7 +1146,7 @@ void EHOutputSection::addSectionAux( if (!HasReloc) fatal("FDE doesn't reference another section"); InputSectionBase *Target = S->getRelocTarget(*RelI); - if (Target != InputSection::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::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 e2fa005..30179e4 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -46,12 +46,17 @@ getSymVA(const SymbolBody &Body, typename ELFFile::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::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::TlsPhdr->p_vaddr; + return VA; } case SymbolBody::DefinedCommonKind: return Out::Bss->getVA() + cast(Body).OffsetInBss; @@ -72,27 +77,6 @@ getSymVA(const SymbolBody &Body, typename ELFFile::uintX_t &Addend) { return 0; case SymbolBody::DefinedBitcodeKind: llvm_unreachable("Should have been replaced"); - case SymbolBody::DefinedLocalKind: { - auto &L = cast>(Body); - InputSectionBase *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::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::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 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 DefinedSynthetic::DefinedSynthetic(StringRef N, uintX_t Value, OutputSectionBase &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 d874203..5cbe21d 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 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 LocalSymbol : public DefinedElf { - typedef typename llvm::object::ELFFile::Elf_Sym Elf_Sym; - -public: - LocalSymbol(const Elf_Sym &Sym, InputSectionBase *Section) - : DefinedElf(SymbolBody::DefinedLocalKind, "", Sym), - Section(Section) {} - - static bool classof(const SymbolBody *S) { - return S->kind() == SymbolBody::DefinedLocalKind; - } - - InputSectionBase *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 8c1a50c..40963b0 100644 --- a/lld/ELF/Writer.cpp +++ b/lld/ELF/Writer.cpp @@ -548,7 +548,7 @@ template void Writer::copyLocalSymbols() { return; for (const std::unique_ptr> &F : Symtab.getObjectFiles()) { for (SymbolBody *B : F->getLocalSymbols()) { - auto *L = cast>(B); + auto *L = cast>(B); const Elf_Sym &Sym = L->Sym; StringRef SymName = check(Sym.getName(F->getStringTable())); if (!shouldKeepInSymtab(*F, SymName, Sym))