Date: Mon, 18 Aug 2014 10:23:42 GMT From: dpl@FreeBSD.org To: svn-soc-all@FreeBSD.org Subject: socsvn commit: r272599 - in soc2014/dpl/netmap-ipfwjit: . sys/netpfil/ipfw Message-ID: <201408181023.s7IANg2f002229@socsvn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: dpl Date: Mon Aug 18 10:23:41 2014 New Revision: 272599 URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272599 Log: Added all the flow control necessary to JIT compile the rules. Modified: soc2014/dpl/netmap-ipfwjit/Makefile.kipfw soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Modified: soc2014/dpl/netmap-ipfwjit/Makefile.kipfw ============================================================================== --- soc2014/dpl/netmap-ipfwjit/Makefile.kipfw Mon Aug 18 09:40:19 2014 (r272598) +++ soc2014/dpl/netmap-ipfwjit/Makefile.kipfw Mon Aug 18 10:23:41 2014 (r272599) @@ -141,7 +141,7 @@ EFILES = $(foreach i,$(EDIRS),$(subst $(empty) , $(i)/, $(EFILES_$(i): = ))) BCFLAGS=-emit-llvm -c -CXXFLAGS=`llvm-config-devel --cxxflags` +CXXFLAGS= -g `llvm-config-devel --cxxflags` include_e: -@echo "Building $(OBJPATH)/include_e ..." @@ -169,7 +169,7 @@ $(HIDE)clang++ -o $@ $^ $(LIBS) jit.o: jit.cc ../ip_fw_rules.bc - clang++ $(J_CFLAGS) $(CXXFLAGS) ../sys/netpfil/ipfw/jit.cc -o ./jit.o + clang++ -v $(J_CFLAGS) $(CXXFLAGS) $(LIBS) ../sys/netpfil/ipfw/jit.cc -o ./jit.o clean: -rm -f *.o $(DN) $(MOD) Modified: soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc ============================================================================== --- soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Mon Aug 18 09:40:19 2014 (r272598) +++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Mon Aug 18 10:23:41 2014 (r272599) @@ -8,9 +8,14 @@ #include <llvm/Bitcode/ReaderWriter.h> #include <llvm/CodeGen/MachineCodeInfo.h> #include <llvm/ExecutionEngine/ExecutionEngine.h> +#include <llvm/IR/BasicBlock.h> +#include <llvm/IR/Constants.h> +#include <llvm/IR/Function.h> #include <llvm/IR/IRBuilder.h> #include <llvm/IR/LLVMContext.h> #include <llvm/IR/Module.h> +#include <llvm/IR/Type.h> +#include <llvm/IR/Value.h> #include <llvm/Support/MemoryBuffer.h> #include <llvm/Support/ErrorOr.h> #define _KERNEL @@ -50,13 +55,18 @@ Type *int8Ty; Type *int16Ty; Type *int32Ty; + Type *int64Ty; PointerType *int8PtrTy; // Basic blocks used - BasicBlock *entry; + BasicBlock *entry, *end; BasicBlock *pullup_failed; BasicBlock *startrules; - BasicBlock *end; + BasicBlock *outer_for_prologue; + BasicBlock *inner_for_prologue; + BasicBlock *outer_for_epilogue; + BasicBlock *inner_for_epilogue; + // This BB is the next emitted rule, always. BasicBlock *next; @@ -70,11 +80,16 @@ Value *done; Value *f_pos; Value *retval; + Value *cmd; + Value *cmdlen; + Value *tablearg; + Value *skip_or; + Value *f; // Packet matching variables. Value *m; Value *ip; - Value *ucred; + Value *ucred_cache; Value *ucred_lookup; Value *oif; Value *hlen; //unsigned @@ -127,6 +142,7 @@ // Not pkg-filtering related funcs. Function *printfFunc; Function *ipfw_find_rule; + Function *crfree; // Used structs. StructType *ifnetTy; @@ -135,7 +151,7 @@ StructType *ip_fw_argsTy; StructType *ip_fw_chainTy; StructType *ip_fwTy; - StructType *ip_fw_insnTy; + StructType *ipfw_insnTy; StructType *ipfw_dyn_ruleTy; StructType *ipfw_insn_ifTy; StructType *mbufTy; @@ -148,7 +164,7 @@ PointerType *ip_fw_argsPtrTy; PointerType *ip_fw_chainPtrTy; PointerType *ip_fwPtrTy; - PointerType *ip_fw_insnPtrTy; + PointerType *ipfw_insnPtrTy; PointerType *ipfw_dyn_rulePtrTy; PointerType *ipfw_insn_ifPtrTy; PointerType *mbufPtrTy; @@ -193,6 +209,7 @@ int8Ty = Type::getInt8Ty(con); int16Ty = Type::getInt16Ty(con); int32Ty = Type::getInt32Ty(con); + int64Ty = Type::getInt64Ty(con); int8PtrTy = PointerType::getUnqual(int8Ty); // Get StrucType from bitcode. @@ -203,7 +220,7 @@ ip_fw_argsTy = mod->getTypeByName("ip_fw_args"); ip_fw_chainTy = mod->getTypeByName("ip_fw_chain"); ip_fwTy = mod->getTypeByName("ip_fw"); - ip_fw_insnTy = mod->getTypeByName("_ip_fw_insn"); + ipfw_insnTy = mod->getTypeByName("_ipfw_insn"); ipfw_insn_ifTy = mod->getTypeByName("_ipfw_insn_if"); mbufTy = mod->getTypeByName("mbuf"); #ifdef __FreeBSD__ @@ -220,7 +237,7 @@ ip_fw_argsPtrTy = PointerType::get(ip_fw_argsTy, 0); ip_fw_chainPtrTy = PointerType::get(ip_fw_chainTy, 0); ip_fwPtrTy = PointerType::get(ip_fwTy, 0); - ip_fw_insnPtrTy = PointerType::get(ip_fw_insnTy, 0); + ipfw_insnPtrTy = PointerType::get(ipfw_insnTy, 0); ipfw_insn_ifPtrTy = PointerType::get(ipfw_insn_ifTy, 0); mbufPtrTy = PointerType::get(mbufTy, 0); #ifdef __FreeBSD__ @@ -253,12 +270,15 @@ // Functions declared at bitcode. printfFunc = mod->getFunction("printf"); ipfw_find_rule = mod->getFunction("ipfw_find_rule"); + crfree = mod->getFunction("crfree"); } - // Allocate and initialize vars. + // Allocate and initialize LLVM vars. void allocaAndInit(struct ip_fw_args *args, struct ip_fw_chain *chain) { + irb.SetInsertPoint(entry); + // Control flow variables. match = irb.CreateAlloca(int32Ty); l = irb.CreateAlloca(int32Ty); done = irb.CreateAlloca(int32Ty); @@ -267,6 +287,11 @@ irb.CreateStore(ConstantInt::get(int32Ty, 0), f_pos); retval = irb.CreateAlloca(int32Ty); irb.CreateStore(ConstantInt::get(int32Ty, 0), retval); + cmd = irb.CreateAlloca(ipfw_insnPtrTy); + tablearg = irb.CreateAlloca(int32Ty); + cmdlen = irb.CreateAlloca(int32Ty); + skip_or = irb.CreateAlloca(int32Ty); + f = irb.CreateAlloca(ip_fwPtrTy); // m = args->m (idx: 0) m = irb.CreateAlloca(mbufPtrTy); @@ -277,10 +302,10 @@ irb.CreateStore(irb.CreateBitCast(irb.CreateInBoundsGEP(argsptr, ConstantInt::get(int32Ty, 2)), ipPtrTy), ip); #ifdef __FreeBSD__ - ucred = irb.CreateAlloca(ucredPtrTy); // Init: NULL if type ucred. - irb.CreateStore(ConstantPointerNull::get(ucredPtrTy), ucred); + ucred_cache = irb.CreateAlloca(ucredPtrTy); // Init: NULL if type ucred. + irb.CreateStore(ConstantPointerNull::get(ucredPtrTy), ucred_cache); #else - ucred = irb.CreateAlloca(ucredTy); + ucred_cache = irb.CreateAlloca(ucredTy); #endif ucred_lookup = irb.CreateAlloca(int32Ty); @@ -352,7 +377,9 @@ emit_pullup_failed() { Value *is_verbose, *str; - BasicBlock *print, *ret; + + BasicBlock *print = BasicBlock::Create(con, "print", func); + BasicBlock *ret = BasicBlock::Create(con, "ret", func); // VNET_DECLARE(int, fw_verbose); // #define V_fw_verbose VNET(fw_verbose) @@ -366,6 +393,8 @@ is_verbose = mod->getGlobalVariable("fw_verbose"); str = irb.CreateGlobalString("ipfw: pullup failed\n"); + irb.SetInsertPoint(pullup_failed); + // if (V_fw_verbose) irb.CreateCondBr(irb.CreateICmpEQ(is_verbose, ConstantInt::get(int32Ty, 0)), ret, print); // printf("ipfw: pullup failed\n"); @@ -381,8 +410,10 @@ void emit_check_tag() { - BasicBlock *tagged, *nottagged; - BasicBlock *yes, *no; + BasicBlock *tagged = BasicBlock::Create(con, "tagged", func); + BasicBlock *nottagged = BasicBlock::Create(con, "nottagged", func); + BasicBlock *jt = BasicBlock::Create(con, "jt", func); + BasicBlock *jf = BasicBlock::Create(con, "jf", func); // if (args->rule.slot) { // /* @@ -404,15 +435,15 @@ irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateInBoundsGEP(argsptr, {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(argsptr, {ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 3)}), irb.CreateInBoundsGEP(chainptr, ConstantInt::get(int32Ty, 12))), yes, no); + irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateInBoundsGEP(argsptr, {ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 3)}), irb.CreateInBoundsGEP(chainptr, ConstantInt::get(int32Ty, 12))), jt, jf); // f_pos = args->rule.slot; - irb.SetInsertPoint(yes); + irb.SetInsertPoint(jt); irb.CreateStore(irb.CreateInBoundsGEP(argsptr, {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(no); + irb.SetInsertPoint(jf); irb.CreateStore(irb.CreateCall3(ipfw_find_rule, chainptr, irb.CreateInBoundsGEP(argsptr, {ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 1)}), irb.CreateInBoundsGEP(argsptr, {ConstantInt::get(int32Ty, 4), ConstantInt::get(int32Ty, 2)})), f_pos); // Branch to nottagged because it @@ -425,6 +456,249 @@ irb.CreateBr(startrules); } + void + emit_outer_for_prologue() + { + BasicBlock *jt = BasicBlock::Create(con, "jt", func); + BasicBlock *jf = BasicBlock::Create(con, "jf", func); + Value *set_disable = mod->getGlobalVariable("set_disable"); + + // All this variables are already allocated. + // ipfw_insn *cmd; + // uint32_t tablearg = 0; + // int l, cmdlen, skip_or; /* skip rest of OR block */ + // struct ip_fw *f; + // f = chain->map[f_pos]; + // if (V_set_disable & (1 << f->set) ) + // continue; + // skip_or = 0; + + irb.SetInsertPoint(outer_for_prologue); + // uint32_t tablearg = 0; + irb.CreateStore(ConstantInt::get(int32Ty, 0), tablearg); + + // f = chain->map[f_pos]; + irb.CreateStore(irb.CreateInBoundsGEP(chainptr, {ConstantInt::get(int32Ty, 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.SetInsertPoint(jt); + // continue; + irb.CreateBr(next); + + // skip_or = 0; + irb.SetInsertPoint(jf); + irb.CreateStore(ConstantInt::get(int32Ty, 0), skip_or); + + irb.CreateBr(inner_for_prologue); + } + + void + emit_inner_for_prologue() + { + BasicBlock *firstt = BasicBlock::Create(con, "firstt", func); + BasicBlock *firstf = BasicBlock::Create(con, "firstf", func); + BasicBlock *secondt = BasicBlock::Create(con, "secondt", func); + BasicBlock *secondf = BasicBlock::Create(con, "secondf", func); + + // The first to are the intializers of the for loop. + // l = f->cmd_len; + // cmd = f->cmd; + // + // int match; + // cmdlen = F_LEN(cmd); + // if (skip_or) { /* skip this instruction */ + // if ((cmd->len & F_OR) == 0) + // skip_or = 0; /* next one is good */ + // continue; + // } + // match = 0; /* set to 1 if we succeed */ + irb.SetInsertPoint(inner_for_prologue); + + // 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); + // cmd = f->cmd; + irb.CreateStore(irb.CreateInBoundsGEP(f, 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); + + // 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.SetInsertPoint(secondt); + // skip_or = 0; + irb.CreateStore(ConstantInt::get(int32Ty, 0), skip_or); + irb.CreateBr(secondf); + + irb.SetInsertPoint(secondf); + // continue; + irb.CreateBr(next); + + irb.SetInsertPoint(firstf); + // match = 0; + irb.CreateStore(ConstantInt::get(int32Ty, 0), match); + + irb.CreateBr(inner_for_epilogue); + } + + // We get here ar the end of switch() on opcodes. + void + emit_inner_for_epilogue() + { + BasicBlock *jt = BasicBlock::Create(con, "jt", func); + BasicBlock *jf = BasicBlock::Create(con, "jf", func); + BasicBlock *sec_cond = BasicBlock::Create(con, "sec_cond", func); + BasicBlock *matchzero = BasicBlock::Create(con, "matchzero", func); + BasicBlock *matchnotzero = BasicBlock::Create(con, "matchnotzero", func); + BasicBlock *is_or = BasicBlock::Create(con, "is_or", func); + BasicBlock *is_not_or = BasicBlock::Create(con, "is_not_or", func); + + // This are the increments of the for loop. + // l -= cmdlen, cmd += cmdlen; + irb.CreateStore(irb.CreateNSWSub(l, cmdlen), l); + irb.CreateStore(irb.CreateAdd(cmd, cmdlen), cmd); + + // if (cmd->len & F_NOT) + // match = !match; + // + // if (match) { + // if (cmd->len & F_OR) + // skip_or = 1; + // } else { + // if (!(cmd->len & F_OR)) /* not an OR block, */ + // break; /* try next rule */ + // } + + 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.SetInsertPoint(jt); + // match = !match; + irb.CreateStore(irb.CreateNot(match), match); + irb.CreateBr(sec_cond); + + irb.SetInsertPoint(sec_cond); + // if (match) + irb.CreateCondBr(irb.CreateICmpNE(match, ConstantInt::get(int32Ty, 0)), matchnotzero, matchzero); + + 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.SetInsertPoint(is_or); + // skip_or = 1; + irb.CreateStore(ConstantInt::get(int32Ty, 1), skip_or); + irb.CreateBr(outer_for_epilogue); + + 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); + } + + // This code gets executed at the end of inner loop. + // In this context, break means goto end, else continue loop. + void + emit_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; + + BasicBlock *jt = BasicBlock::Create(con, "jt", func); + BasicBlock *jf = BasicBlock::Create(con, "jf", func); + BasicBlock *ret = BasicBlock::Create(con, "ret", func); + + // if (done) { + // struct ip_fw *rule = chain->map[f_pos]; + // /* Update statistics */ + // (rule)->pcnt++; + // (rule)->bcnt += pktlen; + // (rule)->timestamp = time_uptime; + // } else { + // retval = IP_FW_DENY; + // printf("ipfw: ouch!, skip past end of rules, denying packet\n"); + // } + // + // #ifdef __FreeBSD__ + // if (ucred_cache != NULL) + // crfree(ucred_cache); + // #endif + // + // return (retval); + + irb.SetInsertPoint(end); + // We need to get the timestamp variable. + timestamp = mod->getGlobalVariable("timestamp"); + str = irb.CreateGlobalString("ipfw: ouch!, skip past end of rules, denying packet\n"); + + // if (done) + irb.CreateCondBr(irb.CreateICmpNE(done, ConstantInt::get(int32Ty, 0)), jt, jf); + + irb.SetInsertPoint(jt); + // struct ip_fw *rule = chain->map[f_pos]; + rule = irb.CreateAlloca(ip_fwPtrTy); + irb.CreateStore(irb.CreateInBoundsGEP(chainptr, {ConstantInt::get(int32Ty, 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))); + // 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)); + + // (rule)->timestamp = time_uptime; + // uint32_t timestamp; + irb.CreateStore(irb.CreateInBoundsGEP(rule, ConstantInt::get(int32Ty, 10)), timestamp); + + irb.SetInsertPoint(jf); + // retval = IP_FW_DENY; + // printf("ipfw: ouch!, skip past end of rules, denying packet\n"); + irb.CreateStore(ConstantInt::get(int32Ty, IP_FW_DENY), retval); + irb.CreateCall(printfFunc, str); +#ifndef __FreeBSD__ + irb.CreateBr(ret); +#endif + +#ifdef __FreeBSD__ + { + irb.SetInsertPoint(end); + BasicBlock *cache_nnull; + // if (ucred_cache != NULL) + irb.CreateCondBr(irb.CreateICmpNE(ucred_cache, ConstantPointerNull::get(ucredPtrTy)), cache_nnull, ret); + + irb.SetInsertPoint(cache_nnull); + // crfree(ucred_cache); + irb.CreateCall(crfree, ucred_cache); + irb.CreateBr(ret); + } +#endif + + irb.SetInsertPoint(ret); + irb.CreateRet(retval); + } + public: ipfwJIT(struct ip_fw_args *args, struct ip_fw_chain *chain): irb(con) { @@ -446,15 +720,26 @@ // 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); + inner_for_prologue = BasicBlock::Create(con, "inner_for_prologue", func); + inner_for_epilogue = BasicBlock::Create(con, "inner_for_epilogue", func); + outer_for_epilogue = BasicBlock::Create(con, "outer_for_epilogue", func); + // Get struct types, and store vars - irb.SetInsertPoint(entry); setEnv(); allocaAndInit(args, chain); emit_check_tag(); - - irb.SetInsertPoint(pullup_failed); emit_pullup_failed(); + + // Snippets of code to be used for each iteration. + emit_outer_for_prologue(); + emit_inner_for_prologue(); + emit_inner_for_epilogue(); + emit_outer_for_epilogue(); + emit_end(); + } ~ipfwJIT() { @@ -477,60 +762,41 @@ // Call the function that fills in some vars. void - emit_lookpkt() + emit_lookpkt_call() { // If it returns one, goto pullup_failed. // Else, goto starrules. irb.CreateCondBr(irb.CreateICmpEQ(irb.CreateCall(inspect_pkt, {argsptr, 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); - return; } - // We get here ar the end of switch() on opcodes. - // XXX void - emit_end_switch() + emit_outer_for_prologue_call() { - // /* if we get here with l=0, then match is irrelevant. */ - // if (cmd->len & F_NOT) - // match = !match; + irb.CreateBr(outer_for_prologue); + } - // if (match) { - // if (cmd->len & F_OR) - // skip_or = 1; - // } else { - // if (!(cmd->len & F_OR)) /* not an OR block, */ - // break; /* try next rule */ - // } + void + emit_inner_for_prologue_call() + { + irb.CreateBr(inner_for_prologue); } - // This code gets executed at the end of inner loop. - // In this context, break means goto end, else continue loop. void - emit_end_opcodes() + emit_inner_for_epilogue_call() { - // if (done) - // break; - irb.CreateCondBr(irb.CreateCmpNE(done, ConstantInt::get(int32Ty, 0)), end, next); + irb.CreateBr(inner_for_epilogue); } - // This will emit some code executed at the end. - // And set up basic blocks, if necessary. - // XXX void - emit_end() + emit_outer_for_epilogue_call() { - // if (done) { - // struct ip_fw *rule = chain->map[f_pos]; - // /* Update statistics */ - // (rule)->pcnt++; - // (rule)->bcnt += pktlen; - // (rule)->timestamp = time_uptime; - // } else { - // retval = IP_FW_DENY; - // printf("ipfw: ouch!, skip past end of rules, denying packet\n"); - // } + irb.CreateBr(outer_for_epilogue); + } - irb.SetInsertPoint(end); + void + emit_end_call() + { + irb.CreateBr(end); } // Rules @@ -567,13 +833,13 @@ extern "C" funcptr compile_code(struct ip_fw_args *args, struct ip_fw_chain *chain) { - ipfwJIT comp(args, chain); + ipfwJIT compiler(args, chain); int res; int f_pos = 0; - // Fill up needed variables type. - comp.emit_lookpkt(); + // Fill up needed local variables. + compiler.emit_lookpkt_call(); // Iterate through the rules. int pktlen = args->m->m_pkthdr.len; @@ -587,208 +853,211 @@ f = chain->map[f_pos]; + compiler.emit_outer_for_prologue_call(); + // For each different command. for (l = f->cmd_len, cmd = f->cmd ; l > 0 ; l -= cmdlen, cmd += cmdlen) { /* check_body: */ cmdlen = F_LEN(cmd); + compiler.emit_inner_for_prologue_call(); switch (cmd->opcode) { case O_NOP: - comp.emit_nop(); + compiler.emit_nop(); break; case O_FORWARD_MAC: - comp.emit_forward_mac(cmd->opcode); + compiler.emit_forward_mac(cmd->opcode); break; case O_GID: case O_UID: case O_JAIL: - comp.emit_jail(); + compiler.emit_jail(); break; case O_RECV: - comp.emit_recv(); + compiler.emit_recv(); break; /* XXX case O_XMIT: - comp.emit_xmit(); + compiler.emit_xmit(); break; case O_VIA: - comp.emit_via(); + compiler.emit_via(); break; case O_MACADDR2: - comp.emit_macaddr2(); + compiler.emit_macaddr2(); break; case O_MAC_TYPE: - comp.emit_mac_type(); + compiler.emit_mac_type(); break; case O_FRAG: - comp.emit_frag(); + compiler.emit_frag(); break; case O_IN: - comp.emit_in(); + compiler.emit_in(); break; case O_LAYER2: - comp.emit_layer2(); + compiler.emit_layer2(); break; case O_DIVERTED: - comp.emit_diverted(); + compiler.emit_diverted(); break; case O_PROTO: - comp.emit_proto(); + compiler.emit_proto(); break; case O_IP_SRC: - comp.emit_ip_src(); + compiler.emit_ip_src(); break; case O_IP_SRC_LOOKUP: case O_IP_DST_LOOKUP: - comp.emit_ip_dst_lookup(); + compiler.emit_ip_dst_lookup(); break; case O_IP_SRC_MASK: case O_IP_DST_MASK: - comp.emit_ip_dst_mask(); + compiler.emit_ip_dst_mask(); break; case O_IP_SRC_ME: - comp.emit_ip_src_me(); + compiler.emit_ip_src_me(); #ifdef INET6 /* FALLTHROUGH */ /* XXX case O_IP6_SRC_ME: - comp.emit_ip6_src_me(); + compiler.emit_ip6_src_me(); #endif break; case O_IP_DST_SET: case O_IP_SRC_SET: - comp.emit_ip_src_set(); + compiler.emit_ip_src_set(); break; case O_IP_DST: - comp.emit_ip_dst(); + compiler.emit_ip_dst(); break; case O_IP_DST_ME: - comp.emit_ip_dst_me(); + compiler.emit_ip_dst_me(); #ifdef INET6 /* FALLTHROUGH */ /* XXX case O_IP6_DST_ME: - comp.emit_ip6_dst_me(); + compiler.emit_ip6_dst_me(); #endif break; case O_IP_SRCPORT: case O_IP_DSTPORT: - comp.emit_ip_dstport(); + compiler.emit_ip_dstport(); break; case O_ICMPTYPE: - comp.emit_icmptype(); + compiler.emit_icmptype(); break; #ifdef INET6 case O_ICMP6TYPE: - comp.emit_icmp6type(); + compiler.emit_icmp6type(); break; #endif /* INET6 */ /* case O_IPOPT: - comp.emit_ipopt(); + compiler.emit_ipopt(); break; case O_IPVER: - comp.emit_ipver(); + compiler.emit_ipver(); break; case O_IPID: case O_IPLEN: case O_IPTTL: - comp.emit_ipttl(); + compiler.emit_ipttl(); break; case O_IPPRECEDENCE: - comp.emit_ipprecedence(); + compiler.emit_ipprecedence(); break; case O_IPTOS: - comp.emit_iptos(); + compiler.emit_iptos(); break; case O_DSCP: - comp.emit_dscp(); + compiler.emit_dscp(); break; case O_TCPDATALEN: - comp.emit_tcpdatalen(); + compiler.emit_tcpdatalen(); break; case O_TCPFLAGS: - comp.emit_tcpflags(); + compiler.emit_tcpflags(); break; case O_TCPOPTS: - comp.emit_tcpopts(); + compiler.emit_tcpopts(); break; case O_TCPSEQ: - comp.emit_tcpseq(); + compiler.emit_tcpseq(); break; case O_TCPACK: - comp.emit_tcpack(); + compiler.emit_tcpack(); break; case O_TCPWIN: - comp.emit_tcpwin(); + compiler.emit_tcpwin(); break; case O_ESTAB: - comp.emit_estab(); + compiler.emit_estab(); break; case O_ALTQ: - comp.emit_altq(); + compiler.emit_altq(); break; case O_LOG: - comp.emit_log(); + compiler.emit_log(); break; case O_PROB: - comp.emit_prob(); + compiler.emit_prob(); break; case O_VERREVPATH: - comp.emit_verrevpath(); + compiler.emit_verrevpath(); break; case O_VERSRCREACH: - comp.emit_versrcreach(); + compiler.emit_versrcreach(); break; case O_ANTISPOOF: - comp.emit_antispoof(); + compiler.emit_antispoof(); break; case O_IPSEC: #ifdef IPSEC - comp.emit_ipsec(); + compiler.emit_ipsec(); #endif /* otherwise no match */ /* XXX @@ -796,50 +1065,50 @@ #ifdef INET6 case O_IP6_SRC: - comp.emit_ip6_src(); + compiler.emit_ip6_src(); break; case O_IP6_DST: - comp.emit_ip6_dst(); + compiler.emit_ip6_dst(); break; case O_IP6_SRC_MASK: case O_IP6_DST_MASK: - comp.emit_ip6_dst_mask(); + compiler.emit_ip6_dst_mask(); break; case O_FLOW6ID: - comp.emit_flow6id(); + compiler.emit_flow6id(); break; case O_EXT_HDR: - comp.emit_ext_hdr(); + compiler.emit_ext_hdr(); break; case O_IP6: - comp.emit_ip6(); + compiler.emit_ip6(); break; #endif case O_IP4: - comp.emit_ip4(); + compiler.emit_ip4(); break; case O_TAG: - comp.emit_tag(); + compiler.emit_tag(); break; case O_FIB: /* try match the specified fib */ /* XXX - comp.emit_fib(); + compiler.emit_fib(); break; case O_SOCKARG: - comp.emit_sockarg(); + compiler.emit_sockarg(); break; case O_TAGGED: - comp.emit_tagged(); + compiler.emit_tagged(); break; /* @@ -886,101 +1155,101 @@ /* XXX case O_LIMIT: case O_KEEP_STATE: - comp.emit_keep_state(); + compiler.emit_keep_state(); break; case O_PROBE_STATE: case O_CHECK_STATE: - comp.emit_check_state(); + compiler.emit_check_state(); break; case O_ACCEPT: - comp.emit_accept(); + compiler.emit_accept(); break; case O_PIPE: case O_QUEUE: - comp.emit_queue(); + compiler.emit_queue(); break; case O_DIVERT: case O_TEE: - comp.emit_tee(); + compiler.emit_tee(); break; case O_COUNT: - comp.emit_count(); + compiler.emit_count(); break; case O_SKIPTO: - comp.emit_skipto(); + compiler.emit_skipto(); continue; break; /* NOTREACHED */ /* XXX case O_CALLRETURN: - comp.emit_callreturn(); + compiler.emit_callreturn(); continue; break; /* NOTREACHED */ /* XXX case O_REJECT: - comp.emit_reject(); + compiler.emit_reject(); /* FALLTHROUGH */ /* XXX #ifdef INET6 case O_UNREACH6: - comp.emit_unreach6(); + compiler.emit_unreach6(); /* FALLTHROUGH */ /* XXX #endif case O_DENY: - comp.emit_deny(); + compiler.emit_deny(); break; case O_FORWARD_IP: - comp.emit_forward_ip(); + compiler.emit_forward_ip(); break; #ifdef INET6 case O_FORWARD_IP6: - comp.emit_forward_ip6(); + compiler.emit_forward_ip6(); break; #endif case O_NETGRAPH: case O_NGTEE: - comp.emit_ngtee(); + compiler.emit_ngtee(); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201408181023.s7IANg2f002229>