summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNicholas Wilson <nicholas@nicholaswilson.me.uk>2018-03-13 13:30:04 +0000
committerNicholas Wilson <nicholas@nicholaswilson.me.uk>2018-03-13 13:30:04 +0000
commit531769b9f9ffdc38a60869c595115941747e2449 (patch)
tree22b3f1c07088c91956ea693c30a2e5f5aba98120
parent88d9ffc973cbefda1832c98ff80e31759a3382c1 (diff)
downloadbcm5719-llvm-531769b9f9ffdc38a60869c595115941747e2449.tar.gz
bcm5719-llvm-531769b9f9ffdc38a60869c595115941747e2449.zip
[WebAssembly] Demangle symbol names for use by the browser debugger
Differential Revision: https://reviews.llvm.org/D44316 llvm-svn: 327392
-rw-r--r--lld/test/wasm/cxx-mangling.ll66
-rw-r--r--lld/wasm/Driver.cpp6
-rw-r--r--lld/wasm/Writer.cpp6
3 files changed, 75 insertions, 3 deletions
diff --git a/lld/test/wasm/cxx-mangling.ll b/lld/test/wasm/cxx-mangling.ll
new file mode 100644
index 00000000000..8b73ca9bfe2
--- /dev/null
+++ b/lld/test/wasm/cxx-mangling.ll
@@ -0,0 +1,66 @@
+; RUN: llc -filetype=obj %s -o %t.o
+; RUN: wasm-ld --demangle --check-signatures -o %t_demangle.wasm %t.o
+; RUN: obj2yaml %t_demangle.wasm | FileCheck %s
+; RUN: wasm-ld --no-demangle --check-signatures -o %t_nodemangle.wasm %t.o
+; RUN: obj2yaml %t_nodemangle.wasm | FileCheck %s
+
+target triple = "wasm32-unknown-unknown-wasm"
+
+; Check that the EXPORT name is still mangled, but that the "name" custom
+; section contains the unmangled name.
+
+define void @_Z3fooi(i32 %arg) {
+ ret void
+}
+
+declare extern_weak void @_Z3bari(i32 %arg)
+
+define void @_start() {
+ call void @_Z3fooi(i32 1)
+ call void @_Z3bari(i32 1)
+ ret void
+}
+
+; CHECK: - Type: EXPORT
+; CHECK-NEXT: Exports:
+; CHECK-NEXT: - Name: memory
+; CHECK-NEXT: Kind: MEMORY
+; CHECK-NEXT: Index: 0
+; CHECK-NEXT: - Name: __heap_base
+; CHECK-NEXT: Kind: GLOBAL
+; CHECK-NEXT: Index: 1
+; CHECK-NEXT: - Name: __data_end
+; CHECK-NEXT: Kind: GLOBAL
+; CHECK-NEXT: Index: 2
+; CHECK-NEXT: - Name: _start
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 3
+; CHECK-NEXT: - Name: _Z3fooi
+; CHECK-NEXT: Kind: FUNCTION
+; CHECK-NEXT: Index: 2
+; CHECK-NEXT: - Type: CODE
+; CHECK-NEXT: Functions:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 0B
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 000B
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 0B
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Locals:
+; CHECK-NEXT: Body: 410110828080800041011081808080000B
+; CHECK-NEXT: - Type: CUSTOM
+; CHECK-NEXT: Name: name
+; CHECK-NEXT: FunctionNames:
+; CHECK-NEXT: - Index: 0
+; CHECK-NEXT: Name: __wasm_call_ctors
+; CHECK-NEXT: - Index: 1
+; CHECK-NEXT: Name: 'undefined function bar(int)'
+; CHECK-NEXT: - Index: 2
+; CHECK-NEXT: Name: 'foo(int)'
+; CHECK-NEXT: - Index: 3
+; CHECK-NEXT: Name: _start
+; CHECK-NEXT: ...
diff --git a/lld/wasm/Driver.cpp b/lld/wasm/Driver.cpp
index 443def7587d..cdd396b8ee3 100644
--- a/lld/wasm/Driver.cpp
+++ b/lld/wasm/Driver.cpp
@@ -17,6 +17,7 @@
#include "lld/Common/Args.h"
#include "lld/Common/ErrorHandler.h"
#include "lld/Common/Memory.h"
+#include "lld/Common/Strings.h"
#include "lld/Common/Threads.h"
#include "lld/Common/Version.h"
#include "llvm/ADT/Twine.h"
@@ -239,7 +240,10 @@ static void handleWeakUndefines() {
// Add a synthetic dummy for weak undefined functions. These dummies will
// be GC'd if not used as the target of any "call" instructions.
- StringRef StubName = Saver.save("undefined function " + toString(*Sym));
+ Optional<std::string> SymName = demangleItanium(Sym->getName());
+ StringRef StubName =
+ Saver.save("undefined function " +
+ (SymName ? StringRef(*SymName) : Sym->getName()));
SyntheticFunction *Func = make<SyntheticFunction>(Sig, StubName);
Func->setBody(UnreachableFn);
// Ensure it compares equal to the null pointer, and so that table relocs
diff --git a/lld/wasm/Writer.cpp b/lld/wasm/Writer.cpp
index d57c526b2d3..8bf8834726d 100644
--- a/lld/wasm/Writer.cpp
+++ b/lld/wasm/Writer.cpp
@@ -534,13 +534,15 @@ void Writer::createNameSection() {
for (const Symbol *S : ImportedSymbols) {
if (auto *F = dyn_cast<FunctionSymbol>(S)) {
writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
- writeStr(Sub.OS, F->getName(), "symbol name");
+ Optional<std::string> Name = demangleItanium(F->getName());
+ writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name");
}
}
for (const InputFunction *F : InputFunctions) {
if (!F->getName().empty()) {
writeUleb128(Sub.OS, F->getFunctionIndex(), "func index");
- writeStr(Sub.OS, F->getName(), "symbol name");
+ Optional<std::string> Name = demangleItanium(F->getName());
+ writeStr(Sub.OS, Name ? StringRef(*Name) : F->getName(), "symbol name");
}
}
OpenPOWER on IntegriCloud