env tidy-ups

test fixes
 binman fixes and ELF enhancements
 -----BEGIN PGP SIGNATURE-----
 
 iQFFBAABCAAvFiEEslwAIq+Gp8wWVbYnfxc6PpAIreYFAmGQWkgRHHNqZ0BjaHJv
 bWl1bS5vcmcACgkQfxc6PpAIreZjwAgAqUhfZc0Xws5c2lcRZx47QuMo1fVvoY2c
 mX+0fRPwf1+ptSJFtMrrmETsKE1BxAGSbGrelF3Kol3lxOa8dnqM0TRZqn0LvPRx
 p5GOoR1TB03jAo7d5Yxw0jcCLFkeIogbS8wDGf/x5erbW/4yU/VOQBHhX6S2Ic18
 jsh1nc2Gq5f8MCLYYQv1JMwz+lpD28wEkr0mW5l0DMMtWMIHFHhx9ErOoJLQwqGh
 BWC5xgx7oESEbx+4aXnzxZuGcx+YAuPo8I+K6lMACnkLr8OlDkaLeMQWrt5+j3td
 10z7B8gwpHka1Uz4I56GJTYprbX4RtoTyy804cVELwEbIc56FiDhXg==
 =lFLE
 -----END PGP SIGNATURE-----

Merge tag 'dm-pull-13nov21' of https://source.denx.de/u-boot/custodians/u-boot-dm

env tidy-ups
test fixes
binman fixes and ELF enhancements
This commit is contained in:
Tom Rini 2021-11-13 21:14:51 -05:00
commit e035ce4b3b
19 changed files with 395 additions and 38 deletions

View File

@ -1314,7 +1314,7 @@ cmd_binman = $(srctree)/tools/binman/binman $(if $(BINMAN_DEBUG),-D) \
-a spl-bss-pad=$(if $(CONFIG_SPL_SEPARATE_BSS),,1) \
-a tpl-bss-pad=$(if $(CONFIG_TPL_SEPARATE_BSS),,1) \
-a spl-dtb=$(CONFIG_SPL_OF_REAL) \
-a tpl-dtb=$(CONFIG_SPL_OF_REAL) \
-a tpl-dtb=$(CONFIG_TPL_OF_REAL) \
$(BINMAN_$(@F))
OBJCOPYFLAGS_u-boot.ldr.hex := -I binary -O ihex

View File

@ -704,7 +704,7 @@ config SHOW_BOOT_PROGRESS
151 common/cmd_nand.c FIT image format OK
config SPL_SHOW_BOOT_PROGRESS
bool "Show boot progress in a board-specific manner"
bool "Show boot progress in a board-specific manner in SPL"
depends on SPL
help
Defining this option allows to add some board-specific code (calling

View File

@ -39,6 +39,7 @@ static int sandbox_wdt_reset(struct udevice *dev)
static int sandbox_wdt_expire_now(struct udevice *dev, ulong flags)
{
sandbox_wdt_start(dev, 1, flags);
sandbox_reset();
return 0;
}

49
env/common.c vendored
View File

@ -125,7 +125,7 @@ char *env_get(const char *name)
}
/* restricted capabilities before import */
if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) > 0)
if (env_get_f(name, (char *)(gd->env_buf), sizeof(gd->env_buf)) >= 0)
return (char *)(gd->env_buf);
return NULL;
@ -148,12 +148,10 @@ char *from_env(const char *envvar)
return ret;
}
/*
* Look up variable from environment for restricted C runtime env.
*/
int env_get_f(const char *name, char *buf, unsigned len)
static int env_get_from_linear(const char *env, const char *name, char *buf,
unsigned len)
{
const char *env, *p, *end;
const char *p, *end;
size_t name_len;
if (name == NULL || *name == '\0')
@ -161,11 +159,6 @@ int env_get_f(const char *name, char *buf, unsigned len)
name_len = strlen(name);
if (gd->env_valid == ENV_INVALID)
env = default_environment;
else
env = (const char *)gd->env_addr;
for (p = env; *p != '\0'; p = end + 1) {
const char *value;
unsigned res;
@ -193,6 +186,21 @@ int env_get_f(const char *name, char *buf, unsigned len)
return -1;
}
/*
* Look up variable from environment for restricted C runtime env.
*/
int env_get_f(const char *name, char *buf, unsigned len)
{
const char *env;
if (gd->env_valid == ENV_INVALID)
env = default_environment;
else
env = (const char *)gd->env_addr;
return env_get_from_linear(env, name, buf, len);
}
/**
* Decode the integer value of an environment variable and return it.
*
@ -232,17 +240,12 @@ int env_get_yesno(const char *var)
*/
char *env_get_default(const char *name)
{
char *ret_val;
unsigned long really_valid = gd->env_valid;
unsigned long real_gd_flags = gd->flags;
if (env_get_from_linear(default_environment, name,
(char *)(gd->env_buf),
sizeof(gd->env_buf)) >= 0)
return (char *)(gd->env_buf);
/* Pretend that the image is bad. */
gd->flags &= ~GD_FLG_ENV_READY;
gd->env_valid = ENV_INVALID;
ret_val = env_get(name);
gd->env_valid = really_valid;
gd->flags = real_gd_flags;
return ret_val;
return NULL;
}
void env_set_default(const char *s, int flags)
@ -261,9 +264,11 @@ void env_set_default(const char *s, int flags)
flags |= H_DEFAULT;
if (himport_r(&env_htab, default_environment,
sizeof(default_environment), '\0', flags, 0,
0, NULL) == 0)
0, NULL) == 0) {
pr_err("## Error: Environment import failed: errno = %d\n",
errno);
return;
}
gd->flags |= GD_FLG_ENV_READY;
gd->flags |= GD_FLG_ENV_DEFAULT;

