xref: /openbmc/u-boot/tools/binman/elf.py (revision 7fe9173b)
1# Copyright (c) 2016 Google, Inc
2# Written by Simon Glass <sjg@chromium.org>
3#
4# SPDX-License-Identifier:      GPL-2.0+
5#
6# Handle various things related to ELF images
7#
8
9from collections import namedtuple, OrderedDict
10import command
11import os
12import re
13import struct
14
15import tools
16
17# This is enabled from control.py
18debug = False
19
20Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak'])
21
22# Used for tests which don't have an ELF file to read
23ignore_missing_files = False
24
25
26def GetSymbols(fname, patterns):
27    """Get the symbols from an ELF file
28
29    Args:
30        fname: Filename of the ELF file to read
31        patterns: List of regex patterns to search for, each a string
32
33    Returns:
34        None, if the file does not exist, or Dict:
35          key: Name of symbol
36          value: Hex value of symbol
37    """
38    stdout = command.Output('objdump', '-t', fname, raise_on_error=False)
39    lines = stdout.splitlines()
40    if patterns:
41        re_syms = re.compile('|'.join(patterns))
42    else:
43        re_syms = None
44    syms = {}
45    syms_started = False
46    for line in lines:
47        if not line or not syms_started:
48            if 'SYMBOL TABLE' in line:
49                syms_started = True
50            line = None  # Otherwise code coverage complains about 'continue'
51            continue
52        if re_syms and not re_syms.search(line):
53            continue
54
55        space_pos = line.find(' ')
56        value, rest = line[:space_pos], line[space_pos + 1:]
57        flags = rest[:7]
58        parts = rest[7:].split()
59        section, size =  parts[:2]
60        if len(parts) > 2:
61            name = parts[2]
62            syms[name] = Symbol(section, int(value, 16), int(size,16),
63                                flags[1] == 'w')
64    return syms
65
66def GetSymbolAddress(fname, sym_name):
67    """Get a value of a symbol from an ELF file
68
69    Args:
70        fname: Filename of the ELF file to read
71        patterns: List of regex patterns to search for, each a string
72
73    Returns:
74        Symbol value (as an integer) or None if not found
75    """
76    syms = GetSymbols(fname, [sym_name])
77    sym = syms.get(sym_name)
78    if not sym:
79        return None
80    return sym.address
81