]> git.proxmox.com Git - mirror_edk2.git/blob - BaseTools/Source/Python/GenFds/GuidSection.py
e41c2fd31e6c8f584a2358665a936c95e839ebab
[mirror_edk2.git] / BaseTools / Source / Python / GenFds / GuidSection.py
1 ## @file
2 # process GUIDed section generation
3 #
4 # Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>
5 # Copyright (c) 2018, Hewlett Packard Enterprise Development, 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 #
19 from __future__ import absolute_import
20 from . import Section
21 import subprocess
22 from .Ffs import Ffs
23 import Common.LongFilePathOs as os
24 from .GenFdsGlobalVariable import GenFdsGlobalVariable
25 from CommonDataClass.FdfClass import GuidSectionClassObject
26 from Common import ToolDefClassObject
27 import sys
28 from Common import EdkLogger
29 from Common.BuildToolError import *
30 from .FvImageSection import FvImageSection
31 from Common.LongFilePathSupport import OpenLongFilePath as open
32 from Common.DataType import *
33
34 ## generate GUIDed section
35 #
36 #
37 class GuidSection(GuidSectionClassObject) :
38
39 ## The constructor
40 #
41 # @param self The object pointer
42 #
43 def __init__(self):
44 GuidSectionClassObject.__init__(self)
45
46 ## GenSection() method
47 #
48 # Generate GUIDed section
49 #
50 # @param self The object pointer
51 # @param OutputPath Where to place output file
52 # @param ModuleName Which module this section belongs to
53 # @param SecNum Index of section
54 # @param KeyStringList Filter for inputs of section generation
55 # @param FfsInf FfsInfStatement object that contains this section data
56 # @param Dict dictionary contains macro and its value
57 # @retval tuple (Generated file name, section alignment)
58 #
59 def GenSection(self, OutputPath, ModuleName, SecNum, KeyStringList, FfsInf=None, Dict={}, IsMakefile=False):
60 #
61 # Generate all section
62 #
63 self.KeyStringList = KeyStringList
64 self.CurrentArchList = GenFdsGlobalVariable.ArchList
65 if FfsInf is not None:
66 self.Alignment = FfsInf.__ExtendMacro__(self.Alignment)
67 self.NameGuid = FfsInf.__ExtendMacro__(self.NameGuid)
68 self.SectionType = FfsInf.__ExtendMacro__(self.SectionType)
69 self.CurrentArchList = [FfsInf.CurrentArch]
70
71 SectFile = tuple()
72 SectAlign = []
73 Index = 0
74 MaxAlign = None
75 if self.FvAddr != []:
76 FvAddrIsSet = True
77 else:
78 FvAddrIsSet = False
79
80 if self.ProcessRequired in ("TRUE", "1"):
81 if self.FvAddr != []:
82 #no use FvAddr when the image is processed.
83 self.FvAddr = []
84 if self.FvParentAddr is not None:
85 #no use Parent Addr when the image is processed.
86 self.FvParentAddr = None
87
88 for Sect in self.SectionList:
89 Index = Index + 1
90 SecIndex = '%s.%d' % (SecNum, Index)
91 # set base address for inside FvImage
92 if isinstance(Sect, FvImageSection):
93 if self.FvAddr != []:
94 Sect.FvAddr = self.FvAddr.pop(0)
95 self.IncludeFvSection = True
96 elif isinstance(Sect, GuidSection):
97 Sect.FvAddr = self.FvAddr
98 Sect.FvParentAddr = self.FvParentAddr
99 ReturnSectList, align = Sect.GenSection(OutputPath, ModuleName, SecIndex, KeyStringList, FfsInf, Dict, IsMakefile=IsMakefile)
100 if isinstance(Sect, GuidSection):
101 if Sect.IncludeFvSection:
102 self.IncludeFvSection = Sect.IncludeFvSection
103
104 if align is not None:
105 if MaxAlign is None:
106 MaxAlign = align
107 if GenFdsGlobalVariable.GetAlignment (align) > GenFdsGlobalVariable.GetAlignment (MaxAlign):
108 MaxAlign = align
109 if ReturnSectList != []:
110 if align is None:
111 align = "1"
112 for file in ReturnSectList:
113 SectFile += (file,)
114 SectAlign.append(align)
115
116 if MaxAlign is not None:
117 if self.Alignment is None:
118 self.Alignment = MaxAlign
119 else:
120 if GenFdsGlobalVariable.GetAlignment (MaxAlign) > GenFdsGlobalVariable.GetAlignment (self.Alignment):
121 self.Alignment = MaxAlign
122
123 OutputFile = OutputPath + \
124 os.sep + \
125 ModuleName + \
126 SUP_MODULE_SEC + \
127 SecNum + \
128 Ffs.SectionSuffix['GUIDED']
129 OutputFile = os.path.normpath(OutputFile)
130
131 ExternalTool = None
132 ExternalOption = None
133 if self.NameGuid is not None:
134 from .GenFds import FindExtendTool
135 ExternalTool, ExternalOption = FindExtendTool(self.KeyStringList, self.CurrentArchList, self.NameGuid)
136
137 #
138 # If not have GUID , call default
139 # GENCRC32 section
140 #
141 if self.NameGuid is None :
142 GenFdsGlobalVariable.VerboseLogger("Use GenSection function Generate CRC32 Section")
143 GenFdsGlobalVariable.GenerateSection(OutputFile, SectFile, Section.Section.SectionType[self.SectionType], InputAlign=SectAlign, IsMakefile=IsMakefile)
144 OutputFileList = []
145 OutputFileList.append(OutputFile)
146 return OutputFileList, self.Alignment
147 #or GUID not in External Tool List
148 elif ExternalTool is None:
149 EdkLogger.error("GenFds", GENFDS_ERROR, "No tool found with GUID %s" % self.NameGuid)
150 else:
151 DummyFile = OutputFile + ".dummy"
152 #
153 # Call GenSection with DUMMY section type.
154 #
155 GenFdsGlobalVariable.GenerateSection(DummyFile, SectFile, InputAlign=SectAlign, IsMakefile=IsMakefile)
156 #
157 # Use external tool process the Output
158 #
159 TempFile = OutputPath + \
160 os.sep + \
161 ModuleName + \
162 SUP_MODULE_SEC + \
163 SecNum + \
164 '.tmp'
165 TempFile = os.path.normpath(TempFile)
166 #
167 # Remove temp file if its time stamp is older than dummy file
168 # Just in case the external tool fails at this time but succeeded before
169 # Error should be reported if the external tool does not generate a new output based on new input
170 #
171 if os.path.exists(TempFile) and os.path.exists(DummyFile) and os.path.getmtime(TempFile) < os.path.getmtime(DummyFile):
172 os.remove(TempFile)
173
174 FirstCall = False
175 CmdOption = '-e'
176 if ExternalOption is not None:
177 CmdOption = CmdOption + ' ' + ExternalOption
178 if not GenFdsGlobalVariable.EnableGenfdsMultiThread:
179 if self.ProcessRequired not in ("TRUE", "1") and self.IncludeFvSection and not FvAddrIsSet and self.FvParentAddr is not None:
180 #FirstCall is only set for the encapsulated flash FV image without process required attribute.
181 FirstCall = True
182 #
183 # Call external tool
184 #
185 ReturnValue = [1]
186 if FirstCall:
187 #first try to call the guided tool with -z option and CmdOption for the no process required guided tool.
188 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, '-z' + ' ' + CmdOption, ReturnValue)
189
190 #
191 # when no call or first call failed, ReturnValue are not 1.
192 # Call the guided tool with CmdOption
193 #
194 if ReturnValue[0] != 0:
195 FirstCall = False
196 ReturnValue[0] = 0
197 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
198 #
199 # There is external tool which does not follow standard rule which return nonzero if tool fails
200 # The output file has to be checked
201 #
202
203 if not os.path.exists(TempFile) :
204 EdkLogger.error("GenFds", COMMAND_FAILURE, 'Fail to call %s, no output file was generated' % ExternalTool)
205
206 FileHandleIn = open(DummyFile, 'rb')
207 FileHandleIn.seek(0, 2)
208 InputFileSize = FileHandleIn.tell()
209
210 FileHandleOut = open(TempFile, 'rb')
211 FileHandleOut.seek(0, 2)
212 TempFileSize = FileHandleOut.tell()
213
214 Attribute = []
215 HeaderLength = None
216 if self.ExtraHeaderSize != -1:
217 HeaderLength = str(self.ExtraHeaderSize)
218
219 if self.ProcessRequired == "NONE" and HeaderLength is None:
220 if TempFileSize > InputFileSize:
221 FileHandleIn.seek(0)
222 BufferIn = FileHandleIn.read()
223 FileHandleOut.seek(0)
224 BufferOut = FileHandleOut.read()
225 if BufferIn == BufferOut[TempFileSize - InputFileSize:]:
226 HeaderLength = str(TempFileSize - InputFileSize)
227 #auto sec guided attribute with process required
228 if HeaderLength is None:
229 Attribute.append('PROCESSING_REQUIRED')
230
231 FileHandleIn.close()
232 FileHandleOut.close()
233
234 if FirstCall and 'PROCESSING_REQUIRED' in Attribute:
235 # Guided data by -z option on first call is the process required data. Call the guided tool with the real option.
236 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption)
237
238 #
239 # Call Gensection Add Section Header
240 #
241 if self.ProcessRequired in ("TRUE", "1"):
242 if 'PROCESSING_REQUIRED' not in Attribute:
243 Attribute.append('PROCESSING_REQUIRED')
244
245 if self.AuthStatusValid in ("TRUE", "1"):
246 Attribute.append('AUTH_STATUS_VALID')
247 GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
248 Guid=self.NameGuid, GuidAttr=Attribute, GuidHdrLen=HeaderLength)
249
250 else:
251 #add input file for GenSec get PROCESSING_REQUIRED
252 GenFdsGlobalVariable.GuidTool(TempFile, [DummyFile], ExternalTool, CmdOption, IsMakefile=IsMakefile)
253 Attribute = []
254 HeaderLength = None
255 if self.ExtraHeaderSize != -1:
256 HeaderLength = str(self.ExtraHeaderSize)
257 if self.AuthStatusValid in ("TRUE", "1"):
258 Attribute.append('AUTH_STATUS_VALID')
259 if self.ProcessRequired == "NONE" and HeaderLength is None:
260 GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
261 Guid=self.NameGuid, GuidAttr=Attribute,
262 GuidHdrLen=HeaderLength, DummyFile=DummyFile, IsMakefile=IsMakefile)
263 else:
264 if self.ProcessRequired in ("TRUE", "1"):
265 if 'PROCESSING_REQUIRED' not in Attribute:
266 Attribute.append('PROCESSING_REQUIRED')
267 GenFdsGlobalVariable.GenerateSection(OutputFile, [TempFile], Section.Section.SectionType['GUIDED'],
268 Guid=self.NameGuid, GuidAttr=Attribute,
269 GuidHdrLen=HeaderLength, IsMakefile=IsMakefile)
270
271 OutputFileList = []
272 OutputFileList.append(OutputFile)
273 if 'PROCESSING_REQUIRED' in Attribute:
274 # reset guided section alignment to none for the processed required guided data
275 self.Alignment = None
276 self.IncludeFvSection = False
277 self.ProcessRequired = "TRUE"
278 if IsMakefile and self.Alignment is not None and self.Alignment.strip() == '0':
279 self.Alignment = '1'
280 return OutputFileList, self.Alignment
281
282
283