1## @file
2# process FFS generation from INF statement
3#
4#  Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>
5#  Copyright (c) 2014-2016 Hewlett-Packard Development Company, L.P.<BR>
6#
7#  This program and the accompanying materials
8#  are licensed and made available under the terms and conditions of the BSD License
9#  which accompanies this distribution.  The full text of the license may be found at
10#  http://opensource.org/licenses/bsd-license.php
11#
12#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14#
15
16##
17# Import Modules
18#
19import Rule
20import Common.LongFilePathOs as os
21import StringIO
22from struct import *
23from GenFdsGlobalVariable import GenFdsGlobalVariable
24import Ffs
25import subprocess
26import sys
27import Section
28import RuleSimpleFile
29import RuleComplexFile
30from CommonDataClass.FdfClass import FfsInfStatementClassObject
31from Common.MultipleWorkspace import MultipleWorkspace as mws
32from Common.String import *
33from Common.Misc import PathClass
34from Common.Misc import GuidStructureByteArrayToGuidString
35from Common.Misc import ProcessDuplicatedInf
36from Common.Misc import GetVariableOffset
37from Common import EdkLogger
38from Common.BuildToolError import *
39from GuidSection import GuidSection
40from FvImageSection import FvImageSection
41from Common.Misc import PeImageClass
42from AutoGen.GenDepex import DependencyExpression
43from PatchPcdValue.PatchPcdValue import PatchBinaryFile
44from Common.LongFilePathSupport import CopyLongFilePath
45from Common.LongFilePathSupport import OpenLongFilePath as open
46import Common.GlobalData as GlobalData
47
48## generate FFS from INF
49#
50#
51class FfsInfStatement(FfsInfStatementClassObject):
52    ## The mapping dictionary from datum type to its maximum number.
53    _MAX_SIZE_TYPE = {"BOOLEAN":0x01, "UINT8":0xFF, "UINT16":0xFFFF, "UINT32":0xFFFFFFFF, "UINT64":0xFFFFFFFFFFFFFFFF}
54    ## The constructor
55    #
56    #   @param  self        The object pointer
57    #
58    def __init__(self):
59        FfsInfStatementClassObject.__init__(self)
60        self.TargetOverrideList = []
61        self.ShadowFromInfFile = None
62        self.KeepRelocFromRule = None
63        self.InDsc = True
64        self.OptRomDefs = {}
65        self.PiSpecVersion = '0x00000000'
66        self.InfModule = None
67        self.FinalTargetSuffixMap = {}
68        self.CurrentLineNum = None
69        self.CurrentLineContent = None
70        self.FileName = None
71        self.InfFileName = None
72        self.OverrideGuid = None
73        self.PatchedBinFile = ''
74        self.MacroDict = {}
75
76    ## GetFinalTargetSuffixMap() method
77    #
78    #    Get final build target list
79    def GetFinalTargetSuffixMap(self):
80        if not self.InfModule or not self.CurrentArch:
81            return []
82        if not self.FinalTargetSuffixMap:
83            FinalBuildTargetList = GenFdsGlobalVariable.GetModuleCodaTargetList(self.InfModule, self.CurrentArch)
84            for File in FinalBuildTargetList:
85                self.FinalTargetSuffixMap.setdefault(os.path.splitext(File)[1], []).append(File)
86
87            # Check if current INF module has DEPEX
88            if '.depex' not in self.FinalTargetSuffixMap and self.InfModule.ModuleType != "USER_DEFINED" \
89                and not self.InfModule.DxsFile and not self.InfModule.LibraryClass:
90                ModuleType = self.InfModule.ModuleType
91                PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
92
93                if ModuleType != DataType.SUP_MODULE_USER_DEFINED:
94                    for LibraryClass in PlatformDataBase.LibraryClasses.GetKeys():
95                        if LibraryClass.startswith("NULL") and PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]:
96                            self.InfModule.LibraryClasses[LibraryClass] = PlatformDataBase.LibraryClasses[LibraryClass, ModuleType]
97
98                StrModule = str(self.InfModule)
99                PlatformModule = None
100                if StrModule in PlatformDataBase.Modules:
101                    PlatformModule = PlatformDataBase.Modules[StrModule]
102                    for LibraryClass in PlatformModule.LibraryClasses:
103                        if LibraryClass.startswith("NULL"):
104                            self.InfModule.LibraryClasses[LibraryClass] = PlatformModule.LibraryClasses[LibraryClass]
105
106                DependencyList = [self.InfModule]
107                LibraryInstance = {}
108                DepexList = []
109                while len(DependencyList) > 0:
110                    Module = DependencyList.pop(0)
111                    if not Module:
112                        continue
113                    for Dep in Module.Depex[self.CurrentArch, ModuleType]:
114                        if DepexList != []:
115                            DepexList.append('AND')
116                        DepexList.append('(')
117                        DepexList.extend(Dep)
118                        if DepexList[-1] == 'END':  # no need of a END at this time
119                            DepexList.pop()
120                        DepexList.append(')')
121                    if 'BEFORE' in DepexList or 'AFTER' in DepexList:
122                        break
123                    for LibName in Module.LibraryClasses:
124                        if LibName in LibraryInstance:
125                            continue
126                        if PlatformModule and LibName in PlatformModule.LibraryClasses:
127                            LibraryPath = PlatformModule.LibraryClasses[LibName]
128                        else:
129                            LibraryPath = PlatformDataBase.LibraryClasses[LibName, ModuleType]
130                        if not LibraryPath:
131                            LibraryPath = Module.LibraryClasses[LibName]
132                        if not LibraryPath:
133                            continue
134                        LibraryModule = GenFdsGlobalVariable.WorkSpace.BuildObject[LibraryPath, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
135                        LibraryInstance[LibName] = LibraryModule
136                        DependencyList.append(LibraryModule)
137                if DepexList:
138                    Dpx = DependencyExpression(DepexList, ModuleType, True)
139                    if len(Dpx.PostfixNotation) != 0:
140                        # It means this module has DEPEX
141                        self.FinalTargetSuffixMap['.depex'] = [os.path.join(self.EfiOutputPath, self.BaseName) + '.depex']
142        return self.FinalTargetSuffixMap
143
144    ## __InfParse() method
145    #
146    #   Parse inf file to get module information
147    #
148    #   @param  self        The object pointer
149    #   @param  Dict        dictionary contains macro and value pair
150    #
151    def __InfParse__(self, Dict = {}):
152
153        GenFdsGlobalVariable.VerboseLogger( " Begine parsing INf file : %s" %self.InfFileName)
154
155        self.InfFileName = self.InfFileName.replace('$(WORKSPACE)', '')
156        if len(self.InfFileName) > 1 and self.InfFileName[0] == '\\' and self.InfFileName[1] == '\\':
157            pass
158        elif self.InfFileName[0] == '\\' or self.InfFileName[0] == '/' :
159            self.InfFileName = self.InfFileName[1:]
160
161        if self.InfFileName.find('$') == -1:
162            InfPath = NormPath(self.InfFileName)
163            if not os.path.exists(InfPath):
164                InfPath = GenFdsGlobalVariable.ReplaceWorkspaceMacro(InfPath)
165                if not os.path.exists(InfPath):
166                    EdkLogger.error("GenFds", GENFDS_ERROR, "Non-existant Module %s !" % (self.InfFileName))
167
168        self.CurrentArch = self.GetCurrentArch()
169        #
170        # Get the InfClass object
171        #
172
173        PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
174        ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")
175        if ErrorCode != 0:
176            EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
177
178        #
179        # Cache lower case version of INF path before processing FILE_GUID override
180        #
181        InfLowerPath = str(PathClassObj).lower()
182        if self.OverrideGuid:
183            PathClassObj = ProcessDuplicatedInf(PathClassObj, self.OverrideGuid, GenFdsGlobalVariable.WorkSpaceDir)
184        if self.CurrentArch != None:
185
186            Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
187            #
188            # Set Ffs BaseName, MdouleGuid, ModuleType, Version, OutputPath
189            #
190            self.BaseName = Inf.BaseName
191            self.ModuleGuid = Inf.Guid
192            self.ModuleType = Inf.ModuleType
193            if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
194                self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']
195            if Inf.AutoGenVersion < 0x00010005:
196                self.ModuleType = Inf.ComponentType
197            self.VersionString = Inf.Version
198            self.BinFileList = Inf.Binaries
199            self.SourceFileList = Inf.Sources
200            if self.KeepReloc == None and Inf.Shadow:
201                self.ShadowFromInfFile = Inf.Shadow
202
203        else:
204            Inf = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClassObj, 'COMMON', GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
205            self.BaseName = Inf.BaseName
206            self.ModuleGuid = Inf.Guid
207            self.ModuleType = Inf.ModuleType
208            if Inf.Specification != None and 'PI_SPECIFICATION_VERSION' in Inf.Specification:
209                self.PiSpecVersion = Inf.Specification['PI_SPECIFICATION_VERSION']
210            self.VersionString = Inf.Version
211            self.BinFileList = Inf.Binaries
212            self.SourceFileList = Inf.Sources
213            if self.BinFileList == []:
214                EdkLogger.error("GenFds", GENFDS_ERROR,
215                                "INF %s specified in FDF could not be found in build ARCH %s!" \
216                                % (self.InfFileName, GenFdsGlobalVariable.ArchList))
217
218        if self.OverrideGuid:
219            self.ModuleGuid = self.OverrideGuid
220
221        if len(self.SourceFileList) != 0 and not self.InDsc:
222            EdkLogger.warn("GenFds", GENFDS_ERROR, "Module %s NOT found in DSC file; Is it really a binary module?" % (self.InfFileName))
223
224        if self.ModuleType == 'SMM_CORE' and int(self.PiSpecVersion, 16) < 0x0001000A:
225            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)
226
227        if Inf._Defs != None and len(Inf._Defs) > 0:
228            self.OptRomDefs.update(Inf._Defs)
229
230        self.PatchPcds = []
231        InfPcds = Inf.Pcds
232        Platform = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, self.CurrentArch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
233        FdfPcdDict = GenFdsGlobalVariable.FdfParser.Profile.PcdDict
234
235        # Workaround here: both build and GenFds tool convert the workspace path to lower case
236        # But INF file path in FDF and DSC file may have real case characters.
237        # Try to convert the path to lower case to see if PCDs value are override by DSC.
238        DscModules = {}
239        for DscModule in Platform.Modules:
240            DscModules[str(DscModule).lower()] = Platform.Modules[DscModule]
241        for PcdKey in InfPcds:
242            Pcd = InfPcds[PcdKey]
243            if not hasattr(Pcd, 'Offset'):
244                continue
245            if Pcd.Type != 'PatchableInModule':
246                continue
247            # Override Patchable PCD value by the value from DSC
248            PatchPcd = None
249            if InfLowerPath in DscModules and PcdKey in DscModules[InfLowerPath].Pcds:
250                PatchPcd = DscModules[InfLowerPath].Pcds[PcdKey]
251            elif PcdKey in Platform.Pcds:
252                PatchPcd = Platform.Pcds[PcdKey]
253            DscOverride = False
254            if PatchPcd and Pcd.Type == PatchPcd.Type:
255                DefaultValue = PatchPcd.DefaultValue
256                DscOverride = True
257
258            # Override Patchable PCD value by the value from FDF
259            FdfOverride = False
260            if PcdKey in FdfPcdDict:
261                DefaultValue = FdfPcdDict[PcdKey]
262                FdfOverride = True
263
264            # Override Patchable PCD value by the value from Build Option
265            BuildOptionOverride = False
266            if GlobalData.BuildOptionPcd:
267                for pcd in GlobalData.BuildOptionPcd:
268                    if PcdKey == (pcd[1], pcd[0]):
269                        DefaultValue = pcd[2]
270                        BuildOptionOverride = True
271                        break
272
273            if not DscOverride and not FdfOverride and not BuildOptionOverride:
274                continue
275            # Check value, if value are equal, no need to patch
276            if Pcd.DatumType == "VOID*":
277                if Pcd.DefaultValue == DefaultValue or DefaultValue in [None, '']:
278                    continue
279                # Get the string size from FDF or DSC
280                if DefaultValue[0] == 'L':
281                    # Remove L"", but the '\0' must be appended
282                    MaxDatumSize = str((len(DefaultValue) - 2) * 2)
283                elif DefaultValue[0] == '{':
284                    MaxDatumSize = str(len(DefaultValue.split(',')))
285                else:
286                    MaxDatumSize = str(len(DefaultValue) - 1)
287                if DscOverride:
288                    Pcd.MaxDatumSize = PatchPcd.MaxDatumSize
289                # If no defined the maximum size in DSC, try to get current size from INF
290                if Pcd.MaxDatumSize in ['', None]:
291                    Pcd.MaxDatumSize = str(len(Pcd.DefaultValue.split(',')))
292            else:
293                Base1 = Base2 = 10
294                if Pcd.DefaultValue.upper().startswith('0X'):
295                    Base1 = 16
296                if DefaultValue.upper().startswith('0X'):
297                    Base2 = 16
298                try:
299                    PcdValueInImg = int(Pcd.DefaultValue, Base1)
300                    PcdValueInDscOrFdf = int(DefaultValue, Base2)
301                    if PcdValueInImg == PcdValueInDscOrFdf:
302                        continue
303                except:
304                    continue
305            # Check the Pcd size and data type
306            if Pcd.DatumType == "VOID*":
307                if int(MaxDatumSize) > int(Pcd.MaxDatumSize):
308                    EdkLogger.error("GenFds", GENFDS_ERROR, "The size of VOID* type PCD '%s.%s' exceeds its maximum size %d bytes." \
309                                    % (Pcd.TokenSpaceGuidCName, Pcd.TokenCName, int(MaxDatumSize) - int(Pcd.MaxDatumSize)))
310            else:
311                if PcdValueInDscOrFdf > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType] \
312                    or PcdValueInImg > FfsInfStatement._MAX_SIZE_TYPE[Pcd.DatumType]:
313                    EdkLogger.error("GenFds", GENFDS_ERROR, "The size of %s type PCD '%s.%s' doesn't match its data type." \
314                                    % (Pcd.DatumType, Pcd.TokenSpaceGuidCName, Pcd.TokenCName))
315            self.PatchPcds.append((Pcd, DefaultValue))
316
317        self.InfModule = Inf
318        self.PcdIsDriver = Inf.PcdIsDriver
319        self.IsBinaryModule = Inf.IsBinaryModule
320        GenFdsGlobalVariable.VerboseLogger("BaseName : %s" % self.BaseName)
321        GenFdsGlobalVariable.VerboseLogger("ModuleGuid : %s" % self.ModuleGuid)
322        GenFdsGlobalVariable.VerboseLogger("ModuleType : %s" % self.ModuleType)
323        GenFdsGlobalVariable.VerboseLogger("VersionString : %s" % self.VersionString)
324        GenFdsGlobalVariable.VerboseLogger("InfFileName :%s" % self.InfFileName)
325
326        #
327        # Set OutputPath = ${WorkSpace}\Build\Fv\Ffs\${ModuleGuid}+ ${MdouleName}\
328        #
329
330        self.OutputPath = os.path.join(GenFdsGlobalVariable.FfsDir, \
331                                       self.ModuleGuid + self.BaseName)
332        if not os.path.exists(self.OutputPath) :
333            os.makedirs(self.OutputPath)
334
335        self.EfiOutputPath = self.__GetEFIOutPutPath__()
336        GenFdsGlobalVariable.VerboseLogger( "ModuelEFIPath: " + self.EfiOutputPath)
337
338    ## PatchEfiFile
339    #
340    #  Patch EFI file with patch PCD
341    #
342    #  @param EfiFile: EFI file needs to be patched.
343    #  @retval: Full path of patched EFI file: self.OutputPath + EfiFile base name
344    #           If passed in file does not end with efi, return as is
345    #
346    def PatchEfiFile(self, EfiFile, FileType):
347        #
348        # If the module does not have any patches, then return path to input file
349        #
350        if not self.PatchPcds:
351            return EfiFile
352
353        #
354        # Only patch file if FileType is PE32 or ModuleType is USER_DEFINED
355        #
356        if FileType != 'PE32' and self.ModuleType != "USER_DEFINED":
357            return EfiFile
358
359        #
360        # Generate path to patched output file
361        #
362        Basename = os.path.basename(EfiFile)
363        Output = os.path.normpath (os.path.join(self.OutputPath, Basename))
364
365        #
366        # If this file has already been patched, then return the path to the patched file
367        #
368        if self.PatchedBinFile == Output:
369          return Output
370
371        #
372        # If a different file from the same module has already been patched, then generate an error
373        #
374        if self.PatchedBinFile:
375            EdkLogger.error("GenFds", GENFDS_ERROR,
376                            'Only one binary file can be patched:\n'
377                            '  a binary file has been patched: %s\n'
378                            '  current file: %s' % (self.PatchedBinFile, EfiFile),
379                            File=self.InfFileName)
380
381        #
382        # Copy unpatched file contents to output file location to perform patching
383        #
384        CopyLongFilePath(EfiFile, Output)
385
386        #
387        # Apply patches to patched output file
388        #
389        for Pcd, Value in self.PatchPcds:
390            RetVal, RetStr = PatchBinaryFile(Output, int(Pcd.Offset, 0), Pcd.DatumType, Value, Pcd.MaxDatumSize)
391            if RetVal:
392                EdkLogger.error("GenFds", GENFDS_ERROR, RetStr, File=self.InfFileName)
393
394        #
395        # Save the path of the patched output file
396        #
397        self.PatchedBinFile = Output
398
399        #
400        # Return path to patched output file
401        #
402        return Output
403
404    ## GenFfs() method
405    #
406    #   Generate FFS
407    #
408    #   @param  self         The object pointer
409    #   @param  Dict         dictionary contains macro and value pair
410    #   @param  FvChildAddr  Array of the inside FvImage base address
411    #   @param  FvParentAddr Parent Fv base address
412    #   @retval string       Generated FFS file name
413    #
414    def GenFfs(self, Dict = {}, FvChildAddr = [], FvParentAddr=None):
415        #
416        # Parse Inf file get Module related information
417        #
418
419        self.__InfParse__(Dict)
420        SrcFile = mws.join( GenFdsGlobalVariable.WorkSpaceDir , self.InfFileName);
421        DestFile = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
422
423        SrcFileDir = "."
424        SrcPath = os.path.dirname(SrcFile)
425        SrcFileName = os.path.basename(SrcFile)
426        SrcFileBase, SrcFileExt = os.path.splitext(SrcFileName)
427        DestPath = os.path.dirname(DestFile)
428        DestFileName = os.path.basename(DestFile)
429        DestFileBase, DestFileExt = os.path.splitext(DestFileName)
430        self.MacroDict = {
431            # source file
432            "${src}"      :   SrcFile,
433            "${s_path}"   :   SrcPath,
434            "${s_dir}"    :   SrcFileDir,
435            "${s_name}"   :   SrcFileName,
436            "${s_base}"   :   SrcFileBase,
437            "${s_ext}"    :   SrcFileExt,
438            # destination file
439            "${dst}"      :   DestFile,
440            "${d_path}"   :   DestPath,
441            "${d_name}"   :   DestFileName,
442            "${d_base}"   :   DestFileBase,
443            "${d_ext}"    :   DestFileExt
444        }
445        #
446        # Allow binary type module not specify override rule in FDF file.
447        #
448        if len(self.BinFileList) > 0:
449            if self.Rule == None or self.Rule == "":
450                self.Rule = "BINARY"
451
452        #
453        # Get the rule of how to generate Ffs file
454        #
455        Rule = self.__GetRule__()
456        GenFdsGlobalVariable.VerboseLogger( "Packing binaries from inf file : %s" %self.InfFileName)
457        #
458        # Convert Fv File Type for PI1.1 SMM driver.
459        #
460        if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
461            if Rule.FvFileType == 'DRIVER':
462                Rule.FvFileType = 'SMM'
463        #
464        # Framework SMM Driver has no SMM FV file type
465        #
466        if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
467            if Rule.FvFileType == 'SMM' or Rule.FvFileType == 'SMM_CORE':
468                EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM or SMM_CORE FV file type", File=self.InfFileName)
469        #
470        # For the rule only has simpleFile
471        #
472        if isinstance (Rule, RuleSimpleFile.RuleSimpleFile) :
473            SectionOutputList = self.__GenSimpleFileSection__(Rule)
474            FfsOutput = self.__GenSimpleFileFfs__(Rule, SectionOutputList)
475            return FfsOutput
476        #
477        # For Rule has ComplexFile
478        #
479        elif isinstance(Rule, RuleComplexFile.RuleComplexFile):
480            InputSectList, InputSectAlignments = self.__GenComplexFileSection__(Rule, FvChildAddr, FvParentAddr)
481            FfsOutput = self.__GenComplexFileFfs__(Rule, InputSectList, InputSectAlignments)
482
483            return FfsOutput
484
485    ## __ExtendMacro__() method
486    #
487    #   Replace macro with its value
488    #
489    #   @param  self        The object pointer
490    #   @param  String      The string to be replaced
491    #   @retval string      Macro replaced string
492    #
493    def __ExtendMacro__ (self, String):
494        MacroDict = {
495            '$(INF_OUTPUT)'  : self.EfiOutputPath,
496            '$(MODULE_NAME)' : self.BaseName,
497            '$(BUILD_NUMBER)': self.BuildNum,
498            '$(INF_VERSION)' : self.VersionString,
499            '$(NAMED_GUID)'  : self.ModuleGuid
500        }
501        String = GenFdsGlobalVariable.MacroExtend(String, MacroDict)
502        String = GenFdsGlobalVariable.MacroExtend(String, self.MacroDict)
503        return String
504
505    ## __GetRule__() method
506    #
507    #   Get correct rule for generating FFS for this INF
508    #
509    #   @param  self        The object pointer
510    #   @retval Rule        Rule object
511    #
512    def __GetRule__ (self) :
513        CurrentArchList = []
514        if self.CurrentArch == None:
515            CurrentArchList = ['common']
516        else:
517            CurrentArchList.append(self.CurrentArch)
518
519        for CurrentArch in CurrentArchList:
520            RuleName = 'RULE'              + \
521                       '.'                 + \
522                       CurrentArch.upper() + \
523                       '.'                 + \
524                       self.ModuleType.upper()
525            if self.Rule != None:
526                RuleName = RuleName + \
527                           '.'      + \
528                           self.Rule.upper()
529
530            Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
531            if Rule != None:
532                GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
533                return Rule
534
535        RuleName = 'RULE'      + \
536                   '.'         + \
537                   'COMMON'    + \
538                   '.'         + \
539                   self.ModuleType.upper()
540
541        if self.Rule != None:
542            RuleName = RuleName + \
543                       '.'      + \
544                       self.Rule.upper()
545
546        GenFdsGlobalVariable.VerboseLogger ('Trying to apply common rule %s for INF %s' % (RuleName, self.InfFileName))
547
548        Rule = GenFdsGlobalVariable.FdfParser.Profile.RuleDict.get(RuleName)
549        if Rule != None:
550            GenFdsGlobalVariable.VerboseLogger ("Want To Find Rule Name is : " + RuleName)
551            return Rule
552
553        if Rule == None :
554            EdkLogger.error("GenFds", GENFDS_ERROR, 'Don\'t Find common rule %s for INF %s' \
555                            % (RuleName, self.InfFileName))
556
557    ## __GetPlatformArchList__() method
558    #
559    #   Get Arch list this INF built under
560    #
561    #   @param  self        The object pointer
562    #   @retval list        Arch list
563    #
564    def __GetPlatformArchList__(self):
565
566        InfFileKey = os.path.normpath(mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName))
567        DscArchList = []
568        for Arch in GenFdsGlobalVariable.ArchList :
569            PlatformDataBase = GenFdsGlobalVariable.WorkSpace.BuildObject[GenFdsGlobalVariable.ActivePlatform, Arch, GenFdsGlobalVariable.TargetName, GenFdsGlobalVariable.ToolChainTag]
570            if  PlatformDataBase != None:
571                if InfFileKey in PlatformDataBase.Modules:
572                    DscArchList.append (Arch)
573                else:
574                    #
575                    # BaseTools support build same module more than once, the module path with FILE_GUID overridden has
576                    # the file name FILE_GUIDmodule.inf, then PlatformDataBase.Modules use FILE_GUIDmodule.inf as key,
577                    # but the path (self.MetaFile.Path) is the real path
578                    #
579                    for key in PlatformDataBase.Modules.keys():
580                        if InfFileKey == str((PlatformDataBase.Modules[key]).MetaFile.Path):
581                            DscArchList.append (Arch)
582                            break
583
584        return DscArchList
585
586    ## GetCurrentArch() method
587    #
588    #   Get Arch list of the module from this INF is to be placed into flash
589    #
590    #   @param  self        The object pointer
591    #   @retval list        Arch list
592    #
593    def GetCurrentArch(self) :
594
595        TargetArchList = GenFdsGlobalVariable.ArchList
596
597        PlatformArchList = self.__GetPlatformArchList__()
598
599        CurArchList = TargetArchList
600        if PlatformArchList != []:
601            CurArchList = list(set (TargetArchList) & set (PlatformArchList))
602        GenFdsGlobalVariable.VerboseLogger ("Valid target architecture(s) is : " + " ".join(CurArchList))
603
604        ArchList = []
605        if self.KeyStringList != []:
606            for Key in self.KeyStringList:
607                Key = GenFdsGlobalVariable.MacroExtend(Key)
608                Target, Tag, Arch = Key.split('_')
609                if Arch in CurArchList:
610                    ArchList.append(Arch)
611                if Target not in self.TargetOverrideList:
612                    self.TargetOverrideList.append(Target)
613        else:
614            ArchList = CurArchList
615
616        UseArchList = TargetArchList
617        if self.UseArch != None:
618            UseArchList = []
619            UseArchList.append(self.UseArch)
620            ArchList = list(set (UseArchList) & set (ArchList))
621
622        self.InfFileName = NormPath(self.InfFileName)
623        if len(PlatformArchList) == 0:
624            self.InDsc = False
625            PathClassObj = PathClass(self.InfFileName, GenFdsGlobalVariable.WorkSpaceDir)
626            ErrorCode, ErrorInfo = PathClassObj.Validate(".inf")
627            if ErrorCode != 0:
628                EdkLogger.error("GenFds", ErrorCode, ExtraData=ErrorInfo)
629        if len(ArchList) == 1:
630            Arch = ArchList[0]
631            return Arch
632        elif len(ArchList) > 1:
633            if len(PlatformArchList) == 0:
634                EdkLogger.error("GenFds", GENFDS_ERROR, "GenFds command line option has multiple ARCHs %s. Not able to determine which ARCH is valid for Module %s !" % (str(ArchList), self.InfFileName))
635            else:
636                EdkLogger.error("GenFds", GENFDS_ERROR, "Module built under multiple ARCHs %s. Not able to determine which output to put into flash for Module %s !" % (str(ArchList), self.InfFileName))
637        else:
638            EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s appears under ARCH %s in platform %s, but current deduced ARCH is %s, so NO build output could be put into flash." \
639                            % (self.InfFileName, str(PlatformArchList), GenFdsGlobalVariable.ActivePlatform, str(set (UseArchList) & set (TargetArchList))))
640
641    ## __GetEFIOutPutPath__() method
642    #
643    #   Get the output path for generated files
644    #
645    #   @param  self        The object pointer
646    #   @retval string      Path that output files from this INF go to
647    #
648    def __GetEFIOutPutPath__(self):
649        Arch = ''
650        OutputPath = ''
651        (ModulePath, FileName) = os.path.split(self.InfFileName)
652        Index = FileName.rfind('.')
653        FileName = FileName[0:Index]
654        if self.OverrideGuid:
655            FileName = self.OverrideGuid
656        Arch = "NoneArch"
657        if self.CurrentArch != None:
658            Arch = self.CurrentArch
659
660        OutputPath = os.path.join(GenFdsGlobalVariable.OutputDirDict[Arch],
661                                  Arch ,
662                                  ModulePath,
663                                  FileName,
664                                  'OUTPUT'
665                                  )
666        OutputPath = os.path.realpath(OutputPath)
667        return OutputPath
668
669    ## __GenSimpleFileSection__() method
670    #
671    #   Generate section by specified file name or a list of files with file extension
672    #
673    #   @param  self        The object pointer
674    #   @param  Rule        The rule object used to generate section
675    #   @retval string      File name of the generated section file
676    #
677    def __GenSimpleFileSection__(self, Rule):
678        #
679        # Prepare the parameter of GenSection
680        #
681        FileList = []
682        OutputFileList = []
683        GenSecInputFile = None
684        if Rule.FileName != None:
685            GenSecInputFile = self.__ExtendMacro__(Rule.FileName)
686            if os.path.isabs(GenSecInputFile):
687                GenSecInputFile = os.path.normpath(GenSecInputFile)
688            else:
689                GenSecInputFile = os.path.normpath(os.path.join(self.EfiOutputPath, GenSecInputFile))
690        else:
691            FileList, IsSect = Section.Section.GetFileList(self, '', Rule.FileExtension)
692
693        Index = 1
694        SectionType = Rule.SectionType
695        #
696        # Convert Fv Section Type for PI1.1 SMM driver.
697        #
698        if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
699            if SectionType == 'DXE_DEPEX':
700                SectionType = 'SMM_DEPEX'
701        #
702        # Framework SMM Driver has no SMM_DEPEX section type
703        #
704        if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
705            if SectionType == 'SMM_DEPEX':
706                EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
707        NoStrip = True
708        if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
709            if self.KeepReloc != None:
710                NoStrip = self.KeepReloc
711            elif Rule.KeepReloc != None:
712                NoStrip = Rule.KeepReloc
713            elif self.ShadowFromInfFile != None:
714                NoStrip = self.ShadowFromInfFile
715
716        if FileList != [] :
717            for File in FileList:
718
719                SecNum = '%d' %Index
720                GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
721                              Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
722                Index = Index + 1
723                OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
724                File = GenFdsGlobalVariable.MacroExtend(File, Dict, self.CurrentArch)
725
726                #Get PE Section alignment when align is set to AUTO
727                if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
728                    ImageObj = PeImageClass (File)
729                    if ImageObj.SectionAlignment < 0x400:
730                        self.Alignment = str (ImageObj.SectionAlignment)
731                    else:
732                        self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
733
734                if not NoStrip:
735                    FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
736                    if not os.path.exists(FileBeforeStrip) or \
737                           (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
738                        CopyLongFilePath(File, FileBeforeStrip)
739                    StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
740                    GenFdsGlobalVariable.GenerateFirmwareImage(
741                                            StrippedFile,
742                                            [File],
743                                            Strip=True
744                                            )
745                    File = StrippedFile
746
747                if SectionType == 'TE':
748                    TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
749                    GenFdsGlobalVariable.GenerateFirmwareImage(
750                                            TeFile,
751                                            [File],
752                                            Type='te'
753                                            )
754                    File = TeFile
755
756                GenFdsGlobalVariable.GenerateSection(OutputFile, [File], Section.Section.SectionType[SectionType])
757                OutputFileList.append(OutputFile)
758        else:
759            SecNum = '%d' %Index
760            GenSecOutputFile= self.__ExtendMacro__(Rule.NameGuid) + \
761                              Ffs.Ffs.SectionSuffix[SectionType] + 'SEC' + SecNum
762            OutputFile = os.path.join(self.OutputPath, GenSecOutputFile)
763            GenSecInputFile = GenFdsGlobalVariable.MacroExtend(GenSecInputFile, Dict, self.CurrentArch)
764
765            #Get PE Section alignment when align is set to AUTO
766            if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
767                ImageObj = PeImageClass (GenSecInputFile)
768                if ImageObj.SectionAlignment < 0x400:
769                    self.Alignment = str (ImageObj.SectionAlignment)
770                else:
771                    self.Alignment = str (ImageObj.SectionAlignment / 0x400) + 'K'
772
773            if not NoStrip:
774                FileBeforeStrip = os.path.join(self.OutputPath, ModuleName + '.reloc')
775                if not os.path.exists(FileBeforeStrip) or \
776                       (os.path.getmtime(GenSecInputFile) > os.path.getmtime(FileBeforeStrip)):
777                    CopyLongFilePath(GenSecInputFile, FileBeforeStrip)
778
779                StrippedFile = os.path.join(self.OutputPath, ModuleName + '.stipped')
780                GenFdsGlobalVariable.GenerateFirmwareImage(
781                                        StrippedFile,
782                                        [GenSecInputFile],
783                                        Strip=True
784                                        )
785                GenSecInputFile = StrippedFile
786
787            if SectionType == 'TE':
788                TeFile = os.path.join( self.OutputPath, self.ModuleGuid + 'Te.raw')
789                GenFdsGlobalVariable.GenerateFirmwareImage(
790                                        TeFile,
791                                        [GenSecInputFile],
792                                        Type='te'
793                                        )
794                GenSecInputFile = TeFile
795
796            GenFdsGlobalVariable.GenerateSection(OutputFile, [GenSecInputFile], Section.Section.SectionType[SectionType])
797            OutputFileList.append(OutputFile)
798
799        return OutputFileList
800
801    ## __GenSimpleFileFfs__() method
802    #
803    #   Generate FFS
804    #
805    #   @param  self        The object pointer
806    #   @param  Rule        The rule object used to generate section
807    #   @param  InputFileList        The output file list from GenSection
808    #   @retval string      Generated FFS file name
809    #
810    def __GenSimpleFileFfs__(self, Rule, InputFileList):
811        FfsOutput = self.OutputPath                     + \
812                    os.sep                              + \
813                    self.__ExtendMacro__(Rule.NameGuid) + \
814                    '.ffs'
815
816        GenFdsGlobalVariable.VerboseLogger(self.__ExtendMacro__(Rule.NameGuid))
817        InputSection = []
818        SectionAlignments = []
819        for InputFile in InputFileList:
820            InputSection.append(InputFile)
821            SectionAlignments.append(Rule.SectAlignment)
822
823        if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
824            PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
825            if len(PcdValue) == 0:
826                EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
827                            % (Rule.NameGuid))
828            if PcdValue.startswith('{'):
829                PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
830            RegistryGuidStr = PcdValue
831            if len(RegistryGuidStr) == 0:
832                EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
833                            % (Rule.NameGuid))
834            self.ModuleGuid = RegistryGuidStr
835
836        GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputSection,
837                                         Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
838                                         self.ModuleGuid, Fixed=Rule.Fixed,
839                                         CheckSum=Rule.CheckSum, Align=Rule.Alignment,
840                                         SectionAlign=SectionAlignments
841                                        )
842        return FfsOutput
843
844    ## __GenComplexFileSection__() method
845    #
846    #   Generate section by sections in Rule
847    #
848    #   @param  self         The object pointer
849    #   @param  Rule         The rule object used to generate section
850    #   @param  FvChildAddr  Array of the inside FvImage base address
851    #   @param  FvParentAddr Parent Fv base address
852    #   @retval string       File name of the generated section file
853    #
854    def __GenComplexFileSection__(self, Rule, FvChildAddr, FvParentAddr):
855        if self.ModuleType in ('SEC', 'PEI_CORE', 'PEIM'):
856            if Rule.KeepReloc != None:
857                self.KeepRelocFromRule = Rule.KeepReloc
858        SectFiles = []
859        SectAlignments = []
860        Index = 1
861        HasGneratedFlag = False
862        if self.PcdIsDriver == 'PEI_PCD_DRIVER':
863            if self.IsBinaryModule:
864                PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "PEIPcdDataBase.raw")
865            else:
866                PcdExDbFileName = os.path.join(self.EfiOutputPath, "PEIPcdDataBase.raw")
867            PcdExDbSecName = os.path.join(self.OutputPath, "PEIPcdDataBaseSec.raw")
868            GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
869                                                 [PcdExDbFileName],
870                                                 "EFI_SECTION_RAW",
871                                                 )
872            SectFiles.append(PcdExDbSecName)
873            SectAlignments.append(None)
874        elif self.PcdIsDriver == 'DXE_PCD_DRIVER':
875            if self.IsBinaryModule:
876                PcdExDbFileName = os.path.join(GenFdsGlobalVariable.FvDir, "DXEPcdDataBase.raw")
877            else:
878                PcdExDbFileName = os.path.join(self.EfiOutputPath, "DXEPcdDataBase.raw")
879            PcdExDbSecName = os.path.join(self.OutputPath, "DXEPcdDataBaseSec.raw")
880            GenFdsGlobalVariable.GenerateSection(PcdExDbSecName,
881                                                 [PcdExDbFileName],
882                                                 "EFI_SECTION_RAW",
883                                                 )
884            SectFiles.append(PcdExDbSecName)
885            SectAlignments.append(None)
886        for Sect in Rule.SectionList:
887            SecIndex = '%d' %Index
888            SectList  = []
889            #
890            # Convert Fv Section Type for PI1.1 SMM driver.
891            #
892            if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) >= 0x0001000A:
893                if Sect.SectionType == 'DXE_DEPEX':
894                    Sect.SectionType = 'SMM_DEPEX'
895            #
896            # Framework SMM Driver has no SMM_DEPEX section type
897            #
898            if self.ModuleType == 'DXE_SMM_DRIVER' and int(self.PiSpecVersion, 16) < 0x0001000A:
899                if Sect.SectionType == 'SMM_DEPEX':
900                    EdkLogger.error("GenFds", FORMAT_NOT_SUPPORTED, "Framework SMM module doesn't support SMM_DEPEX section type", File=self.InfFileName)
901            #
902            # process the inside FvImage from FvSection or GuidSection
903            #
904            if FvChildAddr != []:
905                if isinstance(Sect, FvImageSection):
906                    Sect.FvAddr = FvChildAddr.pop(0)
907                elif isinstance(Sect, GuidSection):
908                    Sect.FvAddr = FvChildAddr
909            if FvParentAddr != None and isinstance(Sect, GuidSection):
910                Sect.FvParentAddr = FvParentAddr
911
912            if Rule.KeyStringList != []:
913                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, Rule.KeyStringList, self)
914            else :
915                SectList, Align = Sect.GenSection(self.OutputPath , self.ModuleGuid, SecIndex, self.KeyStringList, self)
916
917            if not HasGneratedFlag:
918                UniVfrOffsetFileSection = ""
919                ModuleFileName = mws.join(GenFdsGlobalVariable.WorkSpaceDir, self.InfFileName)
920                InfData = GenFdsGlobalVariable.WorkSpace.BuildObject[PathClass(ModuleFileName), self.CurrentArch]
921                #
922                # Search the source list in InfData to find if there are .vfr file exist.
923                #
924                VfrUniBaseName = {}
925                VfrUniOffsetList = []
926                for SourceFile in InfData.Sources:
927                    if SourceFile.Type.upper() == ".VFR" :
928                        #
929                        # search the .map file to find the offset of vfr binary in the PE32+/TE file.
930                        #
931                        VfrUniBaseName[SourceFile.BaseName] = (SourceFile.BaseName + "Bin")
932                    if SourceFile.Type.upper() == ".UNI" :
933                        #
934                        # search the .map file to find the offset of Uni strings binary in the PE32+/TE file.
935                        #
936                        VfrUniBaseName["UniOffsetName"] = (self.BaseName + "Strings")
937
938
939                if len(VfrUniBaseName) > 0:
940                    VfrUniOffsetList = self.__GetBuildOutputMapFileVfrUniInfo(VfrUniBaseName)
941                    #
942                    # Generate the Raw data of raw section
943                    #
944                    if VfrUniOffsetList:
945                        os.path.join( self.OutputPath, self.BaseName + '.offset')
946                        UniVfrOffsetFileName    =  os.path.join( self.OutputPath, self.BaseName + '.offset')
947                        UniVfrOffsetFileSection =  os.path.join( self.OutputPath, self.BaseName + 'Offset' + '.raw')
948
949                        self.__GenUniVfrOffsetFile (VfrUniOffsetList, UniVfrOffsetFileName)
950
951                        UniVfrOffsetFileNameList = []
952                        UniVfrOffsetFileNameList.append(UniVfrOffsetFileName)
953                        """Call GenSection"""
954                        GenFdsGlobalVariable.GenerateSection(UniVfrOffsetFileSection,
955                                                             UniVfrOffsetFileNameList,
956                                                             "EFI_SECTION_RAW"
957                                                             )
958                        os.remove(UniVfrOffsetFileName)
959                        SectList.append(UniVfrOffsetFileSection)
960                        HasGneratedFlag = True
961
962            for SecName in  SectList :
963                SectFiles.append(SecName)
964                SectAlignments.append(Align)
965            Index = Index + 1
966        return SectFiles, SectAlignments
967
968    ## __GenComplexFileFfs__() method
969    #
970    #   Generate FFS
971    #
972    #   @param  self        The object pointer
973    #   @param  Rule        The rule object used to generate section
974    #   @param  InputFileList        The output file list from GenSection
975    #   @retval string      Generated FFS file name
976    #
977    def __GenComplexFileFfs__(self, Rule, InputFile, Alignments):
978
979        if Rule.NameGuid != None and Rule.NameGuid.startswith('PCD('):
980            PcdValue = GenFdsGlobalVariable.GetPcdValue(Rule.NameGuid)
981            if len(PcdValue) == 0:
982                EdkLogger.error("GenFds", GENFDS_ERROR, '%s NOT defined.' \
983                            % (Rule.NameGuid))
984            if PcdValue.startswith('{'):
985                PcdValue = GuidStructureByteArrayToGuidString(PcdValue)
986            RegistryGuidStr = PcdValue
987            if len(RegistryGuidStr) == 0:
988                EdkLogger.error("GenFds", GENFDS_ERROR, 'GUID value for %s in wrong format.' \
989                            % (Rule.NameGuid))
990            self.ModuleGuid = RegistryGuidStr
991
992        FfsOutput = os.path.join( self.OutputPath, self.ModuleGuid + '.ffs')
993        GenFdsGlobalVariable.GenerateFfs(FfsOutput, InputFile,
994                                         Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType],
995                                         self.ModuleGuid, Fixed=Rule.Fixed,
996                                         CheckSum=Rule.CheckSum, Align=Rule.Alignment,
997                                         SectionAlign=Alignments
998                                        )
999        return FfsOutput
1000
1001    ## __GetGenFfsCmdParameter__() method
1002    #
1003    #   Create parameter string for GenFfs
1004    #
1005    #   @param  self        The object pointer
1006    #   @param  Rule        The rule object used to generate section
1007    #   @retval tuple       (FileType, Fixed, CheckSum, Alignment)
1008    #
1009    def __GetGenFfsCmdParameter__(self, Rule):
1010        result = tuple()
1011        result += ('-t', Ffs.Ffs.FdfFvFileTypeToFileType[Rule.FvFileType])
1012        if Rule.Fixed != False:
1013            result += ('-x',)
1014        if Rule.CheckSum != False:
1015            result += ('-s',)
1016
1017        if Rule.Alignment != None and Rule.Alignment != '':
1018            result += ('-a', Rule.Alignment)
1019
1020        return result
1021
1022    ## __GetBuildOutputMapFileVfrUniInfo() method
1023    #
1024    #   Find the offset of UNI/INF object offset in the EFI image file.
1025    #
1026    #   @param  self                  The object pointer
1027    #   @param  VfrUniBaseName        A name list contain the UNI/INF object name.
1028    #   @retval RetValue              A list contain offset of UNI/INF object.
1029    #
1030    def __GetBuildOutputMapFileVfrUniInfo(self, VfrUniBaseName):
1031        MapFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".map")
1032        EfiFileName = os.path.join(self.EfiOutputPath, self.BaseName + ".efi")
1033        return GetVariableOffset(MapFileName, EfiFileName, VfrUniBaseName.values())
1034
1035    ## __GenUniVfrOffsetFile() method
1036    #
1037    #   Generate the offset file for the module which contain VFR or UNI file.
1038    #
1039    #   @param  self                    The object pointer
1040    #   @param  VfrUniOffsetList        A list contain the VFR/UNI offsets in the EFI image file.
1041    #   @param  UniVfrOffsetFileName    The output offset file name.
1042    #
1043    def __GenUniVfrOffsetFile(self, VfrUniOffsetList, UniVfrOffsetFileName):
1044
1045        try:
1046            fInputfile = open(UniVfrOffsetFileName, "wb+", 0)
1047        except:
1048            EdkLogger.error("GenFds", FILE_OPEN_FAILURE, "File open failed for %s" %UniVfrOffsetFileName,None)
1049
1050        # Use a instance of StringIO to cache data
1051        fStringIO = StringIO.StringIO('')
1052
1053        for Item in VfrUniOffsetList:
1054            if (Item[0].find("Strings") != -1):
1055                #
1056                # UNI offset in image.
1057                # GUID + Offset
1058                # { 0x8913c5e0, 0x33f6, 0x4d86, { 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66 } }
1059                #
1060                UniGuid = [0xe0, 0xc5, 0x13, 0x89, 0xf6, 0x33, 0x86, 0x4d, 0x9b, 0xf1, 0x43, 0xef, 0x89, 0xfc, 0x6, 0x66]
1061                UniGuid = [chr(ItemGuid) for ItemGuid in UniGuid]
1062                fStringIO.write(''.join(UniGuid))
1063                UniValue = pack ('Q', int (Item[1], 16))
1064                fStringIO.write (UniValue)
1065            else:
1066                #
1067                # VFR binary offset in image.
1068                # GUID + Offset
1069                # { 0xd0bc7cb4, 0x6a47, 0x495f, { 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2 } };
1070                #
1071                VfrGuid = [0xb4, 0x7c, 0xbc, 0xd0, 0x47, 0x6a, 0x5f, 0x49, 0xaa, 0x11, 0x71, 0x7, 0x46, 0xda, 0x6, 0xa2]
1072                VfrGuid = [chr(ItemGuid) for ItemGuid in VfrGuid]
1073                fStringIO.write(''.join(VfrGuid))
1074                type (Item[1])
1075                VfrValue = pack ('Q', int (Item[1], 16))
1076                fStringIO.write (VfrValue)
1077
1078        #
1079        # write data into file.
1080        #
1081        try :
1082            fInputfile.write (fStringIO.getvalue())
1083        except:
1084            EdkLogger.error("GenFds", FILE_WRITE_FAILURE, "Write data to file %s failed, please check whether the file been locked or using by other applications." %UniVfrOffsetFileName,None)
1085
1086        fStringIO.close ()
1087        fInputfile.close ()
1088
1089
1090
1091
1092
1093
1094
1095
1096