diff --git a/TODO.md b/TODO.md index b32f279..9328966 100644 --- a/TODO.md +++ b/TODO.md @@ -1,7 +1,11 @@ ## Short term - Implement enough functionality to port the BCC tutorial examples in PythonBPF - +- Static Typing +- Add all maps +- XDP support in pylibbpf +- ringbuf support +- recursive expression resolution ## Long term diff --git a/pythonbpf/codegen.py b/pythonbpf/codegen.py index d6b2f52..1b40e77 100644 --- a/pythonbpf/codegen.py +++ b/pythonbpf/codegen.py @@ -108,7 +108,7 @@ def compile_to_ir(filename: str, output: str): return output -def compile(): +def compile() -> bool: # Look one level up the stack to the caller of this function caller_frame = inspect.stack()[1] caller_file = Path(caller_frame.filename).resolve() @@ -116,14 +116,16 @@ def compile(): ll_file = Path("/tmp") / caller_file.with_suffix(".ll").name o_file = caller_file.with_suffix(".o") - compile_to_ir(str(caller_file), str(ll_file)) + success = True + success = compile_to_ir(str(caller_file), str(ll_file)) and success - subprocess.run([ + success = subprocess.run([ "llc", "-march=bpf", "-filetype=obj", "-O2", str(ll_file), "-o", str(o_file) - ], check=True) + ], check=True) and success - print(f"Object written to {o_file}, {ll_file} can be removed") + print(f"Object written to {o_file}") + return success def BPF() -> BpfProgram: diff --git a/tests/failing_tests/binops.py b/tests/failing_tests/binops.py new file mode 100644 index 0000000..cce8031 --- /dev/null +++ b/tests/failing_tests/binops.py @@ -0,0 +1,15 @@ +from pythonbpf import compile, bpf, section, bpfglobal +from ctypes import c_void_p, c_int64 + +@bpf +@section("sometag1") +def sometag(ctx: c_void_p) -> c_int64: + a = 1 + 2 + 1 + return c_int64(0) + +@bpf +@bpfglobal +def LICENSE() -> str: + return "GPL" + +compile() diff --git a/tests/failing_tests/if.py b/tests/failing_tests/if.py new file mode 100644 index 0000000..e04f4c9 --- /dev/null +++ b/tests/failing_tests/if.py @@ -0,0 +1,16 @@ +from pythonbpf import compile, bpf, section, bpfglobal +from ctypes import c_void_p, c_int64 + +@bpf +@section("sometag1") +def sometag(ctx: c_void_p) -> c_int64: + if 3 + 2 == 5: + return c_int64(5) + return c_int64(0) + +@bpf +@bpfglobal +def LICENSE() -> str: + return "GPL" + +compile() diff --git a/tests/failing_tests/license.py b/tests/failing_tests/license.py new file mode 100644 index 0000000..d21abba --- /dev/null +++ b/tests/failing_tests/license.py @@ -0,0 +1,11 @@ +from pythonbpf import compile, bpf, section, bpfglobal +from ctypes import c_void_p, c_int64 + +# FAILS WHEN THERE IS NO LICENSE. which is wrong. +@bpf +@section("sometag1") +def sometag(ctx: c_void_p) -> c_int64: + a = 1 + 2 + return c_int64(0) + +compile() diff --git a/tests/failing_tests/return.py b/tests/failing_tests/return.py new file mode 100644 index 0000000..9b9dfeb --- /dev/null +++ b/tests/failing_tests/return.py @@ -0,0 +1,14 @@ +from pythonbpf import compile, bpf, section, bpfglobal +from ctypes import c_void_p, c_int64 + +@bpf +@section("sometag1") +def sometag(ctx: c_void_p) -> c_int64: + return c_int64(1 - 1) + +@bpf +@bpfglobal +def LICENSE() -> str: + return "GPL" + +compile()