[Pkg-clamav-commits] [SCM] Debian repository for ClamAV branch, debian/unstable, updated. debian/0.95+dfsg-1-6156-g094ec9b

Török Edvin edwin at clamav.net
Sun Apr 4 01:04:12 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit d0af4afea4e3b74a65aab96720e5a86d9fa95ad4
Author: Török Edvin <edwin at clamav.net>
Date:   Fri Sep 4 16:24:52 2009 +0300

    ctx param to APIs

diff --git a/libclamav/Makefile.am b/libclamav/Makefile.am
index 84f3838..6144b96 100644
--- a/libclamav/Makefile.am
+++ b/libclamav/Makefile.am
@@ -335,7 +335,8 @@ libclamav_la_SOURCES = \
 	type_desc.h \
 	bytecode_api.c \
 	bytecode_api_decl.c \
-	bytecode_api.h
+	bytecode_api.h \
+	bytecode_api_impl.h
 
 if !LINK_TOMMATH
 libclamav_la_SOURCES += bignum.c \
diff --git a/libclamav/bytecode_api.c b/libclamav/bytecode_api.c
index df75295..e625e7b 100644
--- a/libclamav/bytecode_api.c
+++ b/libclamav/bytecode_api.c
@@ -3,6 +3,8 @@
  *
  *  Copyright (C) 2009 Sourcefire, Inc.
  *
+ *  Authors: Török Edvin
+ *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License version 2 as
  *  published by the Free Software Foundation.
@@ -21,13 +23,14 @@
 #include "cltypes.h"
 #include "type_desc.h"
 #include "bytecode_api.h"
+#include "bytecode_api_impl.h"
 
-int32_t cli_bcapi_test0(struct foo* s, uint32_t u)
+uint32_t cli_bcapi_test0(struct cli_bc_ctx *ctx, struct foo* s, uint32_t u)
 {
     return (s && s->nxt == s && u == 0xdeadbeef) ? 0x12345678 : 0x55;
 }
 
-int32_t cli_bcapi_test1(int32_t a, int32_t b)
+uint32_t cli_bcapi_test1(struct cli_bc_ctx *ctx, uint32_t a, uint32_t b)
 {
     return (a==0xf00dbeef && b==0xbeeff00d) ? 0x12345678 : 0x55;
 }
diff --git a/libclamav/bytecode_api.h b/libclamav/bytecode_api.h
index 3028a2c..86261d0 100644
--- a/libclamav/bytecode_api.h
+++ b/libclamav/bytecode_api.h
@@ -30,5 +30,5 @@ struct foo {
     struct foo *nxt;
 };
 
-int32_t test0(struct foo*, uint32_t);
-int32_t test1(int32_t, int32_t);
+uint32_t test0(struct foo*, uint32_t);
+uint32_t test1(uint32_t, uint32_t);
diff --git a/libclamav/bytecode_api_decl.c b/libclamav/bytecode_api_decl.c
index f187b18..711b24c 100644
--- a/libclamav/bytecode_api_decl.c
+++ b/libclamav/bytecode_api_decl.c
@@ -22,6 +22,7 @@
 #include "cltypes.h"
 #include "type_desc.h"
 #include "bytecode_api.h"
+#include "bytecode_api_impl.h"
 
 uint32_t cli_bcapi_test0(struct cli_bc_ctx *ctx, struct foo*, uint32_t);
 uint32_t cli_bcapi_test1(struct cli_bc_ctx *ctx, uint32_t, uint32_t);
diff --git a/libclamav/c++/bytecode2llvm.cpp b/libclamav/c++/bytecode2llvm.cpp
index e2f4d8b..096f5bf 100644
--- a/libclamav/c++/bytecode2llvm.cpp
+++ b/libclamav/c++/bytecode2llvm.cpp
@@ -21,6 +21,7 @@
  */
 #define DEBUG_TYPE "clamavjit"
 #include "llvm/ADT/DenseMap.h"
+#include "llvm/CallingConv.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
 #include "llvm/ExecutionEngine/ExecutionEngine.h"
