diff --git a/llvm/lib/MC/WasmObjectWriter.cpp b/llvm/lib/MC/WasmObjectWriter.cpp --- a/llvm/lib/MC/WasmObjectWriter.cpp +++ b/llvm/lib/MC/WasmObjectWriter.cpp @@ -519,6 +519,13 @@ Sym->setUndefined(); } Sym->setUsedInReloc(); + // Any time we have a TABLE_INDEX relocation against a function symbol, we + // need to ensure that table itself is part of the final output too. In the + // future we may want to define a new kind of reloc against both the + // function and the table, so that the linker can see that the function + // symbol keeps the table alive, but for now manually mark the table as + // live. + Sym->setNoStrip(); Asm.registerSymbol(*Sym); } @@ -1670,10 +1677,6 @@ WS.setIndex(InvalidIndex); continue; } - if (WS.isTable() && WS.getName() == "__indirect_function_table") { - // For the moment, don't emit table symbols -- wasm-ld can't handle them. - continue; - } LLVM_DEBUG(dbgs() << "adding to symtab: " << WS << "\n"); uint32_t Flags = 0; diff --git a/llvm/test/MC/WebAssembly/debug-info.ll b/llvm/test/MC/WebAssembly/debug-info.ll --- a/llvm/test/MC/WebAssembly/debug-info.ll +++ b/llvm/test/MC/WebAssembly/debug-info.ll @@ -89,44 +89,44 @@ ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) -; CHECK-NEXT: Size: 91 +; CHECK-NEXT: Size: 95 ; CHECK-NEXT: Offset: 731 ; CHECK-NEXT: Name: linking ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 9 -; CHECK-NEXT: Offset: 836 +; CHECK-NEXT: Offset: 840 ; CHECK-NEXT: Name: reloc.DATA ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 61 -; CHECK-NEXT: Offset: 862 +; CHECK-NEXT: Offset: 866 ; CHECK-NEXT: Name: reloc..debug_info ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 6 -; CHECK-NEXT: Offset: 947 +; CHECK-NEXT: Offset: 951 ; CHECK-NEXT: Name: reloc..debug_pubnames ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 6 -; CHECK-NEXT: Offset: 981 +; CHECK-NEXT: Offset: 985 ; CHECK-NEXT: Name: reloc..debug_pubtypes ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 6 -; CHECK-NEXT: Offset: 1015 +; CHECK-NEXT: Offset: 1019 ; CHECK-NEXT: Name: reloc..debug_line ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 77 -; CHECK-NEXT: Offset: 1045 +; CHECK-NEXT: Offset: 1049 ; CHECK-NEXT: Name: producers ; CHECK-NEXT: } ; CHECK-NEXT:] @@ -238,6 +238,16 @@ ; CHECK-NEXT: ] ; CHECK-NEXT: ElementIndex: 0xC ; CHECK-NEXT: } +; CHECK-NEXT: Symbol { +; CHECK-NEXT: Name: __indirect_function_table +; CHECK-NEXT: Type: TABLE (0x5) +; CHECK-NEXT: Flags [ (0x90) +; CHECK-NEXT: NO_STRIP (0x80) +; CHECK-NEXT: UNDEFINED (0x10) +; CHECK-NEXT: ] +; CHECK-NEXT: ImportModule: env +; CHECK-NEXT: ElementIndex: 0x0 +; CHECK-NEXT: } ; CHECK-NEXT:] ; generated from the following C code using: clang --target=wasm32 -g -O0 -S -emit-llvm test.c diff --git a/llvm/test/MC/WebAssembly/debug-info64.ll b/llvm/test/MC/WebAssembly/debug-info64.ll --- a/llvm/test/MC/WebAssembly/debug-info64.ll +++ b/llvm/test/MC/WebAssembly/debug-info64.ll @@ -89,44 +89,44 @@ ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) -; CHECK-NEXT: Size: 91 +; CHECK-NEXT: Size: 95 ; CHECK-NEXT: Offset: 759 ; CHECK-NEXT: Name: linking ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 9 -; CHECK-NEXT: Offset: 864 +; CHECK-NEXT: Offset: 868 ; CHECK-NEXT: Name: reloc.DATA ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 61 -; CHECK-NEXT: Offset: 890 +; CHECK-NEXT: Offset: 894 ; CHECK-NEXT: Name: reloc..debug_info ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 6 -; CHECK-NEXT: Offset: 975 +; CHECK-NEXT: Offset: 979 ; CHECK-NEXT: Name: reloc..debug_pubnames ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 6 -; CHECK-NEXT: Offset: 1009 +; CHECK-NEXT: Offset: 1013 ; CHECK-NEXT: Name: reloc..debug_pubtypes ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 6 -; CHECK-NEXT: Offset: 1043 +; CHECK-NEXT: Offset: 1047 ; CHECK-NEXT: Name: reloc..debug_line ; CHECK-NEXT: } ; CHECK-NEXT: Section { ; CHECK-NEXT: Type: CUSTOM (0x0) ; CHECK-NEXT: Size: 77 -; CHECK-NEXT: Offset: 1073 +; CHECK-NEXT: Offset: 1077 ; CHECK-NEXT: Name: producers ; CHECK-NEXT: } ; CHECK-NEXT: ] @@ -238,6 +238,16 @@ ; CHECK-NEXT: ] ; CHECK-NEXT: ElementIndex: 0xC ; CHECK-NEXT: } +; CHECK-NEXT: Symbol { +; CHECK-NEXT: Name: __indirect_function_table +; CHECK-NEXT: Type: TABLE (0x5) +; CHECK-NEXT: Flags [ (0x90) +; CHECK-NEXT: NO_STRIP (0x80) +; CHECK-NEXT: UNDEFINED (0x10) +; CHECK-NEXT: ] +; CHECK-NEXT: ImportModule: env +; CHECK-NEXT: ElementIndex: 0x0 +; CHECK-NEXT: } ; CHECK-NEXT: ] ; generated from the following C code using: clang --target=wasm64 -g -O0 -S -emit-llvm test.c diff --git a/llvm/test/MC/WebAssembly/function-alias.ll b/llvm/test/MC/WebAssembly/function-alias.ll --- a/llvm/test/MC/WebAssembly/function-alias.ll +++ b/llvm/test/MC/WebAssembly/function-alias.ll @@ -41,4 +41,14 @@ ; CHECK-NEXT: ] ; CHECK-NEXT: ElementIndex: 0x0 ; CHECK-NEXT: } +; CHECK-NEXT: Symbol { +; CHECK-NEXT: Name: __indirect_function_table +; CHECK-NEXT: Type: TABLE (0x5) +; CHECK-NEXT: Flags [ (0x90) +; CHECK-NEXT: NO_STRIP (0x80) +; CHECK-NEXT: UNDEFINED (0x10) +; CHECK-NEXT: ] +; CHECK-NEXT: ImportModule: env +; CHECK-NEXT: ElementIndex: 0x0 +; CHECK-NEXT: } ; CHECK-NEXT: ] diff --git a/llvm/test/MC/WebAssembly/global-ctor-dtor.ll b/llvm/test/MC/WebAssembly/global-ctor-dtor.ll --- a/llvm/test/MC/WebAssembly/global-ctor-dtor.ll +++ b/llvm/test/MC/WebAssembly/global-ctor-dtor.ll @@ -170,6 +170,11 @@ ; CHECK-NEXT: Name: func0 ; CHECK-NEXT: Flags: [ UNDEFINED ] ; CHECK-NEXT: Function: 4 +; CHECK-NEXT: - Index: 11 +; CHECK-NEXT: Kind: TABLE +; CHECK-NEXT: Name: __indirect_function_table +; CHECK-NEXT: Flags: [ UNDEFINED, NO_STRIP ] +; CHECK-NEXT: Table: 0 ; CHECK-NEXT: SegmentInfo: ; CHECK-NEXT: - Index: 0 ; CHECK-NEXT: Name: .data.global1 diff --git a/llvm/test/MC/WebAssembly/reloc-pic.s b/llvm/test/MC/WebAssembly/reloc-pic.s --- a/llvm/test/MC/WebAssembly/reloc-pic.s +++ b/llvm/test/MC/WebAssembly/reloc-pic.s @@ -190,6 +190,11 @@ # CHECK-NEXT: Name: hidden_func # CHECK-NEXT: Flags: [ BINDING_LOCAL ] # CHECK-NEXT: Function: 5 +# CHECK-NEXT: - Index: 10 +# CHECK-NEXT: Kind: TABLE +# CHECK-NEXT: Name: __indirect_function_table +# CHECK-NEXT: Flags: [ UNDEFINED, NO_STRIP ] +# CHECK-NEXT: Table: 0 # CHECK-NEXT: SegmentInfo: # CHECK-NEXT: - Index: 0 # CHECK-NEXT: Name: .rodata.hidden_data diff --git a/llvm/test/MC/WebAssembly/type-index.s b/llvm/test/MC/WebAssembly/type-index.s --- a/llvm/test/MC/WebAssembly/type-index.s +++ b/llvm/test/MC/WebAssembly/type-index.s @@ -66,4 +66,9 @@ # BIN-NEXT: Name: test0 # BIN-NEXT: Flags: [ BINDING_LOCAL ] # BIN-NEXT: Function: 0 +# BIN-NEXT: - Index: 1 +# BIN-NEXT: Kind: TABLE +# BIN-NEXT: Name: __indirect_function_table +# BIN-NEXT: Flags: [ UNDEFINED, NO_STRIP ] +# BIN-NEXT: Table: 0 # BIN-NEXT: ... diff --git a/llvm/test/MC/WebAssembly/weak-alias.s b/llvm/test/MC/WebAssembly/weak-alias.s --- a/llvm/test/MC/WebAssembly/weak-alias.s +++ b/llvm/test/MC/WebAssembly/weak-alias.s @@ -227,6 +227,11 @@ # CHECK-NEXT: Flags: [ BINDING_WEAK, VISIBILITY_HIDDEN, NO_STRIP ] # CHECK-NEXT: Segment: 0 # CHECK-NEXT: Size: 4 +# CHECK-NEXT: - Index: 10 +# CHECK-NEXT: Kind: TABLE +# CHECK-NEXT: Name: __indirect_function_table +# CHECK-NEXT: Flags: [ UNDEFINED, NO_STRIP ] +# CHECK-NEXT: Table: 0 # CHECK-NEXT: SegmentInfo: # CHECK-NEXT: - Index: 0 # CHECK-NEXT: Name: .data.bar