Skip to content

Commit a8e7a42

Browse files
WIP functions processing
1 parent b4a2f16 commit a8e7a42

File tree

5 files changed

+76
-4
lines changed

5 files changed

+76
-4
lines changed

examples/execve.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
11
from pythonbpf.decorators import tracepoint
2+
from ctypes import c_void_p, c_int32
23

34
@tracepoint("syscalls:sys_enter_execve")
4-
def trace_execve(ctx) -> int:
5+
def trace_execve(ctx: c_void_p) -> c_int32:
56
print("execve called\n")
6-
return 0
7+
return c_int32(0)
78

89
LICENSE = "GPL"

pythonbpf/codegen.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
11
import ast
22
from llvmlite import ir
33
from .license_pass import license_processing
4+
from .functions_pass import functions_processing
45

56
def processor(source_code, filename, module):
67
tree = ast.parse(source_code, filename)
7-
license_processing(tree, module)
8+
print(ast.dump(tree))
9+
section_names = []
10+
section_names.append(license_processing(tree, module))
11+
section_names.append(functions_processing(tree, module))
12+
if any(name is None for name in section_names):
13+
print("Processing failed")
814

915
def compile_to_ir(filename: str, output: str):
1016
with open(filename) as f:

pythonbpf/functions_pass.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
from llvmlite import ir
2+
import ast
3+
4+
def emit_function(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
16+
gvar.section = "license" # type: ignore
17+
18+
return gvar
19+
20+
def functions_processing(tree, module):
21+
bpf_functions = []
22+
helper_functions = []
23+
for node in tree.body:
24+
section_name = ""
25+
if isinstance(node, ast.FunctionDef):
26+
if len(node.decorator_list) == 1:
27+
bpf_functions.append(node)
28+
else:
29+
if 'helper_functions' not in locals():
30+
helper_functions.append(node)
31+
32+

pythonbpf/license_pass.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ def emit_license(module: ir.Module, license_str: str):
1212

1313
gvar.align = 1 # type: ignore
1414
gvar.linkage = "dso_local" # type: ignore
15-
gvar.global_constant = False # must be global, not constant
15+
gvar.global_constant = False
1616
gvar.section = "license" # type: ignore
1717

1818
return gvar
1919

2020
def license_processing(tree, module):
21+
"""Process the LICENSE assignment in the given AST tree and return the section name"""
2122
count = 0
2223
for node in tree.body:
2324
if isinstance(node, ast.Assign):
@@ -27,7 +28,10 @@ def license_processing(tree, module):
2728
count += 1
2829
if isinstance(node.value, ast.Constant) and isinstance(node.value.value, str):
2930
emit_license(module, node.value.value)
31+
return "LICENSE"
3032
else:
3133
print("ERROR: LICENSE must be a string literal")
34+
return None
3235
else:
3336
print("ERROR: LICENSE already assigned")
37+
return None

pythonbpf/type_deducer.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import ctypes
2+
from llvmlite import ir
3+
4+
def ctypes_to_ir(ctype):
5+
if ctype is ctypes.c_int32:
6+
return ir.IntType(32)
7+
if ctype is ctypes.c_int64:
8+
return ir.IntType(64)
9+
if ctype is ctypes.c_uint8:
10+
return ir.IntType(8)
11+
if ctype is ctypes.c_double:
12+
return ir.DoubleType()
13+
if ctype is ctypes.c_float:
14+
return ir.FloatType()
15+
16+
# pointers
17+
if hasattr(ctype, "_type_") and hasattr(ctype, "_length_"):
18+
# ctypes array
19+
return ir.ArrayType(ctypes_to_ir(ctype._type_), ctype._length_)
20+
21+
# if hasattr(ctype, "_type_") and issubclass(ctype, ctypes._Pointer):
22+
# return ir.PointerType(ctypes_to_ir(ctype._type_))
23+
24+
# structs
25+
if issubclass(ctype, ctypes.Structure):
26+
fields = [ctypes_to_ir(f[1]) for f in ctype._fields_]
27+
return ir.LiteralStructType(fields)
28+
29+
raise NotImplementedError(f"No mapping for {ctype}")

0 commit comments

Comments
 (0)