From: Michael J. Spencer Date: Tue, 28 Jul 2015 22:58:25 +0000 (+0000) Subject: [ELF2] Devirtualize SymbolBody. X-Git-Tag: studio-1.4~1337 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cdae0a4e2d2a3d6755762bfee63467ab7f192069;p=platform%2Fupstream%2Fllvm.git [ELF2] Devirtualize SymbolBody. llvm-svn: 243496 --- diff --git a/lld/ELF/InputFiles.cpp b/lld/ELF/InputFiles.cpp index 2ab8fa2..8db2064 100644 --- a/lld/ELF/InputFiles.cpp +++ b/lld/ELF/InputFiles.cpp @@ -65,7 +65,7 @@ SymbolBody *elf2::ObjectFile::createSymbolBody(StringRef StringTable, StringRef Name = *NameOrErr; if (Sym->isUndefined()) return new (Alloc) Undefined(Name); - return new (Alloc) DefinedRegular(Name); + return new (Alloc) DefinedRegular(this, Sym); } namespace lld { diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp index 9b3bc30..35bc499 100644 --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -9,12 +9,30 @@ #include "Symbols.h" #include "Chunks.h" +#include "InputFiles.h" using namespace llvm::object; using namespace lld; using namespace lld::elf2; +template +StringRef +getSymbolName(const llvm::object::ELFFile *F, + const typename llvm::object::ELFFile::Elf_Sym *S) { + ErrorOr StrTab = F->getStringTableForSymtab(*F->getDotSymtabSec()); + if (!StrTab || S->st_name >= StrTab->size()) + llvm::report_fatal_error("Invalid string table."); + return StrTab->data() + S->st_name; +} + +template +DefinedRegular::DefinedRegular(ObjectFile *F, const Elf_Sym *S) + : Defined(DefinedRegularKind, getSymbolName(F->getObj(), S)), File(F), + Sym(S) { + IsExternal = S->isExternal(); +} + // Returns 1, 0 or -1 if this symbol should take precedence // over the Other, tie or lose, respectively. int SymbolBody::compare(SymbolBody *Other) { diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h index 7ae51cd..2018fd6 100644 --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -21,6 +21,7 @@ using llvm::object::ELFFile; class Chunk; class InputFile; class SymbolBody; +template class ObjectFile; // A real symbol object, SymbolBody, is usually accessed indirectly // through a Symbol. There's always one Symbol for each symbol name. @@ -40,14 +41,13 @@ public: UndefinedKind, }; - Kind kind() const { return SymbolKind; } - virtual ~SymbolBody() {} + Kind kind() const { return static_cast(SymbolKind); } // Returns true if this is an external symbol. - virtual bool isExternal() { return true; } + bool isExternal() const { return true; } // Returns the symbol name. - virtual StringRef getName() = 0; + StringRef getName() const { return Name; } // A SymbolBody has a backreference to a Symbol. Originally they are // doubly-linked. A backreference will never change. But the pointer @@ -64,10 +64,13 @@ public: int compare(SymbolBody *Other); protected: - SymbolBody(Kind K) : SymbolKind(K) {} + SymbolBody(Kind K, StringRef N = "") + : SymbolKind(K), IsExternal(true), Name(N) {} -private: - const Kind SymbolKind; +protected: + const unsigned SymbolKind : 8; + unsigned IsExternal : 1; + StringRef Name; Symbol *Backref = nullptr; }; @@ -75,7 +78,7 @@ private: // etc. class Defined : public SymbolBody { public: - Defined(Kind K) : SymbolBody(K) {} + Defined(Kind K, StringRef N = "") : SymbolBody(K, N) {} static bool classof(const SymbolBody *S) { Kind K = S->kind(); @@ -85,31 +88,28 @@ public: // Regular defined symbols read from object file symbol tables. template class DefinedRegular : public Defined { + typedef typename llvm::object::ELFFile::Elf_Sym Elf_Sym; + public: - DefinedRegular(StringRef Name) : Defined(DefinedRegularKind), Name(Name) {} + DefinedRegular(ObjectFile *F, const Elf_Sym *S); static bool classof(const SymbolBody *S) { return S->kind() == DefinedRegularKind; } - StringRef getName() override { return Name; } - private: - StringRef Name; + ObjectFile *File; + const Elf_Sym *Sym; }; // Undefined symbols. class Undefined : public SymbolBody { public: - explicit Undefined(StringRef N) : SymbolBody(UndefinedKind), Name(N) {} + explicit Undefined(StringRef N) : SymbolBody(UndefinedKind, N) {} static bool classof(const SymbolBody *S) { return S->kind() == UndefinedKind; } - StringRef getName() override { return Name; } - -private: - StringRef Name; }; } // namespace elf2