summaryrefslogtreecommitdiff
path: root/tools/binman/elf.py
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2022-10-20 18:22:47 -0600
committerTom Rini <trini@konsulko.com>2022-10-31 11:02:44 -0400
commitd2afb9edce0089f06d8f353cf88d8f5dec984914 (patch)
tree6e97d230ea5b70e980955fd362030fd6a958d5d1 /tools/binman/elf.py
parent3fbba5568ca9ccd59a6bc824dc2dd9e6eac2b504 (diff)
binman: Support writing symbols into ELF files
In some cases the ELF version of SPL builds may be packaged, rather than a binary .bin file. Add support for this. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'tools/binman/elf.py')
-rw-r--r--tools/binman/elf.py41
1 files changed, 33 insertions, 8 deletions
diff --git a/tools/binman/elf.py b/tools/binman/elf.py
index fec2116880..fe50bf542c 100644
--- a/tools/binman/elf.py
+++ b/tools/binman/elf.py
@@ -210,7 +210,7 @@ def GetPackString(sym, msg):
raise ValueError('%s has size %d: only 4 and 8 are supported' %
(msg, sym.size))
-def LookupAndWriteSymbols(elf_fname, entry, section):
+def LookupAndWriteSymbols(elf_fname, entry, section, is_elf=False):
"""Replace all symbols in an entry with their correct values
The entry contents is updated so that values for referenced symbols will be
@@ -226,27 +226,52 @@ def LookupAndWriteSymbols(elf_fname, entry, section):
"""
fname = tools.get_input_filename(elf_fname)
syms = GetSymbols(fname, ['image', 'binman'])
+ if is_elf:
+ if not ELF_TOOLS:
+ msg = ("Section '%s': entry '%s'" %
+ (section.GetPath(), entry.GetPath()))
+ raise ValueError(f'{msg}: Cannot write symbols to an ELF file without Python elftools')
+ new_syms = {}
+ with open(fname, 'rb') as fd:
+ elf = ELFFile(fd)
+ for name, sym in syms.items():
+ offset = _GetFileOffset(elf, sym.address)
+ new_syms[name] = Symbol(sym.section, sym.address, sym.size,
+ sym.weak, offset)
+ syms = new_syms
+
if not syms:
+ tout.debug('LookupAndWriteSymbols: no syms')
return
base = syms.get('__image_copy_start')
- if not base:
+ if not base and not is_elf:
+ tout.debug('LookupAndWriteSymbols: no base')
return
+ base_addr = 0 if is_elf else base.address
for name, sym in syms.items():
if name.startswith('_binman'):
msg = ("Section '%s': Symbol '%s'\n in entry '%s'" %
(section.GetPath(), name, entry.GetPath()))
- offset = sym.address - base.address
- if offset < 0 or offset + sym.size > entry.contents_size:
- raise ValueError('%s has offset %x (size %x) but the contents '
- 'size is %x' % (entry.GetPath(), offset,
- sym.size, entry.contents_size))
+ if is_elf:
+ # For ELF files, use the file offset
+ offset = sym.offset
+ else:
+ # For blobs use the offset of the symbol, calculated by
+ # subtracting the base address which by definition is at the
+ # start
+ offset = sym.address - base.address
+ if offset < 0 or offset + sym.size > entry.contents_size:
+ raise ValueError('%s has offset %x (size %x) but the contents '
+ 'size is %x' % (entry.GetPath(), offset,
+ sym.size,
+ entry.contents_size))
pack_string = GetPackString(sym, msg)
if name == '_binman_sym_magic':
value = BINMAN_SYM_MAGIC_VALUE
else:
# Look up the symbol in our entry tables.
value = section.GetImage().LookupImageSymbol(name, sym.weak,
- msg, base.address)
+ msg, base_addr)
if value is None:
value = -1
pack_string = pack_string.lower()