From db514f20f2e5b5f21bd11e5b47e5a1ee03718d23 Mon Sep 17 00:00:00 2001 From: Christopher Haster Date: Sat, 5 Aug 2023 16:07:06 -0500 Subject: [PATCH] Fixed structs.py when structs contain substructs The previous state machine would happily pick up random names if the struct had no name of its own. This was picking up typedefs of random structs and making things really confusing. Now the rule is that unnamed structs are not printed. Unnamed structs are usually implementation details so their size is not really useful. Also made the parsing state machine for objdump outputs more resilient to these sort of issues. Also changed structs.py to also report unions if they have a name. --- scripts/code.py | 13 +++++++++---- scripts/data.py | 13 +++++++++---- scripts/structs.py | 22 ++++++++++++++-------- 3 files changed, 32 insertions(+), 16 deletions(-) diff --git a/scripts/code.py b/scripts/code.py index ba8bd1e0..b445f13e 100755 --- a/scripts/code.py +++ b/scripts/code.py @@ -235,6 +235,10 @@ def collect(obj_paths, *, is_func = False f_name = None f_file = None + def append(): + # ignore non-functions and unnamed files + if is_func and f_name: + defs[f_name] = files.get(f_file, '?') # note objdump-path may contain extra args cmd = objdump_path + ['--dwarf=info', path] if args.get('verbose'): @@ -250,15 +254,16 @@ def collect(obj_paths, *, m = info_pattern.match(line) if m: if m.group('tag'): - if is_func: - defs[f_name] = files.get(f_file, '?') + append() is_func = (m.group('tag') == 'DW_TAG_subprogram') + f_name = None + f_file = None elif m.group('name'): f_name = m.group('name') elif m.group('file'): f_file = int(m.group('file')) - if is_func: - defs[f_name] = files.get(f_file, '?') + # don't forget the last function + append() proc.wait() if proc.returncode != 0: if not args.get('verbose'): diff --git a/scripts/data.py b/scripts/data.py index e9770aa1..6e4ed3af 100755 --- a/scripts/data.py +++ b/scripts/data.py @@ -235,6 +235,10 @@ def collect(obj_paths, *, is_func = False f_name = None f_file = None + def append(): + # ignore non-functions and unnamed files + if is_func and f_name: + defs[f_name] = files.get(f_file, '?') # note objdump-path may contain extra args cmd = objdump_path + ['--dwarf=info', path] if args.get('verbose'): @@ -250,15 +254,16 @@ def collect(obj_paths, *, m = info_pattern.match(line) if m: if m.group('tag'): - if is_func: - defs[f_name] = files.get(f_file, '?') + append() is_func = (m.group('tag') == 'DW_TAG_subprogram') + f_name = None + f_file = None elif m.group('name'): f_name = m.group('name') elif m.group('file'): f_file = int(m.group('file')) - if is_func: - defs[f_name] = files.get(f_file, '?') + # don't forget the last function + append() proc.wait() if proc.returncode != 0: if not args.get('verbose'): diff --git a/scripts/structs.py b/scripts/structs.py index e9b97e7d..2c0759a6 100755 --- a/scripts/structs.py +++ b/scripts/structs.py @@ -192,6 +192,11 @@ def collect(obj_paths, *, s_name = None s_file = None s_size = None + def append(): + # ignore non-structs and unnamed files + if is_struct and s_name: + file = files.get(s_file, '?') + results_.append(StructResult(file, s_name, s_size)) # note objdump-path may contain extra args cmd = objdump_path + ['--dwarf=info', path] if args.get('verbose'): @@ -202,24 +207,25 @@ def collect(obj_paths, *, universal_newlines=True, errors='replace', close_fds=False) - for line in proc.stdout: + for i, line in enumerate(proc.stdout): # state machine here to find structs m = info_pattern.match(line) if m: if m.group('tag'): - if is_struct: - file = files.get(s_file, '?') - results_.append(StructResult(file, s_name, s_size)) - is_struct = (m.group('tag') == 'DW_TAG_structure_type') + append() + is_struct = (m.group('tag') == 'DW_TAG_structure_type' + or m.group('tag') == 'DW_TAG_union_type') + s_name = None + s_file = None + s_size = None elif m.group('name'): s_name = m.group('name') elif m.group('file'): s_file = int(m.group('file')) elif m.group('size'): s_size = int(m.group('size')) - if is_struct: - file = files.get(s_file, '?') - results_.append(StructResult(file, s_name, s_size)) + # don't forget the last struct + append() proc.wait() if proc.returncode != 0: if not args.get('verbose'):