add debug info module

This commit is contained in:
2025-09-30 14:29:20 +05:30
parent 26f8f769c5
commit eb73001063
8 changed files with 67 additions and 52 deletions

View File

@ -2,38 +2,39 @@
#include <bpf/bpf_helpers.h>
#define u64 unsigned long long
#define u32 unsigned int
// Define the map
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__type(key, u64);
__type(value, u64);
__type(value, u32);
__uint(max_entries, 4);
} last SEC(".maps");
// Handler for syscall entry
SEC("tracepoint/syscalls/sys_enter_execve")
int hello(void *ctx) {
bpf_printk("entered");
bpf_printk("multi constant support");
return 0;
}
// // Handler for syscall entry
// SEC("tracepoint/syscalls/sys_enter_execve")
// int hello(void *ctx) {
// bpf_printk("entered");
// bpf_printk("multi constant support");
// return 0;
// }
// Handler for syscall exit
SEC("tracepoint/syscalls/sys_exit_execve")
long hello_again(void *ctx) {
bpf_printk("exited");
// // Handler for syscall exit
// SEC("tracepoint/syscalls/sys_exit_execve")
// long hello_again(void *ctx) {
// bpf_printk("exited");
// Create a key for map lookup
u64 key = 0;
// // Create a key for map lookup
// u64 key = 0;
// Simple lookup without conditionals
u64 *tsp = bpf_map_lookup_elem(&last, &key);
// // Simple lookup without conditionals
// u64 *tsp = bpf_map_lookup_elem(&last, &key);
// Get current timestamp
u64 ts = bpf_ktime_get_ns();
// // Get current timestamp
// u64 ts = bpf_ktime_get_ns();
return 0;
}
// return 0;
// }
char LICENSE[] SEC("license") = "GPL";

View File

@ -1,4 +1,4 @@
from pythonbpf.decorators import bpf, map, section, bpfglobal
from pythonbpf import bpf, map, section, bpfglobal, compile_to_ir
from ctypes import c_void_p, c_int64, c_int32, c_uint64
from pythonbpf.helpers import ktime
from pythonbpf.maps import HashMap
@ -10,26 +10,28 @@ def last() -> HashMap:
return HashMap(key=c_uint64, value=c_uint64, max_entries=1)
@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)
# @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)
@bpf
@section("tracepoint/syscalls/sys_exit_execve")
def hello_again(ctx: c_void_p) -> c_int64:
print("exited")
key = 0
tsp = last().lookup(key)
print(tsp)
ts = ktime()
return c_int64(0)
# @bpf
# @section("tracepoint/syscalls/sys_exit_execve")
# def hello_again(ctx: c_void_p) -> c_int64:
# print("exited")
# key = 0
# tsp = last().lookup(key)
# print(tsp)
# ts = ktime()
# return c_int64(0)
@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"
compile_to_ir("execve2.py", "execve2.ll")

View File

@ -1,2 +1,4 @@
from .decorators import bpf, map, section, bpfglobal, struct
from .codegen import compile_to_ir, compile, BPF
from .maps import HashMap, PerfEventArray
from .helpers import pid, XDP_DROP, XDP_PASS, ktime, deref

View File

@ -1,5 +1,7 @@
import ast
from llvmlite import ir
from .debuginfo import DW_LANG_C11, DwarfBehaviorEnum
from .license_pass import license_processing
from .functions_pass import func_proc
from .maps_pass import maps_proc
@ -12,6 +14,7 @@ from pathlib import Path
from pylibbpf import BpfProgram
import tempfile
version = "v0.1.3"
def find_bpf_chunks(tree):
"""Find all functions decorated with @bpf in the AST."""
@ -50,15 +53,15 @@ def compile_to_ir(filename: str, output: str):
module.triple = "bpf"
if not hasattr(module, '_debug_compile_unit'):
module._file_metadata = module.add_debug_info("DIFile", { # type: ignore
module._file_metadata = module.add_debug_info("DIFile", { # type: ignore
"filename": filename,
"directory": os.path.dirname(filename)
})
module._debug_compile_unit = module.add_debug_info("DICompileUnit", { # type: ignore
"language": 29, # DW_LANG_C11
"file": module._file_metadata, # type: ignore
"producer": "PythonBPF DSL Compiler",
module._debug_compile_unit = module.add_debug_info("DICompileUnit", { # type: ignore
"language": DW_LANG_C11,
"file": module._file_metadata, # type: ignore
"producer": f"PythonBPF {version}",
"isOptimized": True,
"runtimeVersion": 0,
"emissionKind": 1,
@ -67,32 +70,32 @@ def compile_to_ir(filename: str, output: str):
}, is_distinct=True)
module.add_named_metadata(
"llvm.dbg.cu", module._debug_compile_unit) # type: ignore
"llvm.dbg.cu", module._debug_compile_unit) # type: ignore
processor(source, filename, module)
wchar_size = module.add_metadata([ir.Constant(ir.IntType(32), 1),
wchar_size = module.add_metadata([DwarfBehaviorEnum.ERROR_IF_MISMATCH,
"wchar_size",
ir.Constant(ir.IntType(32), 4)])
frame_pointer = module.add_metadata([ir.Constant(ir.IntType(32), 7),
frame_pointer = module.add_metadata([DwarfBehaviorEnum.OVERRIDE_USE_LARGEST,
"frame-pointer",
ir.Constant(ir.IntType(32), 2)])
# Add Debug Info Version (3 = DWARF v3, which LLVM expects)
debug_info_version = module.add_metadata([ir.Constant(ir.IntType(32), 2),
debug_info_version = module.add_metadata([DwarfBehaviorEnum.WARNING_IF_MISMATCH,
"Debug Info Version",
ir.Constant(ir.IntType(32), 3)])
# Add explicit DWARF version (4 is common, works with LLVM BPF backend)
dwarf_version = module.add_metadata([ir.Constant(ir.IntType(32), 2),
dwarf_version = module.add_metadata([DwarfBehaviorEnum.OVERRIDE_USE_LARGEST,
"Dwarf Version",
ir.Constant(ir.IntType(32), 4)])
ir.Constant(ir.IntType(32), 5)])
module.add_named_metadata("llvm.module.flags", wchar_size)
module.add_named_metadata("llvm.module.flags", frame_pointer)
module.add_named_metadata("llvm.module.flags", debug_info_version)
module.add_named_metadata("llvm.module.flags", dwarf_version)
module.add_named_metadata("llvm.ident", ["llvmlite PythonBPF v0.0.1"])
module.add_named_metadata("llvm.ident", [f"PythonBPF {version}"])
print(f"IR written to {output}")
with open(output, "w") as f:
@ -125,8 +128,8 @@ def BPF() -> BpfProgram:
caller_frame = inspect.stack()[1]
src = inspect.getsource(caller_frame.frame)
with tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".py") as f, \
tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".ll") as inter, \
tempfile.NamedTemporaryFile(mode="w+", delete=False, suffix=".o") as obj_file:
tempfile.NamedTemporaryFile(mode="w+", delete=True, suffix=".ll") as inter, \
tempfile.NamedTemporaryFile(mode="w+", delete=False, suffix=".o") as obj_file:
f.write(src)
f.flush()
source = f.name

View File

@ -0,0 +1,2 @@
from .dwarf_constants import *
from .dtypes import *

View File

@ -0,0 +1,6 @@
import llvmlite.ir as ir
class DwarfBehaviorEnum:
ERROR_IF_MISMATCH = ir.Constant(ir.IntType(32), 1)
WARNING_IF_MISMATCH = ir.Constant(ir.IntType(32), 2)
OVERRIDE_USE_LARGEST = ir.Constant(ir.IntType(32), 7)

View File

@ -1,7 +1,6 @@
import ast
from llvmlite import ir
from .type_deducer import ctypes_to_ir
from . import dwarf_constants as dc
from .debuginfo import dwarf_constants as dc
map_sym_tab = {}