def UpdateDepsFileforTrim(self): """ Update .deps file which generated by trim. """ for abspath in self.deps_files: if not abspath.endswith(".trim.deps"): continue try: newcontent = [] with open(abspath, "r") as fd: lines = fd.readlines() if lines[-1] == DEP_FILE_TAIL: continue source_abs = lines[0].strip().split(" ")[0] targetitem = self.GetRealTarget(source_abs.strip(" :")) targetitem += ": " if len(lines) >= 2: targetitem += lines[1] newcontent.append(targetitem) newcontent.extend(lines[2:]) newcontent.append("\n") newcontent.append(DEP_FILE_TAIL) with open(abspath, "w") as fw: fw.write("".join(newcontent)) except Exception as e: EdkLogger.error("build", FILE_NOT_FOUND, "%s doesn't exist" % abspath, ExtraData=str(e), RaiseError=False) continue
def CreateDepsInclude(self): deps_file = {'deps_file': self.deps_files} MakePath = self.module_autogen.BuildOption.get('MAKE', {}).get('PATH') if not MakePath: EdkLogger.error("build", PARAMETER_MISSING, Message="No Make path available.") elif "nmake" in MakePath: _INCLUDE_DEPS_TEMPLATE = TemplateString(''' ${BEGIN} !IF EXIST(${deps_file}) !INCLUDE ${deps_file} !ENDIF ${END} ''') else: _INCLUDE_DEPS_TEMPLATE = TemplateString(''' ${BEGIN} -include ${deps_file} ${END} ''') try: deps_include_str = _INCLUDE_DEPS_TEMPLATE.Replace(deps_file) except Exception as e: print(e) SaveFileOnChange(os.path.join(self.makefile_folder, "dependency"), deps_include_str, False)
def GetLanguageCode(LangName, IsCompatibleMode, File): length = len(LangName) if IsCompatibleMode: if length == 3 and LangName.isalpha(): TempLangName = LangConvTable.get(LangName.lower()) if TempLangName is not None: return TempLangName return LangName else: EdkLogger.error("Unicode File Parser", FORMAT_INVALID, "Invalid ISO 639-2 language code : %s" % LangName, File) if (LangName[0] == 'X' or LangName[0] == 'x') and LangName[1] == '-': return LangName if length == 2: if LangName.isalpha(): return LangName elif length == 3: if LangName.isalpha() and LangConvTable.get(LangName.lower()) is None: return LangName elif length == 5: if LangName[0:2].isalpha() and LangName[2] == '-': return LangName elif length >= 6: if LangName[0:2].isalpha() and LangName[2] == '-': return LangName if LangName[0:3].isalpha() and LangConvTable.get( LangName.lower()) is None and LangName[3] == '-': return LangName EdkLogger.error("Unicode File Parser", FORMAT_INVALID, "Invalid RFC 4646 language code : %s" % LangName, File)
def Write(self, FilePath): if not (FilePath is not None or len(FilePath) != 0): EdkLogger.error("VpdInfoFile", BuildToolError.PARAMETER_INVALID, "Invalid parameter FilePath: %s." % FilePath) Content = FILE_COMMENT_TEMPLATE Pcds = sorted(self._VpdArray.keys(), key=lambda x: x.TokenCName) for Pcd in Pcds: i = 0 PcdTokenCName = Pcd.TokenCName for PcdItem in GlobalData.MixedPcd: if (Pcd.TokenCName, Pcd.TokenSpaceGuidCName ) in GlobalData.MixedPcd[PcdItem]: PcdTokenCName = PcdItem[0] for skuname in self._VpdArray[Pcd]: PcdValue = str(Pcd.SkuInfoList[skuname].DefaultValue).strip() if PcdValue == "": PcdValue = Pcd.DefaultValue Content += "%s.%s|%s|%s|%s|%s \n" % ( Pcd.TokenSpaceGuidCName, PcdTokenCName, skuname, str(self._VpdArray[Pcd][skuname]).strip(), str(Pcd.MaxDatumSize).strip(), PcdValue) i += 1 return SaveFileOnChange(FilePath, Content, False)
def CallExtenalBPDGTool(ToolPath, VpdFileName): assert ToolPath is not None, "Invalid parameter ToolPath" assert VpdFileName is not None and os.path.exists( VpdFileName), "Invalid parameter VpdFileName" OutputDir = os.path.dirname(VpdFileName) FileName = os.path.basename(VpdFileName) BaseName, ext = os.path.splitext(FileName) OutputMapFileName = os.path.join(OutputDir, "%s.map" % BaseName) OutputBinFileName = os.path.join(OutputDir, "%s.bin" % BaseName) try: PopenObject = subprocess.Popen(' '.join([ ToolPath, '-o', OutputBinFileName, '-m', OutputMapFileName, '-q', '-f', VpdFileName ]), stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) except Exception as X: EdkLogger.error("BPDG", BuildToolError.COMMAND_FAILURE, ExtraData=str(X)) (out, error) = PopenObject.communicate() print(out.decode()) while PopenObject.returncode is None: PopenObject.wait() if PopenObject.returncode != 0: EdkLogger.debug(EdkLogger.DEBUG_1, "Fail to call BPDG tool", str(error)) EdkLogger.error("BPDG", BuildToolError.COMMAND_FAILURE, "Fail to execute BPDG tool with exit code: %d, the error message is: \n %s" % \ (PopenObject.returncode, str(error))) return PopenObject.returncode
def ParseConfig(self): Filepath = os.path.normpath(self.Filename) if not os.path.isfile(Filepath): ErrorMsg = "Can't find configuration file '%s'" % Filepath EdkLogger.error("Ecc", EdkLogger.ECC_ERROR, ErrorMsg, File = Filepath) LineNo = 0 for Line in open(Filepath, 'r'): LineNo = LineNo + 1 Line = CleanString(Line) if Line != '': List = GetSplitValueList(Line, TAB_EQUAL_SPLIT) if List[0] not in _ConfigFileToInternalTranslation: ErrorMsg = "Invalid configuration option '%s' was found" % List[0] EdkLogger.error("Ecc", EdkLogger.ECC_ERROR, ErrorMsg, File = Filepath, Line = LineNo) assert _ConfigFileToInternalTranslation[List[0]] in self.__dict__ if List[0] == 'ModifierList': List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT) if List[0] == 'MetaDataFileCheckPathOfGenerateFileList' and List[1] == "": continue if List[0] == 'SkipDirList': List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT) if List[0] == 'SkipFileList': List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT) if List[0] == 'BinaryExtList': List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT) if List[0] == 'Copyright': List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT) if List[0] == 'TokenReleaceList': List[1] = GetSplitValueList(List[1], TAB_COMMA_SPLIT) self.__dict__[_ConfigFileToInternalTranslation[List[0]]] = List[1]
def Generate(self, File=None): Buffer = BytesIO() if len(self.PostfixNotation) == 0: return False for Item in self.PostfixNotation: if Item in self.Opcode[self.Phase]: Buffer.write(pack("B", self.Opcode[self.Phase][Item])) elif Item in self.SupportedOpcode: EdkLogger.error("GenDepex", FORMAT_INVALID, "Opcode [%s] is not expected in %s phase" % (Item, self.Phase), ExtraData=self.ExpressionString) else: Buffer.write(self.GetGuidValue(Item)) FilePath = "" FileChangeFlag = True if File is None: sys.stdout.write(Buffer.getvalue()) FilePath = "STDOUT" else: FileChangeFlag = SaveFileOnChange(File, Buffer.getvalue(), True) Buffer.close() return FileChangeFlag
def MacroExtend(Str, MacroDict=None, Arch=DataType.TAB_COMMON): if Str is None: return None Dict = { '$(WORKSPACE)': GenFdsGlobalVariable.WorkSpaceDir, # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc, '$(TARGET)': GenFdsGlobalVariable.TargetName, '$(TOOL_CHAIN_TAG)': GenFdsGlobalVariable.ToolChainTag, '$(SPACE)': ' ' } if Arch != DataType.TAB_COMMON and Arch in GenFdsGlobalVariable.ArchList: OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch] else: OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[ GenFdsGlobalVariable.ArchList[0]] Dict['$(OUTPUT_DIRECTORY)'] = OutputDir if MacroDict: Dict.update(MacroDict) for key in Dict: if Str.find(key) >= 0: Str = Str.replace(key, Dict[key]) if Str.find('$(ARCH)') >= 0: if len(GenFdsGlobalVariable.ArchList) == 1: Str = Str.replace('$(ARCH)', GenFdsGlobalVariable.ArchList[0]) else: EdkLogger.error("GenFds", GENFDS_ERROR, "No way to determine $(ARCH) for %s" % Str) return Str
def GetStringObject(self, Item): Language = '' Value = '' Name = Item.split()[1] # Check the string name if Name != '': MatchString = gIdentifierPattern.match(Name) if MatchString is None: EdkLogger.error( 'Unicode File Parser', FORMAT_INVALID, 'The string token name %s defined in UNI file %s contains the invalid character.' % (Name, self.File)) LanguageList = Item.split(u'#language ') for IndexI in range(len(LanguageList)): if IndexI == 0: continue else: Language = LanguageList[IndexI].split()[0] Value = LanguageList[IndexI][ LanguageList[IndexI].find(u'\"') + len(u'\"'): LanguageList[IndexI].rfind(u'\"')] #.replace(u'\r\n', u'') Language = GetLanguageCode(Language, self.IsCompatibleMode, self.File) self.AddStringToList(Name, Language, Value)
def VerifyUcs2Data(FileIn, FileName, Encoding): Ucs2Info = codecs.lookup('ucs-2') # # Convert to unicode # try: FileDecoded = codecs.decode(FileIn, Encoding) Ucs2Info.encode(FileDecoded) except: UniFile = BytesIO(FileIn) Info = codecs.lookup(Encoding) (Reader, Writer) = (Info.streamreader, Info.streamwriter) File = codecs.StreamReaderWriter(UniFile, Reader, Writer) LineNumber = 0 ErrMsg = lambda Encoding, LineNumber: \ '%s contains invalid %s characters on line %d.' % \ (FileName, Encoding, LineNumber) while True: LineNumber = LineNumber + 1 try: Line = File.readline() if Line == '': EdkLogger.error('Unicode File Parser', PARSER_ERROR, ErrMsg(Encoding, LineNumber)) Ucs2Info.encode(Line) except: EdkLogger.error('Unicode File Parser', PARSER_ERROR, ErrMsg('UCS-2', LineNumber))
def GetDepexExpresionList(self): DepexExpressionList = [] if not self._FileSectionDataList: return DepexExpressionList for SectionDataDict in self._FileSectionDataList: for key in SectionDataDict: if key.lower() == "[depex]" or key.lower().startswith( "[depex."): SectionLine = key.lstrip(TAB_SECTION_START).rstrip( TAB_SECTION_END) SubSectionList = [SectionLine] if str(SectionLine).find(TAB_COMMA_SPLIT) > -1: SubSectionList = str(SectionLine).split( TAB_COMMA_SPLIT) for SubSection in SubSectionList: SectionList = SubSection.split(TAB_SPLIT) SubKey = () if len(SectionList) == 1: SubKey = (TAB_ARCH_COMMON, TAB_ARCH_COMMON) elif len(SectionList) == 2: SubKey = (SectionList[1], TAB_ARCH_COMMON) elif len(SectionList) == 3: SubKey = (SectionList[1], SectionList[2]) else: EdkLogger.error("build", AUTOGEN_ERROR, 'Section %s is invalid.' % key) DepexExpressionList.append( {SubKey: SectionDataDict[key]}) return DepexExpressionList
def CheckUsage(Comments, Usages, InfFile, LineNo, Value, ErrorMsg): for Comment in Comments: for Word in Comment[0].replace('#', ' ').split(): if Word in Usages: return EdkLogger.error("Parser", FORMAT_INVALID, ErrorMsg % (InfFile, LineNo, Value))
def TrimPreprocessedVfr(Source, Target): CreateDirectory(os.path.dirname(Target)) try: with open(Source, "r") as File: Lines = File.readlines() except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) # read whole file FoundTypedef = False Brace = 0 TypedefStart = 0 TypedefEnd = 0 for Index in range(len(Lines)): Line = Lines[Index] # don't trim the lines from "formset" definition to the end of file if Line.strip() == 'formset': break if FoundTypedef == False and (Line.find('#line') == 0 or Line.find('# ') == 0): # empty the line number directive if it's not aomong "typedef struct" Lines[Index] = "\n" continue if FoundTypedef == False and gTypedefPattern.search(Line) is None: # keep "#pragram pack" directive if gPragmaPattern.search(Line) is None: Lines[Index] = "\n" continue elif FoundTypedef == False: # found "typedef struct", keept its position and set a flag FoundTypedef = True TypedefStart = Index # match { and } to find the end of typedef definition if Line.find("{") >= 0: Brace += 1 elif Line.find("}") >= 0: Brace -= 1 # "typedef struct" must end with a ";" if Brace == 0 and Line.find(";") >= 0: FoundTypedef = False TypedefEnd = Index # keep all "typedef struct" except to GUID, EFI_PLABEL and PAL_CALL_RETURN if Line.strip("} ;\r\n") in [ TAB_GUID, "EFI_PLABEL", "PAL_CALL_RETURN" ]: for i in range(TypedefStart, TypedefEnd + 1): Lines[i] = "\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 GenerateVfrBinSec(ModuleName, DebugDir, OutputFile): VfrNameList = [] if os.path.isdir(DebugDir): for CurrentDir, Dirs, Files in os.walk(DebugDir): for FileName in Files: Name, Ext = os.path.splitext(FileName) if Ext == '.c' and Name != 'AutoGen': VfrNameList.append (Name + 'Bin') VfrNameList.append (ModuleName + 'Strings') EfiFileName = os.path.join(DebugDir, ModuleName + '.efi') MapFileName = os.path.join(DebugDir, ModuleName + '.map') VfrUniOffsetList = GetVariableOffset(MapFileName, EfiFileName, VfrNameList) if not VfrUniOffsetList: return try: fInputfile = open(OutputFile, "wb+") except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, "File open failed for %s" %OutputFile, None) # Use a instance of BytesIO to cache data fStringIO = BytesIO() for Item in VfrUniOffsetList: if (Item[0].find("Strings") != -1): # # UNI offset in image. # GUID + Offset # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } } # UniGuid = b'\xe0\xc5\x13\x89\xf63\x86M\x9b\xf1C\xef\x89\xfc\x06f' fStringIO.write(UniGuid) UniValue = pack ('Q', int (Item[1], 16)) fStringIO.write (UniValue) else: # # VFR binary offset in image. # GUID + Offset # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } }; # VfrGuid = b'\xb4|\xbc\xd0Gj_I\xaa\x11q\x07F\xda\x06\xa2' fStringIO.write(VfrGuid) type (Item[1]) VfrValue = pack ('Q', int (Item[1], 16)) fStringIO.write (VfrValue) # # write data into file. # try : fInputfile.write (fStringIO.getvalue()) except: EdkLogger.error("Trim", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %OutputFile, None) fStringIO.close () fInputfile.close ()
def GenSection(self, OutputPath, ModuleName, SecNum, keyStringList, FfsFile=None, Dict=None, IsMakefile=False): if self.ExpressionProcessed == False: self.Expression = self.Expression.replace("\n", " ").replace("\r", " ") ExpList = self.Expression.split() for Exp in ExpList: if Exp.upper() not in ('AND', 'OR', 'NOT', 'TRUE', 'FALSE', 'SOR', 'BEFORE', 'AFTER', 'END'): GuidStr = self.__FindGuidValue(Exp) if GuidStr is None: EdkLogger.error( "GenFds", RESOURCE_NOT_AVAILABLE, "Depex GUID %s could not be found in build DB! (ModuleName: %s)" % (Exp, ModuleName)) self.Expression = self.Expression.replace(Exp, GuidStr) self.Expression = self.Expression.strip() self.ExpressionProcessed = True if self.DepexType == 'PEI_DEPEX_EXP': ModuleType = SUP_MODULE_PEIM SecType = BINARY_FILE_TYPE_PEI_DEPEX elif self.DepexType == 'DXE_DEPEX_EXP': ModuleType = SUP_MODULE_DXE_DRIVER SecType = BINARY_FILE_TYPE_DXE_DEPEX elif self.DepexType == 'SMM_DEPEX_EXP': ModuleType = SUP_MODULE_DXE_SMM_DRIVER SecType = BINARY_FILE_TYPE_SMM_DEPEX else: EdkLogger.error( "GenFds", FORMAT_INVALID, "Depex type %s is not valid for module %s" % (self.DepexType, ModuleName)) InputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + '.depex') InputFile = os.path.normpath(InputFile) Depex = DependencyExpression(self.Expression, ModuleType) Depex.Generate(InputFile) OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + '.dpx') OutputFile = os.path.normpath(OutputFile) GenFdsGlobalVariable.GenerateSection( OutputFile, [InputFile], Section.Section.SectionType.get(SecType), IsMakefile=IsMakefile) return [OutputFile], self.Alignment
def AddStringToList(self, Name, Language, Value, Token=None, Referenced=False, UseOtherLangDef='', Index=-1): for LangNameItem in self.LanguageDef: if Language == LangNameItem[0]: break else: EdkLogger.error('Unicode File Parser', FORMAT_NOT_SUPPORTED, "The language '%s' for %s is not defined in Unicode file %s." \ % (Language, Name, self.File)) if Language not in self.OrderedStringList: self.OrderedStringList[Language] = [] self.OrderedStringDict[Language] = {} IsAdded = True if Name in self.OrderedStringDict[Language]: IsAdded = False if Value is not None: ItemIndexInList = self.OrderedStringDict[Language][Name] Item = self.OrderedStringList[Language][ItemIndexInList] Item.UpdateValue(Value) Item.UseOtherLangDef = '' if IsAdded: Token = len(self.OrderedStringList[Language]) if Index == -1: self.OrderedStringList[Language].append( StringDefClassObject(Name, Value, Referenced, Token, UseOtherLangDef)) self.OrderedStringDict[Language][Name] = Token for LangName in self.LanguageDef: # # New STRING token will be added into all language string lists. # so that the unique STRING identifier is reserved for all languages in the package list. # if LangName[0] != Language: if UseOtherLangDef != '': OtherLangDef = UseOtherLangDef else: OtherLangDef = Language self.OrderedStringList[LangName[0]].append( StringDefClassObject(Name, '', Referenced, Token, OtherLangDef)) self.OrderedStringDict[LangName[0]][Name] = len( self.OrderedStringList[LangName[0]]) - 1 else: self.OrderedStringList[Language].insert( Index, StringDefClassObject(Name, Value, Referenced, Token, UseOtherLangDef)) self.OrderedStringDict[Language][Name] = Index
def Main(): EdkLogger.Initialize() Option, Input = GetOptions() # Set log level if Option.quiet: EdkLogger.SetLevel(EdkLogger.QUIET) elif Option.verbose: EdkLogger.SetLevel(EdkLogger.VERBOSE) elif Option.debug is not None: EdkLogger.SetLevel(Option.debug + 1) else: EdkLogger.SetLevel(EdkLogger.INFO) try: if Option.ModuleType is None or Option.ModuleType not in gType2Phase: EdkLogger.error("GenDepex", OPTION_MISSING, "Module type is not specified or supported") DxsFile = '' if len(Input) > 0 and Option.Expression == "": DxsFile = Input[0] DxsString = open(DxsFile, 'r').read().replace("\n", " ").replace("\r", " ") DxsString = gStartClosePattern.sub("\\1", DxsString) elif Option.Expression != "": if Option.Expression[0] == '"': DxsString = Option.Expression[1:-1] else: DxsString = Option.Expression else: EdkLogger.error("GenDepex", OPTION_MISSING, "No expression string or file given") Dpx = DependencyExpression(DxsString, Option.ModuleType, Option.Optimize) if Option.OutputFile is not None: FileChangeFlag = Dpx.Generate(Option.OutputFile) if not FileChangeFlag and DxsFile: # # Touch the output file if its time stamp is older than the original # DXS file to avoid re-invoke this tool for the dependency check in build rule. # if os.stat(DxsFile)[8] > os.stat(Option.OutputFile)[8]: os.utime(Option.OutputFile, None) else: Dpx.Generate() except BaseException as X: EdkLogger.quiet("") if Option is not None and Option.debug is not None: EdkLogger.quiet(traceback.format_exc()) else: EdkLogger.quiet(str(X)) return 1 return 0
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 DetectOnlyScanDirs(self): if self.OnlyScan == True: OnlyScanDirs = [] # Use regex here if multiple spaces or TAB exists in ScanOnlyDirList in config.ini file for folder in re.finditer(r'\S+', EccGlobalData.gConfig.ScanOnlyDirList): OnlyScanDirs.append(folder.group()) if len(OnlyScanDirs) != 0: self.BuildDatabase(OnlyScanDirs) else: EdkLogger.error("ECC", BuildToolError.OPTION_VALUE_INVALID, ExtraData="Use -f option need to fill specific folders in config.ini file") else: self.BuildDatabase()
def ParseInf(self, Lines=[], FileRelativePath='', Filename=''): IfDefList, SectionItemList, CurrentSection, ArchList, ThirdList, IncludeFiles = \ [], [], TAB_UNKNOWN, [], [], [] LineNo = 0 for Line in Lines: LineNo = LineNo + 1 if Line == '': continue if Line.startswith(TAB_SECTION_START) and Line.endswith( TAB_SECTION_END): self.ParserSource(CurrentSection, SectionItemList, ArchList, ThirdList) # Parse the new section SectionItemList = [] ArchList = [] ThirdList = [] # Parse section name CurrentSection = '' LineList = GetSplitValueList( Line[len(TAB_SECTION_START):len(Line) - len(TAB_SECTION_END)], TAB_COMMA_SPLIT) for Item in LineList: ItemList = GetSplitValueList(Item, TAB_SPLIT) if CurrentSection == '': CurrentSection = ItemList[0] else: if CurrentSection != ItemList[0]: EdkLogger.error( "Parser", PARSER_ERROR, "Different section names '%s' and '%s' are found in one section definition, this is not allowed." % (CurrentSection, ItemList[0]), File=Filename, Line=LineNo) ItemList.append('') ItemList.append('') if len(ItemList) > 5: RaiseParserError(Line, CurrentSection, Filename, '', LineNo) else: ArchList.append(ItemList[1].upper()) ThirdList.append(ItemList[2]) continue # Add a section item SectionItemList.append([Line, LineNo]) # End of parse self.ParserSource(CurrentSection, SectionItemList, ArchList, ThirdList)
def _GenOffsetValue(self): if self.PcdOffset != TAB_STAR: try: self.PcdBinOffset = int(self.PcdOffset) except: try: self.PcdBinOffset = int(self.PcdOffset, 16) except: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Invalid offset value %s for PCD %s (File: %s Line: %s)" % (self.PcdOffset, self.PcdCName, self.FileName, self.Lineno))
def _PackPtrValue(self, ValueString, Size): if ValueString.startswith('L"') or ValueString.startswith("L'"): self._PackUnicode(ValueString, Size) elif ValueString.startswith('{') and ValueString.endswith('}'): self._PackByteArray(ValueString, Size) elif (ValueString.startswith('"') and ValueString.endswith('"')) or ( ValueString.startswith("'") and ValueString.endswith("'")): self._PackString(ValueString, Size) else: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Invalid VOID* type PCD %s value %s (File: %s Line: %s)" % (self.PcdCName, ValueString, self.FileName, self.Lineno))
def PreProcess(Filename, MergeMultipleLines=True, LineNo=-1): Lines = [] Filename = os.path.normpath(Filename) if not os.path.isfile(Filename): EdkLogger.error("Eot", EdkLogger.FILE_NOT_FOUND, ExtraData=Filename) IsFindBlockComment = False IsFindBlockCode = False ReservedLine = '' ReservedLineLength = 0 for Line in open(Filename, 'r'): Line = Line.strip() # Remove comment block if Line.find(TAB_COMMENT_EDK_START) > -1: ReservedLine = GetSplitList(Line, TAB_COMMENT_EDK_START, 1)[0] IsFindBlockComment = True if Line.find(TAB_COMMENT_EDK_END) > -1: Line = ReservedLine + GetSplitList(Line, TAB_COMMENT_EDK_END, 1)[1] ReservedLine = '' IsFindBlockComment = False if IsFindBlockComment: Lines.append('') continue # Remove comments at tail and remove spaces again Line = CleanString(Line) if Line == '': Lines.append('') continue if MergeMultipleLines: # Add multiple lines to one line if IsFindBlockCode and Line[-1] != TAB_SLASH: ReservedLine = (ReservedLine + TAB_SPACE_SPLIT + Line).strip() Lines.append(ReservedLine) for Index in (0, ReservedLineLength): Lines.append('') ReservedLine = '' ReservedLineLength = 0 IsFindBlockCode = False continue if Line[-1] == TAB_SLASH: ReservedLine = ReservedLine + TAB_SPACE_SPLIT + Line[ 0:-1].strip() ReservedLineLength = ReservedLineLength + 1 IsFindBlockCode = True continue Lines.append(Line) return Lines
def Main(): try: # # Check input parameter # EdkLogger.Initialize() CommandOptions, InputFile = Options() if CommandOptions.LogLevel < EdkLogger.DEBUG_9: EdkLogger.SetLevel(CommandOptions.LogLevel + 1) else: EdkLogger.SetLevel(CommandOptions.LogLevel) if not os.path.exists(InputFile): EdkLogger.error("PatchPcdValue", FILE_NOT_FOUND, ExtraData=InputFile) return 1 if CommandOptions.PcdOffset is None or CommandOptions.PcdValue is None or CommandOptions.PcdTypeName is None: EdkLogger.error( "PatchPcdValue", OPTION_MISSING, ExtraData= "PcdOffset or PcdValue of PcdTypeName is not specified.") return 1 if CommandOptions.PcdTypeName.upper( ) not in TAB_PCD_NUMERIC_TYPES_VOID: EdkLogger.error("PatchPcdValue", PARAMETER_INVALID, ExtraData="PCD type %s is not valid." % (CommandOptions.PcdTypeName)) return 1 if CommandOptions.PcdTypeName.upper( ) == TAB_VOID and CommandOptions.PcdMaxSize is None: EdkLogger.error( "PatchPcdValue", OPTION_MISSING, ExtraData="PcdMaxSize is not specified for VOID* type PCD.") return 1 # # Patch value into binary image. # ReturnValue, ErrorInfo = PatchBinaryFile(InputFile, CommandOptions.PcdOffset, CommandOptions.PcdTypeName, CommandOptions.PcdValue, CommandOptions.PcdMaxSize) if ReturnValue != 0: EdkLogger.error("PatchPcdValue", ReturnValue, ExtraData=ErrorInfo) return 1 return 0 except: return 1
def Add(self, Vpd, skuname, Offset): if (Vpd is None): EdkLogger.error("VpdInfoFile", BuildToolError.ATTRIBUTE_UNKNOWN_ERROR, "Invalid VPD PCD entry.") if not (Offset >= "0" or Offset == TAB_STAR): EdkLogger.error("VpdInfoFile", BuildToolError.PARAMETER_INVALID, "Invalid offset parameter: %s." % Offset) if Vpd.DatumType == TAB_VOID: if Vpd.MaxDatumSize <= "0": EdkLogger.error( "VpdInfoFile", BuildToolError.PARAMETER_INVALID, "Invalid max datum size for VPD PCD %s.%s" % (Vpd.TokenSpaceGuidCName, Vpd.TokenCName)) elif Vpd.DatumType in TAB_PCD_NUMERIC_TYPES: if not Vpd.MaxDatumSize: Vpd.MaxDatumSize = MAX_SIZE_TYPE[Vpd.DatumType] else: if Vpd.MaxDatumSize <= "0": EdkLogger.error( "VpdInfoFile", BuildToolError.PARAMETER_INVALID, "Invalid max datum size for VPD PCD %s.%s" % (Vpd.TokenSpaceGuidCName, Vpd.TokenCName)) if Vpd not in self._VpdArray: # # If there is no Vpd instance in dict, that imply this offset for a given SKU is a new one # self._VpdArray[Vpd] = {} self._VpdArray[Vpd].update({skuname: Offset})
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 GetGuidValue(self, Guid): GuidValueString = Guid.replace("{", "").replace("}", "").replace(" ", "") GuidValueList = GuidValueString.split(",") if len(GuidValueList) != 11 and len(GuidValueList) == 16: GuidValueString = GuidStringToGuidStructureString( GuidStructureByteArrayToGuidString(Guid)) GuidValueString = GuidValueString.replace("{", "").replace( "}", "").replace(" ", "") GuidValueList = GuidValueString.split(",") if len(GuidValueList) != 11: EdkLogger.error("GenDepex", PARSER_ERROR, "Invalid GUID value string or opcode: %s" % Guid) return pack("1I2H8B", *(int(value, 16) for value in GuidValueList))
def _PackIntValue(self, IntValue, Size): if Size not in _FORMAT_CHAR: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Invalid size %d for PCD %s in integer datum size(File: %s Line: %s)." % (Size, self.PcdCName, self.FileName, self.Lineno)) for Type, MaxSize in MAX_SIZE_TYPE.items(): if Type == 'BOOLEAN': continue if Size == MaxSize: if IntValue < 0: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "PCD can't be set to negative value %d for PCD %s in %s datum type(File: %s Line: %s)." % (IntValue, self.PcdCName, Type, self.FileName, self.Lineno)) elif IntValue > MAX_VAL_TYPE[Type]: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Too large PCD value %d for datum type %s for PCD %s(File: %s Line: %s)." % (IntValue, Type, self.PcdCName, self.FileName, self.Lineno)) try: self.PcdValue = pack(_FORMAT_CHAR[Size], IntValue) except: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno))
def _PackString(self, ValueString, Size): if (Size < 0): EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Invalid parameter Size %s of PCD %s!(File: %s Line: %s)" % (self.PcdBinSize, self.PcdCName, self.FileName, self.Lineno)) if (ValueString == ""): EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Invalid parameter ValueString %s of PCD %s!(File: %s Line: %s)" % (self.PcdUnpackValue, self.PcdCName, self.FileName, self.Lineno)) QuotedFlag = True if ValueString.startswith("'"): QuotedFlag = False ValueString = ValueString[1:-1] # No null-terminator in 'string' if (QuotedFlag and len(ValueString) + 1 > Size) or ( not QuotedFlag and len(ValueString) > Size): EdkLogger.error( "BPDG", BuildToolError.RESOURCE_OVERFLOW, "PCD value string %s is exceed to size %d(File: %s Line: %s)" % (ValueString, Size, self.FileName, self.Lineno)) try: self.PcdValue = pack('%ds' % Size, ValueString.encode('utf-8')) except: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Invalid size or value for PCD %s to pack(File: %s Line: %s)." % (self.PcdCName, self.FileName, self.Lineno))
def UpdateDepsFileforNonMsvc(self): """ Update .deps files. 1. Update target path to absolute path. 2. Update middle target to final target. """ for abspath in self.deps_files: if abspath.endswith(".trim.deps"): continue try: newcontent = [] with open(abspath, "r") as fd: lines = fd.readlines() if lines[-1] == DEP_FILE_TAIL: continue firstlineitems = lines[0].strip().split(" ") if len(firstlineitems) > 2: sourceitem = firstlineitems[1] else: sourceitem = lines[1].strip().split(" ")[0] source_abs = self.SourceFileList.get(sourceitem, sourceitem) firstlineitems[0] = self.GetRealTarget(source_abs) p_target = firstlineitems if not p_target[0].strip().endswith(":"): p_target[0] += ": " if len(p_target) == 2: p_target[0] += lines[1] newcontent.append(p_target[0]) newcontent.extend(lines[2:]) else: line1 = " ".join(p_target).strip() line1 += "\n" newcontent.append(line1) newcontent.extend(lines[1:]) newcontent.append("\n") newcontent.append(DEP_FILE_TAIL) with open(abspath, "w") as fw: fw.write("".join(newcontent)) except Exception as e: EdkLogger.error("build", FILE_NOT_FOUND, "%s doesn't exist" % abspath, ExtraData=str(e), RaiseError=False) continue