def __GenSimpleFileFfs__(self, Rule, InputFileList): FfsOutput = self.OutputPath + \ os.sep + \ self.__ExtendMacro__(Rule.NameGuid) + \ '.ffs' GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid)) InputSection = [] SectionAlignments = [] for InputFile in InputFileList: InputSection.append(InputFile) SectionAlignments.append(Rule.SectAlignment) if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('): PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid) if len(PcdValue) == 0: EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ % (Rule.NameGuid)) if PcdValue.startswith('{'): PcdValue = GuidStructureByteArrayToGuidString(PcdValue) RegistryGuidStr = PcdValue if len(RegistryGuidStr) == 0: EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ % (Rule.NameGuid)) self.ModuleGuid = RegistryGuidStr GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection, Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType], self.ModuleGuid, Fixed=Rule.Fixed, CheckSum=Rule.CheckSum, Align=Rule.Alignment, SectionAlign=SectionAlignments ) return FfsOutput
def Capacity(self): if self._Capacity is None: self._Capacity = [] dimension = ArrayIndex.findall(self._DatumType) for item in dimension: maxsize = item.lstrip("[").rstrip("]").strip() if not maxsize: maxsize = "-1" maxsize = str(int(maxsize,16)) if maxsize.startswith(("0x","0X")) else maxsize self._Capacity.append(maxsize) if hasattr(self, "SkuOverrideValues"): for sku in self.SkuOverrideValues: for defaultstore in self.SkuOverrideValues[sku]: fields = self.SkuOverrideValues[sku][defaultstore] for demesionattr in fields: fieldinfo = fields[demesionattr] deme = ArrayIndex.findall(demesionattr) for i in range(len(deme)): if int(deme[i].lstrip("[").rstrip("]").strip()) >= int(self._Capacity[i]): if self._Capacity[i] != "-1": firstfieldinfo = list(fieldinfo.values())[0] EdkLogger.error('Build', OPTION_VALUE_INVALID, "For Pcd %s, Array Index exceed the Array size. From %s Line %s \n " % (".".join((self.TokenSpaceGuidCName, self.TokenCName)), firstfieldinfo[1],firstfieldinfo[2] )) if hasattr(self,"DefaultValues"): for demesionattr in self.DefaultValues: fieldinfo = self.DefaultValues[demesionattr] deme = ArrayIndex.findall(demesionattr) for i in range(len(deme)): if int(deme[i].lstrip("[").rstrip("]").strip()) >= int(self._Capacity[i]): if self._Capacity[i] != "-1": firstfieldinfo = list(fieldinfo.values())[0] EdkLogger.error('Build', OPTION_VALUE_INVALID, "For Pcd %s, Array Index exceed the Array size. From %s Line %s \n " % (".".join((self.TokenSpaceGuidCName, self.TokenCName)), firstfieldinfo[1],firstfieldinfo[2] )) return self._Capacity
def GetStringObject(self, Item): Language = '' Value = '' Name = Item.split()[1] # Check the string name is the upper character if Name != '': MatchString = re.match('[A-Z0-9_]+', Name, re.UNICODE) if MatchString == None or MatchString.end(0) != len(Name): EdkLogger.error( 'Unicode File Parser', FORMAT_INVALID, 'The string token name %s defined in UNI file %s contains the invalid lower case 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 _ParserInf(self): FileLinesList = [] UserExtFind = False FindEnd = True FileLastLine = False SectionLine = '' SectionData = [] try: FileLinesList = open(self._FilePath, "r", 0).readlines() except BaseException: EdkLogger.error("build", AUTOGEN_ERROR, 'File %s is opened failed.' % self._FilePath) for Index in range(0, len(FileLinesList)): line = str(FileLinesList[Index]).strip() if Index + 1 == len(FileLinesList): FileLastLine = True NextLine = '' else: NextLine = str(FileLinesList[Index + 1]).strip() if UserExtFind and FindEnd == False: if line: SectionData.append(line) if line.startswith(TAB_SECTION_START) and line.endswith(TAB_SECTION_END): SectionLine = line UserExtFind = True FindEnd = False if (NextLine != '' and NextLine[0] == TAB_SECTION_START and \ NextLine[-1] == TAB_SECTION_END) or FileLastLine: UserExtFind = False FindEnd = True self._FileSectionDataList.append({SectionLine: SectionData[:]}) del SectionData[:] SectionLine = ''
def Options(): OptionList = [ make_option("-f", "--offset", dest="PcdOffset", action="store", type="int", help="Start offset to the image is used to store PCD value."), make_option("-u", "--value", dest="PcdValue", action="store", help="PCD value will be updated into the image."), make_option("-t", "--type", dest="PcdTypeName", action="store", help="The name of PCD data type may be one of VOID*,BOOLEAN, UINT8, UINT16, UINT32, UINT64."), make_option("-s", "--maxsize", dest="PcdMaxSize", action="store", type="int", help="Max size of data buffer is taken by PCD value.It must be set when PCD type is VOID*."), make_option("-v", "--verbose", dest="LogLevel", action="store_const", const=EdkLogger.VERBOSE, help="Run verbosely"), make_option("-d", "--debug", dest="LogLevel", type="int", help="Run with debug information"), make_option("-q", "--quiet", dest="LogLevel", action="store_const", const=EdkLogger.QUIET, help="Run quietly"), make_option("-?", action="help", help="show this help message and exit"), ] # use clearer usage to override default usage message UsageString = "%prog -f Offset -u Value -t Type [-s MaxSize] <input_file>" Parser = OptionParser(description=__copyright__, version=__version__, option_list=OptionList, usage=UsageString) Parser.set_defaults(LogLevel=EdkLogger.INFO) Options, Args = Parser.parse_args() # error check if len(Args) == 0: EdkLogger.error("PatchPcdValue", PARAMETER_INVALID, ExtraData=Parser.get_usage()) InputFile = Args[len(Args) - 1] return Options, InputFile
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 self.__dict__: ErrorMsg = "Invalid configuration option '%s' was found" % List[0] EdkLogger.error("Ecc", EdkLogger.ECC_ERROR, ErrorMsg, File = Filepath, Line = LineNo) 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) self.__dict__[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 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 == None or CommandOptions.PcdValue == None or CommandOptions.PcdTypeName == None: EdkLogger.error("PatchPcdValue", OPTION_MISSING, ExtraData="PcdOffset or PcdValue of PcdTypeName is not specified.") return 1 if CommandOptions.PcdTypeName.upper() not in ["BOOLEAN", "UINT8", "UINT16", "UINT32", "UINT64", "VOID*"]: EdkLogger.error("PatchPcdValue", PARAMETER_INVALID, ExtraData="PCD type %s is not valid." %(CommandOptions.PcdTypeName)) return 1 if CommandOptions.PcdTypeName.upper() == "VOID*" and CommandOptions.PcdMaxSize == 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 PackFile(self, File, ArcName=None): try: print "packing ...", File self._ZipFile.write(File, ArcName) except BaseException, X: EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE, ExtraData="%s (%s)" % (File, str(X)))
def MacroExtend (Str, MacroDict={}, Arch='COMMON'): if Str == None : return None Dict = {'$(WORKSPACE)' : GenFdsGlobalVariable.WorkSpaceDir, '$(EDK_SOURCE)' : GenFdsGlobalVariable.EdkSourceDir, # '$(OUTPUT_DIRECTORY)': GenFdsGlobalVariable.OutputDirFromDsc, '$(TARGET)' : GenFdsGlobalVariable.TargetName, '$(TOOL_CHAIN_TAG)' : GenFdsGlobalVariable.ToolChainTag, '$(SPACE)' : ' ' } OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[GenFdsGlobalVariable.ArchList[0]] if Arch != 'COMMON' and Arch in GenFdsGlobalVariable.ArchList: OutputDir = GenFdsGlobalVariable.OutputDirFromDscDict[Arch] Dict['$(OUTPUT_DIRECTORY)'] = OutputDir if MacroDict != None and len (MacroDict) != 0: Dict.update(MacroDict) for key in Dict.keys(): 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 TrimEdkSourceCode(Source, Target): EdkLogger.verbose("\t%s -> %s" % (Source, Target)) CreateDirectory(os.path.dirname(Target)) try: f = open (Source,'rb') except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) # read whole file Lines = f.read() f.close() NewLines = None for Re,Repl in gImportCodePatterns: if NewLines == None: NewLines = Re.sub(Repl, Lines) else: NewLines = Re.sub(Repl, NewLines) # save all lines if trimmed if Source == Target and NewLines == Lines: return try: f = open (Target,'wb') except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target) f.write(NewLines) f.close()
def __init__(self, File=None, Content=None, LineIndex=0, SupportedFamily=["MSFT", "INTEL", "GCC", "RVCT"]): self.RuleFile = File # Read build rules from file if it's not none if File != None: try: self.RuleContent = open(File, 'r').readlines() except: EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File) elif Content != None: self.RuleContent = Content else: EdkLogger.error("build", PARAMETER_MISSING, ExtraData="No rule file or string given") self.SupportedToolChainFamilyList = SupportedFamily self.RuleDatabase = tdict(True, 4) # {FileExt, ModuleType, Arch, Family : FileBuildRule object} self.Ext2FileType = {} # {ext : file-type} self.FileTypeList = set() self._LineIndex = LineIndex self._State = "" self._RuleInfo = tdict(True, 2) # {toolchain family : {"InputFile": {}, "OutputFile" : [], "Command" : []}} self._FileType = '' self._BuildTypeList = [] self._ArchList = [] self._FamilyList = [] self._TotalToolChainFamilySet = set() self._RuleObjectList = [] # FileBuildRule object list self._FileVersion = "" self.Parse() # some intrinsic rules self.RuleDatabase[TAB_DEFAULT_BINARY_FILE, "COMMON", "COMMON", "COMMON"] = self._BinaryFileRule self.FileTypeList.add(TAB_DEFAULT_BINARY_FILE)
def GetFileList(SourceFileList, IncludeList, SkipList): if IncludeList is None: EdkLogger.error("UnicodeStringGather", AUTOGEN_ERROR, "Include path for unicode file is not defined") FileList = [] if SkipList is None: SkipList = [] for File in SourceFileList: for Dir in IncludeList: if not os.path.exists(Dir): continue File = os.path.join(Dir, File.Path) # # Ignore Dir # if os.path.isfile(File) != True: continue # # Ignore file listed in skip list # IsSkip = False for Skip in SkipList: if os.path.splitext(File)[1].upper() == Skip.upper(): EdkLogger.verbose("Skipped %s for string token uses search" % File) IsSkip = True break if not IsSkip: FileList.append(File) break return FileList
def GetLanguageCode(LangName, IsCompatibleMode, File): global LangConvTable length = len(LangName) if IsCompatibleMode: if length == 3 and LangName.isalpha(): TempLangName = LangConvTable.get(LangName.lower()) if TempLangName != 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()) == 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()) == None and LangName[3] == '-': return LangName EdkLogger.error("Unicode File Parser", FORMAT_INVALID, "Invalid RFC 4646 language code : %s" % LangName, File)
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 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(encoding='utf-8', errors='ignore')) 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 VerifyUcs2Data(self, FileIn, FileName, Encoding): Ucs2Info = codecs.lookup('ucs-2') # # Convert to unicode # try: FileDecoded = codecs.decode(FileIn, Encoding) Ucs2Info.encode(FileDecoded) except: UniFile = StringIO.StringIO(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 GetValidExpression(self, TokenSpaceGuid, PcdCName): SqlCommand = "select Value1,StartLine from %s WHERE Value2='%s' and Value3='%s'" % (self.Table, TokenSpaceGuid, PcdCName) self.Cur.execute(SqlCommand) validateranges = [] validlists = [] expressions = [] try: for row in self.Cur: comment = row[0] LineNum = row[1] comment = comment.strip("#") comment = comment.strip() oricomment = comment if comment.startswith("@ValidRange"): comment = comment.replace("@ValidRange", "", 1) validateranges.append(comment.split("|")[1].strip()) if comment.startswith("@ValidList"): comment = comment.replace("@ValidList", "", 1) validlists.append(comment.split("|")[1].strip()) if comment.startswith("@Expression"): comment = comment.replace("@Expression", "", 1) expressions.append(comment.split("|")[1].strip()) except Exception, Exc: ValidType = "" if oricomment.startswith("@ValidRange"): ValidType = "@ValidRange" if oricomment.startswith("@ValidList"): ValidType = "@ValidList" if oricomment.startswith("@Expression"): ValidType = "@Expression" EdkLogger.error('Parser', FORMAT_INVALID, "The syntax for %s of PCD %s.%s is incorrect" % (ValidType,TokenSpaceGuid, PcdCName), ExtraData=oricomment,File=self.MetaFile, Line=LineNum) return set(), set(), set()
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 GetLangDef(self, File, Line): Lang = Line.split() if len(Lang) != 3: try: FileIn = codecs.open(File, mode='rb', encoding='utf-16').read() except UnicodeError, X: EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File); except:
def GetLangDef(self, File, Line): Lang = distutils.util.split_quoted((Line.split(u"//")[0])) if len(Lang) != 3: try: FileIn = UniFileClassObject.OpenUniFile(LongFilePath(File.Path)) except UnicodeError, X: EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File); except:
def PreProcess(self, File): if not os.path.exists(File.Path) or not os.path.isfile(File.Path): EdkLogger.error("Unicode File Parser", FILE_NOT_FOUND, ExtraData=File.Path) try: FileIn = codecs.open(LongFilePath(File.Path), mode='rb', encoding='utf-16').readlines() except UnicodeError, X: EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File.Path);
def GetLangDef(self, File, Line): Lang = distutils.util.split_quoted((Line.split(u"//")[0])) if len(Lang) != 3: try: FileIn = codecs.open(LongFilePath(File.Path), mode='rb', encoding='utf-16').read() except UnicodeError, X: EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File); except:
def PreProcess(self, File): if not os.path.exists(File.Path) or not os.path.isfile(File.Path): EdkLogger.error("Unicode File Parser", FILE_NOT_FOUND, ExtraData=File.Path) try: FileIn = self.OpenUniFile(LongFilePath(File.Path)) except UnicodeError, X: EdkLogger.error("build", FILE_READ_FAILURE, "File read failure: %s" % str(X), ExtraData=File.Path);
def PackFiles(self, Files): for F in Files: try: print "packing ...", F self._ZipFile.write(F) except BaseException, X: EdkLogger.error("PackagingTool", FILE_COMPRESS_FAILURE, ExtraData="%s (%s)" % (F, str(X)))
def TrimPreprocessedVfr(Source, Target): CreateDirectory(os.path.dirname(Target)) try: f = open (Source,'r') except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) # read whole file Lines = f.readlines() f.close() 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) == None: # keep "#pragram pack" directive if gPragmaPattern.search(Line) == 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 ["GUID", "EFI_PLABEL", "PAL_CALL_RETURN"]: for i in range(TypedefStart, TypedefEnd+1): Lines[i] = "\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 GetFileList(FfsInf, FileType, FileExtension, Dict = {}): if FileType in Section.SectFileType.keys() : IsSect = True else : IsSect = False if FileExtension != None: Suffix = FileExtension elif IsSect : Suffix = Section.SectionType.get(FileType) else: Suffix = Section.BinFileType.get(FileType) if FfsInf == None: EdkLogger.error("GenFds", GENFDS_ERROR, 'Inf File does not exist!') FileList = [] if FileType != None: for File in FfsInf.BinFileList: if File.Arch == "COMMON" or FfsInf.CurrentArch == File.Arch: if File.Type == FileType or (int(FfsInf.PiSpecVersion, 16) >= 0x0001000A \ and FileType == 'DXE_DPEX'and File.Type == 'SMM_DEPEX') \ or (FileType == 'TE'and File.Type == 'PE32'): if '*' in FfsInf.TargetOverrideList or File.Target == '*' or File.Target in FfsInf.TargetOverrideList or FfsInf.TargetOverrideList == []: FileList.append(FfsInf.PatchEfiFile(File.Path, File.Type)) else: GenFdsGlobalVariable.InfLogger ("\nBuild Target \'%s\' of File %s is not in the Scope of %s specified by INF %s in FDF" %(File.Target, File.File, FfsInf.TargetOverrideList, FfsInf.InfFileName)) else: GenFdsGlobalVariable.VerboseLogger ("\nFile Type \'%s\' of File %s in %s is not same with file type \'%s\' from Rule in FDF" %(File.Type, File.File, FfsInf.InfFileName, FileType)) else: GenFdsGlobalVariable.InfLogger ("\nCurrent ARCH \'%s\' of File %s is not in the Support Arch Scope of %s specified by INF %s in FDF" %(FfsInf.CurrentArch, File.File, File.Arch, FfsInf.InfFileName)) if Suffix != None and os.path.exists(FfsInf.EfiOutputPath): # # Get Makefile path and time stamp # MakefileDir = FfsInf.EfiOutputPath[:-len('OUTPUT')] Makefile = os.path.join(MakefileDir, 'Makefile') if not os.path.exists(Makefile): Makefile = os.path.join(MakefileDir, 'GNUmakefile') if not os.path.exists(Makefile): SuffixMap = FfsInf.GetFinalTargetSuffixMap() if Suffix in SuffixMap: FileList.extend(SuffixMap[Suffix]) else: # Update to search files with suffix in all sub-dirs. Tuple = os.walk(FfsInf.EfiOutputPath) for Dirpath, Dirnames, Filenames in Tuple: for F in Filenames: if os.path.splitext(F)[1] in (Suffix): FullName = os.path.join(Dirpath, F) if os.path.getmtime(FullName) > os.path.getmtime(Makefile): FileList.append(FullName) #Process the file lists is alphabetical for a same section type if len (FileList) > 1: FileList.sort() return FileList, IsSect
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 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 PatchEfiFile(self, EfiFile, FileType): # # If the module does not have any patches, then return path to input file # if not self.PatchPcds: return EfiFile # # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED # if FileType != 'PE32' and self.ModuleType != "USER_DEFINED": return EfiFile # # Generate path to patched output file # Basename = os.path.basename(EfiFile) Output = os.path.normpath (os.path.join(self.OutputPath, Basename)) # # If this file has already been patched, then return the path to the patched file # if self.PatchedBinFile == Output: return Output # # If a different file from the same module has already been patched, then generate an error # 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) # # Copy unpatched file contents to output file location to perform patching # CopyLongFilePath(EfiFile, Output) # # Apply patches to patched output file # 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) # # Save the path of the patched output file # self.PatchedBinFile = Output # # Return path to patched output file # return Output
def __GenSimpleFileSection__(self, Rule): # # Prepare the parameter of GenSection # FileList = [] OutputFileList = [] GenSecInputFile = None if Rule.FileName != None: GenSecInputFile = self.__ExtendMacro__(Rule.FileName) if os.path.isabs(GenSecInputFile): GenSecInputFile = os.path.normpath(GenSecInputFile) else: GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile)) else: FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension) Index = 1 SectionType = Rule.SectionType # # Convert Fv Section Type for PI1.1 SMM driver. # if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A: if SectionType == 'DXE_DEPEX': SectionType = 'SMM_DEPEX' # # Framework SMM Driver has no SMM_DEPEX section type # if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A: if SectionType == 'SMM_DEPEX': EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName) NoStrip = True if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'): if self.KeepReloc != None: NoStrip = self.KeepReloc elif Rule.KeepReloc != None: NoStrip = Rule.KeepReloc elif self.ShadowFromInfFile != None: NoStrip = self.ShadowFromInfFile if FileList != [] : for File in FileList: SecNum = '%d' %Index GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \ Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum Index = Index + 1 OutputFile = os.path.join(self.OutputPath, GenSecOutputFile) File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch) #Get PE Section alignment when align is set to AUTO if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'): ImageObj = PeImageClass (File) if ImageObj.SectionAlignment < 0x400: self.Alignment = str (ImageObj.SectionAlignment) else: self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K' 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) StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, [File], Strip=True ) File = StrippedFile if SectionType == 'TE': TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') GenFdsGlobalVariable.GenerateFirmwareImage( TeFile, [File], Type='te' ) File = TeFile GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType]) OutputFileList.append(OutputFile) else: SecNum = '%d' %Index GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \ Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum OutputFile = os.path.join(self.OutputPath, GenSecOutputFile) GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch) #Get PE Section alignment when align is set to AUTO if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'): ImageObj = PeImageClass (GenSecInputFile) if ImageObj.SectionAlignment < 0x400: self.Alignment = str (ImageObj.SectionAlignment) else: self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K' 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) StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, [GenSecInputFile], Strip=True ) GenSecInputFile = StrippedFile if SectionType == 'TE': TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw') GenFdsGlobalVariable.GenerateFirmwareImage( TeFile, [GenSecInputFile], Type='te' ) GenSecInputFile = TeFile GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType]) OutputFileList.append(OutputFile) return OutputFileList
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, X: EdkLogger.error("BPDG", BuildToolError.COMMAND_FAILURE, ExtraData="%s" % (str(X))) (out, error) = PopenObject.communicate() print out while PopenObject.returncode == None : PopenObject.wait() if PopenObject.returncode != 0: 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 GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile=False): OutputFileList = [] if self.FvFileType is not None: FileList, IsSect = Section.Section.GetFileList( FfsInf, self.FvFileType, self.FvFileExtension) if IsSect: return FileList, self.Alignment Num = SecNum MaxFvAlignment = 0 for FvFileName in FileList: FvAlignmentValue = 0 if os.path.isfile(FvFileName): FvFileObj = open(FvFileName, 'rb') FvFileObj.seek(0) # PI FvHeader is 0x48 byte FvHeaderBuffer = FvFileObj.read(0x48) # FV alignment position. FvAlignmentValue = 1 << (FvHeaderBuffer[0x2E] & 0x1F) FvFileObj.close() if FvAlignmentValue > MaxFvAlignment: MaxFvAlignment = FvAlignmentValue OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + Num + Ffs.SectionSuffix.get("FV_IMAGE")) GenFdsGlobalVariable.GenerateSection( OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile) OutputFileList.append(OutputFile) # MaxFvAlignment is larger than or equal to 1K if MaxFvAlignment >= 0x400: if MaxFvAlignment >= 0x100000: #The max alignment supported by FFS is 16M. if MaxFvAlignment >= 0x1000000: self.Alignment = "16M" else: self.Alignment = str(MaxFvAlignment // 0x100000) + "M" else: self.Alignment = str(MaxFvAlignment // 0x400) + "K" else: # MaxFvAlignment is less than 1K self.Alignment = str(MaxFvAlignment) return OutputFileList, self.Alignment # # Generate Fv # if self.FvName is not None: Buffer = BytesIO() Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName) if Fv is not None: self.Fv = Fv if not self.FvAddr and self.Fv.BaseAddress: self.FvAddr = self.Fv.BaseAddress FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict=Dict, Flag=IsMakefile) if Fv.FvAlignment is not None: if self.Alignment is None: self.Alignment = Fv.FvAlignment else: if GenFdsGlobalVariable.GetAlignment( Fv.FvAlignment ) > GenFdsGlobalVariable.GetAlignment(self.Alignment): self.Alignment = Fv.FvAlignment else: if self.FvFileName is not None: FvFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro( self.FvFileName) if os.path.isfile(FvFileName): FvFileObj = open(FvFileName, 'rb') FvFileObj.seek(0) # PI FvHeader is 0x48 byte FvHeaderBuffer = FvFileObj.read(0x48) # FV alignment position. FvAlignmentValue = 1 << (FvHeaderBuffer[0x2E] & 0x1F) # FvAlignmentValue is larger than or equal to 1K if FvAlignmentValue >= 0x400: if FvAlignmentValue >= 0x100000: #The max alignment supported by FFS is 16M. if FvAlignmentValue >= 0x1000000: self.Alignment = "16M" else: self.Alignment = str( FvAlignmentValue // 0x100000) + "M" else: self.Alignment = str( FvAlignmentValue // 0x400) + "K" else: # FvAlignmentValue is less than 1K self.Alignment = str(FvAlignmentValue) FvFileObj.close() else: if len(mws.getPkgPath()) == 0: EdkLogger.error( "GenFds", FILE_NOT_FOUND, "%s is not found in WORKSPACE: %s" % self.FvFileName, GenFdsGlobalVariable.WorkSpaceDir) else: EdkLogger.error( "GenFds", FILE_NOT_FOUND, "%s is not found in packages path:\n\t%s" % (self.FvFileName, '\n\t'.join( mws.getPkgPath()))) else: EdkLogger.error( "GenFds", GENFDS_ERROR, "FvImageSection Failed! %s NOT found in FDF" % self.FvName) # # Prepare the parameter of GenSection # OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + SecNum + Ffs.SectionSuffix.get("FV_IMAGE")) GenFdsGlobalVariable.GenerateSection( OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE', IsMakefile=IsMakefile) OutputFileList.append(OutputFile) return OutputFileList, self.Alignment
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[3] = 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], self.InputFileName) # Strip the space char PCD.PcdCName = PCD.PcdCName.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 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 GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}): OutputFileList = [] if self.FvFileType != None: FileList, IsSect = Section.Section.GetFileList( FfsInf, self.FvFileType, self.FvFileExtension) if IsSect: return FileList, self.Alignment Num = SecNum for FileName in FileList: OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get("FV_IMAGE")) GenFdsGlobalVariable.GenerateSection( OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE') OutputFileList.append(OutputFile) return OutputFileList, self.Alignment # # Generate Fv # if self.FvName != None: Buffer = StringIO.StringIO('') Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get(self.FvName) if Fv != None: self.Fv = Fv FvFileName = Fv.AddToBuffer(Buffer, self.FvAddr, MacroDict=Dict) if Fv.FvAlignment != None: if self.Alignment == None: self.Alignment = Fv.FvAlignment else: if GenFdsGlobalVariable.GetAlignment( Fv.FvAlignment ) > GenFdsGlobalVariable.GetAlignment(self.Alignment): self.Alignment = Fv.FvAlignment else: if self.FvFileName != None: FvFileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro( self.FvFileName) if os.path.isfile(FvFileName): FvFileObj = open(FvFileName, 'r+b') FvFileObj.seek(0) # PI FvHeader is 0x48 byte FvHeaderBuffer = FvFileObj.read(0x48) # FV alignment position. FvAlignmentValue = 1 << (ord(FvHeaderBuffer[0x2E]) & 0x1F) # FvAlignmentValue is larger than or equal to 1K if FvAlignmentValue >= 0x400: if FvAlignmentValue >= 0x10000: #The max alignment supported by FFS is 64K. self.Alignment = "64K" else: self.Alignment = str( FvAlignmentValue / 0x400) + "K" else: # FvAlignmentValue is less than 1K self.Alignment = str(FvAlignmentValue) FvFileObj.close() else: EdkLogger.error( "GenFds", GENFDS_ERROR, "FvImageSection Failed! %s NOT found in FDF" % self.FvName) # # Prepare the parameter of GenSection # OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + SecNum + Ffs.SectionSuffix.get("FV_IMAGE")) GenFdsGlobalVariable.GenerateSection( OutputFile, [FvFileName], 'EFI_SECTION_FIRMWARE_VOLUME_IMAGE') OutputFileList.append(OutputFile) return OutputFileList, self.Alignment
def BlockInfoOfRegion(self, BlockSizeList, FvObj): Start = 0 End = 0 RemindingSize = self.Size ExpectedList = [] for (BlockSize, BlockNum, pcd) in BlockSizeList: End = Start + BlockSize * BlockNum # region not started yet if self.Offset >= End: Start = End continue # region located in current blocks else: # region ended within current blocks if self.Offset + self.Size <= End: ExpectedList.append((BlockSize, (RemindingSize + BlockSize - 1) / BlockSize)) break # region not ended yet else: # region not started in middle of current blocks if self.Offset <= Start: UsedBlockNum = BlockNum # region started in middle of current blocks else: UsedBlockNum = (End - self.Offset) / BlockSize Start = End ExpectedList.append((BlockSize, UsedBlockNum)) RemindingSize -= BlockSize * UsedBlockNum if FvObj.BlockSizeList == []: FvObj.BlockSizeList = ExpectedList else: # first check whether FvObj.BlockSizeList items have only "BlockSize" or "NumBlocks", # if so, use ExpectedList for Item in FvObj.BlockSizeList: if Item[0] is None or Item[1] is None: FvObj.BlockSizeList = ExpectedList break # make sure region size is no smaller than the summed block size in FV Sum = 0 for Item in FvObj.BlockSizeList: Sum += Item[0] * Item[1] if self.Size < Sum: EdkLogger.error("GenFds", GENFDS_ERROR, "Total Size of FV %s 0x%x is larger than Region Size 0x%x " % (FvObj.UiFvName, Sum, self.Size)) # check whether the BlockStatements in FV section is appropriate ExpectedListData = '' for Item in ExpectedList: ExpectedListData += "BlockSize = 0x%x\n\tNumBlocks = 0x%x\n\t" % Item Index = 0 for Item in FvObj.BlockSizeList: if Item[0] != ExpectedList[Index][0]: EdkLogger.error("GenFds", GENFDS_ERROR, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement" % FvObj.UiFvName, ExtraData=ExpectedListData) elif Item[1] != ExpectedList[Index][1]: if (Item[1] < ExpectedList[Index][1]) and (Index == len(FvObj.BlockSizeList) - 1): break; else: EdkLogger.error("GenFds", GENFDS_ERROR, "BlockStatements of FV %s are not align with FD's, suggested FV BlockStatement" % FvObj.UiFvName, ExtraData=ExpectedListData) else: Index += 1
def _OverridePcd(self, ToPcd, FromPcd, Module="", Msg="", Library=""): # # in case there's PCDs coming from FDF file, which have no type given. # at this point, ToPcd.Type has the type found from dependent # package # TokenCName = ToPcd.TokenCName for PcdItem in self.MixedPcd: if (ToPcd.TokenCName, ToPcd.TokenSpaceGuidCName) in self.MixedPcd[PcdItem]: TokenCName = PcdItem[0] break if FromPcd is not None: if ToPcd.Pending and FromPcd.Type: ToPcd.Type = FromPcd.Type elif ToPcd.Type and FromPcd.Type\ and ToPcd.Type != FromPcd.Type and ToPcd.Type in FromPcd.Type: if ToPcd.Type.strip() == TAB_PCDS_DYNAMIC_EX: ToPcd.Type = FromPcd.Type elif ToPcd.Type and FromPcd.Type \ and ToPcd.Type != FromPcd.Type: if Library: Module = str(Module) + " 's library file (" + str( Library) + ")" EdkLogger.error("build", OPTION_CONFLICT, "Mismatched PCD type", ExtraData="%s.%s is used as [%s] in module %s, but as [%s] in %s."\ % (ToPcd.TokenSpaceGuidCName, TokenCName, ToPcd.Type, Module, FromPcd.Type, Msg), File=self.MetaFile) if FromPcd.MaxDatumSize: ToPcd.MaxDatumSize = FromPcd.MaxDatumSize ToPcd.MaxSizeUserSet = FromPcd.MaxDatumSize if FromPcd.DefaultValue: ToPcd.DefaultValue = FromPcd.DefaultValue if FromPcd.TokenValue: ToPcd.TokenValue = FromPcd.TokenValue if FromPcd.DatumType: ToPcd.DatumType = FromPcd.DatumType if FromPcd.SkuInfoList: ToPcd.SkuInfoList = FromPcd.SkuInfoList if FromPcd.UserDefinedDefaultStoresFlag: ToPcd.UserDefinedDefaultStoresFlag = FromPcd.UserDefinedDefaultStoresFlag # Add Flexible PCD format parse if ToPcd.DefaultValue: try: ToPcd.DefaultValue = ValueExpressionEx( ToPcd.DefaultValue, ToPcd.DatumType, self._GuidDict)(True) except BadExpression as Value: EdkLogger.error( 'Parser', FORMAT_INVALID, 'PCD [%s.%s] Value "%s", %s' % (ToPcd.TokenSpaceGuidCName, ToPcd.TokenCName, ToPcd.DefaultValue, Value), File=self.MetaFile) # check the validation of datum IsValid, Cause = CheckPcdDatum(ToPcd.DatumType, ToPcd.DefaultValue) if not IsValid: EdkLogger.error('build', FORMAT_INVALID, Cause, File=self.MetaFile, ExtraData="%s.%s" % (ToPcd.TokenSpaceGuidCName, TokenCName)) ToPcd.validateranges = FromPcd.validateranges ToPcd.validlists = FromPcd.validlists ToPcd.expressions = FromPcd.expressions ToPcd.CustomAttribute = FromPcd.CustomAttribute if FromPcd is not None and ToPcd.DatumType == TAB_VOID and not ToPcd.MaxDatumSize: EdkLogger.debug(EdkLogger.DEBUG_9, "No MaxDatumSize specified for PCD %s.%s" \ % (ToPcd.TokenSpaceGuidCName, TokenCName)) Value = ToPcd.DefaultValue if not Value: ToPcd.MaxDatumSize = '1' elif Value[0] == 'L': ToPcd.MaxDatumSize = str((len(Value) - 2) * 2) elif Value[0] == '{': ToPcd.MaxDatumSize = str(len(Value.split(','))) else: ToPcd.MaxDatumSize = str(len(Value) - 1) # apply default SKU for dynamic PCDS if specified one is not available if (ToPcd.Type in PCD_DYNAMIC_TYPE_SET or ToPcd.Type in PCD_DYNAMIC_EX_TYPE_SET) \ and not ToPcd.SkuInfoList: if self.Platform.SkuName in self.Platform.SkuIds: SkuName = self.Platform.SkuName else: SkuName = TAB_DEFAULT ToPcd.SkuInfoList = { SkuName: SkuInfoClass(SkuName, self.Platform.SkuIds[SkuName][0], '', '', '', '', '', ToPcd.DefaultValue) }
def GenFdsApi(FdsCommandDict, WorkSpaceDataBase=None): global Workspace Workspace = "" ArchList = None ReturnCode = 0 resetFdsGlobalVariable() try: if FdsCommandDict.get("verbose"): EdkLogger.SetLevel(EdkLogger.VERBOSE) GenFdsGlobalVariable.VerboseMode = True if FdsCommandDict.get("FixedAddress"): GenFdsGlobalVariable.FixedLoadAddress = True if FdsCommandDict.get("quiet"): EdkLogger.SetLevel(EdkLogger.QUIET) if FdsCommandDict.get("debug"): EdkLogger.SetLevel(FdsCommandDict.get("debug") + 1) GenFdsGlobalVariable.DebugLevel = FdsCommandDict.get("debug") else: EdkLogger.SetLevel(EdkLogger.INFO) if not FdsCommandDict.get("Workspace", os.environ.get('WORKSPACE')): EdkLogger.error( "GenFds", OPTION_MISSING, "WORKSPACE not defined", ExtraData= "Please use '-w' switch to pass it or set the WORKSPACE environment variable." ) elif not os.path.exists( FdsCommandDict.get("Workspace", os.environ.get('WORKSPACE'))): EdkLogger.error( "GenFds", PARAMETER_INVALID, "WORKSPACE is invalid", ExtraData= "Please use '-w' switch to pass it or set the WORKSPACE environment variable." ) else: Workspace = os.path.normcase( FdsCommandDict.get("Workspace", os.environ.get('WORKSPACE'))) GenFdsGlobalVariable.WorkSpaceDir = Workspace if FdsCommandDict.get("debug"): GenFdsGlobalVariable.VerboseLogger("Using Workspace:" + Workspace) if FdsCommandDict.get("GenfdsMultiThread"): GenFdsGlobalVariable.EnableGenfdsMultiThread = True else: GenFdsGlobalVariable.EnableGenfdsMultiThread = False os.chdir(GenFdsGlobalVariable.WorkSpaceDir) # set multiple workspace PackagesPath = os.getenv("PACKAGES_PATH") mws.setWs(GenFdsGlobalVariable.WorkSpaceDir, PackagesPath) if FdsCommandDict.get("fdf_file"): FdfFilename = FdsCommandDict.get("fdf_file")[0].Path FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro( FdfFilename) if FdfFilename[0:2] == '..': FdfFilename = os.path.realpath(FdfFilename) if not os.path.isabs(FdfFilename): FdfFilename = mws.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename) if not os.path.exists(FdfFilename): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename) GenFdsGlobalVariable.FdfFile = FdfFilename GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime( FdfFilename) else: EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename") if FdsCommandDict.get("build_target"): GenFdsGlobalVariable.TargetName = FdsCommandDict.get( "build_target") if FdsCommandDict.get("toolchain_tag"): GenFdsGlobalVariable.ToolChainTag = FdsCommandDict.get( "toolchain_tag") if FdsCommandDict.get("active_platform"): ActivePlatform = FdsCommandDict.get("active_platform") ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro( ActivePlatform) if ActivePlatform[0:2] == '..': ActivePlatform = os.path.realpath(ActivePlatform) if not os.path.isabs(ActivePlatform): ActivePlatform = mws.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform) if not os.path.exists(ActivePlatform): EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!") else: EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform") GenFdsGlobalVariable.ActivePlatform = PathClass( NormPath(ActivePlatform)) if FdsCommandDict.get("conf_directory"): # Get alternate Conf location, if it is absolute, then just use the absolute directory name ConfDirectoryPath = os.path.normpath( FdsCommandDict.get("conf_directory")) if ConfDirectoryPath.startswith('"'): ConfDirectoryPath = ConfDirectoryPath[1:] if ConfDirectoryPath.endswith('"'): ConfDirectoryPath = ConfDirectoryPath[:-1] if not os.path.isabs(ConfDirectoryPath): # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf ConfDirectoryPath = os.path.join( GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath) else: if "CONF_PATH" in os.environ: ConfDirectoryPath = os.path.normcase(os.environ["CONF_PATH"]) else: # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf ConfDirectoryPath = mws.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf') GenFdsGlobalVariable.ConfDir = ConfDirectoryPath if not GlobalData.gConfDirectory: GlobalData.gConfDirectory = GenFdsGlobalVariable.ConfDir BuildConfigurationFile = os.path.normpath( os.path.join(ConfDirectoryPath, "target.txt")) if os.path.isfile(BuildConfigurationFile) == True: # if no build target given in command line, get it from target.txt TargetObj = TargetTxtDict() TargetTxt = TargetObj.Target if not GenFdsGlobalVariable.TargetName: BuildTargetList = TargetTxt.TargetTxtDictionary[ TAB_TAT_DEFINES_TARGET] if len(BuildTargetList) != 1: EdkLogger.error( "GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for Target.") GenFdsGlobalVariable.TargetName = BuildTargetList[0] # if no tool chain given in command line, get it from target.txt if not GenFdsGlobalVariable.ToolChainTag: ToolChainList = TargetTxt.TargetTxtDictionary[ TAB_TAT_DEFINES_TOOL_CHAIN_TAG] if ToolChainList is None or len(ToolChainList) == 0: EdkLogger.error( "GenFds", RESOURCE_NOT_AVAILABLE, ExtraData="No toolchain given. Don't know how to build." ) if len(ToolChainList) != 1: EdkLogger.error( "GenFds", OPTION_VALUE_INVALID, ExtraData="Only allows one instance for ToolChain.") GenFdsGlobalVariable.ToolChainTag = ToolChainList[0] else: EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile) #Set global flag for build mode GlobalData.gIgnoreSource = FdsCommandDict.get("IgnoreSources") if FdsCommandDict.get("macro"): for Pair in FdsCommandDict.get("macro"): if Pair.startswith('"'): Pair = Pair[1:] if Pair.endswith('"'): Pair = Pair[:-1] List = Pair.split('=') if len(List) == 2: if not List[1].strip(): EdkLogger.error( "GenFds", OPTION_VALUE_INVALID, ExtraData="No Value given for Macro %s" % List[0]) if List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]: GlobalData.gGlobalDefines[ List[0].strip()] = List[1].strip() else: GlobalData.gCommandLineDefines[ List[0].strip()] = List[1].strip() else: GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE" os.environ["WORKSPACE"] = Workspace # Use the -t and -b option as gGlobalDefines's TOOLCHAIN and TARGET if they are not defined if "TARGET" not in GlobalData.gGlobalDefines: GlobalData.gGlobalDefines[ "TARGET"] = GenFdsGlobalVariable.TargetName if "TOOLCHAIN" not in GlobalData.gGlobalDefines: GlobalData.gGlobalDefines[ "TOOLCHAIN"] = GenFdsGlobalVariable.ToolChainTag if "TOOL_CHAIN_TAG" not in GlobalData.gGlobalDefines: GlobalData.gGlobalDefines[ 'TOOL_CHAIN_TAG'] = GenFdsGlobalVariable.ToolChainTag """call Workspace build create database""" GlobalData.gDatabasePath = os.path.normpath( os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath)) if WorkSpaceDataBase: BuildWorkSpace = WorkSpaceDataBase else: BuildWorkSpace = WorkspaceDatabase() # # Get files real name in workspace dir # GlobalData.gAllFiles = DirCache(Workspace) GlobalData.gWorkspace = Workspace if FdsCommandDict.get("build_architecture_list"): ArchList = FdsCommandDict.get("build_architecture_list").split(',') else: ArchList = BuildWorkSpace.BuildObject[ GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList TargetArchList = set(BuildWorkSpace.BuildObject[ GenFdsGlobalVariable.ActivePlatform, TAB_COMMON, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].SupArchList) & set(ArchList) if len(TargetArchList) == 0: EdkLogger.error( "GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[ GenFdsGlobalVariable.ActivePlatform, TAB_COMMON].SupArchList))) for Arch in ArchList: GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath( BuildWorkSpace.BuildObject[ GenFdsGlobalVariable.ActivePlatform, Arch, FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].OutputDirectory) # assign platform name based on last entry in ArchList GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[ GenFdsGlobalVariable.ActivePlatform, ArchList[-1], FdsCommandDict.get("build_target"), FdsCommandDict.get("toolchain_tag")].PlatformName if FdsCommandDict.get("platform_build_directory"): OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro( FdsCommandDict.get("platform_build_directory")) if not os.path.isabs(OutputDirFromCommandLine): OutputDirFromCommandLine = os.path.join( GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine) for Arch in ArchList: GenFdsGlobalVariable.OutputDirDict[ Arch] = OutputDirFromCommandLine else: for Arch in ArchList: GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join( GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag) for Key in GenFdsGlobalVariable.OutputDirDict: OutputDir = GenFdsGlobalVariable.OutputDirDict[Key] if OutputDir[0:2] == '..': OutputDir = os.path.realpath(OutputDir) if OutputDir[1] != ':': OutputDir = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDir) if not os.path.exists(OutputDir): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir) GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """ if WorkSpaceDataBase: FdfParserObj = GlobalData.gFdfParser else: FdfParserObj = FdfParser(FdfFilename) FdfParserObj.ParseFile() if FdfParserObj.CycleReferenceCheck(): EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file") if FdsCommandDict.get("fd"): if FdsCommandDict.get( "fd")[0].upper() in FdfParserObj.Profile.FdDict: GenFds.OnlyGenerateThisFd = FdsCommandDict.get("fd")[0] else: EdkLogger.error( "GenFds", OPTION_VALUE_INVALID, "No such an FD in FDF file: %s" % FdsCommandDict.get("fd")[0]) if FdsCommandDict.get("fv"): if FdsCommandDict.get( "fv")[0].upper() in FdfParserObj.Profile.FvDict: GenFds.OnlyGenerateThisFv = FdsCommandDict.get("fv")[0] else: EdkLogger.error( "GenFds", OPTION_VALUE_INVALID, "No such an FV in FDF file: %s" % FdsCommandDict.get("fv")[0]) if FdsCommandDict.get("cap"): if FdsCommandDict.get( "cap")[0].upper() in FdfParserObj.Profile.CapsuleDict: GenFds.OnlyGenerateThisCap = FdsCommandDict.get("cap")[0] else: EdkLogger.error( "GenFds", OPTION_VALUE_INVALID, "No such a Capsule in FDF file: %s" % FdsCommandDict.get("cap")[0]) GenFdsGlobalVariable.WorkSpace = BuildWorkSpace if ArchList: GenFdsGlobalVariable.ArchList = ArchList # Dsc Build Data will handle Pcd Settings from CommandLine. """Modify images from build output if the feature of loading driver at fixed address is on.""" if GenFdsGlobalVariable.FixedLoadAddress: GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform) # Record the FV Region info that may specific in the FD if FdfParserObj.Profile.FvDict and FdfParserObj.Profile.FdDict: for FvObj in FdfParserObj.Profile.FvDict.values(): for FdObj in FdfParserObj.Profile.FdDict.values(): for RegionObj in FdObj.RegionList: if RegionObj.RegionType != BINARY_FILE_TYPE_FV: continue for RegionData in RegionObj.RegionDataList: if FvObj.UiFvName.upper() == RegionData.upper(): if not FvObj.BaseAddress: FvObj.BaseAddress = '0x%x' % ( int(FdObj.BaseAddress, 0) + RegionObj.Offset) if FvObj.FvRegionInFD: if FvObj.FvRegionInFD != RegionObj.Size: EdkLogger.error( "GenFds", FORMAT_INVALID, "The FV %s's region is specified in multiple FD with different value." % FvObj.UiFvName) else: FvObj.FvRegionInFD = RegionObj.Size RegionObj.BlockInfoOfRegion( FdObj.BlockSizeList, FvObj) """Call GenFds""" GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList) """Generate GUID cross reference file""" GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList, FdfParserObj) """Display FV space info.""" GenFds.DisplayFvSpaceInfo(FdfParserObj) except Warning as X: EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False) ReturnCode = FORMAT_INVALID except FatalError as X: if FdsCommandDict.get("debug") is not None: import traceback EdkLogger.quiet(traceback.format_exc()) ReturnCode = X.args[0] except: import traceback EdkLogger.error( "\nPython", CODE_ERROR, "Tools code failure", ExtraData= "Please send email to %s for help, attaching following call stack trace!\n" % MSG_EDKII_MAIL_ADDR, RaiseError=False) EdkLogger.quiet(traceback.format_exc()) ReturnCode = CODE_ERROR finally: ClearDuplicatedInf() return ReturnCode
def GetModuleLibInstances(Module, Platform, BuildDatabase, Arch, Target, Toolchain, FileName = '', EdkLogger = None): if Module.LibInstances: return Module.LibInstances ModuleType = Module.ModuleType # add forced library instances (specified under LibraryClasses sections) # # If a module has a MODULE_TYPE of USER_DEFINED, # do not link in NULL library class instances from the global [LibraryClasses.*] sections. # if Module.ModuleType != SUP_MODULE_USER_DEFINED: for LibraryClass in Platform.LibraryClasses.GetKeys(): if LibraryClass.startswith("NULL") and Platform.LibraryClasses[LibraryClass, Module.ModuleType]: Module.LibraryClasses[LibraryClass] = Platform.LibraryClasses[LibraryClass, Module.ModuleType] # add forced library instances (specified in module overrides) for LibraryClass in Platform.Modules[str(Module)].LibraryClasses: if LibraryClass.startswith("NULL"): Module.LibraryClasses[LibraryClass] = Platform.Modules[str(Module)].LibraryClasses[LibraryClass] # EdkII module LibraryConsumerList = [Module] Constructor = [] ConsumedByList = OrderedListDict() LibraryInstance = OrderedDict() if not Module.LibraryClass: EdkLogger.verbose("") EdkLogger.verbose("Library instances of module [%s] [%s]:" % (str(Module), Arch)) while len(LibraryConsumerList) > 0: M = LibraryConsumerList.pop() for LibraryClassName in M.LibraryClasses: if LibraryClassName not in LibraryInstance: # override library instance for this module LibraryPath = Platform.Modules[str(Module)].LibraryClasses.get(LibraryClassName,Platform.LibraryClasses[LibraryClassName, ModuleType]) if LibraryPath is None: LibraryPath = M.LibraryClasses.get(LibraryClassName) if LibraryPath is None: if not Module.LibraryClass: EdkLogger.error("build", RESOURCE_NOT_AVAILABLE, "Instance of library class [%s] is not found" % LibraryClassName, File=FileName, ExtraData="in [%s] [%s]\n\tconsumed by module [%s]" % (str(M), Arch, str(Module))) else: return [] LibraryModule = BuildDatabase[LibraryPath, Arch, Target, Toolchain] # for those forced library instance (NULL library), add a fake library class if LibraryClassName.startswith("NULL"): LibraryModule.LibraryClass.append(LibraryClassObject(LibraryClassName, [ModuleType])) elif LibraryModule.LibraryClass is None \ or len(LibraryModule.LibraryClass) == 0 \ or (ModuleType != SUP_MODULE_USER_DEFINED and ModuleType != SUP_MODULE_HOST_APPLICATION and ModuleType not in LibraryModule.LibraryClass[0].SupModList): # only USER_DEFINED can link against any library instance despite of its SupModList if not Module.LibraryClass: EdkLogger.error("build", OPTION_MISSING, "Module type [%s] is not supported by library instance [%s]" \ % (ModuleType, LibraryPath), File=FileName, ExtraData="consumed by [%s]" % str(Module)) else: return [] LibraryInstance[LibraryClassName] = LibraryModule LibraryConsumerList.append(LibraryModule) if not Module.LibraryClass: EdkLogger.verbose("\t" + str(LibraryClassName) + " : " + str(LibraryModule)) else: LibraryModule = LibraryInstance[LibraryClassName] if LibraryModule is None: continue if LibraryModule.ConstructorList != [] and LibraryModule not in Constructor: Constructor.append(LibraryModule) # don't add current module itself to consumer list if M != Module: if M in ConsumedByList[LibraryModule]: continue ConsumedByList[LibraryModule].append(M) # # Initialize the sorted output list to the empty set # SortedLibraryList = [] # # Q <- Set of all nodes with no incoming edges # LibraryList = [] #LibraryInstance.values() Q = [] for LibraryClassName in LibraryInstance: M = LibraryInstance[LibraryClassName] LibraryList.append(M) if not ConsumedByList[M]: Q.append(M) # # start the DAG algorithm # while True: EdgeRemoved = True while Q == [] and EdgeRemoved: EdgeRemoved = False # for each node Item with a Constructor for Item in LibraryList: if Item not in Constructor: continue # for each Node without a constructor with an edge e from Item to Node for Node in ConsumedByList[Item]: if Node in Constructor: continue # remove edge e from the graph if Node has no constructor ConsumedByList[Item].remove(Node) EdgeRemoved = True if not ConsumedByList[Item]: # insert Item into Q Q.insert(0, Item) break if Q != []: break # DAG is done if there's no more incoming edge for all nodes if Q == []: break # remove node from Q Node = Q.pop() # output Node SortedLibraryList.append(Node) # for each node Item with an edge e from Node to Item do for Item in LibraryList: if Node not in ConsumedByList[Item]: continue # remove edge e from the graph ConsumedByList[Item].remove(Node) if ConsumedByList[Item]: continue # insert Item into Q, if Item has no other incoming edges Q.insert(0, Item) # # if any remaining node Item in the graph has a constructor and an incoming edge, then the graph has a cycle # for Item in LibraryList: if ConsumedByList[Item] and Item in Constructor and len(Constructor) > 1: if not Module.LibraryClass: ErrorMessage = "\tconsumed by " + "\n\tconsumed by ".join(str(L) for L in ConsumedByList[Item]) EdkLogger.error("build", BUILD_ERROR, 'Library [%s] with constructors has a cycle' % str(Item), ExtraData=ErrorMessage, File=FileName) else: return [] if Item not in SortedLibraryList: SortedLibraryList.append(Item) # # Build the list of constructor and destructor names # The DAG Topo sort produces the destructor order, so the list of constructors must generated in the reverse order # SortedLibraryList.reverse() Module.LibInstances = SortedLibraryList SortedLibraryList = [lib.SetReferenceModule(Module) for lib in SortedLibraryList] return SortedLibraryList
def FindExtendTool(KeyStringList, CurrentArchList, NameGuid): ToolDb = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDatabase # if user not specify filter, try to deduce it from global data. if KeyStringList is None or KeyStringList == []: Target = GenFdsGlobalVariable.TargetName ToolChain = GenFdsGlobalVariable.ToolChainTag if ToolChain not in ToolDb['TOOL_CHAIN_TAG']: EdkLogger.error("GenFds", GENFDS_ERROR, "Can not find external tool because tool tag %s is not defined in tools_def.txt!" % ToolChain) KeyStringList = [Target + '_' + ToolChain + '_' + CurrentArchList[0]] for Arch in CurrentArchList: if Target + '_' + ToolChain + '_' + Arch not in KeyStringList: KeyStringList.append(Target + '_' + ToolChain + '_' + Arch) if GenFdsGlobalVariable.GuidToolDefinition: if NameGuid in GenFdsGlobalVariable.GuidToolDefinition: return GenFdsGlobalVariable.GuidToolDefinition[NameGuid] ToolDefinition = ToolDefClassObject.ToolDefDict(GenFdsGlobalVariable.ConfDir).ToolsDefTxtDictionary ToolPathTmp = None ToolOption = None ToolPathKey = None ToolOptionKey = None KeyList = None for ToolDef in ToolDefinition.items(): if NameGuid.lower() == ToolDef[1].lower() : KeyList = ToolDef[0].split('_') Key = KeyList[0] + \ '_' + \ KeyList[1] + \ '_' + \ KeyList[2] if Key in KeyStringList and KeyList[4] == TAB_GUID: ToolPathKey = Key + '_' + KeyList[3] + '_PATH' ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS' ToolPath = ToolDefinition.get(ToolPathKey) ToolOption = ToolDefinition.get(ToolOptionKey) if ToolPathTmp is None: ToolPathTmp = ToolPath else: if ToolPathTmp != ToolPath: EdkLogger.error("GenFds", GENFDS_ERROR, "Don't know which tool to use, %s or %s ?" % (ToolPathTmp, ToolPath)) BuildOption = {} for Arch in CurrentArchList: Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] # key is (ToolChainFamily, ToolChain, CodeBase) for item in Platform.BuildOptions: if '_PATH' in item[1] or '_FLAGS' in item[1] or '_GUID' in item[1]: if not item[0] or (item[0] and GenFdsGlobalVariable.ToolChainFamily== item[0]): if item[1] not in BuildOption: BuildOption[item[1]] = Platform.BuildOptions[item] if BuildOption: ToolList = [TAB_TOD_DEFINES_TARGET, TAB_TOD_DEFINES_TOOL_CHAIN_TAG, TAB_TOD_DEFINES_TARGET_ARCH] for Index in range(2, -1, -1): for Key in list(BuildOption.keys()): List = Key.split('_') if List[Index] == '*': for String in ToolDb[ToolList[Index]]: if String in [Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]: List[Index] = String NewKey = '%s_%s_%s_%s_%s' % tuple(List) if NewKey not in BuildOption: BuildOption[NewKey] = BuildOption[Key] continue del BuildOption[Key] elif List[Index] not in ToolDb[ToolList[Index]]: del BuildOption[Key] if BuildOption: if not KeyList: for Op in BuildOption: if NameGuid == BuildOption[Op]: KeyList = Op.split('_') Key = KeyList[0] + '_' + KeyList[1] +'_' + KeyList[2] if Key in KeyStringList and KeyList[4] == TAB_GUID: ToolPathKey = Key + '_' + KeyList[3] + '_PATH' ToolOptionKey = Key + '_' + KeyList[3] + '_FLAGS' if ToolPathKey in BuildOption: ToolPathTmp = BuildOption[ToolPathKey] if ToolOptionKey in BuildOption: ToolOption = BuildOption[ToolOptionKey] GenFdsGlobalVariable.GuidToolDefinition[NameGuid] = (ToolPathTmp, ToolOption) return ToolPathTmp, ToolOption
GenFds.DisplayFvSpaceInfo(FdfParserObj) except FdfParser.Warning, X: EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError=False) ReturnCode = FORMAT_INVALID except FatalError, X: if Options.debug is not None: import traceback EdkLogger.quiet(traceback.format_exc()) ReturnCode = X.args[0] except: import traceback EdkLogger.error( "\nPython", CODE_ERROR, "Tools code failure", ExtraData="Please send email to [email protected] for help, attaching following call stack trace!\n", RaiseError=False ) EdkLogger.quiet(traceback.format_exc()) ReturnCode = CODE_ERROR finally: ClearDuplicatedInf() return ReturnCode gParamCheck = [] def SingleCheckCallback(option, opt_str, value, parser): if option not in gParamCheck: setattr(parser.values, option.dest, value) gParamCheck.append(option) else:
def TrimPreprocessedFile(Source, Target, ConvertHex, TrimLong): CreateDirectory(os.path.dirname(Target)) try: with open(Source, "r") as File: Lines = File.readlines() except IOError: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Source) except: EdkLogger.error("Trim", AUTOGEN_ERROR, "TrimPreprocessedFile: Error while processing file", File=Source) PreprocessedFile = "" InjectedFile = "" LineIndexOfOriginalFile = None NewLines = [] LineControlDirectiveFound = False for Index in range(len(Lines)): Line = Lines[Index] # # Find out the name of files injected by preprocessor from the lines # with Line Control directive # MatchList = gLineControlDirective.findall(Line) if MatchList != []: MatchList = MatchList[0] if len(MatchList) == 2: LineNumber = int(MatchList[0], 0) InjectedFile = MatchList[1] InjectedFile = os.path.normpath(InjectedFile) InjectedFile = os.path.normcase(InjectedFile) # The first injected file must be the preprocessed file itself if PreprocessedFile == "": PreprocessedFile = InjectedFile LineControlDirectiveFound = True continue elif PreprocessedFile == "" or InjectedFile != PreprocessedFile: continue if LineIndexOfOriginalFile is None: # # Any non-empty lines must be from original preprocessed file. # And this must be the first one. # LineIndexOfOriginalFile = Index EdkLogger.verbose("Found original file content starting from line %d" % (LineIndexOfOriginalFile + 1)) if TrimLong: Line = gLongNumberPattern.sub(r"\1", Line) # convert HEX number format if indicated if ConvertHex: Line = gHexNumberPattern.sub(r"0\2h", Line) else: Line = gHexNumberPattern.sub(r"\1\2", Line) # convert Decimal number format Line = gDecNumberPattern.sub(r"\1", Line) if LineNumber is not None: EdkLogger.verbose("Got line directive: line=%d" % LineNumber) # in case preprocessor removed some lines, like blank or comment lines if LineNumber <= len(NewLines): # possible? NewLines[LineNumber - 1] = Line else: if LineNumber > (len(NewLines) + 1): for LineIndex in range(len(NewLines), LineNumber-1): NewLines.append(TAB_LINE_BREAK) NewLines.append(Line) LineNumber = None EdkLogger.verbose("Now we have lines: %d" % len(NewLines)) else: NewLines.append(Line) # in case there's no line directive or linemarker found if (not LineControlDirectiveFound) and NewLines == []: MulPatternFlag = False SinglePatternFlag = False Brace = 0 for Index in range(len(Lines)): Line = Lines[Index] if MulPatternFlag == False and gTypedef_MulPattern.search(Line) is None: if SinglePatternFlag == False and gTypedef_SinglePattern.search(Line) is None: # remove "#pragram pack" directive if gPragmaPattern.search(Line) is None: NewLines.append(Line) continue elif SinglePatternFlag == False: SinglePatternFlag = True if Line.find(";") >= 0: SinglePatternFlag = False elif MulPatternFlag == False: # found "typedef struct, typedef union, union, struct", keep its position and set a flag MulPatternFlag = True # match { and } to find the end of typedef definition if Line.find("{") >= 0: Brace += 1 elif Line.find("}") >= 0: Brace -= 1 # "typedef struct, typedef union, union, struct" must end with a ";" if Brace == 0 and Line.find(";") >= 0: MulPatternFlag = False # save to file try: with open(Target, 'w') as File: File.writelines(NewLines) except: EdkLogger.error("Trim", FILE_OPEN_FAILURE, ExtraData=Target)
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.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) 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.append(AddIncludeHeader(IncludedFile+" --START")) #MU_CHANGE NewFileContent.extend(DoInclude(IncludedFile, CurrentIndent, IncludePathList, LocalSearchPath,IncludeFileList,filetype)) NewFileContent.append(AddIncludeHeader(IncludedFile+" --END")) #MU_CHANGE 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.append(AddIncludeHeader(IncludedFile+" --START")) #MU_CHANGE NewFileContent.extend(DoInclude(IncludedFile, '', IncludePathList, LocalSearchPath,IncludeFileList,filetype)) NewFileContent.append(AddIncludeHeader(IncludedFile+" --END")) #MU_CHANGE 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 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)
def ApplyPcdSetting(self, Ma, Pcds, Library=""): # for each PCD in module Module = Ma.Module for Name, Guid in Pcds: PcdInModule = Pcds[Name, Guid] # find out the PCD setting in platform if (Name, Guid) in self.Pcds: PcdInPlatform = self.Pcds[Name, Guid] else: PcdInPlatform = None # then override the settings if any self._OverridePcd(PcdInModule, PcdInPlatform, Module, Msg="DSC PCD sections", Library=Library) # resolve the VariableGuid value for SkuId in PcdInModule.SkuInfoList: Sku = PcdInModule.SkuInfoList[SkuId] if Sku.VariableGuid == '': continue Sku.VariableGuidValue = GuidValue(Sku.VariableGuid, self.PackageList, self.MetaFile.Path) if Sku.VariableGuidValue is None: PackageList = "\n\t".join(str(P) for P in self.PackageList) EdkLogger.error( 'build', RESOURCE_NOT_AVAILABLE, "Value of GUID [%s] is not found in" % Sku.VariableGuid, ExtraData=PackageList + "\n\t(used with %s.%s from module %s)" \ % (Guid, Name, str(Module)), File=self.MetaFile ) # override PCD settings with module specific setting ModuleScopePcds = self.DataPipe.Get("MOL_PCDS") if Module in self.Platform.Modules: PlatformModule = self.Platform.Modules[str(Module)] PCD_DATA = ModuleScopePcds.get(Ma.Guid, {}) mPcds = {(pcd.TokenCName, pcd.TokenSpaceGuidCName): pcd for pcd in PCD_DATA} for Key in mPcds: if self.BuildOptionPcd: for pcd in self.BuildOptionPcd: (TokenSpaceGuidCName, TokenCName, FieldName, pcdvalue, _) = pcd if (TokenCName, TokenSpaceGuidCName ) == Key and FieldName == "": PlatformModule.Pcds[Key].DefaultValue = pcdvalue PlatformModule.Pcds[ Key].PcdValueFromComm = pcdvalue break Flag = False if Key in Pcds: ToPcd = Pcds[Key] Flag = True elif Key in self.MixedPcd: for PcdItem in self.MixedPcd[Key]: if PcdItem in Pcds: ToPcd = Pcds[PcdItem] Flag = True break if Flag: self._OverridePcd( ToPcd, mPcds[Key], Module, Msg="DSC Components Module scoped PCD section", Library=Library) # use PCD value to calculate the MaxDatumSize when it is not specified for Name, Guid in Pcds: Pcd = Pcds[Name, Guid] if Pcd.DatumType == TAB_VOID and not Pcd.MaxDatumSize: Pcd.MaxSizeUserSet = None Value = Pcd.DefaultValue if not Value: Pcd.MaxDatumSize = '1' elif Value[0] == 'L': Pcd.MaxDatumSize = str((len(Value) - 2) * 2) elif Value[0] == '{': Pcd.MaxDatumSize = str(len(Value.split(','))) else: Pcd.MaxDatumSize = str(len(Value) - 1) return list(Pcds.values())
def GenerateVpdFile(self, MapFileName, BinFileName): #Open an VPD file to process try: fVpdFile = open(BinFileName, "wb") except: # Open failed EdkLogger.error("BPDG", BuildToolError.FILE_OPEN_FAILURE, "File open failed for %s" % self.VpdFileName, None) try: fMapFile = open(MapFileName, "w") except: # Open failed EdkLogger.error("BPDG", BuildToolError.FILE_OPEN_FAILURE, "File open failed for %s" % self.MapFileName, None) # Use a instance of BytesIO to cache data fStringIO = BytesIO() # Write the header of map file. try: fMapFile.write(st.MAP_FILE_COMMENT_TEMPLATE + "\n") except: EdkLogger.error( "BPDG", BuildToolError.FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." % self.MapFileName, None) for eachPcd in self.PcdFixedOffsetSizeList: # write map file try: fMapFile.write( "%s | %s | %s | %s | %s \n" % (eachPcd.PcdCName, eachPcd.SkuId, eachPcd.PcdOffset, eachPcd.PcdSize, eachPcd.PcdUnpackValue)) except: EdkLogger.error( "BPDG", BuildToolError.FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." % self.MapFileName, None) # Write Vpd binary file fStringIO.seek(eachPcd.PcdBinOffset) if isinstance(eachPcd.PcdValue, list): for i in range(len(eachPcd.PcdValue)): Value = eachPcd.PcdValue[i:i + 1] if isinstance(bytes(Value), str): fStringIO.write(chr(Value[0])) else: fStringIO.write(bytes(Value)) else: fStringIO.write(eachPcd.PcdValue) try: fVpdFile.write(fStringIO.getvalue()) except: EdkLogger.error( "BPDG", BuildToolError.FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." % self.VpdFileName, None) fStringIO.close() fVpdFile.close() fMapFile.close()
def ErrorLogger(msg, File=None, Line=None, ExtraData=None): EdkLogger.error('GenFds', GENFDS_ERROR, msg, File, Line, ExtraData)
def main(): global Options Options = myOptionParser() global Workspace Workspace = "" ArchList = None ReturnCode = 0 EdkLogger.Initialize() try: if Options.verbose != None: EdkLogger.SetLevel(EdkLogger.VERBOSE) GenFdsGlobalVariable.VerboseMode = True if Options.FixedAddress != None: GenFdsGlobalVariable.FixedLoadAddress = True if Options.quiet != None: EdkLogger.SetLevel(EdkLogger.QUIET) if Options.debug != None: EdkLogger.SetLevel(Options.debug + 1) GenFdsGlobalVariable.DebugLevel = Options.debug else: EdkLogger.SetLevel(EdkLogger.INFO) if (Options.Workspace == None): EdkLogger.error("GenFds", OPTION_MISSING, "WORKSPACE not defined", ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.") elif not os.path.exists(Options.Workspace): EdkLogger.error("GenFds", PARAMETER_INVALID, "WORKSPACE is invalid", ExtraData="Please use '-w' switch to pass it or set the WORKSPACE environment variable.") else: Workspace = os.path.normcase(Options.Workspace) GenFdsGlobalVariable.WorkSpaceDir = Workspace if 'EDK_SOURCE' in os.environ.keys(): GenFdsGlobalVariable.EdkSourceDir = os.path.normcase(os.environ['EDK_SOURCE']) if (Options.debug): GenFdsGlobalVariable.VerboseLogger( "Using Workspace:" + Workspace) os.chdir(GenFdsGlobalVariable.WorkSpaceDir) if (Options.filename): FdfFilename = Options.filename FdfFilename = GenFdsGlobalVariable.ReplaceWorkspaceMacro(FdfFilename) if FdfFilename[0:2] == '..': FdfFilename = os.path.realpath(FdfFilename) if not os.path.isabs (FdfFilename): FdfFilename = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, FdfFilename) if not os.path.exists(FdfFilename): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=FdfFilename) GenFdsGlobalVariable.FdfFile = FdfFilename GenFdsGlobalVariable.FdfFileTimeStamp = os.path.getmtime(FdfFilename) else: EdkLogger.error("GenFds", OPTION_MISSING, "Missing FDF filename") if (Options.BuildTarget): GenFdsGlobalVariable.TargetName = Options.BuildTarget else: EdkLogger.error("GenFds", OPTION_MISSING, "Missing build target") if (Options.ToolChain): GenFdsGlobalVariable.ToolChainTag = Options.ToolChain else: EdkLogger.error("GenFds", OPTION_MISSING, "Missing tool chain tag") if (Options.activePlatform): ActivePlatform = Options.activePlatform ActivePlatform = GenFdsGlobalVariable.ReplaceWorkspaceMacro(ActivePlatform) if ActivePlatform[0:2] == '..': ActivePlatform = os.path.realpath(ActivePlatform) if not os.path.isabs (ActivePlatform): ActivePlatform = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ActivePlatform) if not os.path.exists(ActivePlatform) : EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!") if os.path.normcase (ActivePlatform).find(Workspace) == 0: ActivePlatform = ActivePlatform[len(Workspace):] if len(ActivePlatform) > 0 : if ActivePlatform[0] == '\\' or ActivePlatform[0] == '/': ActivePlatform = ActivePlatform[1:] else: EdkLogger.error("GenFds", FILE_NOT_FOUND, "ActivePlatform doesn't exist!") else: EdkLogger.error("GenFds", OPTION_MISSING, "Missing active platform") GenFdsGlobalVariable.ActivePlatform = PathClass(NormPath(ActivePlatform), Workspace) if (Options.ConfDirectory): # Get alternate Conf location, if it is absolute, then just use the absolute directory name ConfDirectoryPath = os.path.normpath(Options.ConfDirectory) if ConfDirectoryPath.startswith('"'): ConfDirectoryPath = ConfDirectoryPath[1:] if ConfDirectoryPath.endswith('"'): ConfDirectoryPath = ConfDirectoryPath[:-1] if not os.path.isabs(ConfDirectoryPath): # Since alternate directory name is not absolute, the alternate directory is located within the WORKSPACE # This also handles someone specifying the Conf directory in the workspace. Using --conf=Conf ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, ConfDirectoryPath) else: # Get standard WORKSPACE/Conf, use the absolute path to the WORKSPACE/Conf ConfDirectoryPath = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, 'Conf') GenFdsGlobalVariable.ConfDir = ConfDirectoryPath BuildConfigurationFile = os.path.normpath(os.path.join(ConfDirectoryPath, "target.txt")) if os.path.isfile(BuildConfigurationFile) == True: TargetTxtClassObject.TargetTxtClassObject(BuildConfigurationFile) else: EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=BuildConfigurationFile) #Set global flag for build mode GlobalData.gIgnoreSource = Options.IgnoreSources if Options.Macros: for Pair in Options.Macros: if Pair.startswith('"'): Pair = Pair[1:] if Pair.endswith('"'): Pair = Pair[:-1] List = Pair.split('=') if len(List) == 2: if List[0].strip() == "EFI_SOURCE": GlobalData.gEfiSource = List[1].strip() GlobalData.gGlobalDefines["EFI_SOURCE"] = GlobalData.gEfiSource continue elif List[0].strip() == "EDK_SOURCE": GlobalData.gEdkSource = List[1].strip() GlobalData.gGlobalDefines["EDK_SOURCE"] = GlobalData.gEdkSource continue elif List[0].strip() in ["WORKSPACE", "TARGET", "TOOLCHAIN"]: GlobalData.gGlobalDefines[List[0].strip()] = List[1].strip() else: GlobalData.gCommandLineDefines[List[0].strip()] = List[1].strip() else: GlobalData.gCommandLineDefines[List[0].strip()] = "TRUE" os.environ["WORKSPACE"] = Workspace """call Workspace build create database""" GlobalData.gDatabasePath = os.path.normpath(os.path.join(ConfDirectoryPath, GlobalData.gDatabasePath)) BuildWorkSpace = WorkspaceDatabase(GlobalData.gDatabasePath) BuildWorkSpace.InitDatabase() # # Get files real name in workspace dir # GlobalData.gAllFiles = DirCache(Workspace) GlobalData.gWorkspace = Workspace if (Options.archList) : ArchList = Options.archList.split(',') else: # EdkLogger.error("GenFds", OPTION_MISSING, "Missing build ARCH") ArchList = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList TargetArchList = set(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON', Options.BuildTarget, Options.ToolChain].SupArchList) & set(ArchList) if len(TargetArchList) == 0: EdkLogger.error("GenFds", GENFDS_ERROR, "Target ARCH %s not in platform supported ARCH %s" % (str(ArchList), str(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, 'COMMON'].SupArchList))) for Arch in ArchList: GenFdsGlobalVariable.OutputDirFromDscDict[Arch] = NormPath(BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].OutputDirectory) GenFdsGlobalVariable.PlatformName = BuildWorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, Options.BuildTarget, Options.ToolChain].PlatformName if (Options.outputDir): OutputDirFromCommandLine = GenFdsGlobalVariable.ReplaceWorkspaceMacro(Options.outputDir) if not os.path.isabs (OutputDirFromCommandLine): OutputDirFromCommandLine = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, OutputDirFromCommandLine) for Arch in ArchList: GenFdsGlobalVariable.OutputDirDict[Arch] = OutputDirFromCommandLine else: for Arch in ArchList: GenFdsGlobalVariable.OutputDirDict[Arch] = os.path.join(GenFdsGlobalVariable.OutputDirFromDscDict[Arch], GenFdsGlobalVariable.TargetName + '_' + GenFdsGlobalVariable.ToolChainTag) for Key in GenFdsGlobalVariable.OutputDirDict: OutputDir = GenFdsGlobalVariable.OutputDirDict[Key] if OutputDir[0:2] == '..': OutputDir = os.path.realpath(OutputDir) if OutputDir[1] != ':': OutputDir = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, OutputDir) if not os.path.exists(OutputDir): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=OutputDir) GenFdsGlobalVariable.OutputDirDict[Key] = OutputDir """ Parse Fdf file, has to place after build Workspace as FDF may contain macros from DSC file """ FdfParserObj = FdfParser.FdfParser(FdfFilename) FdfParserObj.ParseFile() if FdfParserObj.CycleReferenceCheck(): EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Cycle Reference Detected in FDF file") if (Options.uiFdName) : if Options.uiFdName.upper() in FdfParserObj.Profile.FdDict.keys(): GenFds.OnlyGenerateThisFd = Options.uiFdName else: EdkLogger.error("GenFds", OPTION_VALUE_INVALID, "No such an FD in FDF file: %s" % Options.uiFdName) if (Options.uiFvName) : if Options.uiFvName.upper() in FdfParserObj.Profile.FvDict.keys(): GenFds.OnlyGenerateThisFv = Options.uiFvName else: EdkLogger.error("GenFds", OPTION_VALUE_INVALID, "No such an FV in FDF file: %s" % Options.uiFvName) if (Options.uiCapName) : if Options.uiCapName.upper() in FdfParserObj.Profile.CapsuleDict.keys(): GenFds.OnlyGenerateThisCap = Options.uiCapName else: EdkLogger.error("GenFds", OPTION_VALUE_INVALID, "No such a Capsule in FDF file: %s" % Options.uiCapName) """Modify images from build output if the feature of loading driver at fixed address is on.""" if GenFdsGlobalVariable.FixedLoadAddress: GenFds.PreprocessImage(BuildWorkSpace, GenFdsGlobalVariable.ActivePlatform) """Call GenFds""" GenFds.GenFd('', FdfParserObj, BuildWorkSpace, ArchList) """Generate GUID cross reference file""" GenFds.GenerateGuidXRefFile(BuildWorkSpace, ArchList) """Display FV space info.""" GenFds.DisplayFvSpaceInfo(FdfParserObj) except FdfParser.Warning, X: EdkLogger.error(X.ToolName, FORMAT_INVALID, File=X.FileName, Line=X.LineNumber, ExtraData=X.Message, RaiseError = False) ReturnCode = FORMAT_INVALID
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.PcdBinSize 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.PcdBinSize > 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.PcdBinSize < 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.PcdBinSize # 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].PcdBinSize 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.PcdBinSize 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.PcdBinSize 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 _PackByteArray(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)) ValueString = ValueString.strip() ValueString = ValueString.lstrip('{').strip('}') ValueList = ValueString.split(',') ValueList = [item.strip() for item in ValueList] if len(ValueList) > Size: EdkLogger.error( "BPDG", BuildToolError.RESOURCE_OVERFLOW, "The byte array %s is too large for size %d(File: %s Line: %s)" % (ValueString, Size, self.FileName, self.Lineno)) ReturnArray = array.array('B') for Index in xrange(len(ValueList)): Value = None if ValueList[Index].startswith('0x'): # translate hex value try: Value = int(ValueList[Index], 16) except: EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "The value item %s in byte array %s is an invalid HEX value.(File: %s Line: %s)" % \ (ValueList[Index], ValueString, self.FileName, self.Lineno)) else: # translate decimal value try: Value = int(ValueList[Index], 10) except: EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "The value item %s in byte array %s is an invalid DECIMAL value.(File: %s Line: %s)" % \ (ValueList[Index], ValueString, self.FileName, self.Lineno)) if Value > 255: EdkLogger.error("BPDG", BuildToolError.FORMAT_INVALID, "The value item %s in byte array %s do not in range 0 ~ 0xFF(File: %s Line: %s)" %\ (ValueList[Index], ValueString, self.FileName, self.Lineno)) ReturnArray.append(Value) for Index in xrange(len(ValueList), Size): ReturnArray.append(0) self.PcdValue = ReturnArray.tolist()
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+", 0) 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 = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66] UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid] fStringIO.write(''.join(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 = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2] VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid] fStringIO.write(''.join(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 GenFfs(self, Dict={}, FvChildAddr=[], FvParentAddr=None): if self.NameGuid != None and self.NameGuid.startswith('PCD('): PcdValue = GenFdsGlobalVariable.GetPcdValue(self.NameGuid) if len(PcdValue) == 0: EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \ % (self.NameGuid)) if PcdValue.startswith('{'): PcdValue = GuidStructureByteArrayToGuidString(PcdValue) RegistryGuidStr = PcdValue if len(RegistryGuidStr) == 0: EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \ % (self.NameGuid)) self.NameGuid = RegistryGuidStr OutputDir = os.path.join(GenFdsGlobalVariable.FfsDir, self.NameGuid) if not os.path.exists(OutputDir): os.makedirs(OutputDir) Dict.update(self.DefineVarDict) SectionAlignments = None if self.FvName != None: Buffer = StringIO.StringIO('') if self.FvName.upper( ) not in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): EdkLogger.error( "GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (self.FvName)) Fv = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get( self.FvName.upper()) FileName = Fv.AddToBuffer(Buffer) SectionFiles = [FileName] elif self.FdName != None: if self.FdName.upper( ) not in GenFdsGlobalVariable.FdfParser.Profile.FdDict.keys(): EdkLogger.error( "GenFds", GENFDS_ERROR, "FD (%s) is NOT described in FDF file!" % (self.FdName)) Fd = GenFdsGlobalVariable.FdfParser.Profile.FdDict.get( self.FdName.upper()) FileName = Fd.GenFd() SectionFiles = [FileName] elif self.FileName != None: self.FileName = GenFdsGlobalVariable.ReplaceWorkspaceMacro( self.FileName) #Replace $(SAPCE) with real space self.FileName = self.FileName.replace('$(SPACE)', ' ') SectionFiles = [ GenFdsGlobalVariable.MacroExtend(self.FileName, Dict) ] else: SectionFiles = [] Index = 0 SectionAlignments = [] for section in self.SectionList: Index = Index + 1 SecIndex = '%d' % Index # process the inside FvImage from FvSection or GuidSection if FvChildAddr != []: if isinstance(section, FvImageSection): section.FvAddr = FvChildAddr.pop(0) elif isinstance(section, GuidSection): section.FvAddr = FvChildAddr if FvParentAddr != None and isinstance(section, GuidSection): section.FvParentAddr = FvParentAddr if self.KeepReloc == False: section.KeepReloc = False sectList, align = section.GenSection(OutputDir, self.NameGuid, SecIndex, self.KeyStringList, None, Dict) if sectList != []: for sect in sectList: SectionFiles.append(sect) SectionAlignments.append(align) # # Prepare the parameter # FfsFileOutput = os.path.join(OutputDir, self.NameGuid + '.ffs') GenFdsGlobalVariable.GenerateFfs(FfsFileOutput, SectionFiles, Ffs.Ffs.FdfFvFileTypeToFileType.get( self.FvFileType), self.NameGuid, Fixed=self.Fixed, CheckSum=self.CheckSum, Align=self.Alignment, SectionAlign=SectionAlignments) return FfsFileOutput
def __init__(self, FileList = []): self.ImageFilesDict = {} self.ImageIDList = [] for File in FileList: if File is None: EdkLogger.error("Image Definition File Parser", PARSER_ERROR, 'No Image definition file is given.') try: IdfFile = open(LongFilePath(File.Path), mode='r') FileIn = IdfFile.read() IdfFile.close() except: EdkLogger.error("build", FILE_OPEN_FAILURE, ExtraData=File) ImageFileList = [] for Line in FileIn.splitlines(): Line = Line.strip() Line = StripComments(Line) if len(Line) == 0: continue LineNo = GetLineNo(FileIn, Line, False) if not Line.startswith('#image '): EdkLogger.error("Image Definition File Parser", PARSER_ERROR, 'The %s in Line %s of File %s is invalid.' % (Line, LineNo, File.Path)) if Line.find('#image ') >= 0: LineDetails = Line.split() Len = len(LineDetails) if Len != 3 and Len != 4: EdkLogger.error("Image Definition File Parser", PARSER_ERROR, 'The format is not match #image IMAGE_ID [TRANSPARENT] ImageFileName in Line %s of File %s.' % (LineNo, File.Path)) if Len == 4 and LineDetails[2] != 'TRANSPARENT': EdkLogger.error("Image Definition File Parser", PARSER_ERROR, 'Please use the keyword "TRANSPARENT" to describe the transparency setting in Line %s of File %s.' % (LineNo, File.Path)) MatchString = gIdentifierPattern.match(LineDetails[1]) if MatchString is None: EdkLogger.error('Image Definition File Parser', FORMAT_INVALID, 'The Image token name %s defined in Idf file %s contains the invalid character.' % (LineDetails[1], File.Path)) if LineDetails[1] not in self.ImageIDList: self.ImageIDList.append(LineDetails[1]) else: EdkLogger.error("Image Definition File Parser", PARSER_ERROR, 'The %s in Line %s of File %s is already defined.' % (LineDetails[1], LineNo, File.Path)) if Len == 4: ImageFile = ImageFileObject(LineDetails[Len-1], LineDetails[1], True) else: ImageFile = ImageFileObject(LineDetails[Len-1], LineDetails[1], False) ImageFileList.append(ImageFile) if ImageFileList: self.ImageFilesDict[File] = ImageFileList
def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr): if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'): if Rule.KeepReloc != None: self.KeepRelocFromRule = Rule.KeepReloc SectFiles = [] SectAlignments = [] Index = 1 HasGneratedFlag = False for Sect in Rule.SectionList: SecIndex = '%d' %Index SectList = [] # # Convert Fv Section Type for PI1.1 SMM driver. # if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A: if Sect.SectionType == 'DXE_DEPEX': Sect.SectionType = 'SMM_DEPEX' # # Framework SMM Driver has no SMM_DEPEX section type # if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A: if Sect.SectionType == 'SMM_DEPEX': EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName) # # process the inside FvImage from FvSection or GuidSection # if FvChildAddr != []: if isinstance(Sect, FvImageSection): Sect.FvAddr = FvChildAddr.pop(0) elif isinstance(Sect, GuidSection): Sect.FvAddr = FvChildAddr if FvParentAddr != None and isinstance(Sect, GuidSection): Sect.FvParentAddr = FvParentAddr if Rule.KeyStringList != []: SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self) else : SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self) if not HasGneratedFlag: UniVfrOffsetFileSection = "" ModuleFileName = os.path.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName) InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch] # # Search the source list in InfData to find if there are .vfr file exist. # VfrUniBaseName = {} VfrUniOffsetList = [] for SourceFile in InfData.Sources: if SourceFile.Type.upper() == ".VFR" : # # search the .map file to find the offset of vfr binary in the PE32+/TE file. # VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin") if SourceFile.Type.upper() == ".UNI" : # # search the .map file to find the offset of Uni strings binary in the PE32+/TE file. # VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings") if len(VfrUniBaseName) > 0: VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName) # # Generate the Raw data of raw section # os.path.join( self.OutputPath, self.BaseName + '.offset') UniVfrOffsetFileName = os.path.join( self.OutputPath, self.BaseName + '.offset') UniVfrOffsetFileSection = os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw') self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName) UniVfrOffsetFileNameList = [] UniVfrOffsetFileNameList.append(UniVfrOffsetFileName) """Call GenSection""" GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection, UniVfrOffsetFileNameList, "EFI_SECTION_RAW" ) os.remove(UniVfrOffsetFileName) SectList.append(UniVfrOffsetFileSection) HasGneratedFlag = True for SecName in SectList : SectFiles.append(SecName) SectAlignments.append(Align) Index = Index + 1 return SectFiles, SectAlignments
def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, vtfDict=None, MacroDict={}, Flag=False): Size = self.Size if not Flag: GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset) GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" % Size) GenFdsGlobalVariable.SharpCounter = 0 if Flag and (self.RegionType != BINARY_FILE_TYPE_FV): return if self.RegionType == BINARY_FILE_TYPE_FV: # # Get Fv from FvDict # self.FvAddress = int(BaseAddress, 16) + self.Offset FvBaseAddress = '0x%X' % self.FvAddress FvOffset = 0 for RegionData in self.RegionDataList: FileName = None if RegionData.endswith(".fv"): RegionData = GenFdsGlobalVariable.MacroExtend( RegionData, MacroDict) if not Flag: GenFdsGlobalVariable.InfLogger( ' Region FV File Name = .fv : %s' % RegionData) if RegionData[1] != ':': RegionData = mws.join( GenFdsGlobalVariable.WorkSpaceDir, RegionData) if not os.path.exists(RegionData): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) FileName = RegionData elif RegionData.upper() + 'fv' in ImageBinDict: if not Flag: GenFdsGlobalVariable.InfLogger(' Region Name = FV') FileName = ImageBinDict[RegionData.upper() + 'fv'] else: # # Generate FvImage. # FvObj = None if RegionData.upper( ) in GenFdsGlobalVariable.FdfParser.Profile.FvDict: FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict[ RegionData.upper()] if FvObj is not None: if not Flag: GenFdsGlobalVariable.InfLogger( ' Region Name = FV') # # Call GenFv tool # self.BlockInfoOfRegion(BlockSizeList, FvObj) self.FvAddress = self.FvAddress + FvOffset FvAlignValue = GenFdsGlobalVariable.GetAlignment( FvObj.FvAlignment) if self.FvAddress % FvAlignValue != 0: EdkLogger.error( "GenFds", GENFDS_ERROR, "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment)) FvBuffer = BytesIO('') FvBaseAddress = '0x%X' % self.FvAddress BlockSize = None BlockNum = None FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict, Flag=Flag) if Flag: continue FvBufferLen = len(FvBuffer.getvalue()) if FvBufferLen > Size: FvBuffer.close() EdkLogger.error( "GenFds", GENFDS_ERROR, "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size)) # # Put the generated image into FD buffer. # Buffer.write(FvBuffer.getvalue()) FvBuffer.close() FvOffset = FvOffset + FvBufferLen Size = Size - FvBufferLen continue else: EdkLogger.error( "GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData)) # # Add the exist Fv image into FD buffer # if not Flag: if FileName is not None: FileLength = os.stat(FileName)[ST_SIZE] if FileLength > Size: EdkLogger.error("GenFds", GENFDS_ERROR, "Size of FV File (%s) is larger than Region Size 0x%X specified." \ % (RegionData, Size)) BinFile = open(FileName, 'rb') Buffer.write(BinFile.read()) BinFile.close() Size = Size - FileLength # # Pad the left buffer # if not Flag: self.PadBuffer(Buffer, ErasePolarity, Size) if self.RegionType == 'CAPSULE': # # Get Capsule from Capsule Dict # for RegionData in self.RegionDataList: if RegionData.endswith(".cap"): RegionData = GenFdsGlobalVariable.MacroExtend( RegionData, MacroDict) GenFdsGlobalVariable.InfLogger( ' Region CAPSULE Image Name = .cap : %s' % RegionData) if RegionData[1] != ':': RegionData = mws.join( GenFdsGlobalVariable.WorkSpaceDir, RegionData) if not os.path.exists(RegionData): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) FileName = RegionData elif RegionData.upper() + 'cap' in ImageBinDict: GenFdsGlobalVariable.InfLogger(' Region Name = CAPSULE') FileName = ImageBinDict[RegionData.upper() + 'cap'] else: # # Generate Capsule image and Put it into FD buffer # CapsuleObj = None if RegionData.upper( ) in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict: CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[ RegionData.upper()] if CapsuleObj is not None: CapsuleObj.CapsuleName = RegionData.upper() GenFdsGlobalVariable.InfLogger( ' Region Name = CAPSULE') # # Call GenFv tool to generate Capsule Image # FileName = CapsuleObj.GenCapsule() CapsuleObj.CapsuleName = None else: EdkLogger.error( "GenFds", GENFDS_ERROR, "Capsule (%s) is NOT described in FDF file!" % (RegionData)) # # Add the capsule image into FD buffer # FileLength = os.stat(FileName)[ST_SIZE] if FileLength > Size: EdkLogger.error("GenFds", GENFDS_ERROR, "Size 0x%X of Capsule File (%s) is larger than Region Size 0x%X specified." \ % (FileLength, RegionData, Size)) BinFile = open(FileName, 'rb') Buffer.write(BinFile.read()) BinFile.close() Size = Size - FileLength # # Pad the left buffer # self.PadBuffer(Buffer, ErasePolarity, Size) if self.RegionType in ('FILE', 'INF'): for RegionData in self.RegionDataList: if self.RegionType == 'INF': RegionData.__InfParse__(None) if len(RegionData.BinFileList) != 1: EdkLogger.error( 'GenFds', GENFDS_ERROR, 'INF in FD region can only contain one binary: %s' % RegionData) File = RegionData.BinFileList[0] RegionData = RegionData.PatchEfiFile(File.Path, File.Type) else: RegionData = GenFdsGlobalVariable.MacroExtend( RegionData, MacroDict) if RegionData[1] != ':': RegionData = mws.join( GenFdsGlobalVariable.WorkSpaceDir, RegionData) if not os.path.exists(RegionData): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) # # Add the file image into FD buffer # FileLength = os.stat(RegionData)[ST_SIZE] if FileLength > Size: EdkLogger.error("GenFds", GENFDS_ERROR, "Size of File (%s) is larger than Region Size 0x%X specified." \ % (RegionData, Size)) GenFdsGlobalVariable.InfLogger(' Region File Name = %s' % RegionData) BinFile = open(RegionData, 'rb') Buffer.write(BinFile.read()) BinFile.close() Size = Size - FileLength # # Pad the left buffer # self.PadBuffer(Buffer, ErasePolarity, Size) if self.RegionType == 'DATA': GenFdsGlobalVariable.InfLogger(' Region Name = DATA') DataSize = 0 for RegionData in self.RegionDataList: Data = RegionData.split(',') DataSize = DataSize + len(Data) if DataSize > Size: EdkLogger.error( "GenFds", GENFDS_ERROR, "Size of DATA is larger than Region Size ") else: for item in Data: Buffer.write(pack('B', int(item, 16))) Size = Size - DataSize # # Pad the left buffer # self.PadBuffer(Buffer, ErasePolarity, Size) if self.RegionType is None: GenFdsGlobalVariable.InfLogger(' Region Name = None') self.PadBuffer(Buffer, ErasePolarity, Size)
def GenFfs(self, FvName, Dict={}, IsMakefile=False): DXE_GUID = "FC510EE7-FFDC-11D4-BD41-0080C73C8881" PEI_GUID = "1B45CC0A-156A-428A-AF62-49864DA0E6E6" Buffer = StringIO.StringIO('') AprioriFileGuid = DXE_GUID if self.AprioriType == "PEI": AprioriFileGuid = PEI_GUID OutputAprFilePath = os.path.join (GenFdsGlobalVariable.WorkSpaceDir, \ GenFdsGlobalVariable.FfsDir,\ AprioriFileGuid + FvName) if not os.path.exists(OutputAprFilePath): os.makedirs(OutputAprFilePath) OutputAprFileName = os.path.join( OutputAprFilePath, \ AprioriFileGuid + FvName + '.Apri' ) AprFfsFileName = os.path.join (OutputAprFilePath,\ AprioriFileGuid + FvName + '.Ffs') Dict.update(self.DefineVarDict) InfFileName = None for FfsObj in self.FfsList: Guid = "" if isinstance(FfsObj, FfsFileStatement.FileStatement): Guid = FfsObj.NameGuid else: InfFileName = NormPath(FfsObj.InfFileName) Arch = FfsObj.GetCurrentArch() if Arch != None: Dict['$(ARCH)'] = Arch InfFileName = GenFdsGlobalVariable.MacroExtend( InfFileName, Dict, Arch) if Arch != None: Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[ PathClass(InfFileName, GenFdsGlobalVariable. WorkSpaceDir), Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] Guid = Inf.Guid else: Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[ PathClass(InfFileName, GenFdsGlobalVariable. WorkSpaceDir), 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag] Guid = Inf.Guid self.BinFileList = Inf.Module.Binaries if self.BinFileList == []: EdkLogger.error("GenFds", RESOURCE_NOT_AVAILABLE, "INF %s not found in build ARCH %s!" \ % (InfFileName, GenFdsGlobalVariable.ArchList)) GuidPart = Guid.split('-') Buffer.write(pack('I', long(GuidPart[0], 16))) Buffer.write(pack('H', int(GuidPart[1], 16))) Buffer.write(pack('H', int(GuidPart[2], 16))) for Num in range(2): Char = GuidPart[3][Num * 2:Num * 2 + 2] Buffer.write(pack('B', int(Char, 16))) for Num in range(6): Char = GuidPart[4][Num * 2:Num * 2 + 2] Buffer.write(pack('B', int(Char, 16))) SaveFileOnChange(OutputAprFileName, Buffer.getvalue()) RawSectionFileName = os.path.join( OutputAprFilePath, \ AprioriFileGuid + FvName + '.raw' ) MakefilePath = None if IsMakefile: if not InfFileName: return None MakefilePath = InfFileName, Arch GenFdsGlobalVariable.GenerateSection(RawSectionFileName, [OutputAprFileName], 'EFI_SECTION_RAW', IsMakefile=IsMakefile) GenFdsGlobalVariable.GenerateFfs(AprFfsFileName, [RawSectionFileName], 'EFI_FV_FILETYPE_FREEFORM', AprioriFileGuid, MakefilePath=MakefilePath) return AprFfsFileName
def ParseSectionHeader(self, LineIndex): self._RuleInfo = tdict(True, 2) self._BuildTypeList = [] self._ArchList = [] self._FamilyList = [] self._TotalToolChainFamilySet = set() FileType = '' RuleNameList = self.RuleContent[LineIndex][1:-1].split(',') for RuleName in RuleNameList: Arch = 'COMMON' BuildType = 'COMMON' TokenList = [ Token.strip().upper() for Token in RuleName.split('.') ] # old format: Build.File-Type if TokenList[0] == "BUILD": if len(TokenList) == 1: EdkLogger.error("build", FORMAT_INVALID, "Invalid rule section", File=self.RuleFile, Line=LineIndex + 1, ExtraData=self.RuleContent[LineIndex]) FileType = TokenList[1] if FileType == '': EdkLogger.error("build", FORMAT_INVALID, "No file type given", File=self.RuleFile, Line=LineIndex + 1, ExtraData=self.RuleContent[LineIndex]) if self._FileTypePattern.match(FileType) == None: EdkLogger.error( "build", FORMAT_INVALID, File=self.RuleFile, Line=LineIndex + 1, ExtraData= "Only character, number (non-first character), '_' and '-' are allowed in file type" ) # new format: File-Type.Build-Type.Arch else: if FileType == '': FileType = TokenList[0] elif FileType != TokenList[0]: EdkLogger.error( "build", FORMAT_INVALID, "Different file types are not allowed in the same rule section", File=self.RuleFile, Line=LineIndex + 1, ExtraData=self.RuleContent[LineIndex]) if len(TokenList) > 1: BuildType = TokenList[1] if len(TokenList) > 2: Arch = TokenList[2] if BuildType not in self._BuildTypeList: self._BuildTypeList.append(BuildType) if Arch not in self._ArchList: self._ArchList.append(Arch) if 'COMMON' in self._BuildTypeList and len(self._BuildTypeList) > 1: EdkLogger.error( "build", FORMAT_INVALID, "Specific build types must not be mixed with common one", File=self.RuleFile, Line=LineIndex + 1, ExtraData=self.RuleContent[LineIndex]) if 'COMMON' in self._ArchList and len(self._ArchList) > 1: EdkLogger.error("build", FORMAT_INVALID, "Specific ARCH must not be mixed with common one", File=self.RuleFile, Line=LineIndex + 1, ExtraData=self.RuleContent[LineIndex]) self._FileType = FileType self._State = self._Section self.FileTypeList.add(FileType)
def _PackIntValue(self, IntValue, Size): if Size not in _FORMAT_CHAR.keys(): 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)) if Size == 1: if IntValue < 0: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "PCD can't be set to negative value %d for PCD %s in UINT8 datum type(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno)) elif IntValue >= 0x100: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Too large PCD value %d for datum type UINT8 for PCD %s(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno)) elif Size == 2: if IntValue < 0: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "PCD can't be set to negative value %d for PCD %s in UINT16 datum type(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno)) elif IntValue >= 0x10000: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Too large PCD value %d for datum type UINT16 for PCD %s(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno)) elif Size == 4: if IntValue < 0: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "PCD can't be set to negative value %d for PCD %s in UINT32 datum type(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno)) elif IntValue >= 0x100000000: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Too large PCD value %d for datum type UINT32 for PCD %s(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno)) elif Size == 8: if IntValue < 0: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "PCD can't be set to negative value %d for PCD %s in UINT32 datum type(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno)) elif IntValue >= 0x10000000000000000: EdkLogger.error( "BPDG", BuildToolError.FORMAT_INVALID, "Too large PCD value %d for datum type UINT32 for PCD %s(File: %s Line: %s)." % (IntValue, self.PcdCName, self.FileName, self.Lineno)) else: 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)) 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 GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile=False): if self.FileName is not None and self.FileName.startswith('PCD('): self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName) """Prepare the parameter of GenSection""" if FfsInf is not None: InfFileName = FfsInf.InfFileName SectionType = FfsInf.__ExtendMacro__(self.SectionType) Filename = FfsInf.__ExtendMacro__(self.FileName) BuildNum = FfsInf.__ExtendMacro__(self.BuildNum) StringData = FfsInf.__ExtendMacro__(self.StringData) ModuleNameStr = FfsInf.__ExtendMacro__('$(MODULE_NAME)') NoStrip = True if FfsInf.ModuleType in ( SUP_MODULE_SEC, SUP_MODULE_PEI_CORE, SUP_MODULE_PEIM, SUP_MODULE_MM_CORE_STANDALONE) and SectionType in ( BINARY_FILE_TYPE_TE, BINARY_FILE_TYPE_PE32): if FfsInf.KeepReloc is not None: NoStrip = FfsInf.KeepReloc elif FfsInf.KeepRelocFromRule is not None: NoStrip = FfsInf.KeepRelocFromRule elif self.KeepReloc is not None: NoStrip = self.KeepReloc elif FfsInf.ShadowFromInfFile is not None: NoStrip = FfsInf.ShadowFromInfFile else: EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s apply rule for None!" % ModuleName) """If the file name was pointed out, add it in FileList""" FileList = [] if Filename is not None: Filename = GenFdsGlobalVariable.MacroExtend(Filename, Dict) # check if the path is absolute or relative if os.path.isabs(Filename): Filename = os.path.normpath(Filename) else: Filename = os.path.normpath( os.path.join(FfsInf.EfiOutputPath, Filename)) if not self.Optional: FileList.append(Filename) elif os.path.exists(Filename): FileList.append(Filename) elif IsMakefile: SuffixMap = FfsInf.GetFinalTargetSuffixMap() if '.depex' in SuffixMap: FileList.append(Filename) else: FileList, IsSect = Section.Section.GetFileList( FfsInf, self.FileType, self.FileExtension, Dict, IsMakefile=IsMakefile) if IsSect: return FileList, self.Alignment Index = 0 Align = self.Alignment """ If Section type is 'VERSION'""" OutputFileList = [] if SectionType == 'VERSION': InfOverrideVerString = False if FfsInf.Version is not None: #StringData = FfsInf.Version BuildNum = FfsInf.Version InfOverrideVerString = True if InfOverrideVerString: #VerTuple = ('-n', '"' + StringData + '"') if BuildNum is not None and BuildNum != '': BuildNumTuple = ('-j', BuildNum) else: BuildNumTuple = tuple() Num = SecNum OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) GenFdsGlobalVariable.GenerateSection( OutputFile, [], 'EFI_SECTION_VERSION', #Ui=StringData, Ver=BuildNum, IsMakefile=IsMakefile) OutputFileList.append(OutputFile) elif FileList != []: for File in FileList: Index = Index + 1 Num = '%s.%d' % (SecNum, Index) OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType)) f = open(File, 'r') VerString = f.read() f.close() BuildNum = VerString if BuildNum is not None and BuildNum != '': BuildNumTuple = ('-j', BuildNum) GenFdsGlobalVariable.GenerateSection( OutputFile, [], 'EFI_SECTION_VERSION', #Ui=VerString, Ver=BuildNum, IsMakefile=IsMakefile) OutputFileList.append(OutputFile) else: BuildNum = StringData if BuildNum is not None and BuildNum != '': BuildNumTuple = ('-j', BuildNum) else: BuildNumTuple = tuple() BuildNumString = ' ' + ' '.join(BuildNumTuple) #if VerString == '' and if BuildNumString == '': if self.Optional == True: GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") return [], None else: EdkLogger.error( "GenFds", GENFDS_ERROR, "File: %s miss Version Section value" % InfFileName) Num = SecNum OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) GenFdsGlobalVariable.GenerateSection( OutputFile, [], 'EFI_SECTION_VERSION', #Ui=VerString, Ver=BuildNum, IsMakefile=IsMakefile) OutputFileList.append(OutputFile) # # If Section Type is BINARY_FILE_TYPE_UI # elif SectionType == BINARY_FILE_TYPE_UI: InfOverrideUiString = False if FfsInf.Ui is not None: StringData = FfsInf.Ui InfOverrideUiString = True if InfOverrideUiString: Num = SecNum if IsMakefile and StringData == ModuleNameStr: StringData = "$(MODULE_NAME)" OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) GenFdsGlobalVariable.GenerateSection( OutputFile, [], 'EFI_SECTION_USER_INTERFACE', Ui=StringData, IsMakefile=IsMakefile) OutputFileList.append(OutputFile) elif FileList != []: for File in FileList: Index = Index + 1 Num = '%s.%d' % (SecNum, Index) OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType)) f = open(File, 'r') UiString = f.read() f.close() if IsMakefile and UiString == ModuleNameStr: UiString = "$(MODULE_NAME)" GenFdsGlobalVariable.GenerateSection( OutputFile, [], 'EFI_SECTION_USER_INTERFACE', Ui=UiString, IsMakefile=IsMakefile) OutputFileList.append(OutputFile) else: if StringData is not None and len(StringData) > 0: UiTuple = ('-n', '"' + StringData + '"') else: UiTuple = tuple() if self.Optional == True: GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") return '', None else: EdkLogger.error( "GenFds", GENFDS_ERROR, "File: %s miss UI Section value" % InfFileName) Num = SecNum if IsMakefile and StringData == ModuleNameStr: StringData = "$(MODULE_NAME)" OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType)) GenFdsGlobalVariable.GenerateSection( OutputFile, [], 'EFI_SECTION_USER_INTERFACE', Ui=StringData, IsMakefile=IsMakefile) OutputFileList.append(OutputFile) else: """If File List is empty""" if FileList == []: if self.Optional == True: GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!") return [], None else: EdkLogger.error( "GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName)) else: """Convert the File to Section file one by one """ for File in FileList: """ Copy Map file to FFS output path """ Index = Index + 1 Num = '%s.%d' % (SecNum, Index) OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType)) File = GenFdsGlobalVariable.MacroExtend(File, Dict) #Get PE Section alignment when align is set to AUTO if self.Alignment == 'Auto' and ( SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE): ImageObj = PeImageClass(File) if ImageObj.SectionAlignment < 0x400: Align = str(ImageObj.SectionAlignment) elif ImageObj.SectionAlignment < 0x100000: Align = str( ImageObj.SectionAlignment // 0x400) + 'K' else: Align = str( ImageObj.SectionAlignment // 0x100000) + 'M' if File[(len(File) - 4):] == '.efi': MapFile = File.replace('.efi', '.map') CopyMapFile = os.path.join(OutputPath, ModuleName + '.map') if IsMakefile: if GenFdsGlobalVariable.CopyList == []: GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)] else: GenFdsGlobalVariable.CopyList.append( (MapFile, CopyMapFile)) else: if os.path.exists(MapFile): if not os.path.exists(CopyMapFile) or \ (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)): CopyLongFilePath(MapFile, CopyMapFile) if not NoStrip: FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi') if IsMakefile: if GenFdsGlobalVariable.CopyList == []: GenFdsGlobalVariable.CopyList = [ (File, FileBeforeStrip) ] else: GenFdsGlobalVariable.CopyList.append( (File, FileBeforeStrip)) else: if not os.path.exists(FileBeforeStrip) or \ (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)): CopyLongFilePath(File, FileBeforeStrip) StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped') GenFdsGlobalVariable.GenerateFirmwareImage( StrippedFile, [File], Strip=True, IsMakefile=IsMakefile) File = StrippedFile """For TE Section call GenFw to generate TE image""" if SectionType == BINARY_FILE_TYPE_TE: TeFile = os.path.join(OutputPath, ModuleName + 'Te.raw') GenFdsGlobalVariable.GenerateFirmwareImage( TeFile, [File], Type='te', IsMakefile=IsMakefile) File = TeFile """Call GenSection""" GenFdsGlobalVariable.GenerateSection( OutputFile, [File], Section.Section.SectionType.get(SectionType), IsMakefile=IsMakefile) OutputFileList.append(OutputFile) return OutputFileList, Align
def AddToBuffer(self, Buffer, BaseAddress, BlockSizeList, ErasePolarity, ImageBinDict, vtfDict=None, MacroDict={}): Size = self.Size GenFdsGlobalVariable.InfLogger('\nGenerate Region at Offset 0x%X' % self.Offset) GenFdsGlobalVariable.InfLogger(" Region Size = 0x%X" % Size) GenFdsGlobalVariable.SharpCounter = 0 if self.RegionType == 'FV': # # Get Fv from FvDict # RegionBlockSize = self.BlockSizeOfRegion(BlockSizeList) RegionBlockNum = self.BlockNumOfRegion(RegionBlockSize) self.FvAddress = int(BaseAddress, 16) + self.Offset FvBaseAddress = '0x%X' % self.FvAddress FvOffset = 0 for RegionData in self.RegionDataList: FileName = None if RegionData.endswith(".fv"): RegionData = GenFdsGlobalVariable.MacroExtend( RegionData, MacroDict) GenFdsGlobalVariable.InfLogger( ' Region FV File Name = .fv : %s' % RegionData) if RegionData[1] != ':': RegionData = os.path.join( GenFdsGlobalVariable.WorkSpaceDir, RegionData) if not os.path.exists(RegionData): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) FileName = RegionData elif RegionData.upper() + 'fv' in ImageBinDict.keys(): GenFdsGlobalVariable.InfLogger(' Region Name = FV') FileName = ImageBinDict[RegionData.upper() + 'fv'] else: # # Generate FvImage. # FvObj = None if RegionData.upper( ) in GenFdsGlobalVariable.FdfParser.Profile.FvDict.keys(): FvObj = GenFdsGlobalVariable.FdfParser.Profile.FvDict.get( RegionData.upper()) if FvObj != None: GenFdsGlobalVariable.InfLogger(' Region Name = FV') # # Call GenFv tool # BlockSize = RegionBlockSize BlockNum = RegionBlockNum if FvObj.BlockSizeList != []: if FvObj.BlockSizeList[0][0] != None: BlockSize = FvObj.BlockSizeList[0][0] if FvObj.BlockSizeList[0][1] != None: BlockNum = FvObj.BlockSizeList[0][1] self.FvAddress = self.FvAddress + FvOffset FvAlignValue = self.GetFvAlignValue(FvObj.FvAlignment) if self.FvAddress % FvAlignValue != 0: EdkLogger.error( "GenFds", GENFDS_ERROR, "FV (%s) is NOT %s Aligned!" % (FvObj.UiFvName, FvObj.FvAlignment)) FvBuffer = StringIO.StringIO('') FvBaseAddress = '0x%X' % self.FvAddress FvObj.AddToBuffer(FvBuffer, FvBaseAddress, BlockSize, BlockNum, ErasePolarity, vtfDict) if FvBuffer.len > Size: FvBuffer.close() EdkLogger.error( "GenFds", GENFDS_ERROR, "Size of FV (%s) is larger than Region Size 0x%X specified." % (RegionData, Size)) # # Put the generated image into FD buffer. # Buffer.write(FvBuffer.getvalue()) FvBuffer.close() FvOffset = FvOffset + FvBuffer.len Size = Size - FvBuffer.len continue else: EdkLogger.error( "GenFds", GENFDS_ERROR, "FV (%s) is NOT described in FDF file!" % (RegionData)) # # Add the exist Fv image into FD buffer # if FileName != None: FileLength = os.stat(FileName)[ST_SIZE] if FileLength > Size: EdkLogger.error("GenFds", GENFDS_ERROR, "Size of FV File (%s) is larger than Region Size 0x%X specified." \ % (RegionData, Size)) BinFile = open(FileName, 'r+b') Buffer.write(BinFile.read()) BinFile.close() Size = Size - FileLength # # Pad the left buffer # if Size > 0: if (ErasePolarity == '1'): PadData = 0xFF else: PadData = 0 for i in range(0, Size): Buffer.write(pack('B', PadData)) if self.RegionType == 'CAPSULE': # # Get Capsule from Capsule Dict # for RegionData in self.RegionDataList: if RegionData.endswith(".cap"): RegionData = GenFdsGlobalVariable.MacroExtend( RegionData, MacroDict) GenFdsGlobalVariable.InfLogger( ' Region CAPSULE Image Name = .cap : %s' % RegionData) if RegionData[1] != ':': RegionData = os.path.join( GenFdsGlobalVariable.WorkSpaceDir, RegionData) if not os.path.exists(RegionData): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) FileName = RegionData elif RegionData.upper() + 'cap' in ImageBinDict.keys(): GenFdsGlobalVariable.InfLogger(' Region Name = CAPSULE') FileName = ImageBinDict[RegionData.upper() + 'cap'] else: # # Generate Capsule image and Put it into FD buffer # CapsuleObj = None if RegionData.upper( ) in GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict.keys( ): CapsuleObj = GenFdsGlobalVariable.FdfParser.Profile.CapsuleDict[ RegionData.upper()] if CapsuleObj != None: CapsuleObj.CapsuleName = RegionData.upper() GenFdsGlobalVariable.InfLogger( ' Region Name = CAPSULE') # # Call GenFv tool to generate Capsule Image # FileName = CapsuleObj.GenCapsule() CapsuleObj.CapsuleName = None else: EdkLogger.error( "GenFds", GENFDS_ERROR, "Capsule (%s) is NOT described in FDF file!" % (RegionData)) # # Add the capsule image into FD buffer # FileLength = os.stat(FileName)[ST_SIZE] if FileLength > Size: EdkLogger.error("GenFds", GENFDS_ERROR, "Size 0x%X of Capsule File (%s) is larger than Region Size 0x%X specified." \ % (FileLength, RegionData, Size)) BinFile = open(FileName, 'r+b') Buffer.write(BinFile.read()) BinFile.close() Size = Size - FileLength # # Pad the left buffer # if Size > 0: if (ErasePolarity == '1'): PadData = 0xFF else: PadData = 0 for i in range(0, Size): Buffer.write(pack('B', PadData)) if self.RegionType == 'FILE': for RegionData in self.RegionDataList: RegionData = GenFdsGlobalVariable.MacroExtend( RegionData, MacroDict) if RegionData[1] != ':': RegionData = os.path.join( GenFdsGlobalVariable.WorkSpaceDir, RegionData) if not os.path.exists(RegionData): EdkLogger.error("GenFds", FILE_NOT_FOUND, ExtraData=RegionData) # # Add the file image into FD buffer # FileLength = os.stat(RegionData)[ST_SIZE] if FileLength > Size: EdkLogger.error("GenFds", GENFDS_ERROR, "Size of File (%s) is larger than Region Size 0x%X specified." \ % (RegionData, Size)) GenFdsGlobalVariable.InfLogger(' Region File Name = %s' % RegionData) BinFile = open(RegionData, 'r+b') Buffer.write(BinFile.read()) BinFile.close() Size = Size - FileLength # # Pad the left buffer # if Size > 0: if (ErasePolarity == '1'): PadData = 0xFF else: PadData = 0 for i in range(0, Size): Buffer.write(pack('B', PadData)) if self.RegionType == 'DATA': GenFdsGlobalVariable.InfLogger(' Region Name = DATA') DataSize = 0 for RegionData in self.RegionDataList: Data = RegionData.split(',') DataSize = DataSize + len(Data) if DataSize > Size: EdkLogger.error( "GenFds", GENFDS_ERROR, "Size of DATA is larger than Region Size ") else: for item in Data: Buffer.write(pack('B', int(item, 16))) Size = Size - DataSize # # Pad the left buffer # if Size > 0: if (ErasePolarity == '1'): PadData = 0xFF else: PadData = 0 for i in range(0, Size): Buffer.write(pack('B', PadData)) if self.RegionType == None: GenFdsGlobalVariable.InfLogger(' Region Name = None') if (ErasePolarity == '1'): PadData = 0xFF else: PadData = 0 for i in range(0, Size): Buffer.write(pack('B', PadData))