diff options
author | Simon Glass <sjg@chromium.org> | 2022-10-20 18:22:47 -0600 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2022-10-31 11:02:44 -0400 |
commit | d2afb9edce0089f06d8f353cf88d8f5dec984914 (patch) | |
tree | 6e97d230ea5b70e980955fd362030fd6a958d5d1 /tools/binman/elf.py | |
parent | 3fbba5568ca9ccd59a6bc824dc2dd9e6eac2b504 (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.py | 41 |
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() |