diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -232,6 +232,9 @@ uint8_t Visibility = getVisibility(StOther); std::tie(S, WasInserted) = insert(Name, Visibility, CanOmitFromDynSym, File); + if (S->Traced) + printTraceUndefinedSymbol(Name, File); + // An undefined symbol with non default visibility must be satisfied // in the same DSO. if (WasInserted || (isa(S) && Visibility != STV_DEFAULT)) { diff --git a/lld/ELF/Symbols.h b/lld/ELF/Symbols.h --- a/lld/ELF/Symbols.h +++ b/lld/ELF/Symbols.h @@ -359,6 +359,7 @@ alignas(LazyObject) char F[sizeof(LazyObject)]; }; +void printTraceUndefinedSymbol(StringRef Name, const InputFile* File); void printTraceSymbol(Symbol *Sym); template diff --git a/lld/ELF/Symbols.cpp b/lld/ELF/Symbols.cpp --- a/lld/ELF/Symbols.cpp +++ b/lld/ELF/Symbols.cpp @@ -276,12 +276,19 @@ return ExportDynamic; } +// Print out a log message for --trace-symbol. +void elf::printTraceUndefinedSymbol(StringRef Name, const InputFile* File) { + message(toString(File) + ": reference to " + Name); +} + // Print out a log message for --trace-symbol. void elf::printTraceSymbol(Symbol *Sym) { - std::string S; + // Undefined symbols are traced via printTraceUndefinedSymbol if (Sym->isUndefined()) - S = ": reference to "; - else if (Sym->isLazy()) + return; + + std::string S; + if (Sym->isLazy()) S = ": lazy definition of "; else if (Sym->isShared()) S = ": shared definition of "; diff --git a/lld/test/ELF/trace-symbols.s b/lld/test/ELF/trace-symbols.s --- 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 @@ -79,7 +84,7 @@ # STARTLIB: trace-symbols.s.tmp1: reference to bar ## Check we do not crash when trying to trace special symbol. -# RUN: not ld.lld -trace-symbol=_end %t -o /dev/null +# RUN: not ld.lld -trace-symbol=_end %t -o %t3 .hidden hsymbol .globl _start diff --git a/lld/test/wasm/trace-symbol.ll b/lld/test/wasm/trace-symbol.ll --- 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 --- a/lld/wasm/SymbolTable.cpp +++ b/lld/wasm/SymbolTable.cpp @@ -378,6 +378,8 @@ Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name, File); + if (S->Traced) + printTraceSymbolUndefined(Name, File); auto Replace = [&]() { replaceSymbol(S, Name, ImportName, ImportModule, Flags, @@ -409,6 +411,8 @@ Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name, File); + if (S->Traced) + printTraceSymbolUndefined(Name, File); if (WasInserted) replaceSymbol(S, Name, Flags, File); @@ -428,6 +432,8 @@ Symbol *S; bool WasInserted; std::tie(S, WasInserted) = insert(Name, File); + if (S->Traced) + printTraceSymbolUndefined(Name, File); if (WasInserted) replaceSymbol(S, Name, ImportName, ImportModule, Flags, diff --git a/lld/wasm/Symbols.h b/lld/wasm/Symbols.h --- a/lld/wasm/Symbols.h +++ b/lld/wasm/Symbols.h @@ -439,6 +439,7 @@ }; void printTraceSymbol(Symbol *Sym); +void printTraceSymbolUndefined(StringRef Name, const InputFile* File); template T *replaceSymbol(Symbol *S, ArgT &&... Arg) { diff --git a/lld/wasm/Symbols.cpp b/lld/wasm/Symbols.cpp --- a/lld/wasm/Symbols.cpp +++ b/lld/wasm/Symbols.cpp @@ -312,12 +312,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 ";