[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