]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/EfiSection.py
BaseTools: extend FFS alignment to 16M
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / EfiSection.py
1 ## @file
2 # process rule section generation
3 #
4 # Copyright (c) 2007 - 2017, 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 #
18 from struct import *
19 import Section
20 from GenFdsGlobalVariable import GenFdsGlobalVariable
21 import subprocess
22 from Ffs import Ffs
23 import Common.LongFilePathOs as os
24 from CommonDataClass.FdfClass import EfiSectionClassObject
25 from Common import EdkLogger
26 from Common.BuildToolError import *
27 from Common.Misc import PeImageClass
28 from Common.LongFilePathSupport import OpenLongFilePath as open
29 from Common.LongFilePathSupport import CopyLongFilePath
30
31 ## generate rule section
32 #
33 #
34 class 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 elif ImageObj.SectionAlignment < 0x100000:
235 Align = str (ImageObj.SectionAlignment / 0x400) + 'K'
236 else:
237 Align = str (ImageObj.SectionAlignment / 0x100000) + 'M'
238
239 if File[(len(File)-4):] == '.efi':
240 MapFile = File.replace('.efi', '.map')
241 if os.path.exists(MapFile):
242 CopyMapFile = os.path.join(OutputPath, ModuleName + '.map')
243 if not os.path.exists(CopyMapFile) or \
244 (os.path.getmtime(MapFile) > os.path.getmtime(CopyMapFile)):
245 CopyLongFilePath(MapFile, CopyMapFile)
246
247 if not NoStrip:
248 FileBeforeStrip = os.path.join(OutputPath, ModuleName + '.efi')
249 if not os.path.exists(FileBeforeStrip) or \
250 (os.path.getmtime(File) > os.path.getmtime(FileBeforeStrip)):
251 CopyLongFilePath(File, FileBeforeStrip)
252 StrippedFile = os.path.join(OutputPath, ModuleName + '.stripped')
253 GenFdsGlobalVariable.GenerateFirmwareImage(
254 StrippedFile,
255 [File],
256 Strip=True
257 )
258 File = StrippedFile
259
260 """For TE Section call GenFw to generate TE image"""
261
262 if SectionType == 'TE':
263 TeFile = os.path.join( OutputPath, ModuleName + 'Te.raw')
264 GenFdsGlobalVariable.GenerateFirmwareImage(
265 TeFile,
266 [File],
267 Type='te'
268 )
269 File = TeFile
270
271 """Call GenSection"""
272 GenFdsGlobalVariable.GenerateSection(OutputFile,
273 [File],
274 Section.Section.SectionType.get (SectionType)
275 )
276 OutputFileList.append(OutputFile)
277
278 return OutputFileList, Align