[lld] r273536 - Implement --trace-symbol=symbol option.

Rui Ueyama via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 23 00:00:17 PDT 2016


Author: ruiu
Date: Thu Jun 23 02:00:17 2016
New Revision: 273536

URL: http://llvm.org/viewvc/llvm-project?rev=273536&view=rev
Log:
Implement --trace-symbol=symbol option.

Patch by Shridhar Joshi.

This option provides names of all the link time modules which define and
reference symbols requested by user. This helps to speed up application
development by detecting references causing undefined symbols.
It also helps in detecting symbols being resolved to wrong (unintended)
definitions in case of applications containing multiple definitions for
same symbols with different types, bindings.

Implements PR28226.

Added:
    lld/trunk/test/ELF/Inputs/trace-symbols-foo-strong.s
    lld/trunk/test/ELF/Inputs/trace-symbols-foo-weak.s
    lld/trunk/test/ELF/trace-symbols.s
Modified:
    lld/trunk/ELF/Config.h
    lld/trunk/ELF/Driver.cpp
    lld/trunk/ELF/InputFiles.cpp
    lld/trunk/ELF/InputFiles.h
    lld/trunk/ELF/Options.td
    lld/trunk/ELF/SymbolTable.cpp
    lld/trunk/ELF/SymbolTable.h

Modified: lld/trunk/ELF/Config.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Config.h?rev=273536&r1=273535&r2=273536&view=diff
==============================================================================
--- lld/trunk/ELF/Config.h (original)
+++ lld/trunk/ELF/Config.h Thu Jun 23 02:00:17 2016
@@ -12,6 +12,7 @@
 
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/ELF.h"
 
 #include <vector>
@@ -59,6 +60,7 @@ struct Configuration {
   llvm::StringRef OutputFile;
   llvm::StringRef SoName;
   llvm::StringRef Sysroot;
+  llvm::StringSet<> TraceSymbol;
   std::string RPath;
   std::vector<Version> SymbolVersions;
   std::vector<llvm::StringRef> DynamicList;

Modified: lld/trunk/ELF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Driver.cpp?rev=273536&r1=273535&r2=273536&view=diff
==============================================================================
--- lld/trunk/ELF/Driver.cpp (original)
+++ lld/trunk/ELF/Driver.cpp Thu Jun 23 02:00:17 2016
@@ -417,6 +417,9 @@ void LinkerDriver::readConfigs(opt::Inpu
     if (Optional<MemoryBufferRef> Buffer = readFile(Arg->getValue()))
       parseVersionScript(*Buffer);
   }
+
+  for (auto *Arg : Args.filtered(OPT_trace_symbol))
+    Config->TraceSymbol.insert(Arg->getValue());
 }
 
 void LinkerDriver::createFiles(opt::InputArgList &Args) {
@@ -499,6 +502,7 @@ template <class ELFT> void LinkerDriver:
   Symtab.scanShlibUndefined();
   Symtab.scanDynamicList();
   Symtab.scanVersionScript();
+  Symtab.traceDefined();
 
   Symtab.addCombinedLtoObject();
   if (HasError)

Modified: lld/trunk/ELF/InputFiles.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.cpp?rev=273536&r1=273535&r2=273536&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.cpp (original)
+++ lld/trunk/ELF/InputFiles.cpp Thu Jun 23 02:00:17 2016
@@ -313,6 +313,14 @@ elf::ObjectFile<ELFT>::createInputSectio
   return new (IAlloc.Allocate()) InputSection<ELFT>(this, &Sec);
 }
 
+// Print the module names which reference the notified
+// symbols provided through -y or --trace-symbol option.
+template <class ELFT>
+void elf::ObjectFile<ELFT>::traceUndefined(StringRef Name) {
+  if (!Config->TraceSymbol.empty() && Config->TraceSymbol.count(Name))
+    outs() << getFilename(this) << ": reference to " << Name << "\n";
+}
+
 template <class ELFT> void elf::ObjectFile<ELFT>::initializeSymbols() {
   this->initStringTable();
   Elf_Sym_Range Syms = this->getElfSymbols(false);
@@ -350,6 +358,7 @@ SymbolBody *elf::ObjectFile<ELFT>::creat
 
   switch (Sym->st_shndx) {
   case SHN_UNDEF:
+    traceUndefined(Name);
     return elf::Symtab<ELFT>::X
         ->addUndefined(Name, Binding, Sym->st_other, Sym->getType(),
                        /*CanOmitFromDynSym*/ false, this)

Modified: lld/trunk/ELF/InputFiles.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/InputFiles.h?rev=273536&r1=273535&r2=273536&view=diff
==============================================================================
--- lld/trunk/ELF/InputFiles.h (original)
+++ lld/trunk/ELF/InputFiles.h Thu Jun 23 02:00:17 2016
@@ -140,6 +140,8 @@ public:
 
   const Elf_Shdr *getSymbolTable() const { return this->Symtab; };
 
+  void traceUndefined(StringRef Name);
+
   // Get MIPS GP0 value defined by this file. This value represents the gp value
   // used to create the relocatable object and required to support
   // R_MIPS_GPREL16 / R_MIPS_GPREL32 relocations.

Modified: lld/trunk/ELF/Options.td
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/Options.td?rev=273536&r1=273535&r2=273536&view=diff
==============================================================================
--- lld/trunk/ELF/Options.td (original)
+++ lld/trunk/ELF/Options.td Thu Jun 23 02:00:17 2016
@@ -142,6 +142,8 @@ def threads: F<"threads">, HelpText<"Ena
 
 def trace: F<"trace">, HelpText<"Print the names of the input files">;
 
+def trace_symbol : J<"trace-symbol=">, HelpText<"Trace references to symbols">;
+
 def undefined: J<"undefined=">,
   HelpText<"Force undefined symbol during linking">;
 
@@ -194,6 +196,7 @@ def alias_soname_soname: S<"soname">, Al
 def alias_strip_all: F<"s">, Alias<strip_all>;
 def alias_strip_debug_S: F<"S">, Alias<strip_debug>;
 def alias_trace: F<"t">, Alias<trace>;
+def alias_trace_symbol_y : JS<"y">, Alias<trace_symbol>;
 def alias_undefined_u: JoinedOrSeparate<["-"], "u">, Alias<undefined>;
 def alias_wrap_wrap: J<"wrap=">, Alias<wrap>;
 

Modified: lld/trunk/ELF/SymbolTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.cpp?rev=273536&r1=273535&r2=273536&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.cpp (original)
+++ lld/trunk/ELF/SymbolTable.cpp Thu Jun 23 02:00:17 2016
@@ -541,6 +541,17 @@ template <class ELFT> void SymbolTable<E
   }
 }
 
+// Print the module names which define the notified
+// symbols provided through -y or --trace-symbol option.
+template <class ELFT> void SymbolTable<ELFT>::traceDefined() {
+  for (const auto &Symbol : Config->TraceSymbol)
+    if (SymbolBody *B = find(Symbol.getKey()))
+      if (B->isDefined() || B->isCommon())
+        if (InputFile *File = B->getSourceFile<ELFT>())
+          outs() << getFilename(File) << ": definition of "
+                 << B->getName() << "\n";
+}
+
 template class elf::SymbolTable<ELF32LE>;
 template class elf::SymbolTable<ELF32BE>;
 template class elf::SymbolTable<ELF64LE>;

Modified: lld/trunk/ELF/SymbolTable.h
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/ELF/SymbolTable.h?rev=273536&r1=273535&r2=273536&view=diff
==============================================================================
--- lld/trunk/ELF/SymbolTable.h (original)
+++ lld/trunk/ELF/SymbolTable.h Thu Jun 23 02:00:17 2016
@@ -82,6 +82,8 @@ public:
   void scanShlibUndefined();
   void scanDynamicList();
   void scanVersionScript();
+  void traceDefined();
+
   SymbolBody *find(StringRef Name);
   void wrap(StringRef Name);
 

Added: lld/trunk/test/ELF/Inputs/trace-symbols-foo-strong.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/trace-symbols-foo-strong.s?rev=273536&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/trace-symbols-foo-strong.s (added)
+++ lld/trunk/test/ELF/Inputs/trace-symbols-foo-strong.s Thu Jun 23 02:00:17 2016
@@ -0,0 +1,14 @@
+.text
+.globl	foo
+.type	foo, @function
+foo:
+nop
+
+.globl	bar
+.type	bar, @function
+bar:
+nop
+
+.global func2
+.type   func2, @function
+func2:

Added: lld/trunk/test/ELF/Inputs/trace-symbols-foo-weak.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/Inputs/trace-symbols-foo-weak.s?rev=273536&view=auto
==============================================================================
--- lld/trunk/test/ELF/Inputs/trace-symbols-foo-weak.s (added)
+++ lld/trunk/test/ELF/Inputs/trace-symbols-foo-weak.s Thu Jun 23 02:00:17 2016
@@ -0,0 +1,12 @@
+.comm	common,4,4
+.text
+.weak	foo
+.type	foo, @function
+foo:
+callq bar at PLT
+
+.globl  func1
+.type   func1, @function
+func1:
+call func2 at PLT
+

Added: lld/trunk/test/ELF/trace-symbols.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/ELF/trace-symbols.s?rev=273536&view=auto
==============================================================================
--- lld/trunk/test/ELF/trace-symbols.s (added)
+++ lld/trunk/test/ELF/trace-symbols.s Thu Jun 23 02:00:17 2016
@@ -0,0 +1,84 @@
+# Test -y symbol and -trace-symbol=symbol
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+# RUN: %p/Inputs/trace-symbols-foo-weak.s -o %t1
+# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux \
+# RUN: %p/Inputs/trace-symbols-foo-strong.s -o %t2
+# RUN: ld.lld -shared %t1 -o %t1.so
+# RUN: ld.lld -shared %t2 -o %t2.so
+# RUN: ar -r %t1.a %t1
+# RUN: ar -r %t2.a %t2
+
+# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
+# RUN:   %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTRFOO %s
+# OBJECTRFOO: trace-symbols.s.tmp: reference to foo
+
+# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
+# RUN:   %t %t1 %t2 -o %t3 2>&1 | not FileCheck -check-prefix=OBJECTDCOMMON %s
+# OBJECTDCOMMON: trace-symbols.s.tmp1: definition of common
+
+# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
+# RUN:   %t %t1 %t2 -o %t3 2>&1 | not FileCheck -check-prefix=OBJECTD1FOO %s
+# RUN: ld.lld -y foo -y common %t %t2 %t1 -o %t3 2>&1 | not FileCheck \
+# RUN:   -check-prefix=OBJECTD1FOO %s
+# OBJECTD1FOO: trace-symbols.s.tmp1: definition of foo
+
+# RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
+# RUN:   %t %t1 %t2 -o %t3 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s
+# RUN: ld.lld -y foo -y common --trace-symbol=hsymbol \
+# RUN:   %t %t2 %t1 -o %t4 2>&1 | FileCheck -check-prefix=OBJECTD2FOO %s
+# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \
+# RUN:   FileCheck -check-prefix=OBJECTD2FOO %s
+# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \
+# RUN:   FileCheck -check-prefix=OBJECTD2FOO %s
+# OBJECTD2FOO: trace-symbols.s.tmp2: definition of foo
+
+# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \
+# RUN:   FileCheck -check-prefix=SHLIBDCOMMON %s
+# SHLIBDCOMMON: trace-symbols.s.tmp1.so: definition of common
+
+# RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 2>&1 | \
+# RUN:   not FileCheck -check-prefix=SHLIBD1FOO %s
+# RUN: ld.lld -y foo -y common %t %t1.so %t2.so -o %t3 2>&1 | \
+# RUN:   FileCheck -check-prefix=SHLIBD1FOO %s
+# RUN: ld.lld -y foo %t %t1.so %t2.a -o %t3 | \
+# RUN:   FileCheck -check-prefix=SHLIBD1FOO %s
+# SHLIBD1FOO: trace-symbols.s.tmp1.so: definition of foo
+
+# RUN: ld.lld -y foo -y common %t %t2.so %t1.so -o %t3 2>&1 | \
+# RUN:   FileCheck -check-prefix=SHLIBD2FOO %s
+# RUN: ld.lld -y foo %t %t1.a %t2.so -o %t3 | \
+# RUN:   not FileCheck -check-prefix=SHLIBD2FOO %s
+# SHLIBD2FOO: trace-symbols.s.tmp2.so: definition of foo
+
+# RUN: ld.lld -y foo -y common %t %t2 %t1.a -o %t3 2>&1 | \
+# RUN:   not FileCheck -check-prefix=ARCHIVEDCOMMON %s
+# ARCHIVEDCOMMON: trace-symbols.s.tmp1.a(trace-symbols.s.tmp1): definition of \
+# common
+
+# RUN: ld.lld -y foo %t %t1.a %t2.so -o %t3 | \
+# RUN:   FileCheck -check-prefix=ARCHIVED1FOO %s
+# ARCHIVED1FOO: trace-symbols.s.tmp1.a(trace-symbols.s.tmp1): definition of foo
+
+# RUN: ld.lld -y foo %t %t1.a %t2.a -o %t3 | \
+# RUN:   FileCheck -check-prefix=ARCHIVED2FOO %s
+# ARCHIVED2FOO: trace-symbols.s.tmp2.a(trace-symbols.s.tmp2): definition of foo
+
+# RUN: ld.lld -y bar %t %t1.so %t2.so -o %t3 | \
+# RUN:   FileCheck -check-prefix=SHLIBDBAR %s
+# SHLIBDBAR: trace-symbols.s.tmp2.so: definition of bar
+
+# RUN: ld.lld -y foo -y bar %t %t1.so %t2.so -o %t3 | \
+# RUN:   not FileCheck -check-prefix=SHLIBRBAR %s
+# SHLIBRBAR: trace-symbols.s.tmp1.so: reference to bar
+
+# RUN: ld.lld -y foo -y bar %t -u bar --start-lib %t1 %t2 --end-lib -o %t3 | \
+# RUN:   FileCheck -check-prefix=STARTLIB %s
+# STARTLIB: trace-symbols.s.tmp1: reference to bar
+
+.hidden hsymbol
+.globl	_start
+.type	_start, @function
+_start:
+call foo




More information about the llvm-commits mailing list