Browse code

Various bytecode JIT fixes, teach clamconf about JIT, and make sure make check runs the JIT!

Török Edvin authored on 2009/08/29 02:07:25
Showing 6 changed files
... ...
@@ -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;
... ...
@@ -57,3 +57,5 @@ int bytecode_init(void)
57 57
 {
58 58
     return 0;
59 59
 }
60
+
61
+int have_clamjit=0;
... ...
@@ -144,6 +144,7 @@ CLAMAV_PRIVATE {
144 144
     messageDestroy;
145 145
     base64Flush;
146 146
     have_rar;
147
+    have_clamjit;
147 148
     cli_bytecode_load;
148 149
     cli_bytecode_prepare;
149 150
     cli_bytecode_run;
... ...
@@ -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