Switch object format from ELF to COFF and fix symbols lookup
- Switch object format from ELF (Linux) to COFF (Windows) - Fix mangled symbols lookup on Windows: remove leading '_' and use malloc to simulate __imp_ variables (that are indirection pointers)
This commit is contained in:
parent
54dbb830b3
commit
92213e719a
@ -894,7 +894,7 @@ static void stringifyPreprocSetting(PreprocessorOptions& PPOpts,
|
||||
llvm::Triple TheTriple(llvm::sys::getProcessTriple());
|
||||
#ifdef LLVM_ON_WIN32
|
||||
// COFF format currently needs a few changes in LLVM to function properly.
|
||||
TheTriple.setObjectFormat(llvm::Triple::ELF);
|
||||
TheTriple.setObjectFormat(llvm::Triple::COFF);
|
||||
#endif
|
||||
clang::driver::Driver Drvr(argv[0], TheTriple.getTriple(), *Diags);
|
||||
//Drvr.setWarnMissingInput(false);
|
||||
|
@ -16,8 +16,8 @@
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/Support/DynamicLibrary.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Apple adds an extra '_'
|
||||
#if defined(__APPLE__) || defined (_MSC_VER)
|
||||
// Apple and Windows add an extra '_'
|
||||
# define MANGLE_PREFIX "_"
|
||||
#endif
|
||||
|
||||
|
@ -533,6 +533,16 @@ const void* DLOpen(const std::string& Path, std::string* Err) {
|
||||
return reinterpret_cast<void*>(dyLibHandle);
|
||||
}
|
||||
|
||||
const void *CheckImp(void *addr, bool dllimp) {
|
||||
// __imp_ variables are indirection pointers, so use malloc to simulate that
|
||||
if (dllimp) {
|
||||
void **imp_addr = (void**)malloc(sizeof(void*));
|
||||
*imp_addr = addr;
|
||||
addr = (void*)imp_addr;
|
||||
}
|
||||
return (const void *)addr;
|
||||
}
|
||||
|
||||
const void* DLSym(const std::string& Name, std::string* Err) {
|
||||
#ifdef _WIN64
|
||||
const DWORD Flags = LIST_MODULES_64BIT;
|
||||
@ -540,6 +550,18 @@ const void* DLSym(const std::string& Name, std::string* Err) {
|
||||
const DWORD Flags = LIST_MODULES_32BIT;
|
||||
#endif
|
||||
|
||||
bool dllimp = false;
|
||||
std::string s = Name;
|
||||
// remove the leading '__imp_' from the symbol (will be replaced by an
|
||||
// indirection pointer later on)
|
||||
if (s.compare(0, 6, "__imp_") == 0) {
|
||||
dllimp = true;
|
||||
s.replace(0, 6, "");
|
||||
}
|
||||
// remove the leading '_' from the symbol
|
||||
if (s.compare(0, 1, "_") == 0)
|
||||
s.replace(0, 1, "");
|
||||
|
||||
DWORD Bytes;
|
||||
std::string ErrStr;
|
||||
llvm::SmallVector<HMODULE, 128> Modules;
|
||||
@ -554,8 +576,8 @@ const void* DLSym(const std::string& Name, std::string* Err) {
|
||||
|
||||
// In reverse so user loaded modules are searched first
|
||||
for (auto It = Modules.rbegin(), End = Modules.rend(); It < End; ++It) {
|
||||
if (const void* Addr = ::GetProcAddress(*It, Name.c_str()))
|
||||
return Addr;
|
||||
if (void* Addr = ::GetProcAddress(*It, s.c_str()))
|
||||
return CheckImp(Addr, dllimp);
|
||||
}
|
||||
if (NumNeeded > NumFirst) {
|
||||
// The number of modules was too small to get them all, so call again
|
||||
@ -563,8 +585,8 @@ const void* DLSym(const std::string& Name, std::string* Err) {
|
||||
if (::EnumProcessModulesEx(::GetCurrentProcess(), &Modules[0],
|
||||
Modules.capacity_in_bytes(), &Bytes, Flags) != 0) {
|
||||
for (DWORD i = NumNeeded-1; i > NumFirst; --i) {
|
||||
if (const void* Addr = ::GetProcAddress(Modules[i], Name.c_str()))
|
||||
return Addr;
|
||||
if (void* Addr = ::GetProcAddress(Modules[i], s.c_str()))
|
||||
return CheckImp(Addr, dllimp);
|
||||
}
|
||||
} else if (Err)
|
||||
GetLastErrorAsString(*Err, "EnumProcessModulesEx");
|
||||
|
Loading…
Reference in New Issue
Block a user