binman: Expand elf support a little
Allow finding a symbol by its address. Also export the function to get
the file offset of a particular address, so it can be used by a script to
be added.
Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/tools/binman/elf.py b/tools/binman/elf.py
index 5e7d6ae..3597173 100644
--- a/tools/binman/elf.py
+++ b/tools/binman/elf.py
@@ -85,6 +85,57 @@
# Sort dict by address
return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address))
+def _GetFileOffset(elf, addr):
+ """Get the file offset for an address
+
+ Args:
+ elf (ELFFile): ELF file to check
+ addr (int): Address to search for
+
+ Returns
+ int: Offset of that address in the ELF file, or None if not valid
+ """
+ for seg in elf.iter_segments():
+ seg_end = seg['p_vaddr'] + seg['p_filesz']
+ if seg.header['p_type'] == 'PT_LOAD':
+ if addr >= seg['p_vaddr'] and addr < seg_end:
+ return addr - seg['p_vaddr'] + seg['p_offset']
+
+def GetFileOffset(fname, addr):
+ """Get the file offset for an address
+
+ Args:
+ fname (str): Filename of ELF file to check
+ addr (int): Address to search for
+
+ Returns
+ int: Offset of that address in the ELF file, or None if not valid
+ """
+ if not ELF_TOOLS:
+ raise ValueError('Python elftools package is not available')
+ with open(fname, 'rb') as fd:
+ elf = ELFFile(fd)
+ return _GetFileOffset(elf, addr)
+
+def GetSymbolFromAddress(fname, addr):
+ """Get the symbol at a particular address
+
+ Args:
+ fname (str): Filename of ELF file to check
+ addr (int): Address to search for
+
+ Returns:
+ str: Symbol name, or None if no symbol at that address
+ """
+ if not ELF_TOOLS:
+ raise ValueError('Python elftools package is not available')
+ with open(fname, 'rb') as fd:
+ elf = ELFFile(fd)
+ syms = GetSymbols(fname, None)
+ for name, sym in syms.items():
+ if sym.address == addr:
+ return name
+
def GetSymbolFileOffset(fname, patterns):
"""Get the symbols from an ELF file
@@ -97,13 +148,6 @@
key: Name of symbol
value: Hex value of symbol
"""
- def _GetFileOffset(elf, addr):
- for seg in elf.iter_segments():
- seg_end = seg['p_vaddr'] + seg['p_filesz']
- if seg.header['p_type'] == 'PT_LOAD':
- if addr >= seg['p_vaddr'] and addr < seg_end:
- return addr - seg['p_vaddr'] + seg['p_offset']
-
if not ELF_TOOLS:
raise ValueError('Python elftools package is not available')