[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:42 UTC 2010


The following commit has been merged in the debian/unstable branch:
commit ec0779294358b638491efb5dd777cec5a379f7e1
Author: Török Edvin <edwin at clamav.net>
Date:   Thu Sep 10 22:51:11 2009 +0300

    Support for constant global with global initializers.

diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c
index a8e28f5..72b51b4 100644
--- a/libclamav/bytecode.c
+++ b/libclamav/bytecode.c
@@ -268,9 +268,8 @@ static inline operand_t readOperand(struct cli_bc_func *func, unsigned char *p,
 	*dest= 0;
 	ty = 8*readFixedNumber(p, off, len, ok, 1);
 	if (!ty) {
-	    cli_errmsg("bytecode: void type constant is invalid!\n");
-	    *ok = 0;
-	    return MAX_OP;
+	    /* This is a global variable */
+	    return 0x80000000 | v;
 	}
 	if (ty <= 8)
 	    *(uint8_t*)dest = v;
@@ -652,6 +651,99 @@ static int parseApis(struct cli_bc *bc, unsigned char *buffer)
     return CL_SUCCESS;
 }
 
+static uint16_t type_components(struct cli_bc *bc, uint16_t id, char *ok)
+{
+    unsigned i, sum=0;
+    const struct cli_bc_type *ty;
+    if (id <= 64)
+	return 1;
+    ty = &bc->types[id-65];
+    /* TODO: protect against recursive types */
+    switch (ty->kind) {
+	case DFunctionType:
+	    cli_errmsg("bytecode: function type not accepted for constant: %u\n", id);
+	    /* don't accept functions as constant initializers */
+	    *ok = 0;
+	    return 0;
+	case DPointerType:
+	    cli_errmsg("bytecode: pointer type not accepted for constant: %u\n", id);
+	    /* don't accept pointer initializers */
+	    *ok = 0;
+	    return 0;
+	case DStructType:
+	case DPackedStructType:
+	    for (i=0;i<ty->numElements;i++) {
+		sum += type_components(bc, ty->containedTypes[i], ok);
+	    }
+	    return sum;
+	case DArrayType:
+	    return type_components(bc, ty->containedTypes[0], ok)*ty->numElements;
+	default:
+	    *ok = 0;
+	    return 0;
+    }
+}
+
+static void readConstant(struct cli_bc *bc, unsigned i, unsigned comp,
+			 unsigned char *buffer, unsigned *offset,
+			 unsigned len, char *ok)
+{
+    unsigned j=0;
+    while (*ok && buffer[*offset] != 0x60) {
+	if (j > comp) {
+	    cli_errmsg("bytecode: constant has too many subcomponents, expected %u\n", comp);
+	    *ok = 0;
+	    return;
+	}
+	buffer[*offset] |= 0x20;
+	bc->globals[i][j++] = readNumber(buffer, offset, len, ok);
+    }
+    if (*ok && j != comp) {
+	cli_errmsg("bytecode: constant has too few subcomponents: %u < %u\n", j, comp);
+    }
+    *offset++;
+}
+
+/* parse constant globals with constant initializers */
+static int parseGlobals(struct cli_bc *bc, unsigned char *buffer)
+{
+    unsigned i, offset = 1, len = strlen((const char*)buffer), numglobals;
+    char ok=1;
+
+    if (buffer[0] != 'G') {
+	cli_errmsg("bytecode: Invalid globals header: %c\n", buffer[0]);
+	return CL_EMALFDB;
+    }
+    numglobals = readNumber(buffer, &offset, len, &ok);
+    bc->globals = cli_calloc(numglobals, sizeof(*bc->globals));
+    if (!bc->globals) {
+	cli_errmsg("bytecode: OOM allocating memory for %u globals\n", numglobals);
+	return CL_EMEM;
+    }
+    bc->globaltys = cli_calloc(numglobals, sizeof(*bc->globaltys));
+    if (!bc->globaltys) {
+	cli_errmsg("bytecode: OOM allocating memory for %u global types\n", numglobals);
+	return CL_EMEM;
+    }
+    bc->num_globals = numglobals;
+    if (!ok)
+	return CL_EMALFDB;
+    for (i=0;i<numglobals;i++) {
+	unsigned comp;
+	bc->globaltys[i] = readTypeID(bc, buffer, &offset, len, &ok);
+	comp = type_components(bc, bc->globaltys[i], &ok);
+	if (!ok)
+	    return CL_EMALFDB;
+	bc->globals[i] = cli_malloc(sizeof(bc->globals[0])*comp);
+	if (!bc->globals[i])
+	    return CL_EMEM;
+	readConstant(bc, i, comp, buffer, &offset, len, &ok);
+    }
+    if (!ok)
+	return CL_EMALFDB;
+    return CL_SUCCESS;
+}
+
 static int parseFunctionHeader(struct cli_bc *bc, unsigned fn, unsigned char *buffer)
 {
     char ok=1;
@@ -921,6 +1013,7 @@ enum parse_state {
     PARSE_BC_HEADER=0,
     PARSE_BC_TYPES,
     PARSE_BC_APIS,
+    PARSE_BC_GLOBALS,
     PARSE_FUNC_HEADER,
     PARSE_BB
 };
@@ -970,6 +1063,18 @@ int cli_bytecode_load(struct cli_bc *bc, FILE *f, struct cli_dbio *dbio)
 		    cli_errmsg("Error at bytecode line %u\n", row);
 		    return rc;
 		}
+		state = PARSE_BC_GLOBALS;
+		break;
+	    case PARSE_BC_GLOBALS:
+		rc = parseGlobals(bc, (unsigned char*)buffer);
+		if (rc == CL_BREAK) /* skip */ {
+		    bc->state = bc_skip;
+		    return CL_SUCCESS;
+		}
+		if (rc != CL_SUCCESS) {
+		    cli_errmsg("Error at bytecode line %u\n", row);
+		    return rc;
+		}
 		state = PARSE_FUNC_HEADER;
 		break;
 	    case PARSE_FUNC_HEADER:
@@ -1079,6 +1184,11 @@ void cli_bytecode_destroy(struct cli_bc *bc)
 	    free(bc->types[i].containedTypes);
     }
     free(bc->types);
