blob: 0fb5a4a8ed637d87feab0b260b4e26763d07b6cf [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
Simon Glass7fe91732017-11-13 18:55:00 -070017# This is enabled from control.py
18debug = False
19
Simon Glassb50e5612017-11-13 18:54:54 -070020Symbol = 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