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