[lld][WebAssembly] Fix resolveIndirectFunctionTable for relocatable output

For relocatable output that needs the indirect function table, identify
the well-known function table.  This allows us to properly fix the
limits on the imported table, and in a followup will allow the element
section to reference the indirect function table even if it's not
assigned to table number 0.  Adapt tests for import reordering.

Differential Revision: https://reviews.llvm.org/D96770
This commit is contained in:
Andy Wingo 2021-02-16 13:28:44 +01:00
parent f48923e884
commit 48219d06b1
5 changed files with 34 additions and 21 deletions

View File

@ -240,7 +240,7 @@
; RELOC-NEXT: Index: 0
; RELOC-NEXT: ElemType: FUNCREF
; RELOC-NEXT: Limits:
; RELOC-NEXT: Initial: 0x3
; RELOC-NEXT: Initial: 0x7
; RELOC-NEXT: - Type: FUNCTION
; RELOC-NEXT: FunctionTypes: [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
; RELOC-NEXT: 0, 0 ]

View File

@ -0,0 +1,6 @@
; RUN: llvm-mc -filetype=obj -triple=wasm32-unknown-unknown %p/Inputs/start.s -o %t.o
; RUN: not wasm-ld -o %t.wasm --relocatable --export-table %t.o 2>&1 | FileCheck %s --check-prefix=EXPORT
; RUN: not wasm-ld -o %t.wasm --relocatable --growable-table %t.o 2>&1 | FileCheck %s --check-prefix=GROWABLE
; EXPORT: error: --relocatable is incompatible with --export-table
; GROWABLE: error: --relocatable is incompatible with --growable-table

View File

@ -60,6 +60,14 @@ define void @_start() {
; CHECK-NEXT: - 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: Initial: 0x4
; CHECK-NEXT: - Module: env
; CHECK-NEXT: Field: puts
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 0
@ -71,14 +79,6 @@ define void @_start() {
; CHECK-NEXT: Field: bar_import
; CHECK-NEXT: Kind: FUNCTION
; CHECK-NEXT: SigIndex: 1
; 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: Initial: 0x3
; CHECK-NEXT: - Type: FUNCTION
; CHECK-NEXT: FunctionTypes: [ 2, 1, 1, 2 ]
; CHECK-NEXT: - Type: MEMORY

View File

@ -145,18 +145,18 @@ entry:
; RELOC-NEXT: - Type: IMPORT
; RELOC-NEXT: Imports:
; RELOC-NEXT: - Module: env
; RELOC-NEXT: Field: __stack_pointer
; RELOC-NEXT: Kind: GLOBAL
; RELOC-NEXT: GlobalType: I32
; RELOC-NEXT: GlobalMutable: true
; RELOC-NEXT: - Module: env
; RELOC-NEXT: Field: __indirect_function_table
; RELOC-NEXT: Kind: TABLE
; RELOC-NEXT: Table:
; RELOC-NEXT: Index: 0
; RELOC-NEXT: ElemType: FUNCREF
; RELOC-NEXT: Limits:
; RELOC-NEXT: Initial: 0x1
; RELOC-NEXT: Initial: 0x2
; RELOC-NEXT: - Module: env
; RELOC-NEXT: Field: __stack_pointer
; RELOC-NEXT: Kind: GLOBAL
; RELOC-NEXT: GlobalType: I32
; RELOC-NEXT: GlobalMutable: true
; RELOC-NEXT: - Type: FUNCTION
; RELOC-NEXT: FunctionTypes: [ 0, 1, 1, 1, 1, 1 ]
; RELOC-NEXT: - Type: MEMORY

View File

@ -470,6 +470,15 @@ static void setConfigs() {
config->importTable = true;
}
if (config->relocatable) {
if (config->exportTable)
error("--relocatable is incompatible with --export-table");
if (config->growableTable)
error("--relocatable is incompatible with --growable-table");
// Ignore any --import-table, as it's redundant.
config->importTable = true;
}
if (config->shared) {
config->importMemory = true;
config->unresolvedSymbols = UnresolvedPolicy::ImportFuncs;
@ -1012,13 +1021,11 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
// Do size optimizations: garbage collection
markLive();
if (!config->relocatable) {
// Provide the indirect funciton table if needed.
WasmSym::indirectFunctionTable = resolveIndirectFunctionTable();
// Provide the indirect funciton table if needed.
WasmSym::indirectFunctionTable = resolveIndirectFunctionTable();
if (errorCount())
return;
}
if (errorCount())
return;
// Write the result to the file.
writeResult();