|
@@ -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:
|