Fix data symbol handling
This commit is contained in:
parent
ec6e273a30
commit
43d210a1a0
1 changed files with 21 additions and 11 deletions
|
|
@ -11,7 +11,8 @@ import colorsys
|
|||
|
||||
import cxxfilt
|
||||
from elftools.elf.elffile import ELFFile
|
||||
from elftools.elf.descriptions import describe_symbol_type
|
||||
from elftools.elf.enums import ENUM_ST_SHNDX
|
||||
from elftools.elf.descriptions import describe_symbol_type, describe_sh_type
|
||||
import libarchive
|
||||
import matplotlib.cm
|
||||
|
||||
|
|
@ -63,6 +64,12 @@ def trace_source_files(linker, cmdline, trace_sections=[]):
|
|||
name_normalized = name.replace(' ', '')
|
||||
if name_normalized in symtab_demangled:
|
||||
entry = symtab.get_symbol(symtab_demangled[name_normalized])
|
||||
index = entry['st_shndx']
|
||||
if index in ENUM_ST_SHNDX:
|
||||
return 'no bits'
|
||||
sec = elf.get_section(index)
|
||||
if describe_sh_type(sec['sh_type']) == 'NOBITS':
|
||||
return 'no bits'
|
||||
return entry['st_size']
|
||||
else:
|
||||
return None
|
||||
|
|
@ -71,16 +78,16 @@ def trace_source_files(linker, cmdline, trace_sections=[]):
|
|||
|
||||
s = set()
|
||||
sec_map = { sec.name: i for i, sec in enumerate(elf.iter_sections()) }
|
||||
sec_name = f'.rel.text.{sym}'
|
||||
matches = [ i for name, i in sec_map.items() if re.match(f'\.rel\..*\.{sym}', name) ]
|
||||
if matches:
|
||||
sec = elf.get_section(matches[0])
|
||||
for reloc in sec.iter_relocations():
|
||||
refsym = symtab.get_symbol(reloc['r_info_sym'])
|
||||
s.add(refsym.name)
|
||||
name = refsym.name if refsym.name else elf.get_section(refsym['st_shndx']).name.split('.')[-1]
|
||||
s.add(name)
|
||||
|
||||
if refsym.name not in defs:
|
||||
syms[refsym.name] = fn, lookup_size(refsym.name)
|
||||
if name not in defs:
|
||||
syms[name] = fn, lookup_size(name)
|
||||
refs[sym] = s
|
||||
|
||||
for tsec in trace_sections:
|
||||
|
|
@ -98,7 +105,7 @@ def trace_source_files(linker, cmdline, trace_sections=[]):
|
|||
elf = ELFFile(f)
|
||||
symtab = elf.get_section_by_name('.symtab')
|
||||
for sym in symtab.iter_symbols():
|
||||
if describe_symbol_type(sym['st_info']['type']) == 'FUNC':
|
||||
if describe_symbol_type(sym['st_info']['type']) in ('FUNC', 'OBJECT'):
|
||||
syms_out.add(sym.name)
|
||||
#for sym in defs:
|
||||
# entry = symtab.get_symbol_by_name(sym)
|
||||
|
|
@ -141,7 +148,7 @@ if __name__ == '__main__':
|
|||
syms, refs, syms_out = trace_source_files(args.linker_binary, args.linker_args, trace_sections)
|
||||
|
||||
for name, (obj, size) in syms.items():
|
||||
if path.basename(obj) in args.trim_stubs and size <= 8 and not refs.get(name):
|
||||
if path.basename(obj) in args.trim_stubs and (not isinstance(size, int) or size <= 8) and not refs.get(name):
|
||||
syms_out.discard(name)
|
||||
|
||||
clusters = defaultdict(lambda: [])
|
||||
|
|
@ -151,9 +158,9 @@ if __name__ == '__main__':
|
|||
|
||||
obj_size = defaultdict(lambda: 0)
|
||||
for sym, (obj, size) in syms.items():
|
||||
if size is not None and sym in syms_out:
|
||||
if isinstance(size, int) and sym in syms_out:
|
||||
obj_size[obj] += size
|
||||
max_size = max([ size for _obj, size in syms.values() if size is not None ])
|
||||
max_size = max([ size for _obj, size in syms.values() if isinstance(size, int) ])
|
||||
|
||||
max_osize = max(obj_size.values())
|
||||
|
||||
|
|
@ -174,6 +181,8 @@ if __name__ == '__main__':
|
|||
|
||||
with wrap('digraph G', print) as lvl1print:
|
||||
print('rankdir=LR;')
|
||||
print('ranksep=1;')
|
||||
print('nodesep=0.2;')
|
||||
print()
|
||||
|
||||
for i, (obj, syms) in enumerate(clusters.items()):
|
||||
|
|
@ -191,8 +200,9 @@ if __name__ == '__main__':
|
|||
lvl2print()
|
||||
for sym, size in syms:
|
||||
if sym in syms_out:
|
||||
fc, cc = vhex(size/max_size)
|
||||
lvl2print(f'{mangle(sym)}[label = "{sym} ({size}B)", style="rounded,filled", shape="box", fillcolor="{fc}", fontname="carlito", fontcolor="{cc}" color=none];')
|
||||
size_s = f'{size}B' if isinstance(size, int) else size
|
||||
fc, cc = vhex(size/max_size if isinstance(size, int) else 0)
|
||||
lvl2print(f'{mangle(sym)}[label = "{sym} ({size_s})", style="rounded,filled", shape="box", fillcolor="{fc}", fontname="carlito", fontcolor="{cc}" color=none];')
|
||||
lvl1print()
|
||||
|
||||
for start, ends in refs.items():
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue