Browse Source

elf_mem_map: reduce some duplication

Yuri D'Elia 2 years ago
parent
commit
d1720cba51
1 changed files with 78 additions and 70 deletions
  1. 78 70
      tools/elf_mem_map

+ 78 - 70
tools/elf_mem_map

@@ -70,6 +70,82 @@ def get_FORM_block1(attr):
         return v
     return None
 
+
+def get_array_dims(DIE):
+    array_DIE = get_type_def(DIE, 'DW_TAG_array_type')
+    if array_DIE is None:
+        return []
+
+    array_dim = []
+    for range_DIE in array_DIE.iter_children():
+        if range_DIE.tag == 'DW_TAG_subrange_type' and \
+           'DW_AT_upper_bound' in range_DIE.attributes:
+            array_dim.append(range_DIE.attributes['DW_AT_upper_bound'].value + 1)
+    return array_dim
+
+
+def get_struct_members(DIE, size, expand_structs, struct_gaps):
+    if not expand_structs or size[0].tag == 'DW_TAG_pointer_type':
+        return []
+    struct_DIE = get_type_def(DIE, 'DW_TAG_structure_type')
+    if struct_DIE is None:
+        return []
+
+    members = []
+    for member_DIE in struct_DIE.iter_children():
+        if member_DIE.tag == 'DW_TAG_member' and 'DW_AT_name' in member_DIE.attributes:
+            m_name = member_DIE.attributes['DW_AT_name'].value.decode('ascii')
+            m_off = get_FORM_block1(member_DIE.attributes['DW_AT_data_member_location'])
+            m_byte_size = get_type_size(member_DIE)[1]
+
+            # still expand member arrays
+            m_array_dim = get_array_dims(member_DIE)
+
+            if m_byte_size == 1 and len(m_array_dim) > 1:
+                # likely string, remove one dimension
+                m_byte_size *= m_array_dim.pop()
+            if len(m_array_dim) == 0 or (len(m_array_dim) == 1 and m_array_dim[0] == 1):
+                # plain entry
+                members.append(Member(m_name, m_off, m_byte_size))
+            elif len(m_array_dim) == 1 and m_byte_size == 1:
+                # likely string, avoid expansion
+                members.append(Member(m_name + '[]', m_off, m_array_dim[0]))
+            else:
+                # expand array entries
+                m_array_pos = m_off
+                m_array_loc = [0] * len(m_array_dim)
+                while True:
+                    # location index
+                    sfx = ''
+                    for d in range(len(m_array_dim)):
+                        sfx += '[{}]'.format(str(m_array_loc[d]).rjust(len(str(m_array_dim[d]-1)), '0'))
+                    members.append(Member(m_name + sfx, m_array_pos, m_byte_size))
+                    # advance
+                    if array_inc(m_array_loc, m_array_dim):
+                        break
+                    m_array_pos += m_byte_size
+
+    if struct_gaps and len(members):
+        # fill gaps in the middle
+        members = list(sorted(members, key=lambda x: x.off))
+        last_end = 0
+        for n in range(len(members)):
+            member = members[n]
+            if member.off > last_end:
+                members.append(Member('*UNKNOWN*', last_end, member.off - last_end))
+            last_end = member.off + member.size
+
+    if struct_gaps and len(members):
+        # fill gap at the end
+        members = list(sorted(members, key=lambda x: x.off))
+        last = members[-1]
+        last_end = last.off + last.size
+        if size[1] > last_end:
+            members.append(Member('*UNKNOWN*', last_end, byte_size - last_end))
+
+    return members
+
+
 def get_elf_globals(path, expand_structs, struct_gaps=True):
     fd = open(path, "rb")
     if fd is None:
@@ -121,78 +197,10 @@ def get_elf_globals(path, expand_structs, struct_gaps=True):
             byte_size = size[1]
 
             # fetch array dimensions (if known)
-            array_dim = []
-            array_DIE = get_type_def(DIE, 'DW_TAG_array_type')
-            if array_DIE is not None:
-                for range_DIE in array_DIE.iter_children():
-                    if range_DIE.tag == 'DW_TAG_subrange_type' and \
-                       'DW_AT_upper_bound' in range_DIE.attributes:
-                        array_dim.append(range_DIE.attributes['DW_AT_upper_bound'].value + 1)
+            array_dim = get_array_dims(DIE)
 
             # fetch structure members (one level only)
-            members = []
-            if expand_structs and size[0].tag != 'DW_TAG_pointer_type':
-                struct_DIE = get_type_def(DIE, 'DW_TAG_structure_type')
-                if struct_DIE is not None:
-                    for member_DIE in struct_DIE.iter_children():
-                        if member_DIE.tag == 'DW_TAG_member' and 'DW_AT_name' in member_DIE.attributes:
-                            m_name = member_DIE.attributes['DW_AT_name'].value.decode('ascii')
-                            m_off = get_FORM_block1(member_DIE.attributes['DW_AT_data_member_location'])
-                            m_byte_size = get_type_size(member_DIE)[1]
-
-                            # still expand member arrays
-                            m_array_dim = []
-                            m_array_DIE = get_type_def(member_DIE, 'DW_TAG_array_type')
-                            if m_array_DIE is not None:
-                                for range_DIE in m_array_DIE.iter_children():
-                                    if range_DIE.tag == 'DW_TAG_subrange_type' and \
-                                       'DW_AT_upper_bound' in range_DIE.attributes:
-                                        m_array_dim.append(range_DIE.attributes['DW_AT_upper_bound'].value + 1)
-
-                            if m_byte_size == 1 and len(m_array_dim) > 1:
-                                # likely string, remove one dimension
-                                m_byte_size *= m_array_dim.pop()
-                            if len(m_array_dim) == 0 or (len(m_array_dim) == 1 and m_array_dim[0] == 1):
-                                # plain entry
-                                members.append(Member(m_name, m_off, m_byte_size))
-                            elif len(m_array_dim) == 1 and m_byte_size == 1:
-                                # likely string, avoid expansion
-                                members.append(Member(m_name + '[]', m_off, m_array_dim[0]))
-                            else:
-                                # expand array entries
-                                m_array_pos = m_off
-                                m_array_loc = [0] * len(m_array_dim)
-                                while True:
-                                    # location index
-                                    sfx = ''
-                                    for d in range(len(m_array_dim)):
-                                        sfx += '[{}]'.format(str(m_array_loc[d]).rjust(len(str(m_array_dim[d]-1)), '0'))
-
-                                    members.append(Member(m_name + sfx, m_array_pos, m_byte_size))
-
-                                    # advance
-                                    if array_inc(m_array_loc, m_array_dim):
-                                        break
-                                    m_array_pos += m_byte_size
-
-                if struct_gaps and len(members):
-                    # fill gaps in the middle
-                    members = list(sorted(members, key=lambda x: x.off))
-                    last_end = 0
-                    for n in range(len(members)):
-                        member = members[n]
-                        if member.off > last_end:
-                            members.append(Member('*UNKNOWN*', last_end, member.off - last_end))
-                        last_end = member.off + member.size
-
-                if struct_gaps and len(members):
-                    # fill gap at the end
-                    members = list(sorted(members, key=lambda x: x.off))
-                    last = members[-1]
-                    last_end = last.off + last.size
-                    if byte_size > last_end:
-                        members.append(Member('*UNKNOWN*', last_end, byte_size - last_end))
-
+            members = get_struct_members(DIE, size, expand_structs, struct_gaps)
 
             def expand_members(entry, members):
                 if len(members) == 0: