socsvn commit: r273169 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw

dpl at FreeBSD.org dpl at FreeBSD.org
Tue Aug 26 14:44:45 UTC 2014


Author: dpl
Date: Tue Aug 26 14:44:44 2014
New Revision: 273169
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=273169

Log:
  Corrected most wrong code, added warnings.

Modified:
  soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc

Modified: soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc
==============================================================================
--- soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc	Tue Aug 26 14:43:46 2014	(r273168)
+++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc	Tue Aug 26 14:44:44 2014	(r273169)
@@ -16,6 +16,7 @@
 #include <llvm/IR/Module.h>
 #include <llvm/IR/Type.h>
 #include <llvm/IR/Value.h>
+#include <llvm/IR/Verifier.h>
 #include <llvm/Support/MemoryBuffer.h>
 #include <llvm/Support/ErrorOr.h>
 #include <llvm/Support/TargetSelect.h>
@@ -49,8 +50,8 @@
 	IRBuilder<> irb;
 
 	// We'll store the BasicBlock objects for each rule here.
-	int rule_number;
-	std::vector<BasicBlock*> blocks;
+	int rulenumber = 1;
+	std::vector<BasicBlock *> rules;
 
 	// Vars Types
 	Type *int8Ty;
@@ -62,7 +63,7 @@
 	// Basic blocks used
 	BasicBlock *entry, *end;
 	BasicBlock *pullup_failed;
-	BasicBlock *startrules;
+	BasicBlock *check_tag;
 	BasicBlock *outer_for_prologue;
 	BasicBlock *inner_for_prologue;
 	BasicBlock *outer_for_epilogue;
@@ -277,6 +278,8 @@
 	}
 
 	// Allocate and initialize LLVM vars.
+	// Note: The type of the object returned by CreateStore
+	// is already a pointer to a given type.
 	void
 	allocaAndInit()
 	{
@@ -284,37 +287,37 @@
 		// Control flow variables.
 		match = irb.CreateAlloca(int32Ty);
 		l = irb.CreateAlloca(int32Ty);
+
 		done = irb.CreateAlloca(int32Ty);
 		irb.CreateStore(ConstantInt::get(int32Ty, 0), done);
+
 		f_pos = irb.CreateAlloca(int32Ty);
 		irb.CreateStore(ConstantInt::get(int32Ty, 0), f_pos);
+
 		retval = irb.CreateAlloca(int32Ty);
 		irb.CreateStore(ConstantInt::get(int32Ty, 0), retval);
-		cmd = irb.CreateAlloca(ipfw_insnPtrTy);
+
+		cmd = irb.CreateAlloca(ipfw_insnTy);
 		tablearg = irb.CreateAlloca(int32Ty);
 		cmdlen = irb.CreateAlloca(int32Ty);
 		skip_or = irb.CreateAlloca(int32Ty);
-		f = irb.CreateAlloca(ip_fwPtrTy);
+		f = irb.CreateAlloca(ip_fwTy);
 
 		// m = args->m (idx: 0)
 		m = irb.CreateAlloca(mbufPtrTy);
-		irb.CreateStore(irb.CreateInBoundsGEP(irb.CreateLoad(args), ConstantInt::get(int32Ty, 0)), m);
+		irb.CreateStore(irb.CreateStructGEP(args, 0), m);
 
 		// ip = (struct ip *)((m)->m_data) (idx: 2)
 		ip = irb.CreateAlloca(ipPtrTy);
-		irb.CreateStore(irb.CreateBitCast(irb.CreateInBoundsGEP(irb.CreateLoad(args), ConstantInt::get(int32Ty, 2)), ipPtrTy), ip);
+		irb.CreateStore(irb.CreateBitCast(irb.CreateStructGEP(irb.CreateLoad(m), 2), ipPtrTy), ip);
 
-#ifdef __FreeBSD__
-		ucred_cache = irb.CreateAlloca(ucredPtrTy); // Init: NULL if type ucred.
-		irb.CreateStore(ConstantPointerNull::get(ucredPtrTy), ucred_cache);
-#else
-		ucred_cache = irb.CreateAlloca(ucredTy);
-#endif
+		ucred_cache = irb.CreateAlloca(ucredTy); // Init: NULL if type ucred.
 
 		ucred_lookup = irb.CreateAlloca(int32Ty);
 		irb.CreateStore(ConstantInt::get(int32Ty, 0), ucred_lookup);
 
-		oif = irb.CreateAlloca(ifnetPtrTy); // Init: args->oif
+		oif = irb.CreateAlloca(ifnetTy); // Init: args->oif
+		irb.CreateLoad(irb.CreateStructGEP(args, 1), oif);
 
 		hlen = irb.CreateAlloca(int32Ty);
 		irb.CreateStore(ConstantInt::get(int32Ty, 0), hlen);
@@ -330,7 +333,7 @@
 		proto = irb.CreateAlloca(int8Ty);
 		irb.CreateStore(ConstantInt::get(int8Ty, 0), proto);
 		// args->f_id.proto = 0 (idx: 6, 5)
-		irb.CreateStore(ConstantInt::get(int8Ty, 0), irb.CreateInBoundsGEP(irb.CreateLoad(args), {ConstantInt::get(int32Ty, 6), ConstantInt::get(int32Ty, 5)} ));
+		irb.CreateStore(ConstantInt::get(int8Ty, 0), irb.CreateStructGEP(irb.CreateStructGEP(args, 6), 5));
 
 		src_port = irb.CreateAlloca(int16Ty);
 		irb.CreateStore(ConstantInt::get(int16Ty, 0), src_port);
@@ -339,11 +342,12 @@
 
 		//src_ip.s_addr = 0;
 		src_ip = irb.CreateAlloca(in_addrTy);
-		irb.CreateStore(ConstantInt::get(int32Ty, 0), irb.CreateInBoundsGEP(src_ip, ConstantInt::get(int32Ty, 0)));
+		irb.CreateStore(ConstantInt::get(int32Ty, 0), irb.CreateStructGEP(src_ip, 0));
 		//dst_ip.s_addr = 0;
 		dst_ip = irb.CreateAlloca(in_addrTy);
-		irb.CreateStore(ConstantInt::get(int32Ty, 0), irb.CreateInBoundsGEP(dst_ip, ConstantInt::get(int32Ty, 0)));
+		irb.CreateStore(ConstantInt::get(int32Ty, 0), irb.CreateStructGEP(dst_ip, 0));
 
+		//iplen = 0;
 		iplen = irb.CreateAlloca(int16Ty);
 		irb.CreateStore(ConstantInt::get(int16Ty, 0), iplen);
 
@@ -351,7 +355,7 @@
 		// m_pkthdr is the 6th element (idx: 5)
 		// len is the 2nd element (idx: 1)
 		pktlen = irb.CreateAlloca(int32Ty);
-		irb.CreateStore(ConstantInt::get(int32Ty, 0), irb.CreateInBoundsGEP(irb.CreateLoad(m), {ConstantInt::get(int32Ty, 5), ConstantInt::get(int32Ty, 1)} ));
+		irb.CreateStore(irb.CreateStructGEP(irb.CreateStructGEP(irb.CreateLoad(m), 5), 1), pktlen);
 
 		etype = irb.CreateAlloca(int16Ty);
 		irb.CreateStore(ConstantInt::get(int32Ty, 0), etype);
@@ -374,6 +378,10 @@
 		irb.CreateStore(ConstantInt::get(int8Ty, 0), icmp6_type);
 		ext_hd = irb.CreateAlloca(int16Ty);
 		irb.CreateStore(ConstantInt::get(int16Ty, 0), ext_hd);
+
+		// If it returns one, goto pullup_failed.
+		// Else, goto first rule.
+		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateCall(inspect_pkt, {args, ip, m, src_ip, dst_ip, src_port, dst_port, etype, ext_hd, iplen, pktlen, is_ipv4, is_ipv6, hlen, proto, icmp6_type, ip6f_mf, offset, ulp}), ConstantInt::get(int32Ty, 1)), pullup_failed, check_tag);
 	}
 
 	void
@@ -418,6 +426,8 @@
 		BasicBlock *jt = BasicBlock::Create(con, "jt", func);
 		BasicBlock *jf = BasicBlock::Create(con, "jf", func);
 
+		irb.SetInsertPoint(check_tag);
+
 		// if (args->rule.slot) {
 		// 	/*
 		// 	 * Packet has already been tagged as a result of a previous
@@ -435,19 +445,19 @@
 		// }
 
 		// if (args->rule.slot)
-		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateInBoundsGEP(args, {ConstantInt::get(int32Ty, 4),ConstantInt::get(int32Ty, 0)}), ConstantInt::get(int32Ty, 0)), nottagged, tagged);
+		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateInBoundsGEP(args, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 4),ConstantInt::get(int32Ty, 0)}), ConstantInt::get(int32Ty, 0)), nottagged, tagged);
 		// if (args->rule.chain_id == chain->id)
 		irb.SetInsertPoint(tagged);
-		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateInBoundsGEP(args, {ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 3)}), irb.CreateInBoundsGEP(chain, ConstantInt::get(int32Ty, 12))), jt, jf);
+		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateInBoundsGEP(args, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 3)}), irb.CreateInBoundsGEP(chain, ConstantInt::get(int32Ty, 12))), jt, jf);
 
 		// f_pos = args->rule.slot;
 		irb.SetInsertPoint(jt);
-		irb.CreateStore(irb.CreateInBoundsGEP(args, {ConstantInt::get(int32Ty, 4),ConstantInt::get(int32Ty, 0)}), f_pos);
+		irb.CreateStore(irb.CreateInBoundsGEP(args, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 4),ConstantInt::get(int32Ty, 0)}), f_pos);
 		irb.CreateBr(nottagged);
 
 		// else fpos = ipfw_find_rule(chain, args->rule.rulenum, args->rule.rule_id)
 		irb.SetInsertPoint(jf);
-		irb.CreateStore(irb.CreateCall3(ipfw_find_rule, chain, irb.CreateInBoundsGEP(args, {ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 1)}), irb.CreateInBoundsGEP(args, {ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 2)})), f_pos);
+		irb.CreateStore(irb.CreateCall3(ipfw_find_rule, chain, irb.CreateInBoundsGEP(args, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 1)}), irb.CreateInBoundsGEP(args, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 2)})), f_pos);
 
 		// Branch to nottagged because it
 		// only finishes the entry BasicBlock.
@@ -456,7 +466,7 @@
 		// else f_pos = 0;
 		// Since f_pos is initialized by default as 0, we only br.
 		irb.SetInsertPoint(nottagged);
-		irb.CreateBr(startrules);
+		irb.CreateBr(rules[rulenumber]);
 	}
 
 	void
@@ -480,11 +490,12 @@
 		// uint32_t tablearg = 0;
 		irb.CreateStore(ConstantInt::get(int32Ty, 0), tablearg);
 
-		// f = chain->map[f_pos];
-		irb.CreateStore(irb.CreateInBoundsGEP(irb.CreateLoad(chain), {ConstantInt::get(int32Ty, 5), f_pos}), f);
+		// f = chain->map[f_pos]; idxs: 5, f_pos
+		irb.CreateStore(irb.CreateInBoundsGEP(irb.CreateLoad(irb.CreateStructGEP(chain, 5)), f_pos), f);
 
 		// if (V_set_disable & (1 << f->set) )
-		irb.CreateCondBr(irb.CreateICmpNE(irb.CreateAnd(set_disable, irb.CreateShl(ConstantInt::get(int32Ty, 1), irb.CreateInBoundsGEP(f, ConstantInt::get(int32Ty, 5)))), ConstantInt::get(int32Ty, 0)), jt, jf);
+		irb.CreateCondBr(irb.CreateICmpNE(irb.CreateAnd(set_disable, irb.CreateShl(ConstantInt::get(int32Ty, 1), irb.CreateStructGEP(f, 5))), ConstantInt::get(int32Ty, 0)), jt, jf);
+
 
 		irb.SetInsertPoint(jt);
 		//		continue;
@@ -521,21 +532,21 @@
 
 		// l = f->cmd_len;
 		// XXX - ask David about types. int l; uint16_t cmd_len;
-		irb.CreateStore(irb.CreateInBoundsGEP(f, ConstantInt::get(int32Ty, 3)), l);
+		irb.CreateStore(irb.CreateInBoundsGEP(f, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 3)}), l);
 		// cmd = f->cmd;
-		irb.CreateStore(irb.CreateInBoundsGEP(f, ConstantInt::get(int32Ty, 11)), cmd);
+		irb.CreateStore(irb.CreateInBoundsGEP(f, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 11)}), cmd);
 		// int match;
 		// match is already allocated.
 
 		// cmdlen = ((cmd)->len & F_LEN_MASK);
