11import ctypes
22import logging
3+
4+ from ..assignment_info import AssignmentInfo , AssignmentType
35from ..dependency_handler import DependencyHandler
46from .debug_info_gen import debug_info_generation
57from ..dependency_node import DependencyNode
1012
1113class IRGenerator :
1214 # get the assignments dict and add this stuff to it.
13- def __init__ (self , llvm_module , handler : DependencyHandler , assignment = None ):
15+ def __init__ (self , llvm_module , handler : DependencyHandler , assignments ):
1416 self .llvm_module = llvm_module
1517 self .handler : DependencyHandler = handler
1618 self .generated : list [str ] = []
1719 self .generated_debug_info : list = []
20+ # Use struct_name and field_name as key instead of Field object
21+ self .generated_field_names : dict [str , dict [str , ir .GlobalVariable ]] = {}
22+ self .assignments : dict [str , AssignmentInfo ] = assignments
1823 if not handler .is_ready :
1924 raise ImportError (
2025 "Semantic analysis of vmlinux imports failed. Cannot generate IR"
@@ -67,10 +72,42 @@ def struct_processor(self, struct, processing_stack=None):
6772 f"Warning: Dependency { dependency } not found in handler"
6873 )
6974
70- # Actual processor logic here after dependencies are resolved
75+ # Generate IR first to populate field names
7176 self .generated_debug_info .append (
7277 (struct , self .gen_ir (struct , self .generated_debug_info ))
7378 )
79+
80+ # Fill the assignments dictionary with struct information
81+ if struct .name not in self .assignments :
82+ # Create a members dictionary for AssignmentInfo
83+ members_dict = {}
84+ for field_name , field in struct .fields .items ():
85+ # Get the generated field name from our dictionary, or use field_name if not found
86+ if (
87+ struct .name in self .generated_field_names
88+ and field_name in self .generated_field_names [struct .name ]
89+ ):
90+ field_global_variable = self .generated_field_names [struct .name ][
91+ field_name
92+ ]
93+ members_dict [field_name ] = (field_global_variable , field )
94+ else :
95+ raise ValueError (
96+ f"llvm global name not found for struct field { field_name } "
97+ )
98+ # members_dict[field_name] = (field_name, field)
99+
100+ # Add struct to assignments dictionary
101+ self .assignments [struct .name ] = AssignmentInfo (
102+ value_type = AssignmentType .STRUCT ,
103+ python_type = struct .ctype_struct ,
104+ value = None ,
105+ pointer_level = None ,
106+ signature = None ,
107+ members = members_dict ,
108+ )
109+ logger .info (f"Added struct assignment info for { struct .name } " )
110+
74111 self .generated .append (struct .name )
75112
76113 finally :
@@ -85,6 +122,11 @@ def gen_ir(self, struct, generated_debug_info):
85122 struct , self .llvm_module , generated_debug_info
86123 )
87124 field_index = 0
125+
126+ # Make sure the struct has an entry in our field names dictionary
127+ if struct .name not in self .generated_field_names :
128+ self .generated_field_names [struct .name ] = {}
129+
88130 for field_name , field in struct .fields .items ():
89131 # does not take arrays and similar types into consideration yet.
90132 if field .ctype_complex_type is not None and issubclass (
@@ -94,6 +136,18 @@ def gen_ir(self, struct, generated_debug_info):
94136 containing_type = field .containing_type
95137 if containing_type .__module__ == ctypes .__name__ :
96138 containing_type_size = ctypes .sizeof (containing_type )
139+ if array_size == 0 :
140+ field_co_re_name = self ._struct_name_generator (
141+ struct , field , field_index , True , 0 , containing_type_size
142+ )
143+ globvar = ir .GlobalVariable (
144+ self .llvm_module , ir .IntType (64 ), name = field_co_re_name
145+ )
146+ globvar .linkage = "external"
147+ globvar .set_metadata ("llvm.preserve.access.index" , debug_info )
148+ self .generated_field_names [struct .name ][field_name ] = globvar
149+ field_index += 1
150+ continue
97151 for i in range (0 , array_size ):
98152 field_co_re_name = self ._struct_name_generator (
99153 struct , field , field_index , True , i , containing_type_size
@@ -103,6 +157,7 @@ def gen_ir(self, struct, generated_debug_info):
103157 )
104158 globvar .linkage = "external"
105159 globvar .set_metadata ("llvm.preserve.access.index" , debug_info )
160+ self .generated_field_names [struct .name ][field_name ] = globvar
106161 field_index += 1
107162 elif field .type_size is not None :
108163 array_size = field .type_size
@@ -120,6 +175,7 @@ def gen_ir(self, struct, generated_debug_info):
120175 )
121176 globvar .linkage = "external"
122177 globvar .set_metadata ("llvm.preserve.access.index" , debug_info )
178+ self .generated_field_names [struct .name ][field_name ] = globvar
123179 field_index += 1
124180 else :
125181 field_co_re_name = self ._struct_name_generator (
@@ -131,6 +187,7 @@ def gen_ir(self, struct, generated_debug_info):
131187 )
132188 globvar .linkage = "external"
133189 globvar .set_metadata ("llvm.preserve.access.index" , debug_info )
190+ self .generated_field_names [struct .name ][field_name ] = globvar
134191 return debug_info
135192
136193 def _struct_name_generator (
0 commit comments