def visit_structure_type(die,dies_dict): # enumerate members of structure or union type_info = { 'kind': DW_TAG[die.tag], 'byte_size': get_int(die, 'byte_size') } members = [] for child in die.children: name = get_str(child, 'name') member_info = { 'name': name } # handle union as "structure with all fields at offset 0" offset = 0 if 'data_member_location' in child.attr_dict: expr = child.attr_dict['data_member_location'].value assert(expr.instructions[0].opcode == DW_OP.plus_uconst) offset = expr.instructions[0].operand_1 member_info['offset'] = offset type = dies_dict.get(get_ref(child, 'type')) (type,indirection) = parse_type(type, dies_dict) member_info['indirection'] = indirection member_info['type'] = type_name(type) members.append(member_info) if DEBUG: print(member_info) worklist.append(type) type_info['members'] = members return type_info
def parse_type(type, dies_dict): ''' Parse type by removing modifiers and counting pointer indirections. ''' indirection = 0 while type is not None and type.tag in [DW_TAG.const_type, DW_TAG.volatile_type, DW_TAG.typedef, DW_TAG.pointer_type]: if type.tag == DW_TAG.pointer_type: indirection += 1 type = dies_dict.get(get_ref(type, 'type'), None) return (type, indirection)
def visit_array_type(die,dies_dict): type = dies_dict.get(get_ref(die, 'type')) (type,indirection) = parse_type(type, dies_dict) type_info = { 'kind': 'array_type', 'indirection': indirection, 'type': type_name(type), 'length': None } for child in die.children: if child.tag != DW_TAG.subrange_type: continue upper_bound = get_int(child, 'upper_bound') if upper_bound is not None: type_info['length'] = upper_bound + 1 if DEBUG: print(type_info) return type_info
def get_type_ref(die, attr): ''' Get type ref for a type attribute. A type ref is a function that, given a name, constructs a syntax tree for referring to that type. ''' type_ = get_ref(die, 'type') if DEBUG: print (die.offset, "->", type_) if type_ is None: ref = base_type_ref('void') else: ref = names.get(type_) if ref is None: #ref = base_type_ref('unknown_%i' % type_) ref = to_c_process(by_offset[type_], by_offset, names, rv, written, preref=True) elif ref is ERROR: raise ValueError("Unexpected recursion") return ref
def get_type_ref(die, attr): ''' Get type ref for a type attribute. A type ref is a function that, given a name, constructs a syntax tree for referring to that type. ''' type_ = get_ref(die, 'type') if DEBUG: print(die.offset, "->", type_) if type_ is None: ref = base_type_ref('void') else: ref = names.get(type_) if ref is None: #ref = base_type_ref('unknown_%i' % type_) ref = to_c_process(by_offset[type_], by_offset, names, rv, written, preref=True) elif ref is ERROR: raise ValueError("Unexpected recursion") return ref
def get_ref_lookup(die, attr, by_offset): '''Get referenced die''' try: return by_offset[get_ref(die, attr)] except KeyError: return None