Skip to content

Commit 9b8462f

Browse files
add bitfield size resolution
1 parent 7851827 commit 9b8462f

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

pythonbpf/vmlinux_parser/class_handler.py

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,41 @@ def process_vmlinux_post_ast(
6262
class_obj = getattr(imported_module, current_symbol_name)
6363
# Inspect the class fields
6464
if hasattr(class_obj, "_fields_"):
65-
for field_name, field_type in class_obj._fields_:
66-
field_table[field_name] = field_type
65+
for field_elem in class_obj._fields_:
66+
field_name = None
67+
field_type = None
68+
bitfield_size = None
69+
if len(field_elem) == 2:
70+
field_name, field_type = field_elem
71+
elif len(field_elem) == 3:
72+
field_name, field_type, bitfield_size = field_elem
73+
field_table[field_name] = [field_type, bitfield_size]
6774
elif hasattr(class_obj, "__annotations__"):
68-
for field_name, field_type in class_obj.__annotations__.items():
69-
field_table[field_name] = field_type
75+
for field_elem in class_obj.__annotations__.items():
76+
field_name = None
77+
field_type = None
78+
bitfield_size = None
79+
if len(field_elem) == 2:
80+
field_name, field_type = field_elem
81+
elif len(field_elem) == 3:
82+
field_name, field_type, bitfield_size = field_elem
83+
field_table[field_name] = [field_type, bitfield_size]
7084
else:
7185
raise TypeError("Could not get required class and definition")
7286

73-
logger.info(f"Extracted fields for {current_symbol_name}: {field_table}")
74-
75-
for elem_name, elem_type in field_table.items():
87+
logger.debug(f"Extracted fields for {current_symbol_name}: {field_table}")
88+
for elem in field_table.items():
89+
elem_name, elem_temp_list = elem
90+
[elem_type, elem_bitfield_size] = elem_temp_list
7691
local_module_name = getattr(elem_type, "__module__", None)
7792
if local_module_name == ctypes.__name__:
78-
new_dep_node.add_field(elem_name, elem_type, ready=True)
93+
new_dep_node.add_field(elem_name, elem_type, ready=False)
94+
new_dep_node.set_field_bitfield_size(elem_name, elem_bitfield_size)
95+
new_dep_node.set_field_ready(elem_name, is_ready=True)
7996
logger.info(f"Field {elem_name} is direct ctypes type: {elem_type}")
8097
elif local_module_name == "vmlinux":
8198
new_dep_node.add_field(elem_name, elem_type, ready=False)
99+
new_dep_node.set_field_bitfield_size(elem_name, elem_bitfield_size)
82100
logger.debug(
83101
f"Processing vmlinux field: {elem_name}, type: {elem_type}"
84102
)

pythonbpf/vmlinux_parser/dependency_node.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Field:
1212
ctype_complex_type: Optional[Any]
1313
containing_type: Optional[Any]
1414
type_size: Optional[int]
15+
bitfield_size: Optional[int]
1516
value: Any = None
1617
ready: bool = False
1718

@@ -51,6 +52,12 @@ def set_ctype_complex_type(self, ctype_complex_type: Any, mark_ready: bool = Tru
5152
if mark_ready:
5253
self.ready = True
5354

55+
def set_bitfield_size(self, bitfield_size: Any, mark_ready: bool = True) -> None:
56+
"""Set the bitfield_size of this field and optionally mark it as ready."""
57+
self.bitfield_size = bitfield_size
58+
if mark_ready:
59+
self.ready = True
60+
5461

5562
@dataclass
5663
class DependencyNode:
@@ -108,6 +115,7 @@ def add_field(
108115
containing_type: Optional[Any] = None,
109116
type_size: Optional[int] = None,
110117
ctype_complex_type: Optional[int] = None,
118+
bitfield_size: Optional[int] = None,
111119
ready: bool = False,
112120
) -> None:
113121
"""Add a field to the node with an optional initial value and readiness state."""
@@ -118,7 +126,8 @@ def add_field(
118126
ready=ready,
119127
containing_type=containing_type,
120128
type_size=type_size,
121-
ctype_complex_type=ctype_complex_type
129+
ctype_complex_type=ctype_complex_type,
130+
bitfield_size=bitfield_size
122131
)
123132
# Invalidate readiness cache
124133
self._ready_cache = None
@@ -178,6 +187,17 @@ def set_field_ctype_complex_type(
178187
# Invalidate readiness cache
179188
self._ready_cache = None
180189

190+
def set_field_bitfield_size(
191+
self, name: str, bitfield_size: Any, mark_ready: bool = True
192+
) -> None:
193+
"""Set a field's bitfield_size and optionally mark it as ready."""
194+
if name not in self.fields:
195+
raise KeyError(f"Field '{name}' does not exist in node '{self.name}'")
196+
197+
self.fields[name].set_bitfield_size(bitfield_size, mark_ready)
198+
# Invalidate readiness cache
199+
self._ready_cache = None
200+
181201
def set_field_ready(self, name: str, is_ready: bool = True) -> None:
182202
"""Mark a field as ready or not ready."""
183203
if name not in self.fields:

0 commit comments

Comments
 (0)