X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=BaseTools%2FSource%2FPython%2FGenFds%2FFfsInfStatement.py;h=6f5aac02f54efee40354ff3a20966e9586c9fb7c;hb=0acb3d286258f50aec7dea6f86f4567078705ffa;hp=3d16398c32ce4e5e9422b71ca43723c9dbbe4da1;hpb=e8a47801a1dfdb148b1bfcd5bdc8ebc3bf51f92d;p=mirror_edk2.git diff --git a/BaseTools/Source/Python/GenFds/FfsInfStatement.py b/BaseTools/Source/Python/GenFds/FfsInfStatement.py index 3d16398c32..6f5aac02f5 100644 --- a/BaseTools/Source/Python/GenFds/FfsInfStatement.py +++ b/BaseTools/Source/Python/GenFds/FfsInfStatement.py @@ -1,7 +1,8 @@ ## @file # process FFS generation from INF statement # -# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.
+# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
+# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
# # This program and the accompanying materials # are licensed and made available under the terms and conditions of the BSD License @@ -16,8 +17,7 @@ # Import Modules # import Rule -import os -import shutil +import Common.LongFilePathOs as os import StringIO from struct import * from GenFdsGlobalVariable import GenFdsGlobalVariable @@ -31,6 +31,7 @@ from CommonDataClass.FdfClass import FfsInfStatementClassObject from Common.String import * from Common.Misc import PathClass from Common.Misc import GuidStructureByteArrayToGuidString +from Common.Misc import ProcessDuplicatedInf from Common import EdkLogger from Common.BuildToolError import * from GuidSection import GuidSection @@ -38,11 +39,15 @@ from FvImageSection import FvImageSection from Common.Misc import PeImageClass from AutoGen.GenDepex import DependencyExpression from PatchPcdValue.PatchPcdValue import PatchBinaryFile +from Common.LongFilePathSupport import CopyLongFilePath +from Common.LongFilePathSupport import OpenLongFilePath as open ## generate FFS from INF # # class FfsInfStatement(FfsInfStatementClassObject): + ## The mapping dictionary from datum type to its maximum number. + _MAX_SIZE_TYPE = {"BOOLEAN":0x01, "UINT8":0xFF, "UINT16":0xFFFF, "UINT32":0xFFFFFFFF, "UINT64":0xFFFFFFFFFFFFFFFF} ## The constructor # # @param self The object pointer @@ -61,6 +66,8 @@ class FfsInfStatement(FfsInfStatementClassObject): self.CurrentLineContent = None self.FileName = None self.InfFileName = None + self.OverrideGuid = None + self.PatchedBinFile = '' ## GetFinalTargetSuffixMap() method # @@ -142,7 +149,9 @@ class FfsInfStatement(FfsInfStatementClassObject): GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName) self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '') - if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' : + if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\': + pass + elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' : self.InfFileName = self.InfFileName[1:] if self.InfFileName.find('$') == -1: @@ -161,7 +170,9 @@ class FfsInfStatement(FfsInfStatementClassObject): ErrorCode, ErrorInfo = PathClassObj.Validate(".inf") if ErrorCode != 0: EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) - + + if self.OverrideGuid: + PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir) if self.CurrentArch != None: Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] @@ -196,6 +207,9 @@ class FfsInfStatement(FfsInfStatementClassObject): "INF %s specified in FDF could not be found in build ARCH %s!" \ % (self.InfFileName, GenFdsGlobalVariable.ArchList)) + if self.OverrideGuid: + self.ModuleGuid = self.OverrideGuid + if len(self.SourceFileList) != 0 and not self.InDsc: EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName)) @@ -204,10 +218,15 @@ class FfsInfStatement(FfsInfStatementClassObject): if Inf._Defs != None and len(Inf._Defs) > 0: self.OptRomDefs.update(Inf._Defs) + self.PatchPcds = [] InfPcds = Inf.Pcds Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict + + # Workaround here: both build and GenFds tool convert the workspace path to lower case + # But INF file path in FDF and DSC file may have real case characters. + # Try to convert the path to lower case to see if PCDs value are override by DSC. DscModules = {} for DscModule in Platform.Modules: DscModules[str(DscModule).lower()] = Platform.Modules[DscModule] @@ -217,6 +236,7 @@ class FfsInfStatement(FfsInfStatementClassObject): continue if Pcd.Type != 'PatchableInModule': continue + # Override Patchable PCD value by the value from DSC PatchPcd = None InfLowerPath = str(PathClassObj).lower() if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds: @@ -227,16 +247,22 @@ class FfsInfStatement(FfsInfStatementClassObject): if PatchPcd and Pcd.Type == PatchPcd.Type: DefaultValue = PatchPcd.DefaultValue DscOverride = True + + # Override Patchable PCD value by the value from FDF FdfOverride = False if PcdKey in FdfPcdDict: DefaultValue = FdfPcdDict[PcdKey] FdfOverride = True + if not DscOverride and not FdfOverride: continue + # Check value, if value are equal, no need to patch if Pcd.DatumType == "VOID*": if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']: continue + # Get the string size from FDF or DSC if DefaultValue[0] == 'L': + # Remove L"", but the '\0' must be appended MaxDatumSize = str((len(DefaultValue) - 2) * 2) elif DefaultValue[0] == '{': MaxDatumSize = str(len(DefaultValue.split(','))) @@ -244,6 +270,7 @@ class FfsInfStatement(FfsInfStatementClassObject): MaxDatumSize = str(len(DefaultValue) - 1) if DscOverride: Pcd.MaxDatumSize = PatchPcd.MaxDatumSize + # If no defined the maximum size in DSC, try to get current size from INF if Pcd.MaxDatumSize in ['', None]: Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(','))) else: @@ -259,6 +286,7 @@ class FfsInfStatement(FfsInfStatementClassObject): continue except: continue + # Check the Pcd size and data type if Pcd.DatumType == "VOID*": if int(MaxDatumSize) > int(Pcd.MaxDatumSize): EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \ @@ -268,8 +296,8 @@ class FfsInfStatement(FfsInfStatementClassObject): or PcdValueInImg > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType]: EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \ % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName)) - Pcd.DefaultValue = DefaultValue - self.PatchPcds.append(Pcd) + self.PatchPcds.append((Pcd, DefaultValue)) + self.InfModule = Inf self.PcdIsDriver = Inf.PcdIsDriver self.IsBinaryModule = Inf.IsBinaryModule @@ -291,7 +319,7 @@ class FfsInfStatement(FfsInfStatementClassObject): self.EfiOutputPath = self.__GetEFIOutPutPath__() GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath) -## PatchEfiFile + ## PatchEfiFile # # Patch EFI file with patch PCD # @@ -299,18 +327,25 @@ class FfsInfStatement(FfsInfStatementClassObject): # @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name # If passed in file does not end with efi, return as is # - def PatchEfiFile(self, EfiFile): - if os.path.splitext(EfiFile)[1].lower() != '.efi': - return EfiFile + def PatchEfiFile(self, EfiFile, FileType): if not self.PatchPcds: return EfiFile + if FileType != 'PE32' and self.ModuleType != "USER_DEFINED": + return EfiFile + if self.PatchedBinFile: + EdkLogger.error("GenFds", GENFDS_ERROR, + 'Only one binary file can be patched:\n' + ' a binary file has been patched: %s\n' + ' current file: %s' % (self.PatchedBinFile, EfiFile), + File=self.InfFileName) Basename = os.path.basename(EfiFile) Output = os.path.join(self.OutputPath, Basename) CopyLongFilePath(EfiFile, Output) - for Pcd in self.PatchPcds: - RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Pcd.DefaultValue, Pcd.MaxDatumSize) + for Pcd, Value in self.PatchPcds: + RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize) if RetVal: EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName) + self.PatchedBinFile = os.path.normpath(EfiFile) return Output ## GenFfs() method # @@ -328,11 +363,35 @@ class FfsInfStatement(FfsInfStatementClassObject): # self.__InfParse__(Dict) + SrcFile = os.path.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName); + DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs') + SrcFileDir = "." + SrcPath = os.path.dirname(SrcFile) + SrcFileName = os.path.basename(SrcFile) + SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName) + DestPath = os.path.dirname(DestFile) + DestFileName = os.path.basename(DestFile) + DestFileBase, DestFileExt = os.path.splitext(DestFileName) + self.MacroDict = { + # source file + "${src}" : SrcFile, + "${s_path}" : SrcPath, + "${s_dir}" : SrcFileDir, + "${s_name}" : SrcFileName, + "${s_base}" : SrcFileBase, + "${s_ext}" : SrcFileExt, + # destination file + "${dst}" : DestFile, + "${d_path}" : DestPath, + "${d_name}" : DestFileName, + "${d_base}" : DestFileBase, + "${d_ext}" : DestFileExt + } # # Allow binary type module not specify override rule in FDF file. # - if len(self.BinFileList) >0 and not self.InDsc: + if len(self.BinFileList) > 0: if self.Rule == None or self.Rule == "": self.Rule = "BINARY" @@ -386,6 +445,7 @@ class FfsInfStatement(FfsInfStatementClassObject): '$(NAMED_GUID)' : self.ModuleGuid } String = GenFdsGlobalVariable.MacroExtend(String, MacroDict) + String = GenFdsGlobalVariable.MacroExtend(String, self.MacroDict) return String ## __GetRule__() method @@ -551,6 +611,8 @@ class FfsInfStatement(FfsInfStatementClassObject): (ModulePath, FileName) = os.path.split(self.InfFileName) Index = FileName.rfind('.') FileName = FileName[0:Index] + if self.OverrideGuid: + FileName = self.OverrideGuid Arch = "NoneArch" if self.CurrentArch != None: Arch = self.CurrentArch @@ -632,8 +694,8 @@ class FfsInfStatement(FfsInfStatementClassObject): if not NoStrip: FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc') if not os.path.exists(FileBeforeStrip) or \ - (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): - shutil.copyfile(File, FileBeforeStrip) + (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): + CopyLongFilePath(File, FileBeforeStrip) StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, @@ -671,8 +733,9 @@ class FfsInfStatement(FfsInfStatementClassObject): if not NoStrip: FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc') if not os.path.exists(FileBeforeStrip) or \ - (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)): - shutil.copyfile(GenSecInputFile, FileBeforeStrip) + (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)): + CopyLongFilePath(GenSecInputFile, FileBeforeStrip) + StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile,