Skip to content

Commit

Permalink
Update SplitFspBin.py to latest from edk2
Browse files Browse the repository at this point in the history
Updated to 9e639c1c
  • Loading branch information
nate-desimone committed Oct 29, 2019
1 parent 7222054 commit 0bc2b07
Showing 1 changed file with 74 additions and 39 deletions.
113 changes: 74 additions & 39 deletions Tools/SplitFspBin.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,7 @@
## @ FspTool.py
#
# Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials are licensed and made available under
# the terms and conditions of the BSD License that accompanies this distribution.
# The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php.
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
# Copyright (c) 2015 - 2019, Intel Corporation. All rights reserved.<BR>
# SPDX-License-Identifier: BSD-2-Clause-Patent
#
##

Expand All @@ -18,14 +12,15 @@
import struct
import argparse
from ctypes import *
from functools import reduce

"""
This utility supports some operations for Intel FSP 2.0 image.
This utility supports some operations for Intel FSP 1.x/2.x image.
It supports:
- Display FSP 2.0 information header
- Split FSP 2.0 image into individual FSP-T/M/S/O component
- Rebase FSP 2.0 components to a different base address
- Generate FSP mapping C header file
- Display FSP 1.x/2.x information header
- Split FSP 2.x image into individual FSP-T/M/S/O component
- Rebase FSP 1.x/2.x components to a different base address
- Generate FSP 1.x/2.x mapping C header file
"""

