1## @file
2# process rule section generation
3#
4#  Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>
5#
6#  This program and the accompanying materials
7#  are licensed and made available under the terms and conditions of the BSD License
8#  which accompanies this distribution.  The full text of the license may be found at
9#  http://opensource.org/licenses/bsd-license.php
10#
11#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13#
14
15##
16# Import Modules
17#
18from struct import *
19import Section
20from GenFdsGlobalVariable import GenFdsGlobalVariable
21import subprocess
22from Ffs import Ffs
23import Common.LongFilePathOs as os
24from CommonDataClass.FdfClass import EfiSectionClassObject
25from Common import EdkLogger
26from Common.BuildToolError import *
27from Common.Misc import PeImageClass
28from Common.LongFilePathSupport import OpenLongFilePath as open
29from Common.LongFilePathSupport import CopyLongFilePath
30
31## generate rule section
32#
33#
34class EfiSection (EfiSectionClassObject):
35
36    ## The constructor
37    #
38    #   @param  self        The object pointer
39    #
40    def __init__(self):
41          EfiSectionClassObject.__init__(self)
42
43    ## GenSection() method
44    #
45    #   Generate rule section
46    #
47    #   @param  self        The object pointer
48    #   @param  OutputPath  Where to place output file
49    #   @param  ModuleName  Which module this section belongs to
50    #   @param  SecNum      Index of section
51    #   @param  KeyStringList  Filter for inputs of section generation
52    #   @param  FfsInf      FfsInfStatement object that contains this section data
53    #   @param  Dict        dictionary contains macro and its value
54    #   @retval tuple       (Generated file name list, section alignment)
55    #
56    def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}) :
57
58        if self.FileName != None and self.FileName.startswith('PCD('):
59            self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName)
60        """Prepare the parameter of GenSection"""
61        if FfsInf != None :
62            InfFileName = FfsInf.InfFileName
63            SectionType = FfsInf.__ExtendMacro__(self.SectionType)
64            Filename = FfsInf.__ExtendMacro__(self.FileName)
65            BuildNum = FfsInf.__ExtendMacro__(self.BuildNum)
66            StringData = FfsInf.__ExtendMacro__(self.StringData)
67            NoStrip = True
68            if FfsInf.ModuleType in ('SEC', 'PEI_CORE', 'PEIM') and SectionType in ('TE', 'PE32'):
69                if FfsInf.KeepReloc != None:
70                    NoStrip = FfsInf.KeepReloc
71                elif FfsInf.KeepRelocFromRule != None:
72                    NoStrip = FfsInf.KeepRelocFromRule
73                elif self.KeepReloc != None:
74                    NoStrip = self.KeepReloc
75                elif FfsInf.ShadowFromInfFile != None:
76                    NoStrip = FfsInf.ShadowFromInfFile
77        else:
78            EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s apply rule for None!" %ModuleName)
79
80        """If the file name was pointed out, add it in FileList"""
81        FileList = []
82        if Filename != None:
83            Filename = GenFdsGlobalVariable.MacroExtend(Filename, Dict)
84            # check if the path is absolute or relative
85            if os.path.isabs(Filename):
86                Filename = os.path.normpath(Filename)
87            else:
88                Filename = os.path.normpath(os.path.join(FfsInf.EfiOutputPath, Filename))
89
90            if not self.Optional:
91                FileList.append(Filename)
92            elif os.path.exists(Filename):
93                FileList.append(Filename)
94        else:
95            FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict)
96            if IsSect :
97                return FileList, self.Alignment
98
99        Index = 0
100        Align = self.Alignment
101
102        """ If Section type is 'VERSION'"""
103        OutputFileList = []
104        if SectionType == 'VERSION':
105
106            InfOverrideVerString = False
107            if FfsInf.Version != None:
108                #StringData = FfsInf.Version
109                BuildNum = FfsInf.Version
110                InfOverrideVerString = True
111
112            if InfOverrideVerString:
113                #VerTuple = ('-n', '"' + StringData + '"')
114                if BuildNum != None and BuildNum != '':
115                    BuildNumTuple = ('-j', BuildNum)
116                else:
117                    BuildNumTuple = tuple()
118
119                Num = SecNum
120                OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
121                GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
122                                                     #Ui=StringData,
123                                                     Ver=BuildNum)
124                OutputFileList.append(OutputFile)
125
126            elif FileList != []:
127                for File in FileList:
128                    Index = Index + 1
129                    Num = '%s.%d' %(SecNum , Index)
130                    OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType))
131                    f = open(File, 'r')
132                    VerString = f.read()
133                    f.close()
134                    BuildNum = VerString
135                    if BuildNum != None and BuildNum != '':
136                        BuildNumTuple = ('-j', BuildNum)
137                    GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
138                                                         #Ui=VerString,
139                                                         Ver=BuildNum)
140                    OutputFileList.append(OutputFile)
141
142            else:
143                BuildNum = StringData
144                if BuildNum != None and BuildNum != '':
145                    BuildNumTuple = ('-j', BuildNum)
146                else:
147                    BuildNumTuple = tuple()
148                BuildNumString = ' ' + ' '.join(BuildNumTuple)
149
150                #if VerString == '' and
151                if BuildNumString == '':
152                    if self.Optional == True :
153                        GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!")
154                        return [], None
155                    else:
156                        EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss Version Section value" %InfFileName)
157                Num = SecNum
158                OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
159                GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
160                                                     #Ui=VerString,
161                                                     Ver=BuildNum)
162                OutputFileList.append(OutputFile)
163
164        #
165        # If Section Type is 'UI'
166        #
167        elif SectionType == 'UI':
168
169            InfOverrideUiString = False
170            if FfsInf.Ui != None:
171                StringData = FfsInf.Ui
172                InfOverrideUiString = True
173
174            if InfOverrideUiString:
175                Num = SecNum
176                OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
177                GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
178                                                     Ui=StringData)
179                OutputFileList.append(OutputFile)
180
181            elif FileList != []:
182                for File in FileList:
183                    Index = Index + 1
184                    Num = '%s.%d' %(SecNum , Index)
185                    OutputFile = os.path.join(OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType))
186                    f = open(File, 'r')
187                    UiString = f.read()
188                    f.close()
189                    GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
190                                                         Ui=UiString)
191                    OutputFileList.append(OutputFile)
192            else:
193                if StringData != None and len(StringData) > 0:
194                    UiTuple = ('-n', '"' + StringData + '"')
195                else:
196                    UiTuple = tuple()
197
198                    if self.Optional == True :
199                        GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!")
200                        return '', None
201                    else:
202                        EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss UI Section value" %InfFileName)
203
204                Num = SecNum
205                OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + str(Num) + Ffs.SectionSuffix.get(SectionType))
206                GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
207                                                     Ui=StringData)
208                OutputFileList.append(OutputFile)
209
210
211        else:
212            """If File List is empty"""
213            if FileList == [] :
214                if self.Optional == True:
215                    GenFdsGlobalVariable.VerboseLogger("Optional Section don't exist!")
216                    return [], None
217                else:
218                    EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName))
219
220            else:
221                """Convert the File to Section file one by one """
222                for File in FileList:
223                    """ Copy Map file to FFS output path """
224                    Index = Index + 1
225                    Num = '%s.%d' %(SecNum , Index)
226                    OutputFile = os.path.join( OutputPath, ModuleName + 'SEC' + Num + Ffs.SectionSuffix.get(SectionType))
227                    File = GenFdsGlobalVariable.MacroExtend(File, Dict)
228
229                    #Get PE Section alignment when align is set to AUTO
230                    if self.Alignment == 'Auto' and (SectionType == 'PE32' or SectionType == 'TE'):
231                        ImageObj = PeImageClass (File)
232                        if ImageObj.SectionAlignment < 0x400:
233                            Align = str (ImageObj.SectionAlignment)
234                        else:
235                            Align = str (ImageObj.SectionAlignment / 0x400) + 'K'
236
237                    if File[(len(File)-4):] == '.efi':
238                        MapFile = File.replace('.efi', '.map')
239                        if os.path.exists(MapFile):
240                            CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
241                            if not os.path.exists(CopyMapFile) or \
242                                   (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
243                                CopyLongFilePath(MapFile, CopyMapFile)
244
245                    if not NoStrip:
246                        FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi')
247                        if not os.path.exists(FileBeforeStrip) or \
248                            (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
249                            CopyLongFilePath(File, FileBeforeStrip)
250                        StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
251                        GenFdsGlobalVariable.GenerateFirmwareImage(
252                                                StrippedFile,
253                                                [File],
254                                                Strip=True
255                                                )
256                        File = StrippedFile
257
258                    """For TE Section call GenFw to generate TE image"""
259
260                    if SectionType == 'TE':
261                        TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
262                        GenFdsGlobalVariable.GenerateFirmwareImage(
263                                                TeFile,
264                                                [File],
265                                                Type='te'
266                                                )
267                        File = TeFile
268
269                    """Call GenSection"""
270                    GenFdsGlobalVariable.GenerateSection(OutputFile,
271                                                         [File],
272                                                         Section.Section.SectionType.get (SectionType)
273                                                         )
274                    OutputFileList.append(OutputFile)
275
276        return OutputFileList, Align
277