def EnsureCompiled(fname, tmpdir=None, capture_stderr=False): """Compile an fdt .dts source file into a .dtb binary blob if needed. Args: fname: Filename (if .dts it will be compiled). It not it will be left alone tmpdir: Temporary directory for output files, or None to use the tools-module output directory Returns: Filename of resulting .dtb file """ _, ext = os.path.splitext(fname) if ext != '.dts': return fname if tmpdir: dts_input = os.path.join(tmpdir, 'source.dts') dtb_output = os.path.join(tmpdir, 'source.dtb') else: dts_input = tools.get_output_filename('source.dts') dtb_output = tools.get_output_filename('source.dtb') search_paths = [os.path.join(os.getcwd(), 'include')] root, _ = os.path.splitext(fname) cc, args = tools.get_target_compile_tool('cc') args += ['-E', '-P', '-x', 'assembler-with-cpp', '-D__ASSEMBLY__'] args += ['-Ulinux'] for path in search_paths: args.extend(['-I', path]) args += ['-o', dts_input, fname] command.run(cc, *args) # If we don't have a directory, put it in the tools tempdir search_list = [] for path in search_paths: search_list.extend(['-i', path]) dtc, args = tools.get_target_compile_tool('dtc') args += [ '-I', 'dts', '-o', dtb_output, '-O', 'dtb', '-W', 'no-unit_address_vs_reg' ] args.extend(search_list) args.append(dts_input) command.run(dtc, *args, capture_stderr=capture_stderr) return dtb_output
def testMakeElf(self): """Test for the MakeElf function""" outdir = tempfile.mkdtemp(prefix='elf.') expected_text = b'1234' expected_data = b'wxyz' elf_fname = os.path.join(outdir, 'elf') bin_fname = os.path.join(outdir, 'bin') # Make an Elf file and then convert it to a fkat binary file. This # should produce the original data. elf.MakeElf(elf_fname, expected_text, expected_data) objcopy, args = tools.get_target_compile_tool('objcopy') args += ['-O', 'binary', elf_fname, bin_fname] stdout = command.output(objcopy, *args) with open(bin_fname, 'rb') as fd: data = fd.read() self.assertEqual(expected_text + expected_data, data) shutil.rmtree(outdir)
def MakeElf(elf_fname, text, data): """Make an elf file with the given data in a single section The output file has a several section including '.text' and '.data', containing the info provided in arguments. Args: elf_fname: Output filename text: Text (code) to put in the file's .text section data: Data to put in the file's .data section """ outdir = tempfile.mkdtemp(prefix='binman.elf.') s_file = os.path.join(outdir, 'elf.S') # Spilt the text into two parts so that we can make the entry point two # bytes after the start of the text section text_bytes1 = ['\t.byte\t%#x' % byte for byte in text[:2]] text_bytes2 = ['\t.byte\t%#x' % byte for byte in text[2:]] data_bytes = ['\t.byte\t%#x' % byte for byte in data] with open(s_file, 'w') as fd: print( '''/* Auto-generated C program to produce an ELF file for testing */ .section .text .code32 .globl _start .type _start, @function %s _start: %s .ident "comment" .comm fred,8,4 .section .empty .globl _empty _empty: .byte 1 .globl ernie .data .type ernie, @object .size ernie, 4 ernie: %s ''' % ('\n'.join(text_bytes1), '\n'.join(text_bytes2), '\n'.join(data_bytes)), file=fd) lds_file = os.path.join(outdir, 'elf.lds') # Use a linker script to set the alignment and text address. with open(lds_file, 'w') as fd: print( '''/* Auto-generated linker script to produce an ELF file for testing */ PHDRS { text PT_LOAD ; data PT_LOAD ; empty PT_LOAD FLAGS ( 6 ) ; note PT_NOTE ; } SECTIONS { . = 0xfef20000; ENTRY(_start) .text . : SUBALIGN(0) { *(.text) } :text .data : { *(.data) } :data _bss_start = .; .empty : { *(.empty) } :empty /DISCARD/ : { *(.note.gnu.property) } .note : { *(.comment) } :note .bss _bss_start (OVERLAY) : { *(.bss) } } ''', file=fd) # -static: Avoid requiring any shared libraries # -nostdlib: Don't link with C library # -Wl,--build-id=none: Don't generate a build ID, so that we just get the # text section at the start # -m32: Build for 32-bit x86 # -T...: Specifies the link script, which sets the start address cc, args = tools.get_target_compile_tool('cc') args += [ '-static', '-nostdlib', '-Wl,--build-id=none', '-m32', '-T', lds_file, '-o', elf_fname, s_file ] stdout = command.output(cc, *args) shutil.rmtree(outdir)