|
import gdb |
|
# https://stackoverflow.com/questions/9788679/how-to-get-the-relative-address-of-a-field-in-a-structure-dump-c |
|
|
|
class Memlayout(gdb.Command): |
|
def __init__(self): |
|
super (Memlayout, self).__init__ ('mem-layout', gdb.COMMAND_DATA) |
|
|
|
def invoke(self, arg, from_tty): |
|
argv = gdb.string_to_argv(arg) |
|
if len(argv) != 1: |
|
raise gdb.GdbError('mem-layout takes exactly 1 argument.') |
|
|
|
stype = gdb.parse_and_eval(argv[0]).type |
|
dfs_offset(0, 0, stype, argv[0]) |
|
# print (argv[0], stype, '{') |
|
# for field in stype.fields(): |
|
# tpsz = field.bitsize |
|
# if tpsz == 0: |
|
# tpsz = field.type.sizeof |
|
# print (' [0x%x] %s, size=%x, is_arti=%s, is_basic=%s' % (field.bitpos//8, field.name, tpsz, str(field.artificial), str(field.is_base_class)) ) |
|
# print ('}') |
|
|
|
# helper function |
|
def dfs_offset(cur_level, cur_off, cur_type, filed_name = ""): |
|
try: |
|
fields = cur_type.fields() |
|
except TypeError: |
|
fields = [] |
|
addr = "[0x%03x]"%(cur_off) |
|
addr = addr.ljust(12, ' ') |
|
print("%s%s%s %s, size=0x%x " % ( |
|
addr, ' '*4*cur_level, cur_type.name, filed_name, cur_type.sizeof |
|
), end='') |
|
if len(fields) != 0: |
|
print('{') |
|
else: |
|
print() |
|
inner_off = 0 |
|
fields = sorted(fields, key=lambda x: x.bitpos) |
|
for field in fields: |
|
dfs_offset(cur_level+1, cur_off+inner_off, field.type, filed_name=field.name) |
|
tpsz = field.bitsize |
|
if tpsz == 0: |
|
tpsz = field.type.sizeof |
|
inner_off += tpsz |
|
if len(fields) != 0: |
|
print("%s%s}" % (' '*12, ' '*4*cur_level)) |
|
|
|
|
|
Memlayout() |