mirror of
https://github.com/Cisco-Talos/clamav.git
synced 2025-10-19 18:33:16 +00:00
115 lines
2.8 KiB
C++
115 lines
2.8 KiB
C++
![]() |
#include "llvm/Support/DataTypes.h"
|
||
|
#include "llvm/System/Threading.h"
|
||
|
#include "llvm/Support/ErrorHandling.h"
|
||
|
#include "llvm/Support/ManagedStatic.h"
|
||
|
#include "llvm/Support/raw_ostream.h"
|
||
|
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||
|
#include "llvm/ExecutionEngine/JIT.h"
|
||
|
#include "llvm/LLVMContext.h"
|
||
|
#include "llvm/System/Signals.h"
|
||
|
#include "llvm/Target/TargetSelect.h"
|
||
|
#include "llvm/Module.h"
|
||
|
#include "llvm/ModuleProvider.h"
|
||
|
#include <cstdlib>
|
||
|
#include <new>
|
||
|
|
||
|
#include "clamav.h"
|
||
|
#include "clambc.h"
|
||
|
#include "bytecode_priv.h"
|
||
|
#include "bytecode.h"
|
||
|
|
||
|
#define MODULE "libclamav JIT: "
|
||
|
|
||
|
using namespace llvm;
|
||
|
struct cli_bcengine {
|
||
|
ExecutionEngine *EE;
|
||
|
LLVMContext Context;
|
||
|
|
||
|
};
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
void do_shutdown() {
|
||
|
llvm_shutdown();
|
||
|
}
|
||
|
void llvm_error_handler(void *user_data, const std::string &reason)
|
||
|
{
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int cli_vm_execute_jit(const struct cli_bc *bc, struct cli_bc_ctx *ctx, const struct cli_bc_func *func, const struct cli_bc_inst *inst)
|
||
|
{
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
|
||
|
{
|
||
|
// LLVM itself never throws exceptions, but operator new may throw bad_alloc
|
||
|
try {
|
||
|
Module *M = new Module("ClamAV jit module", bcs->engine->Context);
|
||
|
{
|
||
|
// Create the JIT.
|
||
|
std::string ErrorMsg;
|
||
|
EngineBuilder builder(M);
|
||
|
builder.setErrorStr(&ErrorMsg);
|
||
|
builder.setEngineKind(EngineKind::JIT);
|
||
|
builder.setOptLevel(CodeGenOpt::Aggressive);
|
||
|
ExecutionEngine *EE = bcs->engine->EE = builder.create();
|
||
|
if (!EE) {
|
||
|
if (!ErrorMsg.empty())
|
||
|
errs() << MODULE << "error creating execution engine: " << ErrorMsg << "\n";
|
||
|
else
|
||
|
errs() << MODULE << "JIT not registered?\n";
|
||
|
return CL_EBYTECODE;
|
||
|
}
|
||
|
EE->DisableLazyCompilation();
|
||
|
|
||
|
// compile all functions now, not lazily!
|
||
|
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
|
||
|
Function *Fn = &*I;
|
||
|
if (!Fn->isDeclaration())
|
||
|
EE->getPointerToFunction(Fn);
|
||
|
}
|
||
|
}
|
||
|
return -1;
|
||
|
} catch (std::bad_alloc &badalloc) {
|
||
|
errs() << MODULE << badalloc.what() << "\n";
|
||
|
return CL_EMEM;
|
||
|
} catch (...) {
|
||
|
errs() << MODULE << "Unexpected unknown exception occurred.\n";
|
||
|
return CL_EBYTECODE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
int bytecode_init(void)
|
||
|
{
|
||
|
llvm_install_error_handler(llvm_error_handler);
|
||
|
sys::PrintStackTraceOnErrorSignal();
|
||
|
atexit(do_shutdown);
|
||
|
|
||
|
llvm_start_multithreaded();
|
||
|
|
||
|
// If we have a native target, initialize it to ensure it is linked in and
|
||
|
// usable by the JIT.
|
||
|
InitializeNativeTarget();
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
// Called once when loading a new set of BC files
|
||
|
int cli_bytecode_init_jit(struct cli_all_bc *bcs)
|
||
|
{
|
||
|
bcs->engine = (struct cli_bcengine*) malloc(sizeof(struct cli_bcengine));
|
||
|
if (!bcs->engine)
|
||
|
return CL_EMEM;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int cli_bytecode_done_jit(struct cli_all_bc *bcs)
|
||
|
{
|
||
|
if (bcs->engine->EE)
|
||
|
delete bcs->engine->EE;
|
||
|
free(bcs->engine);
|
||
|
bcs->engine = 0;
|
||
|
return 0;
|
||
|
}
|