2 #============================================================================
4 #/** @file createxbl.py
7 # Concatentates XBL segments into one ELF image
9 # SPDX-License-Identifier: BSD-3-Clause
13 #----------------------------------------------------------------------------
15 # EDIT HISTORY FOR FILE
17 # This section contains comments describing changes made to the module.
18 # Notice that changes are listed in reverse chronological order.
20 # when who what, where, why
21 # -------- --- ------------------------------------------------------
22 # 05/21/19 rissha Added --mbn_version to add MBN header accordingly
23 # 03/26/18 tv Added -e to enable extended MBNV5 support
24 # 09/04/15 et Added -x and -d to embed xbl_sec ELF
25 # 02/11/15 ck Fixed missing elf type check in ZI OOB feature
26 # 11/04/14 ck Updated calls to mbn_tools functions
27 # 10/22/14 ck Added -z option to remove out of bounds ZI segments when
28 # converting from 64 to 32
29 # 10/10/14 ck Added -c option and logic to enable elf type swapping
30 # 09/12/14 ck Added single file logic
31 # 08/29/14 ck Added no_hash option
32 # 08/29/14 ck Refactored to use proper python arguments and cleaned code
33 # 06/16/14 niting xbl.mbn to xbl.elf
34 # 05/28/14 niting Initial revision
36 #============================================================================
37 from optparse
import OptionParser
51 ##############################################################################
53 ##############################################################################
55 parser
= OptionParser(usage
='usage: %prog [options] arguments')
57 parser
.add_option("-f", "--first_filepath",
58 action
="store", type="string", dest
="elf_inp_file1",
59 help="First ELF file to merge.")
61 parser
.add_option("-s", "--second_filepath",
62 action
="store", type="string", dest
="elf_inp_file2",
63 help="Second ELF file to merge.")
65 parser
.add_option("-x", "--xbl_sec_filepath",
66 action
="store", type="string", dest
="elf_inp_xbl_sec",
67 help="Second ELF file to merge.")
69 parser
.add_option("-o", "--output_filepath",
70 action
="store", type="string", dest
="binary_out",
71 help="Merged filename and path.")
73 parser
.add_option("-a", "--first_elf_arch",
74 action
="store", type="string", dest
="elf_1_arch",
75 help="First (and output) ELF file architecture. '32' or '64'")
77 parser
.add_option("-b", "--second_elf_arch",
78 action
="store", type="string", dest
="elf_2_arch",
79 help="Second ELF file architecture. '32' or '64'")
81 parser
.add_option("-d", "--xbl_sec_elf_arch",
82 action
="store", type="string", dest
="elf_xbl_sec_arch",
83 help="xbl_sec file architecture. '32' or '64'")
85 parser
.add_option("-c", "--output_elf_arch",
86 action
="store", type="string", dest
="elf_out_arch",
87 help="Output ELF file architecture. '32' or '64'" + \
88 " If not given defaults to first file arch.")
90 parser
.add_option("-n", "--no_hash",
91 action
="store_true", dest
="hash_image",
92 help="Disables hashing of image after merging.")
94 parser
.add_option("-z", "--zi_out_of_bounds",
95 action
="store_true", dest
="zi_oob",
96 help="Removes ZI segments that have addresses greater" + \
97 " than 32 bits when converting from a 64 to 32 bit ELF")
99 parser
.add_option("--mbn_version",
100 action
="store", type="int", dest
="mbn_version",
101 help="Add mbn header in elf image. '3', '5' or '6'")
104 (options
, args
) = parser
.parse_args()
105 if not options
.elf_inp_file1
:
106 parser
.error('First ELF filename not given')
108 if not options
.binary_out
:
109 parser
.error('Output filename not given')
111 if not options
.elf_1_arch
:
112 parser
.error('First ELF architecture not given')
114 if (not options
.elf_1_arch
== '64') and (not options
.elf_1_arch
== '32'):
115 parser
.error('Invalid First ELF architecture given')
117 # Only evaluate elf_2_arch if two files are given for merging
118 if options
.elf_inp_file2
:
119 if (not options
.elf_2_arch
== '64') and (not options
.elf_2_arch
== '32'):
120 parser
.error('Invalid Second ELF architecture given')
122 # Only evaluate elf_xbl_sec_arch if file is given
123 if options
.elf_inp_xbl_sec
:
124 if (not options
.elf_xbl_sec_arch
== '64') and (not options
.elf_xbl_sec_arch
== '32'):
125 parser
.error('Invalid xbl_sec ELF architecture given')
127 # If output file architecture is given ensure it is either '32' or '64'
128 if options
.elf_out_arch
:
129 if (not options
.elf_out_arch
== '64') and (not options
.elf_out_arch
== '32'):
130 parser
.error('Invalid Output ELF architecture given')
135 elf_inp_file1
= options
.elf_inp_file1
137 # It is valid for only one file to be "merged". This essentially just
138 # strips off the section names. If second file name is not given then
139 # set elf_inp_file2 to ""
140 if options
.elf_inp_file2
:
141 elf_inp_file2
= options
.elf_inp_file2
145 # Do same for xbl_sec
146 elf_inp_xbl_sec
= options
.elf_inp_xbl_sec
if options
.elf_inp_xbl_sec
else ""
148 binary_out
= options
.binary_out
150 if options
.elf_1_arch
== '64':
151 is_elf1_64_bit
= True
153 is_elf1_64_bit
= False
155 # If second filename is not given then set is_elf2_64_bit to false so it
156 # can be passed even though it is not used.
157 if options
.elf_inp_file2
:
158 if options
.elf_2_arch
== '64':
159 is_elf2_64_bit
= True
161 is_elf2_64_bit
= False
163 is_elf2_64_bit
= False
165 if options
.elf_inp_xbl_sec
:
166 if options
.elf_xbl_sec_arch
== '64':
167 is_elf_xbl_sec_64_bit
= True
169 is_elf_xbl_sec_64_bit
= False
171 is_elf_xbl_sec_64_bit
= False
173 # If output ELF arch is given then set is_out_elf_64_bit accordingly.
174 # If not then default to be input1's setting
175 if options
.elf_out_arch
:
176 if options
.elf_out_arch
== '64':
177 is_out_elf_64_bit
= True
179 is_out_elf_64_bit
= False
181 is_out_elf_64_bit
= is_elf1_64_bit
184 # Store ZI Out of Bounds value
185 if not options
.zi_oob
:
186 zi_oob_enabled
= False
188 zi_oob_enabled
= True
192 if options
.elf_inp_xbl_sec
:
195 if options
.mbn_version
:
196 header_version
= options
.mbn_version
199 header_format
= 'reg'
200 gen_dict
['IMAGE_KEY_IMAGE_ID'] = mbn_tools
.ImageType
.APPSBL_IMG
201 #gen_dict['IMAGE_KEY_IMAGE_SOURCE'] = 0
202 #gen_dict['IMAGE_KEY_IMAGE_DEST'] = 0
203 gen_dict
['IMAGE_KEY_MBN_TYPE'] = mbn_type
204 image_header_secflag
= 'non_secure'
206 source_base
= os
.path
.splitext(str(binary_out
))[0]
207 target_base
= os
.path
.splitext(str(binary_out
))[0]
208 merged_elf
= source_base
+ "_merged.elf"
209 source_elf
= source_base
+ "_nohash.elf"
210 target_hash
= target_base
+ ".hash"
211 target_hash_hd
= target_base
+ "_hash.hd"
212 target_phdr_elf
= target_base
+ "_phdr.pbn"
213 target_nonsec
= target_base
+ "_combined_hash.mbn"
216 #print("Input file 1:", elf_inp_file1)
217 #print("Input file 2:", elf_inp_file2)
218 #print("Output file:", binary_out)
227 is_elf_xbl_sec_64_bit
,
233 # Hash the image if user did not explicitly say not to
234 if options
.hash_image
:
235 # Just copy the merged elf to the final output name
236 shutil
.move(merged_elf
, binary_out
)
238 shutil
.copy(merged_elf
, source_elf
)
241 rv
= mbn_tools
.pboot_gen_elf([],
244 elf_out_file_name
= target_phdr_elf
,
245 secure_type
= image_header_secflag
,
246 header_version
= header_version
)
248 raise RuntimeError("Failed to run pboot_gen_elf")
250 # Create hash table header
251 rv
= mbn_tools
.image_header([],
255 image_header_secflag
,
256 elf_file_name
= source_elf
,
257 header_version
= header_version
)
259 raise RuntimeError("Failed to create image header for hash segment")
261 files_to_cat_in_order
= [target_hash_hd
, target_hash
]
262 mbn_tools
.concat_files (target_nonsec
, files_to_cat_in_order
)
264 # Add the hash segment into the ELF
265 mbn_tools
.pboot_add_hash([],
273 ##############################################################################
275 ##############################################################################
276 def roundup(x
, precision
):
277 return x
if x
% precision
== 0 else (x
+ precision
- (x
% precision
))
279 ##############################################################################
281 ##############################################################################
289 is_elf_xbl_sec_64_bit
,
294 [elf_header1
, phdr_table1
] = \
295 mbn_tools
.preprocess_elf_file(elf_in_file_name1
)
297 # Check to make sure second file path exists before using
298 if elf_in_file_name2
!= "":
299 [elf_header2
, phdr_table2
] = \
300 mbn_tools
.preprocess_elf_file(elf_in_file_name2
)
302 # Check to make sure xbl_sec file path exists before using
303 if elf_in_file_xbl_sec
!= "":
304 [elf_headerxblsec
, phdr_tablexblsec
] = \
305 mbn_tools
.preprocess_elf_file(elf_in_file_xbl_sec
)
308 elf_in_fp1
= mbn_tools
.OPEN(elf_in_file_name1
, "rb")
309 if elf_in_file_name2
!= "":
310 elf_in_fp2
= mbn_tools
.OPEN(elf_in_file_name2
, "rb")
311 if elf_in_file_xbl_sec
!= "":
312 elf_in_fpxblsec
= mbn_tools
.OPEN(elf_in_file_xbl_sec
, "rb")
314 if elf_out_file_name
is not None:
315 elf_out_fp
= mbn_tools
.OPEN(elf_out_file_name
, "wb+")
318 # Calculate the new program header size. This is dependant on the output
319 # ELF type and number of program headers going into output.
320 if is_out_elf_64_bit
:
321 phdr_total_size
= elf_header1
.e_phnum
* ELF64_PHDR_SIZE
322 phdr_total_count
= elf_header1
.e_phnum
324 phdr_total_size
= elf_header1
.e_phnum
* ELF32_PHDR_SIZE
325 phdr_total_count
= elf_header1
.e_phnum
328 # This logic only applies if two files are to be merged
329 if elf_in_file_name2
!= "":
330 if is_out_elf_64_bit
:
331 phdr_total_size
+= elf_header2
.e_phnum
* ELF64_PHDR_SIZE
332 phdr_total_count
+= elf_header2
.e_phnum
334 phdr_total_size
+= elf_header2
.e_phnum
* ELF32_PHDR_SIZE
335 phdr_total_count
+= elf_header2
.e_phnum
337 # Account for xbl_sec header if included
338 if elf_in_file_xbl_sec
!= "":
339 phdr_total_count
+= 1
340 if is_out_elf_64_bit
:
341 phdr_total_size
+= ELF64_PHDR_SIZE
343 phdr_total_size
+= ELF32_PHDR_SIZE
345 # Create a new ELF header for the output file
346 if is_out_elf_64_bit
:
347 out_elf_header
= mbn_tools
.Elf64_Ehdr(b
'\0' * ELF64_HDR_SIZE
)
348 out_elf_header
.e_phoff
= ELF64_HDR_SIZE
349 out_elf_header
.e_ehsize
= ELF64_HDR_SIZE
350 out_elf_header
.e_phentsize
= ELF64_PHDR_SIZE
351 out_elf_header
.e_machine
= 183
352 out_elf_header
.e_ident
= str('\x7f' + 'E' + 'L' + 'F' + \
360 out_elf_header
.e_entry
= elf_header1
.e_entry
362 out_elf_header
= mbn_tools
.Elf32_Ehdr(b
'\0' * ELF32_HDR_SIZE
)
363 out_elf_header
.e_phoff
= ELF32_HDR_SIZE
364 out_elf_header
.e_ehsize
= ELF32_HDR_SIZE
365 out_elf_header
.e_phentsize
= ELF32_PHDR_SIZE
366 out_elf_header
.e_machine
= 40
367 out_elf_header
.e_entry
= elf_header1
.e_entry
368 out_elf_header
.e_ident
= str('\x7f' + 'E' + 'L' + 'F' + \
376 # Address needs to be verified that it is not greater than 32 bits
377 # as it is possible to go from a 64 bit elf to 32.
378 if (elf_header1
.e_entry
> 0xFFFFFFFF):
379 print("ERROR: File 1's entry point is too large to convert.")
381 out_elf_header
.e_entry
= elf_header1
.e_entry
383 # Common header entries
384 out_elf_header
.e_type
= 2
385 out_elf_header
.e_version
= 1
386 out_elf_header
.e_shoff
= 0
387 out_elf_header
.e_flags
= 0
388 out_elf_header
.e_shentsize
= 0
389 out_elf_header
.e_shnum
= 0
390 out_elf_header
.e_shstrndx
= 0
393 # If ZI OOB is enabled then it is possible that a segment could be discarded
394 # Scan for that instance and handle before setting e_phnum and writing header
395 # Ensure ELF output is 32 bit
396 if zi_oob_enabled
== True and is_out_elf_64_bit
== False:
397 for i
in range(len(phdr_table1
)):
398 if (phdr_table1
[i
].p_vaddr
> 0xFFFFFFFF) or \
399 (phdr_table1
[i
].p_paddr
> 0xFFFFFFFF):
400 if phdr_table1
[i
].p_filesz
== 0:
401 phdr_total_count
= phdr_total_count
- 1
403 if elf_in_file_name2
!= "":
404 for i
in range(len(phdr_table2
)):
405 if (phdr_table2
[i
].p_vaddr
> 0xFFFFFFFF) or \
406 (phdr_table2
[i
].p_paddr
> 0xFFFFFFFF):
407 if phdr_table2
[i
].p_filesz
== 0:
408 phdr_total_count
= phdr_total_count
- 1
409 # Do not include xbl_sec in above calculation
410 # xbl_sec is to be treated as a single blob
413 # Now it is ok to populate the ELF header and write it out
414 out_elf_header
.e_phnum
= phdr_total_count
417 if is_out_elf_64_bit
== False:
418 elf_out_fp
.write(mbn_tools
.Elf32_Ehdr
.getPackedData(out_elf_header
))
420 elf_out_fp
.write(mbn_tools
.Elf64_Ehdr
.getPackedData(out_elf_header
))
422 phdr_offset
= out_elf_header
.e_phoff
# offset of where to put next phdr
424 # offset the start of the segments just after the program headers
425 segment_offset
= roundup(out_elf_header
.e_phoff
+ phdr_total_size
, PAGE_SIZE
)
428 # Output first elf data
429 for i
in range(elf_header1
.e_phnum
):
430 curr_phdr
= phdr_table1
[i
]
432 # Copy program header piece by piece to ensure possible conversion success
433 if is_out_elf_64_bit
== True:
434 # Converting from 32 to 64 elf requires no data size validation
435 new_phdr
= mbn_tools
.Elf64_Phdr(b
'\0' * ELF64_PHDR_SIZE
)
436 new_phdr
.p_type
= curr_phdr
.p_type
437 new_phdr
.p_offset
= segment_offset
438 new_phdr
.p_vaddr
= curr_phdr
.p_vaddr
439 new_phdr
.p_paddr
= curr_phdr
.p_paddr
440 new_phdr
.p_filesz
= curr_phdr
.p_filesz
441 new_phdr
.p_memsz
= curr_phdr
.p_memsz
442 new_phdr
.p_flags
= curr_phdr
.p_flags
443 new_phdr
.p_align
= curr_phdr
.p_align
445 # Converting from 64 to 32 elf requires data size validation
446 # Note that there is an option to discard a segment if it is only ZI
447 # and its address is greater than 32 bits
448 new_phdr
= mbn_tools
.Elf32_Phdr(b
'\0' * ELF32_PHDR_SIZE
)
449 new_phdr
.p_type
= curr_phdr
.p_type
450 new_phdr
.p_offset
= segment_offset
452 if curr_phdr
.p_vaddr
> 0xFFFFFFFF:
453 if (zi_oob_enabled
== True) and (curr_phdr
.p_filesz
== 0):
456 print("ERROR: File 1 VAddr is too large for conversion.")
458 new_phdr
.p_vaddr
= curr_phdr
.p_vaddr
460 if curr_phdr
.p_paddr
> 0xFFFFFFFF:
461 if (zi_oob_enabled
== True) and (curr_phdr
.p_filesz
== 0):
464 print("ERROR: File 1 PAddr is too large for conversion.")
466 new_phdr
.p_paddr
= curr_phdr
.p_paddr
468 if curr_phdr
.p_filesz
> 0xFFFFFFFF:
469 print("ERROR: File 1 Filesz is too large for conversion.")
471 new_phdr
.p_filesz
= curr_phdr
.p_filesz
473 if curr_phdr
.p_memsz
> 0xFFFFFFFF:
474 print("ERROR: File 1 Memsz is too large for conversion.")
476 new_phdr
.p_memsz
= curr_phdr
.p_memsz
478 if curr_phdr
.p_flags
> 0xFFFFFFFF:
479 print("ERROR: File 1 Flags is too large for conversion.")
481 new_phdr
.p_flags
= curr_phdr
.p_flags
483 if curr_phdr
.p_align
> 0xFFFFFFFF:
484 print("ERROR: File 1 Align is too large for conversion.")
486 new_phdr
.p_align
= curr_phdr
.p_align
490 #print("phdr_offset=", phdr_offset)
492 # update output file location to next phdr location
493 elf_out_fp
.seek(phdr_offset
)
494 # increment phdr_offset to next location
495 phdr_offset
+= out_elf_header
.e_phentsize
497 inp_data_offset
= curr_phdr
.p_offset
# used to read data from input file
499 # print("inp_data_offset=")
500 # print(inp_data_offset)
502 # print("curr_phdr.p_offset=")
503 # print(curr_phdr.p_offset)
505 # print("curr_phdr.p_filesz=")
506 # print(curr_phdr.p_filesz)
508 # output current phdr
509 if is_out_elf_64_bit
== False:
510 elf_out_fp
.write(mbn_tools
.Elf32_Phdr
.getPackedData(new_phdr
))
512 elf_out_fp
.write(mbn_tools
.Elf64_Phdr
.getPackedData(new_phdr
))
514 # Copy the ELF segment
515 bytes_written
= mbn_tools
.file_copy_offset(elf_in_fp1
,
521 # update data segment offset to be aligned after previous segment
522 segment_offset
+= roundup(new_phdr
.p_filesz
, SEGMENT_ALIGN
);
525 # Output second elf data if applicable
526 if elf_in_file_name2
!= "":
527 for i
in range(elf_header2
.e_phnum
):
528 curr_phdr
= phdr_table2
[i
]
530 # Copy program header piece by piece to ensure possible conversion success
531 if is_out_elf_64_bit
== True:
532 # Converting from 32 to 64 elf requires no data size validation
533 new_phdr
= mbn_tools
.Elf64_Phdr(b
'\0' * ELF64_PHDR_SIZE
)
534 new_phdr
.p_type
= curr_phdr
.p_type
535 new_phdr
.p_offset
= segment_offset
536 new_phdr
.p_vaddr
= curr_phdr
.p_vaddr
537 new_phdr
.p_paddr
= curr_phdr
.p_paddr
538 new_phdr
.p_filesz
= curr_phdr
.p_filesz
539 new_phdr
.p_memsz
= curr_phdr
.p_memsz
540 new_phdr
.p_flags
= curr_phdr
.p_flags
541 new_phdr
.p_align
= curr_phdr
.p_align
543 # Converting from 64 to 32 elf requires data size validation
544 # Note that there is an option to discard a segment if it is only ZI
545 # and its address is greater than 32 bits
546 new_phdr
= mbn_tools
.Elf32_Phdr(b
'\0' * ELF32_PHDR_SIZE
)
547 new_phdr
.p_type
= curr_phdr
.p_type
548 new_phdr
.p_offset
= segment_offset
550 if curr_phdr
.p_vaddr
> 0xFFFFFFFF:
551 if (zi_oob_enabled
== True) and (curr_phdr
.p_filesz
== 0):
554 print("ERROR: File 2 VAddr is too large for conversion.")
556 new_phdr
.p_vaddr
= curr_phdr
.p_vaddr
558 if curr_phdr
.p_paddr
> 0xFFFFFFFF:
559 if (zi_oob_enabled
== True) and (curr_phdr
.p_filesz
== 0):
562 print("ERROR: File 2 PAddr is too large for conversion.")
564 new_phdr
.p_paddr
= curr_phdr
.p_paddr
566 if curr_phdr
.p_filesz
> 0xFFFFFFFF:
567 print("ERROR: File 2 Filesz is too large for conversion.")
569 new_phdr
.p_filesz
= curr_phdr
.p_filesz
571 if curr_phdr
.p_memsz
> 0xFFFFFFFF:
572 print("ERROR: File 2 Memsz is too large for conversion.")
574 new_phdr
.p_memsz
= curr_phdr
.p_memsz
576 if curr_phdr
.p_flags
> 0xFFFFFFFF:
577 print("ERROR: File 2 Flags is too large for conversion.")
579 new_phdr
.p_flags
= curr_phdr
.p_flags
581 if curr_phdr
.p_align
> 0xFFFFFFFF:
582 print("ERROR: File 2 Align is too large for conversion.")
584 new_phdr
.p_align
= curr_phdr
.p_align
588 # print("phdr_offset=", phdr_offset)
590 # update output file location to next phdr location
591 elf_out_fp
.seek(phdr_offset
)
592 # increment phdr_offset to next location
593 phdr_offset
+= out_elf_header
.e_phentsize
595 inp_data_offset
= curr_phdr
.p_offset
# used to read data from input file
597 # print("inp_data_offset=")
598 # print(inp_data_offset)
600 # print("curr_phdr.p_offset=")
601 # print(curr_phdr.p_offset)
603 # print("curr_phdr.p_filesz=")
604 # print(curr_phdr.p_filesz)
606 # output current phdr
607 if is_out_elf_64_bit
== False:
608 elf_out_fp
.write(mbn_tools
.Elf32_Phdr
.getPackedData(new_phdr
))
610 elf_out_fp
.write(mbn_tools
.Elf64_Phdr
.getPackedData(new_phdr
))
612 # Copy the ELF segment
613 bytes_written
= mbn_tools
.file_copy_offset(elf_in_fp2
,
619 # update data segment offset to be aligned after previous segment
620 segment_offset
+= roundup(new_phdr
.p_filesz
, SEGMENT_ALIGN
);
623 # Embed xbl_sec image if provided
624 if elf_in_file_xbl_sec
!= "":
626 # Scan pheaders in xbl_sec for segment that contains entry point address
627 entry_seg_offset
= -1
628 entry_addr
= elf_headerxblsec
.e_entry
629 for i
in range(elf_headerxblsec
.e_phnum
):
630 phdr
= phdr_tablexblsec
[i
]
631 max_addr
= phdr
.p_vaddr
+ phdr
.p_memsz
632 if phdr
.p_vaddr
<= entry_addr
<= max_addr
:
633 entry_seg_offset
= phdr
.p_offset
635 if entry_seg_offset
== -1:
636 print("Error: Failed to find entry point in any segment!")
638 # magical equation for program header's phys and virt addr
639 phys_virt_addr
= entry_addr
- entry_seg_offset
641 if is_out_elf_64_bit
:
642 # Converting from 32 to 64 elf requires no data size validation
643 new_phdr
= mbn_tools
.Elf64_Phdr(b
'\0' * ELF64_PHDR_SIZE
)
644 new_phdr
.p_type
= 0x1
645 new_phdr
.p_offset
= segment_offset
646 new_phdr
.p_vaddr
= phys_virt_addr
647 new_phdr
.p_paddr
= phys_virt_addr
648 new_phdr
.p_filesz
= os
.path
.getsize(elf_in_file_xbl_sec
)
649 new_phdr
.p_memsz
= new_phdr
.p_filesz
650 if header_version
>= 5:
651 new_phdr
.p_flags
= (0x5 |
652 (mbn_tools
.MI_PBT_XBL_SEC_SEGMENT
<<
653 mbn_tools
.MI_PBT_FLAG_SEGMENT_TYPE_SHIFT
));
655 new_phdr
.p_flags
= 0x5
656 new_phdr
.p_align
= 0x1000
658 # Converting from 64 to 32 elf requires data size validation
659 # Don't discard the segment containing xbl_sec, simply error out
660 # if the address is greater than 32 bits
661 new_phdr
= mbn_tools
.Elf32_Phdr(b
'\0' * ELF32_PHDR_SIZE
)
662 new_phdr
.p_type
= 0x1 #
663 new_phdr
.p_offset
= segment_offset
664 if header_version
>= 5:
665 new_phdr
.p_flags
= (0x5 |
666 (mbn_tools
.MI_PBT_XBL_SEC_SEGMENT
<<
667 mbn_tools
.MI_PBT_FLAG_SEGMENT_TYPE_SHIFT
));
669 new_phdr
.p_flags
= 0x5
670 new_phdr
.p_align
= 0x1000
672 if phys_virt_addr
> 0xFFFFFFFF:
673 if zi_oob_enabled
== False or curr_phdr
.p_filesz
!= 0:
674 print("ERROR: File xbl_sec VAddr or PAddr is too big for conversion.")
676 new_phdr
.p_vaddr
= phys_virt_addr
677 new_phdr
.p_paddr
= phys_virt_addr
679 if os
.path
.getsize(elf_in_file_xbl_sec
) > 0xFFFFFFFF:
680 print("ERROR: File xbl_sec Filesz is too big for conversion.")
682 new_phdr
.p_filesz
= os
.path
.getsize(elf_in_file_xbl_sec
)
683 new_phdr
.p_memsz
= new_phdr
.p_filesz
686 # update output file location to next phdr location
687 elf_out_fp
.seek(phdr_offset
)
688 # increment phdr_offset to next location
689 phdr_offset
+= out_elf_header
.e_phentsize
690 # Copy entire xbl_sec file, so start from byte 0
693 # Output xbl_sec's phdr
695 if is_out_elf_64_bit
== False:
696 elf_out_fp
.write(mbn_tools
.Elf32_Phdr
.getPackedData(new_phdr
))
698 elf_out_fp
.write(mbn_tools
.Elf64_Phdr
.getPackedData(new_phdr
))
700 # Copy the ENTIRE xbl_sec image
701 bytes_written
= mbn_tools
.file_copy_offset(elf_in_fpxblsec
,
706 # update data segment offset to be aligned after previous segment
707 # Not necessary, unless appending more pheaders after this point
708 segment_offset
+= roundup(new_phdr
.p_filesz
, SEGMENT_ALIGN
);
710 elf_in_fpxblsec
.close()