]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/EfiSection.py
BaseTools:Make BaseTools support new rules to generate RAW FFS FILE
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / EfiSection.py
1 ## @file
2 # process rule section generation
3 #
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 #
6 # SPDX-License-Identifier: BSD-2-Clause-Patent
7 #
8
9 ##
10 # Import Modules
11 #
12 from __future__ import absolute_import
13 from struct import *
14 from . import Section
15 from .GenFdsGlobalVariable import GenFdsGlobalVariable
16 import subprocess
17 from .Ffs import SectionSuffix
18 import Common.LongFilePathOs as os
19 from CommonDataClass.FdfClass import EfiSectionClassObject
20 from Common import EdkLogger
21 from Common.BuildToolError import *
22 from Common.Misc import PeImageClass
23 from Common.LongFilePathSupport import OpenLongFilePath as open
24 from Common.LongFilePathSupport import CopyLongFilePath
25 from Common.DataType import *
26
27 ## generate rule section
28 #
29 #
30 class EfiSection (EfiSectionClassObject):
31
32 ## The constructor
33 #
34 # @param self The object pointer
35 #
36 def __init__(self):
37 EfiSectionClassObject.__init__(self)
38
39 ## GenSection() method
40 #
41 # Generate rule section
42 #
43 # @param self The object pointer
44 # @param OutputPath Where to place output file
45 # @param ModuleName Which module this section belongs to
46 # @param SecNum Index of section
47 # @param KeyStringList Filter for inputs of section generation
48 # @param FfsInf FfsInfStatement object that contains this section data
49 # @param Dict dictionary contains macro and its value
50 # @retval tuple (Generated file name list, section alignment)
51 #
52 def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf = None, Dict = {}, IsMakefile = False) :
53
54 if self.FileName is not None and self.FileName.startswith('PCD('):
55 self.FileName = GenFdsGlobalVariable.GetPcdValue(self.FileName)
56 """Prepare the parameter of GenSection"""
57 if FfsInf is not None :
58 InfFileName = FfsInf.InfFileName
59 SectionType = FfsInf.__ExtendMacro__(self.SectionType)
60 Filename = FfsInf.__ExtendMacro__(self.FileName)
61 BuildNum = FfsInf.__ExtendMacro__(self.BuildNum)
62 StringData = FfsInf.__ExtendMacro__(self.StringData)
63 ModuleNameStr = FfsInf.__ExtendMacro__('$(MODULE_NAME)')
64 NoStrip = True
65 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):
66 if FfsInf.KeepReloc is not None:
67 NoStrip = FfsInf.KeepReloc
68 elif FfsInf.KeepRelocFromRule is not None:
69 NoStrip = FfsInf.KeepRelocFromRule
70 elif self.KeepReloc is not None:
71 NoStrip = self.KeepReloc
72 elif FfsInf.ShadowFromInfFile is not None:
73 NoStrip = FfsInf.ShadowFromInfFile
74 else:
75 EdkLogger.error("GenFds", GENFDS_ERROR, "Module %s apply rule for None!" %ModuleName)
76
77 """If the file name was pointed out, add it in FileList"""
78 FileList = []
79 if Filename is not None:
80 Filename = GenFdsGlobalVariable.MacroExtend(Filename, Dict)
81 # check if the path is absolute or relative
82 if os.path.isabs(Filename):
83 Filename = os.path.normpath(Filename)
84 else:
85 Filename = os.path.normpath(os.path.join(FfsInf.EfiOutputPath, Filename))
86
87 if not self.Optional:
88 FileList.append(Filename)
89 elif os.path.exists(Filename):
90 FileList.append(Filename)
91 elif IsMakefile:
92 SuffixMap = FfsInf.GetFinalTargetSuffixMap()
93 if '.depex' in SuffixMap:
94 FileList.append(Filename)
95 else:
96 FileList, IsSect = Section.Section.GetFileList(FfsInf, self.FileType, self.FileExtension, Dict, IsMakefile=IsMakefile, SectionType=SectionType)
97 if IsSect :
98 return FileList, self.Alignment
99
100 Index = 0
101 Align = self.Alignment
102
103 """ If Section type is 'VERSION'"""
104 OutputFileList = []
105 if SectionType == 'VERSION':
106
107 InfOverrideVerString = False
108 if FfsInf.Version is not None:
109 #StringData = FfsInf.Version
110 BuildNum = FfsInf.Version
111 InfOverrideVerString = True
112
113 if InfOverrideVerString:
114 #VerTuple = ('-n', '"' + StringData + '"')
115 if BuildNum is not None and BuildNum != '':
116 BuildNumTuple = ('-j', BuildNum)
117 else:
118 BuildNumTuple = tuple()
119
120 Num = SecNum
121 OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType))
122 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
123 #Ui=StringData,
124 Ver=BuildNum,
125 IsMakefile=IsMakefile)
126 OutputFileList.append(OutputFile)
127
128 elif FileList != []:
129 for File in FileList:
130 Index = Index + 1
131 Num = '%s.%d' %(SecNum, Index)
132 OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType))
133 f = open(File, 'r')
134 VerString = f.read()
135 f.close()
136 BuildNum = VerString
137 if BuildNum is not None and BuildNum != '':
138 BuildNumTuple = ('-j', BuildNum)
139 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
140 #Ui=VerString,
141 Ver=BuildNum,
142 IsMakefile=IsMakefile)
143 OutputFileList.append(OutputFile)
144
145 else:
146 BuildNum = StringData
147 if BuildNum is not None and BuildNum != '':
148 BuildNumTuple = ('-j', BuildNum)
149 else:
150 BuildNumTuple = tuple()
151 BuildNumString = ' ' + ' '.join(BuildNumTuple)
152
153 #if VerString == '' and
154 if BuildNumString == '':
155 if self.Optional == True :
156 GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!")
157 return [], None
158 else:
159 EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss Version Section value" %InfFileName)
160 Num = SecNum
161 OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType))
162 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_VERSION',
163 #Ui=VerString,
164 Ver=BuildNum,
165 IsMakefile=IsMakefile)
166 OutputFileList.append(OutputFile)
167
168 #
169 # If Section Type is BINARY_FILE_TYPE_UI
170 #
171 elif SectionType == BINARY_FILE_TYPE_UI:
172
173 InfOverrideUiString = False
174 if FfsInf.Ui is not None:
175 StringData = FfsInf.Ui
176 InfOverrideUiString = True
177
178 if InfOverrideUiString:
179 Num = SecNum
180 if IsMakefile and StringData == ModuleNameStr:
181 StringData = "$(MODULE_NAME)"
182 OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType))
183 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
184 Ui=StringData, IsMakefile=IsMakefile)
185 OutputFileList.append(OutputFile)
186
187 elif FileList != []:
188 for File in FileList:
189 Index = Index + 1
190 Num = '%s.%d' %(SecNum, Index)
191 OutputFile = os.path.join(OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType))
192 f = open(File, 'r')
193 UiString = f.read()
194 f.close()
195 if IsMakefile and UiString == ModuleNameStr:
196 UiString = "$(MODULE_NAME)"
197 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
198 Ui=UiString, IsMakefile=IsMakefile)
199 OutputFileList.append(OutputFile)
200 else:
201 if StringData is not None and len(StringData) > 0:
202 UiTuple = ('-n', '"' + StringData + '"')
203 else:
204 UiTuple = tuple()
205
206 if self.Optional == True :
207 GenFdsGlobalVariable.VerboseLogger( "Optional Section don't exist!")
208 return '', None
209 else:
210 EdkLogger.error("GenFds", GENFDS_ERROR, "File: %s miss UI Section value" %InfFileName)
211
212 Num = SecNum
213 if IsMakefile and StringData == ModuleNameStr:
214 StringData = "$(MODULE_NAME)"
215 OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + str(Num) + SectionSuffix.get(SectionType))
216 GenFdsGlobalVariable.GenerateSection(OutputFile, [], 'EFI_SECTION_USER_INTERFACE',
217 Ui=StringData, IsMakefile=IsMakefile)
218 OutputFileList.append(OutputFile)
219
220 #
221 # If Section Type is BINARY_FILE_TYPE_RAW
222 #
223 elif SectionType == BINARY_FILE_TYPE_RAW:
224 """If File List is empty"""
225 if FileList == []:
226 if self.Optional == True:
227 GenFdsGlobalVariable.VerboseLogger("Optional Section don't exist!")
228 return [], None
229 else:
230 EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName))
231
232 elif len(FileList) > 1:
233 EdkLogger.error("GenFds", GENFDS_ERROR,
234 "Files suffixed with %s are not allowed to have more than one file in %s[Binaries] section" % (
235 self.FileExtension, InfFileName))
236 else:
237 for File in FileList:
238 File = GenFdsGlobalVariable.MacroExtend(File, Dict)
239 OutputFileList.append(File)
240
241 else:
242 """If File List is empty"""
243 if FileList == [] :
244 if self.Optional == True:
245 GenFdsGlobalVariable.VerboseLogger("Optional Section don't exist!")
246 return [], None
247 else:
248 EdkLogger.error("GenFds", GENFDS_ERROR, "Output file for %s section could not be found for %s" % (SectionType, InfFileName))
249
250 else:
251 """Convert the File to Section file one by one """
252 for File in FileList:
253 """ Copy Map file to FFS output path """
254 Index = Index + 1
255 Num = '%s.%d' %(SecNum, Index)
256 OutputFile = os.path.join( OutputPath, ModuleName + SUP_MODULE_SEC + Num + SectionSuffix.get(SectionType))
257 File = GenFdsGlobalVariable.MacroExtend(File, Dict)
258
259 #Get PE Section alignment when align is set to AUTO
260 if self.Alignment == 'Auto' and (SectionType == BINARY_FILE_TYPE_PE32 or SectionType == BINARY_FILE_TYPE_TE):
261 ImageObj = PeImageClass (File)
262 if ImageObj.SectionAlignment < 0x400:
263 Align = str (ImageObj.SectionAlignment)
264 elif ImageObj.SectionAlignment < 0x100000:
265 Align = str (ImageObj.SectionAlignment // 0x400) + 'K'
266 else:
267 Align = str (ImageObj.SectionAlignment // 0x100000) + 'M'
268
269 if File[(len(File)-4):] == '.efi':
270 MapFile = File.replace('.efi', '.map')
271 CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
272 if IsMakefile:
273 if GenFdsGlobalVariable.CopyList == []:
274 GenFdsGlobalVariable.CopyList = [(MapFile, CopyMapFile)]
275 else:
276 GenFdsGlobalVariable.CopyList.append((MapFile, CopyMapFile))
277 else:
278 if os.path.exists(MapFile):
279 if not os.path.exists(CopyMapFile) or \
280 (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
281 CopyLongFilePath(MapFile, CopyMapFile)
282
283 if not NoStrip:
284 FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi')
285 if IsMakefile:
286 if GenFdsGlobalVariable.CopyList == []:
287 GenFdsGlobalVariable.CopyList = [(File, FileBeforeStrip)]
288 else:
289 GenFdsGlobalVariable.CopyList.append((File, FileBeforeStrip))
290 else:
291 if not os.path.exists(FileBeforeStrip) or \
292 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
293 CopyLongFilePath(File, FileBeforeStrip)
294 StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
295 GenFdsGlobalVariable.GenerateFirmwareImage(
296 StrippedFile,
297 [File],
298 Strip=True,
299 IsMakefile = IsMakefile
300 )
301 File = StrippedFile
302
303 """For TE Section call GenFw to generate TE image"""
304
305 if SectionType == BINARY_FILE_TYPE_TE:
306 TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
307 GenFdsGlobalVariable.GenerateFirmwareImage(
308 TeFile,
309 [File],
310 Type='te',
311 IsMakefile = IsMakefile
312 )
313 File = TeFile
314
315 """Call GenSection"""
316 GenFdsGlobalVariable.GenerateSection(OutputFile,
317 [File],
318 Section.Section.SectionType.get (SectionType),
319 IsMakefile=IsMakefile
320 )
321 OutputFileList.append(OutputFile)
322
323 return OutputFileList, Align