diff --git a/README.md b/README.md index 7957bcd..18347d3 100644 --- a/README.md +++ b/README.md @@ -13,25 +13,25 @@ This is an LLVM IR generator for eBPF programs in Python. We use llvmlite to gen ## Usage ```python # pythonbpf_example.py -import pythonbpf as pb +from pythonbpf import bpf, map, bpfglobal, section, compile from pythonbpf.helpers import bpf_ktime_get_ns from pythonbpf.maps import HashMap from ctypes import c_void_p, c_int64, c_int32, c_uint64 -@pb.bpf -@pb.map +@bpf +@map def last() -> HashMap: return HashMap(key_type=c_uint64, value_type=c_uint64, max_entries=1) -@pb.bpf -@pb.section("tracepoint/syscalls/sys_enter_execve") +@bpf +@section("tracepoint/syscalls/sys_enter_execve") def hello(ctx: c_void_p) -> c_int32: print("entered") return c_int32(0) -@pb.bpf -@pb.section("tracepoint/syscalls/sys_exit_execve") +@bpf +@section("tracepoint/syscalls/sys_exit_execve") def hello_again(ctx: c_void_p) -> c_int64: print("exited") key = 0 @@ -40,8 +40,8 @@ def hello_again(ctx: c_void_p) -> c_int64: ts = bpf_ktime_get_ns() return c_int64(0) -@pb.bpf -@pb.bpfglobal +@bpf +@bpfglobal def LICENSE() -> str: return "GPL" @@ -49,7 +49,7 @@ def some_normal_function(): print("normal function") # compiles and dumps object file in the same directory -pb.compile() +compile() ``` - Run `python pythonbpf_example.py` to get the compiled object file that can be then loaded into the kernel. diff --git a/examples/execve3.py b/examples/execve3.py index 4a9ee19..4e53d43 100644 --- a/examples/execve3.py +++ b/examples/execve3.py @@ -1,25 +1,25 @@ -import pythonbpf as pb +from pythonbpf import bpf, map, section, bpfglobal, compile from pythonbpf.helpers import bpf_ktime_get_ns from pythonbpf.maps import HashMap from ctypes import c_void_p, c_int64, c_int32, c_uint64 -@pb.bpf -@pb.map +@bpf +@map def last() -> HashMap: return HashMap(key_type=c_uint64, value_type=c_uint64, max_entries=1) -@pb.bpf -@pb.section("tracepoint/syscalls/sys_enter_execve") +@bpf +@section("tracepoint/syscalls/sys_enter_execve") def hello(ctx: c_void_p) -> c_int32: print("entered") print("multi constant support") return c_int32(0) -@pb.bpf -@pb.section("tracepoint/syscalls/sys_exit_execve") +@bpf +@section("tracepoint/syscalls/sys_exit_execve") def hello_again(ctx: c_void_p) -> c_int64: print("exited") key = 0 @@ -34,9 +34,9 @@ def hello_again(ctx: c_void_p) -> c_int64: return c_int64(0) -@pb.bpf -@pb.bpfglobal +@bpf +@bpfglobal def LICENSE() -> str: return "GPL" -pb.compile() +compile() diff --git a/pythonbpf/codegen.py b/pythonbpf/codegen.py index fde27b0..0b36bcd 100644 --- a/pythonbpf/codegen.py +++ b/pythonbpf/codegen.py @@ -6,8 +6,8 @@ from .maps_pass import maps_proc from .globals_pass import globals_processing import os import subprocess -import pathlib -import __main__ +import inspect +from pathlib import Path def find_bpf_chunks(tree): """Find all functions decorated with @bpf in the AST.""" @@ -96,12 +96,14 @@ def compile_to_ir(filename: str, output: str): return output def compile(): - main_file = pathlib.Path(__main__.__file__).resolve() + # Look one level up the stack to the caller of this function + caller_frame = inspect.stack()[1] + caller_file = Path(caller_frame.filename).resolve() - ll_file = pathlib.Path("/tmp") / main_file.with_suffix(".ll").name - o_file = main_file.with_suffix(".o") + ll_file = Path("/tmp") / caller_file.with_suffix(".ll").name + o_file = caller_file.with_suffix(".o") - compile_to_ir(str(main_file), str(ll_file)) + compile_to_ir(str(caller_file), str(ll_file)) subprocess.run([ "llc", "-march=bpf", "-filetype=obj", "-O2",