From 28565796df769e0a8d5ab1f8424cb262e40edc2e Mon Sep 17 00:00:00 2001 From: Simon Glass Date: Thu, 20 Oct 2022 18:22:44 -0600 Subject: binman: Allow obtaining a symbol value Provide a function to obtain the integer value of an ELF symbol. This will be used Signed-off-by: Simon Glass --- tools/binman/elf.py | 53 +++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 45 insertions(+), 8 deletions(-) (limited to 'tools/binman/elf.py') diff --git a/tools/binman/elf.py b/tools/binman/elf.py index 6d440ddf21d..fec2116880b 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -188,6 +188,28 @@ def GetSymbolAddress(fname, sym_name): return None return sym.address +def GetPackString(sym, msg): + """Get the struct.pack/unpack string to use with a given symbol + + Args: + sym (Symbol): Symbol to check. Only the size member is checked + @msg (str): String which indicates the entry being processed, used for + errors + + Returns: + str: struct string to use, .e.g. ' Date: Thu, 20 Oct 2022 18:22:47 -0600 Subject: 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 --- tools/binman/elf.py | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) (limited to 'tools/binman/elf.py') diff --git a/tools/binman/elf.py b/tools/binman/elf.py index fec2116880b..fe50bf542c3 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() -- cgit v1.2.3