blob: c3969e3ede848b009882b1abbab91e6966e90219 [file] [log] [blame]
Rouven Czerwinski84c0da02019-07-02 11:57:32 +02001#!/usr/bin/env python3
Jens Wiklanderb8c97752019-05-23 17:42:09 +02002# SPDX-License-Identifier: BSD-2-Clause
3#
4# Copyright (c) 2019, Linaro Limited
5#
6
7from __future__ import print_function
8from __future__ import division
9
10import argparse
11import sys
12from elftools.elf.elffile import ELFFile
13from elftools.elf.sections import SymbolTableSection
14from elftools.elf.constants import P_FLAGS
15import struct
16import re
17from collections import deque
18
19
20def round_up(n, m):
21 if n == 0:
22 return 0
23 else:
24 return (((n - 1) // m) + 1) * m
25
26
27def emit_load_segments(elffile, outf):
28 load_size = 0
29 n = 0
30 for segment in elffile.iter_segments():
31 if segment['p_type'] == 'PT_LOAD':
32 if n == 0:
33 if segment['p_flags'] != (P_FLAGS.PF_R | P_FLAGS.PF_X):
34 print('Expected first load segment to be read/execute')
35 sys.exit(1)
36 code_size = segment['p_filesz']
37 if n == 1:
38 if segment['p_flags'] != (P_FLAGS.PF_R | P_FLAGS.PF_W):
39 print('Expected second load segment to be read/write')
40 sys.exit(1)
41 data_size = segment['p_filesz']
42 if n > 1:
43 print('Only expected two load segments')
44 sys.exit(1)
45 load_size += segment['p_filesz']
46 n = n + 1
47
Rouven Czerwinski84c0da02019-07-02 11:57:32 +020048 outf.write(b'const uint8_t ldelf_data[%d]' % round_up(load_size, 4096))
49 outf.write(b' __aligned(4096) = {\n')
Jens Wiklanderb8c97752019-05-23 17:42:09 +020050 i = 0
51 for segment in elffile.iter_segments():
52 if segment['p_type'] == 'PT_LOAD':
53 data = segment.data()
54 for n in range(segment['p_filesz']):
55 if i % 8 == 0:
Rouven Czerwinski84c0da02019-07-02 11:57:32 +020056 outf.write(b'\t')
57 outf.write(b'0x' + '{:02x}'.format(data[n]).encode('utf-8')
58 + b',')
Jens Wiklanderb8c97752019-05-23 17:42:09 +020059 i = i + 1
60 if i % 8 == 0 or i == load_size:
Rouven Czerwinski84c0da02019-07-02 11:57:32 +020061 outf.write(b'\n')
Jens Wiklanderb8c97752019-05-23 17:42:09 +020062 else:
Rouven Czerwinski84c0da02019-07-02 11:57:32 +020063 outf.write(b' ')
64 outf.write(b'};\n')
Jens Wiklanderb8c97752019-05-23 17:42:09 +020065
Rouven Czerwinski84c0da02019-07-02 11:57:32 +020066 outf.write(b'const unsigned int ldelf_code_size = %d;\n' % code_size)
67 outf.write(b'const unsigned int ldelf_data_size = %d;\n' % data_size)
Jens Wiklanderb8c97752019-05-23 17:42:09 +020068
69
70def get_args():
71 parser = argparse.ArgumentParser()
72
73 parser.add_argument('--input',
74 required=True, type=argparse.FileType('rb'),
75 help='The input ldelf.elf')
76
77 parser.add_argument('--output',
78 required=True, type=argparse.FileType('wb'),
79 help='The output ldelf_hex.c')
80
81 return parser.parse_args()
82
83
84def main():
85 args = get_args()
86 inf = args.input
87 outf = args.output
88
89 elffile = ELFFile(inf)
90
Rouven Czerwinski84c0da02019-07-02 11:57:32 +020091 outf.write(b'/* Automatically generated, do no edit */\n')
92 outf.write(b'#include <compiler.h>\n')
93 outf.write(b'#include <stdint.h>\n')
Jens Wiklanderb8c97752019-05-23 17:42:09 +020094 emit_load_segments(elffile, outf)
Rouven Czerwinski84c0da02019-07-02 11:57:32 +020095 outf.write(b'const unsigned long ldelf_entry = %lu;\n' %
Jens Wiklanderb8c97752019-05-23 17:42:09 +020096 elffile.header['e_entry'])
97
98 inf.close()
99 outf.close()
100
101
102if __name__ == "__main__":
103 main()