Skip to content

Instantly share code, notes, and snippets.

@yowl
Created May 15, 2019 21:11
Show Gist options
  • Save yowl/c143f0520fa0544d41a24bce627086fe to your computer and use it in GitHub Desktop.
Save yowl/c143f0520fa0544d41a24bce627086fe to your computer and use it in GitHub Desktop.
ld-wasm linker problem in corert
I'm trying to build the wasm target using llvm9 and I'm getting this error on linking
Microsoft (R) Program Maintenance Utility Version 14.20.27508.1
Copyright (C) Microsoft Corporation. All rights reserved.
[ 1%] Linking CXX static library libPortableRuntime.bc
wasm-ld: error: symbol type mismatch: RhpInterfaceDispatch1
>>> defined as WASM_SYMBOL_TYPE_DATA in CMakeFiles/PortableRuntime.dir/__/CachedInterfaceDispatch.cpp.o
>>> defined as WASM_SYMBOL_TYPE_FUNCTION in CMakeFiles/PortableRuntime.dir/__/portable.cpp.o
wasm-ld: error: symbol type mismatch: RhpInterfaceDispatch2
>>> defined as WASM_SYMBOL_TYPE_DATA in CMakeFiles/PortableRuntime.dir/__/CachedInterfaceDispatch.cpp.o
>>> defined as WASM_SYMBOL_TYPE_FUNCTION in CMakeFiles/PortableRuntime.dir/__/portable.cpp.o
If I run llvm-dumpobj on the 2 files in question you can see the mismatch, CachedInterfaceDispatch.cpp.o:
00000000 g O *UND* RhpInterfaceDispatch1
00000000 g O *UND* RhpInterfaceDispatch2
and portable.cpp.o:
00000ec5 g F CODE .hidden RhpInterfaceDispatch1
00000f13 g F CODE .hidden RhpInterfaceDispatch2
I had a short conversation on the llvm IRC chat where they seemed to confirm that the compilation and linker were correct
and the code could be modified:
<yowl00> extern "C" void (*RhpInterfaceDispatch2)(); <- would you expect clang to output as an undefined data symbol or undefined function symbol?
* V|r (~Vir@p508797D4.dip0.t-ipconnect.de) has joined
<yowl00> it makes it an undefined data symbol which sounds right, its just a pointer, no?
<compnerd> yowl00: undefined data symbol
<yowl00> compnerd: that's good, no problem with the object file generation then. And the linker should be able handle marrying that up to the actual definition which would be a function symbol?
<compnerd> yowl00: nope
<compnerd> yowl00: that will give you an undefined symbol after you link
<compnerd> you need do an explicit `extern "C" void (*RhpInterfaceDispatch2)() = &RhpInterfaceDispatch2Implementation;`
<yowl00> compnerd: I get a symbol type mismatch, so there's some glue missing
<compnerd> the `&` is obviously optional - the type conversion should kick in on that
<compnerd> yowl00: nope, no glue mismatch, you cannot just define a function `RhpInterfaceDispatch2`
<compnerd> that is supposed to be a pointer to the implementation, note the fact that assignment has a suffix
<compnerd> you could do an `extern "C" void RhpInterfaceDispatch2()` if you don't want the indirection
<yowl00> compnerd: what about an extern with a body like https://github.com/dotnet/corert/blob/master/src/Native/Runtime/portable.cpp#L219
<yowl00> where that macro is EXTERN_C REDHAWK_API _rettype __fastcall _method _args
<compnerd> an `extern` with a body or an `extern "C"` with a body?
<yowl00> extern "C"
<compnerd> yeah, that wont work
<compnerd> that will define the the function with the same name
<yowl00> ok, I need to do some more reading, this code compiles somehow, I'm just trying it with llvm/clang9/ld-wasm
<compnerd> it will compile, but fail to link
<yowl00> yes, that's my problem wasm-ld doesn't like the symbol mismatch. Maybe I should see what it does when I build for x64 rather than wasm
<compnerd> yowl00: where is the pointer to it in the code?
<compnerd> yowl00: although! that is .NET core ... they could be doing that across a module boundary and it will work just fine on Windows
compnerd> they could be manually handling the `__declspec(dllimport)` in that case
<yowl00> compnerd: these pointers are stored in an array https://github.com/dotnet/corert/blob/d725e5cbdfe58d70b193affc16519ccc367597fe/src/Native/Runtime/CachedInterfaceDispatch.cpp#L233-L241
<compnerd> yowl00: lol, I see ... yes, that will work unless your linker is clever enough to realize that they type is different; just make those function declarations instead
So is it going to be ok to change the externs in CachedInterfaceDispatch to functions rather than function pointers?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment