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