-
Notifications
You must be signed in to change notification settings - Fork 12.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[lld][WebAssembly] Fix for --import-table when combined with reference types #97451
Conversation
@llvm/pr-subscribers-lld Author: Sam Clegg (sbc100) ChangesWhen reference types are enabled clang will generate call_indirect instructions that explicitly reference the global In this case the resulting global symbol was not being correctly marked with explicit import name/module, resulting in the linker reporting errors when it was referenced. This issue was reported in WebAssembly/tool-conventions#158 Full diff: https://github.com/llvm/llvm-project/pull/97451.diff 3 Files Affected:
diff --git a/lld/test/wasm/import-table-explicit.s b/lld/test/wasm/import-table-explicit.s
new file mode 100644
index 0000000000000..1dc21beba0629
--- /dev/null
+++ b/lld/test/wasm/import-table-explicit.s
@@ -0,0 +1,26 @@
+# RUN: llvm-mc -mattr=+reference-types -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
+# RUN: wasm-ld --import-table -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+.globl __indirect_function_table
+.tabletype __indirect_function_table, funcref
+
+.globl _start
+_start:
+ .functype _start () -> ()
+ i32.const 1
+ call_indirect __indirect_function_table, () -> ()
+ end_function
+
+# Verify the --import-table flag creates a table import
+
+# CHECK: - Type: IMPORT
+# CHECK-NEXT: Imports:
+# CHECK-NEXT: - Module: env
+# CHECK-NEXT: Field: __indirect_function_table
+# CHECK-NEXT: Kind: TABLE
+# CHECK-NEXT: Table:
+# CHECK-NEXT: Index: 0
+# CHECK-NEXT: ElemType: FUNCREF
+# CHECK-NEXT: Limits:
+# CHECK-NEXT: Minimum: 0x1
diff --git a/lld/test/wasm/import-table.test b/lld/test/wasm/import-table.s
similarity index 63%
rename from lld/test/wasm/import-table.test
rename to lld/test/wasm/import-table.s
index 73dc7189bbf28..7a0c94d130276 100644
--- a/lld/test/wasm/import-table.test
+++ b/lld/test/wasm/import-table.s
@@ -1,14 +1,14 @@
-# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/start.s -o %t.start.o
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
-# RUN: wasm-ld --export-all --import-table -o %t.wasm %t.start.o %t.o
+# RUN: wasm-ld --export-all --import-table -o %t.wasm %t.o
# RUN: obj2yaml %t.wasm | FileCheck %s
-.globl require_function_table
-require_function_table:
-.functype require_function_table () -> ()
- i32.const 1
- call_indirect () -> ()
- end_function
+.globl _start
+_start:
+ .functype _start () -> ()
+ i32.const 1
+ # call_indirect instruction implicitly references the function table
+ call_indirect () -> ()
+ end_function
# Verify the --import-table flag creates a table import
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 00c347ea3ef24..09c463299b05c 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -681,10 +681,9 @@ TableSymbol *SymbolTable::createUndefinedIndirectFunctionTable(StringRef name) {
WasmTableType *type = make<WasmTableType>();
type->ElemType = ValType::FUNCREF;
type->Limits = limits;
- StringRef module(defaultModule);
uint32_t flags = config->exportTable ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
flags |= WASM_SYMBOL_UNDEFINED;
- Symbol *sym = addUndefinedTable(name, name, module, flags, nullptr, type);
+ Symbol *sym = addUndefinedTable(name, name, defaultModule, flags, nullptr, type);
sym->markLive();
sym->forceExport = config->exportTable;
return cast<TableSymbol>(sym);
@@ -724,8 +723,11 @@ TableSymbol *SymbolTable::resolveIndirectFunctionTable(bool required) {
}
if (config->importTable) {
- if (existing)
+ if (existing) {
+ existing->importModule = defaultModule;
+ existing->importName = functionTableName;
return cast<TableSymbol>(existing);
+ }
if (required)
return createUndefinedIndirectFunctionTable(functionTableName);
} else if ((existing && existing->isLive()) || config->exportTable ||
|
@llvm/pr-subscribers-lld-wasm Author: Sam Clegg (sbc100) ChangesWhen reference types are enabled clang will generate call_indirect instructions that explicitly reference the global In this case the resulting global symbol was not being correctly marked with explicit import name/module, resulting in the linker reporting errors when it was referenced. This issue was reported in WebAssembly/tool-conventions#158 Full diff: https://github.com/llvm/llvm-project/pull/97451.diff 3 Files Affected:
diff --git a/lld/test/wasm/import-table-explicit.s b/lld/test/wasm/import-table-explicit.s
new file mode 100644
index 0000000000000..1dc21beba0629
--- /dev/null
+++ b/lld/test/wasm/import-table-explicit.s
@@ -0,0 +1,26 @@
+# RUN: llvm-mc -mattr=+reference-types -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
+# RUN: wasm-ld --import-table -o %t.wasm %t.o
+# RUN: obj2yaml %t.wasm | FileCheck %s
+
+.globl __indirect_function_table
+.tabletype __indirect_function_table, funcref
+
+.globl _start
+_start:
+ .functype _start () -> ()
+ i32.const 1
+ call_indirect __indirect_function_table, () -> ()
+ end_function
+
+# Verify the --import-table flag creates a table import
+
+# CHECK: - Type: IMPORT
+# CHECK-NEXT: Imports:
+# CHECK-NEXT: - Module: env
+# CHECK-NEXT: Field: __indirect_function_table
+# CHECK-NEXT: Kind: TABLE
+# CHECK-NEXT: Table:
+# CHECK-NEXT: Index: 0
+# CHECK-NEXT: ElemType: FUNCREF
+# CHECK-NEXT: Limits:
+# CHECK-NEXT: Minimum: 0x1
diff --git a/lld/test/wasm/import-table.test b/lld/test/wasm/import-table.s
similarity index 63%
rename from lld/test/wasm/import-table.test
rename to lld/test/wasm/import-table.s
index 73dc7189bbf28..7a0c94d130276 100644
--- a/lld/test/wasm/import-table.test
+++ b/lld/test/wasm/import-table.s
@@ -1,14 +1,14 @@
-# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/start.s -o %t.start.o
# RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %s -o %t.o
-# RUN: wasm-ld --export-all --import-table -o %t.wasm %t.start.o %t.o
+# RUN: wasm-ld --export-all --import-table -o %t.wasm %t.o
# RUN: obj2yaml %t.wasm | FileCheck %s
-.globl require_function_table
-require_function_table:
-.functype require_function_table () -> ()
- i32.const 1
- call_indirect () -> ()
- end_function
+.globl _start
+_start:
+ .functype _start () -> ()
+ i32.const 1
+ # call_indirect instruction implicitly references the function table
+ call_indirect () -> ()
+ end_function
# Verify the --import-table flag creates a table import
diff --git a/lld/wasm/SymbolTable.cpp b/lld/wasm/SymbolTable.cpp
index 00c347ea3ef24..09c463299b05c 100644
--- a/lld/wasm/SymbolTable.cpp
+++ b/lld/wasm/SymbolTable.cpp
@@ -681,10 +681,9 @@ TableSymbol *SymbolTable::createUndefinedIndirectFunctionTable(StringRef name) {
WasmTableType *type = make<WasmTableType>();
type->ElemType = ValType::FUNCREF;
type->Limits = limits;
- StringRef module(defaultModule);
uint32_t flags = config->exportTable ? 0 : WASM_SYMBOL_VISIBILITY_HIDDEN;
flags |= WASM_SYMBOL_UNDEFINED;
- Symbol *sym = addUndefinedTable(name, name, module, flags, nullptr, type);
+ Symbol *sym = addUndefinedTable(name, name, defaultModule, flags, nullptr, type);
sym->markLive();
sym->forceExport = config->exportTable;
return cast<TableSymbol>(sym);
@@ -724,8 +723,11 @@ TableSymbol *SymbolTable::resolveIndirectFunctionTable(bool required) {
}
if (config->importTable) {
- if (existing)
+ if (existing) {
+ existing->importModule = defaultModule;
+ existing->importName = functionTableName;
return cast<TableSymbol>(existing);
+ }
if (required)
return createUndefinedIndirectFunctionTable(functionTableName);
} else if ((existing && existing->isLive()) || config->exportTable ||
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
…e types When reference types are enabled clang will generate call_indirect instructions that explicitly reference the global `__indirect_function_table` symbol. In this case the resulting global symbol was not being correctly marked with explicit import name/module, resulting in the linker reporting errors when it was referenced. This issue was reported in WebAssembly/tool-conventions#158
@@ -724,8 +724,11 @@ TableSymbol *SymbolTable::resolveIndirectFunctionTable(bool required) { | |||
} | |||
|
|||
if (config->importTable) { | |||
if (existing) | |||
if (existing) { | |||
existing->importModule = defaultModule; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it possible to import a table from a non-default module? If so, how do we do it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, before this PR, what was this importModule
set to?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function only deal with one very particular table (__indirect_function_table
). This table is implicitly generated by the linker and we don't support defining it explicitly anywhere. The import name is also fixed. It should not be possible to attach any kind of custom import name to it.
…e types (llvm#97451) When reference types are enabled clang will generate call_indirect instructions that explicitly reference the global `__indirect_function_table` symbol. In this case the resulting global symbol was not being correctly marked with explicit import name/module, resulting in the linker reporting errors when it was referenced. This issue was reported in WebAssembly/tool-conventions#158
…e types (llvm#97451) When reference types are enabled clang will generate call_indirect instructions that explicitly reference the global `__indirect_function_table` symbol. In this case the resulting global symbol was not being correctly marked with explicit import name/module, resulting in the linker reporting errors when it was referenced. This issue was reported in WebAssembly/tool-conventions#158
When reference types are enabled clang will generate call_indirect instructions that explicitly reference the global
__indirect_function_table
symbol.In this case the resulting global symbol was not being correctly marked with explicit import name/module, resulting in the linker reporting errors when it was referenced.
This issue was reported in WebAssembly/tool-conventions#158