Workaround LLVM JIT PowerPC relocation bug (bb #1921).

Based on Gary Benson's workaround for OpenJDK Shark / IcedTea.
0.96
Török Edvin 16 years ago
parent d772904022
commit f121d43df8
  1. 6
      ChangeLog
  2. 8
      libclamav/c++/bytecode2llvm.cpp
  3. 33
      libclamav/c++/llvm/lib/ExecutionEngine/JIT/JIT.cpp
  4. 26
      libclamav/c++/llvm/lib/Target/PowerPC/PPCISelLowering.cpp

@ -1,3 +1,9 @@
Fri Apr 2 13:09:54 EEST 2010 (edwin)
------------------------------------
* libclamav/c++/{bytecode2llvm.cpp,llvm/lib/ExecutionEngine/JIT/JIT.cpp,
llvm/lib/Target/PowerPC/PPCISelLowering.cpp}: Workaround LLVM JIT PowerPC relocation bug (bb #1921).
Based on Gary Benson's workaround for OpenJDK Shark / IcedTea.
Fri Apr 2 13:07:50 EEST 2010 (edwin)
-------------------------------------
* unit_tests: Fix matchwithread.cbc

@ -1428,6 +1428,7 @@ public:
if (verifyFunction(*F, PrintMessageAction) == 0) {
DEBUG(errs() << "Generating code\n");
// Codegen current function as executable machine code.
EE->getPointerToFunction(Functions[j]);
void *code = EE->getPointerToFunction(F);
DEBUG(errs() << "Code generation finished\n");
@ -1472,6 +1473,7 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
EE->addGlobalMapping(CF->FHandler, (void*)(intptr_t)jit_exception_handler);
EE->InstallLazyFunctionCreator(noUnknownFunctions);
EE->getPointerToFunction(CF->FHandler);
std::vector<const Type*> args;
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
@ -1527,12 +1529,15 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
CF->FRealmemset = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
"memset", M);
EE->addGlobalMapping(CF->FRealmemset, (void*)(intptr_t)memset);
EE->getPointerToFunction(CF->FRealmemset);
CF->FRealMemmove = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
"memmove", M);
EE->addGlobalMapping(CF->FRealMemmove, (void*)(intptr_t)memmove);
EE->getPointerToFunction(CF->FRealMemmove);
CF->FRealmemcpy = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
"memcpy", M);
EE->addGlobalMapping(CF->FRealmemcpy, (void*)(intptr_t)memcpy);
EE->getPointerToFunction(CF->FRealmemcpy);
args.clear();
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
@ -1542,6 +1547,7 @@ static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, M
args, false);
CF->FRealmemcmp = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, "memcmp", M);
EE->addGlobalMapping(CF->FRealmemcmp, (void*)(intptr_t)memcmp);
EE->getPointerToFunction(CF->FRealmemcmp);
}
}
@ -1755,6 +1761,7 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
llvm_unreachable("invalid api type");
}
EE->addGlobalMapping(F, dest);
EE->getPointerToFunction(F);
apiFuncs[i] = F;
}
@ -1774,6 +1781,7 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
Function *SFail = Function::Create(FTy, Function::ExternalLinkage,
"__stack_chk_fail", M);
EE->addGlobalMapping(SFail, (void*)(intptr_t)jit_ssp_handler);
EE->getPointerToFunction(SFail);
for (unsigned i=0;i<bcs->count;i++) {
const struct cli_bc *bc = &bcs->all_bcs[i];

@ -255,7 +255,8 @@ public:
MutexGuard guard(Lock);
JITs.erase(jit);
}
void *getPointerToNamedFunction(const char *Name) const {
void *getPointerToNamedFunction(const char *Name,
bool AbortOnFailure = true) const {
MutexGuard guard(Lock);
assert(JITs.size() != 0 && "No Jit registered");
//search function in every instance of JIT
@ -267,7 +268,19 @@ public:
}
// The function is not available : fallback on the first created (will
// search in symbol of the current program/library)
return (*JITs.begin())->getPointerToNamedFunction(Name);
return (*JITs.begin())->getPointerToNamedFunction(Name, AbortOnFailure);
}
void *getPointerToGlobalIfAvailable(GlobalValue *V) const {
MutexGuard guard(Lock);
assert(JITs.size() != 0 && "No Jit registered");
//search function in every instance of JIT
for (SmallPtrSet<JIT*, 1>::const_iterator Jit = JITs.begin(),
end = JITs.end();
Jit != end; ++Jit) {
if (void *Ptr = (*Jit)->getPointerToGlobalIfAvailable(V))
return Ptr;
}
return 0;
}
};
ManagedStatic<JitPool> AllJits;
@ -283,6 +296,22 @@ extern "C" {
}
}
extern "C" {
// getPointerToNamedFunctionOrNull - same as the above, but returns
// NULL instead of aborting if the function cannot be found.
void *getPointerToNamedFunctionOrNull(const char *Name) {
return AllJits->getPointerToNamedFunction(Name, false);
}
}
extern "C" {
// getPointerToGlobalIfAvailable - same as the above, but for global
// variables, and only for those that have been codegened already.
void *getPointerToGlobalIfAvailable(GlobalValue *V) {
return AllJits->getPointerToGlobalIfAvailable(V);
}
}
JIT::JIT(Module *M, TargetMachine &tm, TargetJITInfo &tji,
JITMemoryManager *JMM, CodeGenOpt::Level OptLevel, bool GVsWithCode)
: ExecutionEngine(M), TM(tm), TJI(tji), AllocateGVsWithCode(GVsWithCode),

@ -2450,6 +2450,9 @@ void PrepareTailCall(SelectionDAG &DAG, SDValue &InFlag, SDValue &Chain,
InFlag = Chain.getValue(1);
}
extern "C" void *getPointerToNamedFunctionOrNull(const char *Name);
extern "C" void *getPointerToGlobalIfAvailable(GlobalValue *Value);
static
unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
SDValue &Chain, DebugLoc dl, int SPDiff, bool isTailCall,
@ -2462,6 +2465,29 @@ unsigned PrepareCall(SelectionDAG &DAG, SDValue &Callee, SDValue &InFlag,
unsigned CallOpc = isSVR4ABI ? PPCISD::CALL_SVR4 : PPCISD::CALL_Darwin;
// XXX Work around for http://llvm.org/bugs/show_bug.cgi?id=5201
// and http://icedtea.classpath.org/bugzilla/show_bug.cgi?id=399
// for Shark.
//
// If the callee is an ExternalSymbol node, and the symbol can be
// resolved to a function pointer, then insert that pointer as a
// constant. This causes the next block of code to fall into the
// block that emits an indirect call. This works around
//
// This works for Shark because the only kinds of call that Shark
// makes that do not already fall into the indirect call block are
// calls to pre-existing external functions.
if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee)) {
void *FuncPtr = getPointerToNamedFunctionOrNull(S->getSymbol());
if (FuncPtr)
Callee = DAG.getConstant((uint64_t) FuncPtr, PtrVT);
}
if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
void *FuncPtr = getPointerToGlobalIfAvailable(G->getGlobal());
if (FuncPtr)
Callee = DAG.getConstant((uint64_t) FuncPtr, PtrVT);
}
// If the callee is a GlobalAddress/ExternalSymbol node (quite common, every
// direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol
// node so that legalize doesn't hack it.

Loading…
Cancel
Save