+    for (i=0;i<bc->num_globals;i++) {
+	free(bc->globals[i]);
+    }
+    free(bc->globals);
+    free(bc->globaltys);
     if (bc->uses_apis)
 	cli_bitset_free(bc->uses_apis);
 }
diff --git a/libclamav/bytecode.h b/libclamav/bytecode.h
index 2026318..b663ba9 100644
--- a/libclamav/bytecode.h
+++ b/libclamav/bytecode.h
@@ -49,6 +49,9 @@ struct cli_bc {
   unsigned num_func;
   struct cli_bc_func *funcs;
   struct cli_bc_type *types;
+  uint64_t **globals;
+  uint16_t *globaltys;
+  size_t num_globals;
   enum bc_state state;
   uint16_t start_tid;
   struct bitset_tag *uses_apis;
diff --git a/libclamav/c++/bytecode2llvm.cpp b/libclamav/c++/bytecode2llvm.cpp
index e26a11e..d167d08 100644
--- a/libclamav/c++/bytecode2llvm.cpp
+++ b/libclamav/c++/bytecode2llvm.cpp
@@ -187,6 +187,7 @@ private:
     ExecutionEngine *EE;
     TargetFolder Folder;
     IRBuilder<false, TargetFolder> Builder;
+    std::vector<GlobalVariable*> globals;
     Value **Values;
     FunctionPassManager &PM;
     unsigned numLocals;
@@ -229,6 +230,12 @@ private:
 	if (operand < func->numValues)
 	    return Builder.CreateLoad(Values[operand]);
 
+	if (operand & 0x80000000) {
+	    operand &= 0x7fffffff;
+	    assert(operand < globals.size() && "Global index out of range");
+	    // Global
+	    return globals[operand];
+	}
 	// Constant
 	operand -= func->numValues;
 	// This was already validated by libclamav.
@@ -282,6 +289,33 @@ private:
     {
 	return TypeMap->get(typeID);
     }
+
+    Constant *buildConstant(const Type *Ty, uint64_t *components, unsigned &c)
+    {
+	if (isa<IntegerType>(Ty)) {
+	    return ConstantInt::get(Ty, components[c++]);
+	}
+	if (const ArrayType *ATy = dyn_cast<ArrayType>(Ty)) {
+	   std::vector<Constant*> elements;
+	   elements.reserve(ATy->getNumElements());
+	   for (unsigned i=0;i<ATy->getNumElements();i++) {
+	       elements.push_back(buildConstant(ATy->getElementType(), components, c));
+	   }
+	   return ConstantArray::get(ATy, elements);
+	}
+	if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+	   std::vector<Constant*> elements;
+	   elements.reserve(STy->getNumElements());
+	   for (unsigned i=0;i<STy->getNumElements();i++) {
+	       elements.push_back(buildConstant(STy->getElementType(i), components, c));
+	   }
+	   return ConstantStruct::get(STy, elements);
+	}
+	Ty->dump();
+	assert(0 && "Not reached");
+	return 0;
+    }
+
 public:
     LLVMCodegen(const struct cli_bc *bc, Module *M, FunctionMapTy &cFuncs,
 		ExecutionEngine *EE, FunctionPassManager &PM, Function **apiFuncs)
@@ -302,11 +336,22 @@ public:
 	FHandler->setDoesNotReturn();
 	FHandler->setDoesNotThrow();
 	FHandler->addFnAttr(Attribute::NoInline);
-	EE->addGlobalMapping(FHandler, (void*)jit_exception_handler); 
+	EE->addGlobalMapping(FHandler, (void*)jit_exception_handler);
 
 	// The hidden ctx param to all functions
 	const Type *HiddenCtx = PointerType::getUnqual(Type::getInt8Ty(Context));
 
+	globals.reserve(bc->num_globals);
+	for (unsigned i=0;i<bc->num_globals;i++) {
+	    const Type *Ty = mapType(bc->globaltys[i]);
+	    GlobalVariable *GV = cast<GlobalVariable>(M->getOrInsertGlobal("glob"+i,
+									   Ty));
+	    // TODO: validate number of components against type_components
+	    unsigned c = 0;
+	    GV->setInitializer(buildConstant(Ty, bc->globals[i], c));
+	    globals.push_back(GV);
+	}
+
 	Function **Functions = new Function*[bc->num_func];
 	for (unsigned j=0;j<bc->num_func;j++) {
 	    PrettyStackTraceString CrashInfo("Generate LLVM IR functions");

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list