-		irb.CreateStore(irb.CreateAnd(irb.CreateInBoundsGEP(cmd, ConstantInt::get(int32Ty, 1)), ConstantInt::get(int8Ty, F_LEN_MASK)), cmdlen);
+		irb.CreateStore(irb.CreateAnd(irb.CreateInBoundsGEP(cmd, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 1)}), ConstantInt::get(int8Ty, F_LEN_MASK)), cmdlen);
 
 		// if (skip_or)
 		irb.CreateCondBr(irb.CreateICmpNE(skip_or, ConstantInt::get(int32Ty, 0)), firstt, firstf);
 
 		irb.SetInsertPoint(firstt);
 		// if ((cmd->len & F_OR) == 0)
-		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateAnd(irb.CreateInBoundsGEP(cmd, ConstantInt::get(int32Ty, 1)), ConstantInt::get(int8Ty, F_OR)), ConstantInt::get(int8Ty, 0)), secondt, secondf);
+		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateAnd(irb.CreateInBoundsGEP(cmd, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 1)}), ConstantInt::get(int8Ty, F_OR)), ConstantInt::get(int8Ty, 0)), secondt, secondf);
 
 		irb.SetInsertPoint(secondt);
 		// skip_or = 0;
@@ -557,6 +568,8 @@
 	void
 	emit_inner_for_epilogue()
 	{
+		BasicBlock *matchnz = BasicBlock::Create(con, "jt", func);
+		BasicBlock *matchz = BasicBlock::Create(con, "jt", func);
 		BasicBlock *jt = BasicBlock::Create(con, "jt", func);
 		BasicBlock *jf = BasicBlock::Create(con, "jf", func);
 		BasicBlock *sec_cond = BasicBlock::Create(con, "sec_cond", func);
@@ -584,11 +597,19 @@
 		irb.SetInsertPoint(inner_for_epilogue);
 
 		// if (cmd->len & F_NOT)
-		irb.CreateCondBr(irb.CreateICmpNE(irb.CreateAnd(irb.CreateInBoundsGEP(cmd, ConstantInt::get(int32Ty, 1)), ConstantInt::get(int8Ty, F_NOT)), ConstantInt::get(int32Ty, 0)), jt, sec_cond);
+		irb.CreateCondBr(irb.CreateICmpNE(irb.CreateAnd(irb.CreateInBoundsGEP(cmd, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 1)}), ConstantInt::get(int8Ty, F_NOT)), ConstantInt::get(int32Ty, 0)), jt, sec_cond);
 
 		irb.SetInsertPoint(jt);
 		// match = !match;
-		irb.CreateStore(irb.CreateNot(match), match);
+		// match = ((match)?0:1);
+		irb.CreateCondBr(irb.CreateICmpNE(match, ConstantInt::get(int32Ty, 0)),matchnz, matchz);
+
+		irb.SetInsertPoint(matchnz);
+		irb.CreateStore(ConstantInt::get(int32Ty, 0), match);
+		irb.CreateBr(sec_cond);
+
+		irb.SetInsertPoint(matchz);
+		irb.CreateStore(ConstantInt::get(int32Ty, 1), match);
 		irb.CreateBr(sec_cond);
 
 		irb.SetInsertPoint(sec_cond);
@@ -597,7 +618,7 @@
 
 		irb.SetInsertPoint(matchnotzero);
 		// if (cmd->len & F_OR)
-		irb.CreateCondBr(irb.CreateICmpNE(irb.CreateAnd(irb.CreateInBoundsGEP(cmd, ConstantInt::get(int32Ty, 1)), ConstantInt::get(int8Ty, F_OR)), ConstantInt::get(int32Ty, 0)), is_or, outer_for_epilogue);
+		irb.CreateCondBr(irb.CreateICmpNE(irb.CreateAnd(irb.CreateInBoundsGEP(cmd, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 1)}), ConstantInt::get(int8Ty, F_OR)), ConstantInt::get(int32Ty, 0)), is_or, outer_for_epilogue);
 
 		irb.SetInsertPoint(is_or);
 		// skip_or = 1;
@@ -607,7 +628,7 @@
 		irb.SetInsertPoint(matchzero);
 		// if (!(cmd->len & F_OR)) /* not an OR block, */
 		//     break;
