bb#11414 - integrate patch for LLVM 3.6 support

pull/40/merge
Kevin Lin 10 years ago
parent 05017893c6
commit 2c859ec754
  1. 142
      libclamav/c++/bytecode2llvm.cpp
  2. 4
      libclamav/c++/configure.ac
  3. 4
      libclamav/c++/detect.cpp

@ -55,7 +55,13 @@
#include "llvm/Analysis/TargetFolder.h"
#endif
#include "llvm/ExecutionEngine/ExecutionEngine.h"
#if LLVM_VERSION < 36
#include "llvm/ExecutionEngine/JIT.h"
#else
#include "llvm/ExecutionEngine/MCJIT.h"
#include "llvm/Support/DynamicLibrary.h"
#include "llvm/Object/ObjectFile.h"
#endif
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/PassManager.h"
#include "llvm/Support/Compiler.h"
@ -424,13 +430,19 @@ static void* noUnknownFunctions(const std::string& name) {
if (addr)
return addr;
#if LLVM_VERSION < 36
std::string reason((Twine("Attempt to call external function ")+name).str());
llvm_error_handler(0, reason);
#else
// noUnknownFunctions relies on addGlobalMapping, which doesn't work with MCJIT.
// Now the function pointers are found with SymbolSearching.
#endif
return 0;
}
class NotifyListener : public JITEventListener {
public:
#if LLVM_VERSION < 36
virtual void NotifyFunctionEmitted(const Function &F,
void *Code, size_t Size,
const EmittedFunctionDetails &Details)
@ -444,6 +456,18 @@ public:
F.getName().str().c_str(), (long)Size, Code);
#endif
}
#else
// MCJIT doesn't emit single functions, but instead whole objects.
virtual void NotifyObjectEmitted(const object::ObjectFile &Obj,
const RuntimeDyld::LoadedObjectInfo &L)
{
if (!cli_debug_flag)
return;
cli_dbgmsg_internal("[Bytecode JIT]; emitted %s %s of %zd bytes\n",
Obj.getFileFormatName().str().c_str(),
Obj.getFileName().str().c_str(), Obj.getData().size());
}
#endif
};
class TimerWrapper {
@ -1172,10 +1196,18 @@ public:
mdnodes.resize(i+1);
assert(i < mdnodes.size());
const struct cli_bc_dbgnode *node = &bc->dbgnodes[i];
#if LLVM_VERSION < 36
Value **Vals = new Value*[node->numelements];
#else
Metadata **Vals = new Metadata*[node->numelements];
#endif
for (unsigned j=0;j<node->numelements;j++) {
const struct cli_bc_dbgnode_element* el = &node->elements[j];
#if LLVM_VERSION < 36
Value *V;
#else
Metadata *V;
#endif
if (!el->len) {
if (el->nodeid == ~0u)
V = 0;
@ -1186,12 +1218,21 @@ public:
} else if (el->string) {
V = MDString::get(Context, StringRef(el->string, el->len));
} else {
#if LLVM_VERSION < 36
V = ConstantInt::get(IntegerType::get(Context, el->len),
el->constant);
#else
V = ConstantAsMetadata::get(ConstantInt::get(IntegerType::get(Context, el->len),
el->constant));
#endif
}
Vals[j] = V;
}
#if LLVM_VERSION < 36
MDNode *N = MDNode::get(Context, ARRAYREF(Value*,Vals, node->numelements));
#else
MDNode *N = MDNode::get(Context, ARRAYREF(Metadata*,Vals, node->numelements));
#endif
delete[] Vals;
mdnodes[i] = N;
return N;
@ -2000,11 +2041,19 @@ class LLVMApiScopedLock {
// it is not like we are going to codegen from multiple threads
// at a time anyway.
// if (!llvm_is_multithreaded())
#if LLVM_VERSION < 36
llvm_api_lock.acquire();
#else
llvm_api_lock.lock();
#endif
}
~LLVMApiScopedLock() {
// if (!llvm_is_multithreaded())
#if LLVM_VERSION < 36
llvm_api_lock.release();
#else
llvm_api_lock.unlock();
#endif
}
};
@ -2022,7 +2071,12 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
#else
CF->FHandler->addFnAttr(Attribute::NoInline);
#endif
#if LLVM_VERSION < 36
// addGlobalMapping still exists in LLVM 3.6, but it doesn't work with MCJIT, which now replaces the JIT implementation.
EE->addGlobalMapping(CF->FHandler, (void*)(intptr_t)jit_exception_handler);
#else
sys::DynamicLibrary::AddSymbol(CF->FHandler->getName(), (void*)(intptr_t)jit_exception_handler);
#endif
EE->InstallLazyFunctionCreator(noUnknownFunctions);
EE->getPointerToFunction(CF->FHandler);
@ -2112,15 +2166,27 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
FunctionType* DummyTy = FunctionType::get(Type::getVoidTy(Context), false);
CF->FRealmemset = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
"memset", M);
#if LLVM_VERSION < 36
EE->addGlobalMapping(CF->FRealmemset, (void*)(intptr_t)memset);
#else
sys::DynamicLibrary::AddSymbol(CF->FRealmemset->getName(), (void*)(intptr_t)memset);
#endif
EE->getPointerToFunction(CF->FRealmemset);
CF->FRealMemmove = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
"memmove", M);
#if LLVM_VERSION < 36
EE->addGlobalMapping(CF->FRealMemmove, (void*)(intptr_t)memmove);
#else
sys::DynamicLibrary::AddSymbol(CF->FRealMemmove->getName(), (void*)(intptr_t)memmove);
#endif
EE->getPointerToFunction(CF->FRealMemmove);
CF->FRealmemcpy = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
"memcpy", M);
#if LLVM_VERSION < 36
EE->addGlobalMapping(CF->FRealmemcpy, (void*)(intptr_t)memcpy);
#else
sys::DynamicLibrary::AddSymbol(CF->FRealmemcpy->getName(), (void*)(intptr_t)memcpy);
#endif
EE->getPointerToFunction(CF->FRealmemcpy);
args.clear();
@ -2134,7 +2200,11 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
FuncTy_5 = FunctionType::get(Type::getInt32Ty(Context),
args, false);
CF->FRealmemcmp = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, "memcmp", M);
#if LLVM_VERSION < 36
EE->addGlobalMapping(CF->FRealmemcmp, (void*)(intptr_t)memcmp);
#else
sys::DynamicLibrary::AddSymbol(CF->FRealmemcmp->getName(), (void*)(intptr_t)memcmp);
#endif
EE->getPointerToFunction(CF->FRealmemcmp);
}
@ -2365,8 +2435,10 @@ static void setGuard(unsigned char* guardbuf)
static void addFPasses(FunctionPassManager &FPM, bool trusted, const TargetData *TD)
#elif LLVM_VERSION < 35
static void addFPasses(FunctionPassManager &FPM, bool trusted, const DataLayout *TD)
#else
#elif LLVM_VERSION < 36
static void addFPasses(FunctionPassManager &FPM, bool trusted, const Module *M)
#else
static void addFPasses(FunctionPassManager &FPM, bool trusted, Module *M)
#endif
{
// Set up the optimizer pipeline. Start with registering info about how
@ -2375,8 +2447,12 @@ static void addFPasses(FunctionPassManager &FPM, bool trusted, const Module *M)
FPM.add(new TargetData(*TD));
#elif LLVM_VERSION < 35
FPM.add(new DataLayout(*TD));
#else
#elif LLVM_VERSION < 36
FPM.add(new DataLayoutPass(M));
#else
DataLayoutPass *DLP = new DataLayoutPass();
DLP->doInitialization(*M);
FPM.add(DLP);
#endif
// Promote allocas to registers.
FPM.add(createPromoteMemoryToRegisterPass());
@ -2398,7 +2474,11 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
{
// Create the JIT.
std::string ErrorMsg;
#if LLVM_VERSION < 36
EngineBuilder builder(M);
#else
EngineBuilder builder(std::move(std::unique_ptr<Module>(M)));
#endif
#if LLVM_VERSION >= 31
TargetOptions Options;
@ -2435,7 +2515,12 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
// Due to LLVM PR4816 only X86 supports non-lazy compilation, disable
// for now.
EE->DisableLazyCompilation();
#if LLVM_VERSION < 36
EE->DisableSymbolSearching();
#else
// This must be enabled for AddSymbol to work.
EE->DisableSymbolSearching(false);
#endif
struct CommonFunctions CF;
addFunctionProtos(&CF, EE, M);
@ -2513,7 +2598,12 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
std::string reason((Twine("No mapping for builtin api ")+api->name).str());
llvm_error_handler(0, reason);
}
#if LLVM_VERSION < 36
EE->addGlobalMapping(F, dest);
#else
// addGlobalMapping doesn't work with MCJIT, so use symbol searching instead.
sys::DynamicLibrary::AddSymbol(F->getName(), dest);
#endif
EE->getPointerToFunction(F);
apiFuncs[i] = F;
}
@ -2527,13 +2617,21 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
if (2*sizeof(void*) <= 16 && cli_rndnum(2)==2) {
plus = sizeof(void*);
}
#if LLVM_VERSION < 36
EE->addGlobalMapping(Guard, (void*)(&bcs->engine->guard.b[plus]));
#else
sys::DynamicLibrary::AddSymbol(Guard->getName(), (void*)(&bcs->engine->guard.b[plus]));
#endif
setGuard(bcs->engine->guard.b);
bcs->engine->guard.b[plus+sizeof(void*)-1] = 0x00;
// printf("%p\n", *(void**)(&bcs->engine->guard.b[plus]));
Function *SFail = Function::Create(FTy, Function::ExternalLinkage,
"__stack_chk_fail", M);
#if LLVM_VERSION < 36
EE->addGlobalMapping(SFail, (void*)(intptr_t)jit_ssp_handler);
#else
sys::DynamicLibrary::AddSymbol(SFail->getName(), (void*)(intptr_t)jit_ssp_handler);
#endif
EE->getPointerToFunction(SFail);
llvm::Function **Functions = new Function*[bcs->count];
@ -2572,12 +2670,26 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
PM.add(new TargetData(*EE->getTargetData()));
#elif LLVM_VERSION < 35
PM.add(new DataLayout(*EE->getDataLayout()));
#else
#elif LLVM_VERSION < 36
PM.add(new DataLayoutPass(M));
#else
DataLayoutPass *DLP = new DataLayoutPass();
DLP->doInitialization(*M);
PM.add(DLP);
#endif
// TODO: only run this on the untrusted bytecodes, not all of them...
if (has_untrusted)
PM.add(createClamBCRTChecks());
#if LLVM_VERSION >= 36
// With LLVM 3.6 (MCJIT) this Pass is required to work around
// a crash in LLVM caused by the SCCP Pass:
// Pass 'Sparse Conditional Constant Propagation' is not initialized.
// Verify if there is a pass dependency cycle.
// Required Passes:
//
// Program received signal SIGSEGV, Segmentation fault.
PM.add(createGVNPass());
#endif
PM.add(createSCCPPass());
PM.add(createCFGSimplificationPass());
PM.add(createGlobalOptimizerPass());
@ -2591,6 +2703,10 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
pmTimer2.stopTimer();
DEBUG(M->dump());
#if LLVM_VERSION >= 36
EE->finalizeObject();
#endif
{
PrettyStackTraceString CrashInfo2("Native machine codegen");
TimerWrapper codegenTimer("Native codegen");
@ -2676,6 +2792,10 @@ int bytecode_init(void)
// usable by the JIT.
#ifndef AC_APPLE_UNIVERSAL_BUILD
InitializeNativeTarget();
#if LLVM_VERSION >= 36
InitializeNativeTargetAsmPrinter();
InitializeNativeTargetAsmParser();
#endif
#else
InitializeAllTargets();
#endif
@ -2853,7 +2973,11 @@ void stop(const char *msg, llvm::Function* F, llvm::Instruction* I)
}
#if LLVM_VERSION >= 29
#if LLVM_VERSION < 36
static Value *findDbgGlobalDeclare(GlobalVariable *V) {
#else
static Metadata *findDbgGlobalDeclare(GlobalVariable *V) {
#endif
const Module *M = V->getParent();
NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv");
if (!NMD)
@ -2870,7 +2994,11 @@ static Value *findDbgGlobalDeclare(GlobalVariable *V) {
}
/// Find the debug info descriptor corresponding to this function.
#if LLVM_VERSION < 36
static Value *findDbgSubprogramDeclare(Function *V) {
#else
static Metadata *findDbgSubprogramDeclare(Function *V) {
#endif
const Module *M = V->getParent();
NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp");
if (!NMD)
@ -2924,7 +3052,11 @@ static bool getLocationInfo(const Value *V, std::string &DisplayName,
StringRef T;
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) {
#if LLVM_VERSION < 36
Value *DIGV = findDbgGlobalDeclare(GV);
#else
Metadata *DIGV = findDbgGlobalDeclare(GV);
#endif
if (!DIGV) return false;
DIGlobalVariable Var(cast<MDNode>(DIGV));
@ -2944,7 +3076,11 @@ static bool getLocationInfo(const Value *V, std::string &DisplayName,
T = Var.getType().getName();
#endif
} else if (Function *F = dyn_cast<Function>(const_cast<Value*>(V))){
#if LLVM_VERSION < 36
Value *DIF = findDbgSubprogramDeclare(F);
#else
Metadata *DIF = findDbgSubprogramDeclare(F);
#endif
if (!DIF) return false;
DISubprogram Var(cast<MDNode>(DIF));

@ -127,9 +127,9 @@ if test "x$packaged_llvm" = "xyes"; then
elif test $llvmver_test -lt 290; then
AC_MSG_RESULT([no ($llvmver)])
AC_MSG_ERROR([LLVM >= 2.9 required, but "$llvmver"($llvmver_test) found])
elif test $llvmver_test -ge 360; then
elif test $llvmver_test -ge 370; then
AC_MSG_RESULT([no ($llvmver)])
AC_MSG_ERROR([LLVM < 3.6 required, but "$llvmver"($llvmver_test) found])
AC_MSG_ERROR([LLVM < 3.7 required, but "$llvmver"($llvmver_test) found])
else
AC_MSG_RESULT([ok ($llvmver)])
fi

@ -147,14 +147,16 @@ void cli_detect_env_jit(struct cli_environment *env)
case Triple::UnknownOS:
env->os = llvm_os_UnknownOS;
break;
#if LLVM_VERSION < 36
CASE_OS(AuroraUX, os_solaris);
CASE_OS(Cygwin, os_win32);
CASE_OS(MinGW32, os_win32);
#endif
CASE_OS(Darwin, os_darwin);
CASE_OS(DragonFly, os_bsd);
CASE_OS(FreeBSD, os_bsd);
CASE_OS(Linux, os_linux);
CASE_OS(Lv2, os_unknown);
CASE_OS(MinGW32, os_win32);
#if LLVM_VERSION < 29
CASE_OS(MinGW64, os_win64);
#endif

Loading…
Cancel
Save