View File

@ -106,6 +106,8 @@ obj-$(CONFIG_TIMER) += timer.o
obj-$(CONFIG_DM_USB) += usb.o
obj-$(CONFIG_DM_VIDEO) += video.o
obj-$(CONFIG_VIRTIO_SANDBOX) += virtio.o
obj-$(CONFIG_WDT) += wdt.o
ifeq ($(CONFIG_WDT_GPIO)$(CONFIG_WDT_SANDBOX),yy)
obj-y += wdt.o
endif
endif
endif # !SPL

View File

@ -818,6 +818,42 @@ the 'warning' line in scripts/Makefile.lib to see what it has found::
# u_boot_dtsi_options_debug = $(u_boot_dtsi_options_raw)
Updating an ELF file
====================
For the EFI app, where U-Boot is loaded from UEFI and runs as an app, there is
no way to update the devicetree after U-Boot is built. Normally this works by
creating a new u-boot.dtb.out with he updated devicetree, which is automatically
built into the output image. With ELF this is not possible since the ELF is
not part of an image, just a stand-along file. We must create an updated ELF
file with the new devicetree.
This is handled by the --update-fdt-in-elf option. It takes four arguments,
separated by comma:
infile - filename of input ELF file, e.g. 'u-boot's
outfile - filename of output ELF file, e.g. 'u-boot.out'
begin_sym - symbol at the start of the embedded devicetree, e.g.
'__dtb_dt_begin'
end_sym - symbol at the start of the embedded devicetree, e.g.
'__dtb_dt_end'
When this flag is used, U-Boot does all the normal packaging, but as an
additional step, it creates a new ELF file with the new devicetree embedded in
it.
If logging is enabled you will see a message like this::
Updating file 'u-boot' with data length 0x400a (16394) between symbols
'__dtb_dt_begin' and '__dtb_dt_end'
There must be enough space for the updated devicetree. If not, an error like
the following is produced::
ValueError: Not enough space in 'u-boot' for data length 0x400a (16394);
size is 0x1744 (5956)
Entry Documentation
===================

View File

