blob: 97208b1795000d0f4e60a38016a71e61df2c43c0 [file] [log] [blame]
Simon Glassb50e5612017-11-13 18:54:54 -07001# 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
17Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak'])
18
19# Used for tests which don't have an ELF file to read
20ignore_missing_files = False
21
22
23def GetSymbols(fname, patterns):
24 """Get the symbols from an ELF file
25
26 Args:
27 fname: Filename of the ELF file to read
28 patterns: List of regex patterns to search for, each a string
29
30 Returns:
31 None, if the file does not exist, or Dict:
32 key: Name of symbol
33 value: Hex value of symbol
34 """
35 stdout = command.Output('objdump', '-t', fname, raise_on_error=False)
36 lines = stdout.splitlines()
37 if patterns:
38 re_syms = re.compile('|'.join(patterns))
39 else:
40 re_syms = None
41 syms = {}
42 syms_started = False
43 for line in lines:
44 if not line or not syms_started:
45 if 'SYMBOL TABLE' in line:
46 syms_started = True
47 line = None # Otherwise code coverage complains about 'continue'
48 continue
49 if re_syms and not re_syms.search(line):
50 continue
51
52 space_pos = line.find(' ')
53 value, rest = line[:space_pos], line[space_pos + 1:]
54 flags = rest[:7]
55 parts = rest[7:].split()
56 section, size = parts[:2]
57 if len(parts) > 2:
58 name = parts[2]
59 syms[name] = Symbol(section, int(value, 16), int(size,16),
60 flags[1] == 'w')
61 return syms
62
63def GetSymbolAddress(fname, sym_name):
64 """Get a value of a symbol from an ELF file
65
66 Args:
67 fname: Filename of the ELF file to read
68 patterns: List of regex patterns to search for, each a string
69
70 Returns:
71 Symbol value (as an integer) or None if not found
72 """
73 syms = GetSymbols(fname, [sym_name])
74 sym = syms.get(sym_name)
75 if not sym:
76 return None
77 return sym.address