... | ... |
@@ -1232,6 +1232,7 @@ public: |
1232 | 1232 |
for (unsigned j=0;j<bc->num_func;j++) { |
1233 | 1233 |
PrettyStackTraceString CrashInfo("Generate LLVM IR"); |
1234 | 1234 |
const struct cli_bc_func *func = &bc->funcs[j]; |
1235 |
+ bool broken = false; |
|
1235 | 1236 |
|
1236 | 1237 |
// Create all BasicBlocks |
1237 | 1238 |
Function *F = Functions[j]; |
... | ... |
@@ -1308,12 +1309,12 @@ public: |
1308 | 1308 |
} |
1309 | 1309 |
|
1310 | 1310 |
// Generate LLVM IR for each BB |
1311 |
- for (unsigned i=0;i<func->numBB;i++) { |
|
1311 |
+ for (unsigned i=0;i<func->numBB && !broken;i++) { |
|
1312 | 1312 |
bool unreachable = false; |
1313 | 1313 |
const struct cli_bc_bb *bb = &func->BB[i]; |
1314 | 1314 |
Builder.SetInsertPoint(BB[i]); |
1315 | 1315 |
unsigned c = 0; |
1316 |
- for (unsigned j=0;j<bb->numInsts;j++) { |
|
1316 |
+ for (unsigned j=0;j<bb->numInsts && !broken;j++) { |
|
1317 | 1317 |
const struct cli_bc_inst *inst = &bb->insts[j]; |
1318 | 1318 |
Value *Op0=0, *Op1=0, *Op2=0; |
1319 | 1319 |
// libclamav has already validated this. |
... | ... |
@@ -1453,8 +1454,8 @@ public: |
1453 | 1453 |
BasicBlock *False = BB[inst->u.branch.br_false]; |
1454 | 1454 |
if (Cond->getType() != Type::getInt1Ty(Context)) { |
1455 | 1455 |
cli_warnmsg("[Bytecode JIT]: type mismatch in condition"); |
1456 |
- apiMap.irgenTimer.stopTimer(); |
|
1457 |
- return 0; |
|
1456 |
+ broken = true; |
|
1457 |
+ break; |
|
1458 | 1458 |
} |
1459 | 1459 |
Builder.CreateCondBr(Cond, True, False); |
1460 | 1460 |
break; |
... | ... |
@@ -1558,8 +1559,8 @@ public: |
1558 | 1558 |
Value *Op = convertOperand(func, I32Ty, inst->u.three[2]); |
1559 | 1559 |
Op = GEPOperand(Op); |
1560 | 1560 |
if (!createGEP(inst->dest, V, ARRAYREF(Value*, &Op, &Op+1))) { |
1561 |
- apiMap.irgenTimer.stopTimer(); |
|
1562 |
- return 0; |
|
1561 |
+ cli_warnmsg("[Bytecode JIT]: OP_BC_GEP1 createGEP failed\n"); |
|
1562 |
+ broken = true; |
|
1563 | 1563 |
} |
1564 | 1564 |
break; |
1565 | 1565 |
} |
... | ... |
@@ -1572,8 +1573,8 @@ public: |
1572 | 1572 |
Ops[1] = convertOperand(func, I32Ty, inst->u.three[2]); |
1573 | 1573 |
Ops[1] = GEPOperand(Ops[1]); |
1574 | 1574 |
if (!createGEP(inst->dest, V, ARRAYREF(Value*, Ops, Ops+2))) { |
1575 |
- apiMap.irgenTimer.stopTimer(); |
|
1576 |
- return 0; |
|
1575 |
+ cli_warnmsg("[Bytecode JIT]: OP_BC_GEPZ createGEP failed\n"); |
|
1576 |
+ broken = true; |
|
1577 | 1577 |
} |
1578 | 1578 |
break; |
1579 | 1579 |
} |
... | ... |
@@ -1589,8 +1590,8 @@ public: |
1589 | 1589 |
Idxs.push_back(Op); |
1590 | 1590 |
} |
1591 | 1591 |
if (!createGEP(inst->dest, V, ARRAYREFVECTOR(Value*, Idxs))) { |
1592 |
- apiMap.irgenTimer.stopTimer(); |
|
1593 |
- return 0; |
|
1592 |
+ cli_warnmsg("[Bytecode JIT]: OP_BC_GEPN createGEP failed\n"); |
|
1593 |
+ broken = true; |
|
1594 | 1594 |
} |
1595 | 1595 |
break; |
1596 | 1596 |
} |
... | ... |
@@ -1745,22 +1746,31 @@ public: |
1745 | 1745 |
default: |
1746 | 1746 |
cli_warnmsg("[Bytecode JIT]: JIT doesn't implement opcode %d yet!\n", |
1747 | 1747 |
inst->opcode); |
1748 |
- apiMap.irgenTimer.stopTimer(); |
|
1749 |
- return 0; |
|
1748 |
+ broken = true; |
|
1749 |
+ break; |
|
1750 | 1750 |
} |
1751 | 1751 |
} |
1752 | 1752 |
} |
1753 | 1753 |
|
1754 |
- if (verifyFunction(*F, PrintMessageAction)) { |
|
1755 |
- // verification failed |
|
1756 |
- cli_warnmsg("[Bytecode JIT]: Verification failed\n"); |
|
1757 |
- if (cli_debug_flag) { |
|
1758 |
- std::string str; |
|
1759 |
- raw_string_ostream ostr(str); |
|
1760 |
- F->print(ostr); |
|
1761 |
- cli_dbgmsg_internal("[Bytecode JIT]: %s\n", ostr.str().c_str()); |
|
1754 |
+ // If successful so far, run verifyFunction |
|
1755 |
+ if (!broken) { |
|
1756 |
+ if (verifyFunction(*F, PrintMessageAction)) { |
|
1757 |
+ // verification failed |
|
1758 |
+ broken = true; |
|
1759 |
+ cli_warnmsg("[Bytecode JIT]: Verification failed\n"); |
|
1760 |
+ if (cli_debug_flag) { |
|
1761 |
+ std::string str; |
|
1762 |
+ raw_string_ostream ostr(str); |
|
1763 |
+ F->print(ostr); |
|
1764 |
+ cli_dbgmsg_internal("[Bytecode JIT]: %s\n", ostr.str().c_str()); |
|
1765 |
+ } |
|
1762 | 1766 |
} |
1763 |
- delete [] Values; |
|
1767 |
+ } |
|
1768 |
+ |
|
1769 |
+ delete [] Values; |
|
1770 |
+ |
|
1771 |
+ // Cleanup after failure and return 0 |
|
1772 |
+ if (broken) { |
|
1764 | 1773 |
for (unsigned z=0; z < func->numBB ; z++) { |
1765 | 1774 |
delete BB[z]; |
1766 | 1775 |
} |
... | ... |
@@ -1773,7 +1783,7 @@ public: |
1773 | 1773 |
delete [] Functions; |
1774 | 1774 |
return 0; |
1775 | 1775 |
} |
1776 |
- delete [] Values; |
|
1776 |
+ |
|
1777 | 1777 |
delete [] BB; |
1778 | 1778 |
apiMap.irgenTimer.stopTimer(); |
1779 | 1779 |
apiMap.pmTimer.startTimer(); |