@ -71,6 +71,8 @@ controlled by a description in the board device tree.'''
'given')
build_parser.add_argument('-u', '--update-fdt', action='store_true',
default=False, help='Update the binman node with offset/size info')
build_parser.add_argument('--update-fdt-in-elf', type=str,
help='Update an ELF file with the output dtb: infile,outfile,begin_sym,end_sym')
entry_parser = subparsers.add_parser('entry-docs',
help='Write out entry documentation (see entries.rst)')
@ -99,7 +101,7 @@ controlled by a description in the board device tree.'''
replace_parser.add_argument('-C', '--compressed', action='store_true',
help='Input data is already compressed if needed for the entry')
replace_parser.add_argument('-i', '--image', type=str, required=True,
help='Image filename to extract')
help='Image filename to update')
replace_parser.add_argument('-f', '--filename', type=str,
help='Input filename to read from')
replace_parser.add_argument('-F', '--fix-size', action='store_true',
@ -109,7 +111,7 @@ controlled by a description in the board device tree.'''
replace_parser.add_argument('-m', '--map', action='store_true',
default=False, help='Output a map file for the updated image')
replace_parser.add_argument('paths', type=str, nargs='*',
help='Paths within file to extract (wildcard)')
help='Paths within file to replace (wildcard)')
test_parser = subparsers.add_parser('test', help='Run tests')
test_parser.add_argument('-P', '--processes', type=int,

View File

@ -343,10 +343,10 @@ def ReplaceEntries(image_fname, input_fname, indir, entry_paths,
Args:
image_fname: Image filename to process
input_fname: Single input ilename to use if replacing one file, None
input_fname: Single input filename to use if replacing one file, None
otherwise
indir: Input directory to use (for any number of files), else None
entry_paths: List of entry paths to extract
entry_paths: List of entry paths to replace
do_compress: True if the input data is uncompressed and may need to be
compressed if the entry requires it, False if the data is already
compressed.
@ -595,6 +595,13 @@ def Binman(args):
tools.FinaliseOutputDir()
return 0
elf_params = None
if args.update_fdt_in_elf:
elf_params = args.update_fdt_in_elf.split(',')
if len(elf_params) != 4:
raise ValueError('Invalid args %s to --update-fdt-in-elf: expected infile,outfile,begin_sym,end_sym' %
elf_params)
# Try to figure out which device tree contains our image description
if args.dt:
dtb_fname = args.dt
@ -641,6 +648,10 @@ def Binman(args):
for dtb_item in state.GetAllFdts():
tools.WriteFile(dtb_item._fname, dtb_item.GetContents())
if elf_params:
data = state.GetFdtForEtype('u-boot-dtb').GetContents()
elf.UpdateFile(*elf_params, data)
if missing:
tout.Warning("\nSome images are invalid")

View File

@ -24,7 +24,14 @@ try:
except: # pragma: no cover
ELF_TOOLS = False
Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak'])
# Information about an EFL symbol:
# section (str): Name of the section containing this symbol
# address (int): Address of the symbol (its value)
# size (int): Size of the symbol in bytes
# weak (bool): True if the symbol is weak
# offset (int or None): Offset of the symbol's data in the ELF file, or None if
# not known
Symbol = namedtuple('Symbol', ['section', 'address', 'size', 'weak', 'offset'])
# Information about an ELF file:
# data: Extracted program contents of ELF file (this would be loaded by an
@ -71,8 +78,48 @@ def GetSymbols(fname, patterns):
section, size = parts[:2]
if len(parts) > 2:
name = parts[2] if parts[2] != '.hidden' else parts[3]
syms[name] = Symbol(section, int(value, 16), int(size,16),
flags[1] == 'w')
syms[name] = Symbol(section, int(value, 16), int(size, 16),
flags[1] == 'w', None)
# Sort dict by address
return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address))
def GetSymbolFileOffset(fname, patterns):
"""Get the symbols from an ELF file
Args:
fname: Filename of the ELF file to read
patterns: List of regex patterns to search for, each a string
Returns:
None, if the file does not exist, or Dict:
key: Name of symbol
value: Hex value of symbol
"""
def _GetFileOffset(elf, addr):
for seg in elf.iter_segments():
seg_end = seg['p_vaddr'] + seg['p_filesz']
if seg.header['p_type'] == 'PT_LOAD':
if addr >= seg['p_vaddr'] and addr < seg_end:
return addr - seg['p_vaddr'] + seg['p_offset']
if not ELF_TOOLS:
raise ValueError('Python elftools package is not available')
syms = {}
with open(fname, 'rb') as fd:
elf = ELFFile(fd)
re_syms = re.compile('|'.join(patterns))
for section in elf.iter_sections():
if isinstance(section, SymbolTableSection):
for symbol in section.iter_symbols():
if not re_syms or re_syms.search(symbol.name):
addr = symbol.entry['st_value']
syms[symbol.name] = Symbol(
section.name, addr, symbol.entry['st_size'],
symbol.entry['st_info']['bind'] == 'STB_WEAK',
_GetFileOffset(elf, addr))
# Sort dict by address
return OrderedDict(sorted(syms.items(), key=lambda x: x[1].address))
@ -301,3 +348,24 @@ def DecodeElf(data, location):
segment.data()[offset:])
return ElfInfo(output, data_start, elf.header['e_entry'] + virt_to_phys,
mem_end - data_start)
def UpdateFile(infile, outfile, start_sym, end_sym, insert):
tout.Notice("Creating file '%s' with data length %#x (%d) between symbols '%s' and '%s'" %
(outfile, len(insert), len(insert), start_sym, end_sym))
syms = GetSymbolFileOffset(infile, [start_sym, end_sym])
if len(syms) != 2:
raise ValueError("Expected two symbols '%s' and '%s': got %d: %s" %
(start_sym, end_sym, len(syms),
','.join(syms.keys())))
size = syms[end_sym].offset - syms[start_sym].offset
if len(insert) > size:
raise ValueError("Not enough space in '%s' for data length %#x (%d); size is %#x (%d)" %
(infile, len(insert), len(insert), size, size))
data = tools.ReadFile(infile)
newdata = data[:syms[start_sym].offset]
newdata += insert + tools.GetBytes(0, size - len(insert))
newdata += data[syms[end_sym].offset:]
tools.WriteFile(outfile, newdata)
tout.Info('Written to offset %#x' % syms[start_sym].offset)

View File

@ -6,6 +6,7 @@
import os
import shutil
import struct
import sys
import tempfile
import unittest
@ -70,8 +71,12 @@ def BuildElfTestFiles(target_dir):
# correctly. So drop any make flags here.
if 'MAKEFLAGS' in os.environ:
del os.environ['MAKEFLAGS']
tools.Run('make', '-C', target_dir, '-f',
os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir)
try:
tools.Run('make', '-C', target_dir, '-f',
os.path.join(testdir, 'Makefile'), 'SRC=%s/' % testdir)
except ValueError as e:
# The test system seems to suppress this in a strange way
print(e)
class TestElf(unittest.TestCase):
@ -217,6 +222,42 @@ class TestElf(unittest.TestCase):
elf.DecodeElf(data, load + 2))
shutil.rmtree(outdir)
def testEmbedData(self):
"""Test for the GetSymbolFileOffset() function"""
if not elf.ELF_TOOLS:
self.skipTest('Python elftools not available')
fname = self.ElfTestFile('embed_data')
offset = elf.GetSymbolFileOffset(fname, ['embed_start', 'embed_end'])
start = offset['embed_start'].offset
end = offset['embed_end'].offset
data = tools.ReadFile(fname)
embed_data = data[start:end]
expect = struct.pack('<III', 0x1234, 0x5678, 0)
self.assertEqual(expect, embed_data)
def testEmbedFail(self):
"""Test calling GetSymbolFileOffset() without elftools"""
try:
old_val = elf.ELF_TOOLS
elf.ELF_TOOLS = False
fname = self.ElfTestFile('embed_data')
with self.assertRaises(ValueError) as e:
elf.GetSymbolFileOffset(fname, ['embed_start', 'embed_end'])
self.assertIn('Python elftools package is not available',
str(e.exception))
finally:
elf.ELF_TOOLS = old_val
def testEmbedDataNoSym(self):
"""Test for GetSymbolFileOffset() getting no symbols"""
if not elf.ELF_TOOLS:
self.skipTest('Python elftools not available')
fname = self.ElfTestFile('embed_data')
offset = elf.GetSymbolFileOffset(fname, ['missing_sym'])
self.assertEqual({}, offset)
if __name__ == '__main__':
unittest.main()

View File

@ -309,7 +309,7 @@ class TestFunctional(unittest.TestCase):
entry_args=None, images=None, use_real_dtb=False,
use_expanded=False, verbosity=None, allow_missing=False,
extra_indirs=None, threads=None,
test_section_timeout=False):
test_section_timeout=False, update_fdt_in_elf=None):
"""Run binman with a given test file
Args:
@ -334,6 +334,12 @@ class TestFunctional(unittest.TestCase):
extra_indirs: Extra input directories to add using -I
threads: Number of threads to use (None for default, 0 for
single-threaded)
test_section_timeout: True to force the first time to timeout, as
used in testThreadTimeout()
update_fdt_in_elf: Value to pass with --update-fdt-in-elf=xxx
Returns:
int return code, 0 on success
"""
args = []
if debug:
@ -363,6 +369,8 @@ class TestFunctional(unittest.TestCase):
args.append('-a%s=%s' % (arg, value))
if allow_missing:
args.append('-M')
if update_fdt_in_elf:
args += ['--update-fdt-in-elf', update_fdt_in_elf]
if images:
for image in images:
args += ['-i', image]
@ -4575,6 +4583,84 @@ class TestFunctional(unittest.TestCase):
self.assertIn('read:', stdout.getvalue())
self.assertIn('compress:', stdout.getvalue())
def testUpdateFdtInElf(self):
"""Test that we can update the devicetree in an ELF file"""
infile = elf_fname = self.ElfTestFile('u_boot_binman_embed')
outfile = os.path.join(self._indir, 'u-boot.out')
begin_sym = 'dtb_embed_begin'
end_sym = 'dtb_embed_end'
retcode = self._DoTestFile(
'060_fdt_update.dts', update_dtb=True,
update_fdt_in_elf=','.join([infile,outfile,begin_sym,end_sym]))
self.assertEqual(0, retcode)
# Check that the output file does in fact contact a dtb with the binman
# definition in the correct place
syms = elf.GetSymbolFileOffset(infile,
['dtb_embed_begin', 'dtb_embed_end'])
data = tools.ReadFile(outfile)
dtb_data = data[syms['dtb_embed_begin'].offset:
syms['dtb_embed_end'].offset]
dtb = fdt.Fdt.FromData(dtb_data)
dtb.Scan()
props = self._GetPropTree(dtb, BASE_DTB_PROPS + REPACK_DTB_PROPS)
self.assertEqual({
'image-pos': 0,
'offset': 0,
'_testing:offset': 32,
'_testing:size': 2,
'_testing:image-pos': 32,
'section@0/u-boot:offset': 0,
'section@0/u-boot:size': len(U_BOOT_DATA),
'section@0/u-boot:image-pos': 0,
'section@0:offset': 0,
'section@0:size': 16,
'section@0:image-pos': 0,
'section@1/u-boot:offset': 0,
'section@1/u-boot:size': len(U_BOOT_DATA),
'section@1/u-boot:image-pos': 16,
'section@1:offset': 16,
'section@1:size': 16,
'section@1:image-pos': 16,
'size': 40
}, props)
def testUpdateFdtInElfInvalid(self):
"""Test that invalid args are detected with --update-fdt-in-elf"""
with self.assertRaises(ValueError) as e:
self._DoTestFile('060_fdt_update.dts', update_fdt_in_elf='fred')
self.assertIn("Invalid args ['fred'] to --update-fdt-in-elf",
str(e.exception))
def testUpdateFdtInElfNoSyms(self):
"""Test that missing symbols are detected with --update-fdt-in-elf"""
infile = elf_fname = self.ElfTestFile('u_boot_binman_embed')
outfile = ''
begin_sym = 'wrong_begin'
end_sym = 'wrong_end'
with self.assertRaises(ValueError) as e:
self._DoTestFile(
'060_fdt_update.dts',
update_fdt_in_elf=','.join([infile,outfile,begin_sym,end_sym]))
self.assertIn("Expected two symbols 'wrong_begin' and 'wrong_end': got 0:",
str(e.exception))
def testUpdateFdtInElfTooSmall(self):
"""Test that an over-large dtb is detected with --update-fdt-in-elf"""
infile = elf_fname = self.ElfTestFile('u_boot_binman_embed_sm')
outfile = os.path.join(self._indir, 'u-boot.out')
begin_sym = 'dtb_embed_begin'
end_sym = 'dtb_embed_end'
with self.assertRaises(ValueError) as e:
self._DoTestFile(
'060_fdt_update.dts', update_dtb=True,
update_fdt_in_elf=','.join([infile,outfile,begin_sym,end_sym]))
self.assertRegex(
str(e.exception),
"Not enough space in '.*u_boot_binman_embed_sm' for data length.*")
if __name__ == "__main__":
unittest.main()

View File

@ -28,10 +28,12 @@ LDS_UCODE := -T $(SRC)u_boot_ucode_ptr.lds
LDS_BINMAN := -T $(SRC)u_boot_binman_syms.lds
LDS_BINMAN_BAD := -T $(SRC)u_boot_binman_syms_bad.lds
LDS_BINMAN_X86 := -T $(SRC)u_boot_binman_syms_x86.lds
LDS_BINMAN_EMBED := -T $(SRC)u_boot_binman_embed.lds
TARGETS = u_boot_ucode_ptr u_boot_no_ucode_ptr bss_data \
u_boot_binman_syms u_boot_binman_syms.bin u_boot_binman_syms_bad \
u_boot_binman_syms_size u_boot_binman_syms_x86
u_boot_binman_syms_size u_boot_binman_syms_x86 embed_data \
u_boot_binman_embed u_boot_binman_embed_sm
all: $(TARGETS)
@ -44,6 +46,9 @@ u_boot_ucode_ptr: u_boot_ucode_ptr.c
bss_data: CFLAGS += $(SRC)bss_data.lds
bss_data: bss_data.c
embed_data: CFLAGS += $(SRC)embed_data.lds
embed_data: embed_data.c
u_boot_binman_syms.bin: u_boot_binman_syms
$(OBJCOPY) -O binary $< -R .note.gnu.build-id $@
@ -59,6 +64,12 @@ u_boot_binman_syms_bad: u_boot_binman_syms_bad.c
u_boot_binman_syms_size: CFLAGS += $(LDS_BINMAN)
u_boot_binman_syms_size: u_boot_binman_syms_size.c
u_boot_binman_embed: CFLAGS += $(LDS_BINMAN_EMBED)
u_boot_binman_embed: u_boot_binman_embed.c
u_boot_binman_embed_sm: CFLAGS += $(LDS_BINMAN_EMBED)
u_boot_binman_embed_sm: u_boot_binman_embed_sm.c
clean:
rm -f $(TARGETS)

View File

@ -2,7 +2,7 @@
/*
* Copyright (c) 2016 Google, Inc
*
* Simple program to create a _dt_ucode_base_size symbol which can be read
* Simple program to create a bss_data region so the symbol can be read
* by binutils. This is used by binman tests.
*/

View File

@ -0,0 +1,16 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2021 Google LLC
*
* Simple program including some embedded data that can be accessed by binman.
* This is used by binman tests.
*/
int first[10] = {1};
int embed[3] __attribute__((section(".embed"))) = {0x1234, 0x5678};
int second[10] = {1};
int main(void)
{
return 0;
}

View File

@ -0,0 +1,23 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2021 Google LLC
*/
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
_start = .;
__data_start = .;
.data :
{
. = ALIGN(32);
embed_start = .;
*(.embed*)
embed_end = .;
. = ALIGN(32);
*(.data*)
}
}

View File

@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2021 Google LLC
*
* Simple program to embed a devicetree. This is used by binman tests.
*/
int __attribute__((section(".mydtb"))) dtb_data[4096];
int main(void)
{
return 0;
}

View File

@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2016 Google, Inc
*/
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
. = 0x00000000;
_start = .;
. = ALIGN(4);
.text :
{
*(.text*)
}
. = ALIGN(4);
.data : {
dtb_embed_begin = .;
KEEP(*(.mydtb));
dtb_embed_end = .;
}
.interp : { *(.interp*) }
}

View File

@ -0,0 +1,13 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright 2021 Google LLC
*
* Simple program to embed a devicetree. This is used by binman tests.
*/
int __attribute__((section(".mydtb"))) dtb_data[16];
int main(void)
{
return 0;
}

View File

@ -349,7 +349,7 @@ def Run(name, *args, **kwargs):
result = command.RunPipe([all_args], capture=True, capture_stderr=True,
env=env, raise_on_error=False, binary=binary)
if result.return_code:
raise Exception("Error %d running '%s': %s" %
raise ValueError("Error %d running '%s': %s" %
(result.return_code,' '.join(all_args),
result.stderr))
return result.stdout