2 # This file is used to be the main entrance of EOT tool
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 from __future__
import absolute_import
18 import Common
.LongFilePathOs
as os
, time
, glob
19 import Common
.EdkLogger
as EdkLogger
20 from . import EotGlobalData
21 from optparse
import OptionParser
22 from Common
.StringUtils
import NormPath
23 from Common
import BuildToolError
24 from Common
.Misc
import GuidStructureStringToGuidString
, sdict
25 from .InfParserLite
import *
27 from . import Database
28 from array
import array
29 from .Report
import Report
30 from Common
.BuildVersion
import gBUILD_VERSION
31 from .Parser
import ConvertGuid
32 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
38 gGuidStringFormat
= "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"
39 gPeiAprioriFileNameGuid
= '1b45cc0a-156a-428a-af62-49864da0e6e6'
40 gAprioriGuid
= 'fc510ee7-ffdc-11d4-bd41-0080c73c8881'
44 _HEADER_
= struct
.Struct("")
45 _HEADER_SIZE_
= _HEADER_
.size
47 def __new__(cls
, *args
, **kwargs
):
48 return array
.__new
__(cls
, 'B')
50 def __init__(self
, ID
=None):
52 self
._ID
_ = str(uuid
.uuid1()).upper()
59 self
._SubImages
= sdict() # {offset: Image()}
61 array
.__init
__(self
, 'B')
67 Len
= array
.__len
__(self
)
68 for Offset
in self
._SubImages
:
69 Len
+= len(self
._SubImages
[Offset
])
73 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
76 def _Pack(self
, PadByte
=0xFF):
77 raise NotImplementedError
79 def frombuffer(self
, Buffer
, Offset
=0, Size
=None):
82 # we may need the Size information in advance if it's given
84 self
._LEN
_ = self
._Unpack
()
89 def GetField(self
, FieldStruct
, Offset
=0):
90 return FieldStruct
.unpack_from(self
, Offset
)
92 def SetField(self
, FieldStruct
, Offset
, *args
):
93 # check if there's enough space
94 Size
= FieldStruct
.size
96 self
.extend([0] * (Size
- len(self
)))
97 FieldStruct
.pack_into(self
, Offset
, *args
)
99 def _SetData(self
, Data
):
100 if len(self
) < self
._HEADER
_SIZE
_:
101 self
.extend([0] * (self
._HEADER
_SIZE
_ - len(self
)))
103 del self
[self
._HEADER
_SIZE
_:]
107 if len(self
) > self
._HEADER
_SIZE
_:
108 return self
[self
._HEADER
_SIZE
_:]
111 Data
= property(_GetData
, _SetData
)
113 ## CompressedImage() class
115 # A class for Compressed Image
117 class CompressedImage(Image
):
118 # UncompressedLength = 4-byte
119 # CompressionType = 1-byte
120 _HEADER_
= struct
.Struct("1I 1B")
121 _HEADER_SIZE_
= _HEADER_
.size
123 _ORIG_SIZE_
= struct
.Struct("1I")
124 _CMPRS_TYPE_
= struct
.Struct("4x 1B")
126 def __init__(self
, CompressedData
=None, CompressionType
=None, UncompressedLength
=None):
128 if UncompressedLength
is not None:
129 self
.UncompressedLength
= UncompressedLength
130 if CompressionType
is not None:
131 self
.CompressionType
= CompressionType
132 if CompressedData
is not None:
133 self
.Data
= CompressedData
137 S
= "algorithm=%s uncompressed=%x" % (self
.CompressionType
, self
.UncompressedLength
)
138 for Sec
in self
.Sections
:
143 def _SetOriginalSize(self
, Size
):
144 self
.SetField(self
._ORIG
_SIZE
_, 0, Size
)
146 def _GetOriginalSize(self
):
147 return self
.GetField(self
._ORIG
_SIZE
_)[0]
149 def _SetCompressionType(self
, Type
):
150 self
.SetField(self
._CMPRS
_TYPE
_, 0, Type
)
152 def _GetCompressionType(self
):
153 return self
.GetField(self
._CMPRS
_TYPE
_)[0]
155 def _GetSections(self
):
157 from . import EfiCompressor
158 TmpData
= EfiCompressor
.FrameworkDecompress(
159 self
[self
._HEADER
_SIZE
_:],
160 len(self
) - self
._HEADER
_SIZE
_
163 DecData
.fromstring(TmpData
)
165 from . import EfiCompressor
166 TmpData
= EfiCompressor
.UefiDecompress(
167 self
[self
._HEADER
_SIZE
_:],
168 len(self
) - self
._HEADER
_SIZE
_
171 DecData
.fromstring(TmpData
)
175 while Offset
< len(DecData
):
178 Sec
.frombuffer(DecData
, Offset
)
180 # the section is aligned to 4-byte boundary
183 SectionList
.append(Sec
)
186 UncompressedLength
= property(_GetOriginalSize
, _SetOriginalSize
)
187 CompressionType
= property(_GetCompressionType
, _SetCompressionType
)
188 Sections
= property(_GetSections
)
195 _HEADER_
= struct
.Struct("")
205 # keep header in this Image object
207 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
210 def _GetUiString(self
):
211 return codecs
.utf_16_decode(self
[0:-2].tostring())[0]
213 String
= property(_GetUiString
)
220 _HEADER_
= struct
.Struct("")
223 _GUID_
= struct
.Struct("1I2H8B")
224 _OPCODE_
= struct
.Struct("1B")
240 -1 : _OPCODE_
, # first one in depex must be an opcdoe
241 0x00 : _GUID_
, #"BEFORE",
242 0x01 : _GUID_
, #"AFTER",
243 0x02 : _GUID_
, #"PUSH",
244 0x03 : _OPCODE_
, #"AND",
245 0x04 : _OPCODE_
, #"OR",
246 0x05 : _OPCODE_
, #"NOT",
247 0x06 : _OPCODE_
, #"TRUE",
248 0x07 : _OPCODE_
, #"FALSE",
250 0x09 : _OPCODE_
, #"SOR"
260 Indention
= ' ' * gIndention
262 for T
in self
.Expression
:
263 if T
in self
._OPCODE
_STRING
_:
264 S
+= Indention
+ self
._OPCODE
_STRING
_[T
]
265 if T
not in [0x00, 0x01, 0x02]:
268 S
+= ' ' + gGuidStringFormat
% T
+ '\n'
273 # keep header in this Image object
275 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
278 def _GetExpression(self
):
279 if self
._ExprList
== []:
281 CurrentData
= self
._OPCODE
_
282 while Offset
< len(self
):
283 Token
= CurrentData
.unpack_from(self
, Offset
)
284 Offset
+= CurrentData
.size
287 if Token
in self
._NEXT
_:
288 CurrentData
= self
._NEXT
_[Token
]
290 CurrentData
= self
._GUID
_
292 CurrentData
= self
._OPCODE
_
293 self
._ExprList
.append(Token
)
294 if CurrentData
is None:
296 return self
._ExprList
298 Expression
= property(_GetExpression
)
300 ## FirmwareVolume() class
302 # A class for Firmware Volume
304 class FirmwareVolume(Image
):
305 # Read FvLength, Attributes, HeaderLength, Checksum
306 _HEADER_
= struct
.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")
307 _HEADER_SIZE_
= _HEADER_
.size
309 _FfsGuid
= "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
311 _GUID_
= struct
.Struct("16x 1I2H8B")
312 _LENGTH_
= struct
.Struct("16x 16x 1Q")
313 _SIG_
= struct
.Struct("16x 16x 8x 1I")
314 _ATTR_
= struct
.Struct("16x 16x 8x 4x 1I")
315 _HLEN_
= struct
.Struct("16x 16x 8x 4x 4x 1H")
316 _CHECKSUM_
= struct
.Struct("16x 16x 8x 4x 4x 2x 1H")
318 def __init__(self
, Name
=''):
321 self
.FfsDict
= sdict()
322 self
.OrderedFfsDict
= sdict()
323 self
.UnDispatchedFfsDict
= sdict()
324 self
.ProtocolList
= sdict()
326 def CheckArchProtocol(self
):
327 for Item
in EotGlobalData
.gArchProtocolGuids
:
328 if Item
.lower() not in EotGlobalData
.gProtocolList
:
332 def ParseDepex(self
, Depex
, Type
):
335 List
= EotGlobalData
.gPpiList
336 if Type
== 'Protocol':
337 List
= EotGlobalData
.gProtocolList
343 for Index
in range(0, len(Depex
.Expression
)):
344 Item
= Depex
.Expression
[Index
]
347 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
348 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
349 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
352 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
353 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
354 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
357 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
358 if Guid
.lower() in List
:
359 DepexStack
.append(True)
360 DepexList
.append(Guid
)
362 DepexStack
.append(False)
363 DepexList
.append(Guid
)
365 elif Item
== 0x03 or Item
== 0x04:
366 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
367 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
369 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
370 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
372 DepexStack
.append(True)
373 DepexList
.append('TRUE')
374 DepexString
= DepexString
+ 'TRUE' + ' '
376 DepexStack
.append(False)
377 DepexList
.append('False')
378 DepexString
= DepexString
+ 'FALSE' + ' '
380 if Index
!= len(Depex
.Expression
) - 1:
381 CouldBeLoaded
= False
383 CouldBeLoaded
= DepexStack
.pop()
385 CouldBeLoaded
= False
387 DepexString
= DepexList
[0].strip()
388 return (CouldBeLoaded
, DepexString
, FileDepex
)
390 def Dispatch(self
, Db
= None):
393 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
394 # Find PeiCore, DexCore, PeiPriori, DxePriori first
395 FfsSecCoreGuid
= None
396 FfsPeiCoreGuid
= None
397 FfsDxeCoreGuid
= None
398 FfsPeiPrioriGuid
= None
399 FfsDxePrioriGuid
= None
400 for FfsID
in self
.UnDispatchedFfsDict
:
401 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
403 FfsSecCoreGuid
= FfsID
406 FfsPeiCoreGuid
= FfsID
409 FfsDxeCoreGuid
= FfsID
411 if Ffs
.Guid
.lower() == gPeiAprioriFileNameGuid
:
412 FfsPeiPrioriGuid
= FfsID
414 if Ffs
.Guid
.lower() == gAprioriGuid
:
415 FfsDxePrioriGuid
= FfsID
418 # Parse SEC_CORE first
419 if FfsSecCoreGuid
is not None:
420 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
421 self
.LoadPpi(Db
, FfsSecCoreGuid
)
424 if FfsPeiCoreGuid
is not None:
425 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
426 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
427 if FfsPeiPrioriGuid
is not None:
428 # Load PEIM described in priori file
429 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
430 if len(FfsPeiPriori
.Sections
) == 1:
431 Section
= FfsPeiPriori
.Sections
.popitem()[1]
432 if Section
.Type
== 0x19:
433 GuidStruct
= struct
.Struct('1I2H8B')
435 while len(Section
) > Start
:
436 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
437 GuidString
= gGuidStringFormat
% Guid
439 if GuidString
in self
.UnDispatchedFfsDict
:
440 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
441 self
.LoadPpi(Db
, GuidString
)
445 if FfsDxeCoreGuid
is not None:
446 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
447 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
448 if FfsDxePrioriGuid
is not None:
449 # Load PEIM described in priori file
450 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
451 if len(FfsDxePriori
.Sections
) == 1:
452 Section
= FfsDxePriori
.Sections
.popitem()[1]
453 if Section
.Type
== 0x19:
454 GuidStruct
= struct
.Struct('1I2H8B')
456 while len(Section
) > Start
:
457 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
458 GuidString
= gGuidStringFormat
% Guid
460 if GuidString
in self
.UnDispatchedFfsDict
:
461 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
462 self
.LoadProtocol(Db
, GuidString
)
465 def LoadProtocol(self
, Db
, ModuleGuid
):
466 SqlCommand
= """select GuidValue from Report
467 where SourceFileFullPath in
468 (select Value1 from Inf where BelongsToFile =
469 (select BelongsToFile from Inf
470 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
472 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
473 % (ModuleGuid
, 5001, 3007)
474 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
475 for Record
in RecordSet
:
476 SqlCommand
= """select Value2 from Inf where BelongsToFile =
477 (select DISTINCT BelongsToFile from Inf
479 (select SourceFileFullPath from Report
480 where GuidValue like '%s' and ItemMode = 'Callback'))
481 and Value1 = 'FILE_GUID'""" % Record
[0]
482 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
483 if CallBackSet
!= []:
484 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
486 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
488 def LoadPpi(self
, Db
, ModuleGuid
):
489 SqlCommand
= """select GuidValue from Report
490 where SourceFileFullPath in
491 (select Value1 from Inf where BelongsToFile =
492 (select BelongsToFile from Inf
493 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
495 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
496 % (ModuleGuid
, 5001, 3007)
497 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
498 for Record
in RecordSet
:
499 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
501 def DisPatchDxe(self
, Db
):
503 ScheduleList
= sdict()
504 for FfsID
in self
.UnDispatchedFfsDict
:
505 CouldBeLoaded
= False
508 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
512 for Section
in Ffs
.Sections
.values():
514 if Section
.Type
== 0x13:
516 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
518 if Section
.Type
== 0x01:
519 CompressSections
= Section
._SubImages
[4]
520 for CompressSection
in CompressSections
.Sections
:
521 if CompressSection
.Type
== 0x13:
523 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
525 if CompressSection
.Type
== 0x02:
526 NewSections
= CompressSection
._SubImages
[4]
527 for NewSection
in NewSections
.Sections
:
528 if NewSection
.Type
== 0x13:
530 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
535 CouldBeLoaded
= self
.CheckArchProtocol()
542 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
543 NewFfs
.Depex
= DepexString
544 if FileDepex
is not None:
545 ScheduleList
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
547 ScheduleList
[FfsID
] = NewFfs
549 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
551 for FfsID
in ScheduleList
:
552 NewFfs
= ScheduleList
.pop(FfsID
)
554 self
.OrderedFfsDict
[FfsID
] = NewFfs
555 self
.LoadProtocol(Db
, FfsID
)
557 SqlCommand
= """select Value2 from Inf
558 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
559 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
560 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
562 FfsName
= RecordSet
[0][0]
566 def DisPatchPei(self
, Db
):
568 for FfsID
in self
.UnDispatchedFfsDict
:
572 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
573 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
575 for Section
in Ffs
.Sections
.values():
576 if Section
.Type
== 0x1B:
577 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
580 if Section
.Type
== 0x01:
581 CompressSections
= Section
._SubImages
[4]
582 for CompressSection
in CompressSections
.Sections
:
583 if CompressSection
.Type
== 0x1B:
584 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
586 if CompressSection
.Type
== 0x02:
587 NewSections
= CompressSection
._SubImages
[4]
588 for NewSection
in NewSections
.Sections
:
589 if NewSection
.Type
== 0x1B:
590 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
596 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
597 NewFfs
.Depex
= DepexString
598 self
.OrderedFfsDict
[FfsID
] = NewFfs
599 self
.LoadPpi(Db
, FfsID
)
601 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
609 FvInfo
= '\n' + ' ' * gIndention
610 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
611 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
613 return FvInfo
+ FfsInfo
616 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
618 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_+Size
])
622 FfsStartAddress
= self
.HeaderSize
624 while FfsStartAddress
< EndOfFv
:
626 FfsObj
.frombuffer(self
, FfsStartAddress
)
628 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
629 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
630 if LastFfsObj
is not None:
631 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
633 if FfsId
in self
.FfsDict
:
634 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
635 ExtraData
="\t%s @ %s\n\t%s @ %s" \
636 % (FfsObj
.Guid
, FfsObj
.Offset
,
637 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
638 self
.FfsDict
[FfsId
] = FfsObj
639 if LastFfsObj
is not None:
640 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
642 FfsStartAddress
+= len(FfsObj
)
644 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
645 # The next FFS must be at the latest next 8-byte aligned address
647 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
650 def _GetAttributes(self
):
651 return self
.GetField(self
._ATTR
_, 0)[0]
654 return self
.GetField(self
._LENGTH
_, 0)[0]
656 def _GetChecksum(self
):
657 return self
.GetField(self
._CHECKSUM
_, 0)[0]
659 def _GetHeaderLength(self
):
660 return self
.GetField(self
._HLEN
_, 0)[0]
662 def _GetFileSystemGuid(self
):
663 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
665 Attributes
= property(_GetAttributes
)
666 Size
= property(_GetSize
)
667 Checksum
= property(_GetChecksum
)
668 HeaderSize
= property(_GetHeaderLength
)
669 FileSystemGuid
= property(_GetFileSystemGuid
)
671 ## GuidDefinedImage() class
673 # A class for GUID Defined Image
675 class GuidDefinedImage(Image
):
676 _HEADER_
= struct
.Struct("1I2H8B 1H 1H")
677 _HEADER_SIZE_
= _HEADER_
.size
679 _GUID_
= struct
.Struct("1I2H8B")
680 _DATA_OFFSET_
= struct
.Struct("16x 1H")
681 _ATTR_
= struct
.Struct("18x 1H")
683 CRC32_GUID
= "FC1BCDB0-7D31-49AA-936A-A4600D9DD083"
684 TIANO_COMPRESS_GUID
= 'A31280AD-481E-41B6-95E8-127F4C984779'
685 LZMA_COMPRESS_GUID
= 'EE4E5898-3914-4259-9D6E-DC7BD79403CF'
687 def __init__(self
, SectionDefinitionGuid
=None, DataOffset
=None, Attributes
=None, Data
=None):
689 if SectionDefinitionGuid
is not None:
690 self
.SectionDefinitionGuid
= SectionDefinitionGuid
691 if DataOffset
is not None:
692 self
.DataOffset
= DataOffset
693 if Attributes
is not None:
694 self
.Attributes
= Attributes
699 S
= "guid=%s" % (gGuidStringFormat
% self
.SectionDefinitionGuid
)
700 for Sec
in self
.Sections
:
705 # keep header in this Image object
707 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
710 def _SetAttribute(self
, Attribute
):
711 self
.SetField(self
._ATTR
_, 0, Attribute
)
713 def _GetAttribute(self
):
714 return self
.GetField(self
._ATTR
_)[0]
716 def _SetGuid(self
, Guid
):
717 self
.SetField(self
._GUID
_, 0, Guid
)
720 return self
.GetField(self
._GUID
_)
722 def _SetDataOffset(self
, Offset
):
723 self
.SetField(self
._DATA
_OFFSET
_, 0, Offset
)
725 def _GetDataOffset(self
):
726 return self
.GetField(self
._DATA
_OFFSET
_)[0]
728 def _GetSections(self
):
730 Guid
= gGuidStringFormat
% self
.SectionDefinitionGuid
731 if Guid
== self
.CRC32_GUID
:
732 # skip the CRC32 value, we don't do CRC32 verification here
733 Offset
= self
.DataOffset
- 4
734 while Offset
< len(self
):
737 Sec
.frombuffer(self
, Offset
)
739 # the section is aligned to 4-byte boundary
740 Offset
= (Offset
+ 3) & (~
3)
743 SectionList
.append(Sec
)
744 elif Guid
== self
.TIANO_COMPRESS_GUID
:
746 from . import EfiCompressor
748 Offset
= self
.DataOffset
- 4
749 TmpData
= EfiCompressor
.FrameworkDecompress(self
[Offset
:], len(self
)-Offset
)
751 DecData
.fromstring(TmpData
)
753 while Offset
< len(DecData
):
756 Sec
.frombuffer(DecData
, Offset
)
758 # the section is aligned to 4-byte boundary
759 Offset
= (Offset
+ 3) & (~
3)
762 SectionList
.append(Sec
)
765 elif Guid
== self
.LZMA_COMPRESS_GUID
:
767 from . import LzmaCompressor
769 Offset
= self
.DataOffset
- 4
770 TmpData
= LzmaCompressor
.LzmaDecompress(self
[Offset
:], len(self
)-Offset
)
772 DecData
.fromstring(TmpData
)
774 while Offset
< len(DecData
):
777 Sec
.frombuffer(DecData
, Offset
)
779 # the section is aligned to 4-byte boundary
780 Offset
= (Offset
+ 3) & (~
3)
783 SectionList
.append(Sec
)
789 Attributes
= property(_GetAttribute
, _SetAttribute
)
790 SectionDefinitionGuid
= property(_GetGuid
, _SetGuid
)
791 DataOffset
= property(_GetDataOffset
, _SetDataOffset
)
792 Sections
= property(_GetSections
)
796 # A class for Section
798 class Section(Image
):
801 0x01 : "COMPRESSION",
802 0x02 : "GUID_DEFINED",
808 0x15 : "USER_INTERFACE",
809 0x16 : "COMPATIBILITY16",
810 0x17 : "FIRMWARE_VOLUME_IMAGE",
811 0x18 : "FREEFORM_SUBTYPE_GUID",
816 _SectionSubImages
= {
817 0x01 : CompressedImage
,
818 0x02 : GuidDefinedImage
,
819 0x17 : FirmwareVolume
,
827 _HEADER_
= struct
.Struct("3B 1B")
828 _HEADER_SIZE_
= _HEADER_
.size
831 # _FREE_FORM_SUBTYPE_GUID_HEADER_ = struct.Struct("1I2H8B")
832 _SIZE_
= struct
.Struct("3B")
833 _TYPE_
= struct
.Struct("3x 1B")
835 def __init__(self
, Type
=None, Size
=None):
846 SectionInfo
= ' ' * gIndention
847 if self
.Type
in self
._TypeName
:
848 SectionInfo
+= "[SECTION:%s] offset=%x size=%x" % (self
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
)
850 SectionInfo
+= "[SECTION:%x<unknown>] offset=%x size=%x " % (self
.Type
, self
._OFF
_, self
.Size
)
851 for Offset
in self
._SubImages
:
852 SectionInfo
+= ", " + str(self
._SubImages
[Offset
])
858 Type
, = self
._TYPE
_.unpack_from(self
._BUF
_, self
._OFF
_)
859 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
860 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
862 if Type
not in self
._SectionSubImages
:
863 # no need to extract sub-image, keep all in this Image object
864 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
866 # keep header in this Image object
867 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._HEADER
_SIZE
_])
869 # use new Image object to represent payload, which may be another kind
870 # of image such as PE32
872 PayloadOffset
= self
._HEADER
_SIZE
_
873 PayloadLen
= self
.Size
- self
._HEADER
_SIZE
_
874 Payload
= self
._SectionSubImages
[self
.Type
]()
875 Payload
.frombuffer(self
._BUF
_, self
._OFF
_ + self
._HEADER
_SIZE
_, PayloadLen
)
876 self
._SubImages
[PayloadOffset
] = Payload
880 def _SetSize(self
, Size
):
882 Size2
= (Size
& 0xFF00) >> 8
883 Size3
= (Size
& 0xFF0000) >> 16
884 self
.SetField(self
._SIZE
_, 0, Size1
, Size2
, Size3
)
887 Size1
, Size2
, Size3
= self
.GetField(self
._SIZE
_)
888 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
890 def _SetType(self
, Type
):
891 self
.SetField(self
._TYPE
_, 0, Type
)
894 return self
.GetField(self
._TYPE
_)[0]
896 def _GetAlignment(self
):
897 return self
._Alignment
899 def _SetAlignment(self
, Alignment
):
900 self
._Alignment
= Alignment
901 AlignmentMask
= Alignment
- 1
902 # section alignment is actually for payload, so we need to add header size
903 PayloadOffset
= self
._OFF
_ + self
._HEADER
_SIZE
_
904 if (PayloadOffset
& (~AlignmentMask
)) == 0:
906 NewOffset
= (PayloadOffset
+ AlignmentMask
) & (~AlignmentMask
)
907 while (NewOffset
- PayloadOffset
) < self
._HEADER
_SIZE
_:
908 NewOffset
+= self
._Alignment
911 self
.Size
= len(self
)
912 Image
.tofile(self
, f
)
913 for Offset
in self
._SubImages
:
914 self
._SubImages
[Offset
].tofile(f
)
916 Type
= property(_GetType
, _SetType
)
917 Size
= property(_GetSize
, _SetSize
)
918 Alignment
= property(_GetAlignment
, _SetAlignment
)
922 # A class for Ffs Section
925 _FfsFormat
= "24B%(payload_size)sB"
926 # skip IntegrityCheck
927 _HEADER_
= struct
.Struct("1I2H8B 2x 1B 1B 3B 1B")
928 _HEADER_SIZE_
= _HEADER_
.size
930 _NAME_
= struct
.Struct("1I2H8B")
931 _INT_CHECK_
= struct
.Struct("16x 1H")
932 _TYPE_
= struct
.Struct("18x 1B")
933 _ATTR_
= struct
.Struct("19x 1B")
934 _SIZE_
= struct
.Struct("20x 3B")
935 _STATE_
= struct
.Struct("23x 1B")
937 VTF_GUID
= "1BA0062E-C779-4582-8566-336AE8F78F09"
939 FFS_ATTRIB_FIXED
= 0x04
940 FFS_ATTRIB_DATA_ALIGNMENT
= 0x38
941 FFS_ATTRIB_CHECKSUM
= 0x40
947 0x03 : "SECURITY_CORE",
952 0x08 : "COMBINED_PEIM_DRIVER",
953 0x09 : "APPLICATION",
955 0x0B : "FIRMWARE_VOLUME_IMAGE",
956 0x0C : "COMBINED_SMM_DXE",
958 0x0E : "MM_STANDALONE",
959 0x0F : "MM_CORE_STANDALONE",
973 self
.Sections
= sdict()
981 Indention
= ' ' * gIndention
983 FfsInfo
+= "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \
984 (Ffs
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
, self
.Guid
, self
.FreeSpace
, self
.Alignment
)
985 SectionInfo
= '\n'.join([str(self
.Sections
[Offset
]) for Offset
in self
.Sections
])
987 return FfsInfo
+ SectionInfo
+ "\n"
996 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
997 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
999 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
1001 # Pad FFS may use the same GUID. We need to avoid it.
1002 if self
.Type
== 0xf0:
1003 self
.__ID
__ = str(uuid
.uuid1()).upper()
1005 self
.__ID
__ = self
.Guid
1007 # Traverse the SECTION. RAW and PAD do not have sections
1008 if self
.Type
not in [0xf0, 0x01] and Size
> 0 and Size
< 0xFFFFFF:
1010 SectionStartAddress
= self
._HEADER
_SIZE
_
1011 while SectionStartAddress
< EndOfFfs
:
1012 SectionObj
= Section()
1013 SectionObj
.frombuffer(self
, SectionStartAddress
)
1014 #f = open(repr(SectionObj), 'wb')
1015 #SectionObj.Size = 0
1016 #SectionObj.tofile(f)
1018 self
.Sections
[SectionStartAddress
] = SectionObj
1019 SectionStartAddress
+= len(SectionObj
)
1020 SectionStartAddress
= (SectionStartAddress
+ 3) & (~
3)
1025 def SetFreeSpace(self
, Size
):
1026 self
.FreeSpace
= Size
1029 return gGuidStringFormat
% self
.Name
1031 def _SetName(self
, Value
):
1032 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1033 self
.SetField(self
._NAME
_, 0, Value
)
1036 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1037 return self
.GetField(self
._NAME
_)
1039 def _SetSize(self
, Size
):
1041 Size2
= (Size
& 0xFF00) >> 8
1042 Size3
= (Size
& 0xFF0000) >> 16
1043 self
.SetField(self
._SIZE
_, 0, Size1
, Size2
, Size3
)
1046 Size1
, Size2
, Size3
= self
.GetField(self
._SIZE
_)
1047 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
1049 def _SetType(self
, Type
):
1050 self
.SetField(self
._TYPE
_, 0, Type
)
1053 return self
.GetField(self
._TYPE
_)[0]
1055 def _SetAttributes(self
, Value
):
1056 self
.SetField(self
._ATTR
_, 0, Value
)
1058 def _GetAttributes(self
):
1059 return self
.GetField(self
._ATTR
_)[0]
1061 def _GetFixed(self
):
1062 if (self
.Attributes
& self
.FFS_ATTRIB_FIXED
) != 0:
1066 def _GetCheckSum(self
):
1067 if (self
.Attributes
& self
.FFS_ATTRIB_CHECKSUM
) != 0:
1071 def _GetAlignment(self
):
1072 return (self
.Attributes
& self
.FFS_ATTRIB_DATA_ALIGNMENT
) >> 3
1074 def _SetState(self
, Value
):
1075 self
.SetField(self
._STATE
_, 0, Value
)
1077 def _GetState(self
):
1078 return self
.GetField(self
._STATE
_)[0]
1080 Name
= property(_GetName
, _SetName
)
1081 Guid
= property(_GetGuid
)
1082 Type
= property(_GetType
, _SetType
)
1083 Size
= property(_GetSize
, _SetSize
)
1084 Attributes
= property(_GetAttributes
, _SetAttributes
)
1085 Fixed
= property(_GetFixed
)
1086 Checksum
= property(_GetCheckSum
)
1087 Alignment
= property(_GetAlignment
)
1088 State
= property(_GetState
, _SetState
)
1090 ## FirmwareVolume() class
1092 # A class for Firmware Volume
1094 class FirmwareVolume(Image
):
1095 # Read FvLength, Attributes, HeaderLength, Checksum
1096 _HEADER_
= struct
.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")
1097 _HEADER_SIZE_
= _HEADER_
.size
1099 _FfsGuid
= "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
1101 _GUID_
= struct
.Struct("16x 1I2H8B")
1102 _LENGTH_
= struct
.Struct("16x 16x 1Q")
1103 _SIG_
= struct
.Struct("16x 16x 8x 1I")
1104 _ATTR_
= struct
.Struct("16x 16x 8x 4x 1I")
1105 _HLEN_
= struct
.Struct("16x 16x 8x 4x 4x 1H")
1106 _CHECKSUM_
= struct
.Struct("16x 16x 8x 4x 4x 2x 1H")
1108 def __init__(self
, Name
=''):
1109 Image
.__init
__(self
)
1111 self
.FfsDict
= sdict()
1112 self
.OrderedFfsDict
= sdict()
1113 self
.UnDispatchedFfsDict
= sdict()
1114 self
.ProtocolList
= sdict()
1116 def CheckArchProtocol(self
):
1117 for Item
in EotGlobalData
.gArchProtocolGuids
:
1118 if Item
.lower() not in EotGlobalData
.gProtocolList
:
1122 def ParseDepex(self
, Depex
, Type
):
1125 List
= EotGlobalData
.gPpiList
1126 if Type
== 'Protocol':
1127 List
= EotGlobalData
.gProtocolList
1132 CouldBeLoaded
= True
1133 for Index
in range(0, len(Depex
.Expression
)):
1134 Item
= Depex
.Expression
[Index
]
1137 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1138 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
1139 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
1142 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1143 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
1144 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
1147 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1148 if Guid
.lower() in List
:
1149 DepexStack
.append(True)
1150 DepexList
.append(Guid
)
1152 DepexStack
.append(False)
1153 DepexList
.append(Guid
)
1155 elif Item
== 0x03 or Item
== 0x04:
1156 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
1157 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
1159 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
1160 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
1162 DepexStack
.append(True)
1163 DepexList
.append('TRUE')
1164 DepexString
= DepexString
+ 'TRUE' + ' '
1166 DepexStack
.append(False)
1167 DepexList
.append('False')
1168 DepexString
= DepexString
+ 'FALSE' + ' '
1170 if Index
!= len(Depex
.Expression
) - 1:
1171 CouldBeLoaded
= False
1173 CouldBeLoaded
= DepexStack
.pop()
1175 CouldBeLoaded
= False
1177 DepexString
= DepexList
[0].strip()
1178 return (CouldBeLoaded
, DepexString
, FileDepex
)
1180 def Dispatch(self
, Db
= None):
1183 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
1184 # Find PeiCore, DexCore, PeiPriori, DxePriori first
1185 FfsSecCoreGuid
= None
1186 FfsPeiCoreGuid
= None
1187 FfsDxeCoreGuid
= None
1188 FfsPeiPrioriGuid
= None
1189 FfsDxePrioriGuid
= None
1190 for FfsID
in self
.UnDispatchedFfsDict
:
1191 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1192 if Ffs
.Type
== 0x03:
1193 FfsSecCoreGuid
= FfsID
1195 if Ffs
.Type
== 0x04:
1196 FfsPeiCoreGuid
= FfsID
1198 if Ffs
.Type
== 0x05:
1199 FfsDxeCoreGuid
= FfsID
1201 if Ffs
.Guid
.lower() == gPeiAprioriFileNameGuid
:
1202 FfsPeiPrioriGuid
= FfsID
1204 if Ffs
.Guid
.lower() == gAprioriGuid
:
1205 FfsDxePrioriGuid
= FfsID
1208 # Parse SEC_CORE first
1209 if FfsSecCoreGuid
is not None:
1210 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
1211 self
.LoadPpi(Db
, FfsSecCoreGuid
)
1214 if FfsPeiCoreGuid
is not None:
1215 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
1216 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
1217 if FfsPeiPrioriGuid
is not None:
1218 # Load PEIM described in priori file
1219 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
1220 if len(FfsPeiPriori
.Sections
) == 1:
1221 Section
= FfsPeiPriori
.Sections
.popitem()[1]
1222 if Section
.Type
== 0x19:
1223 GuidStruct
= struct
.Struct('1I2H8B')
1225 while len(Section
) > Start
:
1226 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
1227 GuidString
= gGuidStringFormat
% Guid
1229 if GuidString
in self
.UnDispatchedFfsDict
:
1230 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
1231 self
.LoadPpi(Db
, GuidString
)
1233 self
.DisPatchPei(Db
)
1236 if FfsDxeCoreGuid
is not None:
1237 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
1238 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
1239 if FfsDxePrioriGuid
is not None:
1240 # Load PEIM described in priori file
1241 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
1242 if len(FfsDxePriori
.Sections
) == 1:
1243 Section
= FfsDxePriori
.Sections
.popitem()[1]
1244 if Section
.Type
== 0x19:
1245 GuidStruct
= struct
.Struct('1I2H8B')
1247 while len(Section
) > Start
:
1248 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
1249 GuidString
= gGuidStringFormat
% Guid
1251 if GuidString
in self
.UnDispatchedFfsDict
:
1252 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
1253 self
.LoadProtocol(Db
, GuidString
)
1255 self
.DisPatchDxe(Db
)
1257 def LoadProtocol(self
, Db
, ModuleGuid
):
1258 SqlCommand
= """select GuidValue from Report
1259 where SourceFileFullPath in
1260 (select Value1 from Inf where BelongsToFile =
1261 (select BelongsToFile from Inf
1262 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
1264 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
1265 % (ModuleGuid
, 5001, 3007)
1266 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1267 for Record
in RecordSet
:
1268 SqlCommand
= """select Value2 from Inf where BelongsToFile =
1269 (select DISTINCT BelongsToFile from Inf
1271 (select SourceFileFullPath from Report
1272 where GuidValue like '%s' and ItemMode = 'Callback'))
1273 and Value1 = 'FILE_GUID'""" % Record
[0]
1274 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
1275 if CallBackSet
!= []:
1276 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
1278 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
1280 def LoadPpi(self
, Db
, ModuleGuid
):
1281 SqlCommand
= """select GuidValue from Report
1282 where SourceFileFullPath in
1283 (select Value1 from Inf where BelongsToFile =
1284 (select BelongsToFile from Inf
1285 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
1287 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
1288 % (ModuleGuid
, 5001, 3007)
1289 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1290 for Record
in RecordSet
:
1291 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
1293 def DisPatchDxe(self
, Db
):
1295 ScheduleList
= sdict()
1296 for FfsID
in self
.UnDispatchedFfsDict
:
1297 CouldBeLoaded
= False
1300 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1301 if Ffs
.Type
== 0x07:
1303 IsFoundDepex
= False
1304 for Section
in Ffs
.Sections
.values():
1306 if Section
.Type
== 0x13:
1308 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
1310 if Section
.Type
== 0x01:
1311 CompressSections
= Section
._SubImages
[4]
1312 for CompressSection
in CompressSections
.Sections
:
1313 if CompressSection
.Type
== 0x13:
1315 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
1317 if CompressSection
.Type
== 0x02:
1318 NewSections
= CompressSection
._SubImages
[4]
1319 for NewSection
in NewSections
.Sections
:
1320 if NewSection
.Type
== 0x13:
1322 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
1326 if not IsFoundDepex
:
1327 CouldBeLoaded
= self
.CheckArchProtocol()
1334 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
1335 NewFfs
.Depex
= DepexString
1336 if FileDepex
is not None:
1337 ScheduleList
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
1339 ScheduleList
[FfsID
] = NewFfs
1341 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
1343 for FfsID
in ScheduleList
:
1344 NewFfs
= ScheduleList
.pop(FfsID
)
1346 self
.OrderedFfsDict
[FfsID
] = NewFfs
1347 self
.LoadProtocol(Db
, FfsID
)
1349 SqlCommand
= """select Value2 from Inf
1350 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
1351 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
1352 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1354 FfsName
= RecordSet
[0][0]
1357 self
.DisPatchDxe(Db
)
1359 def DisPatchPei(self
, Db
):
1361 for FfsID
in self
.UnDispatchedFfsDict
:
1362 CouldBeLoaded
= True
1365 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1366 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
1368 for Section
in Ffs
.Sections
.values():
1369 if Section
.Type
== 0x1B:
1370 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
1372 if Section
.Type
== 0x01:
1373 CompressSections
= Section
._SubImages
[4]
1374 for CompressSection
in CompressSections
.Sections
:
1375 if CompressSection
.Type
== 0x1B:
1376 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
1378 if CompressSection
.Type
== 0x02:
1379 NewSections
= CompressSection
._SubImages
[4]
1380 for NewSection
in NewSections
.Sections
:
1381 if NewSection
.Type
== 0x1B:
1382 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
1388 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
1389 NewFfs
.Depex
= DepexString
1390 self
.OrderedFfsDict
[FfsID
] = NewFfs
1391 self
.LoadPpi(Db
, FfsID
)
1393 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
1396 self
.DisPatchPei(Db
)
1402 FvInfo
= '\n' + ' ' * gIndention
1403 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
1404 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
1406 return FvInfo
+ FfsInfo
1409 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
1411 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_+Size
])
1415 FfsStartAddress
= self
.HeaderSize
1417 while FfsStartAddress
< EndOfFv
:
1419 FfsObj
.frombuffer(self
, FfsStartAddress
)
1420 FfsId
= repr(FfsObj
)
1421 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
1422 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
1423 if LastFfsObj
is not None:
1424 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
1426 if FfsId
in self
.FfsDict
:
1427 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
1428 ExtraData
="\t%s @ %s\n\t%s @ %s" \
1429 % (FfsObj
.Guid
, FfsObj
.Offset
,
1430 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
1431 self
.FfsDict
[FfsId
] = FfsObj
1432 if LastFfsObj
is not None:
1433 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
1435 FfsStartAddress
+= len(FfsObj
)
1437 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
1438 # The next FFS must be at the latest next 8-byte aligned address
1440 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
1443 def _GetAttributes(self
):
1444 return self
.GetField(self
._ATTR
_, 0)[0]
1447 return self
.GetField(self
._LENGTH
_, 0)[0]
1449 def _GetChecksum(self
):
1450 return self
.GetField(self
._CHECKSUM
_, 0)[0]
1452 def _GetHeaderLength(self
):
1453 return self
.GetField(self
._HLEN
_, 0)[0]
1455 def _GetFileSystemGuid(self
):
1456 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
1458 Attributes
= property(_GetAttributes
)
1459 Size
= property(_GetSize
)
1460 Checksum
= property(_GetChecksum
)
1461 HeaderSize
= property(_GetHeaderLength
)
1462 FileSystemGuid
= property(_GetFileSystemGuid
)
1464 ## MultipleFv() class
1466 # A class for Multiple FV
1468 class MultipleFv(FirmwareVolume
):
1469 def __init__(self
, FvList
):
1470 FirmwareVolume
.__init
__(self
)
1472 for FvPath
in FvList
:
1473 FvName
= os
.path
.splitext(os
.path
.split(FvPath
)[1])[0]
1474 Fd
= open(FvPath
, 'rb')
1477 Buf
.fromfile(Fd
, os
.path
.getsize(FvPath
))
1481 Fv
= FirmwareVolume(FvName
)
1482 Fv
.frombuffer(Buf
, 0, len(Buf
))
1484 self
.BasicInfo
.append([Fv
.Name
, Fv
.FileSystemGuid
, Fv
.Size
])
1485 self
.FfsDict
.append(Fv
.FfsDict
)
1489 # This class is used to define Eot main entrance
1491 # @param object: Inherited from object class
1496 # @param self: The object pointer
1498 def __init__(self
, CommandLineOption
=True, IsInit
=True, SourceFileList
=None, \
1499 IncludeDirList
=None, DecFileList
=None, GuidList
=None, LogFile
=None,
1500 FvFileList
="", MapFileList
="", Report
='Report.html', Dispatch
=None):
1501 # Version and Copyright
1502 self
.VersionNumber
= ("0.02" + " " + gBUILD_VERSION
)
1503 self
.Version
= "%prog Version " + self
.VersionNumber
1504 self
.Copyright
= "Copyright (c) 2008 - 2018, Intel Corporation All rights reserved."
1505 self
.Report
= Report
1507 self
.IsInit
= IsInit
1508 self
.SourceFileList
= SourceFileList
1509 self
.IncludeDirList
= IncludeDirList
1510 self
.DecFileList
= DecFileList
1511 self
.GuidList
= GuidList
1512 self
.LogFile
= LogFile
1513 self
.FvFileList
= FvFileList
1514 self
.MapFileList
= MapFileList
1515 self
.Dispatch
= Dispatch
1517 # Check workspace environment
1518 if "EFI_SOURCE" not in os
.environ
:
1519 if "EDK_SOURCE" not in os
.environ
:
1522 EotGlobalData
.gEDK_SOURCE
= os
.path
.normpath(os
.getenv("EDK_SOURCE"))
1524 EotGlobalData
.gEFI_SOURCE
= os
.path
.normpath(os
.getenv("EFI_SOURCE"))
1525 EotGlobalData
.gEDK_SOURCE
= os
.path
.join(EotGlobalData
.gEFI_SOURCE
, 'Edk')
1527 if "WORKSPACE" not in os
.environ
:
1528 EdkLogger
.error("EOT", BuildToolError
.ATTRIBUTE_NOT_AVAILABLE
, "Environment variable not found",
1529 ExtraData
="WORKSPACE")
1531 EotGlobalData
.gWORKSPACE
= os
.path
.normpath(os
.getenv("WORKSPACE"))
1533 EotGlobalData
.gMACRO
['WORKSPACE'] = EotGlobalData
.gWORKSPACE
1534 EotGlobalData
.gMACRO
['EFI_SOURCE'] = EotGlobalData
.gEFI_SOURCE
1535 EotGlobalData
.gMACRO
['EDK_SOURCE'] = EotGlobalData
.gEDK_SOURCE
1537 # Parse the options and args
1538 if CommandLineOption
:
1542 for FvFile
in GetSplitValueList(self
.FvFileList
, ' '):
1543 FvFile
= os
.path
.normpath(FvFile
)
1544 if not os
.path
.isfile(FvFile
):
1545 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % FvFile
)
1546 EotGlobalData
.gFV_FILE
.append(FvFile
)
1548 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "The fv file list of target platform was not specified")
1550 if self
.MapFileList
:
1551 for MapFile
in GetSplitValueList(self
.MapFileList
, ' '):
1552 MapFile
= os
.path
.normpath(MapFile
)
1553 if not os
.path
.isfile(MapFile
):
1554 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % MapFile
)
1555 EotGlobalData
.gMAP_FILE
.append(MapFile
)
1557 # Generate source file list
1558 self
.GenerateSourceFileList(self
.SourceFileList
, self
.IncludeDirList
)
1560 # Generate guid list of dec file list
1561 self
.ParseDecFile(self
.DecFileList
)
1563 # Generate guid list from GUID list file
1564 self
.ParseGuidList(self
.GuidList
)
1567 EotGlobalData
.gDb
= Database
.Database(Database
.DATABASE_PATH
)
1568 EotGlobalData
.gDb
.InitDatabase(self
.IsInit
)
1570 # Build ECC database
1571 self
.BuildDatabase()
1573 # Parse Ppi/Protocol
1574 self
.ParseExecutionOrder()
1576 # Merge Identifier tables
1577 self
.GenerateQueryTable()
1579 # Generate report database
1580 self
.GenerateReportDatabase()
1589 self
.GenerateReport()
1592 self
.ConvertLogFile(self
.LogFile
)
1595 EdkLogger
.quiet("EOT FINISHED!")
1598 EotGlobalData
.gDb
.Close()
1600 ## ParseDecFile() method
1602 # parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}
1603 # The Dict is stored in EotGlobalData.gGuidDict
1605 # @param self: The object pointer
1606 # @param DecFileList: A list of all DEC files
1608 def ParseDecFile(self
, DecFileList
):
1610 path
= os
.path
.normpath(DecFileList
)
1611 lfr
= open(path
, 'rb')
1613 path
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1614 if os
.path
.exists(path
):
1615 dfr
= open(path
, 'rb')
1617 line
= CleanString(line
)
1618 list = line
.split('=')
1620 EotGlobalData
.gGuidDict
[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())
1623 ## ParseGuidList() method
1625 # Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}
1626 # The Dict is stored in EotGlobalData.gGuidDict
1628 # @param self: The object pointer
1629 # @param GuidList: A list of all GUID and its value
1631 def ParseGuidList(self
, GuidList
):
1632 Path
= os
.path
.join(EotGlobalData
.gWORKSPACE
, GuidList
)
1633 if os
.path
.isfile(Path
):
1634 for Line
in open(Path
):
1635 (GuidName
, GuidValue
) = Line
.split()
1636 EotGlobalData
.gGuidDict
[GuidName
] = GuidValue
1638 ## ConvertLogFile() method
1640 # Parse a real running log file to get real dispatch order
1641 # The result is saved to old file name + '.new'
1643 # @param self: The object pointer
1644 # @param LogFile: A real running log file name
1646 def ConvertLogFile(self
, LogFile
):
1651 lfr
= open(LogFile
, 'rb')
1652 lfw
= open(LogFile
+ '.new', 'wb')
1655 line
= line
.replace('.efi', '')
1656 index
= line
.find("Loading PEIM at ")
1658 newline
.append(line
[index
+ 55 : ])
1660 index
= line
.find("Loading driver at ")
1662 newline
.append(line
[index
+ 57 : ])
1665 for line
in newline
:
1666 lfw
.write(line
+ '\r\n')
1673 ## GenerateSourceFileList() method
1675 # Generate a list of all source files
1676 # 1. Search the file list one by one
1677 # 2. Store inf file name with source file names under it like
1678 # { INF file name: [source file1, source file2, ...]}
1679 # 3. Search the include list to find all .h files
1680 # 4. Store source file list to EotGlobalData.gSOURCE_FILES
1681 # 5. Store INF file list to EotGlobalData.gINF_FILES
1683 # @param self: The object pointer
1684 # @param SourceFileList: A list of all source files
1685 # @param IncludeFileList: A list of all include files
1687 def GenerateSourceFileList(self
, SourceFileList
, IncludeFileList
):
1688 EdkLogger
.quiet("Generating source files list ... ")
1689 mSourceFileList
= []
1693 mCurrentInfFile
= ''
1694 mCurrentSourceFileList
= []
1697 sfl
= open(SourceFileList
, 'rb')
1699 line
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1700 if line
[-2:].upper() == '.C' or line
[-2:].upper() == '.H':
1701 if line
not in mCurrentSourceFileList
:
1702 mCurrentSourceFileList
.append(line
)
1703 mSourceFileList
.append(line
)
1704 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % line
)
1705 if line
[-4:].upper() == '.INF':
1706 if mCurrentInfFile
!= '':
1707 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1708 mCurrentSourceFileList
= []
1709 mCurrentInfFile
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
))
1710 EotGlobalData
.gOP_INF
.write('%s\n' % mCurrentInfFile
)
1711 if mCurrentInfFile
not in mFileList
:
1712 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1714 # Get all include files from packages
1716 ifl
= open(IncludeFileList
, 'rb')
1718 if not line
.strip():
1720 newline
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1721 for Root
, Dirs
, Files
in os
.walk(str(newline
)):
1723 FullPath
= os
.path
.normpath(os
.path
.join(Root
, File
))
1724 if FullPath
not in mSourceFileList
and File
[-2:].upper() == '.H':
1725 mSourceFileList
.append(FullPath
)
1726 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % FullPath
)
1727 if FullPath
not in mDecFileList
and File
.upper().find('.DEC') > -1:
1728 mDecFileList
.append(FullPath
)
1730 EotGlobalData
.gSOURCE_FILES
= mSourceFileList
1731 EotGlobalData
.gOP_SOURCE_FILES
.close()
1733 EotGlobalData
.gINF_FILES
= mFileList
1734 EotGlobalData
.gOP_INF
.close()
1736 ## GenerateReport() method
1738 # Generate final HTML report
1740 # @param self: The object pointer
1742 def GenerateReport(self
):
1743 EdkLogger
.quiet("Generating report file ... ")
1744 Rep
= Report(self
.Report
, EotGlobalData
.gFV
, self
.Dispatch
)
1745 Rep
.GenerateReport()
1747 ## LoadMapInfo() method
1749 # Load map files and parse them
1751 # @param self: The object pointer
1753 def LoadMapInfo(self
):
1754 if EotGlobalData
.gMAP_FILE
!= []:
1755 EdkLogger
.quiet("Parsing Map file ... ")
1756 EotGlobalData
.gMap
= ParseMapFile(EotGlobalData
.gMAP_FILE
)
1758 ## LoadFvInfo() method
1760 # Load FV binary files and parse them
1762 # @param self: The object pointer
1764 def LoadFvInfo(self
):
1765 EdkLogger
.quiet("Parsing FV file ... ")
1766 EotGlobalData
.gFV
= MultipleFv(EotGlobalData
.gFV_FILE
)
1767 EotGlobalData
.gFV
.Dispatch(EotGlobalData
.gDb
)
1769 for Protocol
in EotGlobalData
.gProtocolList
:
1770 EotGlobalData
.gOP_UN_MATCHED_IN_LIBRARY_CALLING
.write('%s\n' %Protocol
)
1772 ## GenerateReportDatabase() method
1774 # Generate data for the information needed by report
1775 # 1. Update name, macro and value of all found PPI/PROTOCOL GUID
1776 # 2. Install hard coded PPI/PROTOCOL
1778 # @param self: The object pointer
1780 def GenerateReportDatabase(self
):
1781 EdkLogger
.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")
1783 # Update Protocol/Ppi Guid
1784 SqlCommand
= """select DISTINCT GuidName from Report"""
1785 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1786 for Record
in RecordSet
:
1787 GuidName
= Record
[0]
1792 # Find guid value defined in Dec file
1793 if GuidName
in EotGlobalData
.gGuidDict
:
1794 GuidValue
= EotGlobalData
.gGuidDict
[GuidName
]
1795 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1796 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1799 # Search defined Macros for guid name
1800 SqlCommand
="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName
1801 GuidMacroSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1802 # Ignore NULL result
1803 if not GuidMacroSet
:
1805 GuidMacro
= GuidMacroSet
[0][0].strip()
1808 # Find Guid value of Guid Macro
1809 SqlCommand
="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro
, MODEL_IDENTIFIER_MACRO_DEFINE
)
1810 GuidValueSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1811 if GuidValueSet
!= []:
1812 GuidValue
= GuidValueSet
[0][0]
1813 GuidValue
= GuidValue
[GuidValue
.find(GuidMacro
) + len(GuidMacro
) :]
1814 GuidValue
= GuidValue
.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()
1815 GuidValue
= GuidStructureStringToGuidString(GuidValue
)
1816 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1817 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1820 # Update Hard Coded Ppi/Protocol
1821 SqlCommand
= """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""
1822 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1823 for Record
in RecordSet
:
1824 if Record
[1] == 'Ppi':
1825 EotGlobalData
.gPpiList
[Record
[0].lower()] = -2
1826 if Record
[1] == 'Protocol':
1827 EotGlobalData
.gProtocolList
[Record
[0].lower()] = -2
1829 ## GenerateQueryTable() method
1831 # Generate two tables improve query performance
1833 # @param self: The object pointer
1835 def GenerateQueryTable(self
):
1836 EdkLogger
.quiet("Generating temp query table for analysis ... ")
1837 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1838 SqlCommand
= """insert into Query (Name, Modifier, Value, Model)
1839 select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \
1840 % (Identifier
[0], MODEL_IDENTIFIER_VARIABLE
, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION
)
1841 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1842 SqlCommand
= """insert into Query2 (Name, Modifier, Value, Model)
1843 select Name, Modifier, Value, Model from %s where Model = %s""" \
1844 % (Identifier
[0], MODEL_IDENTIFIER_MACRO_DEFINE
)
1845 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1847 ## ParseExecutionOrder() method
1849 # Get final execution order
1851 # 2. Search all PROTOCOL
1853 # @param self: The object pointer
1855 def ParseExecutionOrder(self
):
1856 EdkLogger
.quiet("Searching Ppi/Protocol ... ")
1857 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1858 ModuleID
, ModuleName
, ModuleGuid
, SourceFileID
, SourceFileFullPath
, ItemName
, ItemType
, ItemMode
, GuidName
, GuidMacro
, GuidValue
, BelongsToFunction
, Enabled
= \
1859 -1, '', '', -1, '', '', '', '', '', '', '', '', 0
1861 SourceFileID
= Identifier
[0].replace('Identifier', '')
1862 SourceFileFullPath
= Identifier
[1]
1863 Identifier
= Identifier
[0]
1866 ItemMode
= 'Produced'
1867 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1868 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1869 % (Identifier
, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1870 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1872 ItemMode
= 'Produced'
1873 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1874 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1875 % (Identifier
, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1876 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1878 SearchPpiCallFunction(Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1880 ItemMode
= 'Consumed'
1881 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1882 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1883 % (Identifier
, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1884 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1886 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Ppi', ItemMode
)
1888 ItemMode
= 'Callback'
1889 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1890 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1891 % (Identifier
, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1892 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1895 ItemMode
= 'Produced'
1896 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1897 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1898 % (Identifier
, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1899 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1901 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1902 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1903 % (Identifier
, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1904 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1906 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1908 ItemMode
= 'Consumed'
1909 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1910 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1911 % (Identifier
, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1912 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1914 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1915 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1916 % (Identifier
, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1917 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1919 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1921 ItemMode
= 'Callback'
1922 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1923 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1924 % (Identifier
, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1925 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1927 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1930 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)
1931 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)
1932 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)
1933 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)
1934 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)
1935 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)
1936 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)
1937 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)
1938 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)
1940 EotGlobalData
.gDb
.Conn
.commit()
1943 ## BuildDatabase() methoc
1945 # Build the database for target
1947 # @param self: The object pointer
1949 def BuildDatabase(self
):
1950 # Clean report table
1951 EotGlobalData
.gDb
.TblReport
.Drop()
1952 EotGlobalData
.gDb
.TblReport
.Create()
1956 self
.BuildMetaDataFileDatabase(EotGlobalData
.gINF_FILES
)
1957 EdkLogger
.quiet("Building database for source code ...")
1958 c
.CreateCCodeDB(EotGlobalData
.gSOURCE_FILES
)
1959 EdkLogger
.quiet("Building database for source code done!")
1961 EotGlobalData
.gIdentifierTableList
= GetTableList((MODEL_FILE_C
, MODEL_FILE_H
), 'Identifier', EotGlobalData
.gDb
)
1963 ## BuildMetaDataFileDatabase() method
1965 # Build the database for meta data files
1967 # @param self: The object pointer
1968 # @param Inf_Files: A list for all INF files
1970 def BuildMetaDataFileDatabase(self
, Inf_Files
):
1971 EdkLogger
.quiet("Building database for meta data files ...")
1972 for InfFile
in Inf_Files
:
1973 EdkLogger
.quiet("Parsing %s ..." % str(InfFile
))
1974 EdkInfParser(InfFile
, EotGlobalData
.gDb
, Inf_Files
[InfFile
], '')
1976 EotGlobalData
.gDb
.Conn
.commit()
1977 EdkLogger
.quiet("Building database for meta data files done!")
1979 ## ParseOption() method
1981 # Parse command line options
1983 # @param self: The object pointer
1985 def ParseOption(self
):
1986 (Options
, Target
) = self
.EotOptionParser()
1989 self
.SetLogLevel(Options
)
1991 if Options
.FvFileList
:
1992 self
.FvFileList
= Options
.FvFileList
1994 if Options
.MapFileList
:
1995 self
.MapFileList
= Options
.FvMapFileList
1997 if Options
.SourceFileList
:
1998 self
.SourceFileList
= Options
.SourceFileList
2000 if Options
.IncludeDirList
:
2001 self
.IncludeDirList
= Options
.IncludeDirList
2003 if Options
.DecFileList
:
2004 self
.DecFileList
= Options
.DecFileList
2006 if Options
.GuidList
:
2007 self
.GuidList
= Options
.GuidList
2010 self
.LogFile
= Options
.LogFile
2012 if Options
.keepdatabase
:
2015 ## SetLogLevel() method
2017 # Set current log level of the tool based on args
2019 # @param self: The object pointer
2020 # @param Option: The option list including log level setting
2022 def SetLogLevel(self
, Option
):
2023 if Option
.verbose
is not None:
2024 EdkLogger
.SetLevel(EdkLogger
.VERBOSE
)
2025 elif Option
.quiet
is not None:
2026 EdkLogger
.SetLevel(EdkLogger
.QUIET
)
2027 elif Option
.debug
is not None:
2028 EdkLogger
.SetLevel(Option
.debug
+ 1)
2030 EdkLogger
.SetLevel(EdkLogger
.INFO
)
2032 ## EotOptionParser() method
2034 # Using standard Python module optparse to parse command line option of this tool.
2036 # @param self: The object pointer
2038 # @retval Opt A optparse.Values object containing the parsed options
2039 # @retval Args Target of build command
2041 def EotOptionParser(self
):
2042 Parser
= OptionParser(description
= self
.Copyright
, version
= self
.Version
, prog
= "Eot.exe", usage
= "%prog [options]")
2043 Parser
.add_option("-m", "--makefile filename", action
="store", type="string", dest
='MakeFile',
2044 help="Specify a makefile for the platform.")
2045 Parser
.add_option("-c", "--dsc filename", action
="store", type="string", dest
="DscFile",
2046 help="Specify a dsc file for the platform.")
2047 Parser
.add_option("-f", "--fv filename", action
="store", type="string", dest
="FvFileList",
2048 help="Specify fv file list, quoted by \"\".")
2049 Parser
.add_option("-a", "--map filename", action
="store", type="string", dest
="MapFileList",
2050 help="Specify map file list, quoted by \"\".")
2051 Parser
.add_option("-s", "--source files", action
="store", type="string", dest
="SourceFileList",
2052 help="Specify source file list by a file")
2053 Parser
.add_option("-i", "--include dirs", action
="store", type="string", dest
="IncludeDirList",
2054 help="Specify include dir list by a file")
2055 Parser
.add_option("-e", "--dec files", action
="store", type="string", dest
="DecFileList",
2056 help="Specify dec file list by a file")
2057 Parser
.add_option("-g", "--guid list", action
="store", type="string", dest
="GuidList",
2058 help="Specify guid file list by a file")
2059 Parser
.add_option("-l", "--log filename", action
="store", type="string", dest
="LogFile",
2060 help="Specify real execution log file")
2062 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.")
2064 Parser
.add_option("-q", "--quiet", action
="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
2065 Parser
.add_option("-v", "--verbose", action
="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
2066 "including library instances selected, final dependency expression, "\
2067 "and warning messages, etc.")
2068 Parser
.add_option("-d", "--debug", action
="store", type="int", help="Enable debug messages at specified level.")
2070 (Opt
, Args
)=Parser
.parse_args()
2076 # This acts like the main() function for the script, unless it is 'import'ed into another
2079 if __name__
== '__main__':
2080 # Initialize log system
2081 EdkLogger
.Initialize()
2082 EdkLogger
.IsRaiseError
= False
2083 EdkLogger
.quiet(time
.strftime("%H:%M:%S, %b.%d %Y ", time
.localtime()) + "[00:00]" + "\n")
2085 StartTime
= time
.clock()
2087 FinishTime
= time
.clock()
2089 BuildDuration
= time
.strftime("%M:%S", time
.gmtime(int(round(FinishTime
- StartTime
))))
2090 EdkLogger
.quiet("\n%s [%s]" % (time
.strftime("%H:%M:%S, %b.%d %Y", time
.localtime()), BuildDuration
))