xref: /optee_os/scripts/gen_ldelf_hex.py (revision d2fb6900542cce08d1ac262a4f2c34348321af70)
184c0da04SRouven Czerwinski#!/usr/bin/env python3
2b8c97753SJens Wiklander# SPDX-License-Identifier: BSD-2-Clause
3b8c97753SJens Wiklander#
4b8c97753SJens Wiklander# Copyright (c) 2019, Linaro Limited
5b8c97753SJens Wiklander#
6b8c97753SJens Wiklander
7b8c97753SJens Wiklanderfrom __future__ import print_function
8b8c97753SJens Wiklanderfrom __future__ import division
9b8c97753SJens Wiklander
10b8c97753SJens Wiklanderimport argparse
11b8c97753SJens Wiklanderimport sys
12b8c97753SJens Wiklanderfrom elftools.elf.elffile import ELFFile
13b8c97753SJens Wiklanderfrom elftools.elf.sections import SymbolTableSection
14b8c97753SJens Wiklanderfrom elftools.elf.constants import P_FLAGS
15b8c97753SJens Wiklanderimport struct
16b8c97753SJens Wiklanderimport re
17b8c97753SJens Wiklanderfrom collections import deque
18b8c97753SJens Wiklander
19b8c97753SJens Wiklander
20b8c97753SJens Wiklanderdef round_up(n, m):
21b8c97753SJens Wiklander    if n == 0:
22b8c97753SJens Wiklander        return 0
23b8c97753SJens Wiklander    else:
24b8c97753SJens Wiklander        return (((n - 1) // m) + 1) * m
25b8c97753SJens Wiklander
26b8c97753SJens Wiklander
27b8c97753SJens Wiklanderdef emit_load_segments(elffile, outf):
28b8c97753SJens Wiklander    load_size = 0
29*d2fb6900SJerome Forissier    data_size = 0
30*d2fb6900SJerome Forissier    next_rwseg_va = 0
31b8c97753SJens Wiklander    n = 0
32b8c97753SJens Wiklander    for segment in elffile.iter_segments():
33b8c97753SJens Wiklander        if segment['p_type'] == 'PT_LOAD':
34b8c97753SJens Wiklander            if n == 0:
35b8c97753SJens Wiklander                if segment['p_flags'] != (P_FLAGS.PF_R | P_FLAGS.PF_X):
36b8c97753SJens Wiklander                    print('Expected first load segment to be read/execute')
37b8c97753SJens Wiklander                    sys.exit(1)
38b8c97753SJens Wiklander                code_size = segment['p_filesz']
39*d2fb6900SJerome Forissier            else:
40b8c97753SJens Wiklander                if segment['p_flags'] != (P_FLAGS.PF_R | P_FLAGS.PF_W):
41*d2fb6900SJerome Forissier                    print('Expected load segment to be read/write')
42b8c97753SJens Wiklander                    sys.exit(1)
43*d2fb6900SJerome Forissier                if next_rwseg_va and segment['p_vaddr'] != next_rwseg_va:
44*d2fb6900SJerome Forissier                    print('Expected contiguous read/write segments')
45*d2fb6900SJerome Forissier                    print(segment['p_vaddr'])
46*d2fb6900SJerome Forissier                    print(next_rwseg_va)
47b8c97753SJens Wiklander                    sys.exit(1)
48*d2fb6900SJerome Forissier                data_size += segment['p_filesz']
49*d2fb6900SJerome Forissier                next_rwseg_va = segment['p_vaddr'] + segment['p_filesz']
50b8c97753SJens Wiklander            load_size += segment['p_filesz']
51b8c97753SJens Wiklander            n = n + 1
52b8c97753SJens Wiklander
5384c0da04SRouven Czerwinski    outf.write(b'const uint8_t ldelf_data[%d]' % round_up(load_size, 4096))
5484c0da04SRouven Czerwinski    outf.write(b' __aligned(4096) = {\n')
55b8c97753SJens Wiklander    i = 0
56b8c97753SJens Wiklander    for segment in elffile.iter_segments():
57b8c97753SJens Wiklander        if segment['p_type'] == 'PT_LOAD':
58b8c97753SJens Wiklander            data = segment.data()
59b8c97753SJens Wiklander            for n in range(segment['p_filesz']):
60b8c97753SJens Wiklander                if i % 8 == 0:
6184c0da04SRouven Czerwinski                    outf.write(b'\t')
6284c0da04SRouven Czerwinski                outf.write(b'0x' + '{:02x}'.format(data[n]).encode('utf-8')
6384c0da04SRouven Czerwinski                           + b',')
64b8c97753SJens Wiklander                i = i + 1
65b8c97753SJens Wiklander                if i % 8 == 0 or i == load_size:
6684c0da04SRouven Czerwinski                    outf.write(b'\n')
67b8c97753SJens Wiklander                else:
6884c0da04SRouven Czerwinski                    outf.write(b' ')
6984c0da04SRouven Czerwinski    outf.write(b'};\n')
70b8c97753SJens Wiklander
7184c0da04SRouven Czerwinski    outf.write(b'const unsigned int ldelf_code_size = %d;\n' % code_size)
7284c0da04SRouven Czerwinski    outf.write(b'const unsigned int ldelf_data_size = %d;\n' % data_size)
73b8c97753SJens Wiklander
74b8c97753SJens Wiklander
75b8c97753SJens Wiklanderdef get_args():
76b8c97753SJens Wiklander    parser = argparse.ArgumentParser()
77b8c97753SJens Wiklander
78b8c97753SJens Wiklander    parser.add_argument('--input',
79b8c97753SJens Wiklander                        required=True, type=argparse.FileType('rb'),
80b8c97753SJens Wiklander                        help='The input ldelf.elf')
81b8c97753SJens Wiklander
82b8c97753SJens Wiklander    parser.add_argument('--output',
83b8c97753SJens Wiklander                        required=True, type=argparse.FileType('wb'),
84b8c97753SJens Wiklander                        help='The output ldelf_hex.c')
85b8c97753SJens Wiklander
86b8c97753SJens Wiklander    return parser.parse_args()
87b8c97753SJens Wiklander
88b8c97753SJens Wiklander
89b8c97753SJens Wiklanderdef main():
90b8c97753SJens Wiklander    args = get_args()
91b8c97753SJens Wiklander    inf = args.input
92b8c97753SJens Wiklander    outf = args.output
93b8c97753SJens Wiklander
94b8c97753SJens Wiklander    elffile = ELFFile(inf)
95b8c97753SJens Wiklander
9684c0da04SRouven Czerwinski    outf.write(b'/* Automatically generated, do no edit */\n')
9784c0da04SRouven Czerwinski    outf.write(b'#include <compiler.h>\n')
9884c0da04SRouven Czerwinski    outf.write(b'#include <stdint.h>\n')
99b8c97753SJens Wiklander    emit_load_segments(elffile, outf)
10084c0da04SRouven Czerwinski    outf.write(b'const unsigned long ldelf_entry = %lu;\n' %
101b8c97753SJens Wiklander               elffile.header['e_entry'])
102b8c97753SJens Wiklander
103b8c97753SJens Wiklander    inf.close()
104b8c97753SJens Wiklander    outf.close()
105b8c97753SJens Wiklander
106b8c97753SJens Wiklander
107b8c97753SJens Wiklanderif __name__ == "__main__":
108b8c97753SJens Wiklander    main()
109