]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Eot/EotMain.py
BaseTools/Tests: Update GNUmakefile to use python3 variable
[mirror_edk2.git] / BaseTools / Source / Python / Eot / EotMain.py
CommitLineData
52302d4d
LG
1## @file\r
2# This file is used to be the main entrance of EOT tool\r
3#\r
d498274f 4# Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>\r
40d841f6 5# This program and the accompanying materials\r
52302d4d
LG
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
13\r
14##\r
15# Import Modules\r
16#\r
64429fbd 17from __future__ import absolute_import\r
1be2ed90 18import Common.LongFilePathOs as os, time, glob\r
52302d4d 19import Common.EdkLogger as EdkLogger\r
22c4de1a 20from Eot import EotGlobalData\r
52302d4d 21from optparse import OptionParser\r
5a57246e 22from Common.StringUtils import NormPath\r
52302d4d 23from Common import BuildToolError\r
e95a0dfb 24from Common.Misc import GuidStructureStringToGuidString, sdict\r
22c4de1a
HC
25from Eot.Parser import *\r
26from Eot.InfParserLite import EdkInfParser\r
27from Common.StringUtils import GetSplitValueList\r
28from Eot import c\r
29from Eot import Database\r
52302d4d 30from array import array\r
22c4de1a 31from Eot.Report import Report\r
b36d134f 32from Common.BuildVersion import gBUILD_VERSION\r
22c4de1a 33from Eot.Parser import ConvertGuid\r
1be2ed90 34from Common.LongFilePathSupport import OpenLongFilePath as open\r
e95a0dfb
JC
35import struct\r
36import uuid\r
37import copy\r
38import codecs\r
39\r
40gGuidStringFormat = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"\r
41gPeiAprioriFileNameGuid = '1b45cc0a-156a-428a-af62-49864da0e6e6'\r
42gAprioriGuid = 'fc510ee7-ffdc-11d4-bd41-0080c73c8881'\r
43gIndention = -4\r
44\r
45class Image(array):\r
46 _HEADER_ = struct.Struct("")\r
47 _HEADER_SIZE_ = _HEADER_.size\r
48\r
49 def __new__(cls, *args, **kwargs):\r
50 return array.__new__(cls, 'B')\r
51\r
52 def __init__(self, ID=None):\r
53 if ID is None:\r
54 self._ID_ = str(uuid.uuid1()).upper()\r
55 else:\r
56 self._ID_ = ID\r
57 self._BUF_ = None\r
58 self._LEN_ = None\r
59 self._OFF_ = None\r
60\r
61 self._SubImages = sdict() # {offset: Image()}\r
62\r
22c4de1a 63 array.__init__(self)\r
e95a0dfb
JC
64\r
65 def __repr__(self):\r
66 return self._ID_\r
67\r
68 def __len__(self):\r
69 Len = array.__len__(self)\r
22c4de1a 70 for Offset in self._SubImages.keys():\r
e95a0dfb
JC
71 Len += len(self._SubImages[Offset])\r
72 return Len\r
73\r
74 def _Unpack(self):\r
75 self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._LEN_])\r
76 return len(self)\r
77\r
78 def _Pack(self, PadByte=0xFF):\r
79 raise NotImplementedError\r
80\r
81 def frombuffer(self, Buffer, Offset=0, Size=None):\r
82 self._BUF_ = Buffer\r
83 self._OFF_ = Offset\r
84 # we may need the Size information in advance if it's given\r
85 self._LEN_ = Size\r
86 self._LEN_ = self._Unpack()\r
87\r
88 def empty(self):\r
89 del self[0:]\r
90\r
91 def GetField(self, FieldStruct, Offset=0):\r
92 return FieldStruct.unpack_from(self, Offset)\r
93\r
94 def SetField(self, FieldStruct, Offset, *args):\r
95 # check if there's enough space\r
96 Size = FieldStruct.size\r
97 if Size > len(self):\r
98 self.extend([0] * (Size - len(self)))\r
99 FieldStruct.pack_into(self, Offset, *args)\r
100\r
101 def _SetData(self, Data):\r
102 if len(self) < self._HEADER_SIZE_:\r
103 self.extend([0] * (self._HEADER_SIZE_ - len(self)))\r
104 else:\r
105 del self[self._HEADER_SIZE_:]\r
106 self.extend(Data)\r
107\r
108 def _GetData(self):\r
109 if len(self) > self._HEADER_SIZE_:\r
110 return self[self._HEADER_SIZE_:]\r
111 return None\r
112\r
113 Data = property(_GetData, _SetData)\r
114\r
115## CompressedImage() class\r
116#\r
117# A class for Compressed Image\r
118#\r
119class CompressedImage(Image):\r
120 # UncompressedLength = 4-byte\r
121 # CompressionType = 1-byte\r
122 _HEADER_ = struct.Struct("1I 1B")\r
123 _HEADER_SIZE_ = _HEADER_.size\r
124\r
125 _ORIG_SIZE_ = struct.Struct("1I")\r
126 _CMPRS_TYPE_ = struct.Struct("4x 1B")\r
127\r
4fea08b9
CJ
128 def __init__(self, CompressedData=None, CompressionType=None, UncompressedLength=None):\r
129 Image.__init__(self)\r
e95a0dfb 130 if UncompressedLength is not None:\r
4fea08b9 131 self.UncompressedLength = UncompressedLength\r
e95a0dfb 132 if CompressionType is not None:\r
4fea08b9 133 self.CompressionType = CompressionType\r
e95a0dfb 134 if CompressedData is not None:\r
4fea08b9 135 self.Data = CompressedData\r
e95a0dfb 136\r
4fea08b9 137 def __str__(self):\r
e95a0dfb 138 global gIndention\r
4fea08b9
CJ
139 S = "algorithm=%s uncompressed=%x" % (self.CompressionType, self.UncompressedLength)\r
140 for Sec in self.Sections:\r
e95a0dfb
JC
141 S += '\n' + str(Sec)\r
142\r
143 return S\r
144\r
4fea08b9
CJ
145 def _SetOriginalSize(self, Size):\r
146 self.SetField(self._ORIG_SIZE_, 0, Size)\r
e95a0dfb 147\r
4fea08b9
CJ
148 def _GetOriginalSize(self):\r
149 return self.GetField(self._ORIG_SIZE_)[0]\r
e95a0dfb 150\r
4fea08b9
CJ
151 def _SetCompressionType(self, Type):\r
152 self.SetField(self._CMPRS_TYPE_, 0, Type)\r
e95a0dfb 153\r
4fea08b9
CJ
154 def _GetCompressionType(self):\r
155 return self.GetField(self._CMPRS_TYPE_)[0]\r
e95a0dfb 156\r
4fea08b9 157 def _GetSections(self):\r
e95a0dfb 158 try:\r
22c4de1a 159 TmpData = DeCompress('Efi', self[self._HEADER_SIZE_:])\r
e95a0dfb
JC
160 DecData = array('B')\r
161 DecData.fromstring(TmpData)\r
162 except:\r
22c4de1a 163 TmpData = DeCompress('Framework', self[self._HEADER_SIZE_:])\r
e95a0dfb
JC
164 DecData = array('B')\r
165 DecData.fromstring(TmpData)\r
166\r
167 SectionList = []\r
168 Offset = 0\r
169 while Offset < len(DecData):\r
170 Sec = Section()\r
171 try:\r
172 Sec.frombuffer(DecData, Offset)\r
173 Offset += Sec.Size\r
174 # the section is aligned to 4-byte boundary\r
175 except:\r
176 break\r
177 SectionList.append(Sec)\r
178 return SectionList\r
179\r
180 UncompressedLength = property(_GetOriginalSize, _SetOriginalSize)\r
181 CompressionType = property(_GetCompressionType, _SetCompressionType)\r
182 Sections = property(_GetSections)\r
183\r
184## Ui() class\r
185#\r
186# A class for Ui\r
187#\r
188class Ui(Image):\r
189 _HEADER_ = struct.Struct("")\r
190 _HEADER_SIZE_ = 0\r
191\r
4fea08b9
CJ
192 def __init__(self):\r
193 Image.__init__(self)\r
e95a0dfb 194\r
4fea08b9
CJ
195 def __str__(self):\r
196 return self.String\r
e95a0dfb 197\r
4fea08b9 198 def _Unpack(self):\r
e95a0dfb 199 # keep header in this Image object\r
4fea08b9
CJ
200 self.empty()\r
201 self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._LEN_])\r
202 return len(self)\r
e95a0dfb 203\r
4fea08b9
CJ
204 def _GetUiString(self):\r
205 return codecs.utf_16_decode(self[0:-2].tostring())[0]\r
e95a0dfb
JC
206\r
207 String = property(_GetUiString)\r
208\r
209## Depex() class\r
210#\r
211# A class for Depex\r
212#\r
213class Depex(Image):\r
214 _HEADER_ = struct.Struct("")\r
215 _HEADER_SIZE_ = 0\r
216\r
217 _GUID_ = struct.Struct("1I2H8B")\r
218 _OPCODE_ = struct.Struct("1B")\r
219\r
220 _OPCODE_STRING_ = {\r
221 0x00 : "BEFORE",\r
222 0x01 : "AFTER",\r
223 0x02 : "PUSH",\r
224 0x03 : "AND",\r
225 0x04 : "OR",\r
226 0x05 : "NOT",\r
227 0x06 : "TRUE",\r
228 0x07 : "FALSE",\r
229 0x08 : "END",\r
230 0x09 : "SOR"\r
231 }\r
232\r
233 _NEXT_ = {\r
234 -1 : _OPCODE_, # first one in depex must be an opcdoe\r
235 0x00 : _GUID_, #"BEFORE",\r
236 0x01 : _GUID_, #"AFTER",\r
237 0x02 : _GUID_, #"PUSH",\r
238 0x03 : _OPCODE_, #"AND",\r
239 0x04 : _OPCODE_, #"OR",\r
240 0x05 : _OPCODE_, #"NOT",\r
241 0x06 : _OPCODE_, #"TRUE",\r
242 0x07 : _OPCODE_, #"FALSE",\r
243 0x08 : None, #"END",\r
244 0x09 : _OPCODE_, #"SOR"\r
245 }\r
246\r
4fea08b9
CJ
247 def __init__(self):\r
248 Image.__init__(self)\r
249 self._ExprList = []\r
e95a0dfb 250\r
4fea08b9 251 def __str__(self):\r
e95a0dfb
JC
252 global gIndention\r
253 gIndention += 4\r
254 Indention = ' ' * gIndention\r
255 S = '\n'\r
4fea08b9
CJ
256 for T in self.Expression:\r
257 if T in self._OPCODE_STRING_:\r
258 S += Indention + self._OPCODE_STRING_[T]\r
e95a0dfb
JC
259 if T not in [0x00, 0x01, 0x02]:\r
260 S += '\n'\r
261 else:\r
262 S += ' ' + gGuidStringFormat % T + '\n'\r
263 gIndention -= 4\r
264 return S\r
265\r
4fea08b9 266 def _Unpack(self):\r
e95a0dfb 267 # keep header in this Image object\r
4fea08b9
CJ
268 self.empty()\r
269 self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._LEN_])\r
270 return len(self)\r
e95a0dfb 271\r
4fea08b9
CJ
272 def _GetExpression(self):\r
273 if self._ExprList == []:\r
e95a0dfb 274 Offset = 0\r
4fea08b9
CJ
275 CurrentData = self._OPCODE_\r
276 while Offset < len(self):\r
277 Token = CurrentData.unpack_from(self, Offset)\r
e95a0dfb
JC
278 Offset += CurrentData.size\r
279 if len(Token) == 1:\r
280 Token = Token[0]\r
4fea08b9
CJ
281 if Token in self._NEXT_:\r
282 CurrentData = self._NEXT_[Token]\r
e95a0dfb 283 else:\r
4fea08b9 284 CurrentData = self._GUID_\r
e95a0dfb 285 else:\r
4fea08b9
CJ
286 CurrentData = self._OPCODE_\r
287 self._ExprList.append(Token)\r
e95a0dfb
JC
288 if CurrentData is None:\r
289 break\r
4fea08b9 290 return self._ExprList\r
e95a0dfb
JC
291\r
292 Expression = property(_GetExpression)\r
293\r
22c4de1a 294# # FirmwareVolume() class\r
e95a0dfb
JC
295#\r
296# A class for Firmware Volume\r
297#\r
298class FirmwareVolume(Image):\r
299 # Read FvLength, Attributes, HeaderLength, Checksum\r
300 _HEADER_ = struct.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")\r
301 _HEADER_SIZE_ = _HEADER_.size\r
302\r
303 _FfsGuid = "8C8CE578-8A3D-4F1C-9935-896185C32DD3"\r
304\r
22c4de1a
HC
305 _GUID_ = struct.Struct("16x 1I2H8B")\r
306 _LENGTH_ = struct.Struct("16x 16x 1Q")\r
307 _SIG_ = struct.Struct("16x 16x 8x 1I")\r
308 _ATTR_ = struct.Struct("16x 16x 8x 4x 1I")\r
309 _HLEN_ = struct.Struct("16x 16x 8x 4x 4x 1H")\r
310 _CHECKSUM_ = struct.Struct("16x 16x 8x 4x 4x 2x 1H")\r
e95a0dfb
JC
311\r
312 def __init__(self, Name=''):\r
313 Image.__init__(self)\r
314 self.Name = Name\r
315 self.FfsDict = sdict()\r
316 self.OrderedFfsDict = sdict()\r
317 self.UnDispatchedFfsDict = sdict()\r
318 self.ProtocolList = sdict()\r
319\r
320 def CheckArchProtocol(self):\r
321 for Item in EotGlobalData.gArchProtocolGuids:\r
322 if Item.lower() not in EotGlobalData.gProtocolList:\r
e95a0dfb 323 return False\r
e95a0dfb
JC
324 return True\r
325\r
326 def ParseDepex(self, Depex, Type):\r
327 List = None\r
328 if Type == 'Ppi':\r
329 List = EotGlobalData.gPpiList\r
330 if Type == 'Protocol':\r
331 List = EotGlobalData.gProtocolList\r
332 DepexStack = []\r
333 DepexList = []\r
334 DepexString = ''\r
335 FileDepex = None\r
336 CouldBeLoaded = True\r
337 for Index in range(0, len(Depex.Expression)):\r
338 Item = Depex.Expression[Index]\r
339 if Item == 0x00:\r
340 Index = Index + 1\r
341 Guid = gGuidStringFormat % Depex.Expression[Index]\r
342 if Guid in self.OrderedFfsDict and Depex.Expression[Index + 1] == 0x08:\r
343 return (True, 'BEFORE %s' % Guid, [Guid, 'BEFORE'])\r
344 elif Item == 0x01:\r
345 Index = Index + 1\r
346 Guid = gGuidStringFormat % Depex.Expression[Index]\r
347 if Guid in self.OrderedFfsDict and Depex.Expression[Index + 1] == 0x08:\r
348 return (True, 'AFTER %s' % Guid, [Guid, 'AFTER'])\r
349 elif Item == 0x02:\r
350 Index = Index + 1\r
351 Guid = gGuidStringFormat % Depex.Expression[Index]\r
352 if Guid.lower() in List:\r
353 DepexStack.append(True)\r
354 DepexList.append(Guid)\r
355 else:\r
356 DepexStack.append(False)\r
357 DepexList.append(Guid)\r
358 continue\r
359 elif Item == 0x03 or Item == 0x04:\r
360 DepexStack.append(eval(str(DepexStack.pop()) + ' ' + Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop())))\r
361 DepexList.append(str(DepexList.pop()) + ' ' + Depex._OPCODE_STRING_[Item].upper() + ' ' + str(DepexList.pop()))\r
362 elif Item == 0x05:\r
363 DepexStack.append(eval(Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexStack.pop())))\r
364 DepexList.append(Depex._OPCODE_STRING_[Item].lower() + ' ' + str(DepexList.pop()))\r
365 elif Item == 0x06:\r
366 DepexStack.append(True)\r
367 DepexList.append('TRUE')\r
368 DepexString = DepexString + 'TRUE' + ' '\r
369 elif Item == 0x07:\r
370 DepexStack.append(False)\r
371 DepexList.append('False')\r
372 DepexString = DepexString + 'FALSE' + ' '\r
373 elif Item == 0x08:\r
374 if Index != len(Depex.Expression) - 1:\r
375 CouldBeLoaded = False\r
376 else:\r
377 CouldBeLoaded = DepexStack.pop()\r
378 else:\r
379 CouldBeLoaded = False\r
380 if DepexList != []:\r
381 DepexString = DepexList[0].strip()\r
382 return (CouldBeLoaded, DepexString, FileDepex)\r
383\r
22c4de1a 384 def Dispatch(self, Db=None):\r
e95a0dfb
JC
385 if Db is None:\r
386 return False\r
387 self.UnDispatchedFfsDict = copy.copy(self.FfsDict)\r
388 # Find PeiCore, DexCore, PeiPriori, DxePriori first\r
389 FfsSecCoreGuid = None\r
390 FfsPeiCoreGuid = None\r
391 FfsDxeCoreGuid = None\r
392 FfsPeiPrioriGuid = None\r
393 FfsDxePrioriGuid = None\r
22c4de1a 394 for FfsID in self.UnDispatchedFfsDict.keys():\r
e95a0dfb
JC
395 Ffs = self.UnDispatchedFfsDict[FfsID]\r
396 if Ffs.Type == 0x03:\r
397 FfsSecCoreGuid = FfsID\r
398 continue\r
399 if Ffs.Type == 0x04:\r
400 FfsPeiCoreGuid = FfsID\r
401 continue\r
402 if Ffs.Type == 0x05:\r
403 FfsDxeCoreGuid = FfsID\r
404 continue\r
405 if Ffs.Guid.lower() == gPeiAprioriFileNameGuid:\r
406 FfsPeiPrioriGuid = FfsID\r
407 continue\r
408 if Ffs.Guid.lower() == gAprioriGuid:\r
409 FfsDxePrioriGuid = FfsID\r
410 continue\r
411\r
412 # Parse SEC_CORE first\r
413 if FfsSecCoreGuid is not None:\r
414 self.OrderedFfsDict[FfsSecCoreGuid] = self.UnDispatchedFfsDict.pop(FfsSecCoreGuid)\r
415 self.LoadPpi(Db, FfsSecCoreGuid)\r
416\r
417 # Parse PEI first\r
418 if FfsPeiCoreGuid is not None:\r
419 self.OrderedFfsDict[FfsPeiCoreGuid] = self.UnDispatchedFfsDict.pop(FfsPeiCoreGuid)\r
420 self.LoadPpi(Db, FfsPeiCoreGuid)\r
421 if FfsPeiPrioriGuid is not None:\r
422 # Load PEIM described in priori file\r
423 FfsPeiPriori = self.UnDispatchedFfsDict.pop(FfsPeiPrioriGuid)\r
424 if len(FfsPeiPriori.Sections) == 1:\r
425 Section = FfsPeiPriori.Sections.popitem()[1]\r
426 if Section.Type == 0x19:\r
427 GuidStruct = struct.Struct('1I2H8B')\r
428 Start = 4\r
429 while len(Section) > Start:\r
430 Guid = GuidStruct.unpack_from(Section[Start : Start + 16])\r
431 GuidString = gGuidStringFormat % Guid\r
432 Start = Start + 16\r
433 if GuidString in self.UnDispatchedFfsDict:\r
434 self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)\r
435 self.LoadPpi(Db, GuidString)\r
22c4de1a 436\r
e95a0dfb
JC
437 self.DisPatchPei(Db)\r
438\r
439 # Parse DXE then\r
440 if FfsDxeCoreGuid is not None:\r
441 self.OrderedFfsDict[FfsDxeCoreGuid] = self.UnDispatchedFfsDict.pop(FfsDxeCoreGuid)\r
442 self.LoadProtocol(Db, FfsDxeCoreGuid)\r
443 if FfsDxePrioriGuid is not None:\r
444 # Load PEIM described in priori file\r
445 FfsDxePriori = self.UnDispatchedFfsDict.pop(FfsDxePrioriGuid)\r
446 if len(FfsDxePriori.Sections) == 1:\r
447 Section = FfsDxePriori.Sections.popitem()[1]\r
448 if Section.Type == 0x19:\r
449 GuidStruct = struct.Struct('1I2H8B')\r
450 Start = 4\r
451 while len(Section) > Start:\r
452 Guid = GuidStruct.unpack_from(Section[Start : Start + 16])\r
453 GuidString = gGuidStringFormat % Guid\r
454 Start = Start + 16\r
455 if GuidString in self.UnDispatchedFfsDict:\r
456 self.OrderedFfsDict[GuidString] = self.UnDispatchedFfsDict.pop(GuidString)\r
457 self.LoadProtocol(Db, GuidString)\r
22c4de1a 458\r
e95a0dfb
JC
459 self.DisPatchDxe(Db)\r
460\r
461 def LoadProtocol(self, Db, ModuleGuid):\r
462 SqlCommand = """select GuidValue from Report\r
463 where SourceFileFullPath in\r
464 (select Value1 from Inf where BelongsToFile =\r
465 (select BelongsToFile from Inf\r
466 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)\r
467 and Model = %s)\r
468 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \\r
469 % (ModuleGuid, 5001, 3007)\r
470 RecordSet = Db.TblReport.Exec(SqlCommand)\r
471 for Record in RecordSet:\r
472 SqlCommand = """select Value2 from Inf where BelongsToFile =\r
473 (select DISTINCT BelongsToFile from Inf\r
474 where Value1 =\r
475 (select SourceFileFullPath from Report\r
476 where GuidValue like '%s' and ItemMode = 'Callback'))\r
477 and Value1 = 'FILE_GUID'""" % Record[0]\r
478 CallBackSet = Db.TblReport.Exec(SqlCommand)\r
479 if CallBackSet != []:\r
480 EotGlobalData.gProtocolList[Record[0].lower()] = ModuleGuid\r
481 else:\r
482 EotGlobalData.gProtocolList[Record[0].lower()] = ModuleGuid\r
483\r
484 def LoadPpi(self, Db, ModuleGuid):\r
485 SqlCommand = """select GuidValue from Report\r
486 where SourceFileFullPath in\r
487 (select Value1 from Inf where BelongsToFile =\r
488 (select BelongsToFile from Inf\r
489 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)\r
490 and Model = %s)\r
491 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \\r
492 % (ModuleGuid, 5001, 3007)\r
493 RecordSet = Db.TblReport.Exec(SqlCommand)\r
494 for Record in RecordSet:\r
495 EotGlobalData.gPpiList[Record[0].lower()] = ModuleGuid\r
496\r
497 def DisPatchDxe(self, Db):\r
498 IsInstalled = False\r
499 ScheduleList = sdict()\r
22c4de1a 500 for FfsID in self.UnDispatchedFfsDict.keys():\r
e95a0dfb
JC
501 CouldBeLoaded = False\r
502 DepexString = ''\r
503 FileDepex = None\r
504 Ffs = self.UnDispatchedFfsDict[FfsID]\r
505 if Ffs.Type == 0x07:\r
506 # Get Depex\r
507 IsFoundDepex = False\r
508 for Section in Ffs.Sections.values():\r
509 # Find Depex\r
510 if Section.Type == 0x13:\r
511 IsFoundDepex = True\r
512 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Protocol')\r
513 break\r
514 if Section.Type == 0x01:\r
515 CompressSections = Section._SubImages[4]\r
516 for CompressSection in CompressSections.Sections:\r
517 if CompressSection.Type == 0x13:\r
518 IsFoundDepex = True\r
519 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(CompressSection._SubImages[4], 'Protocol')\r
520 break\r
521 if CompressSection.Type == 0x02:\r
522 NewSections = CompressSection._SubImages[4]\r
523 for NewSection in NewSections.Sections:\r
524 if NewSection.Type == 0x13:\r
525 IsFoundDepex = True\r
526 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(NewSection._SubImages[4], 'Protocol')\r
527 break\r
528\r
529 # Not find Depex\r
530 if not IsFoundDepex:\r
531 CouldBeLoaded = self.CheckArchProtocol()\r
532 DepexString = ''\r
533 FileDepex = None\r
534\r
535 # Append New Ffs\r
536 if CouldBeLoaded:\r
537 IsInstalled = True\r
538 NewFfs = self.UnDispatchedFfsDict.pop(FfsID)\r
539 NewFfs.Depex = DepexString\r
540 if FileDepex is not None:\r
541 ScheduleList.insert(FileDepex[1], FfsID, NewFfs, FileDepex[0])\r
542 else:\r
543 ScheduleList[FfsID] = NewFfs\r
544 else:\r
545 self.UnDispatchedFfsDict[FfsID].Depex = DepexString\r
546\r
22c4de1a 547 for FfsID in ScheduleList.keys():\r
e95a0dfb
JC
548 NewFfs = ScheduleList.pop(FfsID)\r
549 FfsName = 'UnKnown'\r
550 self.OrderedFfsDict[FfsID] = NewFfs\r
551 self.LoadProtocol(Db, FfsID)\r
552\r
553 SqlCommand = """select Value2 from Inf\r
554 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)\r
555 and Model = %s and Value1='BASE_NAME'""" % (FfsID, 5001, 5001)\r
556 RecordSet = Db.TblReport.Exec(SqlCommand)\r
557 if RecordSet != []:\r
558 FfsName = RecordSet[0][0]\r
22c4de1a 559\r
e95a0dfb
JC
560 if IsInstalled:\r
561 self.DisPatchDxe(Db)\r
562\r
563 def DisPatchPei(self, Db):\r
564 IsInstalled = False\r
22c4de1a 565 for FfsID in self.UnDispatchedFfsDict.keys():\r
e95a0dfb
JC
566 CouldBeLoaded = True\r
567 DepexString = ''\r
568 FileDepex = None\r
569 Ffs = self.UnDispatchedFfsDict[FfsID]\r
570 if Ffs.Type == 0x06 or Ffs.Type == 0x08:\r
571 # Get Depex\r
572 for Section in Ffs.Sections.values():\r
573 if Section.Type == 0x1B:\r
574 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(Section._SubImages[4], 'Ppi')\r
575 break\r
e95a0dfb
JC
576 if Section.Type == 0x01:\r
577 CompressSections = Section._SubImages[4]\r
578 for CompressSection in CompressSections.Sections:\r
579 if CompressSection.Type == 0x1B:\r
580 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(CompressSection._SubImages[4], 'Ppi')\r
581 break\r
582 if CompressSection.Type == 0x02:\r
583 NewSections = CompressSection._SubImages[4]\r
584 for NewSection in NewSections.Sections:\r
585 if NewSection.Type == 0x1B:\r
586 CouldBeLoaded, DepexString, FileDepex = self.ParseDepex(NewSection._SubImages[4], 'Ppi')\r
587 break\r
588\r
589 # Append New Ffs\r
590 if CouldBeLoaded:\r
591 IsInstalled = True\r
592 NewFfs = self.UnDispatchedFfsDict.pop(FfsID)\r
593 NewFfs.Depex = DepexString\r
594 self.OrderedFfsDict[FfsID] = NewFfs\r
595 self.LoadPpi(Db, FfsID)\r
596 else:\r
597 self.UnDispatchedFfsDict[FfsID].Depex = DepexString\r
598\r
599 if IsInstalled:\r
600 self.DisPatchPei(Db)\r
601\r
22c4de1a 602\r
e95a0dfb
JC
603 def __str__(self):\r
604 global gIndention\r
605 gIndention += 4\r
606 FvInfo = '\n' + ' ' * gIndention\r
22c4de1a 607 FvInfo += "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self.Name, self.FileSystemGuid, self.Size, self.Checksum)\r
e95a0dfb
JC
608 FfsInfo = "\n".join([str(self.FfsDict[FfsId]) for FfsId in self.FfsDict])\r
609 gIndention -= 4\r
610 return FvInfo + FfsInfo\r
611\r
612 def _Unpack(self):\r
613 Size = self._LENGTH_.unpack_from(self._BUF_, self._OFF_)[0]\r
614 self.empty()\r
22c4de1a 615 self.extend(self._BUF_[self._OFF_:self._OFF_ + Size])\r
e95a0dfb
JC
616\r
617 # traverse the FFS\r
618 EndOfFv = Size\r
619 FfsStartAddress = self.HeaderSize\r
620 LastFfsObj = None\r
621 while FfsStartAddress < EndOfFv:\r
622 FfsObj = Ffs()\r
623 FfsObj.frombuffer(self, FfsStartAddress)\r
624 FfsId = repr(FfsObj)\r
625 if ((self.Attributes & 0x00000800) != 0 and len(FfsObj) == 0xFFFFFF) \\r
626 or ((self.Attributes & 0x00000800) == 0 and len(FfsObj) == 0):\r
627 if LastFfsObj is not None:\r
628 LastFfsObj.FreeSpace = EndOfFv - LastFfsObj._OFF_ - len(LastFfsObj)\r
629 else:\r
630 if FfsId in self.FfsDict:\r
631 EdkLogger.error("FV", 0, "Duplicate GUID in FFS",\r
632 ExtraData="\t%s @ %s\n\t%s @ %s" \\r
633 % (FfsObj.Guid, FfsObj.Offset,\r
634 self.FfsDict[FfsId].Guid, self.FfsDict[FfsId].Offset))\r
635 self.FfsDict[FfsId] = FfsObj\r
636 if LastFfsObj is not None:\r
637 LastFfsObj.FreeSpace = FfsStartAddress - LastFfsObj._OFF_ - len(LastFfsObj)\r
638\r
639 FfsStartAddress += len(FfsObj)\r
640 #\r
641 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))\r
642 # The next FFS must be at the latest next 8-byte aligned address\r
643 #\r
644 FfsStartAddress = (FfsStartAddress + 7) & (~7)\r
645 LastFfsObj = FfsObj\r
646\r
647 def _GetAttributes(self):\r
648 return self.GetField(self._ATTR_, 0)[0]\r
649\r
650 def _GetSize(self):\r
651 return self.GetField(self._LENGTH_, 0)[0]\r
652\r
653 def _GetChecksum(self):\r
654 return self.GetField(self._CHECKSUM_, 0)[0]\r
655\r
656 def _GetHeaderLength(self):\r
657 return self.GetField(self._HLEN_, 0)[0]\r
658\r
659 def _GetFileSystemGuid(self):\r
660 return gGuidStringFormat % self.GetField(self._GUID_, 0)\r
661\r
662 Attributes = property(_GetAttributes)\r
663 Size = property(_GetSize)\r
664 Checksum = property(_GetChecksum)\r
665 HeaderSize = property(_GetHeaderLength)\r
666 FileSystemGuid = property(_GetFileSystemGuid)\r
667\r
668## GuidDefinedImage() class\r
669#\r
670# A class for GUID Defined Image\r
671#\r
672class GuidDefinedImage(Image):\r
673 _HEADER_ = struct.Struct("1I2H8B 1H 1H")\r
674 _HEADER_SIZE_ = _HEADER_.size\r
675\r
676 _GUID_ = struct.Struct("1I2H8B")\r
677 _DATA_OFFSET_ = struct.Struct("16x 1H")\r
678 _ATTR_ = struct.Struct("18x 1H")\r
679\r
680 CRC32_GUID = "FC1BCDB0-7D31-49AA-936A-A4600D9DD083"\r
681 TIANO_COMPRESS_GUID = 'A31280AD-481E-41B6-95E8-127F4C984779'\r
682 LZMA_COMPRESS_GUID = 'EE4E5898-3914-4259-9D6E-DC7BD79403CF'\r
683\r
4fea08b9
CJ
684 def __init__(self, SectionDefinitionGuid=None, DataOffset=None, Attributes=None, Data=None):\r
685 Image.__init__(self)\r
e95a0dfb 686 if SectionDefinitionGuid is not None:\r
4fea08b9 687 self.SectionDefinitionGuid = SectionDefinitionGuid\r
e95a0dfb 688 if DataOffset is not None:\r
4fea08b9 689 self.DataOffset = DataOffset\r
e95a0dfb 690 if Attributes is not None:\r
4fea08b9 691 self.Attributes = Attributes\r
e95a0dfb 692 if Data is not None:\r
4fea08b9 693 self.Data = Data\r
e95a0dfb 694\r
4fea08b9
CJ
695 def __str__(self):\r
696 S = "guid=%s" % (gGuidStringFormat % self.SectionDefinitionGuid)\r
697 for Sec in self.Sections:\r
e95a0dfb
JC
698 S += "\n" + str(Sec)\r
699 return S\r
700\r
4fea08b9 701 def _Unpack(self):\r
e95a0dfb 702 # keep header in this Image object\r
4fea08b9
CJ
703 self.empty()\r
704 self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._LEN_])\r
705 return len(self)\r
e95a0dfb 706\r
4fea08b9
CJ
707 def _SetAttribute(self, Attribute):\r
708 self.SetField(self._ATTR_, 0, Attribute)\r
e95a0dfb 709\r
4fea08b9
CJ
710 def _GetAttribute(self):\r
711 return self.GetField(self._ATTR_)[0]\r
e95a0dfb 712\r
4fea08b9
CJ
713 def _SetGuid(self, Guid):\r
714 self.SetField(self._GUID_, 0, Guid)\r
e95a0dfb 715\r
4fea08b9
CJ
716 def _GetGuid(self):\r
717 return self.GetField(self._GUID_)\r
e95a0dfb 718\r
4fea08b9
CJ
719 def _SetDataOffset(self, Offset):\r
720 self.SetField(self._DATA_OFFSET_, 0, Offset)\r
e95a0dfb 721\r
4fea08b9
CJ
722 def _GetDataOffset(self):\r
723 return self.GetField(self._DATA_OFFSET_)[0]\r
e95a0dfb 724\r
4fea08b9 725 def _GetSections(self):\r
e95a0dfb 726 SectionList = []\r
4fea08b9
CJ
727 Guid = gGuidStringFormat % self.SectionDefinitionGuid\r
728 if Guid == self.CRC32_GUID:\r
e95a0dfb 729 # skip the CRC32 value, we don't do CRC32 verification here\r
4fea08b9
CJ
730 Offset = self.DataOffset - 4\r
731 while Offset < len(self):\r
e95a0dfb
JC
732 Sec = Section()\r
733 try:\r
4fea08b9 734 Sec.frombuffer(self, Offset)\r
e95a0dfb
JC
735 Offset += Sec.Size\r
736 # the section is aligned to 4-byte boundary\r
737 Offset = (Offset + 3) & (~3)\r
738 except:\r
739 break\r
740 SectionList.append(Sec)\r
4fea08b9 741 elif Guid == self.TIANO_COMPRESS_GUID:\r
e95a0dfb 742 try:\r
e95a0dfb 743 # skip the header\r
4fea08b9 744 Offset = self.DataOffset - 4\r
22c4de1a 745 TmpData = DeCompress('Framework', self[self.Offset:])\r
e95a0dfb
JC
746 DecData = array('B')\r
747 DecData.fromstring(TmpData)\r
748 Offset = 0\r
749 while Offset < len(DecData):\r
750 Sec = Section()\r
751 try:\r
752 Sec.frombuffer(DecData, Offset)\r
753 Offset += Sec.Size\r
754 # the section is aligned to 4-byte boundary\r
755 Offset = (Offset + 3) & (~3)\r
756 except:\r
757 break\r
758 SectionList.append(Sec)\r
759 except:\r
760 pass\r
4fea08b9 761 elif Guid == self.LZMA_COMPRESS_GUID:\r
e95a0dfb 762 try:\r
e95a0dfb 763 # skip the header\r
4fea08b9 764 Offset = self.DataOffset - 4\r
22c4de1a
HC
765\r
766 TmpData = DeCompress('Lzma', self[self.Offset:])\r
e95a0dfb
JC
767 DecData = array('B')\r
768 DecData.fromstring(TmpData)\r
769 Offset = 0\r
770 while Offset < len(DecData):\r
771 Sec = Section()\r
772 try:\r
773 Sec.frombuffer(DecData, Offset)\r
774 Offset += Sec.Size\r
775 # the section is aligned to 4-byte boundary\r
776 Offset = (Offset + 3) & (~3)\r
777 except:\r
778 break\r
779 SectionList.append(Sec)\r
780 except:\r
781 pass\r
782\r
783 return SectionList\r
784\r
785 Attributes = property(_GetAttribute, _SetAttribute)\r
786 SectionDefinitionGuid = property(_GetGuid, _SetGuid)\r
787 DataOffset = property(_GetDataOffset, _SetDataOffset)\r
788 Sections = property(_GetSections)\r
789\r
790## Section() class\r
791#\r
792# A class for Section\r
793#\r
794class Section(Image):\r
795 _TypeName = {\r
796 0x00 : "<unknown>",\r
797 0x01 : "COMPRESSION",\r
798 0x02 : "GUID_DEFINED",\r
799 0x10 : "PE32",\r
800 0x11 : "PIC",\r
801 0x12 : "TE",\r
802 0x13 : "DXE_DEPEX",\r
803 0x14 : "VERSION",\r
804 0x15 : "USER_INTERFACE",\r
805 0x16 : "COMPATIBILITY16",\r
806 0x17 : "FIRMWARE_VOLUME_IMAGE",\r
807 0x18 : "FREEFORM_SUBTYPE_GUID",\r
808 0x19 : "RAW",\r
809 0x1B : "PEI_DEPEX"\r
810 }\r
811\r
812 _SectionSubImages = {\r
813 0x01 : CompressedImage,\r
814 0x02 : GuidDefinedImage,\r
815 0x17 : FirmwareVolume,\r
816 0x13 : Depex,\r
817 0x1B : Depex,\r
818 0x15 : Ui\r
819 }\r
820\r
821 # Size = 3-byte\r
822 # Type = 1-byte\r
823 _HEADER_ = struct.Struct("3B 1B")\r
824 _HEADER_SIZE_ = _HEADER_.size\r
825\r
826 # SubTypeGuid\r
827 # _FREE_FORM_SUBTYPE_GUID_HEADER_ = struct.Struct("1I2H8B")\r
e95a0dfb
JC
828 _SIZE_ = struct.Struct("3B")\r
829 _TYPE_ = struct.Struct("3x 1B")\r
830\r
4fea08b9
CJ
831 def __init__(self, Type=None, Size=None):\r
832 Image.__init__(self)\r
833 self._Alignment = 1\r
e95a0dfb 834 if Type is not None:\r
4fea08b9 835 self.Type = Type\r
e95a0dfb 836 if Size is not None:\r
4fea08b9 837 self.Size = Size\r
e95a0dfb 838\r
4fea08b9 839 def __str__(self):\r
e95a0dfb
JC
840 global gIndention\r
841 gIndention += 4\r
842 SectionInfo = ' ' * gIndention\r
4fea08b9
CJ
843 if self.Type in self._TypeName:\r
844 SectionInfo += "[SECTION:%s] offset=%x size=%x" % (self._TypeName[self.Type], self._OFF_, self.Size)\r
e95a0dfb 845 else:\r
4fea08b9 846 SectionInfo += "[SECTION:%x<unknown>] offset=%x size=%x " % (self.Type, self._OFF_, self.Size)\r
22c4de1a 847 for Offset in self._SubImages.keys():\r
4fea08b9 848 SectionInfo += ", " + str(self._SubImages[Offset])\r
e95a0dfb
JC
849 gIndention -= 4\r
850 return SectionInfo\r
851\r
4fea08b9
CJ
852 def _Unpack(self):\r
853 self.empty()\r
854 Type, = self._TYPE_.unpack_from(self._BUF_, self._OFF_)\r
855 Size1, Size2, Size3 = self._SIZE_.unpack_from(self._BUF_, self._OFF_)\r
e95a0dfb
JC
856 Size = Size1 + (Size2 << 8) + (Size3 << 16)\r
857\r
4fea08b9 858 if Type not in self._SectionSubImages:\r
e95a0dfb 859 # no need to extract sub-image, keep all in this Image object\r
4fea08b9 860 self.extend(self._BUF_[self._OFF_ : self._OFF_ + Size])\r
e95a0dfb
JC
861 else:\r
862 # keep header in this Image object\r
4fea08b9 863 self.extend(self._BUF_[self._OFF_ : self._OFF_ + self._HEADER_SIZE_])\r
e95a0dfb
JC
864 #\r
865 # use new Image object to represent payload, which may be another kind\r
866 # of image such as PE32\r
867 #\r
4fea08b9
CJ
868 PayloadOffset = self._HEADER_SIZE_\r
869 PayloadLen = self.Size - self._HEADER_SIZE_\r
870 Payload = self._SectionSubImages[self.Type]()\r
871 Payload.frombuffer(self._BUF_, self._OFF_ + self._HEADER_SIZE_, PayloadLen)\r
872 self._SubImages[PayloadOffset] = Payload\r
e95a0dfb
JC
873\r
874 return Size\r
875\r
4fea08b9 876 def _SetSize(self, Size):\r
e95a0dfb
JC
877 Size1 = Size & 0xFF\r
878 Size2 = (Size & 0xFF00) >> 8\r
879 Size3 = (Size & 0xFF0000) >> 16\r
4fea08b9 880 self.SetField(self._SIZE_, 0, Size1, Size2, Size3)\r
e95a0dfb 881\r
4fea08b9
CJ
882 def _GetSize(self):\r
883 Size1, Size2, Size3 = self.GetField(self._SIZE_)\r
e95a0dfb
JC
884 return Size1 + (Size2 << 8) + (Size3 << 16)\r
885\r
4fea08b9
CJ
886 def _SetType(self, Type):\r
887 self.SetField(self._TYPE_, 0, Type)\r
e95a0dfb 888\r
4fea08b9
CJ
889 def _GetType(self):\r
890 return self.GetField(self._TYPE_)[0]\r
e95a0dfb 891\r
4fea08b9
CJ
892 def _GetAlignment(self):\r
893 return self._Alignment\r
e95a0dfb 894\r
4fea08b9
CJ
895 def _SetAlignment(self, Alignment):\r
896 self._Alignment = Alignment\r
e95a0dfb
JC
897 AlignmentMask = Alignment - 1\r
898 # section alignment is actually for payload, so we need to add header size\r
4fea08b9 899 PayloadOffset = self._OFF_ + self._HEADER_SIZE_\r
e95a0dfb
JC
900 if (PayloadOffset & (~AlignmentMask)) == 0:\r
901 return\r
902 NewOffset = (PayloadOffset + AlignmentMask) & (~AlignmentMask)\r
4fea08b9
CJ
903 while (NewOffset - PayloadOffset) < self._HEADER_SIZE_:\r
904 NewOffset += self._Alignment\r
e95a0dfb 905\r
4fea08b9
CJ
906 def tofile(self, f):\r
907 self.Size = len(self)\r
908 Image.tofile(self, f)\r
909 for Offset in self._SubImages:\r
910 self._SubImages[Offset].tofile(f)\r
e95a0dfb
JC
911\r
912 Type = property(_GetType, _SetType)\r
913 Size = property(_GetSize, _SetSize)\r
914 Alignment = property(_GetAlignment, _SetAlignment)\r
915\r
916## Ffs() class\r
917#\r
918# A class for Ffs Section\r
919#\r
920class Ffs(Image):\r
921 _FfsFormat = "24B%(payload_size)sB"\r
922 # skip IntegrityCheck\r
923 _HEADER_ = struct.Struct("1I2H8B 2x 1B 1B 3B 1B")\r
924 _HEADER_SIZE_ = _HEADER_.size\r
925\r
926 _NAME_ = struct.Struct("1I2H8B")\r
927 _INT_CHECK_ = struct.Struct("16x 1H")\r
928 _TYPE_ = struct.Struct("18x 1B")\r
929 _ATTR_ = struct.Struct("19x 1B")\r
930 _SIZE_ = struct.Struct("20x 3B")\r
931 _STATE_ = struct.Struct("23x 1B")\r
932\r
933 VTF_GUID = "1BA0062E-C779-4582-8566-336AE8F78F09"\r
934\r
935 FFS_ATTRIB_FIXED = 0x04\r
936 FFS_ATTRIB_DATA_ALIGNMENT = 0x38\r
937 FFS_ATTRIB_CHECKSUM = 0x40\r
938\r
939 _TypeName = {\r
940 0x00 : "<unknown>",\r
941 0x01 : "RAW",\r
942 0x02 : "FREEFORM",\r
943 0x03 : "SECURITY_CORE",\r
944 0x04 : "PEI_CORE",\r
945 0x05 : "DXE_CORE",\r
946 0x06 : "PEIM",\r
947 0x07 : "DRIVER",\r
948 0x08 : "COMBINED_PEIM_DRIVER",\r
949 0x09 : "APPLICATION",\r
950 0x0A : "SMM",\r
951 0x0B : "FIRMWARE_VOLUME_IMAGE",\r
952 0x0C : "COMBINED_SMM_DXE",\r
953 0x0D : "SMM_CORE",\r
954 0x0E : "MM_STANDALONE",\r
955 0x0F : "MM_CORE_STANDALONE",\r
956 0xc0 : "OEM_MIN",\r
957 0xdf : "OEM_MAX",\r
958 0xe0 : "DEBUG_MIN",\r
959 0xef : "DEBUG_MAX",\r
960 0xf0 : "FFS_MIN",\r
961 0xff : "FFS_MAX",\r
962 0xf0 : "FFS_PAD",\r
963 }\r
964\r
965 def __init__(self):\r
966 Image.__init__(self)\r
967 self.FreeSpace = 0\r
968\r
969 self.Sections = sdict()\r
970 self.Depex = ''\r
971\r
972 self.__ID__ = None\r
973\r
974 def __str__(self):\r
975 global gIndention\r
976 gIndention += 4\r
977 Indention = ' ' * gIndention\r
978 FfsInfo = Indention\r
979 FfsInfo += "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \\r
980 (Ffs._TypeName[self.Type], self._OFF_, self.Size, self.Guid, self.FreeSpace, self.Alignment)\r
22c4de1a 981 SectionInfo = '\n'.join([str(self.Sections[Offset]) for Offset in self.Sections.keys()])\r
e95a0dfb
JC
982 gIndention -= 4\r
983 return FfsInfo + SectionInfo + "\n"\r
984\r
985 def __len__(self):\r
986 return self.Size\r
987\r
988 def __repr__(self):\r
989 return self.__ID__\r
990\r
991 def _Unpack(self):\r
992 Size1, Size2, Size3 = self._SIZE_.unpack_from(self._BUF_, self._OFF_)\r
993 Size = Size1 + (Size2 << 8) + (Size3 << 16)\r
994 self.empty()\r
995 self.extend(self._BUF_[self._OFF_ : self._OFF_ + Size])\r
996\r
997 # Pad FFS may use the same GUID. We need to avoid it.\r
998 if self.Type == 0xf0:\r
999 self.__ID__ = str(uuid.uuid1()).upper()\r
1000 else:\r
1001 self.__ID__ = self.Guid\r
1002\r
1003 # Traverse the SECTION. RAW and PAD do not have sections\r
1004 if self.Type not in [0xf0, 0x01] and Size > 0 and Size < 0xFFFFFF:\r
1005 EndOfFfs = Size\r
1006 SectionStartAddress = self._HEADER_SIZE_\r
1007 while SectionStartAddress < EndOfFfs:\r
1008 SectionObj = Section()\r
1009 SectionObj.frombuffer(self, SectionStartAddress)\r
1010 #f = open(repr(SectionObj), 'wb')\r
1011 #SectionObj.Size = 0\r
1012 #SectionObj.tofile(f)\r
1013 #f.close()\r
1014 self.Sections[SectionStartAddress] = SectionObj\r
1015 SectionStartAddress += len(SectionObj)\r
1016 SectionStartAddress = (SectionStartAddress + 3) & (~3)\r
1017\r
1018 def Pack(self):\r
1019 pass\r
1020\r
1021 def SetFreeSpace(self, Size):\r
1022 self.FreeSpace = Size\r
1023\r
1024 def _GetGuid(self):\r
1025 return gGuidStringFormat % self.Name\r
1026\r
1027 def _SetName(self, Value):\r
1028 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11\r
1029 self.SetField(self._NAME_, 0, Value)\r
1030\r
1031 def _GetName(self):\r
1032 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11\r
1033 return self.GetField(self._NAME_)\r
1034\r
4fea08b9 1035 def _SetSize(self, Size):\r
e95a0dfb
JC
1036 Size1 = Size & 0xFF\r
1037 Size2 = (Size & 0xFF00) >> 8\r
1038 Size3 = (Size & 0xFF0000) >> 16\r
4fea08b9 1039 self.SetField(self._SIZE_, 0, Size1, Size2, Size3)\r
e95a0dfb 1040\r
4fea08b9
CJ
1041 def _GetSize(self):\r
1042 Size1, Size2, Size3 = self.GetField(self._SIZE_)\r
e95a0dfb
JC
1043 return Size1 + (Size2 << 8) + (Size3 << 16)\r
1044\r
4fea08b9
CJ
1045 def _SetType(self, Type):\r
1046 self.SetField(self._TYPE_, 0, Type)\r
e95a0dfb 1047\r
4fea08b9
CJ
1048 def _GetType(self):\r
1049 return self.GetField(self._TYPE_)[0]\r
e95a0dfb
JC
1050\r
1051 def _SetAttributes(self, Value):\r
4fea08b9 1052 self.SetField(self._ATTR_, 0, Value)\r
e95a0dfb
JC
1053\r
1054 def _GetAttributes(self):\r
1055 return self.GetField(self._ATTR_)[0]\r
1056\r
1057 def _GetFixed(self):\r
1058 if (self.Attributes & self.FFS_ATTRIB_FIXED) != 0:\r
1059 return True\r
1060 return False\r
1061\r
1062 def _GetCheckSum(self):\r
1063 if (self.Attributes & self.FFS_ATTRIB_CHECKSUM) != 0:\r
1064 return True\r
1065 return False\r
1066\r
1067 def _GetAlignment(self):\r
1068 return (self.Attributes & self.FFS_ATTRIB_DATA_ALIGNMENT) >> 3\r
1069\r
1070 def _SetState(self, Value):\r
4fea08b9 1071 self.SetField(self._STATE_, 0, Value)\r
e95a0dfb
JC
1072\r
1073 def _GetState(self):\r
4fea08b9 1074 return self.GetField(self._STATE_)[0]\r
e95a0dfb
JC
1075\r
1076 Name = property(_GetName, _SetName)\r
1077 Guid = property(_GetGuid)\r
1078 Type = property(_GetType, _SetType)\r
1079 Size = property(_GetSize, _SetSize)\r
1080 Attributes = property(_GetAttributes, _SetAttributes)\r
1081 Fixed = property(_GetFixed)\r
1082 Checksum = property(_GetCheckSum)\r
1083 Alignment = property(_GetAlignment)\r
1084 State = property(_GetState, _SetState)\r
1085\r
52302d4d 1086\r
d498274f
CJ
1087## MultipleFv() class\r
1088#\r
1089# A class for Multiple FV\r
1090#\r
1091class MultipleFv(FirmwareVolume):\r
1092 def __init__(self, FvList):\r
1093 FirmwareVolume.__init__(self)\r
1094 self.BasicInfo = []\r
1095 for FvPath in FvList:\r
22c4de1a 1096 Fd = None\r
d498274f 1097 FvName = os.path.splitext(os.path.split(FvPath)[1])[0]\r
22c4de1a
HC
1098 if FvPath.strip():\r
1099 Fd = open(FvPath, 'rb')\r
d498274f
CJ
1100 Buf = array('B')\r
1101 try:\r
1102 Buf.fromfile(Fd, os.path.getsize(FvPath))\r
1103 except EOFError:\r
1104 pass\r
1105\r
1106 Fv = FirmwareVolume(FvName)\r
1107 Fv.frombuffer(Buf, 0, len(Buf))\r
1108\r
1109 self.BasicInfo.append([Fv.Name, Fv.FileSystemGuid, Fv.Size])\r
f7496d71 1110 self.FfsDict.append(Fv.FfsDict)\r
d498274f 1111\r
52302d4d
LG
1112## Class Eot\r
1113#\r
1114# This class is used to define Eot main entrance\r
1115#\r
1116# @param object: Inherited from object class\r
1117#\r
1118class Eot(object):\r
1119 ## The constructor\r
1120 #\r
1121 # @param self: The object pointer\r
1122 #\r
1123 def __init__(self, CommandLineOption=True, IsInit=True, SourceFileList=None, \\r
1124 IncludeDirList=None, DecFileList=None, GuidList=None, LogFile=None,\r
1125 FvFileList="", MapFileList="", Report='Report.html', Dispatch=None):\r
1126 # Version and Copyright\r
b36d134f 1127 self.VersionNumber = ("0.02" + " " + gBUILD_VERSION)\r
52302d4d 1128 self.Version = "%prog Version " + self.VersionNumber\r
f7496d71 1129 self.Copyright = "Copyright (c) 2008 - 2018, Intel Corporation All rights reserved."\r
52302d4d
LG
1130 self.Report = Report\r
1131\r
1132 self.IsInit = IsInit\r
1133 self.SourceFileList = SourceFileList\r
1134 self.IncludeDirList = IncludeDirList\r
1135 self.DecFileList = DecFileList\r
1136 self.GuidList = GuidList\r
1137 self.LogFile = LogFile\r
1138 self.FvFileList = FvFileList\r
1139 self.MapFileList = MapFileList\r
1140 self.Dispatch = Dispatch\r
f7496d71 1141\r
52302d4d
LG
1142 # Check workspace environment\r
1143 if "EFI_SOURCE" not in os.environ:\r
1144 if "EDK_SOURCE" not in os.environ:\r
1145 pass\r
1146 else:\r
1147 EotGlobalData.gEDK_SOURCE = os.path.normpath(os.getenv("EDK_SOURCE"))\r
1148 else:\r
1149 EotGlobalData.gEFI_SOURCE = os.path.normpath(os.getenv("EFI_SOURCE"))\r
1150 EotGlobalData.gEDK_SOURCE = os.path.join(EotGlobalData.gEFI_SOURCE, 'Edk')\r
1151\r
1152 if "WORKSPACE" not in os.environ:\r
1153 EdkLogger.error("EOT", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",\r
1154 ExtraData="WORKSPACE")\r
1155 else:\r
1156 EotGlobalData.gWORKSPACE = os.path.normpath(os.getenv("WORKSPACE"))\r
1157\r
1158 EotGlobalData.gMACRO['WORKSPACE'] = EotGlobalData.gWORKSPACE\r
1159 EotGlobalData.gMACRO['EFI_SOURCE'] = EotGlobalData.gEFI_SOURCE\r
1160 EotGlobalData.gMACRO['EDK_SOURCE'] = EotGlobalData.gEDK_SOURCE\r
1161\r
1162 # Parse the options and args\r
1163 if CommandLineOption:\r
1164 self.ParseOption()\r
1165\r
1166 if self.FvFileList:\r
1167 for FvFile in GetSplitValueList(self.FvFileList, ' '):\r
1168 FvFile = os.path.normpath(FvFile)\r
1169 if not os.path.isfile(FvFile):\r
1170 EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "Can not find file %s " % FvFile)\r
1171 EotGlobalData.gFV_FILE.append(FvFile)\r
1172 else:\r
1173 EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "The fv file list of target platform was not specified")\r
1174\r
1175 if self.MapFileList:\r
1176 for MapFile in GetSplitValueList(self.MapFileList, ' '):\r
1177 MapFile = os.path.normpath(MapFile)\r
1178 if not os.path.isfile(MapFile):\r
1179 EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "Can not find file %s " % MapFile)\r
1180 EotGlobalData.gMAP_FILE.append(MapFile)\r
f7496d71 1181\r
52302d4d
LG
1182 # Generate source file list\r
1183 self.GenerateSourceFileList(self.SourceFileList, self.IncludeDirList)\r
1184\r
1185 # Generate guid list of dec file list\r
1186 self.ParseDecFile(self.DecFileList)\r
f7496d71 1187\r
52302d4d
LG
1188 # Generate guid list from GUID list file\r
1189 self.ParseGuidList(self.GuidList)\r
1190\r
1191 # Init Eot database\r
1192 EotGlobalData.gDb = Database.Database(Database.DATABASE_PATH)\r
1193 EotGlobalData.gDb.InitDatabase(self.IsInit)\r
1194\r
1195 # Build ECC database\r
1196 self.BuildDatabase()\r
1197\r
1198 # Parse Ppi/Protocol\r
1199 self.ParseExecutionOrder()\r
1200\r
1201 # Merge Identifier tables\r
1202 self.GenerateQueryTable()\r
1203\r
1204 # Generate report database\r
1205 self.GenerateReportDatabase()\r
1206\r
1207 # Load Fv Info\r
1208 self.LoadFvInfo()\r
1209\r
1210 # Load Map Info\r
1211 self.LoadMapInfo()\r
1212\r
1213 # Generate Report\r
1214 self.GenerateReport()\r
1215\r
1216 # Convert log file\r
1217 self.ConvertLogFile(self.LogFile)\r
1218\r
1219 # DONE\r
1220 EdkLogger.quiet("EOT FINISHED!")\r
1221\r
1222 # Close Database\r
1223 EotGlobalData.gDb.Close()\r
1224\r
1225 ## ParseDecFile() method\r
1226 #\r
1227 # parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}\r
1228 # The Dict is stored in EotGlobalData.gGuidDict\r
1229 #\r
1230 # @param self: The object pointer\r
1231 # @param DecFileList: A list of all DEC files\r
1232 #\r
1233 def ParseDecFile(self, DecFileList):\r
1234 if DecFileList:\r
1235 path = os.path.normpath(DecFileList)\r
1236 lfr = open(path, 'rb')\r
1237 for line in lfr:\r
1238 path = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))\r
1239 if os.path.exists(path):\r
1240 dfr = open(path, 'rb')\r
1241 for line in dfr:\r
1242 line = CleanString(line)\r
1243 list = line.split('=')\r
1244 if len(list) == 2:\r
1245 EotGlobalData.gGuidDict[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())\r
1246\r
f7496d71 1247\r
52302d4d
LG
1248 ## ParseGuidList() method\r
1249 #\r
1250 # Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}\r
1251 # The Dict is stored in EotGlobalData.gGuidDict\r
1252 #\r
1253 # @param self: The object pointer\r
1254 # @param GuidList: A list of all GUID and its value\r
1255 #\r
1256 def ParseGuidList(self, GuidList):\r
1257 Path = os.path.join(EotGlobalData.gWORKSPACE, GuidList)\r
1258 if os.path.isfile(Path):\r
1259 for Line in open(Path):\r
22c4de1a
HC
1260 if Line.strip():\r
1261 (GuidName, GuidValue) = Line.split()\r
1262 EotGlobalData.gGuidDict[GuidName] = GuidValue\r
f7496d71 1263\r
52302d4d
LG
1264 ## ConvertLogFile() method\r
1265 #\r
1266 # Parse a real running log file to get real dispatch order\r
1267 # The result is saved to old file name + '.new'\r
1268 #\r
1269 # @param self: The object pointer\r
1270 # @param LogFile: A real running log file name\r
1271 #\r
1272 def ConvertLogFile(self, LogFile):\r
1273 newline = []\r
1274 lfr = None\r
1275 lfw = None\r
1276 if LogFile:\r
1277 lfr = open(LogFile, 'rb')\r
1278 lfw = open(LogFile + '.new', 'wb')\r
1279 for line in lfr:\r
1280 line = line.strip()\r
1281 line = line.replace('.efi', '')\r
1282 index = line.find("Loading PEIM at ")\r
1283 if index > -1:\r
1284 newline.append(line[index + 55 : ])\r
1285 continue\r
1286 index = line.find("Loading driver at ")\r
1287 if index > -1:\r
1288 newline.append(line[index + 57 : ])\r
1289 continue\r
1290\r
1291 for line in newline:\r
1292 lfw.write(line + '\r\n')\r
1293\r
1294 if lfr:\r
1295 lfr.close()\r
1296 if lfw:\r
1297 lfw.close()\r
1298\r
1299 ## GenerateSourceFileList() method\r
1300 #\r
1301 # Generate a list of all source files\r
1302 # 1. Search the file list one by one\r
1303 # 2. Store inf file name with source file names under it like\r
1304 # { INF file name: [source file1, source file2, ...]}\r
1305 # 3. Search the include list to find all .h files\r
1306 # 4. Store source file list to EotGlobalData.gSOURCE_FILES\r
1307 # 5. Store INF file list to EotGlobalData.gINF_FILES\r
1308 #\r
1309 # @param self: The object pointer\r
1310 # @param SourceFileList: A list of all source files\r
1311 # @param IncludeFileList: A list of all include files\r
1312 #\r
1313 def GenerateSourceFileList(self, SourceFileList, IncludeFileList):\r
1314 EdkLogger.quiet("Generating source files list ... ")\r
1315 mSourceFileList = []\r
1316 mInfFileList = []\r
1317 mDecFileList = []\r
1318 mFileList = {}\r
1319 mCurrentInfFile = ''\r
1320 mCurrentSourceFileList = []\r
1321\r
1322 if SourceFileList:\r
22c4de1a 1323 sfl = open(SourceFileList, 'r')\r
52302d4d
LG
1324 for line in sfl:\r
1325 line = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))\r
1326 if line[-2:].upper() == '.C' or line[-2:].upper() == '.H':\r
1327 if line not in mCurrentSourceFileList:\r
1328 mCurrentSourceFileList.append(line)\r
1329 mSourceFileList.append(line)\r
1330 EotGlobalData.gOP_SOURCE_FILES.write('%s\n' % line)\r
1331 if line[-4:].upper() == '.INF':\r
1332 if mCurrentInfFile != '':\r
1333 mFileList[mCurrentInfFile] = mCurrentSourceFileList\r
1334 mCurrentSourceFileList = []\r
1335 mCurrentInfFile = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line))\r
1336 EotGlobalData.gOP_INF.write('%s\n' % mCurrentInfFile)\r
1337 if mCurrentInfFile not in mFileList:\r
1338 mFileList[mCurrentInfFile] = mCurrentSourceFileList\r
1339\r
1340 # Get all include files from packages\r
1341 if IncludeFileList:\r
1342 ifl = open(IncludeFileList, 'rb')\r
1343 for line in ifl:\r
1344 if not line.strip():\r
1345 continue\r
1346 newline = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))\r
1347 for Root, Dirs, Files in os.walk(str(newline)):\r
1348 for File in Files:\r
1349 FullPath = os.path.normpath(os.path.join(Root, File))\r
1350 if FullPath not in mSourceFileList and File[-2:].upper() == '.H':\r
1351 mSourceFileList.append(FullPath)\r
1352 EotGlobalData.gOP_SOURCE_FILES.write('%s\n' % FullPath)\r
1353 if FullPath not in mDecFileList and File.upper().find('.DEC') > -1:\r
1354 mDecFileList.append(FullPath)\r
1355\r
1356 EotGlobalData.gSOURCE_FILES = mSourceFileList\r
1357 EotGlobalData.gOP_SOURCE_FILES.close()\r
1358\r
1359 EotGlobalData.gINF_FILES = mFileList\r
1360 EotGlobalData.gOP_INF.close()\r
1361\r
52302d4d
LG
1362 ## GenerateReport() method\r
1363 #\r
1364 # Generate final HTML report\r
1365 #\r
1366 # @param self: The object pointer\r
1367 #\r
1368 def GenerateReport(self):\r
1369 EdkLogger.quiet("Generating report file ... ")\r
1370 Rep = Report(self.Report, EotGlobalData.gFV, self.Dispatch)\r
1371 Rep.GenerateReport()\r
1372\r
1373 ## LoadMapInfo() method\r
1374 #\r
1375 # Load map files and parse them\r
1376 #\r
1377 # @param self: The object pointer\r
1378 #\r
1379 def LoadMapInfo(self):\r
1380 if EotGlobalData.gMAP_FILE != []:\r
1381 EdkLogger.quiet("Parsing Map file ... ")\r
1382 EotGlobalData.gMap = ParseMapFile(EotGlobalData.gMAP_FILE)\r
1383\r
1384 ## LoadFvInfo() method\r
1385 #\r
1386 # Load FV binary files and parse them\r
1387 #\r
1388 # @param self: The object pointer\r
1389 #\r
1390 def LoadFvInfo(self):\r
1391 EdkLogger.quiet("Parsing FV file ... ")\r
1392 EotGlobalData.gFV = MultipleFv(EotGlobalData.gFV_FILE)\r
1393 EotGlobalData.gFV.Dispatch(EotGlobalData.gDb)\r
1394\r
1395 for Protocol in EotGlobalData.gProtocolList:\r
1396 EotGlobalData.gOP_UN_MATCHED_IN_LIBRARY_CALLING.write('%s\n' %Protocol)\r
1397\r
1398 ## GenerateReportDatabase() method\r
1399 #\r
1400 # Generate data for the information needed by report\r
1401 # 1. Update name, macro and value of all found PPI/PROTOCOL GUID\r
1402 # 2. Install hard coded PPI/PROTOCOL\r
1403 #\r
1404 # @param self: The object pointer\r
1405 #\r
1406 def GenerateReportDatabase(self):\r
1407 EdkLogger.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")\r
1408\r
1409 # Update Protocol/Ppi Guid\r
1410 SqlCommand = """select DISTINCT GuidName from Report"""\r
1411 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1412 for Record in RecordSet:\r
1413 GuidName = Record[0]\r
1414 GuidMacro = ''\r
1415 GuidMacro2 = ''\r
1416 GuidValue = ''\r
1417\r
52302d4d
LG
1418 # Find guid value defined in Dec file\r
1419 if GuidName in EotGlobalData.gGuidDict:\r
1420 GuidValue = EotGlobalData.gGuidDict[GuidName]\r
1421 SqlCommand = """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro, GuidValue, GuidName)\r
1422 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1423 continue\r
1424\r
1425 # Search defined Macros for guid name\r
1426 SqlCommand ="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName\r
1427 GuidMacroSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1428 # Ignore NULL result\r
1429 if not GuidMacroSet:\r
1430 continue\r
1431 GuidMacro = GuidMacroSet[0][0].strip()\r
1432 if not GuidMacro:\r
1433 continue\r
1434 # Find Guid value of Guid Macro\r
1435 SqlCommand ="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro, MODEL_IDENTIFIER_MACRO_DEFINE)\r
1436 GuidValueSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1437 if GuidValueSet != []:\r
1438 GuidValue = GuidValueSet[0][0]\r
1439 GuidValue = GuidValue[GuidValue.find(GuidMacro) + len(GuidMacro) :]\r
1440 GuidValue = GuidValue.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()\r
1441 GuidValue = GuidStructureStringToGuidString(GuidValue)\r
1442 SqlCommand = """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro, GuidValue, GuidName)\r
1443 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1444 continue\r
1445\r
1446 # Update Hard Coded Ppi/Protocol\r
1447 SqlCommand = """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""\r
1448 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1449 for Record in RecordSet:\r
e95a0dfb
JC
1450 if Record[1] == 'Ppi':\r
1451 EotGlobalData.gPpiList[Record[0].lower()] = -2\r
52302d4d
LG
1452 if Record[1] == 'Protocol':\r
1453 EotGlobalData.gProtocolList[Record[0].lower()] = -2\r
1454\r
1455 ## GenerateQueryTable() method\r
1456 #\r
1457 # Generate two tables improve query performance\r
1458 #\r
1459 # @param self: The object pointer\r
1460 #\r
1461 def GenerateQueryTable(self):\r
1462 EdkLogger.quiet("Generating temp query table for analysis ... ")\r
1463 for Identifier in EotGlobalData.gIdentifierTableList:\r
1464 SqlCommand = """insert into Query (Name, Modifier, Value, Model)\r
1465 select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \\r
1466 % (Identifier[0], MODEL_IDENTIFIER_VARIABLE, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r
1467 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1468 SqlCommand = """insert into Query2 (Name, Modifier, Value, Model)\r
1469 select Name, Modifier, Value, Model from %s where Model = %s""" \\r
1470 % (Identifier[0], MODEL_IDENTIFIER_MACRO_DEFINE)\r
1471 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1472\r
1473 ## ParseExecutionOrder() method\r
1474 #\r
1475 # Get final execution order\r
1476 # 1. Search all PPI\r
1477 # 2. Search all PROTOCOL\r
1478 #\r
1479 # @param self: The object pointer\r
1480 #\r
1481 def ParseExecutionOrder(self):\r
1482 EdkLogger.quiet("Searching Ppi/Protocol ... ")\r
1483 for Identifier in EotGlobalData.gIdentifierTableList:\r
1484 ModuleID, ModuleName, ModuleGuid, SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, Enabled = \\r
1485 -1, '', '', -1, '', '', '', '', '', '', '', '', 0\r
1486\r
1487 SourceFileID = Identifier[0].replace('Identifier', '')\r
1488 SourceFileFullPath = Identifier[1]\r
1489 Identifier = Identifier[0]\r
1490\r
1491 # Find Ppis\r
1492 ItemMode = 'Produced'\r
1493 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1494 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1495 % (Identifier, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1496 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1497\r
1498 ItemMode = 'Produced'\r
1499 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1500 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1501 % (Identifier, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1502 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 2)\r
1503\r
1504 SearchPpiCallFunction(Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1505\r
1506 ItemMode = 'Consumed'\r
1507 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1508 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1509 % (Identifier, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1510 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1511\r
1512 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Ppi', ItemMode)\r
1513\r
1514 ItemMode = 'Callback'\r
1515 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1516 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1517 % (Identifier, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1518 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1519\r
1520 # Find Procotols\r
1521 ItemMode = 'Produced'\r
1522 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1523 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1524 % (Identifier, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1525 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 1)\r
1526\r
1527 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1528 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1529 % (Identifier, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1530 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 2)\r
1531\r
1532 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)\r
1533\r
1534 ItemMode = 'Consumed'\r
1535 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1536 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1537 % (Identifier, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1538 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 0)\r
1539\r
1540 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1541 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1542 % (Identifier, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1543 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 1)\r
1544\r
1545 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)\r
1546\r
1547 ItemMode = 'Callback'\r
1548 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1549 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1550 % (Identifier, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1551 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 0)\r
1552\r
1553 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)\r
1554\r
1555 # Hard Code\r
1556 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)\r
1557 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)\r
1558 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)\r
1559 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)\r
1560 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)\r
1561 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)\r
1562 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)\r
1563 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)\r
1564 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)\r
1565\r
1566 EotGlobalData.gDb.Conn.commit()\r
1567\r
1568\r
1569 ## BuildDatabase() methoc\r
1570 #\r
1571 # Build the database for target\r
1572 #\r
1573 # @param self: The object pointer\r
1574 #\r
1575 def BuildDatabase(self):\r
1576 # Clean report table\r
1577 EotGlobalData.gDb.TblReport.Drop()\r
1578 EotGlobalData.gDb.TblReport.Create()\r
1579\r
1580 # Build database\r
1581 if self.IsInit:\r
1582 self.BuildMetaDataFileDatabase(EotGlobalData.gINF_FILES)\r
1583 EdkLogger.quiet("Building database for source code ...")\r
1584 c.CreateCCodeDB(EotGlobalData.gSOURCE_FILES)\r
1585 EdkLogger.quiet("Building database for source code done!")\r
1586\r
1587 EotGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EotGlobalData.gDb)\r
1588\r
1589 ## BuildMetaDataFileDatabase() method\r
1590 #\r
1591 # Build the database for meta data files\r
1592 #\r
1593 # @param self: The object pointer\r
1594 # @param Inf_Files: A list for all INF files\r
1595 #\r
1596 def BuildMetaDataFileDatabase(self, Inf_Files):\r
1597 EdkLogger.quiet("Building database for meta data files ...")\r
1598 for InfFile in Inf_Files:\r
22c4de1a
HC
1599 if not InfFile:\r
1600 continue\r
52302d4d
LG
1601 EdkLogger.quiet("Parsing %s ..." % str(InfFile))\r
1602 EdkInfParser(InfFile, EotGlobalData.gDb, Inf_Files[InfFile], '')\r
1603\r
1604 EotGlobalData.gDb.Conn.commit()\r
1605 EdkLogger.quiet("Building database for meta data files done!")\r
1606\r
1607 ## ParseOption() method\r
1608 #\r
1609 # Parse command line options\r
1610 #\r
1611 # @param self: The object pointer\r
1612 #\r
1613 def ParseOption(self):\r
1614 (Options, Target) = self.EotOptionParser()\r
1615\r
1616 # Set log level\r
1617 self.SetLogLevel(Options)\r
1618\r
1619 if Options.FvFileList:\r
1620 self.FvFileList = Options.FvFileList\r
f7496d71 1621\r
52302d4d
LG
1622 if Options.MapFileList:\r
1623 self.MapFileList = Options.FvMapFileList\r
1624\r
1625 if Options.SourceFileList:\r
1626 self.SourceFileList = Options.SourceFileList\r
1627\r
1628 if Options.IncludeDirList:\r
1629 self.IncludeDirList = Options.IncludeDirList\r
1630\r
1631 if Options.DecFileList:\r
1632 self.DecFileList = Options.DecFileList\r
f7496d71 1633\r
52302d4d
LG
1634 if Options.GuidList:\r
1635 self.GuidList = Options.GuidList\r
1636\r
1637 if Options.LogFile:\r
1638 self.LogFile = Options.LogFile\r
1639\r
1640 if Options.keepdatabase:\r
1641 self.IsInit = False\r
1642\r
1643 ## SetLogLevel() method\r
1644 #\r
1645 # Set current log level of the tool based on args\r
1646 #\r
1647 # @param self: The object pointer\r
1648 # @param Option: The option list including log level setting\r
1649 #\r
1650 def SetLogLevel(self, Option):\r
4231a819 1651 if Option.verbose is not None:\r
52302d4d 1652 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
4231a819 1653 elif Option.quiet is not None:\r
52302d4d 1654 EdkLogger.SetLevel(EdkLogger.QUIET)\r
4231a819 1655 elif Option.debug is not None:\r
52302d4d
LG
1656 EdkLogger.SetLevel(Option.debug + 1)\r
1657 else:\r
1658 EdkLogger.SetLevel(EdkLogger.INFO)\r
1659\r
1660 ## EotOptionParser() method\r
1661 #\r
1662 # Using standard Python module optparse to parse command line option of this tool.\r
1663 #\r
1664 # @param self: The object pointer\r
1665 #\r
1666 # @retval Opt A optparse.Values object containing the parsed options\r
1667 # @retval Args Target of build command\r
1668 #\r
1669 def EotOptionParser(self):\r
1670 Parser = OptionParser(description = self.Copyright, version = self.Version, prog = "Eot.exe", usage = "%prog [options]")\r
1671 Parser.add_option("-m", "--makefile filename", action="store", type="string", dest='MakeFile',\r
1672 help="Specify a makefile for the platform.")\r
1673 Parser.add_option("-c", "--dsc filename", action="store", type="string", dest="DscFile",\r
1674 help="Specify a dsc file for the platform.")\r
1675 Parser.add_option("-f", "--fv filename", action="store", type="string", dest="FvFileList",\r
1676 help="Specify fv file list, quoted by \"\".")\r
1677 Parser.add_option("-a", "--map filename", action="store", type="string", dest="MapFileList",\r
1678 help="Specify map file list, quoted by \"\".")\r
1679 Parser.add_option("-s", "--source files", action="store", type="string", dest="SourceFileList",\r
1680 help="Specify source file list by a file")\r
1681 Parser.add_option("-i", "--include dirs", action="store", type="string", dest="IncludeDirList",\r
1682 help="Specify include dir list by a file")\r
1683 Parser.add_option("-e", "--dec files", action="store", type="string", dest="DecFileList",\r
1684 help="Specify dec file list by a file")\r
1685 Parser.add_option("-g", "--guid list", action="store", type="string", dest="GuidList",\r
1686 help="Specify guid file list by a file")\r
1687 Parser.add_option("-l", "--log filename", action="store", type="string", dest="LogFile",\r
1688 help="Specify real execution log file")\r
1689\r
1690 Parser.add_option("-k", "--keepdatabase", action="store_true", type=None, help="The existing Eot database will not be cleaned except report information if this option is specified.")\r
1691\r
1692 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
1693 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\\r
1694 "including library instances selected, final dependency expression, "\\r
1695 "and warning messages, etc.")\r
1696 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
1697\r
1698 (Opt, Args)=Parser.parse_args()\r
1699\r
1700 return (Opt, Args)\r
1701\r
1702##\r
1703#\r
1704# This acts like the main() function for the script, unless it is 'import'ed into another\r
1705# script.\r
1706#\r
1707if __name__ == '__main__':\r
1708 # Initialize log system\r
1709 EdkLogger.Initialize()\r
1710 EdkLogger.IsRaiseError = False\r
1711 EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")\r
1712\r
1713 StartTime = time.clock()\r
22c4de1a
HC
1714 Eot = Eot(CommandLineOption=False,\r
1715 SourceFileList=r'C:\TestEot\Source.txt',\r
1716 GuidList=r'C:\TestEot\Guid.txt',\r
1717 FvFileList=r'C:\TestEot\FVRECOVERY.Fv')\r
52302d4d
LG
1718 FinishTime = time.clock()\r
1719\r
1720 BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))\r
1721 EdkLogger.quiet("\n%s [%s]" % (time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration))\r