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