-		irb.CreateCondBr(irb.CreateICmpNE(irb.CreateNot(irb.CreateAnd(irb.CreateInBoundsGEP(cmd, ConstantInt::get(int32Ty, 1)), ConstantInt::get(int8Ty, F_OR))), ConstantInt::get(int32Ty, 0)), next /* break */, outer_for_epilogue);
+		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateAnd(irb.CreateInBoundsGEP(cmd, {ConstantInt::get(int32Ty, 0), ConstantInt::get(int32Ty, 1)}), ConstantInt::get(int8Ty, F_OR)), ConstantInt::get(int32Ty, 0)), next /* break */, outer_for_epilogue);
 	}
 
 	// This code gets executed at the end of inner loop.
@@ -615,19 +636,20 @@
 	void
 	emit_outer_for_epilogue()
 	{
+		irb.SetInsertPoint(outer_for_epilogue);
+
 		// f_pos++, increment of the for loop.
 		irb.CreateStore(irb.CreateAdd(f_pos, ConstantInt::get(int32Ty, 1)), f_pos);
 
 		// if (done)
 		//		break;
 		irb.CreateCondBr(irb.CreateICmpNE(done, ConstantInt::get(int32Ty, 0)), end, next);
-
 	}
 
 	void
 	emit_end()
 	{
-		Value *rule, *timestamp, *str;
+		Value *rule, *time_uptime, *str;
 
 		BasicBlock *jt = BasicBlock::Create(con, "jt", func);
 		BasicBlock *jf = BasicBlock::Create(con, "jf", func);
@@ -653,7 +675,7 @@
 
 		irb.SetInsertPoint(end);
 		// We need to get the timestamp variable.
-		timestamp = mod->getGlobalVariable("timestamp");
+		time_uptime = mod->getGlobalVariable("time_uptime");
 		str = irb.CreateGlobalString("ipfw: ouch!, skip past end of rules, denying packet\n");
 
 		// if (done)
@@ -662,18 +684,24 @@
 		irb.SetInsertPoint(jt);
 		// struct ip_fw *rule = chain->map[f_pos];
 		rule = irb.CreateAlloca(ip_fwPtrTy);
-		irb.CreateStore(irb.CreateInBoundsGEP(chain, {ConstantInt::get(int32Ty, 5), f_pos}), rule);
+		irb.CreateStore(irb.CreateInBoundsGEP(irb.CreateLoad(irb.CreateStructGEP(chain, 5)), f_pos), rule);
 
 		// uint64_t pcnt;
 		// (rule)->pcnt++;
-		irb.CreateStore(irb.CreateInBoundsGEP(rule, ConstantInt::get(int32Ty,8)), irb.CreateAdd(irb.CreateInBoundsGEP(rule, ConstantInt::get(int32Ty, 8)), ConstantInt::get(int64Ty, 1)));
+		Value *pcnt = irb.CreateStructGEP(irb.CreateLoad(rule), 8);
+		irb.CreateStore(irb.CreateAdd(pcnt, ConstantInt::get(pcnt->getType(), 1)), pcnt);
 		// uint64_t bnct;
 		// (rule)->bcnt += pktlen;
-		irb.CreateStore(irb.CreateInBoundsGEP(rule, ConstantInt::get(int32Ty, 9)), irb.CreateAdd(irb.CreateInBoundsGEP(rule, ConstantInt::get(int32Ty, 9)), pktlen));
+		// XXX pktlen->getType(): int32Ty
+		Value *bcnt = irb.CreateStructGEP(irb.CreateLoad(rule), 9);
+		irb.CreateStore(irb.CreateAdd(bcnt, pktlen), bcnt);
 
 		// (rule)->timestamp = time_uptime;
 		// uint32_t timestamp;
-		irb.CreateStore(irb.CreateInBoundsGEP(rule, ConstantInt::get(int32Ty, 10)), timestamp);
+		// XXX timestamp->getType(): int32Ty
+		// XXX time_uptime: int64Ty
+		Value *timestamp = irb.CreateStructGEP(irb.CreateLoad(rule), 10);
+		irb.CreateStore(time_uptime, timestamp);
 
 		irb.SetInsertPoint(jf);
 		//	retval = IP_FW_DENY;
@@ -703,7 +731,7 @@
 	}
 
 	public:
