mirror of
https://github.com/varun-r-mallya/Python-BPF.git
synced 2025-12-31 21:06:25 +00:00
correct error size calculation for arrays
This commit is contained in:
@ -81,6 +81,20 @@ class DebugInfoGenerator:
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def create_array_type_vmlinux(self, type_info: Any, count: int) -> Any:
|
||||||
|
"""Create an array type of the given base type with specified count"""
|
||||||
|
base_type, type_sizing = type_info
|
||||||
|
subrange = self.module.add_debug_info("DISubrange", {"count": count})
|
||||||
|
return self.module.add_debug_info(
|
||||||
|
"DICompositeType",
|
||||||
|
{
|
||||||
|
"tag": dc.DW_TAG_array_type,
|
||||||
|
"baseType": base_type,
|
||||||
|
"size": type_sizing,
|
||||||
|
"elements": [subrange],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _compute_array_size(base_type: Any, count: int) -> int:
|
def _compute_array_size(base_type: Any, count: int) -> int:
|
||||||
# Extract size from base_type if possible
|
# Extract size from base_type if possible
|
||||||
@ -101,7 +115,9 @@ class DebugInfoGenerator:
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
def create_struct_member_vmlinux(self, name: str, base_type_with_size: Any, offset: int) -> Any:
|
def create_struct_member_vmlinux(
|
||||||
|
self, name: str, base_type_with_size: Any, offset: int
|
||||||
|
) -> Any:
|
||||||
"""Create a struct member with the given name, type, and offset"""
|
"""Create a struct member with the given name, type, and offset"""
|
||||||
base_type, type_size = base_type_with_size
|
base_type, type_size = base_type_with_size
|
||||||
return self.module.add_debug_info(
|
return self.module.add_debug_info(
|
||||||
|
|||||||
@ -2,12 +2,15 @@ from pythonbpf.debuginfo import DebugInfoGenerator, dwarf_constants as dc
|
|||||||
from ..dependency_node import DependencyNode
|
from ..dependency_node import DependencyNode
|
||||||
import ctypes
|
import ctypes
|
||||||
import logging
|
import logging
|
||||||
from typing import List, Any, Tuple, Optional
|
from typing import List, Any, Tuple
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def debug_info_generation(
|
def debug_info_generation(
|
||||||
struct: DependencyNode, llvm_module, generated_debug_info: List[Tuple[DependencyNode, Any]]
|
struct: DependencyNode,
|
||||||
|
llvm_module,
|
||||||
|
generated_debug_info: List[Tuple[DependencyNode, Any]],
|
||||||
) -> Any:
|
) -> Any:
|
||||||
"""
|
"""
|
||||||
Generate DWARF debug information for a struct defined in a DependencyNode.
|
Generate DWARF debug information for a struct defined in a DependencyNode.
|
||||||
@ -54,11 +57,11 @@ def debug_info_generation(
|
|||||||
|
|
||||||
|
|
||||||
def _get_field_debug_type(
|
def _get_field_debug_type(
|
||||||
field_name: str,
|
field_name: str,
|
||||||
field,
|
field,
|
||||||
generator: DebugInfoGenerator,
|
generator: DebugInfoGenerator,
|
||||||
parent_struct: DependencyNode,
|
parent_struct: DependencyNode,
|
||||||
generated_debug_info: List[Tuple[DependencyNode, Any]]
|
generated_debug_info: List[Tuple[DependencyNode, Any]],
|
||||||
) -> tuple[Any, int]:
|
) -> tuple[Any, int]:
|
||||||
"""
|
"""
|
||||||
Determine the appropriate debug type for a field based on its Python/ctypes type.
|
Determine the appropriate debug type for a field based on its Python/ctypes type.
|
||||||
@ -77,8 +80,12 @@ def _get_field_debug_type(
|
|||||||
if field.ctype_complex_type is not None:
|
if field.ctype_complex_type is not None:
|
||||||
if issubclass(field.ctype_complex_type, ctypes.Array):
|
if issubclass(field.ctype_complex_type, ctypes.Array):
|
||||||
# Handle array types
|
# Handle array types
|
||||||
element_type, base_type_size = _get_basic_debug_type(field.containing_type, generator)
|
element_type, base_type_size = _get_basic_debug_type(
|
||||||
return generator.create_array_type(element_type, field.type_size), field.type_size * base_type_size
|
field.containing_type, generator
|
||||||
|
)
|
||||||
|
return generator.create_array_type_vmlinux(
|
||||||
|
(element_type, base_type_size * field.type_size), field.type_size
|
||||||
|
), field.type_size * base_type_size
|
||||||
elif issubclass(field.ctype_complex_type, ctypes._Pointer):
|
elif issubclass(field.ctype_complex_type, ctypes._Pointer):
|
||||||
# Handle pointer types
|
# Handle pointer types
|
||||||
pointee_type, _ = _get_basic_debug_type(field.containing_type, generator)
|
pointee_type, _ = _get_basic_debug_type(field.containing_type, generator)
|
||||||
@ -136,7 +143,9 @@ def _get_basic_debug_type(ctype, generator: DebugInfoGenerator) -> Any:
|
|||||||
elif ctype == ctypes.c_longlong or ctype == ctypes.c_int64:
|
elif ctype == ctypes.c_longlong or ctype == ctypes.c_int64:
|
||||||
return generator.get_basic_type("long long", 64, dc.DW_ATE_signed), 64
|
return generator.get_basic_type("long long", 64, dc.DW_ATE_signed), 64
|
||||||
elif ctype == ctypes.c_ulonglong or ctype == ctypes.c_uint64:
|
elif ctype == ctypes.c_ulonglong or ctype == ctypes.c_uint64:
|
||||||
return generator.get_basic_type("unsigned long long", 64, dc.DW_ATE_unsigned), 64
|
return generator.get_basic_type(
|
||||||
|
"unsigned long long", 64, dc.DW_ATE_unsigned
|
||||||
|
), 64
|
||||||
elif ctype == ctypes.c_float:
|
elif ctype == ctypes.c_float:
|
||||||
return generator.get_basic_type("float", 32, dc.DW_ATE_float), 32
|
return generator.get_basic_type("float", 32, dc.DW_ATE_float), 32
|
||||||
elif ctype == ctypes.c_double:
|
elif ctype == ctypes.c_double:
|
||||||
@ -147,9 +156,7 @@ def _get_basic_debug_type(ctype, generator: DebugInfoGenerator) -> Any:
|
|||||||
char_type = generator.get_basic_type("char", 8, dc.DW_ATE_signed_char), 8
|
char_type = generator.get_basic_type("char", 8, dc.DW_ATE_signed_char), 8
|
||||||
return generator.create_pointer_type(char_type)
|
return generator.create_pointer_type(char_type)
|
||||||
elif ctype == ctypes.c_void_p:
|
elif ctype == ctypes.c_void_p:
|
||||||
void_type = generator.module.add_debug_info(
|
void_type = generator.module.add_debug_info("DIBasicType", {"name": "void"})
|
||||||
"DIBasicType", {"name": "void"}
|
|
||||||
)
|
|
||||||
return generator.create_pointer_type(void_type), 64
|
return generator.create_pointer_type(void_type), 64
|
||||||
else:
|
else:
|
||||||
return generator.get_uint64_type(), 64
|
return generator.get_uint64_type(), 64
|
||||||
|
|||||||
@ -1,22 +1,20 @@
|
|||||||
from pythonbpf import bpf, map, section, bpfglobal, compile_to_ir, compile
|
from pythonbpf import bpf, section, bpfglobal, compile_to_ir, compile
|
||||||
from pythonbpf.maps import HashMap
|
|
||||||
from pythonbpf.helper import XDP_PASS
|
|
||||||
from vmlinux import TASK_COMM_LEN # noqa: F401
|
from vmlinux import TASK_COMM_LEN # noqa: F401
|
||||||
from vmlinux import struct_xdp_md
|
|
||||||
from vmlinux import struct_trace_event_raw_sys_enter # noqa: F401
|
from vmlinux import struct_trace_event_raw_sys_enter # noqa: F401
|
||||||
from ctypes import c_int64
|
from ctypes import c_int64
|
||||||
|
|
||||||
|
|
||||||
# Instructions to how to run this program
|
# Instructions to how to run this program
|
||||||
# 1. Install PythonBPF: pip install pythonbpf
|
# 1. Install PythonBPF: pip install pythonbpf
|
||||||
# 2. Run the program: python examples/xdp_pass.py
|
# 2. Run the program: python examples/xdp_pass.py
|
||||||
# 3. Run the program with sudo: sudo tools/check.sh run examples/xdp_pass.o
|
# 3. Run the program with sudo: sudo tools/check.sh run examples/xdp_pass.o
|
||||||
# 4. Attach object file to any network device with something like ./check.sh xdp examples/xdp_pass.o tailscale0
|
# 4. Attach object file to any network device with something like ./check.sh xdp examples/xdp_pass.o tailscale0
|
||||||
# 5. send traffic through the device and observe effects
|
# 5. send traffic through the device and observe effects
|
||||||
|
|
||||||
@bpf
|
@bpf
|
||||||
@section("xdp")
|
@section("tracepoint/syscalls/sys_enter_execve")
|
||||||
def hello_world(ctx: struct_xdp_md) -> c_int64:
|
def hello_world(ctx: struct_trace_event_raw_sys_enter) -> c_int64:
|
||||||
return XDP_PASS
|
print("Hello, World!")
|
||||||
|
return c_int64(0)
|
||||||
|
|
||||||
|
|
||||||
@bpf
|
@bpf
|
||||||
|
|||||||
Reference in New Issue
Block a user