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 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] 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 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 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 TAB_STAR to insert into. self.PcdFixedOffsetSizeList.sort(key=lambda x: x.PcdBinOffset) # # Sort the un-fixed pcd's offset by its size. # self.PcdUnknownOffsetList.sort(key=lambda x: x.PcdBinSize) index = 0 for pcd in self.PcdUnknownOffsetList: index += 1 if pcd.PcdCName == ".".join(("gEfiMdeModulePkgTokenSpaceGuid", "PcdNvStoreDefaultValueBuffer")): if index != len(self.PcdUnknownOffsetList): for i in range(len(self.PcdUnknownOffsetList) - index): self.PcdUnknownOffsetList[ index + i - 1], self.PcdUnknownOffsetList[ index + i] = self.PcdUnknownOffsetList[ index + i], self.PcdUnknownOffsetList[index + i - 1] # # Process all Offset value are TAB_STAR # if (len(self.PcdFixedOffsetSizeList) == 0) and (len(self.PcdUnknownOffsetList) != 0): # The offset start from 0 NowOffset = 0 for Pcd in self.PcdUnknownOffsetList: if NowOffset % Pcd.Alignment != 0: NowOffset = (NowOffset // Pcd.Alignment + 1) * Pcd.Alignment 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 == TAB_STAR: if LastOffset % eachUnfixedPcd.Alignment != 0: LastOffset = ( LastOffset // eachUnfixedPcd.Alignment + 1) * eachUnfixedPcd.Alignment # 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, its 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 if NeedFixPcd.PcdBinOffset % NeedFixPcd.Alignment != 0: NeedFixPcd.PcdBinOffset = ( NeedFixPcd.PcdBinOffset // NeedFixPcd.Alignment + 1) * NeedFixPcd.Alignment 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] is 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 is not 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 PCD.Alignment = Alignment if PCD.PcdOffset != TAB_STAR: 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 PackSize = PCD.PcdOccupySize 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 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