Пример #1
0
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
Пример #2
0
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
Пример #3
0
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
Пример #4
0
            \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