(msg, sym.size))
# Look up the symbol in our entry tables.
- value = section.LookupSymbol(name, sym.weak, msg, base.address)
+ value = section.GetImage().LookupImageSymbol(name, sym.weak, msg,
+ base.address)
if value is None:
value = -1
pack_string = pack_string.lower()
def GetPath(self):
return 'section_path'
- def LookupSymbol(self, name, weak, msg, base_addr):
+ def LookupImageSymbol(self, name, weak, msg, base_addr):
"""Fake implementation which returns the same value for all symbols"""
return self.sym_value
+ def GetImage(self):
+ return self
def BuildElfTestFiles(target_dir):
"""Build ELF files used for testing in binman
return entry.GetData()
source_entry.Raise("Cannot find entry for node '%s'" % node.name)
- def LookupSymbol(self, sym_name, optional, msg, base_addr):
+ def LookupSymbol(self, sym_name, optional, msg, base_addr, entries=None):
"""Look up a symbol in an ELF file
Looks up a symbol in an ELF file. Only entry types which come from an
(msg, sym_name))
entry_name, prop_name = m.groups()
entry_name = entry_name.replace('_', '-')
- entry = self._entries.get(entry_name)
+ if not entries:
+ entries = self._entries
+ entry = entries.get(entry_name)
if not entry:
if entry_name.endswith('-any'):
root = entry_name[:-4]
- for name in self._entries:
+ for name in entries:
if name.startswith(root):
rest = name[len(root):]
if rest in ['', '-img', '-nodtb']:
- entry = self._entries[name]
+ entry = entries[name]
if not entry:
err = ("%s: Entry '%s' not found in list (%s)" %
- (msg, entry_name, ','.join(self._entries.keys())))
+ (msg, entry_name, ','.join(entries.keys())))
if optional:
print('Warning: %s' % err, file=sys.stderr)
return None
"""
for entry in self._entries.values():
entry.CheckMissing(missing_list)
+
+ def _CollectEntries(self, entries, entries_by_name, add_entry):
+ """Collect all the entries in an section
+
+ This builds up a dict of entries in this section and all subsections.
+ Entries are indexed by path and by name.
+
+ Since all paths are unique, entries will not have any conflicts. However
+ entries_by_name make have conflicts if two entries have the same name
+ (e.g. with different parent sections). In this case, an entry at a
+ higher level in the hierarchy will win over a lower-level entry.
+
+ Args:
+ entries: dict to put entries:
+ key: entry path
+ value: Entry object
+ entries_by_name: dict to put entries
+ key: entry name
+ value: Entry object
+ add_entry: Entry to add
+ """
+ entries[add_entry.GetPath()] = add_entry
+ to_add = add_entry.GetEntries()
+ if to_add:
+ for entry in to_add.values():
+ entries[entry.GetPath()] = entry
+ for entry in to_add.values():
+ self._CollectEntries(entries, entries_by_name, entry)
+ entries_by_name[add_entry.name] = add_entry
}
self.assertEqual(expected, props)
+ def testSymbolsSubsection(self):
+ """Test binman can assign symbols from a subsection"""
+ elf_fname = self.ElfTestFile('u_boot_binman_syms')
+ syms = elf.GetSymbols(elf_fname, ['binman', 'image'])
+ addr = elf.GetSymbolAddress(elf_fname, '__image_copy_start')
+ self.assertEqual(syms['_binman_u_boot_spl_prop_offset'].address, addr)
+
+ self._SetupSplElf('u_boot_binman_syms')
+ data = self._DoReadFile('187_symbols_sub.dts')
+ sym_values = struct.pack('<LQLL', 0x00, 0x1c, 0x28, 0x04)
+ expected = (sym_values + U_BOOT_SPL_DATA[20:] +
+ tools.GetBytes(0xff, 1) + U_BOOT_DATA + sym_values +
+ U_BOOT_SPL_DATA[20:])
+ self.assertEqual(expected, data)
+
if __name__ == "__main__":
unittest.main()
_DoLine(lines, _EntryToStrings(entry))
selected_entries.append(entry)
return selected_entries, lines, widths
+
+ def LookupImageSymbol(self, sym_name, optional, msg, base_addr):
+ """Look up a symbol in an ELF file
+
+ Looks up a symbol in an ELF file. Only entry types which come from an
+ ELF image can be used by this function.
+
+ This searches through this image including all of its subsections.
+
+ At present the only entry properties supported are:
+ offset
+ image_pos - 'base_addr' is added if this is not an end-at-4gb image
+ size
+
+ Args:
+ sym_name: Symbol name in the ELF file to look up in the format
+ _binman_<entry>_prop_<property> where <entry> is the name of
+ the entry and <property> is the property to find (e.g.
+ _binman_u_boot_prop_offset). As a special case, you can append
+ _any to <entry> to have it search for any matching entry. E.g.
+ _binman_u_boot_any_prop_offset will match entries called u-boot,
+ u-boot-img and u-boot-nodtb)
+ optional: True if the symbol is optional. If False this function
+ will raise if the symbol is not found
+ msg: Message to display if an error occurs
+ base_addr: Base address of image. This is added to the returned
+ image_pos in most cases so that the returned position indicates
+ where the targeted entry/binary has actually been loaded. But
+ if end-at-4gb is used, this is not done, since the binary is
+ already assumed to be linked to the ROM position and using
+ execute-in-place (XIP).
+
+ Returns:
+ Value that should be assigned to that symbol, or None if it was
+ optional and not found
+
+ Raises:
+ ValueError if the symbol is invalid or not found, or references a
+ property which is not supported
+ """
+ entries = OrderedDict()
+ entries_by_name = {}
+ self._CollectEntries(entries, entries_by_name, self)
+ return self.LookupSymbol(sym_name, optional, msg, base_addr,
+ entries_by_name)
--- /dev/null
+/dts-v1/;
+
+/ {
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ binman {
+ section {
+ pad-byte = <0xff>;
+ u-boot-spl {
+ };
+
+ u-boot {
+ offset = <24>;
+ };
+ };
+
+ u-boot-spl2 {
+ type = "u-boot-spl";
+ };
+ };
+};