Invalid TableNumber error when linking static lib into a shared module
Hello! I'm trying to compile some shared modules that link Flang's libFortranRuntime.a (flang source). This has been successful with versions 3.1.61 and older. However, starting with versions 3.1.62 (up to 4.0.5), there is an Invalid TableNumber error that occurs.
Version of emscripten/emsdk:
emcc (Emscripten gcc/clang-like replacement + linker emulating GNU ld) 3.1.62 (34c1aa36052b1882058f22aa1916437ba0872690)
Copyright (C) 2014 the Emscripten authors (see AUTHORS.txt)
This is free and open source software under the MIT license.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Failing command line in full:
emcc libFortranRuntime.a -o test.so -sSIDE_MODULE=1
Full link command and output with -v appended:
Output with error v3.1.62:
/.../emsdk/upstream/bin/clang --version
/.../emsdk/upstream/bin/wasm-ld -o tst.so libFortranRuntime.a -L/.../emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/pic -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-memory --strip-debug --export=__wasm_call_ctors --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js--export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=__wasm_apply_data_relocs --export-if-defined=fflush --experimental-pic --unresolved-symbols=import-dynamic -shared --no-export-dynamic --stack-first
/.../emsdk/upstream/bin/wasm-ld -o tst.so --whole-archive libFortranRuntime.a -L/.../emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/pic --no-whole-archive -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-memory --strip-debug --export-dynamic --export=__wasm_call_ctors --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=__wasm_apply_data_relocs --export-if-defined=fflush --experimental-pic --unresolved-symbols=import-dynamic -shared --stack-first
wasm-ld: warning: function signature mismatch: _FortranACppDotProductComplex4
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(dot-product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppDotProductComplex16
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(dot-product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex16Value
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppSumComplex16
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(sum.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppProductComplex16
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex4Value
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex4Ref
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex8Ref
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex8Value
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppDotProductComplex8
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(dot-product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppSumComplex4
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(sum.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppProductComplex8
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppProductComplex4
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex16Ref
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppSumComplex8
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(sum.cpp.o)
/.../emsdk/upstream/bin/llvm-objcopy tst.so tst.so --remove-section=.debug* --remove-section=producers
/.../emsdk/upstream/bin/llvm-objcopy: error: 'tst.so': invalid TableNumber
emcc: error: '/.../emsdk/upstream/bin/llvm-objcopy tst.so tst.so --remove-section=.debug* --remove-section=producers' failed (returned 1)
Output without error v3.1.61:
/.../emsdk/upstream/bin/clang --version
/.../emsdk/upstream/bin/wasm-ld -o tst.so libFortranRuntime.a -L/.../emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/pic -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-memory --strip-debug --export=__wasm_call_ctors --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js--export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=__wasm_apply_data_relocs --export-if-defined=fflush --experimental-pic --unresolved-symbols=import-dynamic -shared --no-export-dynamic --stack-first
/.../emsdk/upstream/bin/wasm-ld -o tst.so --whole-archive libFortranRuntime.a -L/.../emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/pic --no-whole-archive -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-memory --strip-debug --export-dynamic --export=__wasm_call_ctors --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=__wasm_apply_data_relocs --export-if-defined=fflush --experimental-pic --unresolved-symbols=import-dynamic -shared --stack-first
wasm-ld: warning: function signature mismatch: _FortranACppDotProductComplex4
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(dot-product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppDotProductComplex16
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(dot-product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex16Value
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppSumComplex16
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(sum.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppProductComplex16
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex4Value
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex4Ref
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex8Ref
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex8Value
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppDotProductComplex8
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(dot-product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppSumComplex4
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(sum.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppProductComplex8
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppProductComplex4
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(product.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppReduceComplex16Ref
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(reduce.cpp.o)
wasm-ld: warning: function signature mismatch: _FortranACppSumComplex8
>>> defined as (i32, i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(complex-reduction.c.o)
>>> defined as (i32, i32, i32, i32, i32, i32) -> void in libFortranRuntime.a(sum.cpp.o)
/.../emsdk/upstream/bin/llvm-objcopy tst.so tst.so --remove-section=.debug* --remove-section=producers
/.../emsdk/upstream/bin/wasm-emscripten-finalize --dyncalls-i64 --pass-arg=legalize-js-interface-export-originals --side-module tst.so -o tst.so --detect-features
I would appreciate any help with this error. Please let me know if you need more details. Thank you!
As this is a regression, bisecting may help find the exact commit where this regressed:
https://emscripten.org/docs/contributing/developers_guide.html#bisecting
It seems clear this is in LLVM, so actually bisecting directly there is also an option.
Can you perhaps attach the broken tst.so file?
It looks like the shared library doesn't have any table usage, but it does have table element segment:
Elem[1]:
- segment[0] flags=2 table=4294967295 count=3 - init global=2 <__table_base>
- elem[0] = ref.func:37 <__cxx_global_array_dtor>
- elem[1] = ref.func:38 <__cxx_global_array_dtor.2>
- elem[2] = ref.func:41 <__cxx_global_array_dtor>
So I guess maybe the linker decided not to include a table at all.. resulting in -1 for the table index here.. oops.
Did you rebuild all of the input object and libraries that go in to tst.so.
It seems like the __indirect_function_table symbol is missing in the output, but if I'm reading the linker code correctly that can only happen if non of the input object contains a reference to __indirect_function_table. Can you attach some of the input objects or archive files? Can you try building everything from source?
Did you rebuild all of the input object and libraries that go in to
tst.so.
Yes, I rebuilt libFortranRuntime.a from scratch.
It seems like the
__indirect_function_tablesymbol is missing in the output, but if I'm reading the linker code correctly that can only happen if non of the input object contains a reference to__indirect_function_table. Can you attach some of the input objects or archive files?
Here is the build directory for the Fortran runtime. It has the object files, the static library, and some additional files if that helps. _build_dir_v62.zip
Can you try building everything from source?
What do you mean exactly? Build the fortran runtime from source like above? Or build emscripten from source?
I was looking into the bisecting docs mentioned. It might take me a little while to set it up.
What do you mean exactly? Build the fortran runtime from source like above? Or build emscripten from source?
I mean build all your object files and libraries from source when you update emscripten. It sounds like you did that though.
I believe the linker should be hitting an assert in this case. Can you trying installing the -asserts version of emedk to confirm (e.g ./emsdk install 4.0.5-asserts.
Hi @sbc100 ! Here's the output with the 4.0.5-asserts version
wasm-ld: /b/s/w/ir/cache/builder/emscripten-releases/llvm-project/lld/wasm/Symbols.cpp:402: uint32_t lld::wasm::TableSymbol::getTableNumber() const: Assertion `tableNumber != INVALID_INDEX' failed.
PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace.
Stack dump:
0. Program arguments: /.../emsdk/upstream/bin/wasm-ld -o tst.so --whole-archive libFortranRuntime.a -L/.../emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/pic -L/.../emsdk/upstream/emscripten/src/lib --no-whole-archive -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-memory --strip-debug --export-dynamic --export=__wasm_call_ctors --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=__wasm_apply_data_relocs --export-if-defined=fflush --experimental-pic --unresolved-symbols=import-dynamic -shared --stack-first
#0 0x000077b3e509cfe8 llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) (/.../emsdk/upstream/bin/../lib/libLLVM.so.21.0git+0x229cfe8)
#1 0x000077b3e509aa3e llvm::sys::RunSignalHandlers() (/.../emsdk/upstream/bin/../lib/libLLVM.so.21.0git+0x229aa3e)
#2 0x000077b3e509d6b6 SignalHandler(int, siginfo_t*, void*) Signals.cpp:0:0
#3 0x000077b3e2b53cd0 (/usr/lib/libc.so.6+0x3dcd0)
#4 0x000077b3e2bad624 (/usr/lib/libc.so.6+0x97624)
#5 0x000077b3e2b53ba0 raise (/usr/lib/libc.so.6+0x3dba0)
#6 0x000077b3e2b3b582 abort (/usr/lib/libc.so.6+0x25582)
#7 0x000077b3e2b3b4eb __assert_perror_fail (/usr/lib/libc.so.6+0x254eb)
#8 0x0000631e3a41e077 (/.../emsdk/upstream/bin/wasm-ld+0x5e1077)
#9 0x0000631e3a439483 lld::wasm::ElemSection::writeBody() (/.../emsdk/upstream/bin/wasm-ld+0x5fc483)
#10 0x0000631e3a42bffa lld::wasm::SyntheticSection::finalizeContents() Writer.cpp:0:0
#11 0x0000631e3a427e41 lld::wasm::(anonymous namespace)::Writer::run() Writer.cpp:0:0
#12 0x0000631e3a41e60c lld::wasm::writeResult() (/.../emsdk/upstream/bin/wasm-ld+0x5e160c)
#13 0x0000631e3a3f8400 lld::wasm::(anonymous namespace)::LinkerDriver::linkerMain(llvm::ArrayRef<char const*>) Driver.cpp:0:0
#14 0x0000631e3a3f3420 lld::wasm::link(llvm::ArrayRef<char const*>, llvm::raw_ostream&, llvm::raw_ostream&, bool, bool) (/.../emsdk/upstream/bin/wasm-ld+0x5b6420)
#15 0x0000631e3a0118c0 lld::unsafeLldMain(llvm::ArrayRef<char const*>, llvm::raw_ostream&, llvm::raw_ostream&, llvm::ArrayRef<lld::DriverDef>, bool) (/.../emsdk/upstream/bin/wasm-ld+0x1d48c0)
#16 0x0000631e3a010b2d lld_main(int, char**, llvm::ToolContext const&) (/.../emsdk/upstream/bin/wasm-ld+0x1d3b2d)
#17 0x0000631e3a0110a7 main (/.../emsdk/upstream/bin/wasm-ld+0x1d40a7)
#18 0x000077b3e2b3d488 (/usr/lib/libc.so.6+0x27488)
#19 0x000077b3e2b3d54c __libc_start_main (/usr/lib/libc.so.6+0x2754c)
#20 0x0000631e3a01070a _start (/.../emsdk/upstream/bin/wasm-ld+0x1d370a)
emcc: error: '/.../emsdk/upstream/bin/wasm-ld -o tst.so --whole-archive libFortranRuntime.a -L/.../emsdk/upstream/emscripten/cache/sysroot/lib/wasm32-emscripten/pic -L/.../emsdk/upstream/emscripten/src/lib --no-whole-archive -mllvm -combiner-global-alias-analysis=false -mllvm -enable-emscripten-sjlj -mllvm -disable-lsr --import-memory --strip-debug --export-dynamic --export=__wasm_call_ctors --export-if-defined=__start_em_asm --export-if-defined=__stop_em_asm --export-if-defined=__start_em_lib_deps --export-if-defined=__stop_em_lib_deps --export-if-defined=__start_em_js --export-if-defined=__stop_em_js --export-if-defined=main --export-if-defined=__main_argc_argv --export-if-defined=__wasm_apply_data_relocs --export-if-defined=fflush --experimental-pic --unresolved-symbols=import-dynamic -shared --stack-first' failed (received SIGABRT (-6))
I did some bisecting, this is the commit that breaks it
6e421fbb3aacce38c5596b59c3a29c75bef4a0ee Roll llvm-project from af82e63c28f6 to 560b6452af06 (68 revisions)
Could this be the problem? https://github.com/llvm/llvm-project/pull/80169
Hi! I did some more debugging and bisected LLVM. This is the PR that causes the regression: https://github.com/llvm/llvm-project/pull/93261
--- a/clang/lib/Basic/Targets/WebAssembly.cpp
+++ b/clang/lib/Basic/Targets/WebAssembly.cpp
@@ -153,6 +153,7 @@ bool WebAssemblyTargetInfo::initFeatureMap(
auto addGenericFeatures = [&]() {
Features["multivalue"] = true;
Features["mutable-globals"] = true;
+ Features["reference-types"] = true;
Features["sign-ext"] = true;
};
auto addBleedingEdgeFeatures = [&]() {
@@ -164,7 +165,6 @@ bool WebAssemblyTargetInfo::initFeatureMap(
Features["half-precision"] = true;
Features["multimemory"] = true;
Features["nontrapping-fptoint"] = true;
- Features["reference-types"] = true;
Features["tail-call"] = true;
setSIMDLevel(Features, RelaxedSIMD, true);
};
cc @aheejin given that bisection result.
I was able to reproduce this, but didn't manage to figure out all the details. I has to do with some pretty subtle/complex details of if/when we include the __indirect_function_table symbol itself.