blob: 5077cc409b4a155cf3c82ddbacadc98c5a1e4333 [file] [log] [blame]
Jens Wiklanderb8c97752019-05-23 17:42:09 +02001#!/usr/bin/env python
2# 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
48 outf.write('const uint8_t ldelf_data[%d]' % round_up(load_size, 4096))
49 outf.write(' __aligned(4096) = {\n')
50 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:
56 outf.write('\t')
57 outf.write('0x' + '{:02x}'.format(ord(data[n])) + ',')
58 i = i + 1
59 if i % 8 == 0 or i == load_size:
60 outf.write('\n')
61 else:
62 outf.write(' ')
63 outf.write('};\n')
64
65 outf.write('const unsigned int ldelf_code_size = %d;\n' % code_size)
66 outf.write('const unsigned int ldelf_data_size = %d;\n' % data_size)
67
68
69def get_args():
70 parser = argparse.ArgumentParser()
71
72 parser.add_argument('--input',
73 required=True, type=argparse.FileType('rb'),
74 help='The input ldelf.elf')
75
76 parser.add_argument('--output',
77 required=True, type=argparse.FileType('wb'),
78 help='The output ldelf_hex.c')
79
80 return parser.parse_args()
81
82
83def main():
84 args = get_args()
85 inf = args.input
86 outf = args.output
87
88 elffile = ELFFile(inf)
89
90 outf.write('/* Automatically generated, do no edit */\n')
91 outf.write('#include <compiler.h>\n')
92 outf.write('#include <stdint.h>\n')
93 emit_load_segments(elffile, outf)
94 outf.write('const unsigned long ldelf_entry = %lu;\n' %
95 elffile.header['e_entry'])
96
97 inf.close()
98 outf.close()
99
100
101if __name__ == "__main__":
102 main()