blob: 341c84c391c0d4f5d831f1e90f304eb642415bff [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
Daniel DeGrassea766e4c2022-08-04 10:27:02 -050024import re
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010025from elftools.elf.elffile import ELFFile
26
27
Torsten Rasmussend51a67b2022-01-12 14:21:07 +010028def write_header(filename, segments, adjusted_lma):
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010029 content = []
30
Daniel DeGrassea766e4c2022-08-04 10:27:02 -050031 filename_we = re.sub(r'[\W]','_', filename).upper()
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010032 content.append(f'#ifndef {filename_we}_H')
33 content.append(f'#define {filename_we}_H')
34 content.append(f'')
35 content.append(f'#define SEGMENT_NUM {len(segments)}')
Torsten Rasmussend51a67b2022-01-12 14:21:07 +010036 content.append(f'#define ADJUSTED_LMA {adjusted_lma}')
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010037
38 for idx, segment in enumerate(segments):
39 segment_header = segment['segment'].header
40 hex_lma_addr = hex(segment_header.p_paddr)
41 hex_vma_addr = hex(segment_header.p_vaddr)
42 hex_size = hex(segment_header.p_filesz)
43
44 content.append(f'')
45 content.append(f'#define SEGMENT_LMA_ADDRESS_{idx} {hex_lma_addr}')
46 content.append(f'#define SEGMENT_VMA_ADDRESS_{idx} {hex_vma_addr}')
47 content.append(f'#define SEGMENT_SIZE_{idx} {hex_size}')
48
49 content.append(f'')
50 content.append(f'#endif /* {filename_we}_H */')
51
52 with open(filename, 'w') as out_file:
53 out_file.write('\n'.join(content))
54
55
56def read_segments(filename):
57 elffile = ELFFile(open(filename, 'rb'))
58 segments = list()
59 for segment_idx in range(elffile.num_segments()):
60 segments.insert(segment_idx, dict())
61 segments[segment_idx]['segment'] = elffile.get_segment(segment_idx)
62 return segments
63
64
65def main():
66 parser = argparse.ArgumentParser(description='''
67 Process ELF file and extract image information.
68 Create header file with extracted image information which can be included
Jamie McCraeec704442023-01-04 16:08:36 +000069 in other build systems.''', allow_abbrev=False)
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010070
71 parser.add_argument('--header-file', required=True,
72 help="""Header file to write with image data.""")
73 parser.add_argument('--elf-file', required=True,
74 help="""ELF File to process.""")
Torsten Rasmussend51a67b2022-01-12 14:21:07 +010075 parser.add_argument('--adjusted-lma', required=False, default=0,
76 help="""Adjusted LMA address value.""")
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010077 args = parser.parse_args()
78
79 segments = read_segments(args.elf_file)
Torsten Rasmussend51a67b2022-01-12 14:21:07 +010080 write_header(args.header_file, segments, args.adjusted_lma)
Torsten Rasmussenc8ddc342022-01-10 11:02:26 +010081
82
83if __name__ == "__main__":
84 main()