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