Skip to content

Commit b4a2f16

Browse files
emit license
1 parent b8ef7cc commit b4a2f16

5 files changed

Lines changed: 47 additions & 21 deletions

File tree

examples/c-form/Makefile

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,17 @@ CFLAGS := -O2 -emit-llvm -target bpf -c
33

44
SRC := example.bpf.c
55
OUT := example.bpf.ll
6+
OBJECT := example.bpf.o
67

78
.PHONY: all clean
89

910
all: $(OUT)
11+
12+
object: $(SRC)
13+
$(BPF_CLANG) $(CFLAGS) $< -o $(OBJECT)
1014

11-
$(OUT): $(SRC)
15+
$(OUT): $(SRC) object
1216
$(BPF_CLANG) $(CFLAGS) -S $< -o $@
1317

1418
clean:
15-
rm -f $(OUT)
19+
rm -f $(OUT) $(OBJECT)

examples/execve.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
from pythonbpf.decorators import tracepoint, license
1+
from pythonbpf.decorators import tracepoint
22

33
@tracepoint("syscalls:sys_enter_execve")
44
def trace_execve(ctx) -> int:
55
print("execve called\n")
66
return 0
77

8-
license("GPL")
8+
LICENSE = "GPL"

pythonbpf/codegen.py

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
11
import ast
22
from llvmlite import ir
3+
from .license_pass import license_processing
34

4-
def parser(source_code, filename):
5+
def processor(source_code, filename, module):
56
tree = ast.parse(source_code, filename)
6-
7-
for node in tree.body:
8-
if isinstance(node, ast.FunctionDef):
9-
print("Function:", node.name)
10-
for dec in node.decorator_list:
11-
print(" Decorator AST:", ast.dump(dec))
7+
license_processing(tree, module)
128

139
def compile_to_ir(filename: str, output: str):
1410
with open(filename) as f:
15-
parser(f.read(), filename)
11+
source = f.read()
12+
1613
module = ir.Module(name=filename)
1714
module.data_layout = "e-m:e-p:64:64-i64:64-i128:128-n32:64-S128"
1815
module.triple = "bpf"
1916

20-
func_ty = ir.FunctionType(ir.IntType(64), [], False)
21-
func = ir.Function(module, func_ty, name="trace_execve")
22-
23-
block = func.append_basic_block(name="entry")
24-
builder = ir.IRBuilder(block)
25-
builder.ret(ir.IntType(64)(0))
17+
processor(source, filename, module)
2618

2719
with open(output, "w") as f:
2820
f.write(str(module))

pythonbpf/decorators.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,3 @@ def wrapper(fn):
33
fn._section = f"tracepoint/{name}"
44
return fn
55
return wrapper
6-
7-
def license(license_type: str):
8-
return license_type

pythonbpf/license_pass.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
from llvmlite import ir
2+
import ast
3+
4+
def emit_license(module: ir.Module, license_str: str):
5+
license_bytes = license_str.encode("utf8") + b"\x00"
6+
elems = [ir.Constant(ir.IntType(8), b) for b in license_bytes]
7+
ty = ir.ArrayType(ir.IntType(8), len(elems))
8+
9+
gvar = ir.GlobalVariable(module, ty, name="LICENSE")
10+
11+
gvar.initializer = ir.Constant(ty, elems) # type: ignore
12+
13+
gvar.align = 1 # type: ignore
14+
gvar.linkage = "dso_local" # type: ignore
15+
gvar.global_constant = False # must be global, not constant
16+
gvar.section = "license" # type: ignore
17+
18+
return gvar
19+
20+
def license_processing(tree, module):
21+
count = 0
22+
for node in tree.body:
23+
if isinstance(node, ast.Assign):
24+
for target in node.targets:
25+
if isinstance(target, ast.Name) and target.id == "LICENSE":
26+
if count == 0:
27+
count += 1
28+
if isinstance(node.value, ast.Constant) and isinstance(node.value.value, str):
29+
emit_license(module, node.value.value)
30+
else:
31+
print("ERROR: LICENSE must be a string literal")
32+
else:
33+
print("ERROR: LICENSE already assigned")

0 commit comments

Comments
 (0)