WebAssembly / tool-conventions

Conventions supporting interoperatibility between tools working with WebAssembly.
Artistic License 2.0
298 stars 65 forks source link

LLVM Dynamic Linking(C to wasm) compile error #177

Closed zhanheng1996 closed 2 years ago

zhanheng1996 commented 2 years ago

when i use llvm to build wasm file(shared library), i get some trouble (Forgive my bad english - -!) test1.c

 int g_a = 1;
 int test1() {
    return 100 + g_a;
 }

 void setV(int v) {
   g_a = v;
 }

test2.c

int test2() {
   return 200;
}

this is compile result

zhanheng@ubuntu:~/WASM/test$ /home/zhanheng/WASM/emsdk/upstream/bin/clang  --target=wasm32 -nostdlib -Wl,--export-all -Wl,--shared -o test12.wasm -fPIC test1.c test2.c
wasm-ld: warning: creating shared libraries, with -shared, is not yet stable
wasm-ld: error: /tmp/test1-6da457.o: relocation R_WASM_MEMORY_ADDR_LEB cannot be used against symbol g_a; recompile with -fPIC
wasm-ld: error: /tmp/test1-6da457.o: relocation R_WASM_MEMORY_ADDR_LEB cannot be used against symbol g_a; recompile with -fPIC
clang-14: error: linker command failed with exit code 1 (use -v to see invocation)

it seem like link a static library

if i won use --export-all i can't export global g_a

but i use emcc to compile,it can work emcc test1.c test2.c -s SIDE_MODULE=2 -s LINKABLE=1 -o test12_emcc.wasm this is wasm-objdump -x result


   test12_emcc.wasm: file format wasm 0x1

   Section Details:

   Custom:
    - name: "dylink.0"
   Type[3]:
    - type[0] () -> nil
    - type[1] () -> i32
    - type[2] (i32) -> nil
  Import[5]:
   - global[0] i32 mutable=1 <- env.__stack_pointer
   - global[1] i32 mutable=0 <- env.__memory_base
   - global[2] i32 mutable=0 <- env.__table_base
   - global[3] i32 mutable=1 <- GOT.mem.g_a
   - memory[0] pages: initial=1 <- env.memory
  Function[5]:
   - func[0] sig=0 <__wasm_call_ctors>
   - func[1] sig=0
   - func[2] sig=1 <test1>
   - func[3] sig=2 <setV>
   - func[4] sig=1 <test2>
  Global[1]:
   - global[4] i32 mutable=0 <g_a> - init i32=0
  Export[5]:
   - func[0] <__wasm_call_ctors> -> "__wasm_call_ctors"
   - func[2] <test1> -> "test1"
   - global[4] -> "g_a"
   - func[3] <setV> -> "setV"
   - func[4] <test2> -> "test2"
  Code[5]:
   - func[0] size=4 <__wasm_call_ctors>
   - func[1] size=2
   - func[2] size=30 <test1>
   - func[3] size=45 <setV>
   - func[4] size=12 <test2>
  Data[1]:
   - segment[0] size=4 - init global=1 <env.__memory_base>
    - 0000000: 0100 0000                                ....

it can export g_a with GOT.mem,but it global[4] i32 g_a is not a mutable global.

i want know how to compile use llvm to build the wasm file.