## @ PatchBinFv.py
#
# Copyright (c) 2017, Intel Corporation. All rights reserved.
# 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 re
import sys
import time
import shutil
import struct
import binascii
from ctypes import *
class GUID(Structure):
_fields_ = [
('Guid1', c_uint32),
('Guid2', c_uint16),
('Guid3', c_uint16),
('Guid4', ARRAY(c_uint8, 8)),
]
class EFI_FIRMWARE_VOLUME_HEADER(Structure):
_fields_ = [
('ZeroVector', ARRAY(c_uint8, 16)),
('FileSystemGuid', GUID),
('FvLength', c_uint64),
('Signature', c_uint32),
('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', GUID),
('ExtHeaderSize', c_uint32),
]
#
# File Types Definitions
#
EFI_FV_FILETYPE_ALL = 0x00
EFI_FV_FILETYPE_RAW = 0x01
EFI_FV_FILETYPE_FREEFORM = 0x02
EFI_FV_FILETYPE_SECURITY_CORE = 0x03
EFI_FV_FILETYPE_PEI_CORE = 0x04
EFI_FV_FILETYPE_DXE_CORE = 0x05
EFI_FV_FILETYPE_PEIM = 0x06
EFI_FV_FILETYPE_DRIVER = 0x07
EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER = 0x08
EFI_FV_FILETYPE_APPLICATION = 0x09
EFI_FV_FILETYPE_SMM = 0x0A
EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE = 0x0B
EFI_FV_FILETYPE_COMBINED_SMM_DXE = 0x0C
EFI_FV_FILETYPE_SMM_CORE = 0x0D
EFI_FV_FILETYPE_OEM_MIN = 0xc0
EFI_FV_FILETYPE_OEM_MAX = 0xdf
EFI_FV_FILETYPE_DEBUG_MIN = 0xe0
EFI_FV_FILETYPE_DEBUG_MAX = 0xef
EFI_FV_FILETYPE_FFS_MIN = 0xf0
EFI_FV_FILETYPE_FFS_MAX = 0xff
EFI_FV_FILETYPE_FFS_PAD = 0xf0
#
# FFS File Attributes.
#
FFS_ATTRIB_LARGE_FILE = 0x01
FFS_ATTRIB_DATA_ALIGNMENT_2 = 0x02
FFS_ATTRIB_FIXED = 0x04
FFS_ATTRIB_DATA_ALIGNMENT = 0x38
FFS_ATTRIB_CHECKSUM = 0x40
#
# FFS File State Bits.
#
EFI_FILE_HEADER_CONSTRUCTION = 0x01
EFI_FILE_HEADER_VALID = 0x02
EFI_FILE_DATA_VALID = 0x04
EFI_FILE_MARKED_FOR_UPDATE = 0x08
EFI_FILE_DELETED = 0x10
EFI_FILE_HEADER_INVALID = 0x20
class EFI_FFS_FILE_HEADER(Structure):
_fields_ = [
('Name', GUID),
('IntegrityCheck', c_uint16),
('Type', c_uint8),
('Attributes', c_uint8),
('Size', ARRAY(c_uint8, 3)),
('State', c_uint8),
]
class EFI_FFS_FILE_HEADER2(Structure):
_fields_ = [
('Name', GUID),
('IntegrityCheck', c_uint16),
('Type', c_uint8),
('Attributes', c_uint8),
('Size', ARRAY(c_uint8, 3)),
('State', c_uint8),
('ExtendedSize', c_uint64),
]
#
# Pseudo type. It is used as a wild card when retrieving sections.
# The section type EFI_SECTION_ALL matches all section types.
#
EFI_SECTION_ALL = 0x00
#
# Encapsulation section Type values.
#
EFI_SECTION_COMPRESSION = 0x01
EFI_SECTION_GUID_DEFINED = 0x02
EFI_SECTION_DISPOSABLE = 0x03
#
# Leaf section Type values.
#
EFI_SECTION_PE32 = 0x10
EFI_SECTION_PIC = 0x11
EFI_SECTION_TE = 0x12
EFI_SECTION_DXE_DEPEX = 0x13
EFI_SECTION_VERSION = 0x14
EFI_SECTION_USER_INTERFACE = 0x15
EFI_SECTION_COMPATIBILITY16 = 0x16
EFI_SECTION_FIRMWARE_VOLUME_IMAGE = 0x17
EFI_SECTION_FREEFORM_SUBTYPE_GUID = 0x18
EFI_SECTION_RAW = 0x19
EFI_SECTION_PEI_DEPEX = 0x1B
EFI_SECTION_SMM_DEPEX = 0x1C
class EFI_COMMON_SECTION_HEADER(Structure):
_fields_ = [
('Size', ARRAY(c_uint8, 3)),
('Type', c_uint8),
]
class EFI_COMMON_SECTION_HEADER2(Structure):
_fields_ = [
('Size', ARRAY(c_uint8, 3)),
('Type', c_uint8),
('ExtendedSize', c_uint32),
]
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:
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
IMAGE_FILE_MACHINE_I386 = 0x014c
IMAGE_FILE_MACHINE_X64 = 0x8664
EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC = 5
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_DATA_DIRECTORY(Structure):
_fields_ = [
('VirtualAddress', c_uint32),
('Size', c_uint32)
]
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 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_HEADER64(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_NT_HEADERS32(Structure):
_fields_ = [
('Signature', c_uint32),
('FileHeader', EFI_IMAGE_FILE_HEADER),
('OptionalHeader', EFI_IMAGE_OPTIONAL_HEADER32)
]
class EFI_IMAGE_NT_HEADERS64(Structure):
_fields_ = [
('Signature', c_uint32),
('FileHeader', EFI_IMAGE_FILE_HEADER),
('OptionalHeader', EFI_IMAGE_OPTIONAL_HEADER64)
]
class EFI_IMAGE_SECTION_HEADER(Structure):
_fields_ = [
('Name', ARRAY(c_uint8, 8)),
('VirtualSize', c_uint32),
('VirtualAddress', c_uint32),
('SizeOfRawData', c_uint32),
('PointerToRawData', c_uint32),
('PointerToRelocations', c_uint32),
('PointerToLinenumbers', c_uint32),
('NumberOfRelocations', c_uint16),
('NumberOfLinenumbers', c_uint16),
('Characteristics', 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_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 PE_RELOC_BLOCK_HEADER(Structure):
_fields_ = [
('PageRVA', c_uint32),
('BlockSize', c_uint32)
]
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)]
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': # PE32 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.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:
raise Exception("ERROR: Unsupported PE32 image !")
if self.PeHdr.OptionalHeader.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
raise Exception("ERROR: No relocation information available !")
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:
rsize = self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
roffset = self.PeHdr.OptionalHeader.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: # IMAGE_REL_BASED_HIGHLOW
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 == 0x03: # 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
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
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 FileChecker:
def __init__(self):
# sourceRoot == WORKSPACE
# sourceRoot != PACKAGES_PATH
self.RebasePcd = ["", "", "", ""]
self.FvName = ""
self.target = ""
self.sourceRoot = ""
self.reportFile = ""
def GetSectionName(self, line):
splitLine = line[1:-1].split(".")
return splitLine[0]
def IsSyncSection(self, line):
name = self.GetSectionName(line)
for sectionName in self.SyncSectionList:
if (cmp (sectionName, name) == 0) :
return True
return False
def PrintRebasePcd(self, pcd):
print "PCD: " + pcd[0] + "|" + pcd[3] + " <== " + pcd[1] + "(" + pcd[2] + ")"
def RebaseFv(self, fvName, rebasePcd):
sourceFileName = os.path.join(self.sourceRoot,fvName+"\\"+self.target+"\\"+fvName+".fv")
print "rebasing(FV) - " + sourceFileName
try :
file = open(sourceFileName, "rb")
except Exception:
print "fail to open " + sourceFileName
return
try:
buffer = file.read()
data = bytearray(buffer)
file.close()
FvHeader = EFI_FIRMWARE_VOLUME_HEADER.from_buffer (data, 0)
print "HeaderLength - " + hex(FvHeader.HeaderLength)
print "ExtHeaderOffset - " + hex(FvHeader.ExtHeaderOffset)
if (FvHeader.ExtHeaderOffset == 0):
Offset = FvHeader.HeaderLength
else:
FvExHeader = EFI_FIRMWARE_VOLUME_EXT_HEADER.from_buffer(data, FvHeader.ExtHeaderOffset)
print " FvName - %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (FvExHeader.FvName.Guid1, FvExHeader.FvName.Guid2, FvExHeader.FvName.Guid3, FvExHeader.FvName.Guid4[0], FvExHeader.FvName.Guid4[1], FvExHeader.FvName.Guid4[2], FvExHeader.FvName.Guid4[3], FvExHeader.FvName.Guid4[4], FvExHeader.FvName.Guid4[5], FvExHeader.FvName.Guid4[6], FvExHeader.FvName.Guid4[7])
print " ExtHeaderSize - " + hex(FvExHeader.ExtHeaderSize)
Offset = FvHeader.ExtHeaderOffset + FvExHeader.ExtHeaderSize
Offset = (Offset + 0x7) & ~0x7
while (Offset < FvHeader.FvLength) :
FfsHeader = EFI_FFS_FILE_HEADER.from_buffer (data, Offset)
FfsOffset = Offset
FfsSize = FfsHeader.Size[0] + (FfsHeader.Size[1] << 8) + (FfsHeader.Size[2] << 16)
if (FfsSize == 0xFFFFFF) :
break
#print "Ffs - " + hex(FfsOffset)
if (FfsHeader.Type == 0xFF) or (FfsHeader.Type == EFI_FV_FILETYPE_FFS_PAD) :
Offset = (FfsOffset + FfsSize + 7) & ~0x7
continue
print "Ffs - %08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x" % (FfsHeader.Name.Guid1, FfsHeader.Name.Guid2, FfsHeader.Name.Guid3, FfsHeader.Name.Guid4[0], FfsHeader.Name.Guid4[1], FfsHeader.Name.Guid4[2], FfsHeader.Name.Guid4[3], FfsHeader.Name.Guid4[4], FfsHeader.Name.Guid4[5], FfsHeader.Name.Guid4[6], FfsHeader.Name.Guid4[7])
Offset = Offset + sizeof(EFI_FFS_FILE_HEADER)
while (Offset < FfsOffset + FfsSize) :
SectionHeader = EFI_COMMON_SECTION_HEADER.from_buffer (data, Offset)
#print " Section - " + hex(Offset)
if (SectionHeader.Type == EFI_SECTION_PE32) or (SectionHeader.Type == EFI_SECTION_TE) :
PeOffset = Offset + sizeof(EFI_COMMON_SECTION_HEADER)
print " PE - " + hex(PeOffset) + "(" + binascii.hexlify(data[PeOffset:PeOffset+2]) + ")"
newbase = int(rebasePcd[1],16)
oldbase = int(rebasePcd[3],16)
delta = newbase - oldbase
print " delta - " + hex(delta) + "(" + hex(oldbase) + " <== " + hex(newbase) + ")"
PeLength = FfsSize-sizeof(EFI_FFS_FILE_HEADER);
img = PeTeImage(PeOffset, data[PeOffset:PeOffset + PeLength])
img.ParseReloc()
img.Rebase(delta, data)
SectionSize = SectionHeader.Size[0] + (SectionHeader.Size[1] << 8) + (SectionHeader.Size[2] << 16)
Offset = (Offset + SectionSize + 3) & ~0x3
Offset = (FfsOffset + FfsSize + 7) & ~0x7
file = open(sourceFileName, "wb")
file.write(data)
finally:
file.close()
def GetPcdFromReport(self, file, pcd):
FoundPkg = False
pcdSplit = pcd.split(".")
TargetPkg = pcdSplit[0]
TargetPcd = pcdSplit[1]
while 1:
line = file.readline()
if not line:
break
newline = line[:-1]
if (cmp (newline, TargetPkg) == 0):
FoundPkg = True
continue
if (cmp (newline, "") == 0) or ((cmp (newline[0], " ") != 0) and (cmp (newline[0], "0") != 0)):
FoundPkg = False
if (FoundPkg == True) :
newline = newline.strip()
splitLine = newline.split(" ", 2)
if (cmp (splitLine[0], "*F") == 0) or (cmp (splitLine[0], "*P") == 0):
if (cmp (splitLine[1], TargetPcd) == 0):
print "found - " + TargetPkg + "." + TargetPcd
splitLine = splitLine[2].strip()[1:].strip().split(" ", 1)
if (cmp (splitLine[0], "FIXED") == 0) or (cmp (splitLine[0], "PATCH") == 0):
SplitLine = splitLine[1].strip()[1:].split(")", 1)
Type = SplitLine[0]
Value = SplitLine[1].strip()[1:].strip()
print " Type - (" + Type + "), Value - (" + Value + ")"
return [Value, Type]
return ["", ""]
def GetOldFvBase (self, fvName, PcdName):
ParseBase = False
Value = ""
fileName = os.path.join(self.sourceRoot,fvName+"\\"+self.target+"\\"+fvName+".inf")
try :
file = open(fileName)
except Exception:
print "fail to open " + fileName
return
try:
while 1:
line = file.readline()
if not line:
break
newline = line[:-1]
if cmp (newline, "") == 0:
continue
if cmp (newline, "#![Pcd]") == 0:
ParseBase = True
continue
if ParseBase == True :
if (cmp (line[0:2], "#!") != 0) :
ParseBase = False
continue
newline = newline[2:].strip()
splitLine = newline.split("|")
if cmp (PcdName, splitLine[0]) == 0:
Value = splitLine[1]
finally:
file.close()
return Value
def SetNewFvBase (self, fvName, PcdName, OldFvBase, NewFvBase):
fileName = os.path.join(self.sourceRoot,fvName+"\\"+self.target+"\\"+fvName+".inf")
print "update - " + fileName
try :
file = open(fileName, "r")
except Exception:
print "fail to open " + fileName
return
try:
lines = file.readlines()
file.close()
ParseBase = False
for index in range(len(lines)):
line = lines[index]
if not line:
break
newline = line[:-1]
if cmp (newline, "") == 0:
continue
if cmp (newline, "#![Pcd]") == 0:
ParseBase = True
continue
if ParseBase == True :
if (cmp (line[0:2], "#!") != 0) :
ParseBase = False
continue
newline = newline[2:].strip()
splitLine = newline.split("|")
if cmp (PcdName, splitLine[0]) == 0:
if cmp (OldFvBase, splitLine[1]) != 0:
print "ERROR: OldFvBase mismatch!"
else:
lines[index] = "#! " + PcdName + "|" + NewFvBase + "\n"
break
file = open(fileName, "w")
file.writelines(lines)
finally:
file.close()
def GetRebaseAddressFromReport(self):
try :
file = open(self.reportFile)
except Exception:
print "fail to open " + self.reportFile
return
try:
file.seek(0)
print "checking - " + self.RebasePcd[0]
ValuePair = self.GetPcdFromReport (file, self.RebasePcd[0])
self.RebasePcd[1] = ValuePair[0]
self.RebasePcd[2] = ValuePair[1]
finally:
file.close()
def main():
global FileChecker
fileChecker = FileChecker()
if (len(sys.argv) != 6) :
print "usage: RebaseBinFv "
return 0
fileChecker.target = sys.argv[1]
fileChecker.sourceRoot = sys.argv[2]
fileChecker.reportFile = sys.argv[3]
fileChecker.FvName = sys.argv[4]
fileChecker.RebasePcd[0] = sys.argv[5]
fileChecker.GetRebaseAddressFromReport()
fileChecker.RebasePcd[3] = fileChecker.GetOldFvBase (fileChecker.FvName, fileChecker.RebasePcd[0])
fileChecker.PrintRebasePcd(fileChecker.RebasePcd)
fileChecker.RebaseFv (fileChecker.FvName, fileChecker.RebasePcd)
fileChecker.SetNewFvBase (fileChecker.FvName, fileChecker.RebasePcd[0], fileChecker.RebasePcd[3], fileChecker.RebasePcd[1])
if __name__ == '__main__':
sys.exit(main())