[PATCH] D76999: [ELF] Print versioned name for better "undefined symbol" diagnostics
Fangrui Song via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Tue Mar 31 09:22:22 PDT 2020
MaskRay updated this revision to Diff 253911.
MaskRay added a comment.
Improve test comments
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D76999/new/
https://reviews.llvm.org/D76999
Files:
lld/ELF/Symbols.cpp
lld/ELF/Symbols.h
lld/test/ELF/undef-suggest-version.s
Index: lld/test/ELF/undef-suggest-version.s
===================================================================
--- /dev/null
+++ lld/test/ELF/undef-suggest-version.s
@@ -0,0 +1,57 @@
+# REQUIRES: x86
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o
+# RUN: echo 'v1 {bar;};' > %t.ver
+# RUN: ld.lld -shared --version-script %t.ver %t.o -o %t.so
+
+## For an unversioned undefined symbol, check we can suggest the symbol with the
+## default version.
+# RUN: echo 'call bat' | llvm-mc -filetype=obj -triple=x86_64 - -o %tdef1.o
+# RUN: not ld.lld %t.so %tdef1.o -o /dev/null 2>&1 | FileCheck --check-prefix=DEFAULT1 %s
+
+# DEFAULT1: error: undefined symbol: bat
+# DEFAULT1-NEXT: >>> referenced by {{.*}}.o:(.text+0x1)
+# DEFAULT1-NEXT: >>> did you mean: bar{{$}}
+# DEFAULT1-NEXT: >>> defined in: {{.*}}.so
+
+## For a versioned undefined symbol, check we can suggest the symbol with the
+## default version.
+# RUN: echo '.symver bar.v2,bar at v2; call bar.v2' | llvm-mc -filetype=obj -triple=x86_64 - -o %tdef2.o
+# RUN: not ld.lld %t.so %tdef2.o -o /dev/null 2>&1 | FileCheck --check-prefix=DEFAULT2 %s
+
+# DEFAULT2: error: undefined symbol: bar at v2
+# DEFAULT2-NEXT: >>> referenced by {{.*}}.o:(.text+0x1)
+# DEFAULT2-NEXT: >>> did you mean: bar{{$}}
+# DEFAULT2-NEXT: >>> defined in: {{.*}}.so
+
+## For an unversioned undefined symbol, check we can suggest a symbol with
+## a non-default version.
+# RUN: echo 'call foo; call _Z3fooi' | llvm-mc -filetype=obj -triple=x86_64 - -o %thidden1.o
+# RUN: not ld.lld %t.so %thidden1.o -o /dev/null 2>&1 | FileCheck --check-prefix=HIDDEN1 %s
+
+# HIDDEN1: error: undefined symbol: foo
+# HIDDEN1-NEXT: >>> referenced by {{.*}}.o:(.text+0x1)
+# HIDDEN1-NEXT: >>> did you mean: foo at v1
+# HIDDEN1-NEXT: >>> defined in: {{.*}}.so
+# HIDDEN1-EMPTY:
+# HIDDEN1-NEXT: error: undefined symbol: foo(int)
+# HIDDEN1-NEXT: >>> referenced by {{.*}}.o:(.text+0x6)
+# HIDDEN1-NEXT: >>> did you mean: foo(int)@v1
+# HIDDEN1-NEXT: >>> defined in: {{.*}}.so
+
+## For a versioned undefined symbol, check we can suggest a symbol with
+## a different version.
+# RUN: echo '.symver foo.v2,foo at v2; call foo.v2' | llvm-mc -filetype=obj -triple=x86_64 - -o %thidden2.o
+# RUN: not ld.lld %t.so %thidden2.o -o /dev/null 2>&1 | FileCheck --check-prefix=HIDDEN2 %s
+
+# HIDDEN2: error: undefined symbol: foo at v2
+# HIDDEN2-NEXT: >>> referenced by {{.*}}.o:(.text+0x1)
+# HIDDEN2-NEXT: >>> did you mean: foo at v1
+# HIDDEN2-NEXT: >>> defined in: {{.*}}.so
+
+## %t.so exports bar@@v1 and two VERSYM_HIDDEN symbols: foo at v1 and _Z3fooi at v1.
+.globl foo.v1, _Z3fooi.v1, bar
+.symver foo.v1,foo at v1
+.symver _Z3fooi.v1,_Z3fooi at v1
+foo.v1:
+_Z3fooi.v1:
+bar:
Index: lld/ELF/Symbols.h
===================================================================
--- lld/ELF/Symbols.h
+++ lld/ELF/Symbols.h
@@ -21,6 +21,8 @@
#include "llvm/Object/ELF.h"
namespace lld {
+// Print the versioned name, optionally demangled. This function is used by
+// diagnostics for better context.
std::string toString(const elf::Symbol &);
// There are two different ways to convert an Archive::Symbol to a string:
Index: lld/ELF/Symbols.cpp
===================================================================
--- lld/ELF/Symbols.cpp
+++ lld/ELF/Symbols.cpp
@@ -31,7 +31,18 @@
return std::string(symName);
}
-std::string toString(const elf::Symbol &b) { return demangle(b.getName()); }
+std::string toString(const elf::Symbol &sym) {
+ StringRef name = sym.getName();
+ std::string ret = demangle(name);
+
+ // If sym comes from symtab, its name may have been truncated at '@' by
+ // SymbolTable::insert() or Symbol::parseSymbolVersion(). Add the trailing
+ // part. This check is safe because every symbol name ends with '\0'.
+ if (name.data()[name.size()] == '@')
+ ret += name.data() + name.size();
+ return ret;
+}
+
std::string toELFString(const Archive::Symbol &b) {
return demangle(b.getName());
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D76999.253911.patch
Type: text/x-patch
Size: 3950 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200331/7111a4d3/attachment-0001.bin>
More information about the llvm-commits
mailing list