elf_mem_map: array n-dimensional expansion

This commit is contained in:
Yuri D'Elia 2021-06-02 18:57:14 +02:00 committed by DRracer
parent 29b8c89ec2
commit 2718dbb42c

View file

@ -13,6 +13,15 @@ FILL_BYTE = b'\0'
Entry = namedtuple('Entry', ['name', 'loc', 'size']) Entry = namedtuple('Entry', ['name', 'loc', 'size'])
def array_inc(loc, dim, idx=0):
if idx == len(dim):
return True
loc[idx] += 1
if loc[idx] == dim[idx]:
loc[idx] = 0
return array_inc(loc, dim, idx+1)
return False
def get_elf_globals(path): def get_elf_globals(path):
fd = open(path, "rb") fd = open(path, "rb")
if fd is None: if fd is None:
@ -54,7 +63,7 @@ def get_elf_globals(path):
# recurse on type to find the final storage definition # recurse on type to find the final storage definition
type_DIE = DIE type_DIE = DIE
byte_size = None byte_size = None
array_len = None array_dim = []
while True: while True:
if 'DW_AT_byte_size' in type_DIE.attributes: if 'DW_AT_byte_size' in type_DIE.attributes:
byte_size = type_DIE.attributes.get('DW_AT_byte_size') byte_size = type_DIE.attributes.get('DW_AT_byte_size')
@ -62,25 +71,37 @@ def get_elf_globals(path):
break break
type_DIE = type_DIE.get_DIE_from_attribute('DW_AT_type') type_DIE = type_DIE.get_DIE_from_attribute('DW_AT_type')
if type_DIE.tag == 'DW_TAG_array_type': if type_DIE.tag == 'DW_TAG_array_type':
# fetch the first dimension (if known) # fetch array dimensions (if known)
range_DIE = next(type_DIE.iter_children()) for range_DIE in type_DIE.iter_children():
if range_DIE.tag == 'DW_TAG_subrange_type' and \ if range_DIE.tag == 'DW_TAG_subrange_type' and \
'DW_AT_upper_bound' in range_DIE.attributes: 'DW_AT_upper_bound' in range_DIE.attributes:
array_len = range_DIE.attributes['DW_AT_upper_bound'].value + 1 array_dim.append(range_DIE.attributes['DW_AT_upper_bound'].value + 1)
if byte_size is None: if byte_size is None:
continue continue
size = byte_size.value size = byte_size.value
if array_len is None or array_len == 1: if len(array_dim) == 0 or (len(array_dim) == 1 and array_dim[0] == 1):
# plain entry # plain entry
grefs.append(Entry(name, loc, size)) grefs.append(Entry(name, loc, size))
elif size == 1: elif len(array_dim) == 1 and size == 1:
# string # likely string, avoid expansion
grefs.append(Entry('{}[]'.format(name), loc, array_len)) grefs.append(Entry('{}[]'.format(name), loc, array_dim[0]))
else: else:
# expand array entries # expand array entries
for i in range(array_len): array_pos = loc
grefs.append(Entry('{}[{}]'.format(name, i), loc+size*i, size)) array_loc = [0] * len(array_dim)
while True:
# location index
sfx = ''
for d in range(len(array_dim)):
sfx += '[{}]'.format(array_loc[d])
grefs.append(Entry(name + sfx, array_pos, size))
# advance
array_pos += size
if array_inc(array_loc, array_dim):
break
return grefs return grefs