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