Run C++ static constructors in a DLL loaded with /NOENTRY /NODEFAULTLIB. The compiler places CUDA fatbin registration in the .CRT$XCU section. Without CRT startup, these never run, so we walk the merged .CRT section in the PE and call each non-null function pointer.
| 17 | // Without CRT startup, these never run, so we walk the merged .CRT section |
| 18 | // in the PE and call each non-null function pointer. |
| 19 | void runStaticInitializers(HMODULE module) |
| 20 | { |
| 21 | auto base = reinterpret_cast<const unsigned char*>(module); |
| 22 | auto dos = reinterpret_cast<const IMAGE_DOS_HEADER*>(base); |
| 23 | auto nt = reinterpret_cast<const IMAGE_NT_HEADERS*>(base + dos->e_lfanew); |
| 24 | auto sec = IMAGE_FIRST_SECTION(nt); |
| 25 | |
| 26 | for (WORD i = 0; i < nt->FileHeader.NumberOfSections; ++i, ++sec) |
| 27 | { |
| 28 | if (memcmp(sec->Name, ".CRT", 4) == 0) |
| 29 | { |
| 30 | using InitFunc = void(__cdecl*)(); |
| 31 | auto funcs = reinterpret_cast<InitFunc*>(const_cast<unsigned char*>(base) + sec->VirtualAddress); |
| 32 | size_t count = sec->SizeOfRawData / sizeof(InitFunc); |
| 33 | for (size_t j = 0; j < count; ++j) |
| 34 | { |
| 35 | if (funcs[j]) |
| 36 | { |
| 37 | funcs[j](); |
| 38 | } |
| 39 | } |
| 40 | } |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | std::string getWindowsError() |
| 45 | { |