#!/bin/python """ This script patches the CRC checksums into an existing ELF file. For this, it searches the follwoing sections: 1) .text 2) .data 3) .ccmdata 4) .vectors All sections MUST be a multiple of 4 bytes long because the CRC calculation relies on whole 32 bit words. The sections are excrated and the CRC is calculated for each section. In the section .flashcrc, the script expects a single struct with the prototype: struct flash_crcs { uint32_t start_magic; uint32_t crc_section_text; uint32_t crc_section_data; uint32_t crc_section_ccm_data; uint32_t crc_section_vectors; uint32_t end_magic; }; It checks, if the start magic and end magic are set to the appropriate values and then patches in the CRC values of the sections. The magic values checked for are: 0xA8BE53F9 and 0xFFA582FF """ from elftools.elf.elffile import ELFFile from elftools.elf.segments import Segment import elftools.elf.constants as elf_const import sys import crcmod import crcmod.predefined import struct crc_calc = crcmod.predefined.mkCrcFun('crc-32-mpeg') if len(sys.argv) < 2: print("Usage:", sys.argv[0], ' ') sys.exit(-1) filename=sys.argv[1] def section_calculate_crc(section): data = bytearray(section.data()) be_data = bytearray([0 for k in range(0, len(data))]) # Rearrange data, because the STM controller sees it as 32 bit little endian words for i in range(0, int(len(data)/4)): be_data[i*4+0] = data[i*4+3] be_data[i*4+1] = data[i*4+2] be_data[i*4+2] = data[i*4+1] be_data[i*4+3] = data[i*4+0] return crc_calc(be_data) with open(filename, 'r+b') as f: elf = ELFFile(f) sections = {} sections['.text'] = elf.get_section_by_name('.text') sections['.data'] = elf.get_section_by_name('.data') sections['.ccmdata'] = elf.get_section_by_name('.ccmdata') sections['.vectors'] = elf.get_section_by_name('.vectors') for key, sec in sections.items(): if sec is None: print("Error! Section", key, "not found in ELF file!") sys.exit(-1) print('Found section', key, 'Size:', sec.data_size, 'Type:', sec['sh_type']) if sec['sh_type'] != 'SHT_PROGBITS': print('Error! Section must be of type SHT_PROGBITS') sys.exit(-1) if (sec.data_size % 4 != 0): print("Section", key, "has wrong size. Must be a multiple of 4 bytes!") sys.exit(-1) text_crc = section_calculate_crc(sections['.text']) print('CRC of .text section:', hex(text_crc)) data_crc = section_calculate_crc(sections['.data']) print('CRC of .data section:', hex(data_crc)) ccmdata_crc = section_calculate_crc(sections['.ccmdata']) print('CRC of .ccmdata section:', hex(ccmdata_crc)) vextors_crc = section_calculate_crc(sections['.vectors']) print('CRC of .vectors section:', hex(vextors_crc)) # Check the flashcrc section flashcrc_sec = elf.get_section_by_name('.flashcrc') if flashcrc_sec is None: print('Section for flash CRC missing!') sys.exit(-1) if flashcrc_sec.data_size != 6*4: print("Warning!!! .flashcrc section has wrong size:",flashcrc_sec.data_size) crc_sec_data = bytearray(flashcrc_sec.data()) magic1 = struct.unpack('