[WebAssembly] Fix imported function symbol names that differ from their import names in the .o format
Add a flag to allow symbols to have a wasm import name which differs from the
linker symbol name, allowing the linker to link code using the import_module
attribute.
This is the MC/Object portion of the patch.
Differential Revision: https://reviews.llvm.org/D57632
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@353474 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/BinaryFormat/Wasm.h b/include/llvm/BinaryFormat/Wasm.h
index 348fa11..51f6ab2 100644
--- a/include/llvm/BinaryFormat/Wasm.h
+++ b/include/llvm/BinaryFormat/Wasm.h
@@ -170,7 +170,8 @@
StringRef Name;
uint8_t Kind;
uint32_t Flags;
- StringRef Module; // For undefined symbols the module name of the import
+ StringRef ImportModule; // For undefined symbols the module of the import
+ StringRef ImportName; // For undefined symbols the name of the import
union {
// For function or global symbols, the index in function or global index
// space.
@@ -290,6 +291,7 @@
const unsigned WASM_SYMBOL_VISIBILITY_HIDDEN = 0x4;
const unsigned WASM_SYMBOL_UNDEFINED = 0x10;
const unsigned WASM_SYMBOL_EXPORTED = 0x20;
+const unsigned WASM_SYMBOL_EXPLICIT_NAME = 0x40;
#define WASM_RELOC(name, value) name = value,
diff --git a/lib/MC/WasmObjectWriter.cpp b/lib/MC/WasmObjectWriter.cpp
index 00d4865..600928c 100644
--- a/lib/MC/WasmObjectWriter.cpp
+++ b/lib/MC/WasmObjectWriter.cpp
@@ -982,7 +982,8 @@
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
case wasm::WASM_SYMBOL_TYPE_EVENT:
encodeULEB128(Sym.ElementIndex, W.OS);
- if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
+ if ((Sym.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
+ (Sym.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
writeString(Sym.Name);
break;
case wasm::WASM_SYMBOL_TYPE_DATA:
@@ -1456,6 +1457,8 @@
Flags |= wasm::WASM_SYMBOL_UNDEFINED;
if (WS.isExported())
Flags |= wasm::WASM_SYMBOL_EXPORTED;
+ if (WS.getName() != WS.getImportName())
+ Flags |= wasm::WASM_SYMBOL_EXPLICIT_NAME;
wasm::WasmSymbolInfo Info;
Info.Name = WS.getName();
diff --git a/lib/Object/WasmObjectFile.cpp b/lib/Object/WasmObjectFile.cpp
index 7423dc9..e5b6a9b 100644
--- a/lib/Object/WasmObjectFile.cpp
+++ b/lib/Object/WasmObjectFile.cpp
@@ -505,9 +505,13 @@
Function.SymbolName = Info.Name;
} else {
wasm::WasmImport &Import = *ImportedFunctions[Info.ElementIndex];
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ Info.Name = readString(Ctx);
+ else
+ Info.Name = Import.Field;
Signature = &Signatures[Import.SigIndex];
- Info.Name = Import.Field;
- Info.Module = Import.Module;
+ Info.ImportName = Import.Field;
+ Info.ImportModule = Import.Module;
}
break;
@@ -530,8 +534,13 @@
Global.SymbolName = Info.Name;
} else {
wasm::WasmImport &Import = *ImportedGlobals[Info.ElementIndex];
- Info.Name = Import.Field;
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ Info.Name = readString(Ctx);
+ else
+ Info.Name = Import.Field;
GlobalType = &Import.Global;
+ Info.ImportName = Import.Field;
+ Info.ImportModule = Import.Module;
}
break;
@@ -585,9 +594,14 @@
} else {
wasm::WasmImport &Import = *ImportedEvents[Info.ElementIndex];
+ if ((Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
+ Info.Name = readString(Ctx);
+ else
+ Info.Name = Import.Field;
EventType = &Import.Event;
Signature = &Signatures[EventType->SigIndex];
- Info.Name = Import.Field;
+ Info.ImportName = Import.Field;
+ Info.ImportModule = Import.Module;
}
break;
}
diff --git a/test/MC/WebAssembly/debug-info.ll b/test/MC/WebAssembly/debug-info.ll
index a0f93fe..fe4a4cf 100644
--- a/test/MC/WebAssembly/debug-info.ll
+++ b/test/MC/WebAssembly/debug-info.ll
@@ -186,7 +186,8 @@
; CHECK-NEXT: Flags [ (0x10)
; CHECK-NEXT: UNDEFINED (0x10)
; CHECK-NEXT: ]
-; CHECK-NEXT: Module:
+; CHECK-NEXT: ImportName:
+; CHECK-NEXT: ImportModule:
; CHECK-NEXT: }
; CHECK-NEXT: Symbol {
; CHECK-NEXT: Name: ptr2
diff --git a/test/MC/WebAssembly/import-module.ll b/test/MC/WebAssembly/import-module.ll
new file mode 100644
index 0000000..461d5c2
--- /dev/null
+++ b/test/MC/WebAssembly/import-module.ll
@@ -0,0 +1,31 @@
+; RUN: llc -filetype=obj %s -o - | obj2yaml | FileCheck %s
+
+target triple = "wasm32-unknown-unknown"
+
+define void @test() {
+ call void @foo()
+ call void @plain()
+ ret void
+}
+
+declare void @foo() #0
+declare void @plain()
+
+attributes #0 = { "wasm-import-module"="bar" "wasm-import-name"="qux" }
+
+; CHECK: - Type: IMPORT
+; CHECK-NEXT: Imports:
+; CHECK: - Module: bar
+; CHECK-NEXT: Field: qux
+; CHECK-NEXT: Kind: FUNCTION
+
+; CHECK: - Module: env
+; CHECK-NEXT: Field: plain
+; CHECK-NEXT: Kind: FUNCTION
+
+; CHECK: - Type: CUSTOM
+; CHECK: Name: foo
+; CHECK-NEXT: Flags: [ UNDEFINED ]
+
+; CHECK: Name: plain
+; CHECK-NEXT: Flags: [ UNDEFINED ]
diff --git a/tools/llvm-readobj/WasmDumper.cpp b/tools/llvm-readobj/WasmDumper.cpp
index 9ff222e..edcd073 100644
--- a/tools/llvm-readobj/WasmDumper.cpp
+++ b/tools/llvm-readobj/WasmDumper.cpp
@@ -224,8 +224,10 @@
W.printEnum("Type", Symbol.Info.Kind, makeArrayRef(WasmSymbolTypes));
W.printFlags("Flags", Symbol.Info.Flags, makeArrayRef(WasmSymbolFlags));
- if (Symbol.Info.Flags & wasm::WASM_SYMBOL_UNDEFINED)
- W.printString("Module", Symbol.Info.Module);
+ if (Symbol.Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) {
+ W.printString("ImportName", Symbol.Info.ImportName);
+ W.printString("ImportModule", Symbol.Info.ImportModule);
+ }
if (Symbol.Info.Kind != wasm::WASM_SYMBOL_TYPE_DATA) {
W.printHex("ElementIndex", Symbol.Info.ElementIndex);
} else if (!(Symbol.Info.Flags & wasm::WASM_SYMBOL_UNDEFINED)) {
diff --git a/tools/yaml2obj/yaml2wasm.cpp b/tools/yaml2obj/yaml2wasm.cpp
index a0600c6..3398ace 100644
--- a/tools/yaml2obj/yaml2wasm.cpp
+++ b/tools/yaml2obj/yaml2wasm.cpp
@@ -172,7 +172,8 @@
case wasm::WASM_SYMBOL_TYPE_GLOBAL:
case wasm::WASM_SYMBOL_TYPE_EVENT:
encodeULEB128(Info.ElementIndex, SubSection.getStream());
- if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0)
+ if ((Info.Flags & wasm::WASM_SYMBOL_UNDEFINED) == 0 ||
+ (Info.Flags & wasm::WASM_SYMBOL_EXPLICIT_NAME) != 0)
writeStringRef(Info.Name, SubSection.getStream());
break;
case wasm::WASM_SYMBOL_TYPE_DATA: