]> git.proxmox.com Git - mirror_edk2.git/blame - BaseTools/Source/Python/Eot/EotMain.py
BaseTools: Fixed a build report issue.
[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
47f15da1 20import Eot.EotGlobalData as EotGlobalData\r
52302d4d 21from optparse import OptionParser\r
5a57246e 22from Common.StringUtils import NormPath\r
52302d4d 23from Common import BuildToolError\r
c196d1d1
FB
24from Common.Misc import GuidStructureStringToGuidString\r
25from collections import OrderedDict as sdict\r
47f15da1
HC
26from Eot.Parser import *\r
27from Eot.InfParserLite import EdkInfParser\r
28from Common.StringUtils import GetSplitValueList\r
29from Eot import c\r
30from Eot import Database\r
52302d4d 31from array import array\r
47f15da1 32from Eot.Report import Report\r
b36d134f 33from Common.BuildVersion import gBUILD_VERSION\r
47f15da1 34from Eot.Parser import ConvertGuid\r
1be2ed90 35from Common.LongFilePathSupport import OpenLongFilePath as open\r
e95a0dfb
JC
36import struct\r
37import uuid\r
38import copy\r
39import codecs\r
9e47e6f9 40from GenFds.AprioriSection import DXE_APRIORI_GUID, PEI_APRIORI_GUID\r
e95a0dfb
JC
41\r
42gGuidStringFormat = "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"\r
e95a0dfb
JC
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
47f15da1 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
47f15da1 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
47f15da1 159 TmpData = DeCompress('Efi', self[self._HEADER_SIZE_:])\r
e95a0dfb
JC
160 DecData = array('B')\r
161 DecData.fromstring(TmpData)\r
162 except:\r
47f15da1 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
47f15da1 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
47f15da1
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
47f15da1 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
47f15da1 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
9e47e6f9 405 if Ffs.Guid.lower() == PEI_APRIORI_GUID.lower():\r
e95a0dfb
JC
406 FfsPeiPrioriGuid = FfsID\r
407 continue\r
9e47e6f9 408 if Ffs.Guid.lower() == DXE_APRIORI_GUID.lower():\r
e95a0dfb
JC
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
47f15da1 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
47f15da1 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
47f15da1 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
47f15da1 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
47f15da1 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
47f15da1 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
47f15da1 602\r
e95a0dfb
JC
603 def __str__(self):\r
604 global gIndention\r
605 gIndention += 4\r
606 FvInfo = '\n' + ' ' * gIndention\r
47f15da1 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
47f15da1 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
47f15da1 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
47f15da1
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
47f15da1 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
e95a0dfb
JC
933 FFS_ATTRIB_FIXED = 0x04\r
934 FFS_ATTRIB_DATA_ALIGNMENT = 0x38\r
935 FFS_ATTRIB_CHECKSUM = 0x40\r
936\r
937 _TypeName = {\r
938 0x00 : "<unknown>",\r
939 0x01 : "RAW",\r
940 0x02 : "FREEFORM",\r
941 0x03 : "SECURITY_CORE",\r
942 0x04 : "PEI_CORE",\r
943 0x05 : "DXE_CORE",\r
944 0x06 : "PEIM",\r
945 0x07 : "DRIVER",\r
946 0x08 : "COMBINED_PEIM_DRIVER",\r
947 0x09 : "APPLICATION",\r
948 0x0A : "SMM",\r
949 0x0B : "FIRMWARE_VOLUME_IMAGE",\r
950 0x0C : "COMBINED_SMM_DXE",\r
951 0x0D : "SMM_CORE",\r
952 0x0E : "MM_STANDALONE",\r
953 0x0F : "MM_CORE_STANDALONE",\r
954 0xc0 : "OEM_MIN",\r
955 0xdf : "OEM_MAX",\r
956 0xe0 : "DEBUG_MIN",\r
957 0xef : "DEBUG_MAX",\r
958 0xf0 : "FFS_MIN",\r
959 0xff : "FFS_MAX",\r
960 0xf0 : "FFS_PAD",\r
961 }\r
962\r
963 def __init__(self):\r
964 Image.__init__(self)\r
965 self.FreeSpace = 0\r
966\r
967 self.Sections = sdict()\r
968 self.Depex = ''\r
969\r
970 self.__ID__ = None\r
971\r
972 def __str__(self):\r
973 global gIndention\r
974 gIndention += 4\r
975 Indention = ' ' * gIndention\r
976 FfsInfo = Indention\r
977 FfsInfo += "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \\r
978 (Ffs._TypeName[self.Type], self._OFF_, self.Size, self.Guid, self.FreeSpace, self.Alignment)\r
47f15da1 979 SectionInfo = '\n'.join([str(self.Sections[Offset]) for Offset in self.Sections.keys()])\r
e95a0dfb
JC
980 gIndention -= 4\r
981 return FfsInfo + SectionInfo + "\n"\r
982\r
983 def __len__(self):\r
984 return self.Size\r
985\r
986 def __repr__(self):\r
987 return self.__ID__\r
988\r
989 def _Unpack(self):\r
990 Size1, Size2, Size3 = self._SIZE_.unpack_from(self._BUF_, self._OFF_)\r
991 Size = Size1 + (Size2 << 8) + (Size3 << 16)\r
992 self.empty()\r
993 self.extend(self._BUF_[self._OFF_ : self._OFF_ + Size])\r
994\r
995 # Pad FFS may use the same GUID. We need to avoid it.\r
996 if self.Type == 0xf0:\r
997 self.__ID__ = str(uuid.uuid1()).upper()\r
998 else:\r
999 self.__ID__ = self.Guid\r
1000\r
1001 # Traverse the SECTION. RAW and PAD do not have sections\r
1002 if self.Type not in [0xf0, 0x01] and Size > 0 and Size < 0xFFFFFF:\r
1003 EndOfFfs = Size\r
1004 SectionStartAddress = self._HEADER_SIZE_\r
1005 while SectionStartAddress < EndOfFfs:\r
1006 SectionObj = Section()\r
1007 SectionObj.frombuffer(self, SectionStartAddress)\r
1008 #f = open(repr(SectionObj), 'wb')\r
1009 #SectionObj.Size = 0\r
1010 #SectionObj.tofile(f)\r
1011 #f.close()\r
1012 self.Sections[SectionStartAddress] = SectionObj\r
1013 SectionStartAddress += len(SectionObj)\r
1014 SectionStartAddress = (SectionStartAddress + 3) & (~3)\r
1015\r
1016 def Pack(self):\r
1017 pass\r
1018\r
1019 def SetFreeSpace(self, Size):\r
1020 self.FreeSpace = Size\r
1021\r
1022 def _GetGuid(self):\r
1023 return gGuidStringFormat % self.Name\r
1024\r
1025 def _SetName(self, Value):\r
1026 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11\r
1027 self.SetField(self._NAME_, 0, Value)\r
1028\r
1029 def _GetName(self):\r
1030 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11\r
1031 return self.GetField(self._NAME_)\r
1032\r
4fea08b9 1033 def _SetSize(self, Size):\r
e95a0dfb
JC
1034 Size1 = Size & 0xFF\r
1035 Size2 = (Size & 0xFF00) >> 8\r
1036 Size3 = (Size & 0xFF0000) >> 16\r
4fea08b9 1037 self.SetField(self._SIZE_, 0, Size1, Size2, Size3)\r
e95a0dfb 1038\r
4fea08b9
CJ
1039 def _GetSize(self):\r
1040 Size1, Size2, Size3 = self.GetField(self._SIZE_)\r
e95a0dfb
JC
1041 return Size1 + (Size2 << 8) + (Size3 << 16)\r
1042\r
4fea08b9
CJ
1043 def _SetType(self, Type):\r
1044 self.SetField(self._TYPE_, 0, Type)\r
e95a0dfb 1045\r
4fea08b9
CJ
1046 def _GetType(self):\r
1047 return self.GetField(self._TYPE_)[0]\r
e95a0dfb
JC
1048\r
1049 def _SetAttributes(self, Value):\r
4fea08b9 1050 self.SetField(self._ATTR_, 0, Value)\r
e95a0dfb
JC
1051\r
1052 def _GetAttributes(self):\r
1053 return self.GetField(self._ATTR_)[0]\r
1054\r
1055 def _GetFixed(self):\r
1056 if (self.Attributes & self.FFS_ATTRIB_FIXED) != 0:\r
1057 return True\r
1058 return False\r
1059\r
1060 def _GetCheckSum(self):\r
1061 if (self.Attributes & self.FFS_ATTRIB_CHECKSUM) != 0:\r
1062 return True\r
1063 return False\r
1064\r
1065 def _GetAlignment(self):\r
1066 return (self.Attributes & self.FFS_ATTRIB_DATA_ALIGNMENT) >> 3\r
1067\r
1068 def _SetState(self, Value):\r
4fea08b9 1069 self.SetField(self._STATE_, 0, Value)\r
e95a0dfb
JC
1070\r
1071 def _GetState(self):\r
4fea08b9 1072 return self.GetField(self._STATE_)[0]\r
e95a0dfb
JC
1073\r
1074 Name = property(_GetName, _SetName)\r
1075 Guid = property(_GetGuid)\r
1076 Type = property(_GetType, _SetType)\r
1077 Size = property(_GetSize, _SetSize)\r
1078 Attributes = property(_GetAttributes, _SetAttributes)\r
1079 Fixed = property(_GetFixed)\r
1080 Checksum = property(_GetCheckSum)\r
1081 Alignment = property(_GetAlignment)\r
1082 State = property(_GetState, _SetState)\r
1083\r
52302d4d 1084\r
d498274f
CJ
1085## MultipleFv() class\r
1086#\r
1087# A class for Multiple FV\r
1088#\r
1089class MultipleFv(FirmwareVolume):\r
1090 def __init__(self, FvList):\r
1091 FirmwareVolume.__init__(self)\r
1092 self.BasicInfo = []\r
1093 for FvPath in FvList:\r
47f15da1 1094 Fd = None\r
d498274f 1095 FvName = os.path.splitext(os.path.split(FvPath)[1])[0]\r
47f15da1
HC
1096 if FvPath.strip():\r
1097 Fd = open(FvPath, 'rb')\r
d498274f
CJ
1098 Buf = array('B')\r
1099 try:\r
1100 Buf.fromfile(Fd, os.path.getsize(FvPath))\r
1101 except EOFError:\r
1102 pass\r
1103\r
1104 Fv = FirmwareVolume(FvName)\r
1105 Fv.frombuffer(Buf, 0, len(Buf))\r
1106\r
1107 self.BasicInfo.append([Fv.Name, Fv.FileSystemGuid, Fv.Size])\r
f7496d71 1108 self.FfsDict.append(Fv.FfsDict)\r
d498274f 1109\r
52302d4d
LG
1110## Class Eot\r
1111#\r
1112# This class is used to define Eot main entrance\r
1113#\r
1114# @param object: Inherited from object class\r
1115#\r
1116class Eot(object):\r
1117 ## The constructor\r
1118 #\r
1119 # @param self: The object pointer\r
1120 #\r
1121 def __init__(self, CommandLineOption=True, IsInit=True, SourceFileList=None, \\r
1122 IncludeDirList=None, DecFileList=None, GuidList=None, LogFile=None,\r
1123 FvFileList="", MapFileList="", Report='Report.html', Dispatch=None):\r
1124 # Version and Copyright\r
b36d134f 1125 self.VersionNumber = ("0.02" + " " + gBUILD_VERSION)\r
52302d4d 1126 self.Version = "%prog Version " + self.VersionNumber\r
f7496d71 1127 self.Copyright = "Copyright (c) 2008 - 2018, Intel Corporation All rights reserved."\r
52302d4d
LG
1128 self.Report = Report\r
1129\r
1130 self.IsInit = IsInit\r
1131 self.SourceFileList = SourceFileList\r
1132 self.IncludeDirList = IncludeDirList\r
1133 self.DecFileList = DecFileList\r
1134 self.GuidList = GuidList\r
1135 self.LogFile = LogFile\r
1136 self.FvFileList = FvFileList\r
1137 self.MapFileList = MapFileList\r
1138 self.Dispatch = Dispatch\r
f7496d71 1139\r
52302d4d
LG
1140 # Check workspace environment\r
1141 if "EFI_SOURCE" not in os.environ:\r
1142 if "EDK_SOURCE" not in os.environ:\r
1143 pass\r
1144 else:\r
1145 EotGlobalData.gEDK_SOURCE = os.path.normpath(os.getenv("EDK_SOURCE"))\r
1146 else:\r
1147 EotGlobalData.gEFI_SOURCE = os.path.normpath(os.getenv("EFI_SOURCE"))\r
1148 EotGlobalData.gEDK_SOURCE = os.path.join(EotGlobalData.gEFI_SOURCE, 'Edk')\r
1149\r
1150 if "WORKSPACE" not in os.environ:\r
1151 EdkLogger.error("EOT", BuildToolError.ATTRIBUTE_NOT_AVAILABLE, "Environment variable not found",\r
1152 ExtraData="WORKSPACE")\r
1153 else:\r
1154 EotGlobalData.gWORKSPACE = os.path.normpath(os.getenv("WORKSPACE"))\r
1155\r
1156 EotGlobalData.gMACRO['WORKSPACE'] = EotGlobalData.gWORKSPACE\r
1157 EotGlobalData.gMACRO['EFI_SOURCE'] = EotGlobalData.gEFI_SOURCE\r
1158 EotGlobalData.gMACRO['EDK_SOURCE'] = EotGlobalData.gEDK_SOURCE\r
1159\r
1160 # Parse the options and args\r
1161 if CommandLineOption:\r
1162 self.ParseOption()\r
1163\r
1164 if self.FvFileList:\r
1165 for FvFile in GetSplitValueList(self.FvFileList, ' '):\r
1166 FvFile = os.path.normpath(FvFile)\r
1167 if not os.path.isfile(FvFile):\r
1168 EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "Can not find file %s " % FvFile)\r
1169 EotGlobalData.gFV_FILE.append(FvFile)\r
1170 else:\r
1171 EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "The fv file list of target platform was not specified")\r
1172\r
1173 if self.MapFileList:\r
1174 for MapFile in GetSplitValueList(self.MapFileList, ' '):\r
1175 MapFile = os.path.normpath(MapFile)\r
1176 if not os.path.isfile(MapFile):\r
1177 EdkLogger.error("Eot", EdkLogger.EOT_ERROR, "Can not find file %s " % MapFile)\r
1178 EotGlobalData.gMAP_FILE.append(MapFile)\r
f7496d71 1179\r
52302d4d
LG
1180 # Generate source file list\r
1181 self.GenerateSourceFileList(self.SourceFileList, self.IncludeDirList)\r
1182\r
1183 # Generate guid list of dec file list\r
1184 self.ParseDecFile(self.DecFileList)\r
f7496d71 1185\r
52302d4d
LG
1186 # Generate guid list from GUID list file\r
1187 self.ParseGuidList(self.GuidList)\r
1188\r
1189 # Init Eot database\r
1190 EotGlobalData.gDb = Database.Database(Database.DATABASE_PATH)\r
1191 EotGlobalData.gDb.InitDatabase(self.IsInit)\r
1192\r
1193 # Build ECC database\r
1194 self.BuildDatabase()\r
1195\r
1196 # Parse Ppi/Protocol\r
1197 self.ParseExecutionOrder()\r
1198\r
1199 # Merge Identifier tables\r
1200 self.GenerateQueryTable()\r
1201\r
1202 # Generate report database\r
1203 self.GenerateReportDatabase()\r
1204\r
1205 # Load Fv Info\r
1206 self.LoadFvInfo()\r
1207\r
1208 # Load Map Info\r
1209 self.LoadMapInfo()\r
1210\r
1211 # Generate Report\r
1212 self.GenerateReport()\r
1213\r
1214 # Convert log file\r
1215 self.ConvertLogFile(self.LogFile)\r
1216\r
1217 # DONE\r
1218 EdkLogger.quiet("EOT FINISHED!")\r
1219\r
1220 # Close Database\r
1221 EotGlobalData.gDb.Close()\r
1222\r
1223 ## ParseDecFile() method\r
1224 #\r
1225 # parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}\r
1226 # The Dict is stored in EotGlobalData.gGuidDict\r
1227 #\r
1228 # @param self: The object pointer\r
1229 # @param DecFileList: A list of all DEC files\r
1230 #\r
1231 def ParseDecFile(self, DecFileList):\r
1232 if DecFileList:\r
1233 path = os.path.normpath(DecFileList)\r
1234 lfr = open(path, 'rb')\r
1235 for line in lfr:\r
1236 path = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))\r
1237 if os.path.exists(path):\r
1238 dfr = open(path, 'rb')\r
1239 for line in dfr:\r
1240 line = CleanString(line)\r
1241 list = line.split('=')\r
1242 if len(list) == 2:\r
1243 EotGlobalData.gGuidDict[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())\r
1244\r
f7496d71 1245\r
52302d4d
LG
1246 ## ParseGuidList() method\r
1247 #\r
1248 # Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}\r
1249 # The Dict is stored in EotGlobalData.gGuidDict\r
1250 #\r
1251 # @param self: The object pointer\r
1252 # @param GuidList: A list of all GUID and its value\r
1253 #\r
1254 def ParseGuidList(self, GuidList):\r
1255 Path = os.path.join(EotGlobalData.gWORKSPACE, GuidList)\r
1256 if os.path.isfile(Path):\r
1257 for Line in open(Path):\r
47f15da1
HC
1258 if Line.strip():\r
1259 (GuidName, GuidValue) = Line.split()\r
1260 EotGlobalData.gGuidDict[GuidName] = GuidValue\r
f7496d71 1261\r
52302d4d
LG
1262 ## ConvertLogFile() method\r
1263 #\r
1264 # Parse a real running log file to get real dispatch order\r
1265 # The result is saved to old file name + '.new'\r
1266 #\r
1267 # @param self: The object pointer\r
1268 # @param LogFile: A real running log file name\r
1269 #\r
1270 def ConvertLogFile(self, LogFile):\r
1271 newline = []\r
1272 lfr = None\r
1273 lfw = None\r
1274 if LogFile:\r
1275 lfr = open(LogFile, 'rb')\r
1276 lfw = open(LogFile + '.new', 'wb')\r
1277 for line in lfr:\r
1278 line = line.strip()\r
1279 line = line.replace('.efi', '')\r
1280 index = line.find("Loading PEIM at ")\r
1281 if index > -1:\r
1282 newline.append(line[index + 55 : ])\r
1283 continue\r
1284 index = line.find("Loading driver at ")\r
1285 if index > -1:\r
1286 newline.append(line[index + 57 : ])\r
1287 continue\r
1288\r
1289 for line in newline:\r
1290 lfw.write(line + '\r\n')\r
1291\r
1292 if lfr:\r
1293 lfr.close()\r
1294 if lfw:\r
1295 lfw.close()\r
1296\r
1297 ## GenerateSourceFileList() method\r
1298 #\r
1299 # Generate a list of all source files\r
1300 # 1. Search the file list one by one\r
1301 # 2. Store inf file name with source file names under it like\r
1302 # { INF file name: [source file1, source file2, ...]}\r
1303 # 3. Search the include list to find all .h files\r
1304 # 4. Store source file list to EotGlobalData.gSOURCE_FILES\r
1305 # 5. Store INF file list to EotGlobalData.gINF_FILES\r
1306 #\r
1307 # @param self: The object pointer\r
1308 # @param SourceFileList: A list of all source files\r
1309 # @param IncludeFileList: A list of all include files\r
1310 #\r
1311 def GenerateSourceFileList(self, SourceFileList, IncludeFileList):\r
1312 EdkLogger.quiet("Generating source files list ... ")\r
1313 mSourceFileList = []\r
1314 mInfFileList = []\r
1315 mDecFileList = []\r
1316 mFileList = {}\r
1317 mCurrentInfFile = ''\r
1318 mCurrentSourceFileList = []\r
1319\r
1320 if SourceFileList:\r
47f15da1 1321 sfl = open(SourceFileList, 'r')\r
52302d4d
LG
1322 for line in sfl:\r
1323 line = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))\r
1324 if line[-2:].upper() == '.C' or line[-2:].upper() == '.H':\r
1325 if line not in mCurrentSourceFileList:\r
1326 mCurrentSourceFileList.append(line)\r
1327 mSourceFileList.append(line)\r
1328 EotGlobalData.gOP_SOURCE_FILES.write('%s\n' % line)\r
1329 if line[-4:].upper() == '.INF':\r
1330 if mCurrentInfFile != '':\r
1331 mFileList[mCurrentInfFile] = mCurrentSourceFileList\r
1332 mCurrentSourceFileList = []\r
1333 mCurrentInfFile = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line))\r
1334 EotGlobalData.gOP_INF.write('%s\n' % mCurrentInfFile)\r
1335 if mCurrentInfFile not in mFileList:\r
1336 mFileList[mCurrentInfFile] = mCurrentSourceFileList\r
1337\r
1338 # Get all include files from packages\r
1339 if IncludeFileList:\r
1340 ifl = open(IncludeFileList, 'rb')\r
1341 for line in ifl:\r
1342 if not line.strip():\r
1343 continue\r
1344 newline = os.path.normpath(os.path.join(EotGlobalData.gWORKSPACE, line.strip()))\r
1345 for Root, Dirs, Files in os.walk(str(newline)):\r
1346 for File in Files:\r
1347 FullPath = os.path.normpath(os.path.join(Root, File))\r
1348 if FullPath not in mSourceFileList and File[-2:].upper() == '.H':\r
1349 mSourceFileList.append(FullPath)\r
1350 EotGlobalData.gOP_SOURCE_FILES.write('%s\n' % FullPath)\r
1351 if FullPath not in mDecFileList and File.upper().find('.DEC') > -1:\r
1352 mDecFileList.append(FullPath)\r
1353\r
1354 EotGlobalData.gSOURCE_FILES = mSourceFileList\r
1355 EotGlobalData.gOP_SOURCE_FILES.close()\r
1356\r
1357 EotGlobalData.gINF_FILES = mFileList\r
1358 EotGlobalData.gOP_INF.close()\r
1359\r
52302d4d
LG
1360 ## GenerateReport() method\r
1361 #\r
1362 # Generate final HTML report\r
1363 #\r
1364 # @param self: The object pointer\r
1365 #\r
1366 def GenerateReport(self):\r
1367 EdkLogger.quiet("Generating report file ... ")\r
1368 Rep = Report(self.Report, EotGlobalData.gFV, self.Dispatch)\r
1369 Rep.GenerateReport()\r
1370\r
1371 ## LoadMapInfo() method\r
1372 #\r
1373 # Load map files and parse them\r
1374 #\r
1375 # @param self: The object pointer\r
1376 #\r
1377 def LoadMapInfo(self):\r
1378 if EotGlobalData.gMAP_FILE != []:\r
1379 EdkLogger.quiet("Parsing Map file ... ")\r
1380 EotGlobalData.gMap = ParseMapFile(EotGlobalData.gMAP_FILE)\r
1381\r
1382 ## LoadFvInfo() method\r
1383 #\r
1384 # Load FV binary files and parse them\r
1385 #\r
1386 # @param self: The object pointer\r
1387 #\r
1388 def LoadFvInfo(self):\r
1389 EdkLogger.quiet("Parsing FV file ... ")\r
1390 EotGlobalData.gFV = MultipleFv(EotGlobalData.gFV_FILE)\r
1391 EotGlobalData.gFV.Dispatch(EotGlobalData.gDb)\r
1392\r
1393 for Protocol in EotGlobalData.gProtocolList:\r
1394 EotGlobalData.gOP_UN_MATCHED_IN_LIBRARY_CALLING.write('%s\n' %Protocol)\r
1395\r
1396 ## GenerateReportDatabase() method\r
1397 #\r
1398 # Generate data for the information needed by report\r
1399 # 1. Update name, macro and value of all found PPI/PROTOCOL GUID\r
1400 # 2. Install hard coded PPI/PROTOCOL\r
1401 #\r
1402 # @param self: The object pointer\r
1403 #\r
1404 def GenerateReportDatabase(self):\r
1405 EdkLogger.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")\r
1406\r
1407 # Update Protocol/Ppi Guid\r
1408 SqlCommand = """select DISTINCT GuidName from Report"""\r
1409 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1410 for Record in RecordSet:\r
1411 GuidName = Record[0]\r
1412 GuidMacro = ''\r
1413 GuidMacro2 = ''\r
1414 GuidValue = ''\r
1415\r
52302d4d
LG
1416 # Find guid value defined in Dec file\r
1417 if GuidName in EotGlobalData.gGuidDict:\r
1418 GuidValue = EotGlobalData.gGuidDict[GuidName]\r
1419 SqlCommand = """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro, GuidValue, GuidName)\r
1420 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1421 continue\r
1422\r
1423 # Search defined Macros for guid name\r
1424 SqlCommand ="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName\r
1425 GuidMacroSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1426 # Ignore NULL result\r
1427 if not GuidMacroSet:\r
1428 continue\r
1429 GuidMacro = GuidMacroSet[0][0].strip()\r
1430 if not GuidMacro:\r
1431 continue\r
1432 # Find Guid value of Guid Macro\r
1433 SqlCommand ="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro, MODEL_IDENTIFIER_MACRO_DEFINE)\r
1434 GuidValueSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1435 if GuidValueSet != []:\r
1436 GuidValue = GuidValueSet[0][0]\r
1437 GuidValue = GuidValue[GuidValue.find(GuidMacro) + len(GuidMacro) :]\r
1438 GuidValue = GuidValue.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()\r
1439 GuidValue = GuidStructureStringToGuidString(GuidValue)\r
1440 SqlCommand = """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro, GuidValue, GuidName)\r
1441 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1442 continue\r
1443\r
1444 # Update Hard Coded Ppi/Protocol\r
1445 SqlCommand = """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""\r
1446 RecordSet = EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1447 for Record in RecordSet:\r
e95a0dfb
JC
1448 if Record[1] == 'Ppi':\r
1449 EotGlobalData.gPpiList[Record[0].lower()] = -2\r
52302d4d
LG
1450 if Record[1] == 'Protocol':\r
1451 EotGlobalData.gProtocolList[Record[0].lower()] = -2\r
1452\r
1453 ## GenerateQueryTable() method\r
1454 #\r
1455 # Generate two tables improve query performance\r
1456 #\r
1457 # @param self: The object pointer\r
1458 #\r
1459 def GenerateQueryTable(self):\r
1460 EdkLogger.quiet("Generating temp query table for analysis ... ")\r
1461 for Identifier in EotGlobalData.gIdentifierTableList:\r
1462 SqlCommand = """insert into Query (Name, Modifier, Value, Model)\r
1463 select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \\r
1464 % (Identifier[0], MODEL_IDENTIFIER_VARIABLE, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION)\r
1465 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1466 SqlCommand = """insert into Query2 (Name, Modifier, Value, Model)\r
1467 select Name, Modifier, Value, Model from %s where Model = %s""" \\r
1468 % (Identifier[0], MODEL_IDENTIFIER_MACRO_DEFINE)\r
1469 EotGlobalData.gDb.TblReport.Exec(SqlCommand)\r
1470\r
1471 ## ParseExecutionOrder() method\r
1472 #\r
1473 # Get final execution order\r
1474 # 1. Search all PPI\r
1475 # 2. Search all PROTOCOL\r
1476 #\r
1477 # @param self: The object pointer\r
1478 #\r
1479 def ParseExecutionOrder(self):\r
1480 EdkLogger.quiet("Searching Ppi/Protocol ... ")\r
1481 for Identifier in EotGlobalData.gIdentifierTableList:\r
1482 ModuleID, ModuleName, ModuleGuid, SourceFileID, SourceFileFullPath, ItemName, ItemType, ItemMode, GuidName, GuidMacro, GuidValue, BelongsToFunction, Enabled = \\r
1483 -1, '', '', -1, '', '', '', '', '', '', '', '', 0\r
1484\r
1485 SourceFileID = Identifier[0].replace('Identifier', '')\r
1486 SourceFileFullPath = Identifier[1]\r
1487 Identifier = Identifier[0]\r
1488\r
1489 # Find Ppis\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%%' or Name like '%%%s%%') and Model = %s""" \\r
1493 % (Identifier, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1494 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1495\r
1496 ItemMode = 'Produced'\r
1497 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1498 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1499 % (Identifier, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1500 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 2)\r
1501\r
1502 SearchPpiCallFunction(Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1503\r
1504 ItemMode = 'Consumed'\r
1505 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1506 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1507 % (Identifier, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1508 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1509\r
1510 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Ppi', ItemMode)\r
1511\r
1512 ItemMode = 'Callback'\r
1513 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1514 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1515 % (Identifier, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1516 SearchPpi(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode)\r
1517\r
fb0b35e0 1518 # Find Protocols\r
52302d4d
LG
1519 ItemMode = 'Produced'\r
1520 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1521 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1522 % (Identifier, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1523 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 1)\r
1524\r
1525 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1526 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1527 % (Identifier, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1528 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 2)\r
1529\r
1530 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)\r
1531\r
1532 ItemMode = 'Consumed'\r
1533 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1534 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1535 % (Identifier, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1536 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 0)\r
1537\r
1538 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1539 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1540 % (Identifier, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1541 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 1)\r
1542\r
1543 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)\r
1544\r
1545 ItemMode = 'Callback'\r
1546 SqlCommand = """select Value, Name, BelongsToFile, StartLine, EndLine from %s\r
1547 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \\r
1548 % (Identifier, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING)\r
1549 SearchProtocols(SqlCommand, Identifier, SourceFileID, SourceFileFullPath, ItemMode, 0)\r
1550\r
1551 SearchFunctionCalling(Identifier, SourceFileID, SourceFileFullPath, 'Protocol', ItemMode)\r
1552\r
1553 # Hard Code\r
1554 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)\r
1555 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)\r
1556 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)\r
1557 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)\r
1558 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)\r
1559 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)\r
1560 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)\r
1561 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)\r
1562 EotGlobalData.gDb.TblReport.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)\r
1563\r
1564 EotGlobalData.gDb.Conn.commit()\r
1565\r
1566\r
1567 ## BuildDatabase() methoc\r
1568 #\r
1569 # Build the database for target\r
1570 #\r
1571 # @param self: The object pointer\r
1572 #\r
1573 def BuildDatabase(self):\r
1574 # Clean report table\r
1575 EotGlobalData.gDb.TblReport.Drop()\r
1576 EotGlobalData.gDb.TblReport.Create()\r
1577\r
1578 # Build database\r
1579 if self.IsInit:\r
1580 self.BuildMetaDataFileDatabase(EotGlobalData.gINF_FILES)\r
1581 EdkLogger.quiet("Building database for source code ...")\r
1582 c.CreateCCodeDB(EotGlobalData.gSOURCE_FILES)\r
1583 EdkLogger.quiet("Building database for source code done!")\r
1584\r
1585 EotGlobalData.gIdentifierTableList = GetTableList((MODEL_FILE_C, MODEL_FILE_H), 'Identifier', EotGlobalData.gDb)\r
1586\r
1587 ## BuildMetaDataFileDatabase() method\r
1588 #\r
1589 # Build the database for meta data files\r
1590 #\r
1591 # @param self: The object pointer\r
1592 # @param Inf_Files: A list for all INF files\r
1593 #\r
1594 def BuildMetaDataFileDatabase(self, Inf_Files):\r
1595 EdkLogger.quiet("Building database for meta data files ...")\r
1596 for InfFile in Inf_Files:\r
47f15da1
HC
1597 if not InfFile:\r
1598 continue\r
52302d4d
LG
1599 EdkLogger.quiet("Parsing %s ..." % str(InfFile))\r
1600 EdkInfParser(InfFile, EotGlobalData.gDb, Inf_Files[InfFile], '')\r
1601\r
1602 EotGlobalData.gDb.Conn.commit()\r
1603 EdkLogger.quiet("Building database for meta data files done!")\r
1604\r
1605 ## ParseOption() method\r
1606 #\r
1607 # Parse command line options\r
1608 #\r
1609 # @param self: The object pointer\r
1610 #\r
1611 def ParseOption(self):\r
1612 (Options, Target) = self.EotOptionParser()\r
1613\r
1614 # Set log level\r
1615 self.SetLogLevel(Options)\r
1616\r
1617 if Options.FvFileList:\r
1618 self.FvFileList = Options.FvFileList\r
f7496d71 1619\r
52302d4d
LG
1620 if Options.MapFileList:\r
1621 self.MapFileList = Options.FvMapFileList\r
1622\r
1623 if Options.SourceFileList:\r
1624 self.SourceFileList = Options.SourceFileList\r
1625\r
1626 if Options.IncludeDirList:\r
1627 self.IncludeDirList = Options.IncludeDirList\r
1628\r
1629 if Options.DecFileList:\r
1630 self.DecFileList = Options.DecFileList\r
f7496d71 1631\r
52302d4d
LG
1632 if Options.GuidList:\r
1633 self.GuidList = Options.GuidList\r
1634\r
1635 if Options.LogFile:\r
1636 self.LogFile = Options.LogFile\r
1637\r
1638 if Options.keepdatabase:\r
1639 self.IsInit = False\r
1640\r
1641 ## SetLogLevel() method\r
1642 #\r
1643 # Set current log level of the tool based on args\r
1644 #\r
1645 # @param self: The object pointer\r
1646 # @param Option: The option list including log level setting\r
1647 #\r
1648 def SetLogLevel(self, Option):\r
4231a819 1649 if Option.verbose is not None:\r
52302d4d 1650 EdkLogger.SetLevel(EdkLogger.VERBOSE)\r
4231a819 1651 elif Option.quiet is not None:\r
52302d4d 1652 EdkLogger.SetLevel(EdkLogger.QUIET)\r
4231a819 1653 elif Option.debug is not None:\r
52302d4d
LG
1654 EdkLogger.SetLevel(Option.debug + 1)\r
1655 else:\r
1656 EdkLogger.SetLevel(EdkLogger.INFO)\r
1657\r
1658 ## EotOptionParser() method\r
1659 #\r
1660 # Using standard Python module optparse to parse command line option of this tool.\r
1661 #\r
1662 # @param self: The object pointer\r
1663 #\r
1664 # @retval Opt A optparse.Values object containing the parsed options\r
1665 # @retval Args Target of build command\r
1666 #\r
1667 def EotOptionParser(self):\r
1668 Parser = OptionParser(description = self.Copyright, version = self.Version, prog = "Eot.exe", usage = "%prog [options]")\r
1669 Parser.add_option("-m", "--makefile filename", action="store", type="string", dest='MakeFile',\r
1670 help="Specify a makefile for the platform.")\r
1671 Parser.add_option("-c", "--dsc filename", action="store", type="string", dest="DscFile",\r
1672 help="Specify a dsc file for the platform.")\r
1673 Parser.add_option("-f", "--fv filename", action="store", type="string", dest="FvFileList",\r
1674 help="Specify fv file list, quoted by \"\".")\r
1675 Parser.add_option("-a", "--map filename", action="store", type="string", dest="MapFileList",\r
1676 help="Specify map file list, quoted by \"\".")\r
1677 Parser.add_option("-s", "--source files", action="store", type="string", dest="SourceFileList",\r
1678 help="Specify source file list by a file")\r
1679 Parser.add_option("-i", "--include dirs", action="store", type="string", dest="IncludeDirList",\r
1680 help="Specify include dir list by a file")\r
1681 Parser.add_option("-e", "--dec files", action="store", type="string", dest="DecFileList",\r
1682 help="Specify dec file list by a file")\r
1683 Parser.add_option("-g", "--guid list", action="store", type="string", dest="GuidList",\r
1684 help="Specify guid file list by a file")\r
1685 Parser.add_option("-l", "--log filename", action="store", type="string", dest="LogFile",\r
1686 help="Specify real execution log file")\r
1687\r
1688 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
1689\r
1690 Parser.add_option("-q", "--quiet", action="store_true", type=None, help="Disable all messages except FATAL ERRORS.")\r
1691 Parser.add_option("-v", "--verbose", action="store_true", type=None, help="Turn on verbose output with informational messages printed, "\\r
1692 "including library instances selected, final dependency expression, "\\r
1693 "and warning messages, etc.")\r
1694 Parser.add_option("-d", "--debug", action="store", type="int", help="Enable debug messages at specified level.")\r
1695\r
1696 (Opt, Args)=Parser.parse_args()\r
1697\r
1698 return (Opt, Args)\r
1699\r
1700##\r
1701#\r
1702# This acts like the main() function for the script, unless it is 'import'ed into another\r
1703# script.\r
1704#\r
1705if __name__ == '__main__':\r
1706 # Initialize log system\r
1707 EdkLogger.Initialize()\r
1708 EdkLogger.IsRaiseError = False\r
1709 EdkLogger.quiet(time.strftime("%H:%M:%S, %b.%d %Y ", time.localtime()) + "[00:00]" + "\n")\r
1710\r
1711 StartTime = time.clock()\r
47f15da1
HC
1712 Eot = Eot(CommandLineOption=False,\r
1713 SourceFileList=r'C:\TestEot\Source.txt',\r
1714 GuidList=r'C:\TestEot\Guid.txt',\r
1715 FvFileList=r'C:\TestEot\FVRECOVERY.Fv')\r
52302d4d
LG
1716 FinishTime = time.clock()\r
1717\r
1718 BuildDuration = time.strftime("%M:%S", time.gmtime(int(round(FinishTime - StartTime))))\r
1719 EdkLogger.quiet("\n%s [%s]" % (time.strftime("%H:%M:%S, %b.%d %Y", time.localtime()), BuildDuration))\r