Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions examples/c-form/ex2.bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down
154 changes: 148 additions & 6 deletions pythonbpf/maps_pass.py
Original file line number Diff line number Diff line change
Expand Up @@ -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([
Expand All @@ -35,17 +35,159 @@ 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": 1, # "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
# scope field does not appear for some reason
type_member = module.add_debug_info("DIDerivedType", {
"tag": 13, # "DW_TAG_member"
"name": "type",
"file": file_metadata, # Use the stored file metadata
"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,
"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,
"baseType": key_ptr,
"size": 64,
"offset": 128
})

value_member = module.add_debug_info("DIDerivedType", {
"tag": 13, # DW_TAG_member
"name": "value",
"file": file_metadata,
"baseType": value_ptr,
"size": 64,
"offset": 192
})

# Create the struct type
struct_type = module.add_debug_info("DICompositeType", {
"tag": 19, # DW_TAG_structure_type
"file": file_metadata,
"size": 256, # 4 * 64-bit pointers
"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", {
"name": map_name,
"scope": compile_unit,
"file": file_metadata,
"type": struct_type,
"isLocal": False,
"isDefinition": True
}, is_distinct=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}")
Expand Down