[lld] r287737 - Allow calling getName() on local symbols.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Tue Nov 22 20:57:25 PST 2016


Author: ruiu
Date: Tue Nov 22 22:57:25 2016
New Revision: 287737

URL: http://llvm.org/viewvc/llvm-project?rev=287737&view=rev
Log:
Allow calling getName() on local symbols.

Previously, we stored offsets in string tables to symbols, so
you needed to pass a string table to get a symbol name. This patch
stores const char pointers instead to eliminate the need to pass
a string table.

Modified:
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/Relocations.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/ELF/Writer.cpp

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=287737&r1=287736&r2=287737&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Tue Nov 22 22:57:25 2016
@@ -441,10 +441,14 @@ SymbolBody *elf::ObjectFile<ELFT>::creat
   if (Binding == STB_LOCAL) {
     if (Sym->getType() == STT_FILE)
       SourceFile = check(Sym->getName(this->StringTable));
+
+    if (this->StringTable.size() <= Sym->st_name)
+      fatal(getFilename(this) + ": invalid symbol name offset");
+
+    const char *Name = this->StringTable.data() + Sym->st_name;
     if (Sym->st_shndx == SHN_UNDEF)
-      return new (BAlloc)
-          Undefined(Sym->st_name, Sym->st_other, Sym->getType(), this);
-    return new (BAlloc) DefinedRegular<ELFT>(*Sym, Sec);
+      return new (BAlloc) Undefined(Name, Sym->st_other, Sym->getType(), this);
+    return new (BAlloc) DefinedRegular<ELFT>(Name, *Sym, Sec);
   }
 
   StringRef Name = check(Sym->getName(this->StringTable));

Modified: lld/trunk/ELF/Relocations.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Relocations.cpp?rev=287737&r1=287736&r2=287737&view=diff
==============================================================================
--- lld/trunk/ELF/Relocations.cpp (original)
+++ lld/trunk/ELF/Relocations.cpp Tue Nov 22 22:57:25 2016
@@ -443,7 +443,7 @@ static RelExpr adjustExpr(const elf::Obj
   // only memory. We can hack around it if we are producing an executable and
   // the refered symbol can be preemepted to refer to the executable.
   if (Config->Shared || (Config->Pic && !isRelExpr(Expr))) {
-    StringRef Name = getSymbolName(File.getStringTable(), Body);
+    StringRef Name = Body.getName();
     error(getLocation(S, RelOff) + ": can't create dynamic relocation " +
           getRelName(Type) + " against " +
           ((Name.empty() ? "local symbol in readonly segment"
@@ -552,10 +552,8 @@ std::string getLocation(InputSectionBase
 
   // Find a symbol at a given location.
   DefinedRegular<ELFT> *Encl = getSymbolAt(&S, Offset);
-  if (Encl && Encl->Type == STT_FUNC) {
-    StringRef Func = getSymbolName(File->getStringTable(), *Encl);
-    return SrcFile + ":(function " + maybeDemangle(Func) + ")";
-  }
+  if (Encl && Encl->Type == STT_FUNC)
+    return SrcFile + ":(function " + maybeDemangle(Encl->getName()) + ")";
 
   // If there's no symbol, print out the offset instead of a symbol name.
   return (SrcFile + ":(" + S.Name + "+0x" + Twine::utohexstr(Offset) + ")")

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=287737&r1=287736&r2=287737&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Tue Nov 22 22:57:25 2016
@@ -17,6 +17,7 @@
 
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/Support/Path.h"
+#include <cstring>
 
 using namespace llvm;
 using namespace llvm::object;
@@ -90,20 +91,20 @@ static typename ELFT::uint getSymVA(cons
   llvm_unreachable("invalid symbol kind");
 }
 
-SymbolBody::SymbolBody(Kind K, uint32_t NameOffset, uint8_t StOther,
-                       uint8_t Type)
+SymbolBody::SymbolBody(Kind K, const char *Name, uint8_t StOther, uint8_t Type)
     : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(true),
       IsInGlobalMipsGot(false), Is32BitMipsGot(false), Type(Type),
-      StOther(StOther), NameOffset(NameOffset) {}
+      StOther(StOther), Name(Name) {}
 
 SymbolBody::SymbolBody(Kind K, StringRef Name, uint8_t StOther, uint8_t Type)
     : SymbolKind(K), NeedsCopyOrPltAddr(false), IsLocal(false),
       IsInGlobalMipsGot(false), Is32BitMipsGot(false), Type(Type),
-      StOther(StOther), Name({Name.data(), Name.size()}) {}
+      StOther(StOther), NameLen(Name.size()), Name(Name.data()) {}
 
 StringRef SymbolBody::getName() const {
-  assert(!isLocal());
-  return StringRef(Name.S, Name.Len);
+  if (NameLen == (uint32_t)-1)
+    NameLen = strlen(Name);
+  return StringRef(Name, NameLen);
 }
 
 // Returns true if a symbol can be replaced at load-time by a symbol
@@ -192,8 +193,8 @@ template <class ELFT> typename ELFT::uin
 Defined::Defined(Kind K, StringRef Name, uint8_t StOther, uint8_t Type)
     : SymbolBody(K, Name, StOther, Type) {}
 
-Defined::Defined(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type)
-    : SymbolBody(K, NameOffset, StOther, Type) {}
+Defined::Defined(Kind K, const char *Name, uint8_t StOther, uint8_t Type)
+    : SymbolBody(K, Name, StOther, Type) {}
 
 template <class ELFT> bool DefinedRegular<ELFT>::isMipsPIC() const {
   if (!Section || !isFunc())
@@ -208,9 +209,9 @@ Undefined::Undefined(StringRef Name, uin
   this->File = File;
 }
 
-Undefined::Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type,
+Undefined::Undefined(const char *Name, uint8_t StOther, uint8_t Type,
                      InputFile *File)
-    : SymbolBody(SymbolBody::UndefinedKind, NameOffset, StOther, Type) {
+    : SymbolBody(SymbolBody::UndefinedKind, Name, StOther, Type) {
   this->File = File;
 }
 
@@ -282,14 +283,6 @@ void elf::printTraceSymbol(Symbol *Sym)
   outs() << B->getName() << "\n";
 }
 
-StringRef elf::getSymbolName(StringRef SymTab, SymbolBody &Body) {
-  if (Body.isLocal() && Body.getNameOffset())
-    return SymTab.data() + Body.getNameOffset();
-  if (!Body.isLocal())
-    return Body.getName();
-  return "";
-}
-
 template bool SymbolBody::hasThunk<ELF32LE>() const;
 template bool SymbolBody::hasThunk<ELF32BE>() const;
 template bool SymbolBody::hasThunk<ELF64LE>() const;

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=287737&r1=287736&r2=287737&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Tue Nov 22 22:57:25 2016
@@ -72,11 +72,6 @@ public:
 
   StringRef getName() const;
 
-  uint32_t getNameOffset() const {
-    assert(isLocal());
-    return NameOffset;
-  }
-
   uint8_t getVisibility() const { return StOther & 0x3; }
 
   bool isInGot() const { return GotIndex != -1U; }
@@ -105,8 +100,7 @@ public:
 
 protected:
   SymbolBody(Kind K, StringRef Name, uint8_t StOther, uint8_t Type);
-
-  SymbolBody(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type);
+  SymbolBody(Kind K, const char *Name, uint8_t StOther, uint8_t Type);
 
   const unsigned SymbolKind : 8;
 
@@ -143,21 +137,17 @@ public:
   bool isFile() const { return Type == llvm::ELF::STT_FILE; }
 
 protected:
-  struct Str {
-    const char *S;
-    size_t Len;
-  };
-  union {
-    Str Name;
-    uint32_t NameOffset;
-  };
+  // Local symbols are not inserted to the symbol table, so we usually
+  // don't need their names at all. We read symbol names lazily if possible.
+  mutable uint32_t NameLen = (uint32_t)-1;
+  const char *Name;
 };
 
 // The base class for any defined symbols.
 class Defined : public SymbolBody {
 public:
   Defined(Kind K, StringRef Name, uint8_t StOther, uint8_t Type);
-  Defined(Kind K, uint32_t NameOffset, uint8_t StOther, uint8_t Type);
+  Defined(Kind K, const char *Name, uint8_t StOther, uint8_t Type);
   static bool classof(const SymbolBody *S) { return S->isDefined(); }
 };
 
@@ -197,8 +187,9 @@ public:
   DefinedRegular(StringRef Name, uint8_t StOther, uint8_t Type, BitcodeFile *F)
       : DefinedRegular(Name, StOther, Type, 0, 0, NullInputSection, F) {}
 
-  DefinedRegular(const Elf_Sym &Sym, InputSectionBase<ELFT> *Section)
-      : Defined(SymbolBody::DefinedRegularKind, Sym.st_name, Sym.st_other,
+  DefinedRegular(const char *Name, const Elf_Sym &Sym,
+                 InputSectionBase<ELFT> *Section)
+      : Defined(SymbolBody::DefinedRegularKind, Name, Sym.st_other,
                 Sym.getType()),
         Value(Sym.st_value), Size(Sym.st_size),
         Section(Section ? Section->Repl : NullInputSection) {
@@ -262,7 +253,7 @@ public:
 class Undefined : public SymbolBody {
 public:
   Undefined(StringRef Name, uint8_t StOther, uint8_t Type, InputFile *F);
-  Undefined(uint32_t NameOffset, uint8_t StOther, uint8_t Type, InputFile *F);
+  Undefined(const char *Name, uint8_t StOther, uint8_t Type, InputFile *F);
 
   static bool classof(const SymbolBody *S) {
     return S->kind() == UndefinedKind;
@@ -462,8 +453,6 @@ inline Symbol *SymbolBody::symbol() {
                                     offsetof(Symbol, Body));
 }
 
-StringRef getSymbolName(StringRef SymTab, SymbolBody &Body);
-
 } // namespace elf
 } // namespace lld
 

Modified: lld/trunk/ELF/Writer.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Writer.cpp?rev=287737&r1=287736&r2=287737&view=diff
==============================================================================
--- lld/trunk/ELF/Writer.cpp (original)
+++ lld/trunk/ELF/Writer.cpp Tue Nov 22 22:57:25 2016
@@ -374,7 +374,6 @@ template <class ELFT> void Writer<ELFT>:
   if (!In<ELFT>::SymTab)
     return;
   for (elf::ObjectFile<ELFT> *F : Symtab<ELFT>::X->getObjectFiles()) {
-    StringRef StrTab = F->getStringTable();
     for (SymbolBody *B : F->getLocalSymbols()) {
       if (!B->IsLocal)
         fatal(getFilename(F) +
@@ -385,17 +384,14 @@ template <class ELFT> void Writer<ELFT>:
         continue;
       if (!includeInSymtab<ELFT>(*B))
         continue;
-      if (B->getNameOffset() >= StrTab.size())
-        fatal(getFilename(F) + ": invalid symbol name offset");
-      StringRef SymName(StrTab.data() + B->getNameOffset());
       InputSectionBase<ELFT> *Sec = DR->Section;
-      if (!shouldKeepInSymtab<ELFT>(Sec, SymName, *B))
+      if (!shouldKeepInSymtab<ELFT>(Sec, B->getName(), *B))
         continue;
       ++In<ELFT>::SymTab->NumLocals;
       if (Config->Relocatable)
         B->DynsymIndex = In<ELFT>::SymTab->NumLocals;
-      F->KeptLocalSyms.push_back(
-          std::make_pair(DR, In<ELFT>::SymTab->StrTabSec.addString(SymName)));
+      F->KeptLocalSyms.push_back(std::make_pair(
+          DR, In<ELFT>::SymTab->StrTabSec.addString(B->getName())));
     }
   }
 }
@@ -701,8 +697,8 @@ static void sortBySymbolsOrder(ArrayRef<
       auto *D = dyn_cast<DefinedRegular<ELFT>>(Body);
       if (!D || !D->Section)
         continue;
-      StringRef SymName = getSymbolName(File->getStringTable(), *Body);
-      auto It = Config->SymbolOrderingFile.find(CachedHashString(SymName));
+      auto It =
+          Config->SymbolOrderingFile.find(CachedHashString(Body->getName()));
       if (It == Config->SymbolOrderingFile.end())
         continue;
 




More information about the llvm-commits mailing list