## @ 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())