def analyze_die_TAG_type_qualifier(self, die: DIE, tag: type_info.TAG): # type_info取得 type_inf = self.new_type_info(die.offset, tag) # 情報取得 for at in die.attributes.keys(): attr: AttributeValue = die.attributes[at] if at == "DW_AT_name": type_inf.name = attr.value.decode(self._encoding) elif at == "DW_AT_type": type_inf.child_type = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_address_class": type_inf.address_class = self.analyze_die_AT_FORM( attr.form, attr.value) self.register_address_class(type_inf) elif at == "DW_AT_count": pass else: if self._debug_warning: print("unknown attr: " + at) # child check if die.has_children: child: DIE for child in die.iter_children(): if self._debug_warning: print("unproc child.")
def analyze_die_TAG_array_type(self, die: DIE): # type_info取得 type_inf = self.new_type_info(die.offset, utilDwarf.type_info.TAG.array) # Attr check for at in die.attributes.keys(): attr: AttributeValue = die.attributes[at] if at == "DW_AT_type": type_inf.child_type = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_allocated": pass elif at == "DW_AT_associated": pass elif at == "DW_AT_data_location": pass else: if self._debug_warning: print("array:?:" + at) # child check if die.has_children: for child in die.iter_children(): if child.tag == "DW_TAG_subrange_type": # Attr check for at in child.attributes.keys(): attr: AttributeValue = child.attributes[at] if at == "DW_AT_count": type_inf.range = self.analyze_die_AT_FORM( attr.form, attr.value) elif child.tag == "DW_TAG_enumeration_type": pass
def analyze_die_TAG_typedef(self, die: DIE): # type_info取得 type_inf = self.new_type_info(die.offset, utilDwarf.type_info.TAG.typedef) # 情報取得 for at in die.attributes.keys(): attr: AttributeValue = die.attributes[at] if at == "DW_AT_name": type_inf.name = attr.value.decode(self._encoding) elif at == "DW_AT_type": type_inf.child_type = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_decl_file": file_no = self.analyze_die_AT_FORM(attr.form, attr.value) type_inf.decl_file = self._cu_info.file_list[file_no] elif at == "DW_AT_decl_line": type_inf.decl_line = self.analyze_die_AT_FORM( attr.form, attr.value) else: if self._debug_warning: print("typedef:?:" + at) # child check if die.has_children: child: DIE for child in die.iter_children(): if self._debug_warning: print("unproc child.")
def process_imported_units(self, unit_die: DIE): """Include nested partial units. """ # self._logger.debug(f'Importing unit at {unit_die.cu.cu_offset}') for child in unit_die.iter_children(): if child.tag == 'DW_TAG_imported_unit': imported_unit_die = self.get_attr_as_die(child, 'DW_AT_import') if imported_unit_die is not None: self.process_imported_units(imported_unit_die)
def __init__(self, die: DIE): super().__init__(die) self.die = die self.parameters = [] for child in die.iter_children(): if die.tag != 'DW_TAG_formal_parameter': continue self.parameters.append(die.attributes['DW_AT_type'].value)
def import_from_compile_unit(self, die: DIE, component: Component): for child in die.iter_children(): if child.tag == 'DW_TAG_subprogram': if self._include_subprograms: self.import_subprogram(child, component) elif child.tag == 'DW_TAG_variable': if self._include_variables: self.import_global_variable(child, component) elif child.tag == 'DW_TAG_imported_declaration': if self._include_imports: self.import_imported_declaration(child) elif child.tag in [ 'DW_TAG_namespace', 'DW_TAG_class_type', 'DW_TAG_interface_type', 'DW_TAG_structure_type', 'DW_TAG_union_type' ]: self.import_from_compile_unit(child, component) elif child.tag == 'DW_TAG_module' and 'DW_AT_declaration' in child.attributes: pass elif child.tag in [ 'DW_TAG_imported_unit', 'DW_TAG_typedef', 'DW_TAG_unspecified_type', 'DW_TAG_base_type', 'DW_TAG_const_type', 'DW_TAG_volatile_type', 'DW_TAG_restrict_type', 'DW_TAG_array_type', 'DW_TAG_enumeration_type', 'DW_TAG_pointer_type', 'DW_TAG_reference_type', 'DW_TAG_ptr_to_member_type', 'DW_TAG_subroutine_type', 'DW_TAG_rvalue_reference_type', 'DW_TAG_subrange_type', 'DW_TAG_string_type', 'DW_TAG_member', 'DW_TAG_inheritance', 'DW_TAG_template_type_param', 'DW_TAG_template_value_param', 'DW_TAG_GNU_template_template_param', 'DW_TAG_GNU_template_parameter_pack', 'DW_TAG_imported_module', 'DW_TAG_imported_declaration', 'DW_TAG_dwarf_procedure', 'DW_TAG_constant' ]: pass else: print(child.tag, '(child tag)')
def analyze_die_TAG_subprogram(self, die: DIE): f_inf: utilDwarf.func_info = None if "DW_AT_external" in die.attributes.keys(): # 関数 self._func_tbl.append(utilDwarf.func_info()) f_inf = self._func_tbl[len(self._func_tbl) - 1] else: # ? return # AT取得 call_convention = 1 # デフォルトがDW_CC_normal for at in die.attributes.keys(): attr: AttributeValue = die.attributes[at] if at == "DW_AT_external": pass elif at == "DW_AT_name": f_inf.name = die.attributes[at].value.decode(self._encoding) elif at == "DW_AT_type": f_inf.return_type = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_calling_convention": call_convention = die.attributes[at].value elif at == "DW_AT_decl_file": file_no = self.analyze_die_AT_FORM(attr.form, attr.value) f_inf.decl_file = self._cu_info.file_list[file_no] elif at == "DW_AT_decl_line": f_inf.decl_line = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_low_pc": pass elif at == "DW_AT_high_pc": pass elif at == "DW_AT_frame_base": pass elif at == "DW_AT_return_addr": pass else: if self._debug_warning: print("subprogram:?:" + at) # child check if die.has_children: child: DIE for child in die.iter_children(): if child.tag == "DW_TAG_formal_parameter": param_inf = self.analyze_parameter(child) f_inf.params.append(param_inf) elif child.tag == "DW_TAG_unspecified_parameters": param_inf = self.analyze_parameter(child) f_inf.params.append(param_inf) elif child.tag == "DW_TAG_variable": pass
def __init__(self, die: DIE): super().__init__(die) self.name = '<unnamed-union>' if 'DW_AT_name' in die.attributes: self.name = die.attributes['DW_AT_name'].value.decode('utf-8') self.byte_size = die.attributes['DW_AT_byte_size'].value self.variants = OrderedDict() for variant in die.iter_children(): assert variant.tag == 'DW_TAG_member' name = variant.attributes['DW_AT_name'].value.decode('utf-8') value = variant.attributes['DW_AT_type'].value self.variants[name] = value
def analyze_die_TAG_structure_union_type_impl_child( self, die: DIE, type_inf: type_info): for child in die.iter_children(): if child.tag == "DW_TAG_member": #type_inf.member.append(utilDwarf.type_info()) #mem_inf = type_inf.member[len(type_inf.member)-1] #self.analyze_die_TAG_member(child, mem_inf) mem_inf = self.analyze_die_TAG_member(child) type_inf.member.append(mem_inf) elif child.tag == "DW_TAG_array_type": # struct/union/class内で使う型の定義 # よって, member要素ではない self.analyze_die_TAG_array_type(child) else: # ありえないパス if self._debug_warning: print("?: " + child.tag)
def analyze_die_TAG_variable(self, die: DIE): var = utilDwarf.var_info() # AT解析 for at in die.attributes.keys(): attr = die.attributes[at] if at == "DW_AT_external": var.extern = self.analyze_die_AT_FORM(attr.form, attr.value) elif at == "DW_AT_name": var.name = die.attributes[at].value.decode(self._encoding) elif at == "DW_AT_decl_file": file_no = self.analyze_die_AT_FORM(attr.form, attr.value) # ファイル情報取得 var.decl_file = self._cu_info.file_list[file_no] # ファイルが現在解析中のものでない if file_no != 1: var.external_file = True elif at == "DW_AT_decl_line": var.decl_line = self.analyze_die_AT_FORM(attr.form, attr.value) elif at == "DW_AT_type": var.type = die.attributes[at].value elif at == "DW_AT_location": self.analyze_die_AT_location(var, die.attributes[at]) elif at == "DW_AT_declaration": var.not_declaration = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_const_value": pass else: if self._debug_warning: print("variable:?:" + at) # child check if die.has_children: child: DIE for child in die.iter_children(): if self._debug_warning: print("unproc child.") # 変数登録 if var.addr is not None: # アドレスを持っているとき # グローバル変数 self._global_var_tbl.append(var) else: # アドレスを持たない # ローカル変数, 定数, etc pass
def get_array_count(self, die: DIE) -> Optional[int]: for d in die.iter_children(): if d.tag == 'DW_TAG_subrange_type': if 'DW_AT_count' in d.attributes: return d.attributes['DW_AT_count'].value if 'DW_AT_upper_bound' in d.attributes: upper_bound = d.attributes['DW_AT_upper_bound'] if upper_bound.form == 'DW_FORM_exprloc': return None if upper_bound.form in DWARFDB.REFERENCE_FORMS: return None ub = upper_bound.value if 'DW_AT_lower_bound' in d.attributes: lb = d.attributes['DW_AT_lower_bound'].value return ub - lb assert(isinstance(ub, int)) return ub + 1 # TODO: assuming zero-based, but need to know for sure return None
def analyze_die_TAG_member(self, die: DIE) -> type_info: # type_info取得 type_inf = self.new_type_info(die.offset, None) # type要素追加 idx = die.offset for at in die.attributes.keys(): attr: AttributeValue = die.attributes[at] if at == "DW_AT_name": type_inf.name = attr.value.decode(self._encoding) elif at == "DW_AT_type": type_inf.child_type = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_data_member_location": type_inf.member_location = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_byte_size": type_inf.byte_size = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_bit_offset": type_inf.bit_offset = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_bit_size": type_inf.bit_size = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_decl_file": file_no = self.analyze_die_AT_FORM(attr.form, attr.value) type_inf.decl_file = self._cu_info.file_list[file_no] elif at == "DW_AT_decl_line": type_inf.decl_line = self.analyze_die_AT_FORM( attr.form, attr.value) else: if self._debug_warning: print("unknown attribute detected: " + at) # child check if die.has_children: for child in die.iter_children(): pass # debug comment # print(" DIE tag : " + die.tag) # print(" offset: " + str(die.offset)) # print(" name : " + type_inf.name) # print(" type : " + str(type_inf.typedef)) # print(" memloc: " + str(type_inf.member_location)) return type_inf
def __init__(self, die: DIE): super().__init__(die) self.name = '<unnamed-enum>' if 'DW_AT_name' in die.attributes: self.name = die.attributes['DW_AT_name'].value.decode('utf-8') self.literals = OrderedDict() for lit in die.iter_children(): assert lit.tag == 'DW_TAG_enumerator' name = lit.attributes['DW_AT_name'].value.decode('utf-8') value = lit.attributes['DW_AT_const_value'].value self.literals[name] = value if 'DW_AT_type' in die.attributes: self.item_type = die.attributes['DW_AT_type'].value else: # Probably `void` assert False, 'TODO'
def __init__(self, die: DIE): global no_matrices super().__init__(die) self.item_type = die.attributes['DW_AT_type'].value self.dimensions = [] self.is_vla = False for c in die.iter_children(): # This attribute is usually missing in VLAs (TODO: Not supported currently) if 'DW_AT_upper_bound' in c.attributes: dimension = c.attributes['DW_AT_upper_bound'].value + 1 if no_matrices and len(self.dimensions) > 0: self.dimensions[0] = self.dimensions[0] * dimension else: self.dimensions.append(dimension) else: assert self.is_vla is False self.is_vla = True
def analyze_die_TAG_subroutine_type(self, die: DIE): # type_info取得 type_inf = self.new_type_info(die.offset, utilDwarf.type_info.TAG.func) for at in die.attributes.keys(): if at == "DW_AT_name": type_inf.name = die.attributes[at].value.decode(self._encoding) elif at == "DW_AT_type": # 返り値型 type_inf.result_type = die.attributes[at].value elif at == "DW_AT_prototyped": type_inf.prototyped = die.attributes[at].value else: if self._debug_warning: print("subroutine_type:?:" + at) # child check if die.has_children: child: DIE for child in die.iter_children(): param_inf = self.analyze_parameter(child) type_inf.params.append(param_inf)
def analyze_die_TAG_base_type(self, die: DIE): # type_info取得 type_inf = self.new_type_info(die.offset, utilDwarf.type_info.TAG.base) for at in die.attributes.keys(): attr: AttributeValue = die.attributes[at] if at == "DW_AT_name": type_inf.name = self.analyze_die_AT_FORM(attr.form, attr.value) elif at == "DW_AT_encoding": type_inf.encoding = self.analyze_die_AT_FORM( attr.form, attr.value) elif at == "DW_AT_byte_size": type_inf.byte_size = self.analyze_die_AT_FORM( attr.form, attr.value) else: if self._debug_warning: print("base_type:?:" + at) # child check if die.has_children: child: DIE for child in die.iter_children(): if self._debug_warning: print("unproc child.")
def __init__(self, die: DIE): super().__init__(die) self.name = None if 'DW_AT_name' in die.attributes: self.name = die.attributes['DW_AT_name'].value.decode('utf-8') self.byte_size = 0 if 'DW_AT_byte_size' in die.attributes: self.byte_size = die.attributes['DW_AT_byte_size'].value self.members = [] for c in die.iter_children(): if c.tag not in ['DW_TAG_member', 'DW_TAG_inheritance']: continue member_offset = c.attributes['DW_AT_data_member_location'].value type_num = c.attributes['DW_AT_type'].value if 'DW_AT_name' in c.attributes: member_name = c.attributes['DW_AT_name'].value.decode( 'utf-8') if c.tag == 'DW_TAG_member' else '<base>' else: member_name = '<unnamed>' self.members.append((member_offset, type_num, member_name))
def read_die_rec(self, die: DIE) -> None: self.all_dies[die.offset] = die for child in die.iter_children(): self.read_die_rec(child)
def _make_user_type_helper(self, type_die: DIE, alias: Optional[str] = None, visited = None) -> Type: """Create a type object to represent the DWARF type. """ if type_die in self._defined_types: return self._defined_types[type_die] if type_die is None: return self._defined_types.setdefault(None, Type.void()) # Detect cycles in the DIE structures. if type_die in visited: return Type.void() visited.append(type_die) if type_die.tag == 'DW_TAG_base_type': base_type = Type(scalar_type=ScalarType.BASE_TYPE, name=self.name_of(type_die), size=size_of(type_die)) self._base_types[base_type.name] = base_type return self._defined_types.setdefault(type_die, base_type) elif type_die.tag == 'DW_TAG_unspecified_type': unspecified_type = Type(scalar_type=ScalarType.BASE_TYPE, name=self.name_of(type_die)) return self._defined_types.setdefault(type_die, unspecified_type) elif type_die.tag == 'DW_TAG_typedef': qualified_alias = self._dwarf_db.get_qualified_name(type_die) aliased_type_die = self._dwarf_db.get_type_attr_as_die(type_die) if type_die: element_type = self._make_user_type_helper(aliased_type_die, alias=qualified_alias, visited=visited) else: element_type = Type.void() if element_type.name == qualified_alias: return element_type else: alias = Type(name=qualified_alias, element=element_type) return self._defined_types.setdefault(type_die, alias) elif type_die.tag in ['DW_TAG_const_type', 'DW_TAG_volatile_type']: if has_type(type_die): try: element_type = self._make_user_type_helper(self.type_of(type_die), visited=visited) except Exception as e: self._logger.error(str(e)) raise e else: element_type = Type.void() qualified_type = Type(element=element_type) if type_die.tag == 'DW_TAG_const_type': qualified_type.is_constant = True elif type_die.tag == 'DW_TAG_volatile_type': qualified_type.is_volatile = True return self._defined_types.setdefault(type_die, qualified_type) elif type_die.tag in ['DW_TAG_pointer_type', 'DW_TAG_reference_type', 'DW_TAG_rvalue_reference_type']: if has_type(type_die): element_type = self._make_user_type_helper(self.type_of(type_die), visited=visited) else: element_type = Type.void() pointer_size = size_of(type_die) if has_size(type_die) else None pointer_type = Type(element=element_type, size=pointer_size) if type_die.tag == 'DW_TAG_pointer_type': pointer_type.scalar_type = ScalarType.POINTER_TYPE elif type_die.tag == 'DW_TAG_reference_type': pointer_type.scalar_type = ScalarType.REFERENCE_TYPE elif type_die.tag == 'DW_TAG_class_type': pointer_type.scalar_type = ScalarType.RVALUE_REFERENCE_TYPE elif type_die.tag == 'DW_TAG_interface_type': pointer_type.scalar_type = ScalarType.RVALUE_REFERENCE_TYPE if has_name(type_die): # Create a type alias and return that. alias_type = Type(name=self.name_of(type_die), element=pointer_type) return self._defined_types.setdefault(type_die, alias_type) else: return self._defined_types.setdefault(type_die, pointer_type) elif type_die.tag in ['DW_TAG_structure_type', 'DW_TAG_class_type', 'DW_TAG_union_type', 'DW_TAG_interface_type']: composite_name = self.get_type_name(type_die, alias) composite_size = size_of(type_die) if has_size(type_die) else None composite_type = Type(name=composite_name, size=composite_size) if type_die.tag == 'DW_TAG_structure_type': composite_type.composite_type = CompositeType.STRUCT_TYPE elif type_die.tag == 'DW_TAG_union_type': composite_type.composite_type = CompositeType.UNION_TYPE elif type_die.tag == 'DW_TAG_class_type': composite_type.composite_type = CompositeType.CLASS_TYPE elif type_die.tag == 'DW_TAG_interface_type': composite_type.composite_type = CompositeType.CLASS_TYPE forward_type = Type(name=composite_name, size=composite_size) forward_type.composite_type = composite_type.composite_type self._defined_types[type_die] = forward_type for member_die in type_die.iter_children(): if member_die.tag == 'DW_TAG_member': if not has_type(member_die): print(member_die) member_type = self._make_user_type_helper(self.type_of(member_die), visited=visited) if member_type.name is None: member_type = member_type.clone() member_offset = member_offset_of(member_die) if has_member_offset(member_die) else 0 if member_offset is not None: if has_name(member_die): composite_type.add_member(Type(name=self.name_of(member_die), offset=member_offset, element=member_type)) else: composite_type.add_member(Type(offset=member_offset, element=member_type)) else: if 'DW_AT_const_value' in member_die.attributes: # TODO: add constant pass else: # TODO: must be static pass elif member_die.tag == 'DW_TAG_inheritance': member_type_die = self.type_of(member_die) member_type = self._make_user_type_helper(member_type_die, visited=visited) member_offset = member_offset_of(member_die) if has_member_offset(member_die) else 0 base_name = 'inherited$' if has_name(member_type_die): base_name = f'inherited${self.name_of(member_type_die)}' composite_type.add_member(Type(name=base_name, offset=member_offset, element=member_type)) elif member_die.tag == 'DW_TAG_variant_part': # TODO: implement pass self._defined_types[type_die] = composite_type return composite_type elif type_die.tag in ['DW_TAG_enumeration_type']: enum_name = self.get_type_name(type_die, alias) enum_size = size_of(type_die) if has_size(type_die) else None enum_type = Type(composite_type=CompositeType.ENUM_TYPE, name=enum_name, size=enum_size) for member_die in type_die.iter_children(): if member_die.tag == 'DW_TAG_enumerator': offset = member_die.attributes['DW_AT_const_value'].value enum_type.add_member(Type(scalar_type=ScalarType.ENUMERATOR_TYPE, name=self.name_of(member_die), offset=offset)) return self._defined_types.setdefault(type_die, enum_type) elif type_die.tag == 'DW_TAG_subroutine_type': function_name = self.get_type_name(type_die, alias) if has_type(type_die): return_type = self._make_user_type_helper(self.type_of(type_die), visited=visited) else: return_type = Type.void() function_type = Type(composite_type=CompositeType.FUNCTION_TYPE, name=function_name, element=return_type) ordinal = 0 for param_die in type_die.iter_children(): if param_die.tag == 'DW_TAG_formal_parameter': param_type = self._make_user_type_helper(self.type_of(param_die), visited=visited) function_type.add_member(Type(offset=ordinal, element=param_type)) ordinal += 1 elif param_die.tag == 'DW_TAG_unspecified_parameters': function_type.add_member(Type(offset=ordinal, element=Type.variadic())) ordinal += 1 else: self._logger.warning(f'While defining subroutine type "{function_name}", encountered an unhandled tag "{param_die.tag}"') return self._defined_types.setdefault(type_die, function_type) elif type_die.tag == 'DW_TAG_array_type': array_name = self.get_type_name(type_die, alias) element_type = self._make_user_type_helper(self._dwarf_db.get_type_attr_as_die(type_die), visited=visited) array_count = self._dwarf_db.get_array_count(type_die) array_type = Type(scalar_type=ScalarType.ARRAY_TYPE, name=array_name, element=element_type, array_count=array_count) return self._defined_types.setdefault(type_die, array_type) elif type_die.tag in ['DW_TAG_restrict_type']: return self._make_user_type_helper(self._dwarf_db.get_type_attr_as_die(type_die), visited=visited) elif type_die.tag in ['DW_TAG_ptr_to_member_type']: p2m_name = self.get_type_name(type_die, alias) if has_type(type_die): member_type = self._make_user_type_helper(self._dwarf_db.get_type_attr_as_die(type_die), visited=visited) else: member_type = Type.void() if 'DW_AT_containing_type' in type_die.attributes: containing_die = self._dwarf_db.get_attr_as_die(type_die, 'DW_AT_containing_type') containing_type = self._make_user_type_helper(containing_die, visited=visited) else: containing_type = Type.void() p2m_type = Type(composite_type=CompositeType.PTR_TO_MEMBER_TYPE, name=p2m_name) p2m_type.add_member(containing_type) p2m_type.add_member(member_type) return p2m_type elif type_die.tag == 'DW_TAG_string_type': assert('DW_AT_type' not in type_die.attributes) if 'char' not in self._base_types: char_type = Type(scalar_type=ScalarType.BASE_TYPE, name='char', size=1) self._base_types[char_type.name] = char_type else: char_type = self._base_types['char'] if 'DW_AT_byte_size' in type_die.attributes: # Treat it as a char array of fixed length. size = type_die.attributes['DW_AT_byte_size'].value array_type = Type(scalar_type=ScalarType.ARRAY_TYPE, element=char_type, array_count=size) return self._defined_types.setdefault(type_die, array_type) else: # Treat it a char *. cptr_type = Type(scalar_type=ScalarType.POINTER_TYPE, element=char_type) return self._defined_types.setdefault(type_die, cptr_type) elif type_die.tag == 'DW_TAG_subrange_type': assert('DW_AT_type' in type_die.attributes) return self._make_user_type_helper(self._dwarf_db.get_type_attr_as_die(type_die), visited=visited) elif type_die.tag == 'DW_TAG_variant_part': return None else: print(type_die) assert(type_die and False)
def import_local_elements(self, die: DIE, component: Component, function: Function, parent_function: Function, inside_lexical_block: bool = False, location_map = None, abstract_map=None): """Imports function elements. Notes ----- Local variables can share locations with the formal parameters. For example, opaque parameters that are simply type cast to a structure pointer occur quite often. In these cases, we want the local variable to take priority over the parameter. If a variable shares a Location with a parameter, that location will be removed from the parameter's location list. In short, the variable hides the parameter at that location. Also, inlined functions may have parameters or local variables that share locations with the containing function's variables and/or parameters. Thus, if the type stored at the location differs from the containing function, we use the most specific type - the local hides the pre-existing variable from that location. But if the name of the variable or parameter is "artificial" then the artificial name is replaced/inherited from the variable that shares the location. """ for child in die.iter_children(): if child.tag == 'DW_TAG_variable': if self._include_local_variables: if self._dwarf_db.is_concrete_variable(child): local_var = self.import_local_variable(child, component, function, abstract_map) if local_var: # print(self._dwarf_db.is_concrete_variable(die), child) self.import_locations(local_var, child, location_map, [LocationType.STATIC_LOCAL, LocationType.STATIC_GLOBAL]) # else: # self._logger.warning(f'In {function.name} variable is not concrete\n{child}') elif child.tag == 'DW_TAG_formal_parameter': if self._include_parameters: param = self.import_parameter(child, function, parent_function, abstract_map) if param: self.import_locations(param, child, location_map, [LocationType.STATIC_LOCAL]) elif child.tag == 'DW_TAG_unspecified_parameters': p = Parameter(name='...', type=None) function.add_parameter(p) elif child.tag == 'DW_TAG_lexical_block': self.import_local_elements(child, component, function, parent_function, inside_lexical_block=True, location_map=location_map, abstract_map=abstract_map) elif child.tag == 'DW_TAG_inlined_subroutine': if self._include_inlined_functions: f = self.import_inlined_subroutine(child, component, function if parent_function is None else parent_function, location_map, abstract_map) function.add_inlined_function(f) elif child.tag == 'DW_TAG_subprogram': if self._dwarf_db.is_concrete_subprogram(child): self._logger.warning(f'In {function.name} a concrete subprogram inside subprogram\n{child}') else: pass elif child.tag in [ 'DW_TAG_template_type_parameter', 'DW_TAG_template_type_param', 'DW_TAG_template_value_param', 'DW_TAG_GNU_formal_parameter_pack', 'DW_TAG_GNU_template_parameter_pack', 'DW_TAG_GNU_call_site', 'DW_TAG_label', 'DW_TAG_imported_declaration', 'DW_TAG_constant', # Types are picked up via the variables, as needed. 'DW_TAG_typedef', 'DW_TAG_structure_type', 'DW_TAG_union_type', 'DW_TAG_class_type', 'DW_TAG_interface_type', 'DW_TAG_const_type', 'DW_TAG_pointer_type', 'DW_TAG_enumeration_type' ]: # TODO: use DW_TAG_label to inform control-flow reconstruction pass else: self._logger.warning(f'unhandled tag {child.tag} inside {die.tag}\n\tParent DIE = {die}\n\tChild DIE = {child}')