-	ipfwJIT(): irb(con)
+	ipfwJIT(int rulesnumber): irb(con)
 	{
 		// Create the module and load the code.
 		mod = loadbc("ip_fw_rules.bc");
@@ -711,17 +739,21 @@
 		func = mod->getFunction("ipfw_chk_jit");
 		func->setLinkage(GlobalValue::ExternalLinkage);
 
-		// Create statics BasicBlocks.
+		// Create static BasicBlocks.
 		// The entry basic block contains all the initialization 
 		// and allocation of resources, and a basic check done 
 		// before start emmiting the rules code.
 		entry = BasicBlock::Create(con, "entry", func);
+		check_tag = BasicBlock::Create(con, "check_tag", func);
+		end = BasicBlock::Create(con, "end", func);
+
+		// Initialize the vector.
+		rules = std::vector<BasicBlock *>(rulesnumber + 1);
+		rules[rulenumber] = BasicBlock::Create(con, "rule", func);
+		start_rule();
+
 		// This is equivalent to the pullup_failed tag.
 		pullup_failed = BasicBlock::Create(con, "pullup_failed", func);
-		// This will be the first BasicBlock to store our emmited code.
-		startrules = BasicBlock::Create(con, "startrules", func);
-		// This will be executed at the end of ipfw_chk_jit().
-		end = BasicBlock::Create(con, "end", func);
 
 		//Snippets of code to be executed when iterating through the rules.
 		outer_for_prologue = BasicBlock::Create(con, "outer_for_prologue", func);
@@ -731,8 +763,9 @@
 
 		// Get struct types, and store vars
 		setEnv();
-		allocaAndInit();
 
+		// Start compilation
+		allocaAndInit();
 		emit_check_tag();
 		emit_pullup_failed();
 
@@ -743,6 +776,11 @@
 		emit_outer_for_epilogue();
 		emit_end();
 
+		verifyFunction(*func);
+
+
+		verifyModule(*mod);
+		mod->dump();
 	}
 	~ipfwJIT()
 	{
@@ -753,6 +791,7 @@
 	void
 	optimize()
 	{
+		// We don't need it anymore.
 		Function *vf = mod->getFunction("voidfunction");
 		vf->eraseFromParent();
 	}
@@ -764,18 +803,26 @@
 		return ((funcptr)NULL);
 	}
 
-	// Call the function that fills in some vars.
 	void
-	emit_lookpkt_call()
+	start_rule()
 	{
-		// If it returns one, goto pullup_failed.
-		// Else, goto starrules.
-		irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateCall(inspect_pkt, {args, ip, m, src_ip, dst_ip, src_port, dst_port, etype, ext_hd, iplen, pktlen, is_ipv4, is_ipv6, hlen, proto, icmp6_type, ip6f_mf, offset, ulp}), ConstantInt::get(int32Ty, 1)), pullup_failed, startrules);
+		// This will be the first BasicBlock to store our emmited code.
+		rules[rulenumber] = BasicBlock::Create(con, "rule", func);
+		next = rules[rulenumber+1] = BasicBlock::Create(con, "rule", func);
 	}
 
 	void
+	end_rule()
+	{
+		// We're on the next rule now.
+		rulenumber++;
+	}
+
+	// Also initialized the rules vector.
+	void
 	emit_outer_for_prologue_call()
 	{
+		irb.SetInsertPoint(rules[rulenumber]);
 		irb.CreateBr(outer_for_prologue);
 	}
 
@@ -843,10 +890,7 @@
 	InitializeNativeTarget();
 	LLVMLinkInJIT();
 
-	ipfwJIT compiler;
-
-	// Fill up needed local variables.
-	compiler.emit_lookpkt_call();
+	ipfwJIT compiler(chain->n_rules);
 
 	// Iterate through the rules.
 	int pktlen = args->m->m_pkthdr.len;
@@ -860,6 +904,8 @@
 
 		f = chain->map[f_pos];
 
+		// Rule start.
+		compiler.start_rule();
 		compiler.emit_outer_for_prologue_call();
 
 		// For each different command.
@@ -1251,7 +1297,9 @@
 			} /* end of switch() on opcodes */
 			compiler.emit_inner_for_prologue_call();
 		}	/* end of inner loop, scan opcodes */
-		compiler.emit_outer_for_prologue_call();
+		// Rule ends.
+		compiler.emit_outer_for_epilogue_call();
+		compiler.end_rule();
 	}		/* end of outer for, scan rules */
 
 	compiler.emit_end_call();


More information about the svn-soc-all mailing list