blob: 758c0b8e2aab190375413bb7885e154c26e1c2ae [file] [log] [blame]
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +01001#!/usr/bin/env python3
2#
3# Copyright (c) 2022, Nordic Semiconductor ASA
4#
5# SPDX-License-Identifier: Apache-2.0
6
7'''
8Script to generate image information files.
9
10This script creates a image information header which can be included by a
11second build system.
12This allows a second stage build system to use image information from a Zephyr
13build by including the generated header.
14
15Information included in the image information header:
16- Number of segments in the image
17- LMA address of each segment
18- VMA address of each segment
Torsten Rasmussend51a67b2022-01-12 14:21:07 +010019- LMA adjusted of each segment if the LMA addresses has been adjusted after linking
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010020- Size of each segment
21'''
22
23import argparse
24from elftools.elf.elffile import ELFFile
25
26
Torsten Rasmussend51a67b2022-01-12 14:21:07 +010027def write_header(filename, segments, adjusted_lma):
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010028 content = []
29
30 filename_we = filename.split('.h')[0].upper()
31 content.append(f'#ifndef {filename_we}_H')
32 content.append(f'#define {filename_we}_H')
33 content.append(f'')
34 content.append(f'#define SEGMENT_NUM {len(segments)}')
Torsten Rasmussend51a67b2022-01-12 14:21:07 +010035 content.append(f'#define ADJUSTED_LMA {adjusted_lma}')
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010036
37 for idx, segment in enumerate(segments):
38 segment_header = segment['segment'].header
39 hex_lma_addr = hex(segment_header.p_paddr)
40 hex_vma_addr = hex(segment_header.p_vaddr)
41 hex_size = hex(segment_header.p_filesz)
42
43 content.append(f'')
44 content.append(f'#define SEGMENT_LMA_ADDRESS_{idx} {hex_lma_addr}')
45 content.append(f'#define SEGMENT_VMA_ADDRESS_{idx} {hex_vma_addr}')
46 content.append(f'#define SEGMENT_SIZE_{idx} {hex_size}')
47
48 content.append(f'')
49 content.append(f'#endif /* {filename_we}_H */')
50
51 with open(filename, 'w') as out_file:
52 out_file.write('\n'.join(content))
53
54
55def read_segments(filename):
56 elffile = ELFFile(open(filename, 'rb'))
57 segments = list()
58 for segment_idx in range(elffile.num_segments()):
59 segments.insert(segment_idx, dict())
60 segments[segment_idx]['segment'] = elffile.get_segment(segment_idx)
61 return segments
62
63
64def main():
65 parser = argparse.ArgumentParser(description='''
66 Process ELF file and extract image information.
67 Create header file with extracted image information which can be included
68 in other build systems.''')
69
70 parser.add_argument('--header-file', required=True,
71 help="""Header file to write with image data.""")
72 parser.add_argument('--elf-file', required=True,
73 help="""ELF File to process.""")
Torsten Rasmussend51a67b2022-01-12 14:21:07 +010074 parser.add_argument('--adjusted-lma', required=False, default=0,
75 help="""Adjusted LMA address value.""")
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010076 args = parser.parse_args()
77
78 segments = read_segments(args.elf_file)
Torsten Rasmussend51a67b2022-01-12 14:21:07 +010079 write_header(args.header_file, segments, args.adjusted_lma)
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010080
81
82if __name__ == "__main__":
83 main()