If __cxa_atexit does not exist in teh module then add it.

This commit is contained in:
Axel Naumann 2013-11-01 18:31:18 +01:00 committed by sftnight
parent bd3c03cc17
commit 869ba659a1

View File

@ -12,6 +12,7 @@
#include "clang/AST/Type.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/PassManager.h"
#include "llvm/ADT/SmallPtrSet.h"
@ -51,10 +52,38 @@ void ExecutionContext::shuttingDown() {
void ExecutionContext::remapCXAAtExit() {
assert(!m_CxaAtExitRemapped && "__cxa_at_exit already remapped.");
llvm::Function* atExit = m_engine->FindFunctionNamed("__cxa_atexit");
llvm::Function* clingAtExit
= m_engine->FindFunctionNamed("cling_cxa_atexit");
assert(atExit && clingAtExit && "atExit and clingAtExit must exist.");
assert(clingAtExit && "cling_cxa_atexit must exist.");
llvm::Function* atExit = m_engine->FindFunctionNamed("__cxa_atexit");
if (!atExit) {
// Inject __cxa_atexit into module
llvm::Type* retTy = 0;
llvm::Type* voidPtrTy = 0;
if (sizeof(int) == 4) {
retTy = llvm::Type::getInt32Ty(llvm::getGlobalContext());
voidPtrTy = llvm::Type::getInt32PtrTy(llvm::getGlobalContext());
} else if (sizeof(int) == 8) {
retTy = llvm::Type::getInt64Ty(llvm::getGlobalContext());
voidPtrTy = llvm::Type::getInt64PtrTy(llvm::getGlobalContext());
} else {
assert(retTy && "Unsupported sizeof(int)!");
retTy = llvm::Type::getInt64Ty(llvm::getGlobalContext());
voidPtrTy = llvm::Type::getInt64PtrTy(llvm::getGlobalContext());
}
llvm::SmallVector<llvm::Type*, 3> argTy;
argTy.push_back(voidPtrTy);
argTy.push_back(voidPtrTy);
argTy.push_back(voidPtrTy);
llvm::FunctionType* cxaatexitTy
= llvm::FunctionType::get(retTy, argTy, false /*varArg*/);
llvm::Function* atexitFunc
= llvm::Function::Create(cxaatexitTy, llvm::GlobalValue::InternalLinkage,
"__cxa_atexit", 0 /*module*/);
m_engine->addGlobalMapping(atexitFunc, clingAtExit);
}
void* clingAtExitAddr = m_engine->getPointerToFunction(clingAtExit);
assert(clingAtExitAddr && "cannot find cling_cxa_atexit");