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