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