summaryrefslogtreecommitdiff
path: root/tools/binman/elf.py
diff options
context:
space:
mode:
authorSimon Glass <sjg@chromium.org>2019-07-08 13:18:34 -0600
committerSimon Glass <sjg@chromium.org>2019-07-23 20:27:57 -0700
commitf58558a5ae785fdbdaadbe172a2bb86158f01d4f (patch)
tree81ba045929b780fe38ec141057a8d629986a49dd /tools/binman/elf.py
parent45cb9d80ae274fe46ed64c76cc87a36fc994a182 (diff)
binman: Add a function to create a sample ELF file
It is useful to create an ELF file for testing purposes, with just the right attributes used by the test. Add a function to handle this, along with a test that it works correctly. Signed-off-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'tools/binman/elf.py')
-rw-r--r--tools/binman/elf.py97
1 files changed, 97 insertions, 0 deletions
diff --git a/tools/binman/elf.py b/tools/binman/elf.py
index 828681d76d0..82ea8c3857f 100644
--- a/tools/binman/elf.py
+++ b/tools/binman/elf.py
@@ -5,11 +5,15 @@
# Handle various things related to ELF images
#
+from __future__ import print_function
+
from collections import namedtuple, OrderedDict
import command
import os
import re
+import shutil
import struct
+import tempfile
import tools
@@ -128,3 +132,96 @@ def LookupAndWriteSymbols(elf_fname, entry, section):
(msg, name, offset, value, len(value_bytes)))
entry.data = (entry.data[:offset] + value_bytes +
entry.data[offset + sym.size:])
+
+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' % tools.ToByte(byte) for byte in text[:2]]
+ text_bytes2 = ['\t.byte\t%#x' % tools.ToByte(byte) for byte in text[2:]]
+ data_bytes = ['\t.byte\t%#x' % tools.ToByte(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
+ .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
+ stdout = command.Output('cc', '-static', '-nostdlib', '-Wl,--build-id=none',
+ '-m32','-T', lds_file, '-o', elf_fname, s_file)
+ shutil.rmtree(outdir)