CopyRightHeaderFile = """/*
Expand Down Expand Up @@ -346,6 +341,31 @@ def Bytes2Val (bytes):
def Val2Bytes (value, blen):
return [(value>>(i*8) & 0xff) for i in range(blen)]

def IsIntegerType (val):
if sys.version_info[0] < 3:
if type(val) in (int, long):
return True
else:
if type(val) is int:
return True
return False

def IsStrType (val):
if sys.version_info[0] < 3:
if type(val) is str:
return True
else:
if type(val) is bytes:
return True
return False

def HandleNameStr (val):
if sys.version_info[0] < 3:
rep = "0x%X ('%s')" % (Bytes2Val (bytearray (val)), val)
else:
rep = "0x%X ('%s')" % (Bytes2Val (bytearray (val)), str (val, 'utf-8'))
return rep

def OutputStruct (obj, indent = 0, plen = 0):
if indent:
body = ''
Expand All @@ -367,15 +387,19 @@ def OutputStruct (obj, indent = 0, plen = 0):
body += OutputStruct (val, indent + 1)
plen -= sizeof(val)
else:
if type(val) is str:
rep = "0x%X ('%s')" % (Bytes2Val(bytearray(val)), val)
elif type(val) in (int, long):
if IsStrType (val):
rep = HandleNameStr (val)
elif IsIntegerType (val):
rep = '0x%X' % val
elif isinstance(val, c_uint24):
rep = '0x%X' % val.get_value()
elif 'c_ubyte_Array' in str(type(val)):
if sizeof(val) == 16:
rep = str(uuid.UUID(bytes = str(bytearray(val)))).upper()
if sys.version_info[0] < 3:
rep = str(bytearray(val))
else:
rep = bytes(val)
rep = str(uuid.UUID(bytes_le = rep)).upper()
else:
res = ['0x%02X'%i for i in bytearray(val)]
rep = '[%s]' % (','.join(res))
Expand Down Expand Up @@ -404,7 +428,7 @@ def ParseFfs(self):
ffssize = len(self.FfsData)
offset = sizeof(self.FfsHdr)
if self.FfsHdr.Name != '\xff' * 16:
while offset < ffssize:
while offset < (ffssize - sizeof (EFI_COMMON_SECTION_HEADER)):
sechdr = EFI_COMMON_SECTION_HEADER.from_buffer (self.FfsData, offset)
sec = Section (offset, self.FfsData[offset:offset + int(sechdr.Size)])
self.SecList.append(sec)
Expand All @@ -429,7 +453,7 @@ def ParseFv(self):
else:
offset = self.FvHdr.HeaderLength
offset = AlignPtr(offset)
while offset < fvsize:
while offset < (fvsize - sizeof (EFI_FFS_FILE_HEADER)):
ffshdr = EFI_FFS_FILE_HEADER.from_buffer (self.FvData, offset)
if (ffshdr.Name == '\xff' * 16) and (int(ffshdr.Size) == 0xFFFFFF):
offset = fvsize
Expand Down Expand Up @@ -491,9 +515,9 @@ def ParseFd(self):
offset = 0
fdsize = len(self.FdData)
self.FvList = []
while offset < fdsize:
while offset < (fdsize - sizeof (EFI_FIRMWARE_VOLUME_HEADER)):
fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FdData, offset)
if '_FVH' != fvh.Signature:
if b'_FVH' != fvh.Signature:
raise Exception("ERROR: Invalid FV header !")
fv = FirmwareVolume (offset, self.FdData[offset:offset + fvh.FvLength])
fv.ParseFv ()
Expand All @@ -506,8 +530,6 @@ def CheckFsp (self):

fih = None
for fsp in self.FspList:
if fsp.Fih.HeaderRevision < 3:
raise Exception("ERROR: FSP 1.x is not supported by this tool !")
if not fih:
fih = fsp.Fih
else:
Expand All @@ -532,15 +554,15 @@ def ParseFsp(self):
fspoffset = fv.Offset
offset = fspoffset + fihoffset
fih = FSP_INFORMATION_HEADER.from_buffer (self.FdData, offset)
if 'FSPH' != fih.Signature:
if b'FSPH' != fih.Signature:
continue

offset += fih.HeaderLength
offset = AlignPtr(offset, 4)
plist = []
while True:
fch = FSP_COMMON_HEADER.from_buffer (self.FdData, offset)
if 'FSPP' != fch.Signature:
if b'FSPP' != fch.Signature:
offset += fch.HeaderLength
offset = AlignPtr(offset, 4)
else:
Expand All @@ -565,9 +587,9 @@ class PeTeImage:
def __init__(self, offset, data):
self.Offset = offset
tehdr = EFI_TE_IMAGE_HEADER.from_buffer (data, 0)
if tehdr.Signature == 'VZ': # TE image
if tehdr.Signature == b'VZ': # TE image
self.TeHdr = tehdr
elif tehdr.Signature == 'MZ': # PE image
elif tehdr.Signature == b'MZ': # PE image
self.TeHdr = None
self.DosHdr = EFI_IMAGE_DOS_HEADER.from_buffer (data, 0)
self.PeHdr = EFI_IMAGE_NT_HEADERS32.from_buffer (data, self.DosHdr.e_lfanew)
Expand Down Expand Up @@ -612,7 +634,7 @@ def ParseReloc(self):
offset += sizeof(blkhdr)
# Read relocation type,offset pairs
rlen = blkhdr.BlockSize - sizeof(PE_RELOC_BLOCK_HEADER)
rnum = rlen/sizeof(c_uint16)
rnum = int (rlen/sizeof(c_uint16))
rdata = (c_uint16 * rnum).from_buffer(self.Data, offset)
for each in rdata:
roff = each & 0xfff
Expand Down Expand Up @@ -674,8 +696,11 @@ def ShowFspInfo (fspfile):
if not name:
name = '\xff' * 16
else:
name = str(bytearray(name))
guid = uuid.UUID(bytes = name)
if sys.version_info[0] < 3:
name = str(bytearray(name))
else:
name = bytes(name)
guid = uuid.UUID(bytes_le = name)
print ("FV%d:" % idx)
print (" GUID : %s" % str(guid).upper())
print (" Offset : 0x%08X" % fv.Offset)
Expand Down Expand Up @@ -703,7 +728,10 @@ def GenFspHdr (fspfile, outdir, hfile):
for fsp in fd.FspList:
fih = fsp.Fih
if firstfv:
hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (Bytes2Val(bytearray(fih.ImageId)), fih.ImageId))
if sys.version_info[0] < 3:
hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (Bytes2Val(bytearray(fih.ImageId)), fih.ImageId))
else:
hfsp.write("#define FSP_IMAGE_ID 0x%016X /* '%s' */\n" % (Bytes2Val(bytearray(fih.ImageId)), str (fih.ImageId, 'utf-8')))
hfsp.write("#define FSP_IMAGE_REV 0x%08X \n\n" % fih.ImageRevision)
firstfv = False
fv = fd.FvList[fsp.FvIdxList[0]]
Expand All @@ -719,6 +747,8 @@ def SplitFspBin (fspfile, outdir, nametemplate):
fd.ParseFsp ()

for fsp in fd.FspList:
if fsp.Fih.HeaderRevision < 3:
raise Exception("ERROR: FSP 1.x is not supported by the split command !")
ftype = fsp.Type
if not nametemplate:
nametemplate = fspfile
Expand All @@ -739,7 +769,7 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
numcomp = len(FspComponent)
baselist = FspBase
if numcomp != len(baselist):
print "ERROR: Required number of base does not match number of FSP component !"
print ("ERROR: Required number of base does not match number of FSP component !")
return

newfspbin = fd.FdData[:]
Expand All @@ -748,13 +778,18 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):

found = False
for fsp in fd.FspList:
# Is this FSP 1.x single binary?
if fsp.Fih.HeaderRevision < 3:
found = True
ftype = 'X'
break
ftype = fsp.Type.lower()
if ftype == fspcomp:
found = True
break

if not found:
print "ERROR: Could not find FSP_%c component to rebase !" % fspcomp.upper()
print ("ERROR: Could not find FSP_%c component to rebase !" % fspcomp.upper())
return

fspbase = baselist[idx]
Expand All @@ -764,7 +799,7 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
newbase = int(fspbase)
oldbase = fsp.Fih.ImageBase
delta = newbase - oldbase
print "Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase)
print ("Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase))

imglist = []
for fvidx in fsp.FvIdxList:
Expand All @@ -783,12 +818,12 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
pcount += img.Rebase(delta, newfspbin)
fcount += 1

print " Patched %d entries in %d TE/PE32 images." % (pcount, fcount)
print (" Patched %d entries in %d TE/PE32 images." % (pcount, fcount))

(count, applied) = fsp.Patch(delta, newfspbin)
print " Patched %d entries using FSP patch table." % applied
print (" Patched %d entries using FSP patch table." % applied)
if count != applied:
print " %d invalid entries are ignored !" % (count - applied)
print (" %d invalid entries are ignored !" % (count - applied))

if OutputFile == '':
filename = os.path.basename(FspBinary)
Expand All @@ -803,7 +838,7 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):

def main ():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(title='commands')
subparsers = parser.add_subparsers(title='commands', dest="which")

parser_rebase = subparsers.add_parser('rebase', help='rebase a FSP into a new base address')
parser_rebase.set_defaults(which='rebase')
Expand Down Expand Up @@ -845,7 +880,7 @@ def main ():
elif args.which == 'info':
ShowFspInfo (args.FspBinary)
else:
pass
parser.print_help()

return 0

Expand Down

0 comments on commit 0bc2b07

Please sign in to comment.