2
* JIT compile ClamAV bytecode.
4
* Copyright (C) 2009-2010 Sourcefire, Inc.
8
* This program is free software; you can redistribute it and/or modify
9
* it under the terms of the GNU General Public License version 2 as
10
* published by the Free Software Foundation.
12
* This program is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
* GNU General Public License for more details.
17
* You should have received a copy of the GNU General Public License
18
* along with this program; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
22
#define DEBUG_TYPE "clamavjit"
28
#include "ClamBCModule.h"
29
#include "ClamBCDiagnostics.h"
30
#include "llvm/Analysis/DebugInfo.h"
31
#include "llvm/ADT/DenseMap.h"
32
#include "llvm/ADT/BitVector.h"
33
#include "llvm/ADT/PostOrderIterator.h"
34
#include "llvm/ADT/StringMap.h"
35
#include "llvm/ADT/StringSwitch.h"
36
#include "llvm/ADT/Triple.h"
37
#include "llvm/ADT/SmallSet.h"
38
#include "llvm/ADT/SmallVector.h"
39
#include "llvm/Analysis/LoopInfo.h"
40
#include "llvm/Analysis/ScalarEvolution.h"
41
#include "llvm/Analysis/Verifier.h"
42
#include "llvm/AutoUpgrade.h"
43
#include "llvm/CallingConv.h"
44
#include "llvm/DerivedTypes.h"
45
#include "llvm/Function.h"
46
#include "llvm/ExecutionEngine/ExecutionEngine.h"
47
#include "llvm/ExecutionEngine/JIT.h"
48
#include "llvm/ExecutionEngine/JITEventListener.h"
49
#include "llvm/LLVMContext.h"
50
#include "llvm/Intrinsics.h"
51
#include "llvm/Module.h"
52
#include "llvm/PassManager.h"
53
#include "llvm/Support/Compiler.h"
54
#include "llvm/Support/Debug.h"
55
#include "llvm/Support/CommandLine.h"
56
#include "llvm/Support/ErrorHandling.h"
57
#include "llvm/Support/ManagedStatic.h"
58
#include "llvm/Support/MemoryBuffer.h"
59
#include "llvm/Support/raw_ostream.h"
60
#include "llvm/Support/SourceMgr.h"
61
#include "llvm/Support/IRBuilder.h"
62
#include "llvm/Support/PrettyStackTrace.h"
65
#include "llvm/Support/DataTypes.h"
66
#include "llvm/Support/FileSystem.h"
67
#include "llvm/Support/Host.h"
68
#include "llvm/Support/Memory.h"
69
#include "llvm/Support/Mutex.h"
70
#include "llvm/Support/Signals.h"
71
#include "llvm/Support/Threading.h"
72
#include "llvm/Support/ThreadLocal.h"
73
#include "llvm/IntrinsicInst.h"
74
#include "llvm/PassRegistry.h"
76
#include "llvm/System/DataTypes.h"
77
#include "llvm/System/Host.h"
78
#include "llvm/System/Memory.h"
79
#include "llvm/System/Mutex.h"
80
#include "llvm/System/Signals.h"
81
#include "llvm/System/Threading.h"
82
#include "llvm/System/ThreadLocal.h"
85
#include "llvm/Support/Timer.h"
88
void LLVMInitializeX86AsmPrinter();
89
void LLVMInitializePowerPCAsmPrinter();
91
#include "llvm30_compat.h"
93
#include "llvm/Support/TargetSelect.h"
95
#include "llvm/Target/TargetSelect.h"
97
#include "llvm/Target/TargetData.h"
98
#include "llvm/Target/TargetOptions.h"
99
#include "llvm/Support/TargetFolder.h"
100
#include "llvm/Transforms/Scalar.h"
101
#include "llvm/Transforms/IPO.h"
102
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
112
#include "llvm/Config/config.h"
114
#error "Thread support was explicitly disabled. Cannot continue"
117
#ifdef _GLIBCXX_PARALLEL
118
#error "libstdc++ parallel mode is not supported for ClamAV. Please remove -D_GLIBCXX_PARALLEL from CXXFLAGS!"
122
#undef PACKAGE_BUGREPORT
124
#undef PACKAGE_STRING
125
#undef PACKAGE_TARNAME
126
#undef PACKAGE_VERSION
128
#include "clamav-config.h"
131
#include <openssl/ssl.h>
132
#include <openssl/err.h>
135
#include "libclamav/crypto.h"
141
#include "bytecode.h"
142
#include "bytecode_priv.h"
143
#include "type_desc.h"
145
#define MODULE "libclamav JIT: "
147
extern "C" unsigned int cli_rndnum(unsigned int max);
148
using namespace llvm;
149
typedef DenseMap<const struct cli_bc_func*, void*> FunctionMapTy;
150
struct cli_bcengine {
152
JITEventListener *Listener;
154
FunctionMapTy compiledFunctions;
157
void* align;/* just to align field to ptr */
161
extern "C" uint8_t cli_debug_flag;
164
void initializeRuntimeLimitsPass(PassRegistry&);
174
#define llvm_report_error(x) report_fatal_error(x)
175
#define llvm_install_error_handler(x) install_fatal_error_handler(x)
176
#define DwarfExceptionHandling JITExceptionHandling
177
#define SetCurrentDebugLocation(x) SetCurrentDebugLocation(DebugLoc::getFromDILocation(x))
178
#define DEFINEPASS(passname) passname() : FunctionPass(ID)
180
#define DEFINEPASS(passname) passname() : FunctionPass(&ID)
184
#define NORETURN LLVM_ATTRIBUTE_NORETURN
187
static sys::ThreadLocal<const jmp_buf> ExceptionReturn;
189
static void UpgradeCall(CallInst *&C, Function *Intr)
192
if (!UpgradeIntrinsicFunction(Intr, New) || New == Intr)
194
UpgradeIntrinsicCall(C, New);
199
void cli_errmsg(const char *str, ...) __attribute__((format(printf, 1, 2)));
201
void cli_errmsg(const char *str, ...);
205
void cli_warnmsg(const char *str, ...) __attribute__((format(printf, 1, 2)));
207
void cli_warnmsg(const char *str, ...);
211
void cli_dbgmsg_internal(const char *str, ...) __attribute__((format(printf, 1, 2)));
213
void cli_dbgmsg_internal(const char *str, ...);
217
class ScopedExceptionHandler {
219
jmp_buf &getEnv() { return env;}
221
/* set the exception handler's return location to here for the
223
ExceptionReturn.set((const jmp_buf*)&env);
225
~ScopedExceptionHandler() {
226
/* leaving scope, remove exception handler for current thread */
227
ExceptionReturn.erase();
232
#define HANDLER_TRY(handler) \
233
if (setjmp(handler.getEnv()) == 0) {\
236
#define HANDLER_END(handler) \
237
} else cli_warnmsg("[Bytecode JIT]: recovered from error\n");
241
ScopedExceptionHandler handler;
242
HANDLER_TRY(handler) {
243
// TODO: be on the safe side, and clear errors here,
244
// otherwise destructor calls report_fatal_error
245
((class raw_fd_ostream&)errs()).clear_error();
249
((class raw_fd_ostream&)errs()).clear_error();
251
HANDLER_END(handler);
252
remove_fatal_error_handler();
255
static void NORETURN jit_exception_handler(void)
257
jmp_buf* buf = const_cast<jmp_buf*>(ExceptionReturn.get());
259
// For errors raised during bytecode generation and execution.
262
// Oops, got no error recovery pointer set up,
263
// this is probably an error raised during shutdown.
264
cli_errmsg("[Bytecode JIT]: exception handler called, but no recovery point set up");
265
// should never happen, we remove the error handler when we don't use
266
// LLVM anymore, and when we use it, we do set an error recovery point.
267
llvm_unreachable("Bytecode JIT]: no exception handler recovery installed, but exception hit!");
271
static void NORETURN jit_ssp_handler(void)
273
cli_errmsg("[Bytecode JIT]: *** stack smashing detected, bytecode aborted\n");
274
jit_exception_handler();
277
void llvm_error_handler(void *user_data, const std::string &reason)
279
// Output it to stderr, it might exceed the 1k/4k limit of cli_errmsg
280
cli_errmsg("[Bytecode JIT]: [LLVM error] %s\n", reason.c_str());
281
jit_exception_handler();
284
// Since libgcc is not available on all compilers (for example on win32),
285
// just define what these functions should do, the compiler will forward to
286
// the appropriate libcall if needed.
287
static int64_t rtlib_sdiv_i64(int64_t a, int64_t b)
292
static uint64_t rtlib_udiv_i64(uint64_t a, uint64_t b)
297
static int64_t rtlib_srem_i64(int64_t a, int64_t b)
302
static uint64_t rtlib_urem_i64(uint64_t a, uint64_t b)
307
static int64_t rtlib_mul_i64(uint64_t a, uint64_t b)
312
static int64_t rtlib_shl_i64(int64_t a, int32_t b)
317
static int64_t rtlib_srl_i64(int64_t a, int32_t b)
319
return (uint64_t)a >> b;
321
/* Implementation independent sign-extended signed right shift */
323
#define CLI_SRS(n,s) ((n)>>(s))
325
#define CLI_SRS(n,s) ((((n)>>(s)) ^ (1<<(sizeof(n)*8-1-s))) - (1<<(sizeof(n)*8-1-s)))
327
static int64_t rtlib_sra_i64(int64_t a, int32_t b)
329
return CLI_SRS(a, b);//CLI_./..
332
static void rtlib_bzero(void *s, size_t n)
339
extern "C" void __chkstk(void);
341
extern "C" void _chkstk(void);
344
// Resolve integer libcalls, but nothing else.
345
static void* noUnknownFunctions(const std::string& name) {
347
StringSwitch<void*>(name)
348
.Case("__divdi3", (void*)(intptr_t)rtlib_sdiv_i64)
349
.Case("__udivdi3", (void*)(intptr_t)rtlib_udiv_i64)
350
.Case("__moddi3", (void*)(intptr_t)rtlib_srem_i64)
351
.Case("__umoddi3", (void*)(intptr_t)rtlib_urem_i64)
352
.Case("__muldi3", (void*)(intptr_t)rtlib_mul_i64)
353
.Case("__ashrdi3", (void*)(intptr_t)rtlib_sra_i64)
354
.Case("__ashldi3", (void*)(intptr_t)rtlib_shl_i64)
355
.Case("__lshrdi3", (void*)(intptr_t)rtlib_srl_i64)
356
.Case("__bzero", (void*)(intptr_t)rtlib_bzero)
357
.Case("memmove", (void*)(intptr_t)memmove)
358
.Case("memcpy", (void*)(intptr_t)memcpy)
359
.Case("memset", (void*)(intptr_t)memset)
360
.Case("abort", (void*)(intptr_t)jit_exception_handler)
363
.Case("_chkstk", (void*)(intptr_t)__chkstk)
365
.Case("_chkstk", (void*)(intptr_t)_chkstk)
372
std::string reason((Twine("Attempt to call external function ")+name).str());
373
llvm_error_handler(0, reason);
377
class NotifyListener : public JITEventListener {
379
virtual void NotifyFunctionEmitted(const Function &F,
380
void *Code, size_t Size,
381
const EmittedFunctionDetails &Details)
385
cli_dbgmsg_internal("[Bytecode JIT]: emitted function %s of %ld bytes at %p\n",
386
F.getNameStr().c_str(), (long)Size, Code);
394
TimerWrapper(const std::string &name) {
417
class LLVMTypeMapper {
420
std::vector<Type*> TypeMap;
422
std::vector<PATypeHolder> TypeMap;
424
LLVMContext &Context;
426
constType *getStatic(uint16_t ty)
429
return Type::getVoidTy(Context);
431
return IntegerType::get(Context, ty);
434
return PointerType::getUnqual(Type::getInt8Ty(Context));
436
return PointerType::getUnqual(Type::getInt16Ty(Context));
438
return PointerType::getUnqual(Type::getInt32Ty(Context));
440
return PointerType::getUnqual(Type::getInt64Ty(Context));
442
llvm_unreachable("getStatic");
445
TimerWrapper pmTimer;
446
TimerWrapper irgenTimer;
448
LLVMTypeMapper(LLVMContext &Context, const struct cli_bc_type *types,
449
unsigned count, constType *Hidden=0) : Context(Context), numTypes(count),
450
pmTimer("Function passes"),irgenTimer("IR generation")
452
TypeMap.reserve(count);
453
// During recursive type construction pointers to Type* may be
454
// invalidated, so we must use a TypeHolder to an Opaque type as a
456
for (unsigned i=0;i<count;i++) {
458
TypeMap.push_back(0);
460
TypeMap.push_back(OpaqueType::get(Context));
463
for (unsigned i=0;i<count;i++) {
464
const struct cli_bc_type *type = &types[i];
466
constType *Ty = buildType(type, types, Hidden, 0);
470
// Make the opaque type a concrete type, doing recursive type
471
// unification if needed.
472
cast<OpaqueType>(TypeMap[i].get())->refineAbstractTypeTo(Ty);
477
constType *buildType(const struct cli_bc_type *type, const struct cli_bc_type *types, constType *Hidden,
480
std::vector<constType*> Elts;
481
unsigned n = type->kind == DArrayType ? 1 : type->numElements;
482
for (unsigned j=0;j<n;j++) {
483
Elts.push_back(get(type->containedTypes[j], types, Hidden));
486
switch (type->kind) {
489
assert(Elts.size() > 0 && "Function with no return type?");
490
constType *RetTy = Elts[0];
494
Elts.erase(Elts.begin());
495
Ty = FunctionType::get(RetTy, Elts, false);
499
if (!PointerType::isValidElementType(Elts[0]))
500
Ty = PointerType::getUnqual(Type::getInt8Ty(Context));
502
Ty = PointerType::getUnqual(Elts[0]);
505
case DPackedStructType:
506
Ty = StructType::get(Context, Elts, type->kind == DPackedStructType);
509
Ty = ArrayType::get(Elts[0], type->numElements);
512
llvm_unreachable("type->kind");
517
constType *get(uint16_t ty, const struct cli_bc_type *types, constType *Hidden)
521
return getStatic(ty);
523
assert(ty < numTypes && "TypeID out of range");
525
Type *Ty = TypeMap[ty];
528
assert(types && Hidden || "accessing not-yet-built type");
529
Ty = buildType(&types[ty], types, Hidden, 1);
533
return TypeMap[ty].get();
538
struct CommonFunctions {
543
Function *FRealmemset;
544
Function *FRealMemmove;
545
Function *FRealmemcmp;
546
Function *FRealmemcpy;
552
// loops with tripcounts higher than this need timeout check
553
static const unsigned LoopThreshold = 1000;
555
// after every N API calls we need timeout check
556
static const unsigned ApiThreshold = 100;
558
class RuntimeLimits : public FunctionPass {
559
typedef SmallVector<std::pair<const BasicBlock*, const BasicBlock*>, 16>
561
typedef SmallSet<BasicBlock*, 16> BBSetTy;
562
typedef DenseMap<const BasicBlock*, unsigned> BBMapTy;
563
bool loopNeedsTimeoutCheck(ScalarEvolution &SE, const Loop *L, BBMapTy &Map) {
564
// This BB is a loop header, if trip count is small enough
565
// no timeout checks are needed here.
566
const SCEV *S = SE.getMaxBackedgeTakenCount(L);
567
if (isa<SCEVCouldNotCompute>(S))
569
DEBUG(errs() << "Found loop trip count" << *S << "\n");
570
ConstantRange CR = SE.getUnsignedRange(S);
571
uint64_t max = CR.getUnsignedMax().getLimitedValue();
572
DEBUG(errs() << "Found max trip count " << max << "\n");
573
if (max > LoopThreshold)
575
unsigned apicalls = 0;
576
for (Loop::block_iterator J=L->block_begin(),JE=L->block_end();
581
if (apicalls > ApiThreshold) {
582
DEBUG(errs() << "apicall threshold exceeded: " << apicalls << "\n");
585
Map[L->getHeader()] = apicalls;
591
DEFINEPASS(RuntimeLimits) {
593
PassRegistry &Registry = *PassRegistry::getPassRegistry();
594
initializeRuntimeLimitsPass(Registry);
598
virtual bool runOnFunction(Function &F) {
599
BBSetTy BackedgeTargets;
600
if (!F.isDeclaration()) {
601
// Get the common backedge targets.
602
// Note that we don't rely on LoopInfo here, since
603
// it is possible to construct a CFG that doesn't have natural loops,
604
// yet it does have backedges, and thus can lead to unbounded/high
607
FindFunctionBackedges(F, V);
608
for (BBPairVectorTy::iterator I=V.begin(),E=V.end();I != E; ++I) {
609
BackedgeTargets.insert(const_cast<BasicBlock*>(I->second));
612
BBSetTy needsTimeoutCheck;
614
DominatorTree &DT = getAnalysis<DominatorTree>();
615
for (Function::iterator I=F.begin(),E=F.end(); I != E; ++I) {
616
BasicBlock *BB = &*I;
617
unsigned apicalls = 0;
618
for (BasicBlock::const_iterator J=BB->begin(),JE=BB->end();
620
if (const CallInst *CI = dyn_cast<CallInst>(J)) {
621
Function *F = CI->getCalledFunction();
622
if (!F || F->isDeclaration())
626
if (apicalls > ApiThreshold) {
627
DEBUG(errs() << "apicall threshold exceeded: " << apicalls << "\n");
628
needsTimeoutCheck.insert(BB);
631
BBMap[BB] = apicalls;
633
if (!BackedgeTargets.empty()) {
634
LoopInfo &LI = getAnalysis<LoopInfo>();
635
ScalarEvolution &SE = getAnalysis<ScalarEvolution>();
637
// Now check whether any of these backedge targets are part of a loop
638
// with a small constant trip count
639
for (BBSetTy::iterator I=BackedgeTargets.begin(),E=BackedgeTargets.end();
641
const Loop *L = LI.getLoopFor(*I);
642
if (L && L->getHeader() == *I &&
643
!loopNeedsTimeoutCheck(SE, L, BBMap))
645
needsTimeoutCheck.insert(*I);
649
// Estimate number of apicalls by walking dominator-tree bottom-up.
650
// BBs that have timeout checks are considered to have 0 APIcalls
651
// (since we already checked for timeout).
652
for (po_iterator<DomTreeNode*> I = po_begin(DT.getRootNode()),
653
E = po_end(DT.getRootNode()); I != E; ++I) {
654
if (needsTimeoutCheck.count(I->getBlock()))
656
unsigned apicalls = BBMap[I->getBlock()];
657
for (DomTreeNode::iterator J=I->begin(),JE=I->end();
659
apicalls += BBMap[(*J)->getBlock()];
661
if (apicalls > ApiThreshold) {
662
needsTimeoutCheck.insert(I->getBlock());
665
BBMap[I->getBlock()] = apicalls;
667
if (needsTimeoutCheck.empty())
669
DEBUG(errs() << "needs timeoutcheck:\n");
670
std::vector<constType*>args;
671
FunctionType* abrtTy = FunctionType::get(
672
Type::getVoidTy(F.getContext()),args,false);
673
Constant *func_abort =
674
F.getParent()->getOrInsertFunction("abort", abrtTy);
675
BasicBlock *AbrtBB = BasicBlock::Create(F.getContext(), "", &F);
676
CallInst* AbrtC = CallInst::Create(func_abort, "", AbrtBB);
677
AbrtC->setCallingConv(CallingConv::C);
678
AbrtC->setTailCall(true);
679
AbrtC->setDoesNotReturn(true);
680
AbrtC->setDoesNotThrow(true);
681
new UnreachableInst(F.getContext(), AbrtBB);
682
IRBuilder<false> Builder(F.getContext());
684
Value *Flag = F.arg_begin();
686
Function *LSBarrier = Intrinsic::getDeclaration(F.getParent(),
687
Intrinsic::memory_barrier);
689
ConstantInt::getFalse(F.getContext()),
690
ConstantInt::getFalse(F.getContext()),
691
ConstantInt::getTrue(F.getContext()),
692
ConstantInt::getFalse(F.getContext()),
693
ConstantInt::getFalse(F.getContext())
697
BasicBlock *BB = &F.getEntryBlock();
698
Builder.SetInsertPoint(BB, BB->getTerminator());
699
Flag = Builder.CreatePointerCast(Flag, PointerType::getUnqual(
700
Type::getInt1Ty(F.getContext())));
701
for (BBSetTy::iterator I=needsTimeoutCheck.begin(),
702
E=needsTimeoutCheck.end(); I != E; ++I) {
704
Builder.SetInsertPoint(BB, BB->getTerminator());
706
Builder.CreateFence(Release);
708
// store-load barrier: will be a no-op on x86 but not other arches
709
Builder.CreateCall(LSBarrier, ARRAYREF(Value*, MBArgs, MBArgs+5));
711
// Load Flag that tells us we timed out (first byte in bc_ctx)
712
Value *Cond = Builder.CreateLoad(Flag, true);
713
BasicBlock *newBB = SplitBlock(BB, BB->getTerminator(), this);
714
TerminatorInst *TI = BB->getTerminator();
715
BranchInst::Create(AbrtBB, newBB, Cond, TI);
716
TI->eraseFromParent();
717
// Update dominator info
718
DomTreeNode *N = DT.getNode(AbrtBB);
720
DT.addNewBlock(AbrtBB, BB);
722
BasicBlock *DomBB = DT.findNearestCommonDominator(BB,
723
N->getIDom()->getBlock());
724
DT.changeImmediateDominator(AbrtBB, DomBB);
726
DEBUG(errs() << *I << "\n");
732
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
733
AU.setPreservesAll();
734
AU.addRequired<LoopInfo>();
735
AU.addRequired<ScalarEvolution>();
736
AU.addRequired<DominatorTree>();
739
char RuntimeLimits::ID;
741
// select i1 false ... which instcombine would simplify but we don't run
743
class BrSimplifier : public FunctionPass {
746
DEFINEPASS(BrSimplifier) {}
748
virtual bool runOnFunction(Function &F) {
749
bool Changed = false;
750
for (Function::iterator I=F.begin(),E=F.end(); I != E; ++I) {
751
if (BranchInst *BI = dyn_cast<BranchInst>(I->getTerminator())) {
752
if (BI->isUnconditional())
754
Value *V = BI->getCondition();
755
if (ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
758
BranchInst::Create(BI->getSuccessor(0), &*I);
759
Other = BI->getSuccessor(1);
761
BranchInst::Create(BI->getSuccessor(1), &*I);
762
Other = BI->getSuccessor(0);
764
Other->removePredecessor(&*I);
765
BI->eraseFromParent();
769
for (BasicBlock::iterator J=I->begin(),JE=I->end();
771
SelectInst *SI = dyn_cast<SelectInst>(J);
775
ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition());
779
SI->replaceAllUsesWith(SI->getTrueValue());
781
SI->replaceAllUsesWith(SI->getFalseValue());
782
SI->eraseFromParent();
790
char BrSimplifier::ID;
792
class SimpleGlobalDCE : public ModulePass {
796
SimpleGlobalDCE(ExecutionEngine *EE) : ModulePass(&ID), EE(EE) {}
798
virtual bool runOnModule(Module &M) {
799
bool Changed = false;
800
std::vector<GlobalValue*> toErase;
801
for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) {
802
GlobalValue *GV = &*I;
803
if (GV->use_empty() && !EE->getPointerToGlobalIfAvailable(GV))
804
toErase.push_back(GV);
806
for (std::vector<GlobalValue*>::iterator I=toErase.begin(), E=toErase.end();
808
(*I)->eraseFromParent();
815
char SimpleGlobalDCE::ID;
819
const struct cli_bc *bc;
821
LLVMContext &Context;
823
FunctionPassManager &PM, &PMUnsigned;
824
LLVMTypeMapper *TypeMap;
827
LLVMTypeMapper &apiMap;
828
FunctionMapTy &compiledFunctions;
832
IRBuilder<false, TargetFolder> Builder;
834
std::vector<Value*> globals;
835
DenseMap<unsigned, unsigned> GVoffsetMap;
836
DenseMap<unsigned, constType*> GVtypeMap;
840
std::vector<MDNode*> mdnodes;
842
struct CommonFunctions *CF;
844
Value *getOperand(const struct cli_bc_func *func, constType *Ty, operand_t operand)
846
unsigned map[] = {0, 1, 2, 3, 3, 4, 4, 4, 4};
847
if (operand < func->numValues)
848
return Values[operand];
849
unsigned w = Ty->getPrimitiveSizeInBits();
854
return convertOperand(func, map[w], operand);
857
Value *convertOperand(const struct cli_bc_func *func, constType *Ty, operand_t operand)
859
unsigned map[] = {0, 1, 2, 3, 3, 4, 4, 4, 4};
860
if (operand < func->numArgs)
861
return Values[operand];
862
if (operand < func->numValues) {
863
Value *V = Values[operand];
864
if (func->types[operand]&0x8000 && V->getType() == Ty) {
867
V = Builder.CreateLoad(V);
868
if (V->getType() != Ty &&
869
isa<PointerType>(V->getType()) &&
870
isa<PointerType>(Ty))
871
V = Builder.CreateBitCast(V, Ty);
872
if (V->getType() != Ty) {
873
if (cli_debug_flag) {
875
raw_string_ostream ostr(str);
876
ostr << operand << " " ;
880
cli_dbgmsg_internal("[Bytecode JIT]: operand %d: %s\n", operand,ostr.str().c_str());
882
llvm_report_error("(libclamav) Type mismatch converting operand");
886
unsigned w = Ty->getPrimitiveSizeInBits();
891
return convertOperand(func, map[w], operand);
894
Value *convertOperand(const struct cli_bc_func *func,
895
const struct cli_bc_inst *inst, operand_t operand)
897
return convertOperand(func, inst->interp_op%5, operand);
900
Value *convertOperand(const struct cli_bc_func *func,
901
unsigned w, operand_t operand) {
902
if (operand < func->numArgs)
903
return Values[operand];
904
if (operand < func->numValues) {
905
if (func->types[operand]&0x8000)
906
return Values[operand];
907
return Builder.CreateLoad(Values[operand]);
910
if (operand & 0x80000000) {
911
operand &= 0x7fffffff;
912
assert(operand < globals.size() && "Global index out of range");
915
return ConstantPointerNull::get(PointerType::getUnqual(Type::getInt8Ty(Context)));
916
assert(globals[operand]);
917
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(globals[operand])) {
918
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(GV->getInitializer())) {
923
return globals[operand];
926
operand -= func->numValues;
927
// This was already validated by libclamav.
928
assert(operand < func->numConstants && "Constant out of range");
929
uint64_t *c = &func->constants[operand];
935
Ty = w ? Type::getInt8Ty(Context) :
936
Type::getInt1Ty(Context);
940
Ty = Type::getInt16Ty(Context);
944
Ty = Type::getInt32Ty(Context);
948
Ty = Type::getInt64Ty(Context);
952
llvm_unreachable("width");
954
return ConstantInt::get(Ty, v);
957
void Store(uint16_t dest, Value *V)
959
assert(dest >= numArgs && dest < numLocals+numArgs && "Instruction destination out of range");
960
Builder.CreateStore(V, Values[dest]);
963
// Insert code that calls \arg CF->FHandler if \arg FailCond is true.
964
void InsertVerify(Value *FailCond, BasicBlock *&Fail, Function *FHandler,
967
Fail = BasicBlock::Create(Context, "fail", F);
968
CallInst::Create(FHandler,"",Fail);
969
new UnreachableInst(Context, Fail);
971
BasicBlock *OkBB = BasicBlock::Create(Context, "", F);
972
Builder.CreateCondBr(FailCond, Fail, OkBB);
973
Builder.SetInsertPoint(OkBB);
976
constType* mapType(uint16_t typeID)
978
return TypeMap->get(typeID&0x7fffffff, NULL, NULL);
981
Constant *buildConstant(constType *Ty, uint64_t *components, unsigned &c)
983
if (constPointerType *PTy = dyn_cast<PointerType>(Ty)) {
985
ConstantInt::get(Type::getInt64Ty(Context), components[c++])
987
unsigned idx = components[c++];
989
return ConstantPointerNull::get(PTy);
990
assert(idx < globals.size());
991
GlobalVariable *GV = cast<GlobalVariable>(globals[idx]);
992
Type *IP8Ty = PointerType::getUnqual(Type::getInt8Ty(Ty->getContext()));
993
Constant *C = ConstantExpr::getPointerCast(GV, IP8Ty);
994
//TODO: check constant bounds here
995
return ConstantExpr::getPointerCast(
996
ConstantExpr::getInBoundsGetElementPtr(C, ARRAYREF(Value*, idxs, 1)),
999
if (isa<IntegerType>(Ty)) {
1000
return ConstantInt::get(Ty, components[c++]);
1002
if (constArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
1003
std::vector<Constant*> elements;
1004
elements.reserve(ATy->getNumElements());
1005
for (unsigned i=0;i<ATy->getNumElements();i++) {
1006
elements.push_back(buildConstant(ATy->getElementType(), components, c));
1008
return ConstantArray::get(ATy, elements);
1010
if (constStructType *STy = dyn_cast<StructType>(Ty)) {
1011
std::vector<Constant*> elements;
1012
elements.reserve(STy->getNumElements());
1013
for (unsigned i=0;i<STy->getNumElements();i++) {
1014
elements.push_back(buildConstant(STy->getElementType(i), components, c));
1016
return ConstantStruct::get(STy, elements);
1019
llvm_unreachable("invalid type");
1024
LLVMCodegen(const struct cli_bc *bc, Module *M, struct CommonFunctions *CF, FunctionMapTy &cFuncs,
1025
ExecutionEngine *EE, FunctionPassManager &PM, FunctionPassManager &PMUnsigned,
1026
Function **apiFuncs, LLVMTypeMapper &apiMap)
1027
: bc(bc), M(M), Context(M->getContext()), EE(EE),
1028
PM(PM),PMUnsigned(PMUnsigned), TypeMap(), apiFuncs(apiFuncs),apiMap(apiMap),
1029
compiledFunctions(cFuncs), BytecodeID("bc"+Twine(bc->id)),
1030
Folder(EE->getTargetData()), Builder(Context, Folder), Values(), CF(CF) {
1032
for (unsigned i=0;i<cli_apicall_maxglobal - _FIRST_GLOBAL;i++) {
1033
unsigned id = cli_globals[i].globalid;
1034
GVoffsetMap[id] = cli_globals[i].offset;
1041
template <typename InputIterator>
1043
Value* createGEP(Value *Base, constType *ETy, ARRAYREFPARAM(Value*,InputIterator Start,InputIterator End,ARef)) {
1044
constType *Ty = GetElementPtrInst::getIndexedType(Base->getType(),ARRAYREFP(Start,End,ARef));
1045
if (!Ty || (ETy && (Ty != ETy && (!isa<IntegerType>(Ty) || !isa<IntegerType>(ETy))))) {
1046
if (cli_debug_flag) {
1048
raw_string_ostream ostr(str);
1050
ostr << "Wrong indices for GEP opcode: "
1051
<< " expected type: " << *ETy;
1053
ostr << " actual type: " << *Ty;
1054
ostr << " base: " << *Base << ";";
1055
Base->getType()->print(ostr);
1056
ostr << "\n indices: ";
1058
for (ArrayRef<Value*>::iterator I=ARef.begin(); I != ARef.end(); I++) {
1060
for (InputIterator I=Start; I != End; I++) {
1062
ostr << **I << ", ";
1065
cli_dbgmsg_internal("[Bytecode JIT]: %s\n", ostr.str().c_str());
1067
cli_warnmsg("[Bytecode JIT]: Wrong indices for GEP opcode\n");
1071
return Builder.CreateGEP(Base,ARRAYREFP(Start,End,ARef));
1075
template <typename InputIterator>
1077
bool createGEP(unsigned dest, Value *Base, ARRAYREFPARAM(Value*,InputIterator Start,InputIterator End,ARef)) {
1078
assert(dest >= numArgs && dest < numLocals+numArgs && "Instruction destination out of range");
1079
constType *ETy = cast<PointerType>(cast<PointerType>(Values[dest]->getType())->getElementType())->getElementType();
1080
Value *V = createGEP(Base, ETy, ARRAYREFP(Start,End,ARef));
1083
cli_dbgmsg_internal("[Bytecode JIT] @%d\n", dest);
1086
V = Builder.CreateBitCast(V, PointerType::getUnqual(ETy));
1091
MDNode *convertMDNode(unsigned i) {
1092
if (i < mdnodes.size()) {
1096
mdnodes.resize(i+1);
1097
assert(i < mdnodes.size());
1098
const struct cli_bc_dbgnode *node = &bc->dbgnodes[i];
1099
Value **Vals = new Value*[node->numelements];
1100
for (unsigned j=0;j<node->numelements;j++) {
1101
const struct cli_bc_dbgnode_element* el = &node->elements[j];
1104
if (el->nodeid == ~0u)
1106
else if (el->nodeid)
1107
V = convertMDNode(el->nodeid);
1109
V = MDString::get(Context, "");
1110
} else if (el->string) {
1111
V = MDString::get(Context, StringRef(el->string, el->len));
1113
V = ConstantInt::get(IntegerType::get(Context, el->len),
1118
MDNode *N = MDNode::get(Context, ARRAYREF(Value*,Vals, node->numelements));
1124
void AddStackProtect(Function *F)
1126
BasicBlock &BB = F->getEntryBlock();
1127
if (isa<AllocaInst>(BB.begin())) {
1128
// Have an alloca -> some instruction uses its address otherwise
1129
// mem2reg would have converted it to an SSA register.
1130
// Enable stack protector for this function.
1132
// LLVM 2.9 has broken SSP, it does a 'mov 0x28, $rax', which tries
1133
// to read from the address 0x28 and crashes
1134
F->addFnAttr(Attribute::StackProtectReq);
1137
// always add stackprotect attribute (bb #2239), so we know this
1138
// function was verified. If there is no alloca it won't actually add
1139
// stack protector in emitted code so this won't slow down the app.
1141
F->addFnAttr(Attribute::StackProtect);
1145
Value *GEPOperand(Value *V) {
1146
if (LoadInst *LI = dyn_cast<LoadInst>(V)) {
1147
Value *VI = LI->getOperand(0);
1149
for (Value::use_iterator I=VI->use_begin(),
1150
E=VI->use_end(); I != E; ++I) {
1152
if (StoreInst *S = dyn_cast<StoreInst>(I_V)) {
1156
} else if (!isa<LoadInst>(I_V))
1159
V = SI->getOperand(0);
1161
if (EE->getTargetData()->getPointerSize() == 8) {
1162
// eliminate useless trunc, GEP can take i64 too
1163
if (TruncInst *I = dyn_cast<TruncInst>(V)) {
1164
Value *Src = I->getOperand(0);
1165
if (Src->getType() == Type::getInt64Ty(Context) &&
1166
I->getType() == Type::getInt32Ty(Context))
1173
Function* generate() {
1174
PrettyStackTraceString CrashInfo("Generate LLVM IR functions");
1175
apiMap.irgenTimer.startTimer();
1176
TypeMap = new LLVMTypeMapper(Context, bc->types + 4, bc->num_types - 5);
1177
for (unsigned i=0;i<bc->dbgnode_cnt;i++) {
1178
mdnodes.push_back(convertMDNode(i));
1181
for (unsigned i=0;i<cli_apicall_maxglobal - _FIRST_GLOBAL;i++) {
1182
unsigned id = cli_globals[i].globalid;
1183
constType *Ty = apiMap.get(cli_globals[i].type, NULL, NULL);
1184
/*if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty))
1185
Ty = PointerType::getUnqual(ATy->getElementType());*/
1189
// The hidden ctx param to all functions
1190
unsigned maxh = cli_globals[0].offset + sizeof(struct cli_bc_hooks);
1191
constType *HiddenCtx = PointerType::getUnqual(ArrayType::get(Type::getInt8Ty(Context), maxh));
1193
globals.reserve(bc->num_globals);
1195
FakeGVs.resize(bc->num_globals);
1196
globals.push_back(0);
1197
for (unsigned i=1;i<bc->num_globals;i++) {
1198
constType *Ty = mapType(bc->globaltys[i]);
1200
// TODO: validate number of components against type_components
1203
if (isa<PointerType>(Ty)) {
1204
unsigned g = bc->globals[i][1];
1205
if (GVoffsetMap.count(g)) {
1207
globals.push_back(0);
1211
Constant *C = buildConstant(Ty, bc->globals[i], c);
1212
GV = new GlobalVariable(*M, Ty, true,
1213
GlobalValue::InternalLinkage,
1214
C, "glob"+Twine(i));
1215
globals.push_back(GV);
1217
Function **Functions = new Function*[bc->num_func];
1218
for (unsigned j=0;j<bc->num_func;j++) {
1219
// Create LLVM IR Function
1220
const struct cli_bc_func *func = &bc->funcs[j];
1221
std::vector<constType*> argTypes;
1222
argTypes.push_back(HiddenCtx);
1223
for (unsigned a=0;a<func->numArgs;a++) {
1224
argTypes.push_back(mapType(func->types[a]));
1226
constType *RetTy = mapType(func->returnType);
1227
FunctionType *FTy = FunctionType::get(RetTy, argTypes,
1229
Functions[j] = Function::Create(FTy, Function::InternalLinkage,
1230
BytecodeID+"f"+Twine(j), M);
1231
Functions[j]->setDoesNotThrow();
1232
Functions[j]->setCallingConv(CallingConv::Fast);
1233
Functions[j]->setLinkage(GlobalValue::InternalLinkage);
1235
/* bb #2270, this should really be fixed either by LLVM or GCC.*/
1236
Functions[j]->addFnAttr(Attribute::constructStackAlignmentFromInt(16));
1239
constType *I32Ty = Type::getInt32Ty(Context);
1240
for (unsigned j=0;j<bc->num_func;j++) {
1241
PrettyStackTraceString CrashInfo("Generate LLVM IR");
1242
const struct cli_bc_func *func = &bc->funcs[j];
1243
bool broken = false;
1245
// Create all BasicBlocks
1246
Function *F = Functions[j];
1247
BasicBlock **BB = new BasicBlock*[func->numBB];
1248
for (unsigned i=0;i<func->numBB;i++) {
1249
BB[i] = BasicBlock::Create(Context, "", F);
1252
BasicBlock *Fail = 0;
1253
Values = new Value*[func->numValues];
1254
Builder.SetInsertPoint(BB[0]);
1255
Function::arg_iterator I = F->arg_begin();
1256
assert(F->arg_size() == (unsigned)(func->numArgs + 1) && "Mismatched args");
1258
for (unsigned i=0;i<func->numArgs; i++) {
1259
assert(I != F->arg_end());
1263
for (unsigned i=func->numArgs;i<func->numValues;i++) {
1264
if (!func->types[i]) {
1265
//instructions without return value, like store
1269
Values[i] = Builder.CreateAlloca(mapType(func->types[i]));
1271
numLocals = func->numLocals;
1272
numArgs = func->numArgs;
1274
if (FakeGVs.any()) {
1275
Argument *Ctx = F->arg_begin();
1276
for (unsigned i=0;i<bc->num_globals;i++) {
1279
unsigned g = bc->globals[i][1];
1280
unsigned offset = GVoffsetMap[g];
1282
Constant *Idx = ConstantInt::get(Type::getInt32Ty(Context),
1285
ConstantInt::get(Type::getInt32Ty(Context), 0),
1288
Value *GEP = Builder.CreateInBoundsGEP(Ctx, ARRAYREF(Value*, Idxs, Idxs+2));
1289
constType *Ty = GVtypeMap[g];
1290
Ty = PointerType::getUnqual(PointerType::getUnqual(Ty));
1291
Value *Cast = Builder.CreateBitCast(GEP, Ty);
1292
Value *SpecialGV = Builder.CreateLoad(Cast);
1293
constType *IP8Ty = Type::getInt8Ty(Context);
1294
IP8Ty = PointerType::getUnqual(IP8Ty);
1295
SpecialGV = Builder.CreateBitCast(SpecialGV, IP8Ty);
1296
SpecialGV->setName("g"+Twine(g-_FIRST_GLOBAL)+"_");
1298
ConstantInt::get(Type::getInt32Ty(Context), bc->globals[i][0])
1300
globals[i] = createGEP(SpecialGV, 0, ARRAYREF(Value*,C, C+1));
1302
if (cli_debug_flag) {
1304
raw_string_ostream ostr(str);
1305
ostr << i << ":" << g << ":" << bc->globals[i][0] <<"\n";
1307
cli_dbgmsg_internal("[Bytecode JIT]: %s\n", ostr.str().c_str());
1309
llvm_report_error("(libclamav) unable to create fake global");
1311
globals[i] = Builder.CreateBitCast(globals[i], Ty);
1312
if(GetElementPtrInst *GI = dyn_cast<GetElementPtrInst>(globals[i])) {
1313
GI->setIsInBounds(true);
1314
GI->setName("geped"+Twine(i)+"_");
1319
// Generate LLVM IR for each BB
1320
for (unsigned i=0;i<func->numBB && !broken;i++) {
1321
bool unreachable = false;
1322
const struct cli_bc_bb *bb = &func->BB[i];
1323
Builder.SetInsertPoint(BB[i]);
1325
for (unsigned j=0;j<bb->numInsts && !broken;j++) {
1326
const struct cli_bc_inst *inst = &bb->insts[j];
1327
Value *Op0=0, *Op1=0, *Op2=0;
1328
// libclamav has already validated this.
1329
assert(inst->opcode < OP_BC_INVALID && "Invalid opcode");
1330
if (func->dbgnodes) {
1331
if (func->dbgnodes[c] != ~0u) {
1332
unsigned j = func->dbgnodes[c];
1333
assert(j < mdnodes.size());
1334
Builder.SetCurrentDebugLocation(mdnodes[j]);
1336
Builder.SetCurrentDebugLocation(0);
1339
switch (inst->opcode) {
1342
case OP_BC_CALL_API:
1343
case OP_BC_CALL_DIRECT:
1353
case OP_BC_PTRDIFF32:
1354
case OP_BC_PTRTOINT64:
1355
// these instructions represents operands differently
1358
switch (operand_counts[inst->opcode]) {
1360
Op0 = convertOperand(func, inst, inst->u.unaryop);
1363
Op0 = convertOperand(func, inst, inst->u.binop[0]);
1364
Op1 = convertOperand(func, inst, inst->u.binop[1]);
1365
if (Op0->getType() != Op1->getType()) {
1368
llvm_report_error("(libclamav) binop type mismatch");
1372
Op0 = convertOperand(func, inst, inst->u.three[0]);
1373
Op1 = convertOperand(func, inst, inst->u.three[1]);
1374
Op2 = convertOperand(func, inst, inst->u.three[2]);
1379
switch (inst->opcode) {
1381
Store(inst->dest, Builder.CreateAdd(Op0, Op1));
1384
Store(inst->dest, Builder.CreateSub(Op0, Op1));
1387
Store(inst->dest, Builder.CreateMul(Op0, Op1));
1391
Value *Bad = Builder.CreateICmpEQ(Op1, ConstantInt::get(Op1->getType(), 0));
1392
InsertVerify(Bad, Fail, CF->FHandler, F);
1393
Store(inst->dest, Builder.CreateUDiv(Op0, Op1));
1398
//TODO: also verify Op0 == -1 && Op1 = INT_MIN
1399
Value *Bad = Builder.CreateICmpEQ(Op1, ConstantInt::get(Op1->getType(), 0));
1400
InsertVerify(Bad, Fail, CF->FHandler, F);
1401
Store(inst->dest, Builder.CreateSDiv(Op0, Op1));
1406
Value *Bad = Builder.CreateICmpEQ(Op1, ConstantInt::get(Op1->getType(), 0));
1407
InsertVerify(Bad, Fail, CF->FHandler, F);
1408
Store(inst->dest, Builder.CreateURem(Op0, Op1));
1413
//TODO: also verify Op0 == -1 && Op1 = INT_MIN
1414
Value *Bad = Builder.CreateICmpEQ(Op1, ConstantInt::get(Op1->getType(), 0));
1415
InsertVerify(Bad, Fail, CF->FHandler, F);
1416
Store(inst->dest, Builder.CreateSRem(Op0, Op1));
1420
Store(inst->dest, Builder.CreateShl(Op0, Op1));
1423
Store(inst->dest, Builder.CreateLShr(Op0, Op1));
1426
Store(inst->dest, Builder.CreateAShr(Op0, Op1));
1429
Store(inst->dest, Builder.CreateAnd(Op0, Op1));
1432
Store(inst->dest, Builder.CreateOr(Op0, Op1));
1435
Store(inst->dest, Builder.CreateXor(Op0, Op1));
1439
Value *Src = convertOperand(func, inst, inst->u.cast.source);
1440
constType *Ty = mapType(func->types[inst->dest]);
1441
Store(inst->dest, Builder.CreateTrunc(Src, Ty));
1446
Value *Src = convertOperand(func, inst, inst->u.cast.source);
1447
constType *Ty = mapType(func->types[inst->dest]);
1448
Store(inst->dest, Builder.CreateZExt(Src, Ty));
1453
Value *Src = convertOperand(func, inst, inst->u.cast.source);
1454
constType *Ty = mapType(func->types[inst->dest]);
1455
Store(inst->dest, Builder.CreateSExt(Src, Ty));
1460
Value *Cond = convertOperand(func, inst, inst->u.branch.condition);
1461
BasicBlock *True = BB[inst->u.branch.br_true];
1462
BasicBlock *False = BB[inst->u.branch.br_false];
1463
if (Cond->getType() != Type::getInt1Ty(Context)) {
1464
cli_warnmsg("[Bytecode JIT]: type mismatch in condition");
1468
Builder.CreateCondBr(Cond, True, False);
1473
BasicBlock *Jmp = BB[inst->u.jump];
1474
Builder.CreateBr(Jmp);
1479
Op0 = convertOperand(func, F->getReturnType(), inst->u.unaryop);
1480
Builder.CreateRet(Op0);
1483
case OP_BC_RET_VOID:
1484
Builder.CreateRetVoid();
1487
Store(inst->dest, Builder.CreateICmpEQ(Op0, Op1));
1490
Store(inst->dest, Builder.CreateICmpNE(Op0, Op1));
1492
case OP_BC_ICMP_UGT:
1493
Store(inst->dest, Builder.CreateICmpUGT(Op0, Op1));
1495
case OP_BC_ICMP_UGE:
1496
Store(inst->dest, Builder.CreateICmpUGE(Op0, Op1));
1498
case OP_BC_ICMP_ULT:
1499
Store(inst->dest, Builder.CreateICmpULT(Op0, Op1));
1501
case OP_BC_ICMP_ULE:
1502
Store(inst->dest, Builder.CreateICmpULE(Op0, Op1));
1504
case OP_BC_ICMP_SGT:
1505
Store(inst->dest, Builder.CreateICmpSGT(Op0, Op1));
1507
case OP_BC_ICMP_SGE:
1508
Store(inst->dest, Builder.CreateICmpSGE(Op0, Op1));
1510
case OP_BC_ICMP_SLT:
1511
Store(inst->dest, Builder.CreateICmpSLT(Op0, Op1));
1514
Store(inst->dest, Builder.CreateSelect(Op0, Op1, Op2));
1518
Value *Dest = Values[inst->u.binop[1]];
1519
constPointerType *PTy = cast<PointerType>(Dest->getType());
1520
Op0 = convertOperand(func, PTy->getElementType(), inst->u.binop[0]);
1521
PTy = PointerType::getUnqual(Op0->getType());
1522
Dest = Builder.CreateBitCast(Dest, PTy);
1523
Builder.CreateStore(Op0, Dest);
1526
case OP_BC_CALL_DIRECT:
1528
Function *DestF = Functions[inst->u.ops.funcid];
1529
SmallVector<Value*, 2> args;
1530
args.push_back(&*F->arg_begin()); // pass hidden arg
1531
for (unsigned a=0;a<inst->u.ops.numOps;a++) {
1532
operand_t op = inst->u.ops.ops[a];
1533
args.push_back(convertOperand(func, DestF->getFunctionType()->getParamType(a+1), op));
1535
CallInst *CI = Builder.CreateCall(DestF, ARRAYREF(Value*, args.begin(), args.end()));
1536
CI->setCallingConv(CallingConv::Fast);
1537
CI->setDoesNotThrow(true);
1538
if (CI->getType()->getTypeID() != Type::VoidTyID)
1539
Store(inst->dest, CI);
1542
case OP_BC_CALL_API:
1544
assert(inst->u.ops.funcid < cli_apicall_maxapi && "APICall out of range");
1545
std::vector<Value*> args;
1546
Function *DestF = apiFuncs[inst->u.ops.funcid];
1547
if (!strcmp(cli_apicalls[inst->u.ops.funcid].name, "engine_functionality_level")) {
1549
ConstantInt::get(Type::getInt32Ty(Context),
1552
args.push_back(&*F->arg_begin()); // pass hidden arg
1553
for (unsigned a=0;a<inst->u.ops.numOps;a++) {
1554
operand_t op = inst->u.ops.ops[a];
1555
args.push_back(convertOperand(func, DestF->getFunctionType()->getParamType(a+1), op));
1557
CallInst *CI = Builder.CreateCall(DestF, ARRAYREFVECTOR(Value*, args));
1558
CI->setDoesNotThrow(true);
1559
Store(inst->dest, CI);
1565
constType *SrcTy = mapType(inst->u.three[0]);
1566
Value *V = convertOperand(func, SrcTy, inst->u.three[1]);
1567
Value *Op = convertOperand(func, I32Ty, inst->u.three[2]);
1568
Op = GEPOperand(Op);
1569
if (!createGEP(inst->dest, V, ARRAYREF(Value*, &Op, &Op+1))) {
1570
cli_warnmsg("[Bytecode JIT]: OP_BC_GEP1 createGEP failed\n");
1578
Ops[0] = ConstantInt::get(Type::getInt32Ty(Context), 0);
1579
constType *SrcTy = mapType(inst->u.three[0]);
1580
Value *V = convertOperand(func, SrcTy, inst->u.three[1]);
1581
Ops[1] = convertOperand(func, I32Ty, inst->u.three[2]);
1582
Ops[1] = GEPOperand(Ops[1]);
1583
if (!createGEP(inst->dest, V, ARRAYREF(Value*, Ops, Ops+2))) {
1584
cli_warnmsg("[Bytecode JIT]: OP_BC_GEPZ createGEP failed\n");
1591
std::vector<Value*> Idxs;
1592
assert(inst->u.ops.numOps > 2);
1593
constType *SrcTy = mapType(inst->u.ops.ops[0]);
1594
Value *V = convertOperand(func, SrcTy, inst->u.ops.ops[1]);
1595
for (unsigned a=2;a<inst->u.ops.numOps;a++) {
1596
Value *Op = convertOperand(func, I32Ty, inst->u.ops.ops[a]);
1597
Op = GEPOperand(Op);
1600
if (!createGEP(inst->dest, V, ARRAYREFVECTOR(Value*, Idxs))) {
1601
cli_warnmsg("[Bytecode JIT]: OP_BC_GEPN createGEP failed\n");
1608
Value *Dest = convertOperand(func, inst, inst->u.binop[1]);
1609
Value *V = convertOperand(func, inst, inst->u.binop[0]);
1610
constType *VPTy = PointerType::getUnqual(V->getType());
1611
if (VPTy != Dest->getType())
1612
Dest = Builder.CreateBitCast(Dest, VPTy);
1613
Builder.CreateStore(V, Dest);
1618
Op0 = Builder.CreateBitCast(Op0,
1619
Values[inst->dest]->getType());
1620
Op0 = Builder.CreateLoad(Op0);
1621
Store(inst->dest, Op0);
1626
Value *Dst = convertOperand(func, inst, inst->u.three[0]);
1627
Dst = Builder.CreatePointerCast(Dst, PointerType::getUnqual(Type::getInt8Ty(Context)));
1628
Value *Val = convertOperand(func, Type::getInt8Ty(Context), inst->u.three[1]);
1629
Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
1631
CallInst *c = Builder.CreateCall5(CF->FMemset, Dst, Val, Len,
1632
ConstantInt::get(Type::getInt32Ty(Context), 1),
1633
ConstantInt::get(Type::getInt1Ty(Context), 0)
1636
CallInst *c = Builder.CreateCall4(CF->FMemset, Dst, Val, Len,
1637
ConstantInt::get(Type::getInt32Ty(Context), 1));
1639
c->setTailCall(true);
1640
c->setDoesNotThrow();
1641
UpgradeCall(c, CF->FMemset);
1646
Value *Dst = convertOperand(func, inst, inst->u.three[0]);
1647
Dst = Builder.CreatePointerCast(Dst, PointerType::getUnqual(Type::getInt8Ty(Context)));
1648
Value *Src = convertOperand(func, inst, inst->u.three[1]);
1649
Src = Builder.CreatePointerCast(Src, PointerType::getUnqual(Type::getInt8Ty(Context)));
1650
Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
1652
CallInst *c = Builder.CreateCall5(CF->FMemcpy, Dst, Src, Len,
1653
ConstantInt::get(Type::getInt32Ty(Context), 1),
1654
ConstantInt::get(Type::getInt1Ty(Context), 0)
1657
CallInst *c = Builder.CreateCall4(CF->FMemcpy, Dst, Src, Len,
1658
ConstantInt::get(Type::getInt32Ty(Context), 1));
1660
c->setTailCall(true);
1661
c->setDoesNotThrow();
1662
UpgradeCall(c, CF->FMemcpy);
1667
Value *Dst = convertOperand(func, inst, inst->u.three[0]);
1668
Dst = Builder.CreatePointerCast(Dst, PointerType::getUnqual(Type::getInt8Ty(Context)));
1669
Value *Src = convertOperand(func, inst, inst->u.three[1]);
1670
Src = Builder.CreatePointerCast(Src, PointerType::getUnqual(Type::getInt8Ty(Context)));
1671
Value *Len = convertOperand(func, Type::getInt32Ty(Context), inst->u.three[2]);
1673
CallInst *c = Builder.CreateCall5(CF->FMemmove, Dst, Src, Len,
1674
ConstantInt::get(Type::getInt32Ty(Context), 1),
1675
ConstantInt::get(Type::getInt1Ty(Context), 0));
1677
CallInst *c = Builder.CreateCall4(CF->FMemmove, Dst, Src, Len,
1678
ConstantInt::get(Type::getInt32Ty(Context), 1));
1680
c->setTailCall(true);
1681
c->setDoesNotThrow();
1682
UpgradeCall(c, CF->FMemmove);
1687
Value *Dst = convertOperand(func, inst, inst->u.three[0]);
1688
Dst = Builder.CreatePointerCast(Dst, PointerType::getUnqual(Type::getInt8Ty(Context)));
1689
Value *Src = convertOperand(func, inst, inst->u.three[1]);
1690
Src = Builder.CreatePointerCast(Src, PointerType::getUnqual(Type::getInt8Ty(Context)));
1691
Value *Len = convertOperand(func, EE->getTargetData()->getIntPtrType(Context), inst->u.three[2]);
1692
CallInst *c = Builder.CreateCall3(CF->FRealmemcmp, Dst, Src, Len);
1693
c->setTailCall(true);
1694
c->setDoesNotThrow();
1695
Store(inst->dest, c);
1698
case OP_BC_ISBIGENDIAN:
1699
Store(inst->dest, WORDS_BIGENDIAN ?
1700
ConstantInt::getTrue(Context) :
1701
ConstantInt::getFalse(Context));
1705
CallInst *CI = Builder.CreateCall(CF->FHandler);
1706
CI->setDoesNotReturn();
1707
CI->setDoesNotThrow();
1708
Builder.CreateUnreachable();
1714
CallInst *C = Builder.CreateCall(CF->FBSwap16, convertOperand(func, inst, inst->u.unaryop));
1715
C->setTailCall(true);
1716
C->setDoesNotThrow(true);
1717
Store(inst->dest, C);
1722
CallInst *C = Builder.CreateCall(CF->FBSwap32, convertOperand(func, inst, inst->u.unaryop));
1723
C->setTailCall(true);
1724
C->setDoesNotThrow(true);
1725
Store(inst->dest, C);
1730
CallInst *C = Builder.CreateCall(CF->FBSwap64, convertOperand(func, inst, inst->u.unaryop));
1731
C->setTailCall(true);
1732
C->setDoesNotThrow(true);
1733
Store(inst->dest, C);
1736
case OP_BC_PTRDIFF32:
1738
Value *P1 = convertOperand(func, inst, inst->u.binop[0]);
1739
Value *P2 = convertOperand(func, inst, inst->u.binop[1]);
1740
P1 = Builder.CreatePtrToInt(P1, Type::getInt64Ty(Context));
1741
P2 = Builder.CreatePtrToInt(P2, Type::getInt64Ty(Context));
1742
Value *R = Builder.CreateSub(P1, P2);
1743
R = Builder.CreateTrunc(R, Type::getInt32Ty(Context));
1744
Store(inst->dest, R);
1747
case OP_BC_PTRTOINT64:
1749
Value *P1 = convertOperand(func, inst, inst->u.unaryop);
1750
P1 = Builder.CreatePtrToInt(P1, Type::getInt64Ty(Context));
1751
Store(inst->dest, P1);
1755
cli_warnmsg("[Bytecode JIT]: JIT doesn't implement opcode %d yet!\n",
1763
// If successful so far, run verifyFunction
1765
if (verifyFunction(*F, PrintMessageAction)) {
1766
// verification failed
1768
cli_warnmsg("[Bytecode JIT]: Verification failed\n");
1769
if (cli_debug_flag) {
1771
raw_string_ostream ostr(str);
1773
cli_dbgmsg_internal("[Bytecode JIT]: %s\n", ostr.str().c_str());
1780
// Cleanup after failure and return 0
1782
for (unsigned z=0; z < func->numBB ; z++) {
1786
apiMap.irgenTimer.stopTimer();
1788
for (unsigned z=0; z < bc->num_func; z++) {
1789
delete Functions[z];
1791
delete [] Functions;
1796
apiMap.irgenTimer.stopTimer();
1797
apiMap.pmTimer.startTimer();
1799
PM.doInitialization();
1801
PM.doFinalization();
1804
PMUnsigned.doInitialization();
1806
PMUnsigned.doFinalization();
1808
apiMap.pmTimer.stopTimer();
1809
apiMap.irgenTimer.startTimer();
1812
for (unsigned j=0;j<bc->num_func;j++) {
1813
Function *F = Functions[j];
1817
std::vector<constType*> args;
1819
args.push_back(HiddenCtx);
1820
FunctionType *Callable = FunctionType::get(Type::getInt32Ty(Context),
1823
// If prototype matches, add to callable functions
1824
if (Functions[0]->getFunctionType() != Callable) {
1825
cli_warnmsg("[Bytecode JIT]: Wrong prototype for function 0 in bytecode %d\n", bc->id);
1826
apiMap.irgenTimer.stopTimer();
1827
for (unsigned z=0; z < bc->num_func; z++) {
1828
delete Functions[z];
1830
delete [] Functions;
1833
// All functions have the Fast calling convention, however
1834
// entrypoint can only be C, emit wrapper
1835
Function *F = Function::Create(Functions[0]->getFunctionType(),
1836
Function::ExternalLinkage,
1837
Functions[0]->getName()+"_wrap", M);
1838
F->setDoesNotThrow();
1839
BasicBlock *BB = BasicBlock::Create(Context, "", F);
1840
std::vector<Value*> Args;
1841
for (Function::arg_iterator J=F->arg_begin(),
1842
JE=F->arg_end(); J != JE; ++JE) {
1843
Args.push_back(&*J);
1845
CallInst *CI = CallInst::Create(Functions[0], ARRAYREFVECTOR(Value*, Args), "", BB);
1846
CI->setCallingConv(CallingConv::Fast);
1847
ReturnInst::Create(Context, CI, BB);
1849
delete [] Functions;
1850
if (verifyFunction(*F, PrintMessageAction))
1853
/* DEBUG(errs() << "Generating code\n");
1854
// Codegen current function as executable machine code.
1855
EE->getPointerToFunction(Functions[j]);
1856
void *code = EE->getPointerToFunction(F);
1857
DEBUG(errs() << "Code generation finished\n");*/
1859
// compiledFunctions[func] = code;
1860
apiMap.irgenTimer.stopTimer();
1865
static sys::Mutex llvm_api_lock;
1867
// This class automatically acquires the lock when instantiated,
1868
// and releases the lock when leaving scope.
1869
class LLVMApiScopedLock {
1871
// when multithreaded mode is false (no atomics available),
1872
// we need to wrap all LLVM API calls with a giant mutex lock, but
1874
LLVMApiScopedLock() {
1875
// It is safer to just run all codegen under the mutex,
1876
// it is not like we are going to codegen from multiple threads
1877
// at a time anyway.
1878
// if (!llvm_is_multithreaded())
1879
llvm_api_lock.acquire();
1881
~LLVMApiScopedLock() {
1882
// if (!llvm_is_multithreaded())
1883
llvm_api_lock.release();
1887
static void addFunctionProtos(struct CommonFunctions *CF, ExecutionEngine *EE, Module *M)
1889
LLVMContext &Context = M->getContext();
1890
FunctionType *FTy = FunctionType::get(Type::getVoidTy(Context),
1892
CF->FHandler = Function::Create(FTy, Function::ExternalLinkage,
1894
CF->FHandler->setDoesNotReturn();
1895
CF->FHandler->setDoesNotThrow();
1896
CF->FHandler->addFnAttr(Attribute::NoInline);
1898
EE->addGlobalMapping(CF->FHandler, (void*)(intptr_t)jit_exception_handler);
1899
EE->InstallLazyFunctionCreator(noUnknownFunctions);
1900
EE->getPointerToFunction(CF->FHandler);
1902
std::vector<constType*> args;
1903
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
1904
args.push_back(Type::getInt8Ty(Context));
1905
args.push_back(Type::getInt32Ty(Context));
1906
args.push_back(Type::getInt32Ty(Context));
1908
args.push_back(Type::getInt1Ty(Context));
1910
FunctionType* FuncTy_3 = FunctionType::get(Type::getVoidTy(Context),
1912
CF->FMemset = Function::Create(FuncTy_3, GlobalValue::ExternalLinkage,
1914
"llvm.memset.p0i8.i32",
1919
CF->FMemset->setDoesNotThrow();
1920
CF->FMemset->setDoesNotCapture(1, true);
1923
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
1924
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
1925
args.push_back(Type::getInt32Ty(Context));
1926
args.push_back(Type::getInt32Ty(Context));
1928
args.push_back(Type::getInt1Ty(Context));
1930
FunctionType* FuncTy_4 = FunctionType::get(Type::getVoidTy(Context),
1932
CF->FMemmove = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage,
1934
"llvm.memmove.p0i8.i32",
1939
CF->FMemmove->setDoesNotThrow();
1940
CF->FMemmove->setDoesNotCapture(1, true);
1942
CF->FMemcpy = Function::Create(FuncTy_4, GlobalValue::ExternalLinkage,
1944
"llvm.memcpy.p0i8.p0i8.i32",
1949
CF->FMemcpy->setDoesNotThrow();
1950
CF->FMemcpy->setDoesNotCapture(1, true);
1953
args.push_back(Type::getInt16Ty(Context));
1954
FunctionType *FuncTy_5 = FunctionType::get(Type::getInt16Ty(Context), args, false);
1955
CF->FBSwap16 = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage,
1956
"llvm.bswap.i16", M);
1957
CF->FBSwap16->setDoesNotThrow();
1960
args.push_back(Type::getInt32Ty(Context));
1961
FunctionType *FuncTy_6 = FunctionType::get(Type::getInt32Ty(Context), args, false);
1962
CF->FBSwap32 = Function::Create(FuncTy_6, GlobalValue::ExternalLinkage,
1963
"llvm.bswap.i32", M);
1964
CF->FBSwap32->setDoesNotThrow();
1967
args.push_back(Type::getInt64Ty(Context));
1968
FunctionType *FuncTy_7 = FunctionType::get(Type::getInt64Ty(Context), args, false);
1969
CF->FBSwap64 = Function::Create(FuncTy_7, GlobalValue::ExternalLinkage,
1970
"llvm.bswap.i64", M);
1971
CF->FBSwap64->setDoesNotThrow();
1973
FunctionType* DummyTy = FunctionType::get(Type::getVoidTy(Context), false);
1974
CF->FRealmemset = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
1976
EE->addGlobalMapping(CF->FRealmemset, (void*)(intptr_t)memset);
1977
EE->getPointerToFunction(CF->FRealmemset);
1978
CF->FRealMemmove = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
1980
EE->addGlobalMapping(CF->FRealMemmove, (void*)(intptr_t)memmove);
1981
EE->getPointerToFunction(CF->FRealMemmove);
1982
CF->FRealmemcpy = Function::Create(DummyTy, GlobalValue::ExternalLinkage,
1984
EE->addGlobalMapping(CF->FRealmemcpy, (void*)(intptr_t)memcpy);
1985
EE->getPointerToFunction(CF->FRealmemcpy);
1988
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
1989
args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
1990
args.push_back(EE->getTargetData()->getIntPtrType(Context));
1991
FuncTy_5 = FunctionType::get(Type::getInt32Ty(Context),
1993
CF->FRealmemcmp = Function::Create(FuncTy_5, GlobalValue::ExternalLinkage, "memcmp", M);
1994
EE->addGlobalMapping(CF->FRealmemcmp, (void*)(intptr_t)memcmp);
1995
EE->getPointerToFunction(CF->FRealmemcmp);
2000
INITIALIZE_PASS_BEGIN(RuntimeLimits, "rl", "Runtime Limits", false, false)
2001
INITIALIZE_PASS_DEPENDENCY(LoopInfo)
2002
INITIALIZE_PASS_DEPENDENCY(ScalarEvolution)
2003
INITIALIZE_PASS_DEPENDENCY(DominatorTree)
2004
INITIALIZE_PASS_END(RuntimeLimits, "rl" ,"Runtime Limits", false, false)
2007
static pthread_mutex_t watchdog_mutex = PTHREAD_MUTEX_INITIALIZER;
2008
static pthread_cond_t watchdog_cond = PTHREAD_COND_INITIALIZER;
2009
static pthread_cond_t watchdog_cond2 = PTHREAD_COND_INITIALIZER;
2010
static int watchdog_running = 0;
2012
struct watchdog_item {
2013
volatile uint8_t* timeout;
2014
struct timespec abstimeout;
2015
struct watchdog_item *next;
2019
static struct watchdog_item* watchdog_head = NULL;
2020
static struct watchdog_item* watchdog_tail = NULL;
2022
extern "C" const char *cli_strerror(int errnum, char* buf, size_t len);
2023
#define WATCHDOG_IDLE 10
2024
static void *bytecode_watchdog(void *arg)
2027
struct timespec out;
2030
pthread_mutex_lock(&watchdog_mutex);
2032
cli_dbgmsg_internal("bytecode watchdog is running\n");
2034
struct watchdog_item *item;
2035
gettimeofday(&tv, NULL);
2036
out.tv_sec = tv.tv_sec + WATCHDOG_IDLE;
2037
out.tv_nsec = tv.tv_usec*1000;
2038
/* wait for some work, up to WATCHDOG_IDLE time */
2039
while (watchdog_head == NULL) {
2040
ret = pthread_cond_timedwait(&watchdog_cond, &watchdog_mutex,
2042
if (ret == ETIMEDOUT)
2045
cli_warnmsg("bytecode_watchdog: cond_timedwait(1) failed: %s\n",
2046
cli_strerror(ret, err, sizeof(err)));
2050
if (watchdog_head == NULL)
2052
/* wait till timeout is reached on this item */
2053
item = watchdog_head;
2054
while (item == watchdog_head) {
2056
ret = pthread_cond_timedwait(&watchdog_cond, &watchdog_mutex,
2058
if (ret == ETIMEDOUT)
2061
cli_warnmsg("bytecode_watchdog: cond_timedwait(2) failed: %s\n",
2062
cli_strerror(ret, err, sizeof(err)));
2067
pthread_cond_signal(&watchdog_cond2);
2068
if (item != watchdog_head)
2069
continue;/* got removed meanwhile */
2070
/* timeout reached, signal it to bytecode */
2072
cli_warnmsg("[Bytecode JIT]: Bytecode run timed out, timeout flag set\n");
2073
watchdog_head = item->next;
2075
watchdog_tail = NULL;
2077
watchdog_running = 0;
2079
cli_dbgmsg_internal("bytecode watchdog quiting\n");
2080
pthread_mutex_unlock(&watchdog_mutex);
2084
static void watchdog_disarm(struct watchdog_item *item)
2086
struct watchdog_item *q, *p = NULL;
2089
pthread_mutex_lock(&watchdog_mutex);
2090
for (q=watchdog_head;q && q != item;p = q, q = q->next) {}
2094
if (q == watchdog_head)
2095
watchdog_head = q->next;
2096
if (q == watchdog_tail)
2099
/* don't remove the item from the list until the watchdog is sleeping on
2100
* item, or it'll wake up on uninit data */
2101
while (item->in_use) {
2102
pthread_cond_signal(&watchdog_cond);
2103
pthread_cond_wait(&watchdog_cond2, &watchdog_mutex);
2105
pthread_mutex_unlock(&watchdog_mutex);
2108
static int watchdog_arm(struct watchdog_item *item, int ms, volatile uint8_t *timeout)
2114
item->timeout = timeout;
2118
gettimeofday(&tv0, NULL);
2119
tv0.tv_usec += ms * 1000;
2120
item->abstimeout.tv_sec = tv0.tv_sec + tv0.tv_usec/1000000;
2121
item->abstimeout.tv_nsec = (tv0.tv_usec%1000000)*1000;
2123
pthread_mutex_lock(&watchdog_mutex);
2124
if (!watchdog_running) {
2126
pthread_attr_t attr;
2127
pthread_attr_init(&attr);
2128
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
2130
if ((rc = pthread_create(&thread, &attr, bytecode_watchdog, NULL))) {
2132
cli_errmsg("(watchdog) pthread_create failed: %s\n", cli_strerror(rc, buf, sizeof(buf)));
2135
watchdog_running = 1;
2136
pthread_attr_destroy(&attr);
2140
watchdog_tail->next = item;
2141
watchdog_tail = item;
2143
watchdog_head = item;
2145
pthread_cond_signal(&watchdog_cond);
2146
pthread_mutex_unlock(&watchdog_mutex);
2150
static int bytecode_execute(intptr_t code, struct cli_bc_ctx *ctx)
2152
ScopedExceptionHandler handler;
2154
HANDLER_TRY(handler) {
2155
// setup exception handler to longjmp back here
2156
uint32_t result = ((uint32_t (*)(struct cli_bc_ctx *))(intptr_t)code)(ctx);
2157
*(uint32_t*)ctx->values = result;
2160
HANDLER_END(handler);
2161
cli_warnmsg("[Bytecode JIT]: JITed code intercepted runtime error!\n");
2162
return CL_EBYTECODE;
2165
int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx,
2166
const struct cli_bc_func *func)
2169
struct timeval tv0, tv1;
2170
struct watchdog_item witem;
2171
// no locks needed here, since LLVM automatically acquires a JIT lock
2173
void *code = bcs->engine->compiledFunctions[func];
2175
cli_warnmsg("[Bytecode JIT]: Unable to find compiled function\n");
2177
cli_warnmsg("[Bytecode JIT] Function has %d arguments, it must have 0 to be called as entrypoint\n",
2179
return CL_EBYTECODE;
2182
gettimeofday(&tv0, NULL);
2184
if (ctx->bytecode_timeout) {
2185
/* only spawn if timeout is set.
2186
* we don't set timeout for selfcheck (see bb #2235) */
2187
if (watchdog_arm(&witem, ctx->bytecode_timeout, &ctx->timeout))
2188
return CL_EBYTECODE;
2191
ret = bytecode_execute((intptr_t)code, ctx);
2193
if (ctx->bytecode_timeout)
2194
watchdog_disarm(&witem);
2196
if (cli_debug_flag) {
2198
gettimeofday(&tv1, NULL);
2199
tv1.tv_sec -= tv0.tv_sec;
2200
tv1.tv_usec -= tv0.tv_usec;
2201
diff = tv1.tv_sec*1000000 + tv1.tv_usec;
2202
cli_dbgmsg_internal("bytecode finished in %ld us\n", diff);
2204
return ctx->timeout ? CL_ETIMEOUT : ret;
2207
static unsigned char name_salt[16] = { 16, 38, 97, 12, 8, 4, 72, 196, 217, 144, 33, 124, 18, 11, 17, 253 };
2208
static void setGuard(unsigned char* guardbuf)
2211
memcpy(salt, name_salt, 16);
2212
for(unsigned i = 16; i < 48; i++)
2213
salt[i] = cli_rndnum(255);
2215
cl_hash_data("md5", salt, 48, guardbuf, NULL);
2218
static void addFPasses(FunctionPassManager &FPM, bool trusted, const TargetData *TD)
2220
// Set up the optimizer pipeline. Start with registering info about how
2221
// the target lays out data structures.
2222
FPM.add(new TargetData(*TD));
2223
// Promote allocas to registers.
2224
FPM.add(createPromoteMemoryToRegisterPass());
2225
FPM.add(new BrSimplifier());
2226
FPM.add(createDeadCodeEliminationPass());
2229
int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
2232
return CL_EBYTECODE;
2233
ScopedExceptionHandler handler;
2234
LLVMApiScopedLock scopedLock;
2235
// setup exception handler to longjmp back here
2236
HANDLER_TRY(handler) {
2237
// LLVM itself never throws exceptions, but operator new may throw bad_alloc
2239
Module *M = new Module("ClamAV jit module", bcs->engine->Context);
2242
std::string ErrorMsg;
2243
EngineBuilder builder(M);
2244
builder.setErrorStr(&ErrorMsg);
2245
builder.setEngineKind(EngineKind::JIT);
2246
builder.setOptLevel(CodeGenOpt::Default);
2247
ExecutionEngine *EE = bcs->engine->EE = builder.create();
2249
if (!ErrorMsg.empty())
2250
cli_errmsg("[Bytecode JIT]: error creating execution engine: %s\n",
2253
cli_errmsg("[Bytecode JIT]: JIT not registered?\n");
2254
return CL_EBYTECODE;
2256
bcs->engine->Listener = new NotifyListener();
2257
EE->RegisterJITEventListener(bcs->engine->Listener);
2258
// EE->RegisterJITEventListener(createOProfileJITEventListener());
2259
// Due to LLVM PR4816 only X86 supports non-lazy compilation, disable
2261
EE->DisableLazyCompilation();
2262
EE->DisableSymbolSearching();
2264
struct CommonFunctions CF;
2265
addFunctionProtos(&CF, EE, M);
2267
FunctionPassManager OurFPM(M), OurFPMUnsigned(M);
2268
M->setDataLayout(EE->getTargetData()->getStringRepresentation());
2269
M->setTargetTriple(sys::getHostTriple());
2271
addFPasses(OurFPM, true, EE->getTargetData());
2272
addFPasses(OurFPMUnsigned, false, EE->getTargetData());
2274
//TODO: create a wrapper that calls pthread_getspecific
2275
unsigned maxh = cli_globals[0].offset + sizeof(struct cli_bc_hooks);
2276
constType *HiddenCtx = PointerType::getUnqual(ArrayType::get(Type::getInt8Ty(bcs->engine->Context), maxh));
2278
LLVMTypeMapper apiMap(bcs->engine->Context, cli_apicall_types, cli_apicall_maxtypes, HiddenCtx);
2279
Function **apiFuncs = new Function *[cli_apicall_maxapi];
2280
for (unsigned i=0;i<cli_apicall_maxapi;i++) {
2281
const struct cli_apicall *api = &cli_apicalls[i];
2282
constFunctionType *FTy = cast<FunctionType>(apiMap.get(69+api->type, NULL, NULL));
2283
Function *F = Function::Create(FTy, Function::ExternalLinkage,
2286
switch (api->kind) {
2288
dest = (void*)(intptr_t)cli_apicalls0[api->idx];
2291
dest = (void*)(intptr_t)cli_apicalls1[api->idx];
2294
dest = (void*)(intptr_t)cli_apicalls2[api->idx];
2297
dest = (void*)(intptr_t)cli_apicalls3[api->idx];
2300
dest = (void*)(intptr_t)cli_apicalls4[api->idx];
2303
dest = (void*)(intptr_t)cli_apicalls5[api->idx];
2306
dest = (void*)(intptr_t)cli_apicalls6[api->idx];
2309
dest = (void*)(intptr_t)cli_apicalls7[api->idx];
2312
dest = (void*)(intptr_t)cli_apicalls8[api->idx];
2315
dest = (void*)(intptr_t)cli_apicalls9[api->idx];
2318
llvm_unreachable("invalid api type");
2321
std::string reason((Twine("No mapping for builtin api ")+api->name).str());
2322
llvm_error_handler(0, reason);
2324
EE->addGlobalMapping(F, dest);
2325
EE->getPointerToFunction(F);
2330
FunctionType *FTy = FunctionType::get(Type::getVoidTy(M->getContext()),
2332
GlobalVariable *Guard = new GlobalVariable(*M, PointerType::getUnqual(Type::getInt8Ty(M->getContext())),
2333
true, GlobalValue::ExternalLinkage, 0, "__stack_chk_guard");
2335
if (2*sizeof(void*) <= 16 && cli_rndnum(2)==2) {
2336
plus = sizeof(void*);
2338
EE->addGlobalMapping(Guard, (void*)(&bcs->engine->guard.b[plus]));
2339
setGuard(bcs->engine->guard.b);
2340
bcs->engine->guard.b[plus+sizeof(void*)-1] = 0x00;
2341
// printf("%p\n", *(void**)(&bcs->engine->guard.b[plus]));
2342
Function *SFail = Function::Create(FTy, Function::ExternalLinkage,
2343
"__stack_chk_fail", M);
2344
EE->addGlobalMapping(SFail, (void*)(intptr_t)jit_ssp_handler);
2345
EE->getPointerToFunction(SFail);
2347
llvm::Function **Functions = new Function*[bcs->count];
2348
for (unsigned i=0;i<bcs->count;i++) {
2349
const struct cli_bc *bc = &bcs->all_bcs[i];
2350
if (bc->state == bc_skip || bc->state == bc_interp) {
2354
LLVMCodegen Codegen(bc, M, &CF, bcs->engine->compiledFunctions, EE,
2355
OurFPM, OurFPMUnsigned, apiFuncs, apiMap);
2356
Function *F = Codegen.generate();
2358
cli_errmsg("[Bytecode JIT]: JIT codegen failed\n");
2360
for (unsigned z=0; z < i; z++) {
2361
delete Functions[z];
2363
delete [] Functions;
2364
return CL_EBYTECODE;
2370
bool has_untrusted = false;
2372
for (unsigned i=0;i<bcs->count;i++) {
2373
if (!bcs->all_bcs[i].trusted) {
2374
has_untrusted = true;
2379
PM.add(new TargetData(*EE->getTargetData()));
2380
// TODO: only run this on the untrusted bytecodes, not all of them...
2382
PM.add(createClamBCRTChecks());
2383
PM.add(createSCCPPass());
2384
PM.add(createCFGSimplificationPass());
2385
PM.add(createGlobalOptimizerPass());
2386
PM.add(createConstantMergePass());
2388
RuntimeLimits *RL = new RuntimeLimits();
2390
TimerWrapper pmTimer2("Transform passes");
2391
pmTimer2.startTimer();
2393
pmTimer2.stopTimer();
2397
PrettyStackTraceString CrashInfo2("Native machine codegen");
2398
TimerWrapper codegenTimer("Native codegen");
2399
codegenTimer.startTimer();
2400
// compile all functions now, not lazily!
2401
for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
2403
if (!Fn->isDeclaration()) {
2404
EE->getPointerToFunction(Fn);
2407
codegenTimer.stopTimer();
2410
for (unsigned i=0;i<bcs->count;i++) {
2411
const struct cli_bc_func *func = &bcs->all_bcs[i].funcs[0];
2413
continue;// not JITed
2414
bcs->engine->compiledFunctions[func] = EE->getPointerToFunction(Functions[i]);
2415
bcs->all_bcs[i].state = bc_jit;
2417
delete [] Functions;
2420
} catch (std::bad_alloc &badalloc) {
2421
cli_errmsg("[Bytecode JIT]: bad_alloc: %s\n",
2425
cli_errmsg("[Bytecode JIT]: Unexpected unknown exception occured\n");
2426
return CL_EBYTECODE;
2429
} HANDLER_END(handler);
2430
cli_errmsg("[Bytecode JIT] *** FATAL error encountered during bytecode generation\n");
2431
return CL_EBYTECODE;
2434
int bytecode_init(void)
2436
// If already initialized return
2437
if (llvm_is_multithreaded()) {
2438
cli_warnmsg("bytecode_init: already initialized\n");
2441
llvm_install_error_handler(llvm_error_handler);
2443
sys::PrintStackTraceOnErrorSignal();
2445
llvm::DisablePrettyStackTrace = true;
2447
atexit(do_shutdown);
2450
//disable this for now, it leaks
2451
llvm::JITEmitDebugInfo = false;
2452
// llvm::JITEmitDebugInfo = true;
2454
llvm::JITEmitDebugInfo = false;
2456
llvm::DwarfExceptionHandling = false;
2457
llvm_start_multithreaded();
2459
// If we have a native target, initialize it to ensure it is linked in and
2460
// usable by the JIT.
2461
#ifndef AC_APPLE_UNIVERSAL_BUILD
2462
InitializeNativeTarget();
2464
InitializeAllTargets();
2467
if (!llvm_is_multithreaded()) {
2469
DEBUG(errs() << "WARNING: ClamAV JIT built w/o atomic builtins\n"
2470
<< "On x86 for best performance ClamAV should be built for i686, not i386!\n");
2475
// Called once when loading a new set of BC files
2476
int cli_bytecode_init_jit(struct cli_all_bc *bcs, unsigned dconfmask)
2478
LLVMApiScopedLock scopedLock;
2479
bcs->engine = new(std::nothrow) cli_bcengine;
2482
bcs->engine->EE = 0;
2483
bcs->engine->Listener = 0;
2487
int cli_bytecode_done_jit(struct cli_all_bc *bcs, int partial)
2489
LLVMApiScopedLock scopedLock;
2491
if (bcs->engine->EE) {
2492
if (bcs->engine->Listener)
2493
bcs->engine->EE->UnregisterJITEventListener(bcs->engine->Listener);
2494
delete bcs->engine->EE;
2495
bcs->engine->EE = 0;
2497
delete bcs->engine->Listener;
2498
bcs->engine->Listener = 0;
2507
void cli_bytecode_debug(int argc, char **argv)
2509
cl::ParseCommandLineOptions(argc, argv);
2512
typedef struct lines {
2513
MemoryBuffer *buffer;
2514
std::vector<const char*> linev;
2517
static struct lineprinter {
2518
StringMap<linesTy*> files;
2521
void cli_bytecode_debug_printsrc(const struct cli_bc_ctx *ctx)
2523
if (!ctx->file || !ctx->directory || !ctx->line) {
2524
errs() << (ctx->directory ? "d":"null") << ":" << (ctx->file ? "f" : "null")<< ":" << ctx->line << "\n";
2527
// acquire a mutex here
2528
sys::Mutex mtx(false);
2529
sys::SmartScopedLock<false> lock(mtx);
2531
std::string path = std::string(ctx->directory) + "/" + std::string(ctx->file);
2532
StringMap<linesTy*>::iterator I = LinePrinter.files.find(path);
2534
if (I == LinePrinter.files.end()) {
2535
lines = new linesTy;
2536
std::string ErrorMessage;
2538
OwningPtr<MemoryBuffer> File;
2539
error_code ec = MemoryBuffer::getFile(path, File);
2541
ErrorMessage = ec.message();
2544
lines->buffer = File.take();
2546
lines->buffer = MemoryBuffer::getFile(path, &ErrorMessage);
2548
if (!lines->buffer) {
2549
errs() << "Unable to open file '" << path << "'\n";
2553
LinePrinter.files[path] = lines;
2555
lines = I->getValue();
2557
while (lines->linev.size() <= ctx->line+1) {
2559
if (lines->linev.empty()) {
2560
p = lines->buffer->getBufferStart();
2561
lines->linev.push_back(p);
2563
p = lines->linev.back();
2564
if (p == lines->buffer->getBufferEnd())
2566
p = strchr(p, '\n');
2568
p = lines->buffer->getBufferEnd();
2569
lines->linev.push_back(p);
2571
lines->linev.push_back(p+1);
2574
if (ctx->line >= lines->linev.size()) {
2575
errs() << "Line number " << ctx->line << "out of file\n";
2578
assert(ctx->line < lines->linev.size());
2581
int line = (int)ctx->line ? (int)ctx->line : -1;
2582
int col = (int)ctx->col ? (int)ctx->col : -1;
2583
//TODO: print this ourselves, instead of using SMDiagnostic
2584
SMDiagnostic diag(ctx->file, line, col,
2585
"", std::string(lines->linev[ctx->line-1], lines->linev[ctx->line]-1));
2586
diag.Print("[trace]", errs());
2591
void cli_bytecode_printversion()
2593
cl::PrintVersionMessage();
2596
void cli_printcxxver()
2598
/* Try to print information about some commonly used compilers */
2600
printf("GNU C++: %s (%u.%u.%u)\n", __VERSION__, __GNUC__, __GNUC_MINOR__,
2601
__GNUC_PATCHLEVEL__);
2603
#ifdef __INTEL_COMPILER
2604
printf("Intel Compiler C++ %u\n", __INTEL_COMPILER);
2607
printf("Microsoft Visual C++ %u\n", _MSC_VER);
2611
namespace ClamBCModule {
2612
void stop(const char *msg, llvm::Function* F, llvm::Instruction* I)
2614
if (F && F->hasName()) {
2615
cli_warnmsg("[Bytecode JIT] in function %s: %s", F->getNameStr().c_str(), msg);
2617
cli_warnmsg("[Bytecode JIT] %s", msg);
2623
static Value *findDbgGlobalDeclare(GlobalVariable *V) {
2624
const Module *M = V->getParent();
2625
NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.gv");
2629
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2630
DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
2631
if (!DIG.isGlobalVariable())
2633
if (DIGlobalVariable(DIG).getGlobal() == V)
2639
/// Find the debug info descriptor corresponding to this function.
2640
static Value *findDbgSubprogramDeclare(Function *V) {
2641
const Module *M = V->getParent();
2642
NamedMDNode *NMD = M->getNamedMetadata("llvm.dbg.sp");
2646
for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2647
DIDescriptor DIG(cast<MDNode>(NMD->getOperand(i)));
2648
if (!DIG.isSubprogram())
2650
if (DISubprogram(DIG).getFunction() == V)
2656
/// Finds the llvm.dbg.declare intrinsic corresponding to this value if any.
2657
/// It looks through pointer casts too.
2658
static const DbgDeclareInst *findDbgDeclare(const Value *V) {
2659
V = V->stripPointerCasts();
2661
if (!isa<Instruction>(V) && !isa<Argument>(V))
2664
const Function *F = NULL;
2665
if (const Instruction *I = dyn_cast<Instruction>(V))
2666
F = I->getParent()->getParent();
2667
else if (const Argument *A = dyn_cast<Argument>(V))
2670
for (Function::const_iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI)
2671
for (BasicBlock::const_iterator BI = (*FI).begin(), BE = (*FI).end();
2673
if (const DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(BI))
2674
if (DDI->getAddress() == V)
2679
static bool getLocationInfo(const Value *V, std::string &DisplayName,
2680
std::string &Type, unsigned &LineNo,
2681
std::string &File, std::string &Dir) {
2685
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(const_cast<Value*>(V))) {
2686
Value *DIGV = findDbgGlobalDeclare(GV);
2687
if (!DIGV) return false;
2688
DIGlobalVariable Var(cast<MDNode>(DIGV));
2690
StringRef D = Var.getDisplayName();
2693
LineNo = Var.getLineNumber();
2694
Unit = Var.getCompileUnit();
2695
TypeD = Var.getType();
2696
} else if (Function *F = dyn_cast<Function>(const_cast<Value*>(V))){
2697
Value *DIF = findDbgSubprogramDeclare(F);
2698
if (!DIF) return false;
2699
DISubprogram Var(cast<MDNode>(DIF));
2701
StringRef D = Var.getDisplayName();
2704
LineNo = Var.getLineNumber();
2705
Unit = Var.getCompileUnit();
2706
TypeD = Var.getType();
2708
const DbgDeclareInst *DDI = findDbgDeclare(V);
2709
if (!DDI) return false;
2710
DIVariable Var(cast<MDNode>(DDI->getVariable()));
2712
StringRef D = Var.getName();
2715
LineNo = Var.getLineNumber();
2716
Unit = Var.getCompileUnit();
2717
TypeD = Var.getType();
2720
StringRef T = TypeD.getName();
2723
StringRef F = Unit.getFilename();
2726
StringRef D = Unit.getDirectory();
2733
void printValue(llvm::Value *V, bool a, bool b) {
2734
std::string DisplayName;
2739
if (!getLocationInfo(V, DisplayName, Type, Line, File, Dir)) {
2740
errs() << *V << "\n";
2743
errs() << "'" << DisplayName << "' (" << File << ":" << Line << ")";
2746
void printLocation(llvm::Instruction *I, bool a, bool b) {
2747
if (MDNode *N = I->getMetadata("dbg")) {
2749
errs() << Loc.getFilename() << ":" << Loc.getLineNumber();
2750
if (unsigned Col = Loc.getColumnNumber()) {
2751
errs() << ":" << Col;
2756
errs() << *I << ":\n";