@@ -114,7 +115,7 @@ private:
     }
 public:
     LLVMTypeMapper(LLVMContext &Context, const struct cli_bc_type *types,
-		   unsigned count) : Context(Context), numTypes(count)
+		   unsigned count, const Type *Hidden=0) : Context(Context), numTypes(count)
     {
 	TypeMap.reserve(count);
 	// During recursive type construction pointers to Type* may be
@@ -137,7 +138,10 @@ public:
 		{
 		    assert(Elts.size() > 0 && "Function with no return type?");
 		    const Type *RetTy = Elts[0];
-		    Elts.erase(Elts.begin());
+		    if (Hidden)
+			Elts[0] = Hidden;
+		    else
+			Elts.erase(Elts.begin());
 		    Ty = FunctionType::get(RetTy, Elts, false);
 		    break;
 		}
@@ -281,10 +285,10 @@ private:
 public:
     LLVMCodegen(const struct cli_bc *bc, Module *M, FunctionMapTy &cFuncs,
 		ExecutionEngine *EE, FunctionPassManager &PM, Function **apiFuncs)
-	: bc(bc), M(M), Context(M->getContext()), compiledFunctions(cFuncs), 
-	BytecodeID("bc"+Twine(bc->id)), EE(EE), 
-	Folder(EE->getTargetData(), Context), Builder(Context, Folder), PM(PM), 
-	apiFuncs(apiFuncs) 
+	: bc(bc), M(M), Context(M->getContext()), compiledFunctions(cFuncs),
+	BytecodeID("bc"+Twine(bc->id)), EE(EE),
+	Folder(EE->getTargetData(), Context), Builder(Context, Folder), PM(PM),
+	apiFuncs(apiFuncs)
     {}
 
     bool generate() {
@@ -300,21 +304,26 @@ public:
 	FHandler->addFnAttr(Attribute::NoInline);
 	EE->addGlobalMapping(FHandler, (void*)jit_exception_handler); 
 
+	// The hidden ctx param to all functions
+	const Type *HiddenCtx = PointerType::getUnqual(Type::getInt8Ty(Context));
+
 	Function **Functions = new Function*[bc->num_func];
 	for (unsigned j=0;j<bc->num_func;j++) {
 	    PrettyStackTraceString CrashInfo("Generate LLVM IR functions");
 	    // Create LLVM IR Function
 	    const struct cli_bc_func *func = &bc->funcs[j];
 	    std::vector<const Type*> argTypes;
+	    argTypes.push_back(HiddenCtx);
 	    for (unsigned a=0;a<func->numArgs;a++) {
 		argTypes.push_back(mapType(func->types[a]));
 	    }
 	    const Type *RetTy = mapType(func->returnType);
 	    FunctionType *FTy =  FunctionType::get(RetTy, argTypes,
 							 false);
-	    Functions[j] = Function::Create(FTy, Function::InternalLinkage, 
+	    Functions[j] = Function::Create(FTy, Function::InternalLinkage,
 					   BytecodeID+"f"+Twine(j), M);
 	    Functions[j]->setDoesNotThrow();
+	    Functions[j]->setCallingConv(CallingConv::Fast);
 	}
 	const Type *I32Ty = Type::getInt32Ty(Context);
 	for (unsigned j=0;j<bc->num_func;j++) {
@@ -332,6 +341,8 @@ public:
 	    Values = new Value*[func->numValues];
 	    Builder.SetInsertPoint(BB[0]);
 	    Function::arg_iterator I = F->arg_begin();
+	    assert(F->arg_size() == func->numArgs + 1 && "Mismatched args");
+	    ++I;
 	    for (unsigned i=0;i<func->numArgs; i++) {
 		assert(I != F->arg_end());
 		Values[i] = &*I;
@@ -524,11 +535,14 @@ public:
 			{
 			    Function *DestF = Functions[inst->u.ops.funcid];
 			    SmallVector<Value*, 2> args;
+			    args.push_back(&*F->arg_begin()); // pass hidden arg
 			    for (unsigned a=0;a<inst->u.ops.numOps;a++) {
 				operand_t op = inst->u.ops.ops[a];
-				args.push_back(convertOperand(func, DestF->getFunctionType()->getParamType(a), op));
+				args.push_back(convertOperand(func, DestF->getFunctionType()->getParamType(a+1), op));
 			    }
-			    Store(inst->dest, Builder.CreateCall(DestF, args.begin(), args.end()));
+			    CallInst *CI = Builder.CreateCall(DestF, args.begin(), args.end());
+			    CI->setCallingConv(CallingConv::Fast);
+			    Store(inst->dest, CI);
 			    break;
 			}
 			case OP_CALL_API:
@@ -537,9 +551,10 @@ public:
 			    const struct cli_apicall *api = &cli_apicalls[inst->u.ops.funcid];
 			    std::vector<Value*> args;
 			    Function *DestF = apiFuncs[inst->u.ops.funcid];
+			    args.push_back(&*F->arg_begin()); // pass hidden arg
 			    for (unsigned a=0;a<inst->u.ops.numOps;a++) {
 				operand_t op = inst->u.ops.ops[a];
-				args.push_back(convertOperand(func, DestF->getFunctionType()->getParamType(a), op));
+				args.push_back(convertOperand(func, DestF->getFunctionType()->getParamType(a+1), op));
 			    }
 			    Store(inst->dest, Builder.CreateCall(DestF, args.begin(), args.end()));
 			    break;
@@ -601,16 +616,38 @@ public:
 
 	DEBUG(M->dump());
 	delete TypeMap;
-	FunctionType *Callable = FunctionType::get(Type::getInt32Ty(Context),false);
+	std::vector<const Type*> args;
+	args.push_back(PointerType::getUnqual(Type::getInt8Ty(Context)));
+	FunctionType *Callable = FunctionType::get(Type::getInt32Ty(Context),
+						   args, false);
 	for (unsigned j=0;j<bc->num_func;j++) {
 	    const struct cli_bc_func *func = &bc->funcs[j];
 	    PrettyStackTraceString CrashInfo2("Native machine codegen");
-	    // Codegen current function as executable machine code.
-	    void *code = EE->getPointerToFunction(Functions[j]);
 
 	    // If prototype matches, add to callable functions
-	    if (Functions[j]->getFunctionType() == Callable)
+	    if (Functions[j]->getFunctionType() == Callable) {
+		// All functions have the Fast calling convention, however
+		// entrypoint can only be C, emit wrapper
+		Function *F = Function::Create(Functions[j]->getFunctionType(),
+					       Function::ExternalLinkage,
+					       Functions[j]->getName()+"_wrap", M);
+		F->setDoesNotThrow();
+		BasicBlock *BB = BasicBlock::Create(Context, "", F);
+		std::vector<Value*> args;
+		for (Function::arg_iterator J=F->arg_begin(),
+		     JE=F->arg_end(); J != JE; ++JE) {
+		    args.push_back(&*J);
+		}
+		CallInst *CI = CallInst::Create(Functions[j], args.begin(), args.end(), "", BB);
+		CI->setCallingConv(CallingConv::Fast);
+		ReturnInst::Create(Context, CI, BB);
+
+		if (verifyFunction(*F, PrintMessageAction));
+		// Codegen current function as executable machine code.
+		void *code = EE->getPointerToFunction(F);
+
 		compiledFunctions[func] = code;
+	    }
 	}
 	delete [] Functions;
 	return true;
@@ -631,7 +668,7 @@ int cli_vm_execute_jit(const struct cli_all_bc *bcs, struct cli_bc_ctx *ctx,
     if (setjmp(env) == 0) {
 	// setup exception handler to longjmp back here
 	ExceptionReturn.set(&env);
-	uint32_t result = ((uint32_t (*)(void))code)();
+	uint32_t result = ((uint32_t (*)(struct cli_bc_ctx *))code)(ctx);
 	*(uint32_t*)ctx->values = result;
 	return 0;
     }
@@ -693,7 +730,10 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
 	OurFPM.add(createDeadCodeEliminationPass());
 	OurFPM.doInitialization();
 
-	LLVMTypeMapper apiMap(bcs->engine->Context, cli_apicall_types, cli_apicall_maxtypes);
+	//TODO: create a wrapper that calls pthread_getspecific
+	const Type *HiddenCtx = PointerType::getUnqual(Type::getInt8Ty(bcs->engine->Context));
+
+	LLVMTypeMapper apiMap(bcs->engine->Context, cli_apicall_types, cli_apicall_maxtypes, HiddenCtx);
 	Function **apiFuncs = new Function *[cli_apicall_maxapi];
 	for (unsigned i=0;i<cli_apicall_maxapi;i++) {
 	    const struct cli_apicall *api = &cli_apicalls[i];
diff --git a/libclamav/type_desc.h b/libclamav/type_desc.h
index b769701..1f105f5 100644
--- a/libclamav/type_desc.h
+++ b/libclamav/type_desc.h
@@ -40,8 +40,8 @@ struct cli_bc_type {
     unsigned align;
 };
 
-typedef int32_t (*cli_apicall_int2)(struct cli_bc_ctx *, int32_t, int32_t);
-typedef int32_t (*cli_apicall_pointer)(struct cli_bc_ctx *, void*, uint32_t);
+typedef uint32_t (*cli_apicall_int2)(struct cli_bc_ctx *, uint32_t, uint32_t);
+typedef uint32_t (*cli_apicall_pointer)(struct cli_bc_ctx *, void*, uint32_t);
 
 struct cli_apicall {
     const char *name;

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list