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 import Common
.LongFilePathOs
as os
, time
, glob
18 import Common
.EdkLogger
as EdkLogger
20 from optparse
import OptionParser
21 from Common
.String
import NormPath
22 from Common
import BuildToolError
23 from Common
.Misc
import GuidStructureStringToGuidString
, sdict
24 from InfParserLite
import *
27 from array
import array
28 from Report
import Report
29 from Common
.BuildVersion
import gBUILD_VERSION
30 from Parser
import ConvertGuid
31 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
37 gGuidStringFormat
= "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"
38 gPeiAprioriFileNameGuid
= '1b45cc0a-156a-428a-af62-49864da0e6e6'
39 gAprioriGuid
= 'fc510ee7-ffdc-11d4-bd41-0080c73c8881'
43 _HEADER_
= struct
.Struct("")
44 _HEADER_SIZE_
= _HEADER_
.size
46 def __new__(cls
, *args
, **kwargs
):
47 return array
.__new
__(cls
, 'B')
49 def __init__(self
, ID
=None):
51 self
._ID
_ = str(uuid
.uuid1()).upper()
58 self
._SubImages
= sdict() # {offset: Image()}
60 array
.__init
__(self
, 'B')
66 Len
= array
.__len
__(self
)
67 for Offset
in self
._SubImages
:
68 Len
+= len(self
._SubImages
[Offset
])
72 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
75 def _Pack(self
, PadByte
=0xFF):
76 raise NotImplementedError
78 def frombuffer(self
, Buffer
, Offset
=0, Size
=None):
81 # we may need the Size information in advance if it's given
83 self
._LEN
_ = self
._Unpack
()
88 def GetField(self
, FieldStruct
, Offset
=0):
89 return FieldStruct
.unpack_from(self
, Offset
)
91 def SetField(self
, FieldStruct
, Offset
, *args
):
92 # check if there's enough space
93 Size
= FieldStruct
.size
95 self
.extend([0] * (Size
- len(self
)))
96 FieldStruct
.pack_into(self
, Offset
, *args
)
98 def _SetData(self
, Data
):
99 if len(self
) < self
._HEADER
_SIZE
_:
100 self
.extend([0] * (self
._HEADER
_SIZE
_ - len(self
)))
102 del self
[self
._HEADER
_SIZE
_:]
106 if len(self
) > self
._HEADER
_SIZE
_:
107 return self
[self
._HEADER
_SIZE
_:]
110 Data
= property(_GetData
, _SetData
)
112 ## CompressedImage() class
114 # A class for Compressed Image
116 class CompressedImage(Image
):
117 # UncompressedLength = 4-byte
118 # CompressionType = 1-byte
119 _HEADER_
= struct
.Struct("1I 1B")
120 _HEADER_SIZE_
= _HEADER_
.size
122 _ORIG_SIZE_
= struct
.Struct("1I")
123 _CMPRS_TYPE_
= struct
.Struct("4x 1B")
125 def __init__(m
, CompressedData
=None, CompressionType
=None, UncompressedLength
=None):
127 if UncompressedLength
is not None:
128 m
.UncompressedLength
= UncompressedLength
129 if CompressionType
is not None:
130 m
.CompressionType
= CompressionType
131 if CompressedData
is not None:
132 m
.Data
= CompressedData
136 S
= "algorithm=%s uncompressed=%x" % (m
.CompressionType
, m
.UncompressedLength
)
137 for Sec
in m
.Sections
:
142 def _SetOriginalSize(m
, Size
):
143 m
.SetField(m
._ORIG
_SIZE
_, 0, Size
)
145 def _GetOriginalSize(m
):
146 return m
.GetField(m
._ORIG
_SIZE
_)[0]
148 def _SetCompressionType(m
, Type
):
149 m
.SetField(m
._CMPRS
_TYPE
_, 0, Type
)
151 def _GetCompressionType(m
):
152 return m
.GetField(m
._CMPRS
_TYPE
_)[0]
157 TmpData
= EfiCompressor
.FrameworkDecompress(
159 len(m
) - m
._HEADER
_SIZE
_
162 DecData
.fromstring(TmpData
)
165 TmpData
= EfiCompressor
.UefiDecompress(
167 len(m
) - m
._HEADER
_SIZE
_
170 DecData
.fromstring(TmpData
)
174 while Offset
< len(DecData
):
177 Sec
.frombuffer(DecData
, Offset
)
179 # the section is aligned to 4-byte boundary
182 SectionList
.append(Sec
)
185 UncompressedLength
= property(_GetOriginalSize
, _SetOriginalSize
)
186 CompressionType
= property(_GetCompressionType
, _SetCompressionType
)
187 Sections
= property(_GetSections
)
194 _HEADER_
= struct
.Struct("")
204 # keep header in this Image object
206 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._LEN
_])
210 return codecs
.utf_16_decode(m
[0:-2].tostring())[0]
212 String
= property(_GetUiString
)
219 _HEADER_
= struct
.Struct("")
222 _GUID_
= struct
.Struct("1I2H8B")
223 _OPCODE_
= struct
.Struct("1B")
239 -1 : _OPCODE_
, # first one in depex must be an opcdoe
240 0x00 : _GUID_
, #"BEFORE",
241 0x01 : _GUID_
, #"AFTER",
242 0x02 : _GUID_
, #"PUSH",
243 0x03 : _OPCODE_
, #"AND",
244 0x04 : _OPCODE_
, #"OR",
245 0x05 : _OPCODE_
, #"NOT",
246 0x06 : _OPCODE_
, #"TRUE",
247 0x07 : _OPCODE_
, #"FALSE",
249 0x09 : _OPCODE_
, #"SOR"
259 Indention
= ' ' * gIndention
261 for T
in m
.Expression
:
262 if T
in m
._OPCODE
_STRING
_:
263 S
+= Indention
+ m
._OPCODE
_STRING
_[T
]
264 if T
not in [0x00, 0x01, 0x02]:
267 S
+= ' ' + gGuidStringFormat
% T
+ '\n'
272 # keep header in this Image object
274 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._LEN
_])
277 def _GetExpression(m
):
278 if m
._ExprList
== []:
280 CurrentData
= m
._OPCODE
_
281 while Offset
< len(m
):
282 Token
= CurrentData
.unpack_from(m
, Offset
)
283 Offset
+= CurrentData
.size
286 if Token
in m
._NEXT
_:
287 CurrentData
= m
._NEXT
_[Token
]
289 CurrentData
= m
._GUID
_
291 CurrentData
= m
._OPCODE
_
292 m
._ExprList
.append(Token
)
293 if CurrentData
is None:
297 Expression
= property(_GetExpression
)
299 ## FirmwareVolume() class
301 # A class for Firmware Volume
303 class FirmwareVolume(Image
):
304 # Read FvLength, Attributes, HeaderLength, Checksum
305 _HEADER_
= struct
.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")
306 _HEADER_SIZE_
= _HEADER_
.size
308 _FfsGuid
= "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
310 _GUID_
= struct
.Struct("16x 1I2H8B")
311 _LENGTH_
= struct
.Struct("16x 16x 1Q")
312 _SIG_
= struct
.Struct("16x 16x 8x 1I")
313 _ATTR_
= struct
.Struct("16x 16x 8x 4x 1I")
314 _HLEN_
= struct
.Struct("16x 16x 8x 4x 4x 1H")
315 _CHECKSUM_
= struct
.Struct("16x 16x 8x 4x 4x 2x 1H")
317 def __init__(self
, Name
=''):
320 self
.FfsDict
= sdict()
321 self
.OrderedFfsDict
= sdict()
322 self
.UnDispatchedFfsDict
= sdict()
323 self
.ProtocolList
= sdict()
325 def CheckArchProtocol(self
):
326 for Item
in EotGlobalData
.gArchProtocolGuids
:
327 if Item
.lower() not in EotGlobalData
.gProtocolList
:
333 def ParseDepex(self
, Depex
, Type
):
336 List
= EotGlobalData
.gPpiList
337 if Type
== 'Protocol':
338 List
= EotGlobalData
.gProtocolList
344 for Index
in range(0, len(Depex
.Expression
)):
345 Item
= Depex
.Expression
[Index
]
348 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
349 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
350 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
353 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
354 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
355 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
358 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
359 if Guid
.lower() in List
:
360 DepexStack
.append(True)
361 DepexList
.append(Guid
)
363 DepexStack
.append(False)
364 DepexList
.append(Guid
)
366 elif Item
== 0x03 or Item
== 0x04:
367 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
368 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
370 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
371 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
373 DepexStack
.append(True)
374 DepexList
.append('TRUE')
375 DepexString
= DepexString
+ 'TRUE' + ' '
377 DepexStack
.append(False)
378 DepexList
.append('False')
379 DepexString
= DepexString
+ 'FALSE' + ' '
381 if Index
!= len(Depex
.Expression
) - 1:
382 CouldBeLoaded
= False
384 CouldBeLoaded
= DepexStack
.pop()
386 CouldBeLoaded
= False
388 DepexString
= DepexList
[0].strip()
389 return (CouldBeLoaded
, DepexString
, FileDepex
)
391 def Dispatch(self
, Db
= None):
394 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
395 # Find PeiCore, DexCore, PeiPriori, DxePriori first
396 FfsSecCoreGuid
= None
397 FfsPeiCoreGuid
= None
398 FfsDxeCoreGuid
= None
399 FfsPeiPrioriGuid
= None
400 FfsDxePrioriGuid
= None
401 for FfsID
in self
.UnDispatchedFfsDict
:
402 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
404 FfsSecCoreGuid
= FfsID
407 FfsPeiCoreGuid
= FfsID
410 FfsDxeCoreGuid
= FfsID
412 if Ffs
.Guid
.lower() == gPeiAprioriFileNameGuid
:
413 FfsPeiPrioriGuid
= FfsID
415 if Ffs
.Guid
.lower() == gAprioriGuid
:
416 FfsDxePrioriGuid
= FfsID
419 # Parse SEC_CORE first
420 if FfsSecCoreGuid
is not None:
421 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
422 self
.LoadPpi(Db
, FfsSecCoreGuid
)
425 if FfsPeiCoreGuid
is not None:
426 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
427 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
428 if FfsPeiPrioriGuid
is not None:
429 # Load PEIM described in priori file
430 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
431 if len(FfsPeiPriori
.Sections
) == 1:
432 Section
= FfsPeiPriori
.Sections
.popitem()[1]
433 if Section
.Type
== 0x19:
434 GuidStruct
= struct
.Struct('1I2H8B')
436 while len(Section
) > Start
:
437 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
438 GuidString
= gGuidStringFormat
% Guid
440 if GuidString
in self
.UnDispatchedFfsDict
:
441 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
442 self
.LoadPpi(Db
, GuidString
)
447 if FfsDxeCoreGuid
is not None:
448 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
449 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
450 if FfsDxePrioriGuid
is not None:
451 # Load PEIM described in priori file
452 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
453 if len(FfsDxePriori
.Sections
) == 1:
454 Section
= FfsDxePriori
.Sections
.popitem()[1]
455 if Section
.Type
== 0x19:
456 GuidStruct
= struct
.Struct('1I2H8B')
458 while len(Section
) > Start
:
459 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
460 GuidString
= gGuidStringFormat
% Guid
462 if GuidString
in self
.UnDispatchedFfsDict
:
463 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
464 self
.LoadProtocol(Db
, GuidString
)
468 def LoadProtocol(self
, Db
, ModuleGuid
):
469 SqlCommand
= """select GuidValue from Report
470 where SourceFileFullPath in
471 (select Value1 from Inf where BelongsToFile =
472 (select BelongsToFile from Inf
473 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
475 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
476 % (ModuleGuid
, 5001, 3007)
477 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
478 for Record
in RecordSet
:
479 SqlCommand
= """select Value2 from Inf where BelongsToFile =
480 (select DISTINCT BelongsToFile from Inf
482 (select SourceFileFullPath from Report
483 where GuidValue like '%s' and ItemMode = 'Callback'))
484 and Value1 = 'FILE_GUID'""" % Record
[0]
485 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
486 if CallBackSet
!= []:
487 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
489 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
491 def LoadPpi(self
, Db
, ModuleGuid
):
492 SqlCommand
= """select GuidValue from Report
493 where SourceFileFullPath in
494 (select Value1 from Inf where BelongsToFile =
495 (select BelongsToFile from Inf
496 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
498 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
499 % (ModuleGuid
, 5001, 3007)
500 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
501 for Record
in RecordSet
:
502 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
504 def DisPatchDxe(self
, Db
):
506 ScheduleList
= sdict()
507 for FfsID
in self
.UnDispatchedFfsDict
:
508 CouldBeLoaded
= False
511 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
515 for Section
in Ffs
.Sections
.values():
517 if Section
.Type
== 0x13:
519 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
521 if Section
.Type
== 0x01:
522 CompressSections
= Section
._SubImages
[4]
523 for CompressSection
in CompressSections
.Sections
:
524 if CompressSection
.Type
== 0x13:
526 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
528 if CompressSection
.Type
== 0x02:
529 NewSections
= CompressSection
._SubImages
[4]
530 for NewSection
in NewSections
.Sections
:
531 if NewSection
.Type
== 0x13:
533 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
538 CouldBeLoaded
= self
.CheckArchProtocol()
545 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
546 NewFfs
.Depex
= DepexString
547 if FileDepex
is not None:
548 ScheduleList
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
550 ScheduleList
[FfsID
] = NewFfs
552 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
554 for FfsID
in ScheduleList
:
555 NewFfs
= ScheduleList
.pop(FfsID
)
557 self
.OrderedFfsDict
[FfsID
] = NewFfs
558 self
.LoadProtocol(Db
, FfsID
)
560 SqlCommand
= """select Value2 from Inf
561 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
562 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
563 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
565 FfsName
= RecordSet
[0][0]
570 def DisPatchPei(self
, Db
):
572 for FfsID
in self
.UnDispatchedFfsDict
:
576 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
577 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
579 for Section
in Ffs
.Sections
.values():
580 if Section
.Type
== 0x1B:
581 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
584 if Section
.Type
== 0x01:
585 CompressSections
= Section
._SubImages
[4]
586 for CompressSection
in CompressSections
.Sections
:
587 if CompressSection
.Type
== 0x1B:
588 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
590 if CompressSection
.Type
== 0x02:
591 NewSections
= CompressSection
._SubImages
[4]
592 for NewSection
in NewSections
.Sections
:
593 if NewSection
.Type
== 0x1B:
594 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
600 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
601 NewFfs
.Depex
= DepexString
602 self
.OrderedFfsDict
[FfsID
] = NewFfs
603 self
.LoadPpi(Db
, FfsID
)
605 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
614 FvInfo
= '\n' + ' ' * gIndention
615 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
616 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
618 return FvInfo
+ FfsInfo
621 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
623 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_+Size
])
627 FfsStartAddress
= self
.HeaderSize
629 while FfsStartAddress
< EndOfFv
:
631 FfsObj
.frombuffer(self
, FfsStartAddress
)
633 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
634 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
635 if LastFfsObj
is not None:
636 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
638 if FfsId
in self
.FfsDict
:
639 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
640 ExtraData
="\t%s @ %s\n\t%s @ %s" \
641 % (FfsObj
.Guid
, FfsObj
.Offset
,
642 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
643 self
.FfsDict
[FfsId
] = FfsObj
644 if LastFfsObj
is not None:
645 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
647 FfsStartAddress
+= len(FfsObj
)
649 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
650 # The next FFS must be at the latest next 8-byte aligned address
652 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
655 def _GetAttributes(self
):
656 return self
.GetField(self
._ATTR
_, 0)[0]
659 return self
.GetField(self
._LENGTH
_, 0)[0]
661 def _GetChecksum(self
):
662 return self
.GetField(self
._CHECKSUM
_, 0)[0]
664 def _GetHeaderLength(self
):
665 return self
.GetField(self
._HLEN
_, 0)[0]
667 def _GetFileSystemGuid(self
):
668 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
670 Attributes
= property(_GetAttributes
)
671 Size
= property(_GetSize
)
672 Checksum
= property(_GetChecksum
)
673 HeaderSize
= property(_GetHeaderLength
)
674 FileSystemGuid
= property(_GetFileSystemGuid
)
676 ## GuidDefinedImage() class
678 # A class for GUID Defined Image
680 class GuidDefinedImage(Image
):
681 _HEADER_
= struct
.Struct("1I2H8B 1H 1H")
682 _HEADER_SIZE_
= _HEADER_
.size
684 _GUID_
= struct
.Struct("1I2H8B")
685 _DATA_OFFSET_
= struct
.Struct("16x 1H")
686 _ATTR_
= struct
.Struct("18x 1H")
688 CRC32_GUID
= "FC1BCDB0-7D31-49AA-936A-A4600D9DD083"
689 TIANO_COMPRESS_GUID
= 'A31280AD-481E-41B6-95E8-127F4C984779'
690 LZMA_COMPRESS_GUID
= 'EE4E5898-3914-4259-9D6E-DC7BD79403CF'
692 def __init__(m
, SectionDefinitionGuid
=None, DataOffset
=None, Attributes
=None, Data
=None):
694 if SectionDefinitionGuid
is not None:
695 m
.SectionDefinitionGuid
= SectionDefinitionGuid
696 if DataOffset
is not None:
697 m
.DataOffset
= DataOffset
698 if Attributes
is not None:
699 m
.Attributes
= Attributes
704 S
= "guid=%s" % (gGuidStringFormat
% m
.SectionDefinitionGuid
)
705 for Sec
in m
.Sections
:
710 # keep header in this Image object
712 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._LEN
_])
715 def _SetAttribute(m
, Attribute
):
716 m
.SetField(m
._ATTR
_, 0, Attribute
)
718 def _GetAttribute(m
):
719 return m
.GetField(m
._ATTR
_)[0]
721 def _SetGuid(m
, Guid
):
722 m
.SetField(m
._GUID
_, 0, Guid
)
725 return m
.GetField(m
._GUID
_)
727 def _SetDataOffset(m
, Offset
):
728 m
.SetField(m
._DATA
_OFFSET
_, 0, Offset
)
730 def _GetDataOffset(m
):
731 return m
.GetField(m
._DATA
_OFFSET
_)[0]
735 Guid
= gGuidStringFormat
% m
.SectionDefinitionGuid
736 if Guid
== m
.CRC32_GUID
:
737 # skip the CRC32 value, we don't do CRC32 verification here
738 Offset
= m
.DataOffset
- 4
739 while Offset
< len(m
):
742 Sec
.frombuffer(m
, Offset
)
744 # the section is aligned to 4-byte boundary
745 Offset
= (Offset
+ 3) & (~
3)
748 SectionList
.append(Sec
)
749 elif Guid
== m
.TIANO_COMPRESS_GUID
:
753 Offset
= m
.DataOffset
- 4
754 TmpData
= EfiCompressor
.FrameworkDecompress(m
[Offset
:], len(m
)-Offset
)
756 DecData
.fromstring(TmpData
)
758 while Offset
< len(DecData
):
761 Sec
.frombuffer(DecData
, Offset
)
763 # the section is aligned to 4-byte boundary
764 Offset
= (Offset
+ 3) & (~
3)
767 SectionList
.append(Sec
)
770 elif Guid
== m
.LZMA_COMPRESS_GUID
:
772 import LzmaCompressor
774 Offset
= m
.DataOffset
- 4
775 TmpData
= LzmaCompressor
.LzmaDecompress(m
[Offset
:], len(m
)-Offset
)
777 DecData
.fromstring(TmpData
)
779 while Offset
< len(DecData
):
782 Sec
.frombuffer(DecData
, Offset
)
784 # the section is aligned to 4-byte boundary
785 Offset
= (Offset
+ 3) & (~
3)
788 SectionList
.append(Sec
)
794 Attributes
= property(_GetAttribute
, _SetAttribute
)
795 SectionDefinitionGuid
= property(_GetGuid
, _SetGuid
)
796 DataOffset
= property(_GetDataOffset
, _SetDataOffset
)
797 Sections
= property(_GetSections
)
801 # A class for Section
803 class Section(Image
):
806 0x01 : "COMPRESSION",
807 0x02 : "GUID_DEFINED",
813 0x15 : "USER_INTERFACE",
814 0x16 : "COMPATIBILITY16",
815 0x17 : "FIRMWARE_VOLUME_IMAGE",
816 0x18 : "FREEFORM_SUBTYPE_GUID",
821 _SectionSubImages
= {
822 0x01 : CompressedImage
,
823 0x02 : GuidDefinedImage
,
824 0x17 : FirmwareVolume
,
832 _HEADER_
= struct
.Struct("3B 1B")
833 _HEADER_SIZE_
= _HEADER_
.size
836 # _FREE_FORM_SUBTYPE_GUID_HEADER_ = struct.Struct("1I2H8B")
838 _SIZE_
= struct
.Struct("3B")
839 _TYPE_
= struct
.Struct("3x 1B")
841 def __init__(m
, Type
=None, Size
=None):
852 SectionInfo
= ' ' * gIndention
853 if m
.Type
in m
._TypeName
:
854 SectionInfo
+= "[SECTION:%s] offset=%x size=%x" % (m
._TypeName
[m
.Type
], m
._OFF
_, m
.Size
)
856 SectionInfo
+= "[SECTION:%x<unknown>] offset=%x size=%x " % (m
.Type
, m
._OFF
_, m
.Size
)
857 for Offset
in m
._SubImages
:
858 SectionInfo
+= ", " + str(m
._SubImages
[Offset
])
864 Type
, = m
._TYPE
_.unpack_from(m
._BUF
_, m
._OFF
_)
865 Size1
, Size2
, Size3
= m
._SIZE
_.unpack_from(m
._BUF
_, m
._OFF
_)
866 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
868 if Type
not in m
._SectionSubImages
:
869 # no need to extract sub-image, keep all in this Image object
870 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + Size
])
872 # keep header in this Image object
873 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._HEADER
_SIZE
_])
875 # use new Image object to represent payload, which may be another kind
876 # of image such as PE32
878 PayloadOffset
= m
._HEADER
_SIZE
_
879 PayloadLen
= m
.Size
- m
._HEADER
_SIZE
_
880 Payload
= m
._SectionSubImages
[m
.Type
]()
881 Payload
.frombuffer(m
._BUF
_, m
._OFF
_ + m
._HEADER
_SIZE
_, PayloadLen
)
882 m
._SubImages
[PayloadOffset
] = Payload
886 def _SetSize(m
, Size
):
888 Size2
= (Size
& 0xFF00) >> 8
889 Size3
= (Size
& 0xFF0000) >> 16
890 m
.SetField(m
._SIZE
_, 0, Size1
, Size2
, Size3
)
893 Size1
, Size2
, Size3
= m
.GetField(m
._SIZE
_)
894 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
896 def _SetType(m
, Type
):
897 m
.SetField(m
._TYPE
_, 0, Type
)
900 return m
.GetField(m
._TYPE
_)[0]
902 def _GetAlignment(m
):
905 def _SetAlignment(m
, Alignment
):
906 m
._Alignment
= Alignment
907 AlignmentMask
= Alignment
- 1
908 # section alignment is actually for payload, so we need to add header size
909 PayloadOffset
= m
._OFF
_ + m
._HEADER
_SIZE
_
910 if (PayloadOffset
& (~AlignmentMask
)) == 0:
912 NewOffset
= (PayloadOffset
+ AlignmentMask
) & (~AlignmentMask
)
913 while (NewOffset
- PayloadOffset
) < m
._HEADER
_SIZE
_:
914 NewOffset
+= m
._Alignment
919 for Offset
in m
._SubImages
:
920 m
._SubImages
[Offset
].tofile(f
)
922 Type
= property(_GetType
, _SetType
)
923 Size
= property(_GetSize
, _SetSize
)
924 Alignment
= property(_GetAlignment
, _SetAlignment
)
928 # A class for Ffs Section
931 _FfsFormat
= "24B%(payload_size)sB"
932 # skip IntegrityCheck
933 _HEADER_
= struct
.Struct("1I2H8B 2x 1B 1B 3B 1B")
934 _HEADER_SIZE_
= _HEADER_
.size
936 _NAME_
= struct
.Struct("1I2H8B")
937 _INT_CHECK_
= struct
.Struct("16x 1H")
938 _TYPE_
= struct
.Struct("18x 1B")
939 _ATTR_
= struct
.Struct("19x 1B")
940 _SIZE_
= struct
.Struct("20x 3B")
941 _STATE_
= struct
.Struct("23x 1B")
943 VTF_GUID
= "1BA0062E-C779-4582-8566-336AE8F78F09"
945 FFS_ATTRIB_FIXED
= 0x04
946 FFS_ATTRIB_DATA_ALIGNMENT
= 0x38
947 FFS_ATTRIB_CHECKSUM
= 0x40
953 0x03 : "SECURITY_CORE",
958 0x08 : "COMBINED_PEIM_DRIVER",
959 0x09 : "APPLICATION",
961 0x0B : "FIRMWARE_VOLUME_IMAGE",
962 0x0C : "COMBINED_SMM_DXE",
964 0x0E : "MM_STANDALONE",
965 0x0F : "MM_CORE_STANDALONE",
979 self
.Sections
= sdict()
987 Indention
= ' ' * gIndention
989 FfsInfo
+= "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \
990 (Ffs
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
, self
.Guid
, self
.FreeSpace
, self
.Alignment
)
991 SectionInfo
= '\n'.join([str(self
.Sections
[Offset
]) for Offset
in self
.Sections
])
993 return FfsInfo
+ SectionInfo
+ "\n"
1002 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
1003 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
1005 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
1007 # Pad FFS may use the same GUID. We need to avoid it.
1008 if self
.Type
== 0xf0:
1009 self
.__ID
__ = str(uuid
.uuid1()).upper()
1011 self
.__ID
__ = self
.Guid
1013 # Traverse the SECTION. RAW and PAD do not have sections
1014 if self
.Type
not in [0xf0, 0x01] and Size
> 0 and Size
< 0xFFFFFF:
1016 SectionStartAddress
= self
._HEADER
_SIZE
_
1017 while SectionStartAddress
< EndOfFfs
:
1018 SectionObj
= Section()
1019 SectionObj
.frombuffer(self
, SectionStartAddress
)
1020 #f = open(repr(SectionObj), 'wb')
1021 #SectionObj.Size = 0
1022 #SectionObj.tofile(f)
1024 self
.Sections
[SectionStartAddress
] = SectionObj
1025 SectionStartAddress
+= len(SectionObj
)
1026 SectionStartAddress
= (SectionStartAddress
+ 3) & (~
3)
1031 def SetFreeSpace(self
, Size
):
1032 self
.FreeSpace
= Size
1035 return gGuidStringFormat
% self
.Name
1037 def _SetName(self
, Value
):
1038 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1039 self
.SetField(self
._NAME
_, 0, Value
)
1042 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1043 return self
.GetField(self
._NAME
_)
1045 def _SetSize(m
, Size
):
1047 Size2
= (Size
& 0xFF00) >> 8
1048 Size3
= (Size
& 0xFF0000) >> 16
1049 m
.SetField(m
._SIZE
_, 0, Size1
, Size2
, Size3
)
1052 Size1
, Size2
, Size3
= m
.GetField(m
._SIZE
_)
1053 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
1055 def _SetType(m
, Type
):
1056 m
.SetField(m
._TYPE
_, 0, Type
)
1059 return m
.GetField(m
._TYPE
_)[0]
1061 def _SetAttributes(self
, Value
):
1062 self
.SetField(m
._ATTR
_, 0, Value
)
1064 def _GetAttributes(self
):
1065 return self
.GetField(self
._ATTR
_)[0]
1067 def _GetFixed(self
):
1068 if (self
.Attributes
& self
.FFS_ATTRIB_FIXED
) != 0:
1072 def _GetCheckSum(self
):
1073 if (self
.Attributes
& self
.FFS_ATTRIB_CHECKSUM
) != 0:
1077 def _GetAlignment(self
):
1078 return (self
.Attributes
& self
.FFS_ATTRIB_DATA_ALIGNMENT
) >> 3
1080 def _SetState(self
, Value
):
1081 self
.SetField(m
._STATE
_, 0, Value
)
1083 def _GetState(self
):
1084 return self
.GetField(m
._STATE
_)[0]
1086 Name
= property(_GetName
, _SetName
)
1087 Guid
= property(_GetGuid
)
1088 Type
= property(_GetType
, _SetType
)
1089 Size
= property(_GetSize
, _SetSize
)
1090 Attributes
= property(_GetAttributes
, _SetAttributes
)
1091 Fixed
= property(_GetFixed
)
1092 Checksum
= property(_GetCheckSum
)
1093 Alignment
= property(_GetAlignment
)
1094 State
= property(_GetState
, _SetState
)
1096 ## FirmwareVolume() class
1098 # A class for Firmware Volume
1100 class FirmwareVolume(Image
):
1101 # Read FvLength, Attributes, HeaderLength, Checksum
1102 _HEADER_
= struct
.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")
1103 _HEADER_SIZE_
= _HEADER_
.size
1105 _FfsGuid
= "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
1107 _GUID_
= struct
.Struct("16x 1I2H8B")
1108 _LENGTH_
= struct
.Struct("16x 16x 1Q")
1109 _SIG_
= struct
.Struct("16x 16x 8x 1I")
1110 _ATTR_
= struct
.Struct("16x 16x 8x 4x 1I")
1111 _HLEN_
= struct
.Struct("16x 16x 8x 4x 4x 1H")
1112 _CHECKSUM_
= struct
.Struct("16x 16x 8x 4x 4x 2x 1H")
1114 def __init__(self
, Name
=''):
1115 Image
.__init
__(self
)
1117 self
.FfsDict
= sdict()
1118 self
.OrderedFfsDict
= sdict()
1119 self
.UnDispatchedFfsDict
= sdict()
1120 self
.ProtocolList
= sdict()
1122 def CheckArchProtocol(self
):
1123 for Item
in EotGlobalData
.gArchProtocolGuids
:
1124 if Item
.lower() not in EotGlobalData
.gProtocolList
:
1130 def ParseDepex(self
, Depex
, Type
):
1133 List
= EotGlobalData
.gPpiList
1134 if Type
== 'Protocol':
1135 List
= EotGlobalData
.gProtocolList
1140 CouldBeLoaded
= True
1141 for Index
in range(0, len(Depex
.Expression
)):
1142 Item
= Depex
.Expression
[Index
]
1145 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1146 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
1147 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
1150 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1151 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
1152 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
1155 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1156 if Guid
.lower() in List
:
1157 DepexStack
.append(True)
1158 DepexList
.append(Guid
)
1160 DepexStack
.append(False)
1161 DepexList
.append(Guid
)
1163 elif Item
== 0x03 or Item
== 0x04:
1164 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
1165 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
1167 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
1168 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
1170 DepexStack
.append(True)
1171 DepexList
.append('TRUE')
1172 DepexString
= DepexString
+ 'TRUE' + ' '
1174 DepexStack
.append(False)
1175 DepexList
.append('False')
1176 DepexString
= DepexString
+ 'FALSE' + ' '
1178 if Index
!= len(Depex
.Expression
) - 1:
1179 CouldBeLoaded
= False
1181 CouldBeLoaded
= DepexStack
.pop()
1183 CouldBeLoaded
= False
1185 DepexString
= DepexList
[0].strip()
1186 return (CouldBeLoaded
, DepexString
, FileDepex
)
1188 def Dispatch(self
, Db
= None):
1191 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
1192 # Find PeiCore, DexCore, PeiPriori, DxePriori first
1193 FfsSecCoreGuid
= None
1194 FfsPeiCoreGuid
= None
1195 FfsDxeCoreGuid
= None
1196 FfsPeiPrioriGuid
= None
1197 FfsDxePrioriGuid
= None
1198 for FfsID
in self
.UnDispatchedFfsDict
:
1199 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1200 if Ffs
.Type
== 0x03:
1201 FfsSecCoreGuid
= FfsID
1203 if Ffs
.Type
== 0x04:
1204 FfsPeiCoreGuid
= FfsID
1206 if Ffs
.Type
== 0x05:
1207 FfsDxeCoreGuid
= FfsID
1209 if Ffs
.Guid
.lower() == gPeiAprioriFileNameGuid
:
1210 FfsPeiPrioriGuid
= FfsID
1212 if Ffs
.Guid
.lower() == gAprioriGuid
:
1213 FfsDxePrioriGuid
= FfsID
1216 # Parse SEC_CORE first
1217 if FfsSecCoreGuid
is not None:
1218 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
1219 self
.LoadPpi(Db
, FfsSecCoreGuid
)
1222 if FfsPeiCoreGuid
is not None:
1223 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
1224 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
1225 if FfsPeiPrioriGuid
is not None:
1226 # Load PEIM described in priori file
1227 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
1228 if len(FfsPeiPriori
.Sections
) == 1:
1229 Section
= FfsPeiPriori
.Sections
.popitem()[1]
1230 if Section
.Type
== 0x19:
1231 GuidStruct
= struct
.Struct('1I2H8B')
1233 while len(Section
) > Start
:
1234 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
1235 GuidString
= gGuidStringFormat
% Guid
1237 if GuidString
in self
.UnDispatchedFfsDict
:
1238 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
1239 self
.LoadPpi(Db
, GuidString
)
1241 self
.DisPatchPei(Db
)
1244 if FfsDxeCoreGuid
is not None:
1245 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
1246 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
1247 if FfsDxePrioriGuid
is not None:
1248 # Load PEIM described in priori file
1249 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
1250 if len(FfsDxePriori
.Sections
) == 1:
1251 Section
= FfsDxePriori
.Sections
.popitem()[1]
1252 if Section
.Type
== 0x19:
1253 GuidStruct
= struct
.Struct('1I2H8B')
1255 while len(Section
) > Start
:
1256 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
1257 GuidString
= gGuidStringFormat
% Guid
1259 if GuidString
in self
.UnDispatchedFfsDict
:
1260 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
1261 self
.LoadProtocol(Db
, GuidString
)
1263 self
.DisPatchDxe(Db
)
1265 def LoadProtocol(self
, Db
, ModuleGuid
):
1266 SqlCommand
= """select GuidValue from Report
1267 where SourceFileFullPath in
1268 (select Value1 from Inf where BelongsToFile =
1269 (select BelongsToFile from Inf
1270 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
1272 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
1273 % (ModuleGuid
, 5001, 3007)
1274 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1275 for Record
in RecordSet
:
1276 SqlCommand
= """select Value2 from Inf where BelongsToFile =
1277 (select DISTINCT BelongsToFile from Inf
1279 (select SourceFileFullPath from Report
1280 where GuidValue like '%s' and ItemMode = 'Callback'))
1281 and Value1 = 'FILE_GUID'""" % Record
[0]
1282 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
1283 if CallBackSet
!= []:
1284 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
1286 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
1288 def LoadPpi(self
, Db
, ModuleGuid
):
1289 SqlCommand
= """select GuidValue from Report
1290 where SourceFileFullPath in
1291 (select Value1 from Inf where BelongsToFile =
1292 (select BelongsToFile from Inf
1293 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
1295 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
1296 % (ModuleGuid
, 5001, 3007)
1297 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1298 for Record
in RecordSet
:
1299 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
1301 def DisPatchDxe(self
, Db
):
1303 ScheduleList
= sdict()
1304 for FfsID
in self
.UnDispatchedFfsDict
:
1305 CouldBeLoaded
= False
1308 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1309 if Ffs
.Type
== 0x07:
1311 IsFoundDepex
= False
1312 for Section
in Ffs
.Sections
.values():
1314 if Section
.Type
== 0x13:
1316 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
1318 if Section
.Type
== 0x01:
1319 CompressSections
= Section
._SubImages
[4]
1320 for CompressSection
in CompressSections
.Sections
:
1321 if CompressSection
.Type
== 0x13:
1323 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
1325 if CompressSection
.Type
== 0x02:
1326 NewSections
= CompressSection
._SubImages
[4]
1327 for NewSection
in NewSections
.Sections
:
1328 if NewSection
.Type
== 0x13:
1330 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
1334 if not IsFoundDepex
:
1335 CouldBeLoaded
= self
.CheckArchProtocol()
1342 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
1343 NewFfs
.Depex
= DepexString
1344 if FileDepex
is not None:
1345 ScheduleList
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
1347 ScheduleList
[FfsID
] = NewFfs
1349 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
1351 for FfsID
in ScheduleList
:
1352 NewFfs
= ScheduleList
.pop(FfsID
)
1354 self
.OrderedFfsDict
[FfsID
] = NewFfs
1355 self
.LoadProtocol(Db
, FfsID
)
1357 SqlCommand
= """select Value2 from Inf
1358 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
1359 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
1360 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1362 FfsName
= RecordSet
[0][0]
1365 self
.DisPatchDxe(Db
)
1367 def DisPatchPei(self
, Db
):
1369 for FfsID
in self
.UnDispatchedFfsDict
:
1370 CouldBeLoaded
= True
1373 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1374 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
1376 for Section
in Ffs
.Sections
.values():
1377 if Section
.Type
== 0x1B:
1378 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
1381 if Section
.Type
== 0x01:
1382 CompressSections
= Section
._SubImages
[4]
1383 for CompressSection
in CompressSections
.Sections
:
1384 if CompressSection
.Type
== 0x1B:
1385 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
1387 if CompressSection
.Type
== 0x02:
1388 NewSections
= CompressSection
._SubImages
[4]
1389 for NewSection
in NewSections
.Sections
:
1390 if NewSection
.Type
== 0x1B:
1391 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
1397 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
1398 NewFfs
.Depex
= DepexString
1399 self
.OrderedFfsDict
[FfsID
] = NewFfs
1400 self
.LoadPpi(Db
, FfsID
)
1402 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
1405 self
.DisPatchPei(Db
)
1411 FvInfo
= '\n' + ' ' * gIndention
1412 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
1413 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
1415 return FvInfo
+ FfsInfo
1418 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
1420 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_+Size
])
1424 FfsStartAddress
= self
.HeaderSize
1426 while FfsStartAddress
< EndOfFv
:
1428 FfsObj
.frombuffer(self
, FfsStartAddress
)
1429 FfsId
= repr(FfsObj
)
1430 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
1431 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
1432 if LastFfsObj
is not None:
1433 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
1435 if FfsId
in self
.FfsDict
:
1436 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
1437 ExtraData
="\t%s @ %s\n\t%s @ %s" \
1438 % (FfsObj
.Guid
, FfsObj
.Offset
,
1439 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
1440 self
.FfsDict
[FfsId
] = FfsObj
1441 if LastFfsObj
is not None:
1442 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
1444 FfsStartAddress
+= len(FfsObj
)
1446 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
1447 # The next FFS must be at the latest next 8-byte aligned address
1449 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
1452 def _GetAttributes(self
):
1453 return self
.GetField(self
._ATTR
_, 0)[0]
1456 return self
.GetField(self
._LENGTH
_, 0)[0]
1458 def _GetChecksum(self
):
1459 return self
.GetField(self
._CHECKSUM
_, 0)[0]
1461 def _GetHeaderLength(self
):
1462 return self
.GetField(self
._HLEN
_, 0)[0]
1464 def _GetFileSystemGuid(self
):
1465 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
1467 Attributes
= property(_GetAttributes
)
1468 Size
= property(_GetSize
)
1469 Checksum
= property(_GetChecksum
)
1470 HeaderSize
= property(_GetHeaderLength
)
1471 FileSystemGuid
= property(_GetFileSystemGuid
)
1473 ## MultipleFv() class
1475 # A class for Multiple FV
1477 class MultipleFv(FirmwareVolume
):
1478 def __init__(self
, FvList
):
1479 FirmwareVolume
.__init
__(self
)
1481 for FvPath
in FvList
:
1482 FvName
= os
.path
.splitext(os
.path
.split(FvPath
)[1])[0]
1483 Fd
= open(FvPath
, 'rb')
1486 Buf
.fromfile(Fd
, os
.path
.getsize(FvPath
))
1490 Fv
= FirmwareVolume(FvName
)
1491 Fv
.frombuffer(Buf
, 0, len(Buf
))
1493 self
.BasicInfo
.append([Fv
.Name
, Fv
.FileSystemGuid
, Fv
.Size
])
1494 self
.FfsDict
.append(Fv
.FfsDict
)
1498 # This class is used to define Eot main entrance
1500 # @param object: Inherited from object class
1505 # @param self: The object pointer
1507 def __init__(self
, CommandLineOption
=True, IsInit
=True, SourceFileList
=None, \
1508 IncludeDirList
=None, DecFileList
=None, GuidList
=None, LogFile
=None,
1509 FvFileList
="", MapFileList
="", Report
='Report.html', Dispatch
=None):
1510 # Version and Copyright
1511 self
.VersionNumber
= ("0.02" + " " + gBUILD_VERSION
)
1512 self
.Version
= "%prog Version " + self
.VersionNumber
1513 self
.Copyright
= "Copyright (c) 2008 - 2010, Intel Corporation All rights reserved."
1514 self
.Report
= Report
1516 self
.IsInit
= IsInit
1517 self
.SourceFileList
= SourceFileList
1518 self
.IncludeDirList
= IncludeDirList
1519 self
.DecFileList
= DecFileList
1520 self
.GuidList
= GuidList
1521 self
.LogFile
= LogFile
1522 self
.FvFileList
= FvFileList
1523 self
.MapFileList
= MapFileList
1524 self
.Dispatch
= Dispatch
1526 # Check workspace environment
1527 if "EFI_SOURCE" not in os
.environ
:
1528 if "EDK_SOURCE" not in os
.environ
:
1531 EotGlobalData
.gEDK_SOURCE
= os
.path
.normpath(os
.getenv("EDK_SOURCE"))
1533 EotGlobalData
.gEFI_SOURCE
= os
.path
.normpath(os
.getenv("EFI_SOURCE"))
1534 EotGlobalData
.gEDK_SOURCE
= os
.path
.join(EotGlobalData
.gEFI_SOURCE
, 'Edk')
1536 if "WORKSPACE" not in os
.environ
:
1537 EdkLogger
.error("EOT", BuildToolError
.ATTRIBUTE_NOT_AVAILABLE
, "Environment variable not found",
1538 ExtraData
="WORKSPACE")
1540 EotGlobalData
.gWORKSPACE
= os
.path
.normpath(os
.getenv("WORKSPACE"))
1542 EotGlobalData
.gMACRO
['WORKSPACE'] = EotGlobalData
.gWORKSPACE
1543 EotGlobalData
.gMACRO
['EFI_SOURCE'] = EotGlobalData
.gEFI_SOURCE
1544 EotGlobalData
.gMACRO
['EDK_SOURCE'] = EotGlobalData
.gEDK_SOURCE
1546 # Parse the options and args
1547 if CommandLineOption
:
1551 for FvFile
in GetSplitValueList(self
.FvFileList
, ' '):
1552 FvFile
= os
.path
.normpath(FvFile
)
1553 if not os
.path
.isfile(FvFile
):
1554 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % FvFile
)
1555 EotGlobalData
.gFV_FILE
.append(FvFile
)
1557 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "The fv file list of target platform was not specified")
1559 if self
.MapFileList
:
1560 for MapFile
in GetSplitValueList(self
.MapFileList
, ' '):
1561 MapFile
= os
.path
.normpath(MapFile
)
1562 if not os
.path
.isfile(MapFile
):
1563 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % MapFile
)
1564 EotGlobalData
.gMAP_FILE
.append(MapFile
)
1566 # Generate source file list
1567 self
.GenerateSourceFileList(self
.SourceFileList
, self
.IncludeDirList
)
1569 # Generate guid list of dec file list
1570 self
.ParseDecFile(self
.DecFileList
)
1572 # Generate guid list from GUID list file
1573 self
.ParseGuidList(self
.GuidList
)
1576 EotGlobalData
.gDb
= Database
.Database(Database
.DATABASE_PATH
)
1577 EotGlobalData
.gDb
.InitDatabase(self
.IsInit
)
1579 # Build ECC database
1580 self
.BuildDatabase()
1582 # Parse Ppi/Protocol
1583 self
.ParseExecutionOrder()
1585 # Merge Identifier tables
1586 self
.GenerateQueryTable()
1588 # Generate report database
1589 self
.GenerateReportDatabase()
1598 self
.GenerateReport()
1601 self
.ConvertLogFile(self
.LogFile
)
1604 EdkLogger
.quiet("EOT FINISHED!")
1607 EotGlobalData
.gDb
.Close()
1609 ## ParseDecFile() method
1611 # parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}
1612 # The Dict is stored in EotGlobalData.gGuidDict
1614 # @param self: The object pointer
1615 # @param DecFileList: A list of all DEC files
1617 def ParseDecFile(self
, DecFileList
):
1619 path
= os
.path
.normpath(DecFileList
)
1620 lfr
= open(path
, 'rb')
1622 path
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1623 if os
.path
.exists(path
):
1624 dfr
= open(path
, 'rb')
1626 line
= CleanString(line
)
1627 list = line
.split('=')
1629 EotGlobalData
.gGuidDict
[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())
1632 ## ParseGuidList() method
1634 # Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}
1635 # The Dict is stored in EotGlobalData.gGuidDict
1637 # @param self: The object pointer
1638 # @param GuidList: A list of all GUID and its value
1640 def ParseGuidList(self
, GuidList
):
1641 Path
= os
.path
.join(EotGlobalData
.gWORKSPACE
, GuidList
)
1642 if os
.path
.isfile(Path
):
1643 for Line
in open(Path
):
1644 (GuidName
, GuidValue
) = Line
.split()
1645 EotGlobalData
.gGuidDict
[GuidName
] = GuidValue
1647 ## ConvertLogFile() method
1649 # Parse a real running log file to get real dispatch order
1650 # The result is saved to old file name + '.new'
1652 # @param self: The object pointer
1653 # @param LogFile: A real running log file name
1655 def ConvertLogFile(self
, LogFile
):
1660 lfr
= open(LogFile
, 'rb')
1661 lfw
= open(LogFile
+ '.new', 'wb')
1664 line
= line
.replace('.efi', '')
1665 index
= line
.find("Loading PEIM at ")
1667 newline
.append(line
[index
+ 55 : ])
1669 index
= line
.find("Loading driver at ")
1671 newline
.append(line
[index
+ 57 : ])
1674 for line
in newline
:
1675 lfw
.write(line
+ '\r\n')
1682 ## GenerateSourceFileList() method
1684 # Generate a list of all source files
1685 # 1. Search the file list one by one
1686 # 2. Store inf file name with source file names under it like
1687 # { INF file name: [source file1, source file2, ...]}
1688 # 3. Search the include list to find all .h files
1689 # 4. Store source file list to EotGlobalData.gSOURCE_FILES
1690 # 5. Store INF file list to EotGlobalData.gINF_FILES
1692 # @param self: The object pointer
1693 # @param SourceFileList: A list of all source files
1694 # @param IncludeFileList: A list of all include files
1696 def GenerateSourceFileList(self
, SourceFileList
, IncludeFileList
):
1697 EdkLogger
.quiet("Generating source files list ... ")
1698 mSourceFileList
= []
1702 mCurrentInfFile
= ''
1703 mCurrentSourceFileList
= []
1706 sfl
= open(SourceFileList
, 'rb')
1708 line
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1709 if line
[-2:].upper() == '.C' or line
[-2:].upper() == '.H':
1710 if line
not in mCurrentSourceFileList
:
1711 mCurrentSourceFileList
.append(line
)
1712 mSourceFileList
.append(line
)
1713 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % line
)
1714 if line
[-4:].upper() == '.INF':
1715 if mCurrentInfFile
!= '':
1716 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1717 mCurrentSourceFileList
= []
1718 mCurrentInfFile
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
))
1719 EotGlobalData
.gOP_INF
.write('%s\n' % mCurrentInfFile
)
1720 if mCurrentInfFile
not in mFileList
:
1721 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1723 # Get all include files from packages
1725 ifl
= open(IncludeFileList
, 'rb')
1727 if not line
.strip():
1729 newline
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1730 for Root
, Dirs
, Files
in os
.walk(str(newline
)):
1732 FullPath
= os
.path
.normpath(os
.path
.join(Root
, File
))
1733 if FullPath
not in mSourceFileList
and File
[-2:].upper() == '.H':
1734 mSourceFileList
.append(FullPath
)
1735 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % FullPath
)
1736 if FullPath
not in mDecFileList
and File
.upper().find('.DEC') > -1:
1737 mDecFileList
.append(FullPath
)
1739 EotGlobalData
.gSOURCE_FILES
= mSourceFileList
1740 EotGlobalData
.gOP_SOURCE_FILES
.close()
1742 EotGlobalData
.gINF_FILES
= mFileList
1743 EotGlobalData
.gOP_INF
.close()
1745 ## GenerateReport() method
1747 # Generate final HTML report
1749 # @param self: The object pointer
1751 def GenerateReport(self
):
1752 EdkLogger
.quiet("Generating report file ... ")
1753 Rep
= Report(self
.Report
, EotGlobalData
.gFV
, self
.Dispatch
)
1754 Rep
.GenerateReport()
1756 ## LoadMapInfo() method
1758 # Load map files and parse them
1760 # @param self: The object pointer
1762 def LoadMapInfo(self
):
1763 if EotGlobalData
.gMAP_FILE
!= []:
1764 EdkLogger
.quiet("Parsing Map file ... ")
1765 EotGlobalData
.gMap
= ParseMapFile(EotGlobalData
.gMAP_FILE
)
1767 ## LoadFvInfo() method
1769 # Load FV binary files and parse them
1771 # @param self: The object pointer
1773 def LoadFvInfo(self
):
1774 EdkLogger
.quiet("Parsing FV file ... ")
1775 EotGlobalData
.gFV
= MultipleFv(EotGlobalData
.gFV_FILE
)
1776 EotGlobalData
.gFV
.Dispatch(EotGlobalData
.gDb
)
1778 for Protocol
in EotGlobalData
.gProtocolList
:
1779 EotGlobalData
.gOP_UN_MATCHED_IN_LIBRARY_CALLING
.write('%s\n' %Protocol
)
1781 ## GenerateReportDatabase() method
1783 # Generate data for the information needed by report
1784 # 1. Update name, macro and value of all found PPI/PROTOCOL GUID
1785 # 2. Install hard coded PPI/PROTOCOL
1787 # @param self: The object pointer
1789 def GenerateReportDatabase(self
):
1790 EdkLogger
.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")
1792 # Update Protocol/Ppi Guid
1793 SqlCommand
= """select DISTINCT GuidName from Report"""
1794 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1795 for Record
in RecordSet
:
1796 GuidName
= Record
[0]
1801 # Find guid value defined in Dec file
1802 if GuidName
in EotGlobalData
.gGuidDict
:
1803 GuidValue
= EotGlobalData
.gGuidDict
[GuidName
]
1804 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1805 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1808 # Search defined Macros for guid name
1809 SqlCommand
="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName
1810 GuidMacroSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1811 # Ignore NULL result
1812 if not GuidMacroSet
:
1814 GuidMacro
= GuidMacroSet
[0][0].strip()
1817 # Find Guid value of Guid Macro
1818 SqlCommand
="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro
, MODEL_IDENTIFIER_MACRO_DEFINE
)
1819 GuidValueSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1820 if GuidValueSet
!= []:
1821 GuidValue
= GuidValueSet
[0][0]
1822 GuidValue
= GuidValue
[GuidValue
.find(GuidMacro
) + len(GuidMacro
) :]
1823 GuidValue
= GuidValue
.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()
1824 GuidValue
= GuidStructureStringToGuidString(GuidValue
)
1825 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1826 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1829 # Update Hard Coded Ppi/Protocol
1830 SqlCommand
= """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""
1831 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1832 for Record
in RecordSet
:
1833 if Record
[1] == 'Ppi':
1834 EotGlobalData
.gPpiList
[Record
[0].lower()] = -2
1835 if Record
[1] == 'Protocol':
1836 EotGlobalData
.gProtocolList
[Record
[0].lower()] = -2
1838 ## GenerateQueryTable() method
1840 # Generate two tables improve query performance
1842 # @param self: The object pointer
1844 def GenerateQueryTable(self
):
1845 EdkLogger
.quiet("Generating temp query table for analysis ... ")
1846 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1847 SqlCommand
= """insert into Query (Name, Modifier, Value, Model)
1848 select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \
1849 % (Identifier
[0], MODEL_IDENTIFIER_VARIABLE
, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION
)
1850 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1851 SqlCommand
= """insert into Query2 (Name, Modifier, Value, Model)
1852 select Name, Modifier, Value, Model from %s where Model = %s""" \
1853 % (Identifier
[0], MODEL_IDENTIFIER_MACRO_DEFINE
)
1854 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1856 ## ParseExecutionOrder() method
1858 # Get final execution order
1860 # 2. Search all PROTOCOL
1862 # @param self: The object pointer
1864 def ParseExecutionOrder(self
):
1865 EdkLogger
.quiet("Searching Ppi/Protocol ... ")
1866 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1867 ModuleID
, ModuleName
, ModuleGuid
, SourceFileID
, SourceFileFullPath
, ItemName
, ItemType
, ItemMode
, GuidName
, GuidMacro
, GuidValue
, BelongsToFunction
, Enabled
= \
1868 -1, '', '', -1, '', '', '', '', '', '', '', '', 0
1870 SourceFileID
= Identifier
[0].replace('Identifier', '')
1871 SourceFileFullPath
= Identifier
[1]
1872 Identifier
= Identifier
[0]
1875 ItemMode
= 'Produced'
1876 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1877 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1878 % (Identifier
, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1879 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1881 ItemMode
= 'Produced'
1882 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1883 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1884 % (Identifier
, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1885 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1887 SearchPpiCallFunction(Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1889 ItemMode
= 'Consumed'
1890 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1891 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1892 % (Identifier
, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1893 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1895 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Ppi', ItemMode
)
1897 ItemMode
= 'Callback'
1898 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1899 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1900 % (Identifier
, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1901 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1904 ItemMode
= 'Produced'
1905 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1906 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1907 % (Identifier
, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1908 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1910 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1911 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1912 % (Identifier
, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1913 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1915 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1917 ItemMode
= 'Consumed'
1918 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1919 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1920 % (Identifier
, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1921 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1923 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1924 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1925 % (Identifier
, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1926 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1928 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1930 ItemMode
= 'Callback'
1931 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1932 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1933 % (Identifier
, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1934 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1936 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1939 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)
1940 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)
1941 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)
1942 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)
1943 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)
1944 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)
1945 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)
1946 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)
1947 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)
1949 EotGlobalData
.gDb
.Conn
.commit()
1952 ## BuildDatabase() methoc
1954 # Build the database for target
1956 # @param self: The object pointer
1958 def BuildDatabase(self
):
1959 # Clean report table
1960 EotGlobalData
.gDb
.TblReport
.Drop()
1961 EotGlobalData
.gDb
.TblReport
.Create()
1965 self
.BuildMetaDataFileDatabase(EotGlobalData
.gINF_FILES
)
1966 EdkLogger
.quiet("Building database for source code ...")
1967 c
.CreateCCodeDB(EotGlobalData
.gSOURCE_FILES
)
1968 EdkLogger
.quiet("Building database for source code done!")
1970 EotGlobalData
.gIdentifierTableList
= GetTableList((MODEL_FILE_C
, MODEL_FILE_H
), 'Identifier', EotGlobalData
.gDb
)
1972 ## BuildMetaDataFileDatabase() method
1974 # Build the database for meta data files
1976 # @param self: The object pointer
1977 # @param Inf_Files: A list for all INF files
1979 def BuildMetaDataFileDatabase(self
, Inf_Files
):
1980 EdkLogger
.quiet("Building database for meta data files ...")
1981 for InfFile
in Inf_Files
:
1982 EdkLogger
.quiet("Parsing %s ..." % str(InfFile
))
1983 EdkInfParser(InfFile
, EotGlobalData
.gDb
, Inf_Files
[InfFile
], '')
1985 EotGlobalData
.gDb
.Conn
.commit()
1986 EdkLogger
.quiet("Building database for meta data files done!")
1988 ## ParseOption() method
1990 # Parse command line options
1992 # @param self: The object pointer
1994 def ParseOption(self
):
1995 (Options
, Target
) = self
.EotOptionParser()
1998 self
.SetLogLevel(Options
)
2000 if Options
.FvFileList
:
2001 self
.FvFileList
= Options
.FvFileList
2003 if Options
.MapFileList
:
2004 self
.MapFileList
= Options
.FvMapFileList
2006 if Options
.SourceFileList
:
2007 self
.SourceFileList
= Options
.SourceFileList
2009 if Options
.IncludeDirList
:
2010 self
.IncludeDirList
= Options
.IncludeDirList
2012 if Options
.DecFileList
:
2013 self
.DecFileList
= Options
.DecFileList
2015 if Options
.GuidList
:
2016 self
.GuidList
= Options
.GuidList
2019 self
.LogFile
= Options
.LogFile
2021 if Options
.keepdatabase
:
2024 ## SetLogLevel() method
2026 # Set current log level of the tool based on args
2028 # @param self: The object pointer
2029 # @param Option: The option list including log level setting
2031 def SetLogLevel(self
, Option
):
2032 if Option
.verbose
is not None:
2033 EdkLogger
.SetLevel(EdkLogger
.VERBOSE
)
2034 elif Option
.quiet
is not None:
2035 EdkLogger
.SetLevel(EdkLogger
.QUIET
)
2036 elif Option
.debug
is not None:
2037 EdkLogger
.SetLevel(Option
.debug
+ 1)
2039 EdkLogger
.SetLevel(EdkLogger
.INFO
)
2041 ## EotOptionParser() method
2043 # Using standard Python module optparse to parse command line option of this tool.
2045 # @param self: The object pointer
2047 # @retval Opt A optparse.Values object containing the parsed options
2048 # @retval Args Target of build command
2050 def EotOptionParser(self
):
2051 Parser
= OptionParser(description
= self
.Copyright
, version
= self
.Version
, prog
= "Eot.exe", usage
= "%prog [options]")
2052 Parser
.add_option("-m", "--makefile filename", action
="store", type="string", dest
='MakeFile',
2053 help="Specify a makefile for the platform.")
2054 Parser
.add_option("-c", "--dsc filename", action
="store", type="string", dest
="DscFile",
2055 help="Specify a dsc file for the platform.")
2056 Parser
.add_option("-f", "--fv filename", action
="store", type="string", dest
="FvFileList",
2057 help="Specify fv file list, quoted by \"\".")
2058 Parser
.add_option("-a", "--map filename", action
="store", type="string", dest
="MapFileList",
2059 help="Specify map file list, quoted by \"\".")
2060 Parser
.add_option("-s", "--source files", action
="store", type="string", dest
="SourceFileList",
2061 help="Specify source file list by a file")
2062 Parser
.add_option("-i", "--include dirs", action
="store", type="string", dest
="IncludeDirList",
2063 help="Specify include dir list by a file")
2064 Parser
.add_option("-e", "--dec files", action
="store", type="string", dest
="DecFileList",
2065 help="Specify dec file list by a file")
2066 Parser
.add_option("-g", "--guid list", action
="store", type="string", dest
="GuidList",
2067 help="Specify guid file list by a file")
2068 Parser
.add_option("-l", "--log filename", action
="store", type="string", dest
="LogFile",
2069 help="Specify real execution log file")
2071 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.")
2073 Parser
.add_option("-q", "--quiet", action
="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
2074 Parser
.add_option("-v", "--verbose", action
="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
2075 "including library instances selected, final dependency expression, "\
2076 "and warning messages, etc.")
2077 Parser
.add_option("-d", "--debug", action
="store", type="int", help="Enable debug messages at specified level.")
2079 (Opt
, Args
)=Parser
.parse_args()
2085 # This acts like the main() function for the script, unless it is 'import'ed into another
2088 if __name__
== '__main__':
2089 # Initialize log system
2090 EdkLogger
.Initialize()
2091 EdkLogger
.IsRaiseError
= False
2092 EdkLogger
.quiet(time
.strftime("%H:%M:%S, %b.%d %Y ", time
.localtime()) + "[00:00]" + "\n")
2094 StartTime
= time
.clock()
2096 FinishTime
= time
.clock()
2098 BuildDuration
= time
.strftime("%M:%S", time
.gmtime(int(round(FinishTime
- StartTime
))))
2099 EdkLogger
.quiet("\n%s [%s]" % (time
.strftime("%H:%M:%S, %b.%d %Y", time
.localtime()), BuildDuration
))