summaryrefslogtreecommitdiffstats
path: root/tools/binman/elf.py
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2017-11-13 18:54:54 -0700
committerSimon Glass <sjg@chromium.org>2017-12-12 19:53:45 -0700
commitb50e5611a6b5dff4bc2ae47d332ba0d046e2a782 (patch)
treeec72ed0ab95983e04c4d4697d3af70aac64ff33b /tools/binman/elf.py
parentcf71338ee7a1dc16f13a4f1b89f32c624210df45 (diff)
downloadu-boot-b50e5611a6b5dff4bc2ae47d332ba0d046e2a782.tar.gz
u-boot-b50e5611a6b5dff4bc2ae47d332ba0d046e2a782.tar.xz
u-boot-b50e5611a6b5dff4bc2ae47d332ba0d046e2a782.zip
binman: Add a function to read ELF symbols
In some cases we need to read symbols from U-Boot. At present we have a a few cases which does this via 'nm' and 'grep'. It is better to use objdump since that tells us the size of the symbols and also whether it is weak or not. Add a new module which reads ELF information from files. Update existing uses of 'nm' to use this module. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'tools/binman/elf.py')
-rw-r--r--tools/binman/elf.py77
1 files changed, 77 insertions, 0 deletions
diff --git a/tools/binman/elf.py b/tools/binman/elf.py
new file mode 100644
index 0000000000..97208b1795
--- /dev/null
+++ b/tools/binman/elf.py
@@ -0,0 +1,77 @@
+# Copyright (c) 2016 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Handle various things related to ELF images
+#
+
+from collections import namedtuple, OrderedDict
+import command
+import os
+import re
+import struct
+
+import tools
+
+Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak'])
+
+# Used for tests which don't have an ELF file to read
+ignore_missing_files = False
+
+
+def GetSymbols(fname, patterns):
+ """Get the symbols from an ELF file
+
+ Args:
+ fname: Filename of the ELF file to read
+ patterns: List of regex patterns to search for, each a string
+
+ Returns:
+ None, if the file does not exist, or Dict:
+ key: Name of symbol
+ value: Hex value of symbol
+ """
+ stdout = command.Output('objdump', '-t', fname, raise_on_error=False)
+ lines = stdout.splitlines()
+ if patterns:
+ re_syms = re.compile('|'.join(patterns))
+ else:
+ re_syms = None
+ syms = {}
+ syms_started = False
+ for line in lines:
+ if not line or not syms_started:
+ if 'SYMBOL TABLE' in line:
+ syms_started = True
+ line = None # Otherwise code coverage complains about 'continue'
+ continue
+ if re_syms and not re_syms.search(line):
+ continue
+
+ space_pos = line.find(' ')
+ value, rest = line[:space_pos], line[space_pos + 1:]
+ flags = rest[:7]
+ parts = rest[7:].split()
+ section, size = parts[:2]
+ if len(parts) > 2:
+ name = parts[2]
+ syms[name] = Symbol(section, int(value, 16), int(size,16),
+ flags[1] == 'w')
+ return syms
+
+def GetSymbolAddress(fname, sym_name):
+ """Get a value of a symbol from an ELF file
+
+ Args:
+ fname: Filename of the ELF file to read
+ patterns: List of regex patterns to search for, each a string
+
+ Returns:
+ Symbol value (as an integer) or None if not found
+ """
+ syms = GetSymbols(fname, [sym_name])
+ sym = syms.get(sym_name)
+ if not sym:
+ return None
+ return sym.address