Some symbols generated by the toolchain cannot be found by GetProcAddress
Here is my case :
lib.cpp:
class __declspec(dllexport) foo {
foo();
virtual ~foo();
};
foo::foo() { }
foo::~foo() { }
app.cpp
#include <windows.h>
#include <cassert>
int main() {
auto module = LoadLibrary("foo.dll");
assert(module);
auto addr = GetProcAddress(module, "_ZTI3foo"); // e.g. typeinfo for foo
assert(addr != 0);
}
even though nm shows that the symbol is there.
Would you have any idea of what causes this behaviour and what would be ways to get the address of this symbol ? The only difference I can see is that the symbol is marked as being in the read-only section by nm. I could not find a way to put it in the "standard", text section where I guess GetProcAddress may be looking.
The reason for this is that the convention within mingw environments (the same goes for GCC) is that the type info for a dllexported class isn't exported as a symbol in the DLL, but any caller that accesses this class via dllimport will locally generate such a typeinfo symbol instead of referring to it elsewhere.
If the caller doesn't see the class definition with a __declspec(dllimport), clang currently doesn't generate the type info though (but GCC does). I have a patch 0001-ItaniumCXXABI-Always-emit-local-typeinfo-for-MinGW.patch.txt that I haven't upstreamed yet, which makes clang match GCC wrt this detail.
The section the symbol is in doesn't matter wrt to what symbols are exported. If there are symbols that are marked dllexport, the linker will export only those and nothing else, when creating a DLL. If there are no symbols marked dllexport, the linker will export all symbols. You can check this with llvm-readobj -coff-directives lib.o for your object file, and you'll see this:
$ llvm-readobj -coff-directives lib.o
File: lib.o
Format: COFF-x86-64
Arch: x86_64
AddressSize: 64bit
Directive(s): -export:_ZN3fooC2Ev -export:_ZN3fooD2Ev -export:_ZN3fooD0Ev -export:_ZTV3foo,data -export:_ZN3fooC1Ev -export:_ZN3fooD1Ev
So this object file explicitly lists which symbols to export, and that doesn't include _ZTI3foo.
You can override this, though, by passing -Wl,--export-all-symbols when linking the DLL. Then the linker will export all symbols, even if they weren't marked for export.