def cu_offset_to_path_map(config: Config, dwarf_info): """Return a map from Dwarf compilation unit offsets to source paths.""" prefixes = config.get_re('collect.prefix') address_map = {} for compilation_unit in dwarf_info.iter_CUs(): path = pathlib.Path(compilation_unit.get_top_DIE().get_full_path()) source = simplify_source(str(path.resolve()), prefixes) address_map[compilation_unit.cu_offset] = source return address_map
def postprocess_symbols(config: Config, symbols: SymbolDF) -> SymbolDF: """Postprocess a symbol table after collecting from one source. If the symbol table contains FILE symbols, they will be removed and replaced by a 'file' column on other symbols. If the symbol table contains ARM mode symbols, they will be removed and replaced by an 'arm' column on other symbols. """ files = [] arms = [] arm_symbols = {} current_file = '' current_arm = '' has_file = False if config['collect.prefix-file']: prefixes = config.get_re('collect.prefix') else: prefixes = None if 'type' in symbols.columns: for symbol in symbols.itertuples(): if symbol.type == 'FILE': has_file = True current_file = symbol.symbol if prefixes: current_file = simplify_source(current_file, prefixes) elif symbol.type == 'NOTYPE': if symbol.symbol.startswith('$'): if current_arm or symbol.symbol in ARM_SPECIAL_SYMBOLS: current_arm = symbol.symbol arm_symbols[current_arm] = True files.append(current_file) arms.append(current_arm) if has_file: symbols['file'] = files if current_arm: symbols['arm'] = arms if has_file: symbols = symbols[symbols['type'] != 'FILE'] if current_arm: syms = arm_symbols.keys() symbols = symbols[~symbols.symbol.isin(syms)] return symbols
def read_symbols(config: Config, filename: str) -> SymbolDF: """Read a binary's symbol map using bloaty.""" column_map = { 'compileunits': 'cu', 'sections': 'section', 'symbols': 'symbol', 'vmsize': 'size', } process = memdf.util.subprocess.run_tool_pipe(config, [ 'bloaty', '--tsv', '--demangle=none', '-n', '0', '-d', 'compileunits,sections,symbols', filename ]) if not process or not process.stdout: return SymbolDF() df = pd.read_table(io.TextIOWrapper(process.stdout, newline=os.linesep), usecols=list(column_map.keys()), dtype=SymbolDF.dtype, na_filter=False) df.rename(inplace=True, columns=column_map) prefixes = config.get_re('collect.prefix') df['cu'] = df['cu'].apply(lambda s: simplify_source(s, prefixes)) return df
\s(?P<kind>\S) \s(?P<symbol>\S+) (\t(?P<source>\S+):(?P<line>\d+))? """, re.VERBOSE) columns = ['address', 'kind', 'symbol', 'cu'] rows = [] while line := text.readline(): if not (match := decoder.match(line.rstrip())): continue if a := match.group('address'): address = int(a, 16) else: address = 0 source = match.group('source') or '' if source: source = simplify_source(source, prefixes) rows.append( [address, match.group('kind'), match.group('symbol'), source]) return SymbolSourceDF(rows, columns=columns) def add_cu(config: Config, filename: str, symbols: SymbolDF) -> SymbolDF: """Add a 'cu' (compilation unit) column to a symbol table.""" sources = read_sources(config, filename).set_index(['symbol', 'address']) symbols = pd.merge(symbols, sources, on=('symbol', 'address'), how='left') symbols.fillna({'cu': ''}, inplace=True) return symbols