[lld] Trace all references with lld --trace-symbol

Previously undefined symbol references were only traced if they were
seen before that definition.

Fixes https://bugs.llvm.org/show_bug.cgi?id=41878

Differential Revision: https://reviews.llvm.org/D61929

llvm-svn: 361636
diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp
index d44b24d..45c545d 100644
--- a/lld/ELF/Symbols.cpp
+++ b/lld/ELF/Symbols.cpp
@@ -291,7 +291,7 @@
 }
 
 // Print out a log message for --trace-symbol.
-void elf::printTraceSymbol(Symbol *Sym) {
+void elf::printTraceSymbol(const Symbol *Sym) {
   std::string S;
   if (Sym->isUndefined())
     S = ": reference to ";
@@ -413,6 +413,9 @@
     return;
   }
 
+  if (Traced)
+    printTraceSymbol(&Other);
+
   if (isShared() || isLazy() || (isUndefined() && Other.Binding != STB_WEAK))
     Binding = Other.Binding;
 
diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h
index 04c23b5..64fa30d 100644
--- a/lld/ELF/Symbols.h
+++ b/lld/ELF/Symbols.h
@@ -464,7 +464,7 @@
   AssertSymbol<LazyObject>();
 }
 
-void printTraceSymbol(Symbol *Sym);
+void printTraceSymbol(const Symbol *Sym);
 
 size_t Symbol::getSymbolSize() const {
   switch (kind()) {
diff --git a/lld/test/ELF/trace-symbols.s b/lld/test/ELF/trace-symbols.s
index dfcce16..b6f8bea 100644
--- a/lld/test/ELF/trace-symbols.s
+++ b/lld/test/ELF/trace-symbols.s
@@ -28,10 +28,15 @@
 # OBJECTD1FOO: trace-symbols.s.tmp1: definition of foo
 # OBJECTD1FOO: trace-symbols.s.tmp2: definition of foo
 
+# RUN: ld.lld -y foo %t1 %t2 %t -o %t3 | FileCheck -check-prefix=REFLAST %s
+# REFLAST: trace-symbols.s.tmp1: definition of foo
+# REFLAST: trace-symbols.s.tmp2: definition of foo
+# REFLAST: trace-symbols.s.tmp: reference to foo
+
 # RUN: ld.lld -y foo -trace-symbol=common -trace-symbol=hsymbol \
 # RUN:   %t %t1 %t2 -o %t3 | FileCheck -check-prefix=OBJECTD2FOO %s
 # RUN: ld.lld -y foo -y common --trace-symbol=hsymbol \
-# RUN:   %t %t2 %t1 -o /dev/null | FileCheck -check-prefix=OBJECTD2FOO %s
+# RUN:   %t %t2 %t1 -o %t3 | FileCheck -check-prefix=OBJECTD2FOO %s
 # RUN: ld.lld -y foo -y common %t %t1.so %t2 -o %t3 | \
 # RUN:   FileCheck -check-prefix=OBJECTD2FOO %s
 # OBJECTD2FOO: trace-symbols.s.tmp2: definition of foo
diff --git a/lld/test/wasm/trace-symbol.ll b/lld/test/wasm/trace-symbol.ll
index 4d16701..e589de0 100644
--- a/lld/test/wasm/trace-symbol.ll
+++ b/lld/test/wasm/trace-symbol.ll
@@ -1,9 +1,10 @@
 ; RUN: llc -filetype=obj %p/Inputs/ret32.ll -o %t.ret32.o
-; RUN: llc -filetype=obj -o %t.o %s
-; RUN: wasm-ld -o %t.wasm %t.o %t.ret32.o -y ret32 -y _start | FileCheck %s -check-prefix=BOTH
+; RUN: llc -filetype=obj -o %t.start.o %s
+; RUN: wasm-ld -o %t.wasm %t.start.o %t.ret32.o -y ret32 -y _start | FileCheck %s -check-prefix=BOTH
+; RUN: wasm-ld -o %t.wasm %t.ret32.o %t.start.o -y ret32 -y _start | FileCheck %s -check-prefix=REVERSED
 
 ; check alias
-; RUN: wasm-ld -o %t.wasm %t.o %t.ret32.o -trace-symbol=_start | FileCheck %s -check-prefixes=JUST-START
+; RUN: wasm-ld -o %t.wasm %t.start.o %t.ret32.o -trace-symbol=_start | FileCheck %s -check-prefixes=JUST-START
 
 target triple = "wasm32-unknown-unknown"
 
@@ -15,9 +16,13 @@
   ret void
 }
 
-; BOTH: .o: definition of _start
-; BOTH: .o: reference to ret32
-; BOTH: .ret32.o: definition of ret32
+; BOTH:          start.o: definition of _start
+; BOTH-NEXT:     start.o: reference to ret32
+; BOTH-NEXT:     ret32.o: definition of ret32
 
-; JUST-START: .o: definition of _start
+; REVERSED:      ret32.o: definition of ret32
+; REVERSED-NEXT: start.o: definition of _start
+; REVERSED-NEXT: start.o: reference to ret32
+
+; JUST-START: start.o: definition of _start
 ; JUST-START-NOT: ret32
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index ce1aa51..244e24e 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -389,6 +389,8 @@
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name, File);
+  if (S->Traced)
+    printTraceSymbolUndefined(Name, File);
 
   auto Replace = [&]() {
     replaceSymbol<UndefinedFunction>(S, Name, ImportName, ImportModule, Flags,
@@ -420,6 +422,8 @@
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name, File);
+  if (S->Traced)
+    printTraceSymbolUndefined(Name, File);
 
   if (WasInserted)
     replaceSymbol<UndefinedData>(S, Name, Flags, File);
@@ -439,6 +443,8 @@
   Symbol *S;
   bool WasInserted;
   std::tie(S, WasInserted) = insert(Name, File);
+  if (S->Traced)
+    printTraceSymbolUndefined(Name, File);
 
   if (WasInserted)
     replaceSymbol<UndefinedGlobal>(S, Name, ImportName, ImportModule, Flags,
diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp
index ba5bb5d..07b895a 100644
--- a/lld/wasm/Symbols.cpp
+++ b/lld/wasm/Symbols.cpp
@@ -307,12 +307,19 @@
   llvm_unreachable("invalid symbol kind");
 }
 
+
+void lld::wasm::printTraceSymbolUndefined(StringRef Name, const InputFile* File) {
+  message(toString(File) + ": reference to " + Name);
+}
+
 // Print out a log message for --trace-symbol.
 void lld::wasm::printTraceSymbol(Symbol *Sym) {
-  std::string S;
+  // Undefined symbols are traced via printTraceSymbolUndefined
   if (Sym->isUndefined())
-    S = ": reference to ";
-  else if (Sym->isLazy())
+    return;
+
+  std::string S;
+  if (Sym->isLazy())
     S = ": lazy definition of ";
   else
     S = ": definition of ";
diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h
index 8b8b8eb..0bac81c 100644
--- a/lld/wasm/Symbols.h
+++ b/lld/wasm/Symbols.h
@@ -457,6 +457,7 @@
 };
 
 void printTraceSymbol(Symbol *Sym);
+void printTraceSymbolUndefined(StringRef Name, const InputFile* File);
 
 template <typename T, typename... ArgT>
 T *replaceSymbol(Symbol *S, ArgT &&... Arg) {