Skip to content

Instantly share code, notes, and snippets.

@spiiin
Created June 9, 2021 19:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save spiiin/d9edf2c32f555b530b1413d632c14888 to your computer and use it in GitHub Desktop.
Save spiiin/d9edf2c32f555b530b1413d632c14888 to your computer and use it in GitHub Desktop.
dwex_get_class_padding
def calc_padding(size, roundFactor):
return ((size - 1) // roundFactor + 1) * roundFactor
#for 64-bits archs
def calc_padding_8(size):
return calc_padding(size, 8)
def print_class_padding(class_die):
virtual_ancestors = OrderedDict()
virtual_ancestors_proccessed = set()
class_size_without_padding = 0 # sum of member sizes
class_size_with_padding = 0 # sum of member sizes with padding
def print_members_info(class_die, collect_virtuals):
nonlocal class_size_with_padding
members = get_class_padding(compilation_unit, class_die)
ancestors = get_class_ancestors(compilation_unit, class_die)
#print("ttt", ancestors)
#presort ancestors
normal_ancestors = []
for ancestor in ancestors:
if ancestor.is_virtual and collect_virtuals:
#first pass - collect virtuals
if ancestor.ancestor_rec[0] not in virtual_ancestors:
virtual_ancestors[ancestor.ancestor_rec[0]] = ancestor
else:
#second pass - process virtuals as normal, but only once
if ancestor.is_virtual:
ancestor_class = ancestor.ancestor_rec[0]
if ancestor_class not in virtual_ancestors_proccessed:
virtual_ancestors_proccessed.add(ancestor_class)
normal_ancestors.append(ancestor) #proccess virtual ancestor as normal, but only once
else:
#process non-virtual ancestor
normal_ancestors.append(ancestor)
### print normal ancestors
for ancestor in normal_ancestors:
ancestor_class, ancestor_die, ancestor_size = ancestor.ancestor_rec
is_virtual = ancestor.is_virtual
#print("%-24s | %3s |<%3s> | %-10s"%("<ancestor>", "[]" , ancestor_size, ancestor_class))
print_members_info(ancestor_die, collect_virtuals)
print("^^^------- %s --------^^^"%ancestor_class)
#print members
prev_member = members[0] if len(members) > 0 else None
#corner case for empty class
if not prev_member:
#empty class
return
#
print("%-24s | %3s |<%3s> | %-10s"%(prev_member.name, prev_member.location, prev_member.member_size, prev_member.member_type))
class_size_with_padding += prev_member.member_size
#
for m in members[1:]:
padding = m.location - (prev_member.location + prev_member.member_size)
if padding != 0:
print("%-24s | %3s |<%3s> | %-10s"%("---padding---", prev_member.location + prev_member.member_size, padding, "---unused---"))
class_size_with_padding += padding
#
print("%-24s | %3s |<%3s> | %-10s"%(m.name, m.location, m.member_size, m.member_type))
class_size_with_padding += m.member_size
#
prev_member = m
#
class_size_with_padding = calc_padding_8(class_size_with_padding)
print(" padded offset:", class_size_with_padding)
#
#print normal ancestors
print_members_info(class_die, True)
print("^^^------- %s --------^^^"%"__self__")
#print virtual ancestors
for ancestor in virtual_ancestors.values():
ancestor_class, ancestor_die, ancestor_size = ancestor.ancestor_rec
is_virtual = ancestor.is_virtual
#print("%-24s | %3s |<%3s> | %-10s"%("<ancestor>", "[]" , ancestor_size, ancestor_class))
print_members_info(ancestor_die, False)
print("^^^-------- %s (virtual)-----------"%ancestor_class)
###print total size
print("----------------------------------------------------------")
#class_size_calced = prev_member.location + prev_member.member_size
#class_size_calced += sum(ancestor.ancestor_rec[2] for ancestor in ancestors)
print("Total struct size (calculated) : %d"% class_size_with_padding)
print("Total struct size (read from bin) : %d"% class_size)
print_class_padding(class_die)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment