diff --git a/common/spl/spl.c b/common/spl/spl.c index 5dd122611c..29e0898f03 100644 --- a/common/spl/spl.c +++ b/common/spl/spl.c @@ -41,6 +41,7 @@ #include DECLARE_GLOBAL_DATA_PTR; +DECLARE_BINMAN_MAGIC_SYM; #ifndef CONFIG_SYS_UBOOT_START #define CONFIG_SYS_UBOOT_START CONFIG_SYS_TEXT_BASE diff --git a/include/binman_sym.h b/include/binman_sym.h index 8586ef8731..528d7e4e90 100644 --- a/include/binman_sym.h +++ b/include/binman_sym.h @@ -11,6 +11,8 @@ #ifndef __BINMAN_SYM_H #define __BINMAN_SYM_H +/* BSYM in little endian, keep in sync with tools/binman/elf.py */ +#define BINMAN_SYM_MAGIC_VALUE (0x4d595342UL) #define BINMAN_SYM_MISSING (-1UL) #if CONFIG_IS_ENABLED(BINMAN_SYMBOLS) @@ -62,6 +64,37 @@ __attribute__((aligned(4), weak, unused, \ section(".binman_sym"))) +/** + * _binman_sym_magic - Internal magic symbol for validity checks + * + * When building images, binman fills in this symbol with the magic + * value #defined above. This is used to check at runtime if the + * symbol values were filled in and are OK to use. + */ +extern ulong _binman_sym_magic; + +/** + * DECLARE_BINMAN_MAGIC_SYM - Declare the internal magic symbol + * + * This macro declares the _binman_sym_magic symbol so that it exists. + * Declaring it here would cause errors during linking due to multiple + * definitions of the symbol. + */ +#define DECLARE_BINMAN_MAGIC_SYM \ + ulong _binman_sym_magic \ + __attribute__((aligned(4), section(".binman_sym"))) + +/** + * BINMAN_SYMS_OK - Check if the symbol values are valid + * + * This macro checks if the magic symbol's value is filled properly, + * which indicates that other symbols are OK to use as well. + * + * Return: 1 if binman symbol values are usable, 0 if not + */ +#define BINMAN_SYMS_OK \ + (*(ulong *)&_binman_sym_magic == BINMAN_SYM_MAGIC_VALUE) + /** * binman_sym() - Access a previously declared symbol * @@ -72,10 +105,14 @@ * @_type: Type f the symbol (e.g. unsigned long) * @entry_name: Name of the entry to look for (e.g. 'u_boot_spl') * @_prop_name: Property value to get from that entry (e.g. 'pos') - * @returns value of that property (filled in by binman) + * + * Return: value of that property (filled in by binman), or + * BINMAN_SYM_MISSING if the value is unavailable */ #define binman_sym(_type, _entry_name, _prop_name) \ - (*(_type *)&binman_symname(_entry_name, _prop_name)) + (BINMAN_SYMS_OK ? \ + (*(_type *)&binman_symname(_entry_name, _prop_name)) : \ + BINMAN_SYM_MISSING) #else /* !CONFIG_IS_ENABLED(BINMAN_SYMBOLS) */ @@ -85,6 +122,10 @@ #define binman_sym_extern(_type, _entry_name, _prop_name) +#define DECLARE_BINMAN_MAGIC_SYM + +#define BINMAN_SYMS_OK (0) + #define binman_sym(_type, _entry_name, _prop_name) BINMAN_SYM_MISSING #endif /* CONFIG_IS_ENABLED(BINMAN_SYMBOLS) */ diff --git a/tools/binman/elf.py b/tools/binman/elf.py index afa05e58fd..6d440ddf21 100644 --- a/tools/binman/elf.py +++ b/tools/binman/elf.py @@ -25,6 +25,9 @@ try: except: # pragma: no cover ELF_TOOLS = False +# BSYM in little endian, keep in sync with include/binman_sym.h +BINMAN_SYM_MAGIC_VALUE = 0x4d595342 + # Information about an EFL symbol: # section (str): Name of the section containing this symbol # address (int): Address of the symbol (its value) @@ -223,9 +226,12 @@ def LookupAndWriteSymbols(elf_fname, entry, section): raise ValueError('%s has size %d: only 4 and 8 are supported' % (msg, sym.size)) - # Look up the symbol in our entry tables. - value = section.GetImage().LookupImageSymbol(name, sym.weak, msg, - base.address) + 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) if value is None: value = -1 pack_string = pack_string.lower() diff --git a/tools/binman/elf_test.py b/tools/binman/elf_test.py index 02bc108374..5a51c64cfe 100644 --- a/tools/binman/elf_test.py +++ b/tools/binman/elf_test.py @@ -127,7 +127,7 @@ class TestElf(unittest.TestCase): elf_fname = self.ElfTestFile('u_boot_binman_syms') with self.assertRaises(ValueError) as e: elf.LookupAndWriteSymbols(elf_fname, entry, section) - self.assertIn('entry_path has offset 4 (size 8) but the contents size ' + self.assertIn('entry_path has offset 8 (size 8) but the contents size ' 'is a', str(e.exception)) def testMissingImageStart(self): @@ -161,18 +161,20 @@ class TestElf(unittest.TestCase): This should produce -1 values for all thress symbols, taking up the first 16 bytes of the image. """ - entry = FakeEntry(24) + entry = FakeEntry(28) section = FakeSection(sym_value=None) elf_fname = self.ElfTestFile('u_boot_binman_syms') elf.LookupAndWriteSymbols(elf_fname, entry, section) - self.assertEqual(tools.get_bytes(255, 20) + tools.get_bytes(ord('a'), 4), - entry.data) + expected = (struct.pack('; + offset = <28>; }; }; }; diff --git a/tools/binman/test/024_sorted.dts b/tools/binman/test/024_sorted.dts index b79d9adf68..b54f9b1419 100644 --- a/tools/binman/test/024_sorted.dts +++ b/tools/binman/test/024_sorted.dts @@ -7,7 +7,7 @@ binman { sort-by-offset; u-boot { - offset = <26>; + offset = <30>; }; u-boot-spl { diff --git a/tools/binman/test/028_pack_4gb_outside.dts b/tools/binman/test/028_pack_4gb_outside.dts index 11a1f6059e..b6ad7fb56a 100644 --- a/tools/binman/test/028_pack_4gb_outside.dts +++ b/tools/binman/test/028_pack_4gb_outside.dts @@ -13,7 +13,7 @@ }; u-boot-spl { - offset = <0xffffffe7>; + offset = <0xffffffe3>; }; }; }; diff --git a/tools/binman/test/029_x86_rom.dts b/tools/binman/test/029_x86_rom.dts index 88aa007bba..ad8f9d6e1b 100644 --- a/tools/binman/test/029_x86_rom.dts +++ b/tools/binman/test/029_x86_rom.dts @@ -7,13 +7,13 @@ binman { sort-by-offset; end-at-4gb; - size = <32>; + size = <36>; u-boot { - offset = <0xffffffe0>; + offset = <0xffffffdc>; }; u-boot-spl { - offset = <0xffffffe7>; + offset = <0xffffffe3>; }; }; }; diff --git a/tools/binman/test/053_symbols.dts b/tools/binman/test/053_symbols.dts index 2965809276..b28f34a72f 100644 --- a/tools/binman/test/053_symbols.dts +++ b/tools/binman/test/053_symbols.dts @@ -10,7 +10,7 @@ }; u-boot { - offset = <0x18>; + offset = <0x1c>; }; u-boot-spl2 { diff --git a/tools/binman/test/149_symbols_tpl.dts b/tools/binman/test/149_symbols_tpl.dts index 0a4ab3f1fa..4e649c4597 100644 --- a/tools/binman/test/149_symbols_tpl.dts +++ b/tools/binman/test/149_symbols_tpl.dts @@ -11,12 +11,12 @@ }; u-boot-spl2 { - offset = <0x1c>; + offset = <0x20>; type = "u-boot-spl"; }; u-boot { - offset = <0x34>; + offset = <0x3c>; }; section { diff --git a/tools/binman/test/155_symbols_tpl_x86.dts b/tools/binman/test/155_symbols_tpl_x86.dts index 9d7dc51b3d..e1ce33e67f 100644 --- a/tools/binman/test/155_symbols_tpl_x86.dts +++ b/tools/binman/test/155_symbols_tpl_x86.dts @@ -14,12 +14,12 @@ }; u-boot-spl2 { - offset = <0xffffff1c>; + offset = <0xffffff20>; type = "u-boot-spl"; }; u-boot { - offset = <0xffffff34>; + offset = <0xffffff3c>; }; section { diff --git a/tools/binman/test/187_symbols_sub.dts b/tools/binman/test/187_symbols_sub.dts index 54511a7371..3ab62d3721 100644 --- a/tools/binman/test/187_symbols_sub.dts +++ b/tools/binman/test/187_symbols_sub.dts @@ -11,7 +11,7 @@ }; u-boot { - offset = <24>; + offset = <28>; }; }; diff --git a/tools/binman/test/u_boot_binman_syms.c b/tools/binman/test/u_boot_binman_syms.c index 89fee5567e..ed761246ae 100644 --- a/tools/binman/test/u_boot_binman_syms.c +++ b/tools/binman/test/u_boot_binman_syms.c @@ -5,9 +5,13 @@ * Simple program to create some binman symbols. This is used by binman tests. */ +typedef unsigned long ulong; + #include #include +DECLARE_BINMAN_MAGIC_SYM; + binman_sym_declare(unsigned long, u_boot_spl_any, offset); binman_sym_declare(unsigned long long, u_boot_spl2, offset); binman_sym_declare(unsigned long, u_boot_any, image_pos); diff --git a/tools/binman/test/u_boot_binman_syms_size.c b/tools/binman/test/u_boot_binman_syms_size.c index c4a053f96f..fa41b3d9a3 100644 --- a/tools/binman/test/u_boot_binman_syms_size.c +++ b/tools/binman/test/u_boot_binman_syms_size.c @@ -5,7 +5,11 @@ * Simple program to create some binman symbols. This is used by binman tests. */ +typedef unsigned long ulong; + #include #include +DECLARE_BINMAN_MAGIC_SYM; + binman_sym_declare(char, u_boot_spl, pos);