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 12*7ba36df9SVolodymyr Babchuktry: 13b8c97753SJens Wiklander from elftools.elf.elffile import ELFFile 14b8c97753SJens Wiklander from elftools.elf.sections import SymbolTableSection 15b8c97753SJens Wiklander from elftools.elf.constants import P_FLAGS 16*7ba36df9SVolodymyr Babchukexcept ImportError: 17*7ba36df9SVolodymyr Babchuk print(""" 18*7ba36df9SVolodymyr Babchuk*** 19*7ba36df9SVolodymyr BabchukCan't find elftools module. Probably it is not installed on your system. 20*7ba36df9SVolodymyr BabchukYou can install this module with 21*7ba36df9SVolodymyr Babchuk 22*7ba36df9SVolodymyr Babchuk$ apt install python3-pyelftools 23*7ba36df9SVolodymyr Babchuk 24*7ba36df9SVolodymyr Babchukif you are using Ubuntu. Or try to search for "pyelftools" or "elftools" in 25*7ba36df9SVolodymyr Babchukyour package manager if you are using some other distribution. 26*7ba36df9SVolodymyr Babchuk*** 27*7ba36df9SVolodymyr Babchuk""") 28*7ba36df9SVolodymyr Babchuk raise 29*7ba36df9SVolodymyr Babchuk 30b8c97753SJens Wiklanderimport struct 31b8c97753SJens Wiklanderimport re 32b8c97753SJens Wiklanderfrom collections import deque 33b8c97753SJens Wiklander 34b8c97753SJens Wiklander 35b8c97753SJens Wiklanderdef round_up(n, m): 36b8c97753SJens Wiklander if n == 0: 37b8c97753SJens Wiklander return 0 38b8c97753SJens Wiklander else: 39b8c97753SJens Wiklander return (((n - 1) // m) + 1) * m 40b8c97753SJens Wiklander 41b8c97753SJens Wiklander 42b8c97753SJens Wiklanderdef emit_load_segments(elffile, outf): 43b8c97753SJens Wiklander load_size = 0 44d2fb6900SJerome Forissier data_size = 0 45d2fb6900SJerome Forissier next_rwseg_va = 0 46b8c97753SJens Wiklander n = 0 47b8c97753SJens Wiklander for segment in elffile.iter_segments(): 48b8c97753SJens Wiklander if segment['p_type'] == 'PT_LOAD': 49b8c97753SJens Wiklander if n == 0: 50b8c97753SJens Wiklander if segment['p_flags'] != (P_FLAGS.PF_R | P_FLAGS.PF_X): 51b8c97753SJens Wiklander print('Expected first load segment to be read/execute') 52b8c97753SJens Wiklander sys.exit(1) 53b8c97753SJens Wiklander code_size = segment['p_filesz'] 54d2fb6900SJerome Forissier else: 55b8c97753SJens Wiklander if segment['p_flags'] != (P_FLAGS.PF_R | P_FLAGS.PF_W): 56d2fb6900SJerome Forissier print('Expected load segment to be read/write') 57b8c97753SJens Wiklander sys.exit(1) 58d2fb6900SJerome Forissier if next_rwseg_va and segment['p_vaddr'] != next_rwseg_va: 59d2fb6900SJerome Forissier print('Expected contiguous read/write segments') 60d2fb6900SJerome Forissier print(segment['p_vaddr']) 61d2fb6900SJerome Forissier print(next_rwseg_va) 62b8c97753SJens Wiklander sys.exit(1) 63d2fb6900SJerome Forissier data_size += segment['p_filesz'] 64d2fb6900SJerome Forissier next_rwseg_va = segment['p_vaddr'] + segment['p_filesz'] 65b8c97753SJens Wiklander load_size += segment['p_filesz'] 66b8c97753SJens Wiklander n = n + 1 67b8c97753SJens Wiklander 6884c0da04SRouven Czerwinski outf.write(b'const uint8_t ldelf_data[%d]' % round_up(load_size, 4096)) 6984c0da04SRouven Czerwinski outf.write(b' __aligned(4096) = {\n') 70b8c97753SJens Wiklander i = 0 71b8c97753SJens Wiklander for segment in elffile.iter_segments(): 72b8c97753SJens Wiklander if segment['p_type'] == 'PT_LOAD': 73b8c97753SJens Wiklander data = segment.data() 74b8c97753SJens Wiklander for n in range(segment['p_filesz']): 75b8c97753SJens Wiklander if i % 8 == 0: 7684c0da04SRouven Czerwinski outf.write(b'\t') 7784c0da04SRouven Czerwinski outf.write(b'0x' + '{:02x}'.format(data[n]).encode('utf-8') 7884c0da04SRouven Czerwinski + b',') 79b8c97753SJens Wiklander i = i + 1 80b8c97753SJens Wiklander if i % 8 == 0 or i == load_size: 8184c0da04SRouven Czerwinski outf.write(b'\n') 82b8c97753SJens Wiklander else: 8384c0da04SRouven Czerwinski outf.write(b' ') 8484c0da04SRouven Czerwinski outf.write(b'};\n') 85b8c97753SJens Wiklander 8684c0da04SRouven Czerwinski outf.write(b'const unsigned int ldelf_code_size = %d;\n' % code_size) 8784c0da04SRouven Czerwinski outf.write(b'const unsigned int ldelf_data_size = %d;\n' % data_size) 88b8c97753SJens Wiklander 89b8c97753SJens Wiklander 90b8c97753SJens Wiklanderdef get_args(): 91b8c97753SJens Wiklander parser = argparse.ArgumentParser() 92b8c97753SJens Wiklander 93b8c97753SJens Wiklander parser.add_argument('--input', 94b8c97753SJens Wiklander required=True, type=argparse.FileType('rb'), 95b8c97753SJens Wiklander help='The input ldelf.elf') 96b8c97753SJens Wiklander 97b8c97753SJens Wiklander parser.add_argument('--output', 98b8c97753SJens Wiklander required=True, type=argparse.FileType('wb'), 99b8c97753SJens Wiklander help='The output ldelf_hex.c') 100b8c97753SJens Wiklander 101b8c97753SJens Wiklander return parser.parse_args() 102b8c97753SJens Wiklander 103b8c97753SJens Wiklander 104b8c97753SJens Wiklanderdef main(): 105b8c97753SJens Wiklander args = get_args() 106b8c97753SJens Wiklander inf = args.input 107b8c97753SJens Wiklander outf = args.output 108b8c97753SJens Wiklander 109b8c97753SJens Wiklander elffile = ELFFile(inf) 110b8c97753SJens Wiklander 11184c0da04SRouven Czerwinski outf.write(b'/* Automatically generated, do no edit */\n') 11284c0da04SRouven Czerwinski outf.write(b'#include <compiler.h>\n') 11384c0da04SRouven Czerwinski outf.write(b'#include <stdint.h>\n') 114b8c97753SJens Wiklander emit_load_segments(elffile, outf) 11584c0da04SRouven Czerwinski outf.write(b'const unsigned long ldelf_entry = %lu;\n' % 116b8c97753SJens Wiklander elffile.header['e_entry']) 117b8c97753SJens Wiklander 118b8c97753SJens Wiklander inf.close() 119b8c97753SJens Wiklander outf.close() 120b8c97753SJens Wiklander 121b8c97753SJens Wiklander 122b8c97753SJens Wiklanderif __name__ == "__main__": 123b8c97753SJens Wiklander main() 124