diff --git a/Makefile b/Makefile index e8d433a..48d01a3 100644 --- a/Makefile +++ b/Makefile @@ -1,10 +1,10 @@ -install: - pip install -e . - compile: chmod +x ./tools/compile.py ./tools/compile.py ./examples/execve.py +install: + pip install -e . + clean: rm -rf build dist *.egg-info rm -rf examples/execve.ll examples/execve.o diff --git a/README.md b/README.md index e69de29..1db8238 100644 --- a/README.md +++ b/README.md @@ -0,0 +1,10 @@ +# Python-BPF +This is an LLVM IR generator for eBPF program. We use `llvmlite` to generate LLVM IR code from pure Python code. This is then compiled to LLVM object files, which can be loaded into the kernel for execution. + +## Development +Step 1. Run `make install` to install the required dependencies. +Step 2. Run `make` to see the compilation output of the example. + +## Authors +- [@r41k0u](https://github.com/r41k0u) +- [@varun-r-mallya](https://github.com/varun-r-mallya) diff --git a/examples/c-form/Makefile b/examples/c-form/Makefile new file mode 100644 index 0000000..2d1d359 --- /dev/null +++ b/examples/c-form/Makefile @@ -0,0 +1,15 @@ +BPF_CLANG := clang +CFLAGS := -O2 -emit-llvm -target bpf -c + +SRC := example.bpf.c +OUT := example.bpf.ll + +.PHONY: all clean + +all: $(OUT) + +$(OUT): $(SRC) + $(BPF_CLANG) $(CFLAGS) -S $< -o $@ + +clean: + rm -f $(OUT) diff --git a/examples/example.bpf.c b/examples/c-form/example.bpf.c similarity index 100% rename from examples/example.bpf.c rename to examples/c-form/example.bpf.c diff --git a/examples/execve.py b/examples/execve.py index 729db63..2e22bbf 100644 --- a/examples/execve.py +++ b/examples/execve.py @@ -1,10 +1,8 @@ -from pythonbpf import decorators +from pythonbpf.decorators import tracepoint, license -@decorators.tracepoint("syscalls:sys_enter_execve") +@tracepoint("syscalls:sys_enter_execve") def trace_execve(ctx) -> int: - decorators.trace_printk("execve called\n") + print("execve called\n") return 0 -@decorators.license("GPL") -def _(): - pass +license("GPL") \ No newline at end of file diff --git a/pythonbpf/codegen.py b/pythonbpf/codegen.py index dc0fa22..56fe41b 100644 --- a/pythonbpf/codegen.py +++ b/pythonbpf/codegen.py @@ -1,11 +1,22 @@ import ast from llvmlite import ir +def parser(source_code, filename): + tree = ast.parse(source_code, filename) + + for node in tree.body: + if isinstance(node, ast.FunctionDef): + print("Function:", node.name) + for dec in node.decorator_list: + print(" Decorator AST:", ast.dump(dec)) + def compile_to_ir(filename: str, output: str): with open(filename) as f: - ast.parse(f.read(), filename) + parser(f.read(), filename) + module = ir.Module(name=filename) + module.data_layout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128" + module.triple = "bpf" - module = ir.Module(name="pythonbpf") func_ty = ir.FunctionType(ir.IntType(64), [], False) func = ir.Function(module, func_ty, name="trace_execve") diff --git a/pythonbpf/decorators.py b/pythonbpf/decorators.py index d16b77e..28bacfd 100644 --- a/pythonbpf/decorators.py +++ b/pythonbpf/decorators.py @@ -4,11 +4,8 @@ def tracepoint(name: str): return fn return wrapper -def license(name: str): - def wrapper(fn): - fn._license = name - return fn - return wrapper +def license(license_type: str): + return license_type def trace_printk(msg: str): # placeholder — real version lowers to IR later