diff --git a/scripts/ctx.py b/scripts/ctx.py index cb4e40a1..5953142c 100755 --- a/scripts/ctx.py +++ b/scripts/ctx.py @@ -701,11 +701,16 @@ def collect(obj_paths, *, type = info[int(type['DW_AT_type'].strip('<>'), 0)] if (type.name is not None and type.tag != 'DW_TAG_subroutine_type'): + # if we have no file guess from obj path + if 'DW_AT_decl_file' in type: + file_ = files.get(int(type['DW_AT_decl_file']), '?') + else: + file_ = re.sub('(\.o)?$', '.c', obj_path, 1) name_ = type.name size_ = sizeof(type, seen | {entry.off}) children_, notes_, dirty_ = childrenof( type, seen | {entry.off}) - children.append(CtxResult(file, name_, size_, + children.append(CtxResult(file_, name_, size_, children=children_, notes=notes_)) dirty = dirty or dirty_ @@ -717,11 +722,16 @@ def collect(obj_paths, *, for child in entry.children: if child.tag != 'DW_TAG_member': continue + # if we have no file guess from obj path + if 'DW_AT_decl_file' in child: + file_ = files.get(int(child['DW_AT_decl_file']), '?') + else: + file_ = re.sub('(\.o)?$', '.c', obj_path, 1) name_ = child.name size_ = sizeof(child, seen | {entry.off}) children_, notes_, dirty_ = childrenof( child, seen | {entry.off}) - children.append(CtxResult(file, name_, size_, + children.append(CtxResult(file_, name_, size_, i=child.off, children=children_, notes=notes_)) @@ -793,6 +803,12 @@ def collect(obj_paths, *, if param.tag != 'DW_TAG_formal_parameter': continue + # if we have no file guess from obj path + if 'DW_AT_decl_file' in param: + file_ = files.get(int(param['DW_AT_decl_file']), '?') + else: + file_ = re.sub('(\.o)?$', '.c', obj_path, 1) + # find name, if there is one name_ = param.name if param.name is not None else '(unnamed)' @@ -802,7 +818,7 @@ def collect(obj_paths, *, # find children, recursing if necessary children_, notes_, _ = childrenof(param) - params.append(CtxResult(file, name_, size_, + params.append(CtxResult(file_, name_, size_, i=param.off, children=children_, notes=notes_)) diff --git a/scripts/stack.py b/scripts/stack.py index 853b5ced..4a29fbf2 100755 --- a/scripts/stack.py +++ b/scripts/stack.py @@ -633,16 +633,17 @@ class Parser: self.data[self.i:self.i+32])) class CGNode(co.namedtuple('CGNode', [ - 'name', 'size', 'qualifiers', 'calls'])): + 'name', 'file', 'size', 'qualifiers', 'calls'])): __slots__ = () - def __new__(cls, name, size, qualifiers, calls=None): - return super().__new__(cls, name, size, qualifiers, + def __new__(cls, name, file, size, qualifiers, calls=None): + return super().__new__(cls, name, file, size, qualifiers, calls if calls is not None else set()) def __repr__(self): - return '%s(%r, %r, %r, %r)' % ( + return '%s(%r, %r, %r, %r, %r)' % ( self.__class__.__name__, self.name, + self.file, self.size, self.qualifiers, self.calls) @@ -699,13 +700,15 @@ def collect_callgraph(ci_path, cg_ = {} for node in cg['graph'][0].get('node') or []: - m = re.search('([0-9]+) bytes \((.*)\)', node['label'][0]) - if not m: - continue name = cg_key(node['title'][0]) + label = node['label'][0].split('\\n') + if len(label) < 3: + continue + file = cg_key(label[1]+':').split(':', 1)[0] + m = re.match('([0-9]+) bytes \((.*)\)', label[2]) size = int(m.group(1)) qualifiers = [q.strip() for q in m.group(2).split(',')] - cg_[name] = CGNode(name, size, qualifiers) + cg_[name] = CGNode(name, file, size, qualifiers) for edge in cg['graph'][0].get('edge') or []: cg_[cg_key(edge['sourcename'][0])].calls.add( @@ -777,12 +780,12 @@ def collect(obj_paths, ci_paths, *, if call not in cg: continue node_ = cg[call] + file_ = node_.file name_ = node_.name.split(':', 1)[-1] frame_ = frameof(node_) limit_ = limitof(node_, seen | {node.name}) children_, notes_, dirty_ = childrenof(node_, seen | {node.name}) - # TODO this file is a hack... how do we find the correct file? - children.append(StackResult(file, name_, frame_, limit_, + children.append(StackResult(file_, name_, frame_, limit_, children=children_, notes=notes_)) dirty = dirty or dirty_ diff --git a/scripts/structs.py b/scripts/structs.py index 11bf39aa..c19fe2b7 100755 --- a/scripts/structs.py +++ b/scripts/structs.py @@ -546,12 +546,17 @@ def collect(obj_paths, *, 'DW_TAG_union_type'}: children = [] for child in entry.children: + # if we have no file guess from obj path + if 'DW_AT_decl_file' in child: + file_ = files.get(int(child['DW_AT_decl_file']), '?') + else: + file_ = re.sub('(\.o)?$', '.c', obj_path, 1) name_ = child.name size_ = sizeof(child) align_ = alignof(child) children_ = childrenof(child) children.append(StructResult( - file, name_, size_, align_, + file_, name_, size_, align_, i=child.off, children=children_)) # indirect type?