[lld] r268310 - Teach Undefined symbols from which file they are created from.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Mon May 2 14:30:43 PDT 2016


Author: ruiu
Date: Mon May  2 16:30:42 2016
New Revision: 268310

URL: http://llvm.org/viewvc/llvm-project?rev=268310&view=rev
Log:
Teach Undefined symbols from which file they are created from.

This patch increases the size of Undefined by the size of a pointer,
but it wouldn't actually increase the size of memory that LLD uses
because we are not allocating the exact size but the size of the
largest SymbolBody.

Modified:
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/Symbols.cpp
    lld/trunk/ELF/Symbols.h
    lld/trunk/test/ELF/lto/combined-lto-object-name.ll

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=268310&r1=268309&r2=268310&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Mon May  2 16:30:42 2016
@@ -166,7 +166,6 @@ template <class ELFT> void SymbolTable<E
 
 // Returns a file from which symbol B was created.
 // If B does not belong to any file, returns a nullptr.
-// This function is slow, but it's okay as it is used only for error messages.
 template <class ELFT> InputFile *SymbolTable<ELFT>::findFile(SymbolBody *B) {
   // If this symbol has a definition, follow pointers in the symbol to its
   // defining file.
@@ -177,21 +176,8 @@ template <class ELFT> InputFile *SymbolT
     return SS->File;
   if (auto *BC = dyn_cast<DefinedBitcode>(B))
     return BC->File;
-  // If not, we might be able to find it by searching symbol tables of files.
-  // This code is generally only used for undefined symbols. Note that we can't
-  // rely exclusively on a file search because we may find what was originally
-  // an undefined symbol that was later replaced with a defined symbol, and we
-  // want to return the file that defined the symbol.
-  for (const std::unique_ptr<ObjectFile<ELFT>> &F : ObjectFiles) {
-    ArrayRef<SymbolBody *> Syms = F->getSymbols();
-    if (std::find(Syms.begin(), Syms.end(), B) != Syms.end())
-      return F.get();
-  }
-  for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles) {
-    ArrayRef<Symbol *> Syms = F->getSymbols();
-    if (std::find(Syms.begin(), Syms.end(), B->symbol()) != Syms.end())
-      return F.get();
-  }
+  if (auto *U = dyn_cast<Undefined>(B))
+    return U->File;
   return nullptr;
 }
 
@@ -253,8 +239,8 @@ template <typename ELFT>
 std::string SymbolTable<ELFT>::conflictMsg(SymbolBody *Existing,
                                            InputFile *NewFile) {
   StringRef Sym = Existing->getName();
-  return demangle(Sym) + " in " + getFilename(findFile(Existing)) + " and " +
-         getFilename(NewFile);
+  return demangle(Sym) + " in " + getFilename(Existing->getSourceFile<ELFT>()) +
+         " and " + getFilename(NewFile);
 }
 
 template <class ELFT> Symbol *SymbolTable<ELFT>::addUndefined(StringRef Name) {
@@ -274,6 +260,7 @@ Symbol *SymbolTable<ELFT>::addUndefined(
   if (WasInserted) {
     S->Binding = Binding;
     replaceBody<Undefined>(S, Name, StOther, Type);
+    cast<Undefined>(S->body())->File = File;
     return S;
   }
   if (Binding != STB_WEAK &&

Modified: lld/trunk/ELF/Symbols.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.cpp?rev=268310&r1=268309&r2=268310&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.cpp (original)
+++ lld/trunk/ELF/Symbols.cpp Mon May  2 16:30:42 2016
@@ -129,6 +129,18 @@ bool SymbolBody::isPreemptible() const {
   return symbol()->Visibility == STV_DEFAULT;
 }
 
+template <class ELFT> InputFile *SymbolBody::getSourceFile() {
+  if (auto *S = dyn_cast<DefinedRegular<ELFT>>(this))
+    return S->Section ? S->Section->getFile() : nullptr;
+  if (auto *S = dyn_cast<SharedSymbol<ELFT>>(this))
+    return S->File;
+  if (auto *S = dyn_cast<DefinedBitcode>(this))
+    return S->File;
+  if (auto *S = dyn_cast<Undefined>(this))
+    return S->File;
+  return nullptr;
+}
+
 template <class ELFT>
 typename ELFT::uint SymbolBody::getVA(typename ELFT::uint Addend) const {
   typename ELFT::uint OutVA = getSymVA<ELFT>(*this, Addend);
@@ -258,6 +270,11 @@ bool Symbol::includeInDynsym() const {
          (body()->isUndefined() && Config->Shared);
 }
 
+template InputFile *SymbolBody::template getSourceFile<ELF32LE>();
+template InputFile *SymbolBody::template getSourceFile<ELF32BE>();
+template InputFile *SymbolBody::template getSourceFile<ELF64LE>();
+template InputFile *SymbolBody::template getSourceFile<ELF64BE>();
+
 template uint32_t SymbolBody::template getVA<ELF32LE>(uint32_t) const;
 template uint32_t SymbolBody::template getVA<ELF32BE>(uint32_t) const;
 template uint64_t SymbolBody::template getVA<ELF64LE>(uint64_t) const;

Modified: lld/trunk/ELF/Symbols.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Symbols.h?rev=268310&r1=268309&r2=268310&view=diff
==============================================================================
--- lld/trunk/ELF/Symbols.h (original)
+++ lld/trunk/ELF/Symbols.h Mon May  2 16:30:42 2016
@@ -108,6 +108,10 @@ public:
   template <class ELFT> typename ELFT::uint getThunkVA() const;
   template <class ELFT> typename ELFT::uint getSize() const;
 
+  // Returns the file from which the symbol was created.
+  // For logging purpose only.
+  template <class ELFT> InputFile *getSourceFile();
+
 protected:
   SymbolBody(Kind K, StringRef Name, uint8_t StOther, uint8_t Type);
 
@@ -259,6 +263,10 @@ public:
   static bool classof(const SymbolBody *S) {
     return S->kind() == UndefinedKind;
   }
+
+  // The file this undefined symbol was created from.
+  // For logging purpose only.
+  InputFile *File = nullptr;
 };
 
 template <class ELFT> class SharedSymbol : public Defined {

Modified: lld/trunk/test/ELF/lto/combined-lto-object-name.ll
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/lto/combined-lto-object-name.ll?rev=268310&r1=268309&r2=268310&view=diff
==============================================================================
--- lld/trunk/test/ELF/lto/combined-lto-object-name.ll (original)
+++ lld/trunk/test/ELF/lto/combined-lto-object-name.ll Mon May  2 16:30:42 2016
@@ -11,4 +11,4 @@ define void @_start() {
   ret void
 }
 
-; CHECK: undefined symbol: foo in LLD-INTERNAL-combined-lto-object
+; CHECK: undefined symbol: foo in {{.*}}combined-lto-object-name.ll.tmp.o




More information about the llvm-commits mailing list