public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Desimone, Nathaniel L" <nathaniel.l.desimone@intel.com>
To: Patrick Georgi <pgeorgi@google.com>,
	"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH 3/3] IntelFsp2Pkg: Tell git to format SplitFspBin.py with native newlines
Date: Tue, 18 Sep 2018 15:10:31 +0000	[thread overview]
Message-ID: <5608C728-C8C9-4D20-8C4D-FEC4FA974BA6@intel.com> (raw)
In-Reply-To: <20180918133203.192779-3-pgeorgi@google.com>

Hi Patrick,

The EDK2 coding standard specifies that all files should be in CR-LF format. Please see the following: https://edk2-docs.gitbooks.io/edk-ii-c-coding-standards-specification/content/5_source_files/#51-general-rules

Is the .gitattributes file alone sufficient?

Thanks,
Nate

On 9/18/18, 6:32 AM, "edk2-devel on behalf of Patrick Georgi" <edk2-devel-bounces@lists.01.org on behalf of pgeorgi@google.com> wrote:

    Signed-off-by: Patrick Georgi <pgeorgi@google.com>
    Contributed-under: TianoCore Contribution Agreement 1.1
    ---
     IntelFsp2Pkg/Tools/.gitattributes |    1 +
     IntelFsp2Pkg/Tools/SplitFspBin.py | 1708 ++++++++++++++---------------
     2 files changed, 855 insertions(+), 854 deletions(-)
     create mode 100644 IntelFsp2Pkg/Tools/.gitattributes
    
    diff --git a/IntelFsp2Pkg/Tools/.gitattributes b/IntelFsp2Pkg/Tools/.gitattributes
    new file mode 100644
    index 0000000000..0f876007cd
    --- /dev/null
    +++ b/IntelFsp2Pkg/Tools/.gitattributes
    @@ -0,0 +1 @@
    +SplitFspBin.py text
    diff --git a/IntelFsp2Pkg/Tools/SplitFspBin.py b/IntelFsp2Pkg/Tools/SplitFspBin.py
    index ac864492e8..5f1fab071f 100755
    --- a/IntelFsp2Pkg/Tools/SplitFspBin.py
    +++ b/IntelFsp2Pkg/Tools/SplitFspBin.py
    @@ -1,854 +1,854 @@
    -#!/usr/bin/env python
    -## @ 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.
    -#
    -##
    -
    -import os
    -import sys
    -import uuid
    -import copy
    -import struct
    -import argparse
    -from   ctypes import *
    -
    -"""
    -This utility supports some operations for Intel FSP 2.0 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
    -"""
    -
    -CopyRightHeaderFile = """/*
    - *
    - * Automatically generated file; DO NOT EDIT.
    - * FSP mapping file
    - *
    - */
    -"""
    -
    -class c_uint24(Structure):
    -    """Little-Endian 24-bit Unsigned Integer"""
    -    _pack_   = 1
    -    _fields_ = [('Data', (c_uint8 * 3))]
    -
    -    def __init__(self, val=0):
    -        self.set_value(val)
    -
    -    def __str__(self, indent=0):
    -        return '0x%.6x' % self.value
    -
    -    def __int__(self):
    -        return self.get_value()
    -
    -    def set_value(self, val):
    -        self.Data[0:3] = Val2Bytes(val, 3)
    -
    -    def get_value(self):
    -        return Bytes2Val(self.Data[0:3])
    -
    -    value = property(get_value, set_value)
    -
    -class EFI_FIRMWARE_VOLUME_HEADER(Structure):
    -    _fields_ = [
    -        ('ZeroVector',           ARRAY(c_uint8, 16)),
    -        ('FileSystemGuid',       ARRAY(c_uint8, 16)),
    -        ('FvLength',             c_uint64),
    -        ('Signature',            ARRAY(c_char, 4)),
    -        ('Attributes',           c_uint32),
    -        ('HeaderLength',         c_uint16),
    -        ('Checksum',             c_uint16),
    -        ('ExtHeaderOffset',      c_uint16),
    -        ('Reserved',             c_uint8),
    -        ('Revision',             c_uint8)
    -        ]
    -
    -class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
    -    _fields_ = [
    -        ('FvName',               ARRAY(c_uint8, 16)),
    -        ('ExtHeaderSize',        c_uint32)
    -        ]
    -
    -class EFI_FFS_INTEGRITY_CHECK(Structure):
    -    _fields_ = [
    -        ('Header',               c_uint8),
    -        ('File',                 c_uint8)
    -        ]
    -
    -class EFI_FFS_FILE_HEADER(Structure):
    -    _fields_ = [
    -        ('Name',                 ARRAY(c_uint8, 16)),
    -        ('IntegrityCheck',       EFI_FFS_INTEGRITY_CHECK),
    -        ('Type',                 c_uint8),
    -        ('Attributes',           c_uint8),
    -        ('Size',                 c_uint24),
    -        ('State',                c_uint8)
    -        ]
    -
    -class EFI_COMMON_SECTION_HEADER(Structure):
    -    _fields_ = [
    -        ('Size',                 c_uint24),
    -        ('Type',                 c_uint8)
    -        ]
    -
    -class FSP_COMMON_HEADER(Structure):
    -     _fields_ = [
    -        ('Signature',            ARRAY(c_char, 4)),
    -        ('HeaderLength',         c_uint32)
    -        ]
    -
    -class FSP_INFORMATION_HEADER(Structure):
    -     _fields_ = [
    -        ('Signature',            ARRAY(c_char, 4)),
    -        ('HeaderLength',         c_uint32),
    -        ('Reserved1',            c_uint16),
    -        ('SpecVersion',          c_uint8),
    -        ('HeaderRevision',       c_uint8),
    -        ('ImageRevision',        c_uint32),
    -        ('ImageId',              ARRAY(c_char, 8)),
    -        ('ImageSize',            c_uint32),
    -        ('ImageBase',            c_uint32),
    -        ('ImageAttribute',       c_uint16),
    -        ('ComponentAttribute',   c_uint16),
    -        ('CfgRegionOffset',      c_uint32),
    -        ('CfgRegionSize',        c_uint32),
    -        ('Reserved2',            c_uint32),
    -        ('TempRamInitEntryOffset',     c_uint32),
    -        ('Reserved3',                  c_uint32),
    -        ('NotifyPhaseEntryOffset',     c_uint32),
    -        ('FspMemoryInitEntryOffset',   c_uint32),
    -        ('TempRamExitEntryOffset',     c_uint32),
    -        ('FspSiliconInitEntryOffset',  c_uint32)
    -    ]
    -
    -class FSP_PATCH_TABLE(Structure):
    -    _fields_ = [
    -        ('Signature',            ARRAY(c_char, 4)),
    -        ('HeaderLength',         c_uint16),
    -        ('HeaderRevision',       c_uint8),
    -        ('Reserved',             c_uint8),
    -        ('PatchEntryNum',        c_uint32)
    -        ]
    -
    -class EFI_IMAGE_DATA_DIRECTORY(Structure):
    -    _fields_ = [
    -        ('VirtualAddress',       c_uint32),
    -        ('Size',                 c_uint32)
    -        ]
    -
    -class EFI_TE_IMAGE_HEADER(Structure):
    -    _fields_ = [
    -        ('Signature',            ARRAY(c_char, 2)),
    -        ('Machine',              c_uint16),
    -        ('NumberOfSections',     c_uint8),
    -        ('Subsystem',            c_uint8),
    -        ('StrippedSize',         c_uint16),
    -        ('AddressOfEntryPoint',  c_uint32),
    -        ('BaseOfCode',           c_uint32),
    -        ('ImageBase',            c_uint64),
    -        ('DataDirectoryBaseReloc',  EFI_IMAGE_DATA_DIRECTORY),
    -        ('DataDirectoryDebug',      EFI_IMAGE_DATA_DIRECTORY)
    -        ]
    -
    -class EFI_IMAGE_DOS_HEADER(Structure):
    -    _fields_ = [
    -        ('e_magic',              c_uint16),
    -        ('e_cblp',               c_uint16),
    -        ('e_cp',                 c_uint16),
    -        ('e_crlc',               c_uint16),
    -        ('e_cparhdr',            c_uint16),
    -        ('e_minalloc',           c_uint16),
    -        ('e_maxalloc',           c_uint16),
    -        ('e_ss',                 c_uint16),
    -        ('e_sp',                 c_uint16),
    -        ('e_csum',               c_uint16),
    -        ('e_ip',                 c_uint16),
    -        ('e_cs',                 c_uint16),
    -        ('e_lfarlc',             c_uint16),
    -        ('e_ovno',               c_uint16),
    -        ('e_res',                ARRAY(c_uint16, 4)),
    -        ('e_oemid',              c_uint16),
    -        ('e_oeminfo',            c_uint16),
    -        ('e_res2',               ARRAY(c_uint16, 10)),
    -        ('e_lfanew',             c_uint16)
    -        ]
    -
    -class EFI_IMAGE_FILE_HEADER(Structure):
    -    _fields_ = [
    -        ('Machine',               c_uint16),
    -        ('NumberOfSections',      c_uint16),
    -        ('TimeDateStamp',         c_uint32),
    -        ('PointerToSymbolTable',  c_uint32),
    -        ('NumberOfSymbols',       c_uint32),
    -        ('SizeOfOptionalHeader',  c_uint16),
    -        ('Characteristics',       c_uint16)
    -        ]
    -
    -class PE_RELOC_BLOCK_HEADER(Structure):
    -    _fields_ = [
    -        ('PageRVA',              c_uint32),
    -        ('BlockSize',            c_uint32)
    -        ]
    -
    -class EFI_IMAGE_OPTIONAL_HEADER32(Structure):
    -    _fields_ = [
    -        ('Magic',                         c_uint16),
    -        ('MajorLinkerVersion',            c_uint8),
    -        ('MinorLinkerVersion',            c_uint8),
    -        ('SizeOfCode',                    c_uint32),
    -        ('SizeOfInitializedData',         c_uint32),
    -        ('SizeOfUninitializedData',       c_uint32),
    -        ('AddressOfEntryPoint',           c_uint32),
    -        ('BaseOfCode',                    c_uint32),
    -        ('BaseOfData',                    c_uint32),
    -        ('ImageBase',                     c_uint32),
    -        ('SectionAlignment',              c_uint32),
    -        ('FileAlignment',                 c_uint32),
    -        ('MajorOperatingSystemVersion',   c_uint16),
    -        ('MinorOperatingSystemVersion',   c_uint16),
    -        ('MajorImageVersion',             c_uint16),
    -        ('MinorImageVersion',             c_uint16),
    -        ('MajorSubsystemVersion',         c_uint16),
    -        ('MinorSubsystemVersion',         c_uint16),
    -        ('Win32VersionValue',             c_uint32),
    -        ('SizeOfImage',                   c_uint32),
    -        ('SizeOfHeaders',                 c_uint32),
    -        ('CheckSum'     ,                 c_uint32),
    -        ('Subsystem',                     c_uint16),
    -        ('DllCharacteristics',            c_uint16),
    -        ('SizeOfStackReserve',            c_uint32),
    -        ('SizeOfStackCommit' ,            c_uint32),
    -        ('SizeOfHeapReserve',             c_uint32),
    -        ('SizeOfHeapCommit' ,             c_uint32),
    -        ('LoaderFlags'     ,              c_uint32),
    -        ('NumberOfRvaAndSizes',           c_uint32),
    -        ('DataDirectory',                 ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
    -        ]
    -
    -class EFI_IMAGE_OPTIONAL_HEADER32_PLUS(Structure):
    -    _fields_ = [
    -        ('Magic',                         c_uint16),
    -        ('MajorLinkerVersion',            c_uint8),
    -        ('MinorLinkerVersion',            c_uint8),
    -        ('SizeOfCode',                    c_uint32),
    -        ('SizeOfInitializedData',         c_uint32),
    -        ('SizeOfUninitializedData',       c_uint32),
    -        ('AddressOfEntryPoint',           c_uint32),
    -        ('BaseOfCode',                    c_uint32),
    -        ('ImageBase',                     c_uint64),
    -        ('SectionAlignment',              c_uint32),
    -        ('FileAlignment',                 c_uint32),
    -        ('MajorOperatingSystemVersion',   c_uint16),
    -        ('MinorOperatingSystemVersion',   c_uint16),
    -        ('MajorImageVersion',             c_uint16),
    -        ('MinorImageVersion',             c_uint16),
    -        ('MajorSubsystemVersion',         c_uint16),
    -        ('MinorSubsystemVersion',         c_uint16),
    -        ('Win32VersionValue',             c_uint32),
    -        ('SizeOfImage',                   c_uint32),
    -        ('SizeOfHeaders',                 c_uint32),
    -        ('CheckSum'     ,                 c_uint32),
    -        ('Subsystem',                     c_uint16),
    -        ('DllCharacteristics',            c_uint16),
    -        ('SizeOfStackReserve',            c_uint64),
    -        ('SizeOfStackCommit' ,            c_uint64),
    -        ('SizeOfHeapReserve',             c_uint64),
    -        ('SizeOfHeapCommit' ,             c_uint64),
    -        ('LoaderFlags'     ,              c_uint32),
    -        ('NumberOfRvaAndSizes',           c_uint32),
    -        ('DataDirectory',                 ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
    -        ]
    -
    -class EFI_IMAGE_OPTIONAL_HEADER(Union):
    -    _fields_ = [
    -        ('PeOptHdr',             EFI_IMAGE_OPTIONAL_HEADER32),
    -        ('PePlusOptHdr',         EFI_IMAGE_OPTIONAL_HEADER32_PLUS)
    -        ]
    -
    -class EFI_IMAGE_NT_HEADERS32(Structure):
    -    _fields_ = [
    -        ('Signature',            c_uint32),
    -        ('FileHeader',           EFI_IMAGE_FILE_HEADER),
    -        ('OptionalHeader',       EFI_IMAGE_OPTIONAL_HEADER)
    -        ]
    -
    -
    -class EFI_IMAGE_DIRECTORY_ENTRY:
    -    EXPORT                     = 0
    -    IMPORT                     = 1
    -    RESOURCE                   = 2
    -    EXCEPTION                  = 3
    -    SECURITY                   = 4
    -    BASERELOC                  = 5
    -    DEBUG                      = 6
    -    COPYRIGHT                  = 7
    -    GLOBALPTR                  = 8
    -    TLS                        = 9
    -    LOAD_CONFIG                = 10
    -
    -class EFI_FV_FILETYPE:
    -    ALL                        = 0x00
    -    RAW                        = 0x01
    -    FREEFORM                   = 0x02
    -    SECURITY_CORE              = 0x03
    -    PEI_CORE                   = 0x04
    -    DXE_CORE                   = 0x05
    -    PEIM                       = 0x06
    -    DRIVER                     = 0x07
    -    COMBINED_PEIM_DRIVER       = 0x08
    -    APPLICATION                = 0x09
    -    SMM                        = 0x0a
    -    FIRMWARE_VOLUME_IMAGE      = 0x0b
    -    COMBINED_SMM_DXE           = 0x0c
    -    SMM_CORE                   = 0x0d
    -    OEM_MIN                    = 0xc0
    -    OEM_MAX                    = 0xdf
    -    DEBUG_MIN                  = 0xe0
    -    DEBUG_MAX                  = 0xef
    -    FFS_MIN                    = 0xf0
    -    FFS_MAX                    = 0xff
    -    FFS_PAD                    = 0xf0
    -
    -class EFI_SECTION_TYPE:
    -    """Enumeration of all valid firmware file section types."""
    -    ALL                        = 0x00
    -    COMPRESSION                = 0x01
    -    GUID_DEFINED               = 0x02
    -    DISPOSABLE                 = 0x03
    -    PE32                       = 0x10
    -    PIC                        = 0x11
    -    TE                         = 0x12
    -    DXE_DEPEX                  = 0x13
    -    VERSION                    = 0x14
    -    USER_INTERFACE             = 0x15
    -    COMPATIBILITY16            = 0x16
    -    FIRMWARE_VOLUME_IMAGE      = 0x17
    -    FREEFORM_SUBTYPE_GUID      = 0x18
    -    RAW                        = 0x19
    -    PEI_DEPEX                  = 0x1b
    -    SMM_DEPEX                  = 0x1c
    -
    -def AlignPtr (offset, alignment = 8):
    -    return (offset + alignment - 1) & ~(alignment - 1)
    -
    -def Bytes2Val (bytes):
    -    return reduce(lambda x,y: (x<<8)|y,  bytes[::-1] )
    -
    -def Val2Bytes (value, blen):
    -    return [(value>>(i*8) & 0xff) for i in range(blen)]
    -
    -def OutputStruct (obj, indent = 0, plen = 0):
    -    if indent:
    -        body = ''
    -    else:
    -        body = ('  ' * indent + '<%s>:\n') % obj.__class__.__name__
    -
    -    if plen == 0:
    -        plen = sizeof(obj)
    -
    -    max_key_len = 26
    -    pstr = ('  ' * (indent + 1) + '{0:<%d} = {1}\n') % max_key_len
    -
    -    for field in obj._fields_:
    -        key = field[0]
    -        val = getattr(obj, key)
    -        rep = ''
    -        if not isinstance(val, c_uint24) and isinstance(val, Structure):
    -            body += pstr.format(key, val.__class__.__name__)
    -            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):
    -                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()
    -                else:
    -                    res = ['0x%02X'%i for i in bytearray(val)]
    -                    rep = '[%s]' % (','.join(res))
    -            else:
    -                rep = str(val)
    -            plen -= sizeof(field[1])
    -            body += pstr.format(key, rep)
    -        if plen <= 0:
    -            break
    -    return body
    -
    -class Section:
    -    def __init__(self, offset, secdata):
    -        self.SecHdr   = EFI_COMMON_SECTION_HEADER.from_buffer (secdata, 0)
    -        self.SecData  = secdata[0:int(self.SecHdr.Size)]
    -        self.Offset   = offset
    -
    -class FirmwareFile:
    -    def __init__(self, offset, filedata):
    -        self.FfsHdr   = EFI_FFS_FILE_HEADER.from_buffer (filedata, 0)
    -        self.FfsData  = filedata[0:int(self.FfsHdr.Size)]
    -        self.Offset   = offset
    -        self.SecList  = []
    -
    -    def ParseFfs(self):
    -        ffssize = len(self.FfsData)
    -        offset  = sizeof(self.FfsHdr)
    -        if self.FfsHdr.Name != '\xff' * 16:
    -            while offset < ffssize:
    -                sechdr = EFI_COMMON_SECTION_HEADER.from_buffer (self.FfsData, offset)
    -                sec = Section (offset, self.FfsData[offset:offset + int(sechdr.Size)])
    -                self.SecList.append(sec)
    -                offset += int(sechdr.Size)
    -                offset  = AlignPtr(offset, 4)
    -
    -class FirmwareVolume:
    -    def __init__(self, offset, fvdata):
    -        self.FvHdr    = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (fvdata, 0)
    -        self.FvData   = fvdata[0 : self.FvHdr.FvLength]
    -        self.Offset   = offset
    -        if self.FvHdr.ExtHeaderOffset > 0:
    -            self.FvExtHdr = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FvData, self.FvHdr.ExtHeaderOffset)
    -        else:
    -            self.FvExtHdr = None
    -        self.FfsList  = []
    -
    -    def ParseFv(self):
    -        fvsize = len(self.FvData)
    -        if self.FvExtHdr:
    -            offset = self.FvHdr.ExtHeaderOffset + self.FvExtHdr.ExtHeaderSize
    -        else:
    -            offset = self.FvHdr.HeaderLength
    -        offset = AlignPtr(offset)
    -        while offset < fvsize:
    -            ffshdr = EFI_FFS_FILE_HEADER.from_buffer (self.FvData, offset)
    -            if (ffshdr.Name == '\xff' * 16) and (int(ffshdr.Size) == 0xFFFFFF):
    -                offset = fvsize
    -            else:
    -                ffs = FirmwareFile (offset, self.FvData[offset:offset + int(ffshdr.Size)])
    -                ffs.ParseFfs()
    -                self.FfsList.append(ffs)
    -                offset += int(ffshdr.Size)
    -                offset = AlignPtr(offset)
    -
    -class FspImage:
    -    def __init__(self, offset, fih, fihoff, patch):
    -        self.Fih       = fih
    -        self.FihOffset = fihoff
    -        self.Offset    = offset
    -        self.FvIdxList = []
    -        self.Type      = "XTMSXXXXOXXXXXXX"[(fih.ComponentAttribute >> 12) & 0x0F]
    -        self.PatchList = patch
    -        self.PatchList.append(fihoff + 0x1C)
    -
    -    def AppendFv(self, FvIdx):
    -        self.FvIdxList.append(FvIdx)
    -
    -    def Patch(self, delta, fdbin):
    -        count   = 0
    -        applied = 0
    -        for idx, patch in enumerate(self.PatchList):
    -            ptype = (patch>>24) & 0x0F
    -            if ptype not in [0x00, 0x0F]:
    -                raise Exception('ERROR: Invalid patch type %d !' % ptype)
    -            if patch & 0x80000000:
    -                patch = self.Fih.ImageSize - (0x1000000 - (patch & 0xFFFFFF))
    -            else:
    -                patch = patch & 0xFFFFFF
    -            if (patch < self.Fih.ImageSize) and (patch + sizeof(c_uint32) <= self.Fih.ImageSize):
    -                offset = patch + self.Offset
    -                value  = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
    -                value += delta
    -                fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
    -                applied += 1
    -            count += 1
    -        # Don't count the FSP base address patch entry appended at the end
    -        if count != 0:
    -            count   -= 1
    -            applied -= 1
    -        return (count, applied)
    -
    -class FirmwareDevice:
    -    def __init__(self, offset, fdfile):
    -        self.FvList  = []
    -        self.FspList = []
    -        self.FdFile = fdfile
    -        self.Offset = 0
    -        hfsp = open (self.FdFile, 'rb')
    -        self.FdData = bytearray(hfsp.read())
    -        hfsp.close()
    -
    -    def ParseFd(self):
    -        offset = 0
    -        fdsize = len(self.FdData)
    -        self.FvList  = []
    -        while offset < fdsize:
    -            fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FdData, offset)
    -            if '_FVH' != fvh.Signature:
    -                raise Exception("ERROR: Invalid FV header !")
    -            fv = FirmwareVolume (offset, self.FdData[offset:offset + fvh.FvLength])
    -            fv.ParseFv ()
    -            self.FvList.append(fv)
    -            offset += fv.FvHdr.FvLength
    -
    -    def CheckFsp (self):
    -        if len(self.FspList) == 0:
    -            return
    -
    -        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:
    -                newfih = fsp.Fih
    -                if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision):
    -                    raise Exception("ERROR: Inconsistent FSP ImageId or ImageRevision detected !")
    -
    -    def ParseFsp(self):
    -        flen = 0
    -        for idx, fv in enumerate(self.FvList):
    -            # Check if this FV contains FSP header
    -            if flen == 0:
    -                if len(fv.FfsList) == 0:
    -                    continue
    -                ffs = fv.FfsList[0]
    -                if len(ffs.SecList) == 0:
    -                    continue
    -                sec = ffs.SecList[0]
    -                if sec.SecHdr.Type != EFI_SECTION_TYPE.RAW:
    -                    continue
    -                fihoffset = ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
    -                fspoffset = fv.Offset
    -                offset    = fspoffset + fihoffset
    -                fih = FSP_INFORMATION_HEADER.from_buffer (self.FdData, offset)
    -                if '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:
    -                        offset += fch.HeaderLength
    -                        offset = AlignPtr(offset, 4)
    -                    else:
    -                        fspp = FSP_PATCH_TABLE.from_buffer (self.FdData, offset)
    -                        offset += sizeof(fspp)
    -                        pdata  = (c_uint32 * fspp.PatchEntryNum).from_buffer(self.FdData, offset)
    -                        plist  = list(pdata)
    -                        break
    -
    -                fsp  = FspImage (fspoffset, fih, fihoffset, plist)
    -                fsp.AppendFv (idx)
    -                self.FspList.append(fsp)
    -                flen = fsp.Fih.ImageSize - fv.FvHdr.FvLength
    -            else:
    -                fsp.AppendFv (idx)
    -                flen -= fv.FvHdr.FvLength
    -                if flen < 0:
    -                    raise Exception("ERROR: Incorrect FV size in image !")
    -        self.CheckFsp ()
    -
    -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
    -            self.TeHdr   = tehdr
    -        elif tehdr.Signature == '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)
    -            if self.PeHdr.Signature != 0x4550:
    -                raise Exception("ERROR: Invalid PE32 header !")
    -            if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b: # PE32 image
    -                if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:
    -                    raise Exception("ERROR: Unsupported PE32 image !")
    -                if self.PeHdr.OptionalHeader.PeOptHdr.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
    -                    raise Exception("ERROR: No relocation information available !")
    -            elif self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x20b: # PE32+ image
    -                if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32_PLUS.DataDirectory.offset:
    -                    raise Exception("ERROR: Unsupported PE32+ image !")
    -                if self.PeHdr.OptionalHeader.PePlusOptHdr.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
    -                    raise Exception("ERROR: No relocation information available !")
    -            else:
    -                raise Exception("ERROR: Invalid PE32 optional header !")
    -        self.Offset    = offset
    -        self.Data      = data
    -        self.RelocList = []
    -
    -    def IsTeImage(self):
    -        return  self.TeHdr is not None
    -
    -    def ParseReloc(self):
    -        if self.IsTeImage():
    -            rsize   = self.TeHdr.DataDirectoryBaseReloc.Size
    -            roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
    -        else:
    -            if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b: # PE32 image
    -                rsize   = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
    -                roffset = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress
    -            if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x20b: # PE32+ image
    -                rsize   = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
    -                roffset = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress
    -
    -        alignment = 4
    -        offset = roffset
    -        while offset < roffset + rsize:
    -            offset = AlignPtr(offset, 4)
    -            blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.Data, offset)
    -            offset += sizeof(blkhdr)
    -            # Read relocation type,offset pairs
    -            rlen  = blkhdr.BlockSize - sizeof(PE_RELOC_BLOCK_HEADER)
    -            rnum  = rlen/sizeof(c_uint16)
    -            rdata = (c_uint16 * rnum).from_buffer(self.Data, offset)
    -            for each in rdata:
    -                roff  = each & 0xfff
    -                rtype = each >> 12
    -                if rtype == 0: # IMAGE_REL_BASED_ABSOLUTE:
    -                    continue
    -                if ((rtype != 3) and (rtype != 10)): # IMAGE_REL_BASED_HIGHLOW and IMAGE_REL_BASED_DIR64
    -                    raise Exception("ERROR: Unsupported relocation type %d!" % rtype)
    -                # Calculate the offset of the relocation
    -                aoff  = blkhdr.PageRVA + roff
    -                if self.IsTeImage():
    -                    aoff += sizeof(self.TeHdr) - self.TeHdr.StrippedSize
    -                self.RelocList.append((rtype, aoff))
    -            offset += sizeof(rdata)
    -
    -    def Rebase(self, delta, fdbin):
    -        count = 0
    -        if delta == 0:
    -            return count
    -
    -        for (rtype, roff) in self.RelocList:
    -            if rtype == 3: # IMAGE_REL_BASED_HIGHLOW
    -                offset = roff + self.Offset
    -                value  = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
    -                value += delta
    -                fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
    -                count += 1
    -            elif rtype == 10: # IMAGE_REL_BASED_DIR64
    -                offset = roff + self.Offset
    -                value  = Bytes2Val(fdbin[offset:offset+sizeof(c_uint64)])
    -                value += delta
    -                fdbin[offset:offset+sizeof(c_uint64)] = Val2Bytes(value, sizeof(c_uint64))
    -                count += 1
    -            else:
    -                raise Exception('ERROR: Unknown relocation type %d !' % rtype)
    -
    -        if self.IsTeImage():
    -            offset  = self.Offset + EFI_TE_IMAGE_HEADER.ImageBase.offset
    -            size    = EFI_TE_IMAGE_HEADER.ImageBase.size
    -        else:
    -            offset  = self.Offset + self.DosHdr.e_lfanew
    -            offset += EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset
    -            offset += EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset
    -            size    = EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size
    -
    -        value  = Bytes2Val(fdbin[offset:offset+size]) + delta
    -        fdbin[offset:offset+size] = Val2Bytes(value, size)
    -
    -        return count
    -
    -def ShowFspInfo (fspfile):
    -    fd = FirmwareDevice(0, fspfile)
    -    fd.ParseFd  ()
    -    fd.ParseFsp ()
    -
    -    print ("\nFound the following %d Firmware Volumes in FSP binary:" % (len(fd.FvList)))
    -    for idx, fv in enumerate(fd.FvList):
    -        name = fv.FvExtHdr.FvName
    -        if not name:
    -            name = '\xff' * 16
    -        else:
    -            name = str(bytearray(name))
    -        guid = uuid.UUID(bytes = name)
    -        print ("FV%d:" % idx)
    -        print ("  GUID   : %s" % str(guid).upper())
    -        print ("  Offset : 0x%08X" %  fv.Offset)
    -        print ("  Length : 0x%08X" % fv.FvHdr.FvLength)
    -    print ("\n")
    -
    -    for fsp in fd.FspList:
    -        fvlist = map(lambda x : 'FV%d' % x, fsp.FvIdxList)
    -        print ("FSP_%s contains %s" % (fsp.Type, ','.join(fvlist)))
    -        print ("%s" % (OutputStruct(fsp.Fih, 0, fsp.Fih.HeaderLength)))
    -
    -def GenFspHdr (fspfile, outdir, hfile):
    -    fd = FirmwareDevice(0, fspfile)
    -    fd.ParseFd  ()
    -    fd.ParseFsp ()
    -
    -    if not hfile:
    -        hfile = os.path.splitext(os.path.basename(fspfile))[0] + '.h'
    -    fspname, ext = os.path.splitext(os.path.basename(hfile))
    -    filename = os.path.join(outdir, fspname + ext)
    -    hfsp   = open(filename, 'w')
    -    hfsp.write ('%s\n\n' % CopyRightHeaderFile)
    -
    -    firstfv = True
    -    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))
    -            hfsp.write("#define  FSP_IMAGE_REV   0x%08X \n\n" % fih.ImageRevision)
    -            firstfv = False
    -        fv = fd.FvList[fsp.FvIdxList[0]]
    -        hfsp.write ('#define  FSP%s_BASE       0x%08X\n'   % (fsp.Type, fih.ImageBase))
    -        hfsp.write ('#define  FSP%s_OFFSET     0x%08X\n'   % (fsp.Type, fv.Offset))
    -        hfsp.write ('#define  FSP%s_LENGTH     0x%08X\n\n' % (fsp.Type, fih.ImageSize))
    -
    -    hfsp.close()
    -
    -def SplitFspBin (fspfile, outdir, nametemplate):
    -    fd = FirmwareDevice(0, fspfile)
    -    fd.ParseFd  ()
    -    fd.ParseFsp ()
    -
    -    for fsp in fd.FspList:
    -        ftype = fsp.Type
    -        if not nametemplate:
    -            nametemplate = fspfile
    -        fspname, ext = os.path.splitext(os.path.basename(nametemplate))
    -        filename = os.path.join(outdir, fspname + '_' + fsp.Type + ext)
    -        hfsp = open(filename, 'wb')
    -        print ("Create FSP component file '%s'" % filename)
    -        for fvidx in fsp.FvIdxList:
    -            fv = fd.FvList[fvidx]
    -            hfsp.write(fv.FvData)
    -        hfsp.close()
    -
    -def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
    -    fd = FirmwareDevice(0, FspBinary)
    -    fd.ParseFd  ()
    -    fd.ParseFsp ()
    -
    -    numcomp  = len(FspComponent)
    -    baselist = FspBase
    -    if numcomp != len(baselist):
    -        print "ERROR: Required number of base does not match number of FSP component !"
    -        return
    -
    -    newfspbin = fd.FdData[:]
    -
    -    for idx, fspcomp in enumerate(FspComponent):
    -
    -        found = False
    -        for fsp in fd.FspList:
    -            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()
    -            return
    -
    -        fspbase = baselist[idx]
    -        if fspbase.startswith('0x'):
    -            newbase = int(fspbase, 16)
    -        else:
    -            newbase = int(fspbase)
    -        oldbase = fsp.Fih.ImageBase
    -        delta = newbase - oldbase
    -        print "Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase)
    -
    -        imglist = []
    -        for fvidx in fsp.FvIdxList:
    -            fv = fd.FvList[fvidx]
    -            for ffs in fv.FfsList:
    -                for sec in ffs.SecList:
    -                    if sec.SecHdr.Type in [EFI_SECTION_TYPE.TE, EFI_SECTION_TYPE.PE32]:   # TE or PE32
    -                        offset = fd.Offset + fv.Offset + ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
    -                        imglist.append ((offset, len(sec.SecData) - sizeof(sec.SecHdr)))
    -
    -        fcount  = 0
    -        pcount  = 0
    -        for (offset, length) in imglist:
    -            img = PeTeImage(offset, fd.FdData[offset:offset + length])
    -            img.ParseReloc()
    -            pcount += img.Rebase(delta, newfspbin)
    -            fcount += 1
    -
    -        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
    -        if count != applied:
    -            print "  %d invalid entries are ignored !" % (count - applied)
    -
    -    if OutputFile == '':
    -        filename = os.path.basename(FspBinary)
    -        base, ext  = os.path.splitext(filename)
    -        OutputFile = base + "_%08X" % newbase + ext
    -
    -    fspname, ext = os.path.splitext(os.path.basename(OutputFile))
    -    filename = os.path.join(OutputDir, fspname + ext)
    -    fd = open(filename, "wb")
    -    fd.write(newfspbin)
    -    fd.close()
    -
    -def main ():
    -    parser     = argparse.ArgumentParser()
    -    subparsers = parser.add_subparsers(title='commands')
    -
    -    parser_rebase  = subparsers.add_parser('rebase',  help='rebase a FSP into a new base address')
    -    parser_rebase.set_defaults(which='rebase')
    -    parser_rebase.add_argument('-f',  '--fspbin' , dest='FspBinary',  type=str, help='FSP binary file path', required = True)
    -    parser_rebase.add_argument('-c',  '--fspcomp', choices=['t','m','s','o'],  nargs='+', dest='FspComponent', type=str, help='FSP component to rebase', default = "['t']", required = True)
    -    parser_rebase.add_argument('-b',  '--newbase', dest='FspBase', nargs='+', type=str, help='Rebased FSP binary file name', default = '', required = True)
    -    parser_rebase.add_argument('-o',  '--outdir' , dest='OutputDir',  type=str, help='Output directory path', default = '.')
    -    parser_rebase.add_argument('-n',  '--outfile', dest='OutputFile', type=str, help='Rebased FSP binary file name', default = '')
    -
    -    parser_split  = subparsers.add_parser('split',  help='split a FSP into multiple components')
    -    parser_split.set_defaults(which='split')
    -    parser_split.add_argument('-f',  '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
    -    parser_split.add_argument('-o',  '--outdir' , dest='OutputDir', type=str, help='Output directory path',   default = '.')
    -    parser_split.add_argument('-n',  '--nametpl', dest='NameTemplate', type=str, help='Output name template', default = '')
    -
    -    parser_genhdr = subparsers.add_parser('genhdr',  help='generate a header file for FSP binary')
    -    parser_genhdr.set_defaults(which='genhdr')
    -    parser_genhdr.add_argument('-f',  '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
    -    parser_genhdr.add_argument('-o',  '--outdir' , dest='OutputDir', type=str, help='Output directory path',   default = '.')
    -    parser_genhdr.add_argument('-n',  '--hfile',   dest='HFileName', type=str, help='Output header file name', default = '')
    -
    -    parser_info = subparsers.add_parser('info',  help='display FSP information')
    -    parser_info.set_defaults(which='info')
    -    parser_info.add_argument('-f',  '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
    -
    -    args = parser.parse_args()
    -    if args.which in ['rebase', 'split', 'genhdr', 'info']:
    -        if not os.path.exists(args.FspBinary):
    -            raise Exception ("ERROR: Could not locate FSP binary file '%s' !" % args.FspBinary)
    -        if hasattr(args, 'OutputDir') and not os.path.exists(args.OutputDir):
    -            raise Exception ("ERROR: Invalid output directory '%s' !" % args.OutputDir)
    -
    -    if args.which == 'rebase':
    -        RebaseFspBin (args.FspBinary, args.FspComponent, args.FspBase, args.OutputDir, args.OutputFile)
    -    elif args.which == 'split':
    -        SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate)
    -    elif args.which == 'genhdr':
    -        GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName)
    -    elif args.which == 'info':
    -        ShowFspInfo (args.FspBinary)
    -    else:
    -        pass
    -
    -    return 0
    -
    -if __name__ == '__main__':
    -    sys.exit(main())
    +#!/usr/bin/env python
    +## @ 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.
    +#
    +##
    +
    +import os
    +import sys
    +import uuid
    +import copy
    +import struct
    +import argparse
    +from   ctypes import *
    +
    +"""
    +This utility supports some operations for Intel FSP 2.0 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
    +"""
    +
    +CopyRightHeaderFile = """/*
    + *
    + * Automatically generated file; DO NOT EDIT.
    + * FSP mapping file
    + *
    + */
    +"""
    +
    +class c_uint24(Structure):
    +    """Little-Endian 24-bit Unsigned Integer"""
    +    _pack_   = 1
    +    _fields_ = [('Data', (c_uint8 * 3))]
    +
    +    def __init__(self, val=0):
    +        self.set_value(val)
    +
    +    def __str__(self, indent=0):
    +        return '0x%.6x' % self.value
    +
    +    def __int__(self):
    +        return self.get_value()
    +
    +    def set_value(self, val):
    +        self.Data[0:3] = Val2Bytes(val, 3)
    +
    +    def get_value(self):
    +        return Bytes2Val(self.Data[0:3])
    +
    +    value = property(get_value, set_value)
    +
    +class EFI_FIRMWARE_VOLUME_HEADER(Structure):
    +    _fields_ = [
    +        ('ZeroVector',           ARRAY(c_uint8, 16)),
    +        ('FileSystemGuid',       ARRAY(c_uint8, 16)),
    +        ('FvLength',             c_uint64),
    +        ('Signature',            ARRAY(c_char, 4)),
    +        ('Attributes',           c_uint32),
    +        ('HeaderLength',         c_uint16),
    +        ('Checksum',             c_uint16),
    +        ('ExtHeaderOffset',      c_uint16),
    +        ('Reserved',             c_uint8),
    +        ('Revision',             c_uint8)
    +        ]
    +
    +class EFI_FIRMWARE_VOLUME_EXT_HEADER(Structure):
    +    _fields_ = [
    +        ('FvName',               ARRAY(c_uint8, 16)),
    +        ('ExtHeaderSize',        c_uint32)
    +        ]
    +
    +class EFI_FFS_INTEGRITY_CHECK(Structure):
    +    _fields_ = [
    +        ('Header',               c_uint8),
    +        ('File',                 c_uint8)
    +        ]
    +
    +class EFI_FFS_FILE_HEADER(Structure):
    +    _fields_ = [
    +        ('Name',                 ARRAY(c_uint8, 16)),
    +        ('IntegrityCheck',       EFI_FFS_INTEGRITY_CHECK),
    +        ('Type',                 c_uint8),
    +        ('Attributes',           c_uint8),
    +        ('Size',                 c_uint24),
    +        ('State',                c_uint8)
    +        ]
    +
    +class EFI_COMMON_SECTION_HEADER(Structure):
    +    _fields_ = [
    +        ('Size',                 c_uint24),
    +        ('Type',                 c_uint8)
    +        ]
    +
    +class FSP_COMMON_HEADER(Structure):
    +     _fields_ = [
    +        ('Signature',            ARRAY(c_char, 4)),
    +        ('HeaderLength',         c_uint32)
    +        ]
    +
    +class FSP_INFORMATION_HEADER(Structure):
    +     _fields_ = [
    +        ('Signature',            ARRAY(c_char, 4)),
    +        ('HeaderLength',         c_uint32),
    +        ('Reserved1',            c_uint16),
    +        ('SpecVersion',          c_uint8),
    +        ('HeaderRevision',       c_uint8),
    +        ('ImageRevision',        c_uint32),
    +        ('ImageId',              ARRAY(c_char, 8)),
    +        ('ImageSize',            c_uint32),
    +        ('ImageBase',            c_uint32),
    +        ('ImageAttribute',       c_uint16),
    +        ('ComponentAttribute',   c_uint16),
    +        ('CfgRegionOffset',      c_uint32),
    +        ('CfgRegionSize',        c_uint32),
    +        ('Reserved2',            c_uint32),
    +        ('TempRamInitEntryOffset',     c_uint32),
    +        ('Reserved3',                  c_uint32),
    +        ('NotifyPhaseEntryOffset',     c_uint32),
    +        ('FspMemoryInitEntryOffset',   c_uint32),
    +        ('TempRamExitEntryOffset',     c_uint32),
    +        ('FspSiliconInitEntryOffset',  c_uint32)
    +    ]
    +
    +class FSP_PATCH_TABLE(Structure):
    +    _fields_ = [
    +        ('Signature',            ARRAY(c_char, 4)),
    +        ('HeaderLength',         c_uint16),
    +        ('HeaderRevision',       c_uint8),
    +        ('Reserved',             c_uint8),
    +        ('PatchEntryNum',        c_uint32)
    +        ]
    +
    +class EFI_IMAGE_DATA_DIRECTORY(Structure):
    +    _fields_ = [
    +        ('VirtualAddress',       c_uint32),
    +        ('Size',                 c_uint32)
    +        ]
    +
    +class EFI_TE_IMAGE_HEADER(Structure):
    +    _fields_ = [
    +        ('Signature',            ARRAY(c_char, 2)),
    +        ('Machine',              c_uint16),
    +        ('NumberOfSections',     c_uint8),
    +        ('Subsystem',            c_uint8),
    +        ('StrippedSize',         c_uint16),
    +        ('AddressOfEntryPoint',  c_uint32),
    +        ('BaseOfCode',           c_uint32),
    +        ('ImageBase',            c_uint64),
    +        ('DataDirectoryBaseReloc',  EFI_IMAGE_DATA_DIRECTORY),
    +        ('DataDirectoryDebug',      EFI_IMAGE_DATA_DIRECTORY)
    +        ]
    +
    +class EFI_IMAGE_DOS_HEADER(Structure):
    +    _fields_ = [
    +        ('e_magic',              c_uint16),
    +        ('e_cblp',               c_uint16),
    +        ('e_cp',                 c_uint16),
    +        ('e_crlc',               c_uint16),
    +        ('e_cparhdr',            c_uint16),
    +        ('e_minalloc',           c_uint16),
    +        ('e_maxalloc',           c_uint16),
    +        ('e_ss',                 c_uint16),
    +        ('e_sp',                 c_uint16),
    +        ('e_csum',               c_uint16),
    +        ('e_ip',                 c_uint16),
    +        ('e_cs',                 c_uint16),
    +        ('e_lfarlc',             c_uint16),
    +        ('e_ovno',               c_uint16),
    +        ('e_res',                ARRAY(c_uint16, 4)),
    +        ('e_oemid',              c_uint16),
    +        ('e_oeminfo',            c_uint16),
    +        ('e_res2',               ARRAY(c_uint16, 10)),
    +        ('e_lfanew',             c_uint16)
    +        ]
    +
    +class EFI_IMAGE_FILE_HEADER(Structure):
    +    _fields_ = [
    +        ('Machine',               c_uint16),
    +        ('NumberOfSections',      c_uint16),
    +        ('TimeDateStamp',         c_uint32),
    +        ('PointerToSymbolTable',  c_uint32),
    +        ('NumberOfSymbols',       c_uint32),
    +        ('SizeOfOptionalHeader',  c_uint16),
    +        ('Characteristics',       c_uint16)
    +        ]
    +
    +class PE_RELOC_BLOCK_HEADER(Structure):
    +    _fields_ = [
    +        ('PageRVA',              c_uint32),
    +        ('BlockSize',            c_uint32)
    +        ]
    +
    +class EFI_IMAGE_OPTIONAL_HEADER32(Structure):
    +    _fields_ = [
    +        ('Magic',                         c_uint16),
    +        ('MajorLinkerVersion',            c_uint8),
    +        ('MinorLinkerVersion',            c_uint8),
    +        ('SizeOfCode',                    c_uint32),
    +        ('SizeOfInitializedData',         c_uint32),
    +        ('SizeOfUninitializedData',       c_uint32),
    +        ('AddressOfEntryPoint',           c_uint32),
    +        ('BaseOfCode',                    c_uint32),
    +        ('BaseOfData',                    c_uint32),
    +        ('ImageBase',                     c_uint32),
    +        ('SectionAlignment',              c_uint32),
    +        ('FileAlignment',                 c_uint32),
    +        ('MajorOperatingSystemVersion',   c_uint16),
    +        ('MinorOperatingSystemVersion',   c_uint16),
    +        ('MajorImageVersion',             c_uint16),
    +        ('MinorImageVersion',             c_uint16),
    +        ('MajorSubsystemVersion',         c_uint16),
    +        ('MinorSubsystemVersion',         c_uint16),
    +        ('Win32VersionValue',             c_uint32),
    +        ('SizeOfImage',                   c_uint32),
    +        ('SizeOfHeaders',                 c_uint32),
    +        ('CheckSum'     ,                 c_uint32),
    +        ('Subsystem',                     c_uint16),
    +        ('DllCharacteristics',            c_uint16),
    +        ('SizeOfStackReserve',            c_uint32),
    +        ('SizeOfStackCommit' ,            c_uint32),
    +        ('SizeOfHeapReserve',             c_uint32),
    +        ('SizeOfHeapCommit' ,             c_uint32),
    +        ('LoaderFlags'     ,              c_uint32),
    +        ('NumberOfRvaAndSizes',           c_uint32),
    +        ('DataDirectory',                 ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
    +        ]
    +
    +class EFI_IMAGE_OPTIONAL_HEADER32_PLUS(Structure):
    +    _fields_ = [
    +        ('Magic',                         c_uint16),
    +        ('MajorLinkerVersion',            c_uint8),
    +        ('MinorLinkerVersion',            c_uint8),
    +        ('SizeOfCode',                    c_uint32),
    +        ('SizeOfInitializedData',         c_uint32),
    +        ('SizeOfUninitializedData',       c_uint32),
    +        ('AddressOfEntryPoint',           c_uint32),
    +        ('BaseOfCode',                    c_uint32),
    +        ('ImageBase',                     c_uint64),
    +        ('SectionAlignment',              c_uint32),
    +        ('FileAlignment',                 c_uint32),
    +        ('MajorOperatingSystemVersion',   c_uint16),
    +        ('MinorOperatingSystemVersion',   c_uint16),
    +        ('MajorImageVersion',             c_uint16),
    +        ('MinorImageVersion',             c_uint16),
    +        ('MajorSubsystemVersion',         c_uint16),
    +        ('MinorSubsystemVersion',         c_uint16),
    +        ('Win32VersionValue',             c_uint32),
    +        ('SizeOfImage',                   c_uint32),
    +        ('SizeOfHeaders',                 c_uint32),
    +        ('CheckSum'     ,                 c_uint32),
    +        ('Subsystem',                     c_uint16),
    +        ('DllCharacteristics',            c_uint16),
    +        ('SizeOfStackReserve',            c_uint64),
    +        ('SizeOfStackCommit' ,            c_uint64),
    +        ('SizeOfHeapReserve',             c_uint64),
    +        ('SizeOfHeapCommit' ,             c_uint64),
    +        ('LoaderFlags'     ,              c_uint32),
    +        ('NumberOfRvaAndSizes',           c_uint32),
    +        ('DataDirectory',                 ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
    +        ]
    +
    +class EFI_IMAGE_OPTIONAL_HEADER(Union):
    +    _fields_ = [
    +        ('PeOptHdr',             EFI_IMAGE_OPTIONAL_HEADER32),
    +        ('PePlusOptHdr',         EFI_IMAGE_OPTIONAL_HEADER32_PLUS)
    +        ]
    +
    +class EFI_IMAGE_NT_HEADERS32(Structure):
    +    _fields_ = [
    +        ('Signature',            c_uint32),
    +        ('FileHeader',           EFI_IMAGE_FILE_HEADER),
    +        ('OptionalHeader',       EFI_IMAGE_OPTIONAL_HEADER)
    +        ]
    +
    +
    +class EFI_IMAGE_DIRECTORY_ENTRY:
    +    EXPORT                     = 0
    +    IMPORT                     = 1
    +    RESOURCE                   = 2
    +    EXCEPTION                  = 3
    +    SECURITY                   = 4
    +    BASERELOC                  = 5
    +    DEBUG                      = 6
    +    COPYRIGHT                  = 7
    +    GLOBALPTR                  = 8
    +    TLS                        = 9
    +    LOAD_CONFIG                = 10
    +
    +class EFI_FV_FILETYPE:
    +    ALL                        = 0x00
    +    RAW                        = 0x01
    +    FREEFORM                   = 0x02
    +    SECURITY_CORE              = 0x03
    +    PEI_CORE                   = 0x04
    +    DXE_CORE                   = 0x05
    +    PEIM                       = 0x06
    +    DRIVER                     = 0x07
    +    COMBINED_PEIM_DRIVER       = 0x08
    +    APPLICATION                = 0x09
    +    SMM                        = 0x0a
    +    FIRMWARE_VOLUME_IMAGE      = 0x0b
    +    COMBINED_SMM_DXE           = 0x0c
    +    SMM_CORE                   = 0x0d
    +    OEM_MIN                    = 0xc0
    +    OEM_MAX                    = 0xdf
    +    DEBUG_MIN                  = 0xe0
    +    DEBUG_MAX                  = 0xef
    +    FFS_MIN                    = 0xf0
    +    FFS_MAX                    = 0xff
    +    FFS_PAD                    = 0xf0
    +
    +class EFI_SECTION_TYPE:
    +    """Enumeration of all valid firmware file section types."""
    +    ALL                        = 0x00
    +    COMPRESSION                = 0x01
    +    GUID_DEFINED               = 0x02
    +    DISPOSABLE                 = 0x03
    +    PE32                       = 0x10
    +    PIC                        = 0x11
    +    TE                         = 0x12
    +    DXE_DEPEX                  = 0x13
    +    VERSION                    = 0x14
    +    USER_INTERFACE             = 0x15
    +    COMPATIBILITY16            = 0x16
    +    FIRMWARE_VOLUME_IMAGE      = 0x17
    +    FREEFORM_SUBTYPE_GUID      = 0x18
    +    RAW                        = 0x19
    +    PEI_DEPEX                  = 0x1b
    +    SMM_DEPEX                  = 0x1c
    +
    +def AlignPtr (offset, alignment = 8):
    +    return (offset + alignment - 1) & ~(alignment - 1)
    +
    +def Bytes2Val (bytes):
    +    return reduce(lambda x,y: (x<<8)|y,  bytes[::-1] )
    +
    +def Val2Bytes (value, blen):
    +    return [(value>>(i*8) & 0xff) for i in range(blen)]
    +
    +def OutputStruct (obj, indent = 0, plen = 0):
    +    if indent:
    +        body = ''
    +    else:
    +        body = ('  ' * indent + '<%s>:\n') % obj.__class__.__name__
    +
    +    if plen == 0:
    +        plen = sizeof(obj)
    +
    +    max_key_len = 26
    +    pstr = ('  ' * (indent + 1) + '{0:<%d} = {1}\n') % max_key_len
    +
    +    for field in obj._fields_:
    +        key = field[0]
    +        val = getattr(obj, key)
    +        rep = ''
    +        if not isinstance(val, c_uint24) and isinstance(val, Structure):
    +            body += pstr.format(key, val.__class__.__name__)
    +            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):
    +                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()
    +                else:
    +                    res = ['0x%02X'%i for i in bytearray(val)]
    +                    rep = '[%s]' % (','.join(res))
    +            else:
    +                rep = str(val)
    +            plen -= sizeof(field[1])
    +            body += pstr.format(key, rep)
    +        if plen <= 0:
    +            break
    +    return body
    +
    +class Section:
    +    def __init__(self, offset, secdata):
    +        self.SecHdr   = EFI_COMMON_SECTION_HEADER.from_buffer (secdata, 0)
    +        self.SecData  = secdata[0:int(self.SecHdr.Size)]
    +        self.Offset   = offset
    +
    +class FirmwareFile:
    +    def __init__(self, offset, filedata):
    +        self.FfsHdr   = EFI_FFS_FILE_HEADER.from_buffer (filedata, 0)
    +        self.FfsData  = filedata[0:int(self.FfsHdr.Size)]
    +        self.Offset   = offset
    +        self.SecList  = []
    +
    +    def ParseFfs(self):
    +        ffssize = len(self.FfsData)
    +        offset  = sizeof(self.FfsHdr)
    +        if self.FfsHdr.Name != '\xff' * 16:
    +            while offset < ffssize:
    +                sechdr = EFI_COMMON_SECTION_HEADER.from_buffer (self.FfsData, offset)
    +                sec = Section (offset, self.FfsData[offset:offset + int(sechdr.Size)])
    +                self.SecList.append(sec)
    +                offset += int(sechdr.Size)
    +                offset  = AlignPtr(offset, 4)
    +
    +class FirmwareVolume:
    +    def __init__(self, offset, fvdata):
    +        self.FvHdr    = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (fvdata, 0)
    +        self.FvData   = fvdata[0 : self.FvHdr.FvLength]
    +        self.Offset   = offset
    +        if self.FvHdr.ExtHeaderOffset > 0:
    +            self.FvExtHdr = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer (self.FvData, self.FvHdr.ExtHeaderOffset)
    +        else:
    +            self.FvExtHdr = None
    +        self.FfsList  = []
    +
    +    def ParseFv(self):
    +        fvsize = len(self.FvData)
    +        if self.FvExtHdr:
    +            offset = self.FvHdr.ExtHeaderOffset + self.FvExtHdr.ExtHeaderSize
    +        else:
    +            offset = self.FvHdr.HeaderLength
    +        offset = AlignPtr(offset)
    +        while offset < fvsize:
    +            ffshdr = EFI_FFS_FILE_HEADER.from_buffer (self.FvData, offset)
    +            if (ffshdr.Name == '\xff' * 16) and (int(ffshdr.Size) == 0xFFFFFF):
    +                offset = fvsize
    +            else:
    +                ffs = FirmwareFile (offset, self.FvData[offset:offset + int(ffshdr.Size)])
    +                ffs.ParseFfs()
    +                self.FfsList.append(ffs)
    +                offset += int(ffshdr.Size)
    +                offset = AlignPtr(offset)
    +
    +class FspImage:
    +    def __init__(self, offset, fih, fihoff, patch):
    +        self.Fih       = fih
    +        self.FihOffset = fihoff
    +        self.Offset    = offset
    +        self.FvIdxList = []
    +        self.Type      = "XTMSXXXXOXXXXXXX"[(fih.ComponentAttribute >> 12) & 0x0F]
    +        self.PatchList = patch
    +        self.PatchList.append(fihoff + 0x1C)
    +
    +    def AppendFv(self, FvIdx):
    +        self.FvIdxList.append(FvIdx)
    +
    +    def Patch(self, delta, fdbin):
    +        count   = 0
    +        applied = 0
    +        for idx, patch in enumerate(self.PatchList):
    +            ptype = (patch>>24) & 0x0F
    +            if ptype not in [0x00, 0x0F]:
    +                raise Exception('ERROR: Invalid patch type %d !' % ptype)
    +            if patch & 0x80000000:
    +                patch = self.Fih.ImageSize - (0x1000000 - (patch & 0xFFFFFF))
    +            else:
    +                patch = patch & 0xFFFFFF
    +            if (patch < self.Fih.ImageSize) and (patch + sizeof(c_uint32) <= self.Fih.ImageSize):
    +                offset = patch + self.Offset
    +                value  = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
    +                value += delta
    +                fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
    +                applied += 1
    +            count += 1
    +        # Don't count the FSP base address patch entry appended at the end
    +        if count != 0:
    +            count   -= 1
    +            applied -= 1
    +        return (count, applied)
    +
    +class FirmwareDevice:
    +    def __init__(self, offset, fdfile):
    +        self.FvList  = []
    +        self.FspList = []
    +        self.FdFile = fdfile
    +        self.Offset = 0
    +        hfsp = open (self.FdFile, 'rb')
    +        self.FdData = bytearray(hfsp.read())
    +        hfsp.close()
    +
    +    def ParseFd(self):
    +        offset = 0
    +        fdsize = len(self.FdData)
    +        self.FvList  = []
    +        while offset < fdsize:
    +            fvh = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (self.FdData, offset)
    +            if '_FVH' != fvh.Signature:
    +                raise Exception("ERROR: Invalid FV header !")
    +            fv = FirmwareVolume (offset, self.FdData[offset:offset + fvh.FvLength])
    +            fv.ParseFv ()
    +            self.FvList.append(fv)
    +            offset += fv.FvHdr.FvLength
    +
    +    def CheckFsp (self):
    +        if len(self.FspList) == 0:
    +            return
    +
    +        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:
    +                newfih = fsp.Fih
    +                if (newfih.ImageId != fih.ImageId) or (newfih.ImageRevision != fih.ImageRevision):
    +                    raise Exception("ERROR: Inconsistent FSP ImageId or ImageRevision detected !")
    +
    +    def ParseFsp(self):
    +        flen = 0
    +        for idx, fv in enumerate(self.FvList):
    +            # Check if this FV contains FSP header
    +            if flen == 0:
    +                if len(fv.FfsList) == 0:
    +                    continue
    +                ffs = fv.FfsList[0]
    +                if len(ffs.SecList) == 0:
    +                    continue
    +                sec = ffs.SecList[0]
    +                if sec.SecHdr.Type != EFI_SECTION_TYPE.RAW:
    +                    continue
    +                fihoffset = ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
    +                fspoffset = fv.Offset
    +                offset    = fspoffset + fihoffset
    +                fih = FSP_INFORMATION_HEADER.from_buffer (self.FdData, offset)
    +                if '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:
    +                        offset += fch.HeaderLength
    +                        offset = AlignPtr(offset, 4)
    +                    else:
    +                        fspp = FSP_PATCH_TABLE.from_buffer (self.FdData, offset)
    +                        offset += sizeof(fspp)
    +                        pdata  = (c_uint32 * fspp.PatchEntryNum).from_buffer(self.FdData, offset)
    +                        plist  = list(pdata)
    +                        break
    +
    +                fsp  = FspImage (fspoffset, fih, fihoffset, plist)
    +                fsp.AppendFv (idx)
    +                self.FspList.append(fsp)
    +                flen = fsp.Fih.ImageSize - fv.FvHdr.FvLength
    +            else:
    +                fsp.AppendFv (idx)
    +                flen -= fv.FvHdr.FvLength
    +                if flen < 0:
    +                    raise Exception("ERROR: Incorrect FV size in image !")
    +        self.CheckFsp ()
    +
    +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
    +            self.TeHdr   = tehdr
    +        elif tehdr.Signature == '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)
    +            if self.PeHdr.Signature != 0x4550:
    +                raise Exception("ERROR: Invalid PE32 header !")
    +            if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b: # PE32 image
    +                if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:
    +                    raise Exception("ERROR: Unsupported PE32 image !")
    +                if self.PeHdr.OptionalHeader.PeOptHdr.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
    +                    raise Exception("ERROR: No relocation information available !")
    +            elif self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x20b: # PE32+ image
    +                if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32_PLUS.DataDirectory.offset:
    +                    raise Exception("ERROR: Unsupported PE32+ image !")
    +                if self.PeHdr.OptionalHeader.PePlusOptHdr.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
    +                    raise Exception("ERROR: No relocation information available !")
    +            else:
    +                raise Exception("ERROR: Invalid PE32 optional header !")
    +        self.Offset    = offset
    +        self.Data      = data
    +        self.RelocList = []
    +
    +    def IsTeImage(self):
    +        return  self.TeHdr is not None
    +
    +    def ParseReloc(self):
    +        if self.IsTeImage():
    +            rsize   = self.TeHdr.DataDirectoryBaseReloc.Size
    +            roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
    +        else:
    +            if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x10b: # PE32 image
    +                rsize   = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
    +                roffset = self.PeHdr.OptionalHeader.PeOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress
    +            if self.PeHdr.OptionalHeader.PeOptHdr.Magic == 0x20b: # PE32+ image
    +                rsize   = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
    +                roffset = self.PeHdr.OptionalHeader.PePlusOptHdr.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress
    +
    +        alignment = 4
    +        offset = roffset
    +        while offset < roffset + rsize:
    +            offset = AlignPtr(offset, 4)
    +            blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.Data, offset)
    +            offset += sizeof(blkhdr)
    +            # Read relocation type,offset pairs
    +            rlen  = blkhdr.BlockSize - sizeof(PE_RELOC_BLOCK_HEADER)
    +            rnum  = rlen/sizeof(c_uint16)
    +            rdata = (c_uint16 * rnum).from_buffer(self.Data, offset)
    +            for each in rdata:
    +                roff  = each & 0xfff
    +                rtype = each >> 12
    +                if rtype == 0: # IMAGE_REL_BASED_ABSOLUTE:
    +                    continue
    +                if ((rtype != 3) and (rtype != 10)): # IMAGE_REL_BASED_HIGHLOW and IMAGE_REL_BASED_DIR64
    +                    raise Exception("ERROR: Unsupported relocation type %d!" % rtype)
    +                # Calculate the offset of the relocation
    +                aoff  = blkhdr.PageRVA + roff
    +                if self.IsTeImage():
    +                    aoff += sizeof(self.TeHdr) - self.TeHdr.StrippedSize
    +                self.RelocList.append((rtype, aoff))
    +            offset += sizeof(rdata)
    +
    +    def Rebase(self, delta, fdbin):
    +        count = 0
    +        if delta == 0:
    +            return count
    +
    +        for (rtype, roff) in self.RelocList:
    +            if rtype == 3: # IMAGE_REL_BASED_HIGHLOW
    +                offset = roff + self.Offset
    +                value  = Bytes2Val(fdbin[offset:offset+sizeof(c_uint32)])
    +                value += delta
    +                fdbin[offset:offset+sizeof(c_uint32)] = Val2Bytes(value, sizeof(c_uint32))
    +                count += 1
    +            elif rtype == 10: # IMAGE_REL_BASED_DIR64
    +                offset = roff + self.Offset
    +                value  = Bytes2Val(fdbin[offset:offset+sizeof(c_uint64)])
    +                value += delta
    +                fdbin[offset:offset+sizeof(c_uint64)] = Val2Bytes(value, sizeof(c_uint64))
    +                count += 1
    +            else:
    +                raise Exception('ERROR: Unknown relocation type %d !' % rtype)
    +
    +        if self.IsTeImage():
    +            offset  = self.Offset + EFI_TE_IMAGE_HEADER.ImageBase.offset
    +            size    = EFI_TE_IMAGE_HEADER.ImageBase.size
    +        else:
    +            offset  = self.Offset + self.DosHdr.e_lfanew
    +            offset += EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset
    +            offset += EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset
    +            size    = EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size
    +
    +        value  = Bytes2Val(fdbin[offset:offset+size]) + delta
    +        fdbin[offset:offset+size] = Val2Bytes(value, size)
    +
    +        return count
    +
    +def ShowFspInfo (fspfile):
    +    fd = FirmwareDevice(0, fspfile)
    +    fd.ParseFd  ()
    +    fd.ParseFsp ()
    +
    +    print ("\nFound the following %d Firmware Volumes in FSP binary:" % (len(fd.FvList)))
    +    for idx, fv in enumerate(fd.FvList):
    +        name = fv.FvExtHdr.FvName
    +        if not name:
    +            name = '\xff' * 16
    +        else:
    +            name = str(bytearray(name))
    +        guid = uuid.UUID(bytes = name)
    +        print ("FV%d:" % idx)
    +        print ("  GUID   : %s" % str(guid).upper())
    +        print ("  Offset : 0x%08X" %  fv.Offset)
    +        print ("  Length : 0x%08X" % fv.FvHdr.FvLength)
    +    print ("\n")
    +
    +    for fsp in fd.FspList:
    +        fvlist = map(lambda x : 'FV%d' % x, fsp.FvIdxList)
    +        print ("FSP_%s contains %s" % (fsp.Type, ','.join(fvlist)))
    +        print ("%s" % (OutputStruct(fsp.Fih, 0, fsp.Fih.HeaderLength)))
    +
    +def GenFspHdr (fspfile, outdir, hfile):
    +    fd = FirmwareDevice(0, fspfile)
    +    fd.ParseFd  ()
    +    fd.ParseFsp ()
    +
    +    if not hfile:
    +        hfile = os.path.splitext(os.path.basename(fspfile))[0] + '.h'
    +    fspname, ext = os.path.splitext(os.path.basename(hfile))
    +    filename = os.path.join(outdir, fspname + ext)
    +    hfsp   = open(filename, 'w')
    +    hfsp.write ('%s\n\n' % CopyRightHeaderFile)
    +
    +    firstfv = True
    +    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))
    +            hfsp.write("#define  FSP_IMAGE_REV   0x%08X \n\n" % fih.ImageRevision)
    +            firstfv = False
    +        fv = fd.FvList[fsp.FvIdxList[0]]
    +        hfsp.write ('#define  FSP%s_BASE       0x%08X\n'   % (fsp.Type, fih.ImageBase))
    +        hfsp.write ('#define  FSP%s_OFFSET     0x%08X\n'   % (fsp.Type, fv.Offset))
    +        hfsp.write ('#define  FSP%s_LENGTH     0x%08X\n\n' % (fsp.Type, fih.ImageSize))
    +
    +    hfsp.close()
    +
    +def SplitFspBin (fspfile, outdir, nametemplate):
    +    fd = FirmwareDevice(0, fspfile)
    +    fd.ParseFd  ()
    +    fd.ParseFsp ()
    +
    +    for fsp in fd.FspList:
    +        ftype = fsp.Type
    +        if not nametemplate:
    +            nametemplate = fspfile
    +        fspname, ext = os.path.splitext(os.path.basename(nametemplate))
    +        filename = os.path.join(outdir, fspname + '_' + fsp.Type + ext)
    +        hfsp = open(filename, 'wb')
    +        print ("Create FSP component file '%s'" % filename)
    +        for fvidx in fsp.FvIdxList:
    +            fv = fd.FvList[fvidx]
    +            hfsp.write(fv.FvData)
    +        hfsp.close()
    +
    +def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
    +    fd = FirmwareDevice(0, FspBinary)
    +    fd.ParseFd  ()
    +    fd.ParseFsp ()
    +
    +    numcomp  = len(FspComponent)
    +    baselist = FspBase
    +    if numcomp != len(baselist):
    +        print "ERROR: Required number of base does not match number of FSP component !"
    +        return
    +
    +    newfspbin = fd.FdData[:]
    +
    +    for idx, fspcomp in enumerate(FspComponent):
    +
    +        found = False
    +        for fsp in fd.FspList:
    +            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()
    +            return
    +
    +        fspbase = baselist[idx]
    +        if fspbase.startswith('0x'):
    +            newbase = int(fspbase, 16)
    +        else:
    +            newbase = int(fspbase)
    +        oldbase = fsp.Fih.ImageBase
    +        delta = newbase - oldbase
    +        print "Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase)
    +
    +        imglist = []
    +        for fvidx in fsp.FvIdxList:
    +            fv = fd.FvList[fvidx]
    +            for ffs in fv.FfsList:
    +                for sec in ffs.SecList:
    +                    if sec.SecHdr.Type in [EFI_SECTION_TYPE.TE, EFI_SECTION_TYPE.PE32]:   # TE or PE32
    +                        offset = fd.Offset + fv.Offset + ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
    +                        imglist.append ((offset, len(sec.SecData) - sizeof(sec.SecHdr)))
    +
    +        fcount  = 0
    +        pcount  = 0
    +        for (offset, length) in imglist:
    +            img = PeTeImage(offset, fd.FdData[offset:offset + length])
    +            img.ParseReloc()
    +            pcount += img.Rebase(delta, newfspbin)
    +            fcount += 1
    +
    +        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
    +        if count != applied:
    +            print "  %d invalid entries are ignored !" % (count - applied)
    +
    +    if OutputFile == '':
    +        filename = os.path.basename(FspBinary)
    +        base, ext  = os.path.splitext(filename)
    +        OutputFile = base + "_%08X" % newbase + ext
    +
    +    fspname, ext = os.path.splitext(os.path.basename(OutputFile))
    +    filename = os.path.join(OutputDir, fspname + ext)
    +    fd = open(filename, "wb")
    +    fd.write(newfspbin)
    +    fd.close()
    +
    +def main ():
    +    parser     = argparse.ArgumentParser()
    +    subparsers = parser.add_subparsers(title='commands')
    +
    +    parser_rebase  = subparsers.add_parser('rebase',  help='rebase a FSP into a new base address')
    +    parser_rebase.set_defaults(which='rebase')
    +    parser_rebase.add_argument('-f',  '--fspbin' , dest='FspBinary',  type=str, help='FSP binary file path', required = True)
    +    parser_rebase.add_argument('-c',  '--fspcomp', choices=['t','m','s','o'],  nargs='+', dest='FspComponent', type=str, help='FSP component to rebase', default = "['t']", required = True)
    +    parser_rebase.add_argument('-b',  '--newbase', dest='FspBase', nargs='+', type=str, help='Rebased FSP binary file name', default = '', required = True)
    +    parser_rebase.add_argument('-o',  '--outdir' , dest='OutputDir',  type=str, help='Output directory path', default = '.')
    +    parser_rebase.add_argument('-n',  '--outfile', dest='OutputFile', type=str, help='Rebased FSP binary file name', default = '')
    +
    +    parser_split  = subparsers.add_parser('split',  help='split a FSP into multiple components')
    +    parser_split.set_defaults(which='split')
    +    parser_split.add_argument('-f',  '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
    +    parser_split.add_argument('-o',  '--outdir' , dest='OutputDir', type=str, help='Output directory path',   default = '.')
    +    parser_split.add_argument('-n',  '--nametpl', dest='NameTemplate', type=str, help='Output name template', default = '')
    +
    +    parser_genhdr = subparsers.add_parser('genhdr',  help='generate a header file for FSP binary')
    +    parser_genhdr.set_defaults(which='genhdr')
    +    parser_genhdr.add_argument('-f',  '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
    +    parser_genhdr.add_argument('-o',  '--outdir' , dest='OutputDir', type=str, help='Output directory path',   default = '.')
    +    parser_genhdr.add_argument('-n',  '--hfile',   dest='HFileName', type=str, help='Output header file name', default = '')
    +
    +    parser_info = subparsers.add_parser('info',  help='display FSP information')
    +    parser_info.set_defaults(which='info')
    +    parser_info.add_argument('-f',  '--fspbin' , dest='FspBinary', type=str, help='FSP binary file path', required = True)
    +
    +    args = parser.parse_args()
    +    if args.which in ['rebase', 'split', 'genhdr', 'info']:
    +        if not os.path.exists(args.FspBinary):
    +            raise Exception ("ERROR: Could not locate FSP binary file '%s' !" % args.FspBinary)
    +        if hasattr(args, 'OutputDir') and not os.path.exists(args.OutputDir):
    +            raise Exception ("ERROR: Invalid output directory '%s' !" % args.OutputDir)
    +
    +    if args.which == 'rebase':
    +        RebaseFspBin (args.FspBinary, args.FspComponent, args.FspBase, args.OutputDir, args.OutputFile)
    +    elif args.which == 'split':
    +        SplitFspBin (args.FspBinary, args.OutputDir, args.NameTemplate)
    +    elif args.which == 'genhdr':
    +        GenFspHdr (args.FspBinary, args.OutputDir, args.HFileName)
    +    elif args.which == 'info':
    +        ShowFspInfo (args.FspBinary)
    +    else:
    +        pass
    +
    +    return 0
    +
    +if __name__ == '__main__':
    +    sys.exit(main())
    -- 
    2.19.0.397.gdd90340f6a-goog
    
    _______________________________________________
    edk2-devel mailing list
    edk2-devel@lists.01.org
    https://lists.01.org/mailman/listinfo/edk2-devel
    


  reply	other threads:[~2018-09-18 15:10 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-09-18 13:32 [PATCH 1/3] IntelFsp2Pkg: Allow calling SplitFspBin.py directly Patrick Georgi
2018-09-18 13:32 ` [PATCH 2/3] IntelFsp2Pkg: Fix typo in SplitFspBin Patrick Georgi
2018-09-18 15:04   ` Desimone, Nathaniel L
2018-09-20 23:28     ` Chiu, Chasel
2018-09-26  3:11       ` Yao, Jiewen
2018-09-18 13:32 ` [PATCH 3/3] IntelFsp2Pkg: Tell git to format SplitFspBin.py with native newlines Patrick Georgi
2018-09-18 15:10   ` Desimone, Nathaniel L [this message]
2018-09-18 15:53     ` Patrick Georgi
2018-09-20  4:37       ` Desimone, Nathaniel L
2018-09-26  3:12         ` Yao, Jiewen
2018-09-26 15:58           ` Patrick Georgi
2018-09-27  0:40             ` Yao, Jiewen
2018-09-18 15:03 ` [PATCH 1/3] IntelFsp2Pkg: Allow calling SplitFspBin.py directly Desimone, Nathaniel L

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5608C728-C8C9-4D20-8C4D-FEC4FA974BA6@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox