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


The following commit has been merged in the debian/unstable branch:
commit 53bd5bb14da5394112960dec50159da95583e5eb
Author: Török Edvin <edwin at clamav.net>
Date:   Mon Nov 30 15:22:20 2009 +0200

    read optional debug metadata.

diff --git a/libclamav/bytecode.c b/libclamav/bytecode.c
index 9938071..c901d7e 100644
--- a/libclamav/bytecode.c
+++ b/libclamav/bytecode.c
@@ -63,7 +63,9 @@ int cli_bytecode_context_reset(struct cli_bc_ctx *ctx)
     free(ctx->opsizes);
     free(ctx->values);
     free(ctx->operands);
-    ctx->operands = ctx->values = ctx->opsizes = NULL;
+    ctx->operands = NULL;
+    ctx->values = NULL;
+    ctx->opsizes = NULL;
     return CL_SUCCESS;
 }
 
@@ -320,7 +322,7 @@ static inline unsigned char *readData(const unsigned char *p, unsigned *off, uns
     }
     (*off)++;
     l = readNumber(p, off, len, ok);
-    if (!l) {
+    if (!l || !ok) {
 	*datalen = l;
 	return NULL;
     }
@@ -400,6 +402,8 @@ static int parseHeader(struct cli_bc *bc, unsigned char *buffer)
     bc->num_func = readNumber(buffer, &offset, len, &ok);
     bc->state = bc_loaded;
     bc->uses_apis = NULL;
+    bc->dbgnodes = NULL;
+    bc->dbgnode_cnt = 0;
     if (!ok) {
 	cli_errmsg("Invalid bytecode header at %u\n", offset);
 	return CL_EMALFDB;
@@ -787,6 +791,58 @@ static int parseGlobals(struct cli_bc *bc, unsigned char *buffer)
     return CL_SUCCESS;
 }
 
+static int parseMD(struct cli_bc *bc, unsigned char *buffer)
+{
+    unsigned offset = 1, len = strlen(buffer);
+    unsigned numMD, i, b;
+    char ok = 1;
+    if (buffer[0] != 'D')
+	return CL_EMALFDB;
+    numMD = readNumber(buffer, &offset, len, &ok);
+    if (!ok) {
+	cli_errmsg("Unable to parse number of MD nodes\n");
+	return CL_EMALFDB;
+    }
+    b = bc->dbgnode_cnt;
+    bc->dbgnode_cnt += numMD;
+    bc->dbgnodes = cli_realloc(bc->dbgnodes, bc->dbgnode_cnt * sizeof(*bc->dbgnodes));
+    if (!bc->dbgnodes)
+	return CL_EMEM;
+    for (i=0;i<numMD;i++) {
+	unsigned j;
+	struct cli_bc_dbgnode_element* elts;
+	unsigned el = readNumber(buffer, &offset, len, &ok);
+	if (!ok) {
+	    cli_errmsg("Unable to parse number of elements\n");
+	    return CL_EMALFDB;
+	}
+	bc->dbgnodes[b+i].numelements = el;
+	bc->dbgnodes[b+i].elements = elts = cli_calloc(el, sizeof(*elts));
+	if (!elts)
+	    return CL_EMEM;
+	for (j=0;j<el;j++) {
+	    if (buffer[offset] == '|') {
+		elts[j].string = readData(buffer, &offset, len, &ok, &elts[j].len);
+		if (!ok)
+		    return CL_EMALFDB;
+	    } else {
+		elts[j].len = readNumber(buffer, &offset, len, &ok);
+		if (!ok)
+		    return CL_EMALFDB;
+		if (elts[j].len) {
+		    elts[j].constant = readNumber(buffer, &offset, len, &ok);
+		}
+		else
+		    elts[j].nodeid = readNumber(buffer, &offset, len, &ok);
+		if (!ok)
+		    return CL_EMALFDB;
+	    }
+	}
+    }
+    cli_dbgmsg("bytecode: Parsed %u nodes total\n", bc->dbgnode_cnt);
+    return CL_SUCCESS;
+}
+
 static int parseFunctionHeader(struct cli_bc *bc, unsigned fn, unsigned char *buffer)
 {
     char ok=1;
@@ -1046,6 +1102,27 @@ static int parseBB(struct cli_bc *bc, unsigned func, unsigned bb, unsigned char
 	}
 	offset++;
     }
+    if (buffer[offset] == 'D') {
+	unsigned num;
+	offset += 3;
+	if (offset >= len)
+	    return CL_EMALFDB;
+	num = readNumber(buffer, &offset, len, &ok);
+	if (!ok)
+	    return CL_EMALFDB;
+	if (num != bcfunc->numInsts) {
+	    cli_errmsg("invalid number of dbg nodes, expected: %u, got: %u\n", bcfunc->numInsts, num);
+	    return CL_EMALFDB;
+	}
+	bcfunc->dbgnodes = cli_malloc(num*sizeof(*bcfunc->dbgnodes));
+	if (!bcfunc->dbgnodes)
+	    return CL_EMEM;
+	for (i=0;i<num;i++) {
+	    bcfunc->dbgnodes[i] = readNumber(buffer, &offset, len, &ok);
+	    if (!ok)
+		return CL_EMALFDB;
+	}
+    }
     if (offset != len) {
 	cli_errmsg("Trailing garbage in basicblock: %d extra bytes\n",
 		   len-offset);
@@ -1062,6 +1139,7 @@ enum parse_state {
     PARSE_BC_APIS,
     PARSE_BC_GLOBALS,
     PARSE_BC_LSIG,
+    PARSE_MD_OPT_HEADER,
     PARSE_FUNC_HEADER,
     PARSE_BB
 };
@@ -1135,8 +1213,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_FUNC_HEADER;
+		state = PARSE_MD_OPT_HEADER;
 		break;
+	    case PARSE_MD_OPT_HEADER:
+		if (buffer[0] == 'D') {
+		    rc = parseMD(bc, (unsigned char*)buffer);
+		    if (rc != CL_SUCCESS) {
+			cli_errmsg("Error at bytecode line %u\n", row);
+			return rc;
+		    }
+		    break;
+		}
+		// fall-through
 	    case PARSE_FUNC_HEADER:
 		rc = parseFunctionHeader(bc, current_func, (unsigned char*)buffer);
 		if (rc != CL_SUCCESS) {
@@ -1247,6 +1335,14 @@ void cli_bytecode_destroy(struct cli_bc *bc)
     for (i=0;i<bc->num_globals;i++) {
 	free(bc->globals[i]);
     }
+    for (i=0;i<bc->dbgnode_cnt;i++) {
+	for (j=0;j<bc->dbgnodes[i].numelements;j++) {
+	    struct cli_bc_dbgnode_element *el =  &bc->dbgnodes[i].elements[j];
+	    if (el && el->string)
+		free(el->string);
+	}
+    }
+    free(bc->dbgnodes);
     free(bc->globals);
     free(bc->globaltys);
     if (bc->uses_apis)
diff --git a/libclamav/bytecode.h b/libclamav/bytecode.h
index 9a3754d..c22503b 100644
--- a/libclamav/bytecode.h
+++ b/libclamav/bytecode.h
@@ -32,6 +32,7 @@ struct cli_bc_value;
 struct cli_bc_inst;
 struct cli_bc_type;
 struct cli_bc_engine;
+struct cli_bc_dbgnode;
 struct bitset_tag;
 struct cl_engine;
 
@@ -62,6 +63,8 @@ struct cli_bc {
   char *vnameprefix;
   char **vnames;
   unsigned vnames_cnt;
+  struct cli_bc_dbgnode *dbgnodes;
+  unsigned dbgnode_cnt;
 };
 
 struct cli_all_bc {
diff --git a/libclamav/bytecode_priv.h b/libclamav/bytecode_priv.h
index 583f09f..c7650f5 100644
--- a/libclamav/bytecode_priv.h
+++ b/libclamav/bytecode_priv.h
@@ -85,7 +85,21 @@ struct cli_bc_func {
     struct cli_bc_bb *BB;
     struct cli_bc_inst *allinsts;
     uint64_t *constants;
+    unsigned *dbgnodes;
 };
+
+struct cli_bc_dbgnode_element {
+    unsigned nodeid;
+    char *string;
+    unsigned len;
+    uint64_t constant;
+};
+
+struct cli_bc_dbgnode {
+    unsigned numelements;
+    struct cli_bc_dbgnode_element* elements;
+};
+
 #define MAX_OP ~0u
 struct cli_bc_ctx {
     /* id and params of toplevel function called */
diff --git a/libclamav/c++/bytecode2llvm.cpp b/libclamav/c++/bytecode2llvm.cpp
index f5a8819..9624c17 100644
--- a/libclamav/c++/bytecode2llvm.cpp
+++ b/libclamav/c++/bytecode2llvm.cpp
@@ -210,6 +210,7 @@ private:
     unsigned numArgs;
     DenseMap<unsigned, unsigned> GVoffsetMap;
     DenseMap<unsigned, const Type*> GVtypeMap;
+    std::vector<MDNode*> mdnodes;
 
     Value *getOperand(const struct cli_bc_func *func, const Type *Ty, operand_t operand)
     {
@@ -407,8 +408,44 @@ public:
 	return true;
     }
 
+    MDNode *convertMDNode(unsigned i) {
+	if (i < mdnodes.size()) {
+	    if (mdnodes[i])
+		return mdnodes[i];
+	} else 
+	    mdnodes.resize(i+1);
+	assert(i < mdnodes.size());
+	const struct cli_bc_dbgnode *node = &bc->dbgnodes[i];
+	Value **Vals = new Value*[node->numelements];
+	for (unsigned j=0;j<node->numelements;j++) {
+	    const struct cli_bc_dbgnode_element* el = &node->elements[j];
+	    Value *V;
+	    if (!el->len) {
+		if (el->nodeid == ~0u)
+		    V = 0;
+		else if (el->nodeid)
+		    V = convertMDNode(el->nodeid);
+		else
+		    V = MDString::get(Context, "");
+	    } else if (el->string) {
+		V = MDString::get(Context, StringRef(el->string, el->len));
+	    } else {
+		V = ConstantInt::get(IntegerType::get(Context, el->len),
+				     el->constant);
+	    }
+	    Vals[j] = V;
+	}
+	MDNode *N = MDNode::get(Context, Vals, node->numelements);
+	delete[] Vals;
+	mdnodes[i] = N;
+	return N;
+    }
+
     bool generate() {
 	TypeMap = new LLVMTypeMapper(Context, bc->types + 4, bc->num_types - 5);
+	for (unsigned i=0;i<bc->dbgnode_cnt;i++) {
+	    mdnodes.push_back(convertMDNode(i));
+	}
 
 	for (unsigned i=0;i<cli_apicall_maxglobal - _FIRST_GLOBAL;i++) {
 	    unsigned id = cli_globals[i].globalid;
@@ -590,11 +627,21 @@ public:
 		bool unreachable = false;
 		const struct cli_bc_bb *bb = &func->BB[i];
 		Builder.SetInsertPoint(BB[i]);
+		unsigned c = 0;
 		for (unsigned j=0;j<bb->numInsts;j++) {
 		    const struct cli_bc_inst *inst = &bb->insts[j];
 		    Value *Op0, *Op1, *Op2;
 		    // libclamav has already validated this.
 		    assert(inst->opcode < OP_BC_INVALID && "Invalid opcode");
+		    if (func->dbgnodes) {
+			if (func->dbgnodes[c] != ~0u) {
+			unsigned j = func->dbgnodes[c];
+			assert(j < mdnodes.size());
+			Builder.SetCurrentDebugLocation(mdnodes[j]);
+			} else
+			    Builder.SetCurrentDebugLocation(0);
+		    }
+		    c++;
 		    switch (inst->opcode) {
 			case OP_BC_JMP:
 			case OP_BC_BRANCH:
@@ -1036,7 +1083,7 @@ int cli_bytecode_prepare_jit(struct cli_all_bc *bcs)
 //	EE->RegisterJITEventListener(createOProfileJITEventListener());
 	// Due to LLVM PR4816 only X86 supports non-lazy compilation, disable
 	// for now.
-	// EE->DisableLazyCompilation();
+	EE->DisableLazyCompilation();
 	EE->DisableSymbolSearching();
 
 	FunctionPassManager OurFPM(MP);

-- 
Debian repository for ClamAV



More information about the Pkg-clamav-commits mailing list