socsvn commit: r272045 - soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw
dpl at FreeBSD.org
dpl at FreeBSD.org
Thu Aug 7 18:34:12 UTC 2014
Author: dpl
Date: Thu Aug 7 18:34:11 2014
New Revision: 272045
URL: http://svnweb.FreeBSD.org/socsvn/?view=rev&rev=272045
Log:
Generally working on the JITter.
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 Thu Aug 7 18:33:18 2014 (r272044)
+++ soc2014/dpl/netmap-ipfwjit/sys/netpfil/ipfw/jit.cc Thu Aug 7 18:34:11 2014 (r272045)
@@ -1,11 +1,13 @@
-/* JIT compilation code */
#undef _KERNEL
#include <iostream>
#include <string>
#include <vector>
#include <llvm/ADT/OwningPtr.h>
+#include <llvm/ADT/ArrayRef.h>
#include <llvm/Bitcode/ReaderWriter.h>
+#include <llvm/CodeGen/MachineCodeInfo.h>
+#include <llvm/ExecutionEngine/ExecutionEngine.h>
#include <llvm/IR/IRBuilder.h>
#include <llvm/IR/LLVMContext.h>
#include <llvm/IR/Module.h>
@@ -18,6 +20,7 @@
#include <missing.h>
#include <sys/mbuf.h>
+#include <sys/types.h>
#include <netinet/ip_fw.h>
#include <netinet/ip_dummynet.h>
#include <netinet/in_pcb.h>
@@ -27,7 +30,6 @@
#include <netpfil/ipfw/ip_fw_private.h>
}
-
typedef int (*funcptr)();
using namespace llvm;
@@ -39,11 +41,26 @@
LLVMContext con;
OwningPtr<MemoryBuffer> buffer;
IRBuilder<> irb;
- std::vector<BasicBlock> BBs;
+ std::vector<BasicBlock*> blocks;
+
+ // Vars Types
+ Type *int8Ty;
+ Type *int16Ty;
+ Type *int32Ty;
+
+ // JIT Compiled Vars
+ Value *match;
+ Value *l;
+ Value *done;
+ Value *f_pos;
+ Value *retval;
+
+ // Functions used by our JITed code.
+ Function *iface_match;
+ // Load the bc for JIT compilation.
Module *loadbc(std::string name)
{
- /* We load the bc for JIT compilation */
error_code ec = MemoryBuffer::getFile(name, buffer);
if (ec) {
std::cerr << "Failed to open bitcode: " << ec.message() << "\n";
@@ -60,32 +77,49 @@
return (mod);
}
- /* Set the needed variables to perform pkt filtering. */
+ // Create the needed variables to perform pkt filtering.
int
- setVars()
+ setEnv()
{
- //We need the match var.
- Value *match;
- Value *f_pos;
+ // Get Type objects
+ int8Ty = Type::getInt8Ty(con);
+ int16Ty = Type::getInt16Ty(con);
+ int32Ty = Type::getInt32Ty(con);
+
+ // Get StrucType from bitcode.
+
+ // Store vars.
+ match = irb.CreateAlloca(int32Ty);
+ l = irb.CreateAlloca(int32Ty);
+ done = irb.CreateAlloca(int32Ty);
+ f_pos = irb.CreateAlloca(int32Ty);
+ retval = irb.CreateAlloca(int32Ty);
+
+ // Create needed GlobalVariables.
+
+ // Get Function defs from bitcode.
+ iface_match = mod->getFunction("iface_match");
+
return (0);
}
- public:
+ public:
ipfwJIT(): irb(con)
{
- //Create the module and load the code.
+ // Create the module and load the code.
mod = loadbc("ip_fw_rules.bc");
- setVars();
- //Create Function, and start its first BasicBlock.
- //int ipfw_chk_jitted(ip_fw_args *);
- // XXX Do we have to define ip_fw_args using this?
- StructType ipfwargsTy = StructType::get(/*TYPE1, TYPE2, TYPE3...*/);
- Type *argsTy[] = { PointerType::getUnqual(ipfwargsTy) };
- FunctionType *ipfwchkTy = FunctionType::get(Int32Ty, argsTy, false);
- func = Function::Create(ipfwchkTy, GlobalValue::PrivateLinkage, "ipfw_chk", mod);
-
- // XXX Create basic block, and add it to BBs
+ func = mod->getFunction("ipfw_chk_jit");
+ func->setLinkage(GlobalValue::ExternalLinkage);
+ // Create the entry point of the function
+ BasicBlock *entry = BasicBlock::Create(con, "entry", func);
+ // Add the entry block to ArrayRef
+ blocks.push_back(entry);
+ // Set the IRBuilder to insert instructions after the basic block.
+ irb.SetInsertPoint(entry);
+ // Get struct types, and store vars
+ setEnv();
+ // From on on, it's just a matter of emitting the code for each rule/action.
}
~ipfwJIT()
{
@@ -93,63 +127,86 @@
delete mod;
}
+ funcptr
+ functionPtr()
+ {
+ MachineCodeInfo machinf;
+
+ ExecutionEngine::runJITOnFunction(func, &machinf);
+ return ((funcptr)machinf.address());
+ }
+
int
- emit_nop(int *match)
+ emit_nop(int *matchptr)
{
- /*
- static IPFW_RULES_INLINE void
- rule_nop(int *match)
- {
- *match = 1;
- }
- // Get the stub (prototype) for the cell function
- F = Mod->getFunction("cell");
- // Set it to have private linkage, so that it can be removed after being
- // inlined.
- F->setLinkage(GlobalValue::PrivateLinkage);
-
- // Add an entry basic block to this function and set it
- BasicBlock *entry = BasicBlock::Create(C, "entry", F);
- B.SetInsertPoint(entry);
- // Cache the type of registers
- regTy = Type::getInt16Ty(C);
-
- // Collect the function parameters
- auto args = F->arg_begin();
- oldGrid = args++;
- newGrid = args++;
- width = args++;
- height = args++;
- x = args++;
- y = args++;
+ // static IPFW_RULES_INLINE void
+ // rule_nop(int *match)
+ // {
+ // *match = 1;
+ // }
- // Create space on the stack for the local registers
- for (int i=0 ; i<10 ; i++)
- {
- a[i] = B.CreateAlloca(regTy);
- }
+ *matchptr = 1;
- // Create a space on the stack for the current value. This can be
- // assigned to, and will be returned at the end. Store the value passed
- // as a parameter in this.
- v = B.CreateAlloca(regTy);
- B.CreateStore(args++, v);
- // Create a load of pointers to the global registers.
- Value *gArg = args;
- for (int i=0 ; i<10 ; i++)
- {
- B.CreateStore(ConstantInt::get(regTy, 0), a[i]);
- g[i] = B.CreateConstGEP1_32(gArg, i);
- }
- */
+ irb.CreateStore(ConstantInt::get(int32Ty, 1), match);
return (0);
}
int
- emit_forward_mac()
+ emit_forward_mac(u_int8_t opcode)
{
+ // printf("ipfw: opcode %d unimplemented\n",
+ // opcode);
+
+ Function *printf;
+
+ printf = mod->getFunction("printf");
+ irb.CreateCall(printf, "ipfw: opcode %d unimplemented\n", opcode);
return (0);
}
+
+ int
+ emit_jail()
+ {
+ // static IPFW_RULES_INLINE void
+ // rule_jail(int * match, u_short offset, uint8_t proto, ipfw_insn *cmd, struct ip_fw_args *args, int ucred_lookup, void *ucred_cache)
+ // {
+ // /*
+ // * We only check offset == 0 && proto != 0,
+ // * as this ensures that we have a
+ // * packet with the ports info.
+ // */
+ // if (offset != 0)
+ // return;
+ // if (proto == IPPROTO_TCP ||
+ // proto == IPPROTO_UDP)
+ // *match = check_uidgid(
+ // (ipfw_insn_u32 *)cmd,
+ // args, &ucred_lookup,
+ // #ifdef __FreeBSD__
+ // //(struct bsd_ucred **)&ucred_cache);
+ // (struct ucred **)&ucred_cache);
+ // #else
+ // (void *)&ucred_cache);
+ // #endif
+ // }
+
+ return (0);
+ }
+
+ int
+ emit_recv()
+ {
+ // static IPFW_RULES_INLINE void
+ // rule_recv(int *match, ipfw_insn *cmd, struct mbuf *m, struct ip_fw_chain *chain, uint32_t *tablearg)
+ // {
+ // *match = iface_match(m->m_pkthdr.rcvif, (ipfw_insn_if *)cmd, chain, tablearg);
+ // }
+
+ irb.CreateStore(irb.CreateCall4(/*STUFF GOING HERE*/ match);
+
+ return (0);
+ }
+
};
extern "C" funcptr
@@ -157,33 +214,16 @@
{
int res;
ipfwJIT comp;
- Module *mod;
int f_pos = 0;
int retval = 0;
- // Now I have to load the stubs of the loaded rules.
// Iterate through the rules.
- if (args->rule.slot) {
- /*
- * Packet has already been tagged as a result of a previous
- * match on rule args->rule aka args->rule_id (PIPE, QUEUE,
- * REASS, NETGRAPH, DIVERT/TEE...)
- * Validate the slot and continue from the next one
- * if still present, otherwise do a lookup.
- */
- f_pos = (args->rule.chain_id == chain->id) ?
- args->rule.slot :
- ipfw_find_rule(chain, args->rule.rulenum,
- args->rule.rule_id);
- } else {
- f_pos = 0;
- }
int done = 0; /* flag to exit the outer loop */
int pktlen = args->m->m_pkthdr.len;
- // Iterate through the rules.
+ // For all the number of rules.
for (; f_pos < chain->n_rules; f_pos++) {
ipfw_insn *cmd;
int l, cmdlen, skip_or; /* skip rest of OR block */
@@ -194,6 +234,7 @@
continue;
skip_or = 0;
+ // For each different command.
for (l = f->cmd_len, cmd = f->cmd ; l > 0 ;
l -= cmdlen, cmd += cmdlen) {
int match;
@@ -225,15 +266,16 @@
break;
case O_FORWARD_MAC:
- comp.emit_forward_mac();
+ comp.emit_forward_mac(cmd->opcode);
break;
-/* XXX
+
case O_GID:
case O_UID:
case O_JAIL:
comp.emit_jail();
break;
+/* XXX
case O_RECV:
comp.emit_recv();
break;
@@ -635,6 +677,8 @@
printf("ipfw: ouch!, skip past end of rules, denying packet\n");
}
+ // Once we're done iterating through the rules, return the pointer.
+
return (0);
}
}
More information about the svn-soc-all
mailing list