diff --git a/clambc/bcrun.c b/clambc/bcrun.c index 4fa35f0c3..14ebef59a 100644 --- a/clambc/bcrun.c +++ b/clambc/bcrun.c @@ -32,6 +32,7 @@ #include "clamav.h" #include "shared/optparser.h" #include "shared/misc.h" +#include "libclamav/dconf.h" #include #include @@ -224,7 +225,7 @@ int main(int argc, char *argv[]) if (optget(opts, "force-interpreter")->enabled) { bcs.engine = NULL; } else { - rc = cli_bytecode_init(&bcs); + rc = cli_bytecode_init(&bcs, BYTECODE_ENGINE_MASK); if (rc != CL_SUCCESS) { fprintf(stderr,"Unable to init bytecode engine: %s\n", cl_strerror(rc)); optfree(opts); @@ -249,7 +250,7 @@ int main(int argc, char *argv[]) } else if (optget(opts, "printsrc")->enabled) { print_src(opts->filename[0]); } else { - rc = cli_bytecode_prepare(&bcs); + rc = cli_bytecode_prepare(&bcs, BYTECODE_ENGINE_MASK); if (rc != CL_SUCCESS) { fprintf(stderr,"Unable to prepare bytecode: %s\n", cl_strerror(rc)); optfree(opts); diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c index 989a80809..ea7c02a49 100644 --- a/libclamav/bytecode.c +++ b/libclamav/bytecode.c @@ -24,6 +24,7 @@ #include "clamav-config.h" #endif +#include "dconf.h" #include "clamav.h" #include "others.h" #include "pe.h" @@ -1476,6 +1477,7 @@ void cli_bytecode_destroy(struct cli_bc *bc) static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) { unsigned i, j, k; + for (i=0;inum_func;i++) { struct cli_bc_func *bcfunc = &bc->funcs[i]; unsigned totValues = bcfunc->numValues + bcfunc->numConstants; @@ -1604,7 +1606,7 @@ static int cli_bytecode_prepare_interpreter(struct cli_bc *bc) return CL_SUCCESS; } -int cli_bytecode_prepare(struct cli_all_bc *bcs) +int cli_bytecode_prepare(struct cli_all_bc *bcs, unsigned dconfmask) { unsigned i; int rc; @@ -1614,6 +1616,10 @@ int cli_bytecode_prepare(struct cli_all_bc *bcs) struct cli_bc *bc = &bcs->all_bcs[i]; if (bc->state == bc_interp || bc->state == bc_jit) continue; + if (!(dconfmask & BYTECODE_INTERPRETER)) { + cli_warnmsg("Bytecode needs interpreter, but interpreter is disabled\n"); + continue; + } rc = cli_bytecode_prepare_interpreter(bc); if (rc != CL_SUCCESS) return rc; @@ -1621,10 +1627,10 @@ int cli_bytecode_prepare(struct cli_all_bc *bcs) return CL_SUCCESS; } -int cli_bytecode_init(struct cli_all_bc *allbc) +int cli_bytecode_init(struct cli_all_bc *allbc, unsigned dconfmask) { memset(allbc, 0, sizeof(*allbc)); - return cli_bytecode_init_jit(allbc); + return cli_bytecode_init_jit(allbc, dconfmask); } int cli_bytecode_done(struct cli_all_bc *allbc) diff --git a/libclamav/bytecode.h b/libclamav/bytecode.h index 2f1b52c0c..6bba27c19 100644 --- a/libclamav/bytecode.h +++ b/libclamav/bytecode.h @@ -98,9 +98,9 @@ extern int have_clamjit; #ifdef __cplusplus } #endif -int cli_bytecode_init(struct cli_all_bc *allbc); +int cli_bytecode_init(struct cli_all_bc *allbc, unsigned dconfmask); int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio, int security); -int cli_bytecode_prepare(struct cli_all_bc *allbc); +int cli_bytecode_prepare(struct cli_all_bc *allbc, unsigned dconfmask); int cli_bytecode_run(const struct cli_all_bc *bcs, const struct cli_bc *bc, struct cli_bc_ctx *ctx); void cli_bytecode_destroy(struct cli_bc *bc); int cli_bytecode_done(struct cli_all_bc *allbc); diff --git a/libclamav/bytecode_nojit.c b/libclamav/bytecode_nojit.c index 3829b630e..e36555eac 100644 --- a/libclamav/bytecode_nojit.c +++ b/libclamav/bytecode_nojit.c @@ -48,7 +48,7 @@ int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx, con return CL_EBYTECODE; } -int cli_bytecode_init_jit(struct cli_all_bc *allbc) +int cli_bytecode_init_jit(struct cli_all_bc *allbc, unsigned dconfmask) { return CL_SUCCESS; } diff --git a/libclamav/bytecode_priv.h b/libclamav/bytecode_priv.h index d0d37d7f7..860408479 100644 --- a/libclamav/bytecode_priv.h +++ b/libclamav/bytecode_priv.h @@ -157,7 +157,7 @@ extern "C" { int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx, const struct cli_bc_func *func); int cli_bytecode_prepare_jit(struct cli_all_bc *bc); -int cli_bytecode_init_jit(struct cli_all_bc *bc); +int cli_bytecode_init_jit(struct cli_all_bc *bc, unsigned dconfmask); int cli_bytecode_done_jit(struct cli_all_bc *bc); #ifdef __cplusplus diff --git a/libclamav/c++/bytecode2llvm.cpp b/libclamav/c++/bytecode2llvm.cpp index ced93d4fd..c98145111 100644 --- a/libclamav/c++/bytecode2llvm.cpp +++ b/libclamav/c++/bytecode2llvm.cpp @@ -25,6 +25,7 @@ #include "llvm/ADT/BitVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/Triple.h" #include "llvm/CallingConv.h" #include "llvm/DerivedTypes.h" #include "llvm/Function.h" @@ -57,6 +58,7 @@ #include "llvm/Analysis/Verifier.h" #include "llvm/Transforms/Scalar.h" #include "llvm/System/ThreadLocal.h" +#include "dconf.h" #include #include #include @@ -1480,12 +1482,47 @@ int bytecode_init(void) return 0; } +extern "C" uint8_t cli_debug_flag; // Called once when loading a new set of BC files -int cli_bytecode_init_jit(struct cli_all_bc *bcs) +int cli_bytecode_init_jit(struct cli_all_bc *bcs, unsigned dconfmask) { LLVMApiScopedLock scopedLock; + Triple triple(sys::getHostTriple()); + if (cli_debug_flag) + errs() << "host triple is: " << sys::getHostTriple() << "\n"; + enum Triple::ArchType arch = triple.getArch(); + switch (arch) { + case Triple::arm: + if (!(dconfmask & BYTECODE_JIT_ARM)) { + if (cli_debug_flag) + errs() << "host triple is: " << sys::getHostTriple() << "\n"; + return 0; + } + break; + case Triple::ppc: + case Triple::ppc64: + if (!(dconfmask & BYTECODE_JIT_PPC)) { + if (cli_debug_flag) + errs() << "JIT disabled for ppc\n"; + return 0; + } + break; + case Triple::x86: + case Triple::x86_64: + if (!(dconfmask & BYTECODE_JIT_X86)) { + if (cli_debug_flag) + errs() << "JIT disabled for x86\n"; + return 0; + } + break; + default: + errs() << "Not supported architecture for " << triple.str() << "\n"; + return CL_EBYTECODE; + } + std::string cpu = sys::getHostCPUName(); - DEBUG(errs() << "host cpu is: " << cpu << "\n"); + if (cli_debug_flag) + errs() << "host cpu is: " << cpu << "\n"; if (!cpu.compare("i386") || !cpu.compare("i486")) { bcs->engine = 0; diff --git a/libclamav/readdb.c b/libclamav/readdb.c index 9d05f421b..9e315688c 100644 --- a/libclamav/readdb.c +++ b/libclamav/readdb.c @@ -2564,7 +2564,7 @@ int cl_load(const char *path, struct cl_engine *engine, unsigned int *signo, uns return ret; if((dboptions & CL_DB_BYTECODE) && !engine->bcs.engine && (engine->dconf->bytecode & BYTECODE_ENGINE_MASK)) { - if((ret = cli_bytecode_init(&engine->bcs))) + if((ret = cli_bytecode_init(&engine->bcs, engine->dconf->bytecode))) return ret; } else { cli_dbgmsg("Bytecode engine disabled\n"); @@ -2996,7 +2996,7 @@ int cl_engine_compile(struct cl_engine *engine) mpool_flush(engine->mempool); /* Compile bytecode */ - if((ret = cli_bytecode_prepare(&engine->bcs))) { + if((ret = cli_bytecode_prepare(&engine->bcs, engine->dconf->bytecode))) { cli_errmsg("Unable to compile/load bytecode: %s\n", cl_strerror(ret)); return ret; } diff --git a/unit_tests/check_bytecode.c b/unit_tests/check_bytecode.c index 9dfeb9d4a..2e8bbc927 100644 --- a/unit_tests/check_bytecode.c +++ b/unit_tests/check_bytecode.c @@ -33,6 +33,7 @@ #include "../libclamav/others.h" #include "../libclamav/bytecode.h" #include "checks.h" +#include "../libclamav/dconf.h" static void runtest(const char *file, uint64_t expected, int fail, int nojit) { @@ -51,7 +52,7 @@ static void runtest(const char *file, uint64_t expected, int fail, int nojit) cl_debug(); if (!nojit) { - rc = cli_bytecode_init(&bcs); + rc = cli_bytecode_init(&bcs, BYTECODE_ENGINE_MASK); fail_unless(rc == CL_SUCCESS, "cli_bytecode_init failed"); } else { bcs.engine = NULL; @@ -64,7 +65,7 @@ static void runtest(const char *file, uint64_t expected, int fail, int nojit) fail_unless(rc == CL_SUCCESS, "cli_bytecode_load failed"); fclose(f); - rc = cli_bytecode_prepare(&bcs); + rc = cli_bytecode_prepare(&bcs, BYTECODE_ENGINE_MASK); fail_unless(rc == CL_SUCCESS, "cli_bytecode_prepare failed"); if (have_clamjit && !nojit && nojit != -1) {