Skip to content

Commit d5557d3

Browse files
Initialize PythonBPF project and toolchain
0 parents  commit d5557d3

10 files changed

Lines changed: 119 additions & 0 deletions

File tree

.gitignore

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
*venv*/
2+
.ropeproject/
3+
.idea/
4+
*.egg-info/
5+
.vscode/
6+
__pycache__/
7+
*.ll
8+
*.o

Makefile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
install:
2+
pip install -e .
3+
4+
compile:
5+
chmod +x ./tools/compile.py
6+
./tools/compile.py ./examples/execve.py
7+
8+
clean:
9+
rm -rf build dist *.egg-info
10+
rm -rf examples/execve.ll examples/execve.o
11+
12+
all: install compile
13+
14+
.PHONY: all clean

README.md

Whitespace-only changes.

examples/example.bpf.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
#include <linux/bpf.h>
2+
#include <bpf/bpf_helpers.h>
3+
4+
SEC("tracepoint/syscalls/sys_enter_execve")
5+
int trace_execve(void *ctx)
6+
{
7+
bpf_printk("execve called\n");
8+
return 0;
9+
}
10+
11+
char LICENSE[] SEC("license") = "GPL";

examples/execve.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from pythonbpf import decorators
2+
3+
@decorators.tracepoint("syscalls:sys_enter_execve")
4+
def trace_execve(ctx) -> int:
5+
decorators.trace_printk("execve called\n")
6+
return 0
7+
8+
@decorators.license("GPL")
9+
def _():
10+
pass

pyproject.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[build-system]
2+
requires = ["setuptools>=61.0"]
3+
build-backend = "setuptools.build_meta"
4+
5+
[project]
6+
name = "pythonbpf"
7+
version = "0.1.0"
8+
description = "Reduced Python frontend for eBPF"
9+
authors = [
10+
{ name = "r41k0u" },
11+
{ name = "varun-r-mallya" }
12+
]
13+
requires-python = ">=3.8"
14+
15+
dependencies = [
16+
"llvmlite",
17+
"astpretty"
18+
]
19+
20+
[tool.setuptools.packages.find]
21+
where = ["."]
22+
include = ["pythonbpf*"]

pythonbpf/__init__.py

Whitespace-only changes.

pythonbpf/codegen.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import ast
2+
from llvmlite import ir
3+
4+
def compile_to_ir(filename: str, output: str):
5+
with open(filename) as f:
6+
ast.parse(f.read(), filename)
7+
8+
module = ir.Module(name="pythonbpf")
9+
func_ty = ir.FunctionType(ir.IntType(64), [], False)
10+
func = ir.Function(module, func_ty, name="trace_execve")
11+
12+
block = func.append_basic_block(name="entry")
13+
builder = ir.IRBuilder(block)
14+
builder.ret(ir.IntType(64)(0))
15+
16+
with open(output, "w") as f:
17+
f.write(str(module))
18+
19+
return output

pythonbpf/decorators.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
def tracepoint(name: str):
2+
def wrapper(fn):
3+
fn._section = f"tracepoint/{name}"
4+
return fn
5+
return wrapper
6+
7+
def license(name: str):
8+
def wrapper(fn):
9+
fn._license = name
10+
return fn
11+
return wrapper
12+
13+
def trace_printk(msg: str):
14+
# placeholder — real version lowers to IR later
15+
print(f"[trace_printk] {msg}")

tools/compile.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/usr/bin/env python3
2+
import argparse, subprocess, os
3+
from pythonbpf import codegen
4+
5+
def main():
6+
parser = argparse.ArgumentParser()
7+
parser.add_argument("source", help="Python BPF program")
8+
args = parser.parse_args()
9+
10+
ll_file = os.path.splitext(args.source)[0] + ".ll"
11+
o_file = os.path.splitext(args.source)[0] + ".o"
12+
13+
print(f"[+] Compiling {args.source}{ll_file}")
14+
codegen.compile_to_ir(args.source, ll_file)
15+
16+
print("[+] Running llc -march=bpf")
17+
subprocess.run(["llc", "-march=bpf", "-filetype=obj", ll_file, "-o", o_file], check=True)
18+
19+
if __name__ == "__main__":
20+
main()

0 commit comments

Comments
 (0)