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