def ToCSV(self, Filename='Report.csv'): try: File = open(Filename, 'w+') File.write("""No, Error Code, Error Message, File, LineNo, Other Error Message\n""") RecordSet = self.Query() Index = 0 for Record in RecordSet: Index = Index + 1 ErrorID = Record[1] OtherMsg = Record[2] BelongsToTable = Record[3] BelongsToItem = Record[4] IsCorrected = Record[5] SqlCommand = '' if BelongsToTable == 'File': SqlCommand = """select 1, FullPath from %s where ID = %s """ % (BelongsToTable, BelongsToItem) else: SqlCommand = """select A.StartLine, B.FullPath from %s as A, File as B where A.ID = %s and B.ID = A.BelongsToFile """ % (BelongsToTable, BelongsToItem) NewRecord = self.Exec(SqlCommand) if NewRecord != []: File.write("""%s,%s,"%s",%s,%s,"%s"\n""" % (Index, ErrorID, EccToolError.gEccErrorMessage[ErrorID], NewRecord[0][1], NewRecord[0][0], OtherMsg)) EdkLogger.quiet("%s(%s): [%s]%s %s" % (NewRecord[0][1], NewRecord[0][0], ErrorID, EccToolError.gEccErrorMessage[ErrorID], OtherMsg)) File.close() except IOError: NewFilename = 'Report_' + time.strftime("%Y%m%d_%H%M%S.csv", time.localtime()) EdkLogger.warn("ECC", "The report file %s is locked by other progress, use %s instead!" % (Filename, NewFilename)) self.ToCSV(NewFilename)
def DoInclude(Source, Indent=''): NewFileContent = [] # avoid A "include" B and B "include" A if Source in gIncludedAslFile: EdkLogger.warn("Trim", "Circular include", ExtraData= "%s -> %s" % (" -> ".join(gIncludedAslFile), Source)) return [] gIncludedAslFile.append(Source) try: F = open(Source,'r') except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) for Line in F: Result = gAslIncludePattern.findall(Line) if len(Result) == 0: NewFileContent.append("%s%s" % (Indent, Line)) continue CurrentIndent = Indent + Result[0][0] IncludedFile = Result[0][1] NewFileContent.extend(DoInclude(IncludedFile, CurrentIndent)) gIncludedAslFile.pop() F.close() return NewFileContent
def DoInclude(Source, Indent='', IncludePathList=[], LocalSearchPath=None): NewFileContent = [] try: # # Search LocalSearchPath first if it is specified. # if LocalSearchPath: SearchPathList = [LocalSearchPath] + IncludePathList else: SearchPathList = IncludePathList for IncludePath in SearchPathList: IncludeFile = os.path.join(IncludePath, Source) if os.path.isfile(IncludeFile): try: with open(IncludeFile, "r") as File: F = File.readlines() except: with codecs.open(IncludeFile, "r", encoding='utf-8') as File: F = File.readlines() break else: EdkLogger.error("Trim", "Failed to find include file %s" % Source) except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) # avoid A "include" B and B "include" A IncludeFile = os.path.abspath(os.path.normpath(IncludeFile)) if IncludeFile in gIncludedAslFile: EdkLogger.warn("Trim", "Circular include", ExtraData= "%s -> %s" % (" -> ".join(gIncludedAslFile), IncludeFile)) return [] gIncludedAslFile.append(IncludeFile) for Line in F: LocalSearchPath = None Result = gAslIncludePattern.findall(Line) if len(Result) == 0: Result = gAslCIncludePattern.findall(Line) if len(Result) == 0 or os.path.splitext(Result[0][1])[1].lower() not in [".asl", ".asi"]: NewFileContent.append("%s%s" % (Indent, Line)) continue # # We should first search the local directory if current file are using pattern #include "XXX" # if Result[0][2] == '"': LocalSearchPath = os.path.dirname(IncludeFile) CurrentIndent = Indent + Result[0][0] IncludedFile = Result[0][1] NewFileContent.extend(DoInclude(IncludedFile, CurrentIndent, IncludePathList, LocalSearchPath)) NewFileContent.append("\n") gIncludedAslFile.pop() return NewFileContent
def ParseOption(self): EdkLogger.quiet("Loading ECC configuration ... done") (Options, Target) = self.EccOptionParser() if Options.Workspace: os.environ["WORKSPACE"] = Options.Workspace # Check workspace envirnoment if "WORKSPACE" not in os.environ: EdkLogger.error( "ECC", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found", ExtraData="WORKSPACE" ) else: EccGlobalData.gWorkspace = os.path.normpath(os.getenv("WORKSPACE")) if not os.path.exists(EccGlobalData.gWorkspace): EdkLogger.error( "ECC", BuildToolError.FILE_NOT_FOUND, ExtraData="WORKSPACE = %s" % EccGlobalData.gWorkspace ) os.environ["WORKSPACE"] = EccGlobalData.gWorkspace # Set log level self.SetLogLevel(Options) # Set other options if Options.ConfigFile != None: self.ConfigFile = Options.ConfigFile if Options.OutputFile != None: self.OutputFile = Options.OutputFile if Options.ReportFile != None: self.ReportFile = Options.ReportFile if Options.ExceptionFile != None: self.ExceptionFile = Options.ExceptionFile if Options.Target != None: if not os.path.isdir(Options.Target): EdkLogger.error( "ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Target [%s] does NOT exist" % Options.Target ) else: EccGlobalData.gTarget = self.GetRealPathCase(os.path.normpath(Options.Target)) else: EdkLogger.warn( "Ecc", EdkLogger.ECC_ERROR, "The target source tree was not specified, using current WORKSPACE instead!" ) EccGlobalData.gTarget = os.path.normpath(os.getenv("WORKSPACE")) if Options.keepdatabase != None: self.IsInit = False if Options.metadata != None and Options.sourcecode != None: EdkLogger.error("ECC", BuildToolError.OPTION_CONFLICT, ExtraData="-m and -s can't be specified at one time") if Options.metadata != None: self.ScanSourceCode = False if Options.sourcecode != None: self.ScanMetaData = False if Options.folders != None: self.OnlyScan = True
def TrimAslFile(Source, Target, IncludePathFile,AslDeps = False): CreateDirectory(os.path.dirname(Target)) SourceDir = os.path.dirname(Source) if SourceDir == '': SourceDir = '.' # # Add source directory as the first search directory # IncludePathList = [SourceDir] # # If additional include path file is specified, append them all # to the search directory list. # if IncludePathFile: try: LineNum = 0 with open(IncludePathFile, 'r') as File: FileLines = File.readlines() for Line in FileLines: LineNum += 1 if Line.startswith("/I") or Line.startswith ("-I"): IncludePathList.append(Line[2:].strip()) else: EdkLogger.warn("Trim", "Invalid include line in include list file.", IncludePathFile, LineNum) except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=IncludePathFile) AslIncludes = [] Lines = DoInclude(Source, '', IncludePathList,IncludeFileList=AslIncludes,filetype='ASL') AslIncludes = [item for item in AslIncludes if item !=Source] if AslDeps and AslIncludes: SaveFileOnChange(os.path.join(os.path.dirname(Target),os.path.basename(Source))+".trim.deps", " \\\n".join([Source+":"] +AslIncludes),False) # # Undef MIN and MAX to avoid collision in ASL source code # Lines.insert(0, "#undef MIN\n#undef MAX\n") # save all lines trimmed try: with open(Target, 'w') as File: File.writelines(Lines) except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)
def ParseOption(self): (Options, Target) = self.EccOptionParser() if Options.Workspace: os.environ["WORKSPACE"] = Options.Workspace # Check workspace environment if "WORKSPACE" not in os.environ: EdkLogger.error("ECC", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found", ExtraData="WORKSPACE") else: EccGlobalData.gWorkspace = os.path.normpath(os.getenv("WORKSPACE")) if not os.path.exists(EccGlobalData.gWorkspace): EdkLogger.error("ECC", BuildToolError.FILE_NOT_FOUND, ExtraData="WORKSPACE = %s" % EccGlobalData.gWorkspace) os.environ["WORKSPACE"] = EccGlobalData.gWorkspace # Set log level self.SetLogLevel(Options) # Set other options if Options.ConfigFile is not None: self.ConfigFile = Options.ConfigFile if Options.OutputFile is not None: self.OutputFile = Options.OutputFile if Options.ReportFile is not None: self.ReportFile = Options.ReportFile if Options.ExceptionFile is not None: self.ExceptionFile = Options.ExceptionFile if Options.Target is not None: if not os.path.isdir(Options.Target): EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Target [%s] does NOT exist" % Options.Target) else: EccGlobalData.gTarget = self.GetRealPathCase(os.path.normpath(Options.Target)) else: EdkLogger.warn("Ecc", EdkLogger.ECC_ERROR, "The target source tree was not specified, using current WORKSPACE instead!") EccGlobalData.gTarget = os.path.normpath(os.getenv("WORKSPACE")) if Options.keepdatabase is not None: self.IsInit = False if Options.metadata is not None and Options.sourcecode is not None: EdkLogger.error("ECC", BuildToolError.OPTION_CONFLICT, ExtraData="-m and -s can't be specified at one time") if Options.metadata is not None: self.ScanSourceCode = False if Options.sourcecode is not None: self.ScanMetaData = False if Options.folders is not None: self.OnlyScan = True
def ToCSV(self, Filename='Report.csv'): try: File = open(Filename, 'w+') File.write( """No, Error Code, Error Message, File, LineNo, Other Error Message\n""" ) RecordSet = self.Query() Index = 0 for Record in RecordSet: Index = Index + 1 ErrorID = Record[1] OtherMsg = Record[2] BelongsToTable = Record[3] BelongsToItem = Record[4] IsCorrected = Record[5] SqlCommand = '' if BelongsToTable == 'File': SqlCommand = """select 1, FullPath from %s where ID = %s """ % (BelongsToTable, BelongsToItem) else: SqlCommand = """select A.StartLine, B.FullPath from %s as A, File as B where A.ID = %s and B.ID = A.BelongsToFile """ % (BelongsToTable, BelongsToItem) NewRecord = self.Exec(SqlCommand) if NewRecord != []: File.write("""%s,%s,"%s",%s,%s,"%s"\n""" % (Index, ErrorID, EccToolError.gEccErrorMessage[ErrorID], NewRecord[0][1], NewRecord[0][0], OtherMsg)) EdkLogger.quiet( "%s(%s): [%s]%s %s" % (NewRecord[0][1], NewRecord[0][0], ErrorID, EccToolError.gEccErrorMessage[ErrorID], OtherMsg)) File.close() except IOError: NewFilename = 'Report_' + time.strftime("%Y%m%d_%H%M%S.csv", time.localtime()) EdkLogger.warn( "ECC", "The report file %s is locked by other progress, use %s instead!" % (Filename, NewFilename)) self.ToCSV(NewFilename)
def TrimAslFile(Source, Target, IncludePathFile): CreateDirectory(os.path.dirname(Target)) SourceDir = os.path.dirname(Source) if SourceDir == '': SourceDir = '.' # # Add source directory as the first search directory # IncludePathList = [SourceDir] # # If additional include path file is specified, append them all # to the search directory list. # if IncludePathFile: try: LineNum = 0 for Line in open(IncludePathFile,'r'): LineNum += 1 if Line.startswith("/I") or Line.startswith ("-I"): IncludePathList.append(Line[2:].strip()) else: EdkLogger.warn("Trim", "Invalid include line in include list file.", IncludePathFile, LineNum) except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=IncludePathFile) Lines = DoInclude(Source, '', IncludePathList) # # Undef MIN and MAX to avoid collision in ASL source code # Lines.insert(0, "#undef MIN\n#undef MAX\n") # save all lines trimmed try: f = open (Target,'w') except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target) f.writelines(Lines) f.close()
def FixVpdOffset (self): # At first, the offset should start at 0 # Sort fixed offset list in order to find out where has free spaces for the pcd's offset # value is "*" to insert into. self.PcdFixedOffsetSizeList.sort(lambda x, y: cmp(x.PcdBinOffset, y.PcdBinOffset)) # # Sort the un-fixed pcd's offset by it's size. # self.PcdUnknownOffsetList.sort(lambda x, y: cmp(x.PcdBinSize, y.PcdBinSize)) # # Process all Offset value are "*" # if (len(self.PcdFixedOffsetSizeList) == 0) and (len(self.PcdUnknownOffsetList) != 0) : # The offset start from 0 NowOffset = 0 for Pcd in self.PcdUnknownOffsetList : Pcd.PcdBinOffset = NowOffset Pcd.PcdOffset = str(hex(Pcd.PcdBinOffset)) NowOffset += Pcd.PcdOccupySize self.PcdFixedOffsetSizeList = self.PcdUnknownOffsetList return # Check the offset of VPD type pcd's offset start from 0. if self.PcdFixedOffsetSizeList[0].PcdBinOffset != 0 : EdkLogger.warn("BPDG", "The offset of VPD type pcd should start with 0, please check it.", None) # Judge whether the offset in fixed pcd offset list is overlapped or not. lenOfList = len(self.PcdFixedOffsetSizeList) count = 0 while (count < lenOfList - 1) : PcdNow = self.PcdFixedOffsetSizeList[count] PcdNext = self.PcdFixedOffsetSizeList[count+1] # Two pcd's offset is same if PcdNow.PcdBinOffset == PcdNext.PcdBinOffset : EdkLogger.error("BPDG", BuildToolError.ATTRIBUTE_GET_FAILURE, "The offset of %s at line: %s is same with %s at line: %s in file %s" % \ (PcdNow.PcdCName, PcdNow.Lineno, PcdNext.PcdCName, PcdNext.Lineno, PcdNext.FileName), None) # Overlapped if PcdNow.PcdBinOffset + PcdNow.PcdOccupySize > PcdNext.PcdBinOffset : EdkLogger.error("BPDG", BuildToolError.ATTRIBUTE_GET_FAILURE, "The offset of %s at line: %s is overlapped with %s at line: %s in file %s" % \ (PcdNow.PcdCName, PcdNow.Lineno, PcdNext.PcdCName, PcdNext.Lineno, PcdNext.FileName), None) # Has free space, raise a warning message if PcdNow.PcdBinOffset + PcdNow.PcdOccupySize < PcdNext.PcdBinOffset : EdkLogger.warn("BPDG", BuildToolError.ATTRIBUTE_GET_FAILURE, "The offsets have free space of between %s at line: %s and %s at line: %s in file %s" % \ (PcdNow.PcdCName, PcdNow.Lineno, PcdNext.PcdCName, PcdNext.Lineno, PcdNext.FileName), None) count += 1 LastOffset = self.PcdFixedOffsetSizeList[0].PcdBinOffset FixOffsetSizeListCount = 0 lenOfList = len(self.PcdFixedOffsetSizeList) lenOfUnfixedList = len(self.PcdUnknownOffsetList) ## # Insert the un-fixed offset pcd's list into fixed offset pcd's list if has free space between those pcds. # while (FixOffsetSizeListCount < lenOfList) : eachFixedPcd = self.PcdFixedOffsetSizeList[FixOffsetSizeListCount] NowOffset = eachFixedPcd.PcdBinOffset # Has free space if LastOffset < NowOffset : if lenOfUnfixedList != 0 : countOfUnfixedList = 0 while(countOfUnfixedList < lenOfUnfixedList) : eachUnfixedPcd = self.PcdUnknownOffsetList[countOfUnfixedList] needFixPcdSize = eachUnfixedPcd.PcdOccupySize # Not been fixed if eachUnfixedPcd.PcdOffset == '*' : # The offset un-fixed pcd can write into this free space if needFixPcdSize <= (NowOffset - LastOffset) : # Change the offset value of un-fixed pcd eachUnfixedPcd.PcdOffset = str(hex(LastOffset)) eachUnfixedPcd.PcdBinOffset = LastOffset # Insert this pcd into fixed offset pcd list. self.PcdFixedOffsetSizeList.insert(FixOffsetSizeListCount,eachUnfixedPcd) # Delete the item's offset that has been fixed and added into fixed offset list self.PcdUnknownOffsetList.pop(countOfUnfixedList) # After item added, should enlarge the length of fixed pcd offset list lenOfList += 1 FixOffsetSizeListCount += 1 # Decrease the un-fixed pcd offset list's length lenOfUnfixedList -= 1 # Modify the last offset value LastOffset += needFixPcdSize else : # It can not insert into those two pcds, need to check still has other space can store it. LastOffset = NowOffset + self.PcdFixedOffsetSizeList[FixOffsetSizeListCount].PcdOccupySize FixOffsetSizeListCount += 1 break # Set the FixOffsetSizeListCount = lenOfList for quit the loop else : FixOffsetSizeListCount = lenOfList # No free space, smoothly connect with previous pcd. elif LastOffset == NowOffset : LastOffset = NowOffset + eachFixedPcd.PcdOccupySize FixOffsetSizeListCount += 1 # Usually it will not enter into this thunk, if so, means it overlapped. else : EdkLogger.error("BPDG", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "The offset value definition has overlapped at pcd: %s, it's offset is: %s, in file: %s line: %s" % \ (eachFixedPcd.PcdCName, eachFixedPcd.PcdOffset, eachFixedPcd.InputFileName, eachFixedPcd.Lineno), None) FixOffsetSizeListCount += 1 # Continue to process the un-fixed offset pcd's list, add this time, just append them behind the fixed pcd's offset list. lenOfUnfixedList = len(self.PcdUnknownOffsetList) lenOfList = len(self.PcdFixedOffsetSizeList) while (lenOfUnfixedList > 0) : # Still has items need to process # The last pcd instance LastPcd = self.PcdFixedOffsetSizeList[lenOfList-1] NeedFixPcd = self.PcdUnknownOffsetList[0] NeedFixPcd.PcdBinOffset = LastPcd.PcdBinOffset + LastPcd.PcdOccupySize NeedFixPcd.PcdOffset = str(hex(NeedFixPcd.PcdBinOffset)) # Insert this pcd into fixed offset pcd list's tail. self.PcdFixedOffsetSizeList.insert(lenOfList, NeedFixPcd) # Delete the item's offset that has been fixed and added into fixed offset list self.PcdUnknownOffsetList.pop(0) lenOfList += 1 lenOfUnfixedList -= 1
def ParserInputFile (self): count = 0 for line in self.FileLinesList: # Strip "\r\n" generated by readlines (). line = line.strip() line = line.rstrip(os.linesep) # Skip the comment line if (not line.startswith("#")) and len(line) > 1 : # # Enhanced for support "|" character in the string. # ValueList = ['', '', '', '',''] ValueRe = re.compile(r'\s*L?\".*\|.*\"\s*$') PtrValue = ValueRe.findall(line) ValueUpdateFlag = False if len(PtrValue) >= 1: line = re.sub(ValueRe, '', line) ValueUpdateFlag = True TokenList = line.split('|') ValueList[0:len(TokenList)] = TokenList if ValueUpdateFlag: ValueList[4] = PtrValue[0] self.FileLinesList[count] = ValueList # Store the line number self.FileLinesList[count].append(str(count + 1)) elif len(line) <= 1 : # Set the blank line to "None" self.FileLinesList[count] = None else : # Set the comment line to "None" self.FileLinesList[count] = None count += 1 # The line count contain usage information count = 0 # Delete useless lines while (True) : try : if (self.FileLinesList[count] == None) : del(self.FileLinesList[count]) else : count += 1 except : break # # After remove the useless line, if there are no data remain in the file line list, # Report warning messages to user's. # if len(self.FileLinesList) == 0 : EdkLogger.warn('BPDG', BuildToolError.RESOURCE_NOT_AVAILABLE, "There are no VPD type pcds defined in DSC file, Please check it.") # Process the pcds one by one base on the pcd's value and size count = 0 for line in self.FileLinesList: if line != None : PCD = PcdEntry(line[0], line[1], line[2], line[3], line[4],line[5], self.InputFileName) # Strip the space char PCD.PcdCName = PCD.PcdCName.strip(' ') PCD.SkuId = PCD.SkuId.strip(' ') PCD.PcdOffset = PCD.PcdOffset.strip(' ') PCD.PcdSize = PCD.PcdSize.strip(' ') PCD.PcdValue = PCD.PcdValue.strip(' ') PCD.Lineno = PCD.Lineno.strip(' ') # # Store the original pcd value. # This information will be useful while generate the output map file. # PCD.PcdUnpackValue = str(PCD.PcdValue) # # Translate PCD size string to an integer value. PackSize = None try: PackSize = int(PCD.PcdSize, 10) PCD.PcdBinSize = PackSize except: try: PackSize = int(PCD.PcdSize, 16) PCD.PcdBinSize = PackSize except: EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "Invalid PCD size value %s at file: %s line: %s" % (PCD.PcdSize, self.InputFileName, PCD.Lineno)) # # If value is Unicode string (e.g. L""), then use 2-byte alignment # If value is byte array (e.g. {}), then use 8-byte alignment # PCD.PcdOccupySize = PCD.PcdBinSize if PCD.PcdUnpackValue.startswith("{"): Alignment = 8 elif PCD.PcdUnpackValue.startswith("L"): Alignment = 2 else: Alignment = 1 if PCD.PcdOffset != '*': if PCD.PcdOccupySize % Alignment != 0: if PCD.PcdUnpackValue.startswith("{"): EdkLogger.warn("BPDG", "The offset value of PCD %s is not 8-byte aligned!" %(PCD.PcdCName), File=self.InputFileName) else: EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, 'The offset value of PCD %s should be %s-byte aligned.' % (PCD.PcdCName, Alignment)) else: if PCD.PcdOccupySize % Alignment != 0: PCD.PcdOccupySize = (PCD.PcdOccupySize / Alignment + 1) * Alignment if PCD._IsBoolean(PCD.PcdValue, PCD.PcdSize): PCD._PackBooleanValue(PCD.PcdValue) self.FileLinesList[count] = PCD count += 1 continue # # Try to translate value to an integer firstly. # IsInteger = True PackValue = None try: PackValue = int(PCD.PcdValue) except: try: PackValue = int(PCD.PcdValue, 16) except: IsInteger = False if IsInteger: PCD._PackIntValue(PackValue, PackSize) else: PCD._PackPtrValue(PCD.PcdValue, PackSize) self.FileLinesList[count] = PCD count += 1 else : continue
def __InfParse__(self, Dict = {}): GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName) self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '') if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' : self.InfFileName = self.InfFileName[1:] if self.InfFileName.find('$') == -1: InfPath = NormPath(self.InfFileName) if not os.path.exists(InfPath): InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath) if not os.path.exists(InfPath): EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName)) self.CurrentArch = self.GetCurrentArch() # # Get the InfClass object # PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) ErrorCode, ErrorInfo = PathClassObj.Validate(".inf") if ErrorCode != 0: EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) if self.CurrentArch != None: Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] # # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath # self.BaseName = Inf.BaseName self.ModuleGuid = Inf.Guid self.ModuleType = Inf.ModuleType if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification: self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION'] if Inf.AutoGenVersion < 0x00010005: self.ModuleType = Inf.ComponentType self.VersionString = Inf.Version self.BinFileList = Inf.Binaries self.SourceFileList = Inf.Sources if self.KeepReloc == None and Inf.Shadow: self.ShadowFromInfFile = Inf.Shadow else: Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] self.BaseName = Inf.BaseName self.ModuleGuid = Inf.Guid self.ModuleType = Inf.ModuleType if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification: self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION'] self.VersionString = Inf.Version self.BinFileList = Inf.Binaries self.SourceFileList = Inf.Sources if self.BinFileList == []: EdkLogger.error("GenFds", GENFDS_ERROR, "INF %s specified in FDF could not be found in build ARCH %s!" \ % (self.InfFileName, GenFdsGlobalVariable.ArchList)) 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)) if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A: EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName) 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] for PcdKey in InfPcds: Pcd = InfPcds[PcdKey] if not hasattr(Pcd, 'Offset'): 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: PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey] elif PcdKey in Platform.Pcds: PatchPcd = Platform.Pcds[PcdKey] DscOverride = False 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(','))) else: 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: Base1 = Base2 = 10 if Pcd.DefaultValue.upper().startswith('0X'): Base1 = 16 if DefaultValue.upper().startswith('0X'): Base2 = 16 try: PcdValueInImg = int(Pcd.DefaultValue, Base1) PcdValueInDscOrFdf = int(DefaultValue, Base2) if PcdValueInImg == PcdValueInDscOrFdf: 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." \ % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize))) else: if PcdValueInDscOrFdf > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType] \ 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.InfModule = Inf self.PcdIsDriver = Inf.PcdIsDriver self.IsBinaryModule = Inf.IsBinaryModule GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName) GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid) GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType) GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString) GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName) # # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\ # self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \ self.ModuleGuid + self.BaseName) if not os.path.exists(self.OutputPath) : os.makedirs(self.OutputPath) self.EfiOutputPath = self.__GetEFIOutPutPath__() GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
def DoInclude(Source, Indent='', IncludePathList=[], LocalSearchPath=None, IncludeFileList = None, filetype=None): NewFileContent = [] if IncludeFileList is None: IncludeFileList = [] try: # # Search LocalSearchPath first if it is specified. # if LocalSearchPath: SearchPathList = [LocalSearchPath] + IncludePathList else: SearchPathList = IncludePathList for IncludePath in SearchPathList: IncludeFile = os.path.join(IncludePath, Source) if os.path.isfile(IncludeFile): try: with open(IncludeFile, "r") as File: F = File.readlines() except: with codecs.open(IncludeFile, "r", encoding='utf-8') as File: F = File.readlines() break else: EdkLogger.warn("Trim", "Failed to find include file %s" % Source) return [] except: EdkLogger.warn("Trim", FILE_OPEN_FAILURE, ExtraData=Source) return [] # avoid A "include" B and B "include" A IncludeFile = os.path.abspath(os.path.normpath(IncludeFile)) if IncludeFile in gIncludedAslFile: EdkLogger.warn("Trim", "Circular include", ExtraData= "%s -> %s" % (" -> ".join(gIncludedAslFile), IncludeFile)) return [] gIncludedAslFile.append(IncludeFile) IncludeFileList.append(IncludeFile.strip()) for Line in F: LocalSearchPath = None if filetype == "ASL": Result = gAslIncludePattern.findall(Line) if len(Result) == 0: Result = gAslCIncludePattern.findall(Line) if len(Result) == 0 or os.path.splitext(Result[0][1])[1].lower() not in [".asl", ".asi"]: NewFileContent.append("%s%s" % (Indent, Line)) continue # # We should first search the local directory if current file are using pattern #include "XXX" # if Result[0][2] == '"': LocalSearchPath = os.path.dirname(IncludeFile) CurrentIndent = Indent + Result[0][0] IncludedFile = Result[0][1] NewFileContent.extend(DoInclude(IncludedFile, CurrentIndent, IncludePathList, LocalSearchPath,IncludeFileList,filetype)) NewFileContent.append("\n") elif filetype == "ASM": Result = gIncludePattern.findall(Line) if len(Result) == 0: NewFileContent.append("%s%s" % (Indent, Line)) continue IncludedFile = Result[0] IncludedFile = IncludedFile.strip() IncludedFile = os.path.normpath(IncludedFile) NewFileContent.extend(DoInclude(IncludedFile, '', IncludePathList, LocalSearchPath,IncludeFileList,filetype)) NewFileContent.append("\n") gIncludedAslFile.pop() return NewFileContent
def __InfParse__(self, Dict = {}): GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName) self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '') 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: InfPath = NormPath(self.InfFileName) if not os.path.exists(InfPath): InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath) if not os.path.exists(InfPath): EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName)) self.CurrentArch = self.GetCurrentArch() # # Get the InfClass object # PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) 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] # # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath # self.BaseName = Inf.BaseName self.ModuleGuid = Inf.Guid self.ModuleType = Inf.ModuleType if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification: self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION'] if Inf.AutoGenVersion < 0x00010005: self.ModuleType = Inf.ComponentType self.VersionString = Inf.Version self.BinFileList = Inf.Binaries self.SourceFileList = Inf.Sources if self.KeepReloc == None and Inf.Shadow: self.ShadowFromInfFile = Inf.Shadow else: Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] self.BaseName = Inf.BaseName self.ModuleGuid = Inf.Guid self.ModuleType = Inf.ModuleType if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification: self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION'] self.VersionString = Inf.Version self.BinFileList = Inf.Binaries self.SourceFileList = Inf.Sources if self.BinFileList == []: EdkLogger.error("GenFds", GENFDS_ERROR, "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)) if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A: EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName) 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] for PcdKey in InfPcds: Pcd = InfPcds[PcdKey] if not hasattr(Pcd, 'Offset'): 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: PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey] elif PcdKey in Platform.Pcds: PatchPcd = Platform.Pcds[PcdKey] DscOverride = False 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(','))) else: 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: Base1 = Base2 = 10 if Pcd.DefaultValue.upper().startswith('0X'): Base1 = 16 if DefaultValue.upper().startswith('0X'): Base2 = 16 try: PcdValueInImg = int(Pcd.DefaultValue, Base1) PcdValueInDscOrFdf = int(DefaultValue, Base2) if PcdValueInImg == PcdValueInDscOrFdf: 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." \ % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize))) else: if PcdValueInDscOrFdf > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType] \ 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)) self.PatchPcds.append((Pcd, DefaultValue)) self.InfModule = Inf self.PcdIsDriver = Inf.PcdIsDriver self.IsBinaryModule = Inf.IsBinaryModule GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName) GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid) GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType) GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString) GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName) # # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\ # self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \ self.ModuleGuid + self.BaseName) if not os.path.exists(self.OutputPath) : os.makedirs(self.OutputPath) self.EfiOutputPath = self.__GetEFIOutPutPath__() GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
def __InfParse__(self, Dict = {}): GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName) self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '') if self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' : self.InfFileName = self.InfFileName[1:] if self.InfFileName.find('$') == -1: InfPath = NormPath(self.InfFileName) if not os.path.exists(InfPath): InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath) if not os.path.exists(InfPath): EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName)) self.CurrentArch = self.GetCurrentArch() # # Get the InfClass object # PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir) ErrorCode, ErrorInfo = PathClassObj.Validate(".inf") if ErrorCode != 0: EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo) if self.CurrentArch != None: Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] # # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath # self.BaseName = Inf.BaseName self.ModuleGuid = Inf.Guid self.ModuleType = Inf.ModuleType if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification: self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION'] if Inf.AutoGenVersion < 0x00010005: self.ModuleType = Inf.ComponentType self.VersionString = Inf.Version self.BinFileList = Inf.Binaries self.SourceFileList = Inf.Sources if self.KeepReloc == None and Inf.Shadow: self.ShadowFromInfFile = Inf.Shadow else: Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] self.BaseName = Inf.BaseName self.ModuleGuid = Inf.Guid self.ModuleType = Inf.ModuleType if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification: self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION'] self.VersionString = Inf.Version self.BinFileList = Inf.Binaries self.SourceFileList = Inf.Sources if self.BinFileList == []: EdkLogger.error("GenFds", GENFDS_ERROR, "INF %s specified in FDF could not be found in build ARCH %s!" \ % (self.InfFileName, GenFdsGlobalVariable.ArchList)) 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)) if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A: EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "SMM_CORE module type can't be used in the module with PI_SPECIFICATION_VERSION less than 0x0001000A", File=self.InfFileName) if Inf._Defs != None and len(Inf._Defs) > 0: self.OptRomDefs.update(Inf._Defs) self.InfModule = Inf GenFdsGlobalVariable.VerboseLogger( "BaseName : %s" %self.BaseName) GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" %self.ModuleGuid) GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" %self.ModuleType) GenFdsGlobalVariable.VerboseLogger("VersionString : %s" %self.VersionString) GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" %self.InfFileName) # # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\ # self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \ self.ModuleGuid + self.BaseName) if not os.path.exists(self.OutputPath) : os.makedirs(self.OutputPath) self.EfiOutputPath = self.__GetEFIOutPutPath__() GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)