Making a wasm32_emscripten Dynamic Library?
I am investigating using LFortran for Pyodide. We need the generated code to be position independent because we want to build an Emscripten side-module. However, the wasm object file generated by lfortran seems to include relocations that are not position independent. I am running the following code:
emcc -c src/runtime/impure/lfortran_intrinsics.c -o lfortran_intrinsics.o -fPIC
lfortran -c test.f90 -o test.o --target wasm32
emcc test.o lfortran_intrinsics.o -o test.so -sSIDE_MODULE=1 -sWASM_BIGINT
where test.f90
is:
program main
use iso_c_binding
print *, add(1, 1)
contains
integer(kind=c_int) function add(x, y) result(r) bind(c, name="add")
integer(kind=c_int), intent(in) :: x, y
r = x + y + 2021
end function
end program
If I compile it as the main module, it links successfully, runs, and prints 2023 as expected. But with -sSIDE_MODULE=1
(or 2), it complains that there are relocations that are not position-independent, in particular the data relocations are type R_WASM_MEMORY_ADDR_SLEB
but to be position independent they should be type R_WASM_MEMORY_ADDR_REL_SLEB
. It looks to me like lfortran requests PIC here:
https://gitlab.com/lfortran/lfortran/-/blob/master/src/libasr/codegen/evaluator.cpp#L183
I think maybe the problem is that LLVM 11 is too old?
In tip of tree LLVM we see that setting PIC sets OperandFlags = WebAssemblyII::MO_MEMORY_BASE_REL;
Which sets Kind = MCSymbolRefExpr::VK_WASM_MBREL;
Which should cause the WasmObjectWriter to choose to emit R_WASM_MEMORY_ADDR_REL_SLEB
locations: