diff options
author | T Michael Turney <mturney@codeaurora.org> | 2018-05-01 15:59:37 -0700 |
---|---|---|
committer | Julius Werner <jwerner@chromium.org> | 2019-05-03 21:59:05 +0000 |
commit | 101098c41a047184e3eceabca2c1baa11141f36e (patch) | |
tree | b6fcf8f46131e4e8fc28554e0c79eda984bb7fca /util/ipqheader/createxbl.py | |
parent | 61309e39b3c4545f47c9107a0e0ddaedef854505 (diff) |
sdm845: Combine BB with QC-Sec for ROM boot
TEST=build & run
Change-Id: I222a56f1c9b74856a1e1ff8132bab5e041672c5d
Signed-off-by: T Michael Turney <mturney@codeaurora.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/25207
Reviewed-by: Julius Werner <jwerner@chromium.org>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'util/ipqheader/createxbl.py')
-rwxr-xr-x | util/ipqheader/createxbl.py | 714 |
1 files changed, 0 insertions, 714 deletions
diff --git a/util/ipqheader/createxbl.py b/util/ipqheader/createxbl.py deleted file mode 100755 index 1efd8bac0c..0000000000 --- a/util/ipqheader/createxbl.py +++ /dev/null @@ -1,714 +0,0 @@ -#!/usr/bin/env python2 -#============================================================================ -# -#/** @file createxbl.py -# -# GENERAL DESCRIPTION -# Concatentates XBL segments into one ELF image -# -# Copyright (c) 2016, The Linux Foundation. All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are -# met: -# * Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# * Redistributions in binary form must reproduce the above -# copyright notice, this list of conditions and the following -# disclaimer in the documentation and/or other materials provided -# with the distribution. -# * Neither the name of The Linux Foundation nor the names of its -# contributors may be used to endorse or promote products derived -# from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED -# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS -# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR -# BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, -# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE -# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN -# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -# -#**/ -# -#---------------------------------------------------------------------------- -# -# EDIT HISTORY FOR FILE -# -# This section contains comments describing changes made to the module. -# Notice that changes are listed in reverse chronological order. -# -# when who what, where, why -# -------- --- ------------------------------------------------------ -# 09/04/15 et Added -x and -d to embed xbl_sec ELF -# 02/11/15 ck Fixed missing elf type check in ZI OOB feature -# 11/04/14 ck Updated calls to mbn_tools functions -# 10/22/14 ck Added -z option to remove out of bounds ZI segments when converting from 64 to 32 -# 10/10/14 ck Added -c option and logic to enable elf type swapping -# 09/12/14 ck Added single file logic -# 08/29/14 ck Added no_hash option -# 08/29/14 ck Refactored to use proper python arguments and cleaned code -# 06/16/14 niting xbl.mbn to xbl.elf -# 05/28/14 niting Initial revision -# -#============================================================================ -from optparse import OptionParser -import os -import sys -import shutil -import mbn_tools - -PAGE_SIZE = 4096 -SEGMENT_ALIGN = 16 -ELF32_HDR_SIZE = 52 -ELF32_PHDR_SIZE = 32 -ELF64_HDR_SIZE = 64 -ELF64_PHDR_SIZE = 56 - - -############################################################################## -# main -############################################################################## -def main(): - parser = OptionParser(usage='usage: %prog [options] arguments') - - parser.add_option("-f", "--first_filepath", - action="store", type="string", dest="elf_inp_file1", - help="First ELF file to merge.") - - parser.add_option("-s", "--second_filepath", - action="store", type="string", dest="elf_inp_file2", - help="Second ELF file to merge.") - - parser.add_option("-x", "--xbl_sec_filepath", - action="store", type="string", dest="elf_inp_xbl_sec", - help="Second ELF file to merge.") - - parser.add_option("-o", "--output_filepath", - action="store", type="string", dest="binary_out", - help="Merged filename and path.") - - parser.add_option("-a", "--first_elf_arch", - action="store", type="string", dest="elf_1_arch", - help="First (and output) ELF file architecture. '32' or '64'") - - parser.add_option("-b", "--second_elf_arch", - action="store", type="string", dest="elf_2_arch", - help="Second ELF file architecture. '32' or '64'") - - parser.add_option("-d", "--xbl_sec_elf_arch", - action="store", type="string", dest="elf_xbl_sec_arch", - help="xbl_sec file architecture. '32' or '64'") - - parser.add_option("-c", "--output_elf_arch", - action="store", type="string", dest="elf_out_arch", - help="Output ELF file architecture. '32' or '64'" + \ - " If not given defaults to first file arch.") - - parser.add_option("-n", "--no_hash", - action="store_true", dest="hash_image", - help="Disables hashing of image after merging.") - - parser.add_option("-z", "--zi_out_of_bounds", - action="store_true", dest="zi_oob", - help="Removes ZI segments that have addresses greater" + \ - " than 32 bits when converting from a 64 to 32 bit ELF") - - - (options, args) = parser.parse_args() - if not options.elf_inp_file1: - parser.error('First ELF filename not given') - - if not options.binary_out: - parser.error('Output filename not given') - - if not options.elf_1_arch: - parser.error('First ELF architecture not given') - - if (not options.elf_1_arch == '64') and (not options.elf_1_arch == '32'): - parser.error('Invalid First ELF architecture given') - - # Only evaluate elf_2_arch if two files are given for merging - if options.elf_inp_file2: - if (not options.elf_2_arch == '64') and (not options.elf_2_arch == '32'): - parser.error('Invalid Second ELF architecture given') - - # Only evaluate elf_xbl_sec_arch if file is given - if options.elf_inp_xbl_sec: - if (not options.elf_xbl_sec_arch == '64') and (not options.elf_xbl_sec_arch == '32'): - parser.error('Invalid xbl_sec ELF architecture given') - - # If output file architecture is given ensure it is either '32' or '64' - if options.elf_out_arch: - if (not options.elf_out_arch == '64') and (not options.elf_out_arch == '32'): - parser.error('Invalid Output ELF architecture given') - - - gen_dict = {} - - elf_inp_file1 = options.elf_inp_file1 - - # It is valid for only one file to be "merged". This essentially just - # strips off the section names. If second file name is not given then - # set elf_inp_file2 to "" - if options.elf_inp_file2: - elf_inp_file2 = options.elf_inp_file2 - else: - elf_inp_file2 = "" - - # Do same for xbl_sec - elf_inp_xbl_sec = options.elf_inp_xbl_sec if options.elf_inp_xbl_sec else "" - - binary_out = options.binary_out - - if options.elf_1_arch == '64': - is_elf1_64_bit = True - else: - is_elf1_64_bit = False - - # If second filename is not given then set is_elf2_64_bit to false so it - # can be passed even though it is not used. - if options.elf_inp_file2: - if options.elf_2_arch == '64': - is_elf2_64_bit = True - else: - is_elf2_64_bit = False - else: - is_elf2_64_bit = False - - if options.elf_inp_xbl_sec: - if options.elf_xbl_sec_arch == '64': - is_elf_xbl_sec_64_bit = True - else: - is_elf_xbl_sec_64_bit = False - else: - is_elf_xbl_sec_64_bit = False - - # If output ELF arch is given then set is_out_elf_64_bit accordingly. - # If not then default to be input1's setting - if options.elf_out_arch: - if options.elf_out_arch == '64': - is_out_elf_64_bit = True - else: - is_out_elf_64_bit = False - else: - is_out_elf_64_bit = is_elf1_64_bit - - - # Store ZI Out of Bounds value - if not options.zi_oob: - zi_oob_enabled = False - else: - zi_oob_enabled = True - - - mbn_type = 'elf' - header_format = 'reg' - gen_dict['IMAGE_KEY_IMAGE_ID'] = mbn_tools.ImageType.APPSBL_IMG - #gen_dict['IMAGE_KEY_IMAGE_SOURCE'] = 0 - #gen_dict['IMAGE_KEY_IMAGE_DEST'] = 0 - gen_dict['IMAGE_KEY_MBN_TYPE'] = mbn_type - image_header_secflag = 'non_secure' - - source_base = os.path.splitext(str(binary_out))[0] - target_base = os.path.splitext(str(binary_out))[0] - merged_elf = source_base + "_merged.elf" - source_elf = source_base + "_nohash.elf" - target_hash = target_base + ".hash" - target_hash_hd = target_base + "_hash.hd" - target_phdr_elf = target_base + "_phdr.pbn" - target_nonsec = target_base + "_combined_hash.mbn" - - - #print "Input file 1:", elf_inp_file1 - #print "Input file 2:", elf_inp_file2 - #print "Output file:", binary_out - - merge_elfs([], - elf_inp_file1, - elf_inp_file2, - elf_inp_xbl_sec, - merged_elf, - is_elf1_64_bit, - is_elf2_64_bit, - is_elf_xbl_sec_64_bit, - is_out_elf_64_bit, - zi_oob_enabled) - - - # Hash the image if user did not explicitly say not to - if options.hash_image: - # Just copy the merged elf to the final output name - shutil.move(merged_elf, binary_out) - else: - shutil.copy(merged_elf, source_elf) - - # Create hash table - rv = mbn_tools.pboot_gen_elf([], - source_elf, - target_hash, - elf_out_file_name = target_phdr_elf, - secure_type = image_header_secflag) - if rv: - raise RuntimeError, "Failed to run pboot_gen_elf" - - # Create hash table header - rv = mbn_tools.image_header([], - gen_dict, - target_hash, - target_hash_hd, - image_header_secflag, - elf_file_name = source_elf) - if rv: - raise RuntimeError, "Failed to create image header for hash segment" - - files_to_cat_in_order = [target_hash_hd, target_hash] - mbn_tools.concat_files (target_nonsec, files_to_cat_in_order) - - # Add the hash segment into the ELF - mbn_tools.pboot_add_hash([], - target_phdr_elf, - target_nonsec, - binary_out) - - return - - -############################################################################## -# roundup -############################################################################## -def roundup(x, precision): - return x if x % precision == 0 else (x + precision - (x % precision)) - -############################################################################## -# merge_elfs -############################################################################## -def merge_elfs(env, - elf_in_file_name1, - elf_in_file_name2, - elf_in_file_xbl_sec, - elf_out_file_name, - is_elf1_64_bit, - is_elf2_64_bit, - is_elf_xbl_sec_64_bit, - is_out_elf_64_bit, - zi_oob_enabled): - - [elf_header1, phdr_table1] = \ - mbn_tools.preprocess_elf_file(elf_in_file_name1) - - # Check to make sure second file path exists before using - if elf_in_file_name2 != "": - [elf_header2, phdr_table2] = \ - mbn_tools.preprocess_elf_file(elf_in_file_name2) - - # Check to make sure xbl_sec file path exists before using - if elf_in_file_xbl_sec != "": - [elf_headerxblsec, phdr_tablexblsec] = \ - mbn_tools.preprocess_elf_file(elf_in_file_xbl_sec) - - # Open Files - elf_in_fp1 = mbn_tools.OPEN(elf_in_file_name1, "rb") - if elf_in_file_name2 != "": - elf_in_fp2 = mbn_tools.OPEN(elf_in_file_name2, "rb") - if elf_in_file_xbl_sec != "": - elf_in_fpxblsec = mbn_tools.OPEN(elf_in_file_xbl_sec, "rb") - - if elf_out_file_name is not None: - elf_out_fp = mbn_tools.OPEN(elf_out_file_name, "wb+") - - - # Calculate the new program header size. This is dependant on the output - # ELF type and number of program headers going into output. - if is_out_elf_64_bit: - phdr_total_size = elf_header1.e_phnum * ELF64_PHDR_SIZE - phdr_total_count = elf_header1.e_phnum - else: - phdr_total_size = elf_header1.e_phnum * ELF32_PHDR_SIZE - phdr_total_count = elf_header1.e_phnum - - - # This logic only applies if two files are to be merged - if elf_in_file_name2 != "": - if is_out_elf_64_bit: - phdr_total_size += elf_header2.e_phnum * ELF64_PHDR_SIZE - phdr_total_count += elf_header2.e_phnum - else: - phdr_total_size += elf_header2.e_phnum * ELF32_PHDR_SIZE - phdr_total_count += elf_header2.e_phnum - - # Account for xbl_sec header if included - if elf_in_file_xbl_sec != "": - phdr_total_count += 1 - if is_out_elf_64_bit: - phdr_total_size += ELF64_PHDR_SIZE - else: - phdr_total_size += ELF32_PHDR_SIZE - - # Create a new ELF header for the output file - if is_out_elf_64_bit: - out_elf_header = mbn_tools.Elf64_Ehdr('\0' * ELF64_HDR_SIZE) - out_elf_header.e_phoff = ELF64_HDR_SIZE - out_elf_header.e_ehsize = ELF64_HDR_SIZE - out_elf_header.e_phentsize = ELF64_PHDR_SIZE - out_elf_header.e_machine = 183 - out_elf_header.e_ident = str('\x7f' + 'E' + 'L' + 'F' + \ - '\x02' + \ - '\x01' + \ - '\x01' + \ - '\x00' + \ - '\x00' + \ - ('\x00' * 7)) - - out_elf_header.e_entry = elf_header1.e_entry - else: - out_elf_header = mbn_tools.Elf32_Ehdr('\0' * ELF32_HDR_SIZE) - out_elf_header.e_phoff = ELF32_HDR_SIZE - out_elf_header.e_ehsize = ELF32_HDR_SIZE - out_elf_header.e_phentsize = ELF32_PHDR_SIZE - out_elf_header.e_machine = 40 - out_elf_header.e_entry = elf_header1.e_entry - out_elf_header.e_ident = str('\x7f' + 'E' + 'L' + 'F' + \ - '\x01' + \ - '\x01' + \ - '\x01' + \ - '\x00' + \ - '\x00' + \ - ('\x00' * 7)) - - # Address needs to be verified that it is not greater than 32 bits - # as it is possible to go from a 64 bit elf to 32. - if (elf_header1.e_entry > 0xFFFFFFFF): - print "ERROR: File 1's entry point is too large to convert." - exit() - out_elf_header.e_entry = elf_header1.e_entry - - # Common header entries - out_elf_header.e_type = 2 - out_elf_header.e_version = 1 - out_elf_header.e_shoff = 0 - out_elf_header.e_flags = 0 - out_elf_header.e_shentsize = 0 - out_elf_header.e_shnum = 0 - out_elf_header.e_shstrndx = 0 - - - # If ZI OOB is enabled then it is possible that a segment could be discarded - # Scan for that instance and handle before setting e_phnum and writing header - # Ensure ELF output is 32 bit - if zi_oob_enabled == True and is_out_elf_64_bit == False: - for i in range(len(phdr_table1)): - if (phdr_table1[i].p_vaddr > 0xFFFFFFFF) or \ - (phdr_table1[i].p_paddr > 0xFFFFFFFF): - if phdr_table1[i].p_filesz == 0: - phdr_total_count = phdr_total_count - 1 - - if elf_in_file_name2 != "": - for i in range(len(phdr_table2)): - if (phdr_table2[i].p_vaddr > 0xFFFFFFFF) or \ - (phdr_table2[i].p_paddr > 0xFFFFFFFF): - if phdr_table2[i].p_filesz == 0: - phdr_total_count = phdr_total_count - 1 - # Do not include xbl_sec in above calculation - # xbl_sec is to be treated as a single blob - - - # Now it is ok to populate the ELF header and write it out - out_elf_header.e_phnum = phdr_total_count - - # write elf header - if is_out_elf_64_bit == False: - elf_out_fp.write(mbn_tools.Elf32_Ehdr.getPackedData(out_elf_header)) - else: - elf_out_fp.write(mbn_tools.Elf64_Ehdr.getPackedData(out_elf_header)) - - phdr_offset = out_elf_header.e_phoff # offset of where to put next phdr - - # offset the start of the segments just after the program headers - segment_offset = roundup(out_elf_header.e_phoff + phdr_total_size, PAGE_SIZE) - - - # Output first elf data - for i in range(elf_header1.e_phnum): - curr_phdr = phdr_table1[i] - - # Copy program header piece by piece to ensure possible conversion success - if is_out_elf_64_bit == True: - # Converting from 32 to 64 elf requires no data size validation - new_phdr = mbn_tools.Elf64_Phdr('\0' * ELF64_PHDR_SIZE) - new_phdr.p_type = curr_phdr.p_type - new_phdr.p_offset = segment_offset - new_phdr.p_vaddr = curr_phdr.p_vaddr - new_phdr.p_paddr = curr_phdr.p_paddr - new_phdr.p_filesz = curr_phdr.p_filesz - new_phdr.p_memsz = curr_phdr.p_memsz - new_phdr.p_flags = curr_phdr.p_flags - new_phdr.p_align = curr_phdr.p_align - else: - # Converting from 64 to 32 elf requires data size validation - # Note that there is an option to discard a segment if it is only ZI - # and its address is greater than 32 bits - new_phdr = mbn_tools.Elf32_Phdr('\0' * ELF32_PHDR_SIZE) - new_phdr.p_type = curr_phdr.p_type - new_phdr.p_offset = segment_offset - - if curr_phdr.p_vaddr > 0xFFFFFFFF: - if (zi_oob_enabled == True) and (curr_phdr.p_filesz == 0): - continue - else: - print "ERROR: File 1 VAddr is too large for conversion." - exit() - new_phdr.p_vaddr = curr_phdr.p_vaddr - - if curr_phdr.p_paddr > 0xFFFFFFFF: - if (zi_oob_enabled == True) and (curr_phdr.p_filesz == 0): - continue - else: - print "ERROR: File 1 PAddr is too large for conversion." - exit() - new_phdr.p_paddr = curr_phdr.p_paddr - - if curr_phdr.p_filesz > 0xFFFFFFFF: - print "ERROR: File 1 Filesz is too large for conversion." - exit() - new_phdr.p_filesz = curr_phdr.p_filesz - - if curr_phdr.p_memsz > 0xFFFFFFFF: - print "ERROR: File 1 Memsz is too large for conversion." - exit() - new_phdr.p_memsz = curr_phdr.p_memsz - - if curr_phdr.p_flags > 0xFFFFFFFF: - print "ERROR: File 1 Flags is too large for conversion." - exit() - new_phdr.p_flags = curr_phdr.p_flags - - if curr_phdr.p_align > 0xFFFFFFFF: - print "ERROR: File 1 Align is too large for conversion." - exit() - new_phdr.p_align = curr_phdr.p_align - - - #print "i=",i - #print "phdr_offset=", phdr_offset - - # update output file location to next phdr location - elf_out_fp.seek(phdr_offset) - # increment phdr_offset to next location - phdr_offset += out_elf_header.e_phentsize - - inp_data_offset = curr_phdr.p_offset # used to read data from input file - -# print "inp_data_offset=" -# print inp_data_offset -# -# print "curr_phdr.p_offset=" -# print curr_phdr.p_offset -# -# print "curr_phdr.p_filesz=" -# print curr_phdr.p_filesz - - # output current phdr - if is_out_elf_64_bit == False: - elf_out_fp.write(mbn_tools.Elf32_Phdr.getPackedData(new_phdr)) - else: - elf_out_fp.write(mbn_tools.Elf64_Phdr.getPackedData(new_phdr)) - - # Copy the ELF segment - bytes_written = mbn_tools.file_copy_offset(elf_in_fp1, - inp_data_offset, - elf_out_fp, - new_phdr.p_offset, - new_phdr.p_filesz) - - # update data segment offset to be aligned after previous segment - segment_offset += roundup(new_phdr.p_filesz, SEGMENT_ALIGN); - elf_in_fp1.close() - - # Output second elf data if applicable - if elf_in_file_name2 != "": - for i in range(elf_header2.e_phnum): - curr_phdr = phdr_table2[i] - - # Copy program header piece by piece to ensure possible conversion success - if is_out_elf_64_bit == True: - # Converting from 32 to 64 elf requires no data size validation - new_phdr = mbn_tools.Elf64_Phdr('\0' * ELF64_PHDR_SIZE) - new_phdr.p_type = curr_phdr.p_type - new_phdr.p_offset = segment_offset - new_phdr.p_vaddr = curr_phdr.p_vaddr - new_phdr.p_paddr = curr_phdr.p_paddr - new_phdr.p_filesz = curr_phdr.p_filesz - new_phdr.p_memsz = curr_phdr.p_memsz - new_phdr.p_flags = curr_phdr.p_flags - new_phdr.p_align = curr_phdr.p_align - else: - # Converting from 64 to 32 elf requires data size validation - # Note that there is an option to discard a segment if it is only ZI - # and its address is greater than 32 bits - new_phdr = mbn_tools.Elf32_Phdr('\0' * ELF32_PHDR_SIZE) - new_phdr.p_type = curr_phdr.p_type - new_phdr.p_offset = segment_offset - - if curr_phdr.p_vaddr > 0xFFFFFFFF: - if (zi_oob_enabled == True) and (curr_phdr.p_filesz == 0): - continue - else: - print "ERROR: File 2 VAddr is too large for conversion." - exit() - new_phdr.p_vaddr = curr_phdr.p_vaddr - - if curr_phdr.p_paddr > 0xFFFFFFFF: - if (zi_oob_enabled == True) and (curr_phdr.p_filesz == 0): - continue - else: - print "ERROR: File 2 PAddr is too large for conversion." - exit() - new_phdr.p_paddr = curr_phdr.p_paddr - - if curr_phdr.p_filesz > 0xFFFFFFFF: - print "ERROR: File 2 Filesz is too large for conversion." - exit() - new_phdr.p_filesz = curr_phdr.p_filesz - - if curr_phdr.p_memsz > 0xFFFFFFFF: - print "ERROR: File 2 Memsz is too large for conversion." - exit() - new_phdr.p_memsz = curr_phdr.p_memsz - - if curr_phdr.p_flags > 0xFFFFFFFF: - print "ERROR: File 2 Flags is too large for conversion." - exit() - new_phdr.p_flags = curr_phdr.p_flags - - if curr_phdr.p_align > 0xFFFFFFFF: - print "ERROR: File 2 Align is too large for conversion." - exit() - new_phdr.p_align = curr_phdr.p_align - - -# print "i=",i -# print "phdr_offset=", phdr_offset - - # update output file location to next phdr location - elf_out_fp.seek(phdr_offset) - # increment phdr_offset to next location - phdr_offset += out_elf_header.e_phentsize - - inp_data_offset = curr_phdr.p_offset # used to read data from input file - -# print "inp_data_offset=" -# print inp_data_offset -# -# print "curr_phdr.p_offset=" -# print curr_phdr.p_offset -# -# print "curr_phdr.p_filesz=" -# print curr_phdr.p_filesz - - # output current phdr - if is_out_elf_64_bit == False: - elf_out_fp.write(mbn_tools.Elf32_Phdr.getPackedData(new_phdr)) - else: - elf_out_fp.write(mbn_tools.Elf64_Phdr.getPackedData(new_phdr)) - - # Copy the ELF segment - bytes_written = mbn_tools.file_copy_offset(elf_in_fp2, - inp_data_offset, - elf_out_fp, - new_phdr.p_offset, - new_phdr.p_filesz) - - # update data segment offset to be aligned after previous segment - segment_offset += roundup(new_phdr.p_filesz, SEGMENT_ALIGN); - elf_in_fp2.close() - - # Embed xbl_sec image if provided - if elf_in_file_xbl_sec != "": - - # Scan pheaders in xbl_sec for segment that contains entry point address - entry_seg_offset = -1 - entry_addr = elf_headerxblsec.e_entry - for i in range(elf_headerxblsec.e_phnum): - phdr = phdr_tablexblsec[i] - max_addr = phdr.p_vaddr + phdr.p_memsz - if phdr.p_vaddr <= entry_addr <= max_addr: - entry_seg_offset = phdr.p_offset - break - if entry_seg_offset == -1: - print "Error: Failed to find entry point in any segment!" - exit() - # magical equation for program header's phys and virt addr - phys_virt_addr = entry_addr - entry_seg_offset - - if is_out_elf_64_bit: - # Converting from 32 to 64 elf requires no data size validation - new_phdr = mbn_tools.Elf64_Phdr('\0' * ELF64_PHDR_SIZE) - new_phdr.p_type = 0x1 - new_phdr.p_offset = segment_offset - new_phdr.p_vaddr = phys_virt_addr - new_phdr.p_paddr = phys_virt_addr - new_phdr.p_filesz = os.path.getsize(elf_in_file_xbl_sec) - new_phdr.p_memsz = new_phdr.p_filesz - new_phdr.p_flags = 0x5 - new_phdr.p_align = 0x1000 - else: - # Converting from 64 to 32 elf requires data size validation - # Don't discard the segment containing xbl_sec, simply error out - # if the address is greater than 32 bits - new_phdr = mbn_tools.Elf32_Phdr('\0' * ELF32_PHDR_SIZE) - new_phdr.p_type = 0x1 # - new_phdr.p_offset = segment_offset - new_phdr.p_flags = 0x5 - new_phdr.p_align = 0x1000 - - if phys_virt_addr > 0xFFFFFFFF: - if zi_oob_enabled == False or curr_phdr.p_filesz != 0: - print "ERROR: File xbl_sec VAddr or PAddr is too large for conversion." - exit() - new_phdr.p_vaddr = phys_virt_addr - new_phdr.p_paddr = phys_virt_addr - - if os.path.getsize(elf_in_file_xbl_sec) > 0xFFFFFFFF: - print "ERROR: File xbl_sec Filesz is too large for conversion." - exit() - new_phdr.p_filesz = os.path.getsize(elf_in_file_xbl_sec) - new_phdr.p_memsz = new_phdr.p_filesz - - - # update output file location to next phdr location - elf_out_fp.seek(phdr_offset) - # increment phdr_offset to next location - phdr_offset += out_elf_header.e_phentsize - # Copy entire xbl_sec file, so start from byte 0 - inp_data_offset = 0 - - # Output xbl_sec's phdr - elf_in_file_xbl_sec - if is_out_elf_64_bit == False: - elf_out_fp.write(mbn_tools.Elf32_Phdr.getPackedData(new_phdr)) - else: - elf_out_fp.write(mbn_tools.Elf64_Phdr.getPackedData(new_phdr)) - - # Copy the ENTIRE xbl_sec image - bytes_written = mbn_tools.file_copy_offset(elf_in_fpxblsec, - inp_data_offset, - elf_out_fp, - new_phdr.p_offset, - new_phdr.p_filesz) - # update data segment offset to be aligned after previous segment - # Not necessary, unless appending more pheaders after this point - segment_offset += roundup(new_phdr.p_filesz, SEGMENT_ALIGN); - - elf_in_fpxblsec.close() - - elf_out_fp.close() - - return 0 - - -main() |