From 46cefd41435267f367b5c682ca411b52fafda601 Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Tue, 9 Sep 2025 00:42:49 +0530 Subject: [PATCH 1/3] Add debug info --- pythonbpf/maps_pass.py | 161 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 155 insertions(+), 6 deletions(-) diff --git a/pythonbpf/maps_pass.py b/pythonbpf/maps_pass.py index 782b2f6b..f5d88f23 100644 --- a/pythonbpf/maps_pass.py +++ b/pythonbpf/maps_pass.py @@ -21,7 +21,7 @@ def maps_proc(tree, module, chunks): def create_bpf_map(module, map_name, map_params): - """Create a BPF map in the module with the given parameters""" + """Create a BPF map in the module with the given parameters and debug info""" # Create the anonymous struct type for BPF map map_struct_type = ir.LiteralStructType([ @@ -35,17 +35,166 @@ def create_bpf_map(module, map_name, map_params): map_global = ir.GlobalVariable(module, map_struct_type, name=map_name) map_global.linkage = 'dso_local' map_global.global_constant = False - - # Initialize with zeroinitializer (all null pointers) - map_global.initializer = ir.Constant(map_struct_type, None) # type: ignore - + map_global.initializer = ir.Constant(map_struct_type, None) # type: ignore map_global.section = ".maps" - map_global.align = 8 # type: ignore + map_global.align = 8 # type: ignore + + # Generate debug info for BTF + create_map_debug_info(module, map_global, map_name, map_params) print(f"Created BPF map: {map_name}") map_sym_tab[map_name] = map_global return map_global +def create_map_debug_info(module, map_global, map_name, map_params): + """Generate debug information metadata for BPF map""" + file_metadata = module + # Get or create compile unit (you may already have this) + if not hasattr(module, '_debug_compile_unit'): + # Create file metadata + file_metadata = module.add_debug_info("DIFile", { + "filename": "generated.bpf.c", # Adjust as needed + "directory": "/generated", # Adjust as needed + }) + + # Create compile unit + module._debug_compile_unit = module.add_debug_info("DICompileUnit", { + "language": 12, # DW_LANG_C11 + "file": file_metadata, + "producer": "PythonBPF DSL Compiler", + "isOptimized": True, + "runtimeVersion": 0, + "emissionKind": 1, + "splitDebugInlining": False, + "nameTableKind": 0 + }, is_distinct=True) + + module.add_named_metadata("llvm.dbg.cu", module._debug_compile_unit) + + compile_unit = module._debug_compile_unit + + # Create basic type for unsigned int (32-bit) + uint_type = module.add_debug_info("DIBasicType", { + "name": "unsigned int", + "size": 32, + "encoding": 7 + }) + + # Create basic type for unsigned long long (64-bit) + ulong_type = module.add_debug_info("DIBasicType", { + "name": "unsigned long long", + "size": 64, + "encoding": 7 # "DW_ATE_unsigned" + }) + + # Create array type for map type field (array of 1 unsigned int) + array_subrange = module.add_debug_info("DISubrange", {"count": 1}) + array_type = module.add_debug_info("DICompositeType", { + "tag": 17, # "DW_TAG_array_type" + "baseType": uint_type, + "size": 32, + "elements": [array_subrange] + }) + + # Create pointer types + type_ptr = module.add_debug_info("DIDerivedType", { + "tag": 15, # DW_TAG_pointer_type + "baseType": array_type, + "size": 64 + }) + + max_entries_ptr = module.add_debug_info("DIDerivedType", { + "tag": 15, # DW_TAG_pointer_type + "baseType": array_type, + "size": 64 + }) + + key_ptr = module.add_debug_info("DIDerivedType", { + "tag": 15, # DW_TAG_pointer_type + "baseType": uint_type, # Adjust based on actual key type + "size": 64 + }) + + value_ptr = module.add_debug_info("DIDerivedType", { + "tag": 15, # DW_TAG_pointer_type + "baseType": ulong_type, # Adjust based on actual value type + "size": 64 + }) + + # Create struct members + type_member = module.add_debug_info("DIDerivedType", { + "tag": 13, # "DW_TAG_member" + "name": "type", + "file": file_metadata, # Use the stored file metadata + "line": 7, # You may want to track actual line numbers + "baseType": type_ptr, + "size": 64, + "offset": 0 + }) + + max_entries_member = module.add_debug_info("DIDerivedType", { + "tag": 13, # DW_TAG_member + "name": "max_entries", + "file": file_metadata, + "line": 8, + "baseType": max_entries_ptr, + "size": 64, + "offset": 64 + }) + + key_member = module.add_debug_info("DIDerivedType", { + "tag": 13, # DW_TAG_member + "name": "key", + "file": file_metadata, + "line": 9, + "baseType": key_ptr, + "size": 64, + "offset": 128 + }) + + value_member = module.add_debug_info("DIDerivedType", { + "tag": 13, # DW_TAG_member + "name": "value", + "file": file_metadata, + "line": 10, + "baseType": value_ptr, + "size": 64, + "offset": 192 + }) + + # Create the struct type + struct_type = module.add_debug_info("DICompositeType", { + "tag": 19, # DW_TAG_structure_type + "name": "anon", # Anonymous struct + "file": file_metadata, + "line": 6, # Adjust line number + "size": 256, # 4 * 64-bit pointers + "align": 64, + "elements": [type_member, max_entries_member, key_member, value_member] + }) + + # Create global variable debug info + global_var = module.add_debug_info("DIGlobalVariable", { + "name": map_name, + "scope": compile_unit, + "file": file_metadata, + "line": 11, # Adjust line number + "type": struct_type, + "isLocal": False, + "isDefinition": True + }) + + # Create global variable expression + global_var_expr = module.add_debug_info("DIGlobalVariableExpression", { + "var": global_var, + "expr": module.add_debug_info("DIExpression", {}) + }) + + # Attach debug info to the global variable + map_global.set_metadata("dbg", global_var_expr) + + return global_var_expr + def process_hash_map(map_name, rval, module): print(f"Creating HashMap map: {map_name}") From d7a5a06eab7b51af53c755272b3835968227b1fb Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Tue, 9 Sep 2025 12:16:01 +0530 Subject: [PATCH 2/3] remove line numbers from debug info Signed-off-by: varun-r-mallya --- examples/c-form/ex2.bpf.c | 7 ------- pythonbpf/maps_pass.py | 6 ------ 2 files changed, 13 deletions(-) diff --git a/examples/c-form/ex2.bpf.c b/examples/c-form/ex2.bpf.c index e792e7f1..87447ac7 100644 --- a/examples/c-form/ex2.bpf.c +++ b/examples/c-form/ex2.bpf.c @@ -10,13 +10,6 @@ struct { __type(value, u64); } last SEC(".maps"); -struct { - __uint(type, BPF_MAP_TYPE_HASH); - __uint(max_entries, 1); - __type(key, u64); - __type(value, u64); -} last2 SEC(".maps"); - SEC("tracepoint/syscalls/sys_enter_execve") int hello(struct pt_regs *ctx) { bpf_printk("Hello, World!\n"); diff --git a/pythonbpf/maps_pass.py b/pythonbpf/maps_pass.py index f5d88f23..20b5bb02 100644 --- a/pythonbpf/maps_pass.py +++ b/pythonbpf/maps_pass.py @@ -126,7 +126,6 @@ def create_map_debug_info(module, map_global, map_name, map_params): "tag": 13, # "DW_TAG_member" "name": "type", "file": file_metadata, # Use the stored file metadata - "line": 7, # You may want to track actual line numbers "baseType": type_ptr, "size": 64, "offset": 0 @@ -136,7 +135,6 @@ def create_map_debug_info(module, map_global, map_name, map_params): "tag": 13, # DW_TAG_member "name": "max_entries", "file": file_metadata, - "line": 8, "baseType": max_entries_ptr, "size": 64, "offset": 64 @@ -146,7 +144,6 @@ def create_map_debug_info(module, map_global, map_name, map_params): "tag": 13, # DW_TAG_member "name": "key", "file": file_metadata, - "line": 9, "baseType": key_ptr, "size": 64, "offset": 128 @@ -156,7 +153,6 @@ def create_map_debug_info(module, map_global, map_name, map_params): "tag": 13, # DW_TAG_member "name": "value", "file": file_metadata, - "line": 10, "baseType": value_ptr, "size": 64, "offset": 192 @@ -167,7 +163,6 @@ def create_map_debug_info(module, map_global, map_name, map_params): "tag": 19, # DW_TAG_structure_type "name": "anon", # Anonymous struct "file": file_metadata, - "line": 6, # Adjust line number "size": 256, # 4 * 64-bit pointers "align": 64, "elements": [type_member, max_entries_member, key_member, value_member] @@ -178,7 +173,6 @@ def create_map_debug_info(module, map_global, map_name, map_params): "name": map_name, "scope": compile_unit, "file": file_metadata, - "line": 11, # Adjust line number "type": struct_type, "isLocal": False, "isDefinition": True From 12bca3cfab21471f1afa4a68b28143e63cfc3b4a Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Tue, 9 Sep 2025 12:57:03 +0530 Subject: [PATCH 3/3] fix: debug info addition for specific hashmap --- pythonbpf/maps_pass.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pythonbpf/maps_pass.py b/pythonbpf/maps_pass.py index 20b5bb02..95c1a0fd 100644 --- a/pythonbpf/maps_pass.py +++ b/pythonbpf/maps_pass.py @@ -90,7 +90,7 @@ def create_map_debug_info(module, map_global, map_name, map_params): # Create array type for map type field (array of 1 unsigned int) array_subrange = module.add_debug_info("DISubrange", {"count": 1}) array_type = module.add_debug_info("DICompositeType", { - "tag": 17, # "DW_TAG_array_type" + "tag": 1, # "DW_TAG_array_type" "baseType": uint_type, "size": 32, "elements": [array_subrange] @@ -122,6 +122,7 @@ def create_map_debug_info(module, map_global, map_name, map_params): }) # Create struct members + # scope field does not appear for some reason type_member = module.add_debug_info("DIDerivedType", { "tag": 13, # "DW_TAG_member" "name": "type", @@ -161,12 +162,10 @@ def create_map_debug_info(module, map_global, map_name, map_params): # Create the struct type struct_type = module.add_debug_info("DICompositeType", { "tag": 19, # DW_TAG_structure_type - "name": "anon", # Anonymous struct "file": file_metadata, "size": 256, # 4 * 64-bit pointers - "align": 64, "elements": [type_member, max_entries_member, key_member, value_member] - }) + }, is_distinct=True) # Create global variable debug info global_var = module.add_debug_info("DIGlobalVariable", { @@ -176,7 +175,7 @@ def create_map_debug_info(module, map_global, map_name, map_params): "type": struct_type, "isLocal": False, "isDefinition": True - }) + }, is_distinct=True) # Create global variable expression global_var_expr = module.add_debug_info("DIGlobalVariableExpression", {