Exposing disassembler functionality in a DLL/so


We are trying to implement some disassembly support (decode instructions and provide information about them) through a DLL on windows and an SO on linux.

We managed to succeed on windows by building the llvm-c.dll and exporting a function that will return a class instance that supports the necessary API. This so far seems to work in Windows. However, trying to build LLVM-C as a shared object on linux fails on cmake with “Generating libLLVM-c is only supported on Darwin” - Seems like it is build-into the cmakes that you can’t build llvm-c as a shared object on Linux, and according to chatGPT this had been like that since Clang 11.

ChatGPT suggested to build the C++ libLLVM on linux instead, using the cmake flags:
However, when using those flags I get linker errors for missing symbols from our custom target libs. Without those flags, our custom targets build fine on linux, so it’s unclear where we might be missing something in the configuration. Even if we solve this, I’m not sure if that would actually include the required disassembler functionality that we currently got working correctly through LLVM-C.dll on Windows.

Any ideas/suggestions regarding how to handle this in the best way possible, or even any way that would work…


Just use libLLVM; libLLVM-C re-exports a subset of libLLVM’s API (the C API), but ELF doesn’t have a way to do that (without giving them another name).

1 Like

For some reason libLLVM fails to link (although if I just build clang without libLLVM everything works fine - more specifically it fails to link libLTO.so due to missing reference to functions of our custom target), plus it seems like libLLVM DLL can’t be built in MSVC… I guess I might have to use LLVM-C in windows and libLLVM in linux and figure out why I get the linker error.

what references were missing?
My guess is one of those LLVMInitialize<TargetName>XXX functions, if that’s the case, please add the LLVM_EXTERNAL_VISIBILITY attribute.

1 Like

Thanks, that helped!
Should I also use it on the API function that I want to expose (which is the real purpose of building the libLLVM as an SO)?

Also seems like I only need to use -DLLVM_BUILD_LLVM_DYLIB=ON and not -DLLVM_LINK_LLVM_DYLIB=OFF if I just want to build the SO but don’t want to change how clang is built?

I got it working in windows, and in linux I managed to build the shared objects, but when trying to link libLLVM.so to a simple “hello world” app (which doesn’t actually use anything from LLVM), I get an assertion in pass manager:
… /llvm/lib/IR/PassRegistry.cpp:53: void llvm::PassRegistry::registerPass(const llvm::PassInfo&, bool): Assertion `Inserted && “Pass registered multiple times!”’ failed.

Any ideas?