... | ... |
@@ -34,6 +34,7 @@ |
34 | 34 |
#include "libclamav/str.h" |
35 | 35 |
#include "libclamav/clamav.h" |
36 | 36 |
#include "libclamav/others.h" |
37 |
+#include "libclamav/bytecode.h" |
|
37 | 38 |
|
38 | 39 |
static struct _cfgfile { |
39 | 40 |
const char *name; |
... | ... |
@@ -288,7 +289,9 @@ int main(int argc, char **argv) |
288 | 288 |
printf("BZIP2 "); |
289 | 289 |
#endif |
290 | 290 |
if(have_rar) |
291 |
- printf("RAR"); |
|
291 |
+ printf("RAR "); |
|
292 |
+ if (have_clamjit) |
|
293 |
+ printf("JIT"); |
|
292 | 294 |
printf("\n"); |
293 | 295 |
|
294 | 296 |
if(!strlen(dbdir)) { |
... | ... |
@@ -67,6 +67,7 @@ int cli_bytecode_context_clear(struct cli_bc_ctx *ctx); |
67 | 67 |
uint64_t cli_bytecode_context_getresult_int(struct cli_bc_ctx *ctx); |
68 | 68 |
void cli_bytecode_context_destroy(struct cli_bc_ctx *ctx); |
69 | 69 |
|
70 |
+extern int have_clamjit; |
|
70 | 71 |
int cli_bytecode_init(struct cli_all_bc *allbc); |
71 | 72 |
int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio); |
72 | 73 |
int cli_bytecode_prepare(struct cli_all_bc *allbc); |
... | ... |
@@ -444,7 +444,9 @@ public: |
444 | 444 |
break; |
445 | 445 |
} |
446 | 446 |
default: |
447 |
- assert(0 && "Not implemented yet"); |
|
447 |
+ errs() << "JIT doesn't implement opcode " << |
|
448 |
+ inst->opcode << " yet!\n"; |
|
449 |
+ return false; |
|
448 | 450 |
} |
449 | 451 |
} |
450 | 452 |
} |
... | ... |
@@ -505,6 +507,8 @@ int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx, |
505 | 505 |
|
506 | 506 |
int cli_bytecode_prepare_jit(struct cli_all_bc *bcs) |
507 | 507 |
{ |
508 |
+ if (!bcs->engine) |
|
509 |
+ return CL_EBYTECODE; |
|
508 | 510 |
jmp_buf env; |
509 | 511 |
// setup exception handler to longjmp back here |
510 | 512 |
ExceptionReturn.set(&env); |
... | ... |
@@ -536,7 +540,9 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs) |
536 | 536 |
} |
537 | 537 |
|
538 | 538 |
EE->RegisterJITEventListener(createOProfileJITEventListener()); |
539 |
- EE->DisableLazyCompilation(); |
|
539 |
+ // Due to LLVM PR4816 only X86 supports non-lazy compilation, disable |
|
540 |
+ // for now. |
|
541 |
+ // EE->DisableLazyCompilation(); |
|
540 | 542 |
EE->DisableSymbolSearching(); |
541 | 543 |
|
542 | 544 |
FunctionPassManager OurFPM(MP); |
... | ... |
@@ -600,10 +606,12 @@ int cli_bytecode_init_jit(struct cli_all_bc *bcs) |
600 | 600 |
|
601 | 601 |
int cli_bytecode_done_jit(struct cli_all_bc *bcs) |
602 | 602 |
{ |
603 |
- if (bcs->engine->EE) |
|
604 |
- delete bcs->engine->EE; |
|
605 |
- delete bcs->engine; |
|
606 |
- bcs->engine = 0; |
|
603 |
+ if (bcs->engine) { |
|
604 |
+ if (bcs->engine->EE) |
|
605 |
+ delete bcs->engine->EE; |
|
606 |
+ delete bcs->engine; |
|
607 |
+ bcs->engine = 0; |
|
608 |
+ } |
|
607 | 609 |
return 0; |
608 | 610 |
} |
609 | 611 |
|
... | ... |
@@ -611,3 +619,5 @@ void cli_bytecode_debug(int argc, char **argv) |
611 | 611 |
{ |
612 | 612 |
cl::ParseCommandLineOptions(argc, argv); |
613 | 613 |
} |
614 |
+ |
|
615 |
+int have_clamjit=1; |
... | ... |
@@ -34,7 +34,7 @@ |
34 | 34 |
#include "../libclamav/bytecode.h" |
35 | 35 |
#include "checks.h" |
36 | 36 |
|
37 |
-static void runtest(const char *file, uint64_t expected, int fail) |
|
37 |
+static void runtest(const char *file, uint64_t expected, int fail, int nojit) |
|
38 | 38 |
{ |
39 | 39 |
int rc; |
40 | 40 |
int fd = open_testfile(file); |
... | ... |
@@ -50,8 +50,12 @@ static void runtest(const char *file, uint64_t expected, int fail) |
50 | 50 |
|
51 | 51 |
cl_debug(); |
52 | 52 |
|
53 |
- rc = cli_bytecode_init(&bcs); |
|
54 |
- fail_unless(rc == CL_SUCCESS, "cli_bytecode_init failed"); |
|
53 |
+ if (!nojit) { |
|
54 |
+ rc = cli_bytecode_init(&bcs); |
|
55 |
+ fail_unless(rc == CL_SUCCESS, "cli_bytecode_init failed"); |
|
56 |
+ } else { |
|
57 |
+ bcs.engine = NULL; |
|
58 |
+ } |
|
55 | 59 |
|
56 | 60 |
bcs.all_bcs = &bc; |
57 | 61 |
bcs.count = 1; |
... | ... |
@@ -63,6 +67,10 @@ static void runtest(const char *file, uint64_t expected, int fail) |
63 | 63 |
rc = cli_bytecode_prepare(&bcs); |
64 | 64 |
fail_unless(rc == CL_SUCCESS, "cli_bytecode_prepare failed"); |
65 | 65 |
|
66 |
+ if (have_clamjit && !nojit && nojit != -1) { |
|
67 |
+ fail_unless(bc.state == bc_jit, "preparing for JIT failed"); |
|
68 |
+ } |
|
69 |
+ |
|
66 | 70 |
ctx = cli_bytecode_context_alloc(); |
67 | 71 |
fail_unless(!!ctx, "cli_bytecode_context_alloc failed"); |
68 | 72 |
|
... | ... |
@@ -82,26 +90,35 @@ static void runtest(const char *file, uint64_t expected, int fail) |
82 | 82 |
|
83 | 83 |
START_TEST (test_retmagic) |
84 | 84 |
{ |
85 |
- runtest("input/retmagic.cbc", 0x1234f00d, CL_SUCCESS); |
|
85 |
+ cl_init(CL_INIT_DEFAULT); |
|
86 |
+ runtest("input/retmagic.cbc", 0x1234f00d, CL_SUCCESS, 0); |
|
87 |
+ runtest("input/retmagic.cbc", 0x1234f00d, CL_SUCCESS, 1); |
|
86 | 88 |
} |
87 | 89 |
END_TEST |
88 | 90 |
|
89 | 91 |
START_TEST (test_arith) |
90 | 92 |
{ |
91 |
- runtest("input/arith.cbc", 0xd5555555, CL_SUCCESS); |
|
93 |
+ cl_init(CL_INIT_DEFAULT); |
|
94 |
+ runtest("input/arith.cbc", 0xd5555555, CL_SUCCESS, 0); |
|
95 |
+ runtest("input/arith.cbc", 0xd5555555, CL_SUCCESS, 1); |
|
92 | 96 |
} |
93 | 97 |
END_TEST |
94 | 98 |
|
95 | 99 |
START_TEST (test_apicalls) |
96 | 100 |
{ |
97 |
- runtest("input/apicalls.cbc", 0xf00d, CL_SUCCESS); |
|
101 |
+ cl_init(CL_INIT_DEFAULT); |
|
102 |
+ /* Not yet implemented for JIT, expect to return error */ |
|
103 |
+ runtest("input/apicalls.cbc", 0xf00d, CL_SUCCESS, -1); |
|
104 |
+ runtest("input/apicalls.cbc", 0xf00d, CL_SUCCESS, 1); |
|
98 | 105 |
} |
99 | 106 |
END_TEST |
100 | 107 |
|
101 | 108 |
START_TEST (test_div0) |
102 | 109 |
{ |
110 |
+ cl_init(CL_INIT_DEFAULT); |
|
103 | 111 |
/* must not crash on div#0 but catch it */ |
104 |
- runtest("input/div0.cbc", 0, CL_EBYTECODE); |
|
112 |
+ runtest("input/div0.cbc", 0, CL_EBYTECODE, 0); |
|
113 |
+ runtest("input/div0.cbc", 0, CL_EBYTECODE, 1); |
|
105 | 114 |
} |
106 | 115 |
END_TEST |
107 | 116 |
|