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__(m
, CompressedData
=None, CompressionType
=None, UncompressedLength
=None):
128 if UncompressedLength
is not None:
129 m
.UncompressedLength
= UncompressedLength
130 if CompressionType
is not None:
131 m
.CompressionType
= CompressionType
132 if CompressedData
is not None:
133 m
.Data
= CompressedData
137 S
= "algorithm=%s uncompressed=%x" % (m
.CompressionType
, m
.UncompressedLength
)
138 for Sec
in m
.Sections
:
143 def _SetOriginalSize(m
, Size
):
144 m
.SetField(m
._ORIG
_SIZE
_, 0, Size
)
146 def _GetOriginalSize(m
):
147 return m
.GetField(m
._ORIG
_SIZE
_)[0]
149 def _SetCompressionType(m
, Type
):
150 m
.SetField(m
._CMPRS
_TYPE
_, 0, Type
)
152 def _GetCompressionType(m
):
153 return m
.GetField(m
._CMPRS
_TYPE
_)[0]
157 from . import EfiCompressor
158 TmpData
= EfiCompressor
.FrameworkDecompress(
160 len(m
) - m
._HEADER
_SIZE
_
163 DecData
.fromstring(TmpData
)
165 from . import EfiCompressor
166 TmpData
= EfiCompressor
.UefiDecompress(
168 len(m
) - m
._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 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._LEN
_])
211 return codecs
.utf_16_decode(m
[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 m
.Expression
:
263 if T
in m
._OPCODE
_STRING
_:
264 S
+= Indention
+ m
._OPCODE
_STRING
_[T
]
265 if T
not in [0x00, 0x01, 0x02]:
268 S
+= ' ' + gGuidStringFormat
% T
+ '\n'
273 # keep header in this Image object
275 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._LEN
_])
278 def _GetExpression(m
):
279 if m
._ExprList
== []:
281 CurrentData
= m
._OPCODE
_
282 while Offset
< len(m
):
283 Token
= CurrentData
.unpack_from(m
, Offset
)
284 Offset
+= CurrentData
.size
287 if Token
in m
._NEXT
_:
288 CurrentData
= m
._NEXT
_[Token
]
290 CurrentData
= m
._GUID
_
292 CurrentData
= m
._OPCODE
_
293 m
._ExprList
.append(Token
)
294 if CurrentData
is None:
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
:
334 def ParseDepex(self
, Depex
, Type
):
337 List
= EotGlobalData
.gPpiList
338 if Type
== 'Protocol':
339 List
= EotGlobalData
.gProtocolList
345 for Index
in range(0, len(Depex
.Expression
)):
346 Item
= Depex
.Expression
[Index
]
349 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
350 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
351 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
354 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
355 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
356 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
359 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
360 if Guid
.lower() in List
:
361 DepexStack
.append(True)
362 DepexList
.append(Guid
)
364 DepexStack
.append(False)
365 DepexList
.append(Guid
)
367 elif Item
== 0x03 or Item
== 0x04:
368 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
369 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
371 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
372 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
374 DepexStack
.append(True)
375 DepexList
.append('TRUE')
376 DepexString
= DepexString
+ 'TRUE' + ' '
378 DepexStack
.append(False)
379 DepexList
.append('False')
380 DepexString
= DepexString
+ 'FALSE' + ' '
382 if Index
!= len(Depex
.Expression
) - 1:
383 CouldBeLoaded
= False
385 CouldBeLoaded
= DepexStack
.pop()
387 CouldBeLoaded
= False
389 DepexString
= DepexList
[0].strip()
390 return (CouldBeLoaded
, DepexString
, FileDepex
)
392 def Dispatch(self
, Db
= None):
395 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
396 # Find PeiCore, DexCore, PeiPriori, DxePriori first
397 FfsSecCoreGuid
= None
398 FfsPeiCoreGuid
= None
399 FfsDxeCoreGuid
= None
400 FfsPeiPrioriGuid
= None
401 FfsDxePrioriGuid
= None
402 for FfsID
in self
.UnDispatchedFfsDict
:
403 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
405 FfsSecCoreGuid
= FfsID
408 FfsPeiCoreGuid
= FfsID
411 FfsDxeCoreGuid
= FfsID
413 if Ffs
.Guid
.lower() == gPeiAprioriFileNameGuid
:
414 FfsPeiPrioriGuid
= FfsID
416 if Ffs
.Guid
.lower() == gAprioriGuid
:
417 FfsDxePrioriGuid
= FfsID
420 # Parse SEC_CORE first
421 if FfsSecCoreGuid
is not None:
422 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
423 self
.LoadPpi(Db
, FfsSecCoreGuid
)
426 if FfsPeiCoreGuid
is not None:
427 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
428 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
429 if FfsPeiPrioriGuid
is not None:
430 # Load PEIM described in priori file
431 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
432 if len(FfsPeiPriori
.Sections
) == 1:
433 Section
= FfsPeiPriori
.Sections
.popitem()[1]
434 if Section
.Type
== 0x19:
435 GuidStruct
= struct
.Struct('1I2H8B')
437 while len(Section
) > Start
:
438 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
439 GuidString
= gGuidStringFormat
% Guid
441 if GuidString
in self
.UnDispatchedFfsDict
:
442 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
443 self
.LoadPpi(Db
, GuidString
)
448 if FfsDxeCoreGuid
is not None:
449 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
450 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
451 if FfsDxePrioriGuid
is not None:
452 # Load PEIM described in priori file
453 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
454 if len(FfsDxePriori
.Sections
) == 1:
455 Section
= FfsDxePriori
.Sections
.popitem()[1]
456 if Section
.Type
== 0x19:
457 GuidStruct
= struct
.Struct('1I2H8B')
459 while len(Section
) > Start
:
460 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
461 GuidString
= gGuidStringFormat
% Guid
463 if GuidString
in self
.UnDispatchedFfsDict
:
464 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
465 self
.LoadProtocol(Db
, GuidString
)
469 def LoadProtocol(self
, Db
, ModuleGuid
):
470 SqlCommand
= """select GuidValue from Report
471 where SourceFileFullPath in
472 (select Value1 from Inf where BelongsToFile =
473 (select BelongsToFile from Inf
474 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
476 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
477 % (ModuleGuid
, 5001, 3007)
478 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
479 for Record
in RecordSet
:
480 SqlCommand
= """select Value2 from Inf where BelongsToFile =
481 (select DISTINCT BelongsToFile from Inf
483 (select SourceFileFullPath from Report
484 where GuidValue like '%s' and ItemMode = 'Callback'))
485 and Value1 = 'FILE_GUID'""" % Record
[0]
486 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
487 if CallBackSet
!= []:
488 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
490 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
492 def LoadPpi(self
, Db
, ModuleGuid
):
493 SqlCommand
= """select GuidValue from Report
494 where SourceFileFullPath in
495 (select Value1 from Inf where BelongsToFile =
496 (select BelongsToFile from Inf
497 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
499 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
500 % (ModuleGuid
, 5001, 3007)
501 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
502 for Record
in RecordSet
:
503 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
505 def DisPatchDxe(self
, Db
):
507 ScheduleList
= sdict()
508 for FfsID
in self
.UnDispatchedFfsDict
:
509 CouldBeLoaded
= False
512 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
516 for Section
in Ffs
.Sections
.values():
518 if Section
.Type
== 0x13:
520 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
522 if Section
.Type
== 0x01:
523 CompressSections
= Section
._SubImages
[4]
524 for CompressSection
in CompressSections
.Sections
:
525 if CompressSection
.Type
== 0x13:
527 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
529 if CompressSection
.Type
== 0x02:
530 NewSections
= CompressSection
._SubImages
[4]
531 for NewSection
in NewSections
.Sections
:
532 if NewSection
.Type
== 0x13:
534 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
539 CouldBeLoaded
= self
.CheckArchProtocol()
546 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
547 NewFfs
.Depex
= DepexString
548 if FileDepex
is not None:
549 ScheduleList
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
551 ScheduleList
[FfsID
] = NewFfs
553 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
555 for FfsID
in ScheduleList
:
556 NewFfs
= ScheduleList
.pop(FfsID
)
558 self
.OrderedFfsDict
[FfsID
] = NewFfs
559 self
.LoadProtocol(Db
, FfsID
)
561 SqlCommand
= """select Value2 from Inf
562 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
563 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
564 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
566 FfsName
= RecordSet
[0][0]
571 def DisPatchPei(self
, Db
):
573 for FfsID
in self
.UnDispatchedFfsDict
:
577 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
578 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
580 for Section
in Ffs
.Sections
.values():
581 if Section
.Type
== 0x1B:
582 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
585 if Section
.Type
== 0x01:
586 CompressSections
= Section
._SubImages
[4]
587 for CompressSection
in CompressSections
.Sections
:
588 if CompressSection
.Type
== 0x1B:
589 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
591 if CompressSection
.Type
== 0x02:
592 NewSections
= CompressSection
._SubImages
[4]
593 for NewSection
in NewSections
.Sections
:
594 if NewSection
.Type
== 0x1B:
595 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
601 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
602 NewFfs
.Depex
= DepexString
603 self
.OrderedFfsDict
[FfsID
] = NewFfs
604 self
.LoadPpi(Db
, FfsID
)
606 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
615 FvInfo
= '\n' + ' ' * gIndention
616 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
617 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
619 return FvInfo
+ FfsInfo
622 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
624 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_+Size
])
628 FfsStartAddress
= self
.HeaderSize
630 while FfsStartAddress
< EndOfFv
:
632 FfsObj
.frombuffer(self
, FfsStartAddress
)
634 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
635 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
636 if LastFfsObj
is not None:
637 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
639 if FfsId
in self
.FfsDict
:
640 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
641 ExtraData
="\t%s @ %s\n\t%s @ %s" \
642 % (FfsObj
.Guid
, FfsObj
.Offset
,
643 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
644 self
.FfsDict
[FfsId
] = FfsObj
645 if LastFfsObj
is not None:
646 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
648 FfsStartAddress
+= len(FfsObj
)
650 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
651 # The next FFS must be at the latest next 8-byte aligned address
653 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
656 def _GetAttributes(self
):
657 return self
.GetField(self
._ATTR
_, 0)[0]
660 return self
.GetField(self
._LENGTH
_, 0)[0]
662 def _GetChecksum(self
):
663 return self
.GetField(self
._CHECKSUM
_, 0)[0]
665 def _GetHeaderLength(self
):
666 return self
.GetField(self
._HLEN
_, 0)[0]
668 def _GetFileSystemGuid(self
):
669 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
671 Attributes
= property(_GetAttributes
)
672 Size
= property(_GetSize
)
673 Checksum
= property(_GetChecksum
)
674 HeaderSize
= property(_GetHeaderLength
)
675 FileSystemGuid
= property(_GetFileSystemGuid
)
677 ## GuidDefinedImage() class
679 # A class for GUID Defined Image
681 class GuidDefinedImage(Image
):
682 _HEADER_
= struct
.Struct("1I2H8B 1H 1H")
683 _HEADER_SIZE_
= _HEADER_
.size
685 _GUID_
= struct
.Struct("1I2H8B")
686 _DATA_OFFSET_
= struct
.Struct("16x 1H")
687 _ATTR_
= struct
.Struct("18x 1H")
689 CRC32_GUID
= "FC1BCDB0-7D31-49AA-936A-A4600D9DD083"
690 TIANO_COMPRESS_GUID
= 'A31280AD-481E-41B6-95E8-127F4C984779'
691 LZMA_COMPRESS_GUID
= 'EE4E5898-3914-4259-9D6E-DC7BD79403CF'
693 def __init__(m
, SectionDefinitionGuid
=None, DataOffset
=None, Attributes
=None, Data
=None):
695 if SectionDefinitionGuid
is not None:
696 m
.SectionDefinitionGuid
= SectionDefinitionGuid
697 if DataOffset
is not None:
698 m
.DataOffset
= DataOffset
699 if Attributes
is not None:
700 m
.Attributes
= Attributes
705 S
= "guid=%s" % (gGuidStringFormat
% m
.SectionDefinitionGuid
)
706 for Sec
in m
.Sections
:
711 # keep header in this Image object
713 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._LEN
_])
716 def _SetAttribute(m
, Attribute
):
717 m
.SetField(m
._ATTR
_, 0, Attribute
)
719 def _GetAttribute(m
):
720 return m
.GetField(m
._ATTR
_)[0]
722 def _SetGuid(m
, Guid
):
723 m
.SetField(m
._GUID
_, 0, Guid
)
726 return m
.GetField(m
._GUID
_)
728 def _SetDataOffset(m
, Offset
):
729 m
.SetField(m
._DATA
_OFFSET
_, 0, Offset
)
731 def _GetDataOffset(m
):
732 return m
.GetField(m
._DATA
_OFFSET
_)[0]
736 Guid
= gGuidStringFormat
% m
.SectionDefinitionGuid
737 if Guid
== m
.CRC32_GUID
:
738 # skip the CRC32 value, we don't do CRC32 verification here
739 Offset
= m
.DataOffset
- 4
740 while Offset
< len(m
):
743 Sec
.frombuffer(m
, Offset
)
745 # the section is aligned to 4-byte boundary
746 Offset
= (Offset
+ 3) & (~
3)
749 SectionList
.append(Sec
)
750 elif Guid
== m
.TIANO_COMPRESS_GUID
:
752 from . import EfiCompressor
754 Offset
= m
.DataOffset
- 4
755 TmpData
= EfiCompressor
.FrameworkDecompress(m
[Offset
:], len(m
)-Offset
)
757 DecData
.fromstring(TmpData
)
759 while Offset
< len(DecData
):
762 Sec
.frombuffer(DecData
, Offset
)
764 # the section is aligned to 4-byte boundary
765 Offset
= (Offset
+ 3) & (~
3)
768 SectionList
.append(Sec
)
771 elif Guid
== m
.LZMA_COMPRESS_GUID
:
773 from . import LzmaCompressor
775 Offset
= m
.DataOffset
- 4
776 TmpData
= LzmaCompressor
.LzmaDecompress(m
[Offset
:], len(m
)-Offset
)
778 DecData
.fromstring(TmpData
)
780 while Offset
< len(DecData
):
783 Sec
.frombuffer(DecData
, Offset
)
785 # the section is aligned to 4-byte boundary
786 Offset
= (Offset
+ 3) & (~
3)
789 SectionList
.append(Sec
)
795 Attributes
= property(_GetAttribute
, _SetAttribute
)
796 SectionDefinitionGuid
= property(_GetGuid
, _SetGuid
)
797 DataOffset
= property(_GetDataOffset
, _SetDataOffset
)
798 Sections
= property(_GetSections
)
802 # A class for Section
804 class Section(Image
):
807 0x01 : "COMPRESSION",
808 0x02 : "GUID_DEFINED",
814 0x15 : "USER_INTERFACE",
815 0x16 : "COMPATIBILITY16",
816 0x17 : "FIRMWARE_VOLUME_IMAGE",
817 0x18 : "FREEFORM_SUBTYPE_GUID",
822 _SectionSubImages
= {
823 0x01 : CompressedImage
,
824 0x02 : GuidDefinedImage
,
825 0x17 : FirmwareVolume
,
833 _HEADER_
= struct
.Struct("3B 1B")
834 _HEADER_SIZE_
= _HEADER_
.size
837 # _FREE_FORM_SUBTYPE_GUID_HEADER_ = struct.Struct("1I2H8B")
839 _SIZE_
= struct
.Struct("3B")
840 _TYPE_
= struct
.Struct("3x 1B")
842 def __init__(m
, Type
=None, Size
=None):
853 SectionInfo
= ' ' * gIndention
854 if m
.Type
in m
._TypeName
:
855 SectionInfo
+= "[SECTION:%s] offset=%x size=%x" % (m
._TypeName
[m
.Type
], m
._OFF
_, m
.Size
)
857 SectionInfo
+= "[SECTION:%x<unknown>] offset=%x size=%x " % (m
.Type
, m
._OFF
_, m
.Size
)
858 for Offset
in m
._SubImages
:
859 SectionInfo
+= ", " + str(m
._SubImages
[Offset
])
865 Type
, = m
._TYPE
_.unpack_from(m
._BUF
_, m
._OFF
_)
866 Size1
, Size2
, Size3
= m
._SIZE
_.unpack_from(m
._BUF
_, m
._OFF
_)
867 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
869 if Type
not in m
._SectionSubImages
:
870 # no need to extract sub-image, keep all in this Image object
871 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + Size
])
873 # keep header in this Image object
874 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._HEADER
_SIZE
_])
876 # use new Image object to represent payload, which may be another kind
877 # of image such as PE32
879 PayloadOffset
= m
._HEADER
_SIZE
_
880 PayloadLen
= m
.Size
- m
._HEADER
_SIZE
_
881 Payload
= m
._SectionSubImages
[m
.Type
]()
882 Payload
.frombuffer(m
._BUF
_, m
._OFF
_ + m
._HEADER
_SIZE
_, PayloadLen
)
883 m
._SubImages
[PayloadOffset
] = Payload
887 def _SetSize(m
, Size
):
889 Size2
= (Size
& 0xFF00) >> 8
890 Size3
= (Size
& 0xFF0000) >> 16
891 m
.SetField(m
._SIZE
_, 0, Size1
, Size2
, Size3
)
894 Size1
, Size2
, Size3
= m
.GetField(m
._SIZE
_)
895 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
897 def _SetType(m
, Type
):
898 m
.SetField(m
._TYPE
_, 0, Type
)
901 return m
.GetField(m
._TYPE
_)[0]
903 def _GetAlignment(m
):
906 def _SetAlignment(m
, Alignment
):
907 m
._Alignment
= Alignment
908 AlignmentMask
= Alignment
- 1
909 # section alignment is actually for payload, so we need to add header size
910 PayloadOffset
= m
._OFF
_ + m
._HEADER
_SIZE
_
911 if (PayloadOffset
& (~AlignmentMask
)) == 0:
913 NewOffset
= (PayloadOffset
+ AlignmentMask
) & (~AlignmentMask
)
914 while (NewOffset
- PayloadOffset
) < m
._HEADER
_SIZE
_:
915 NewOffset
+= m
._Alignment
920 for Offset
in m
._SubImages
:
921 m
._SubImages
[Offset
].tofile(f
)
923 Type
= property(_GetType
, _SetType
)
924 Size
= property(_GetSize
, _SetSize
)
925 Alignment
= property(_GetAlignment
, _SetAlignment
)
929 # A class for Ffs Section
932 _FfsFormat
= "24B%(payload_size)sB"
933 # skip IntegrityCheck
934 _HEADER_
= struct
.Struct("1I2H8B 2x 1B 1B 3B 1B")
935 _HEADER_SIZE_
= _HEADER_
.size
937 _NAME_
= struct
.Struct("1I2H8B")
938 _INT_CHECK_
= struct
.Struct("16x 1H")
939 _TYPE_
= struct
.Struct("18x 1B")
940 _ATTR_
= struct
.Struct("19x 1B")
941 _SIZE_
= struct
.Struct("20x 3B")
942 _STATE_
= struct
.Struct("23x 1B")
944 VTF_GUID
= "1BA0062E-C779-4582-8566-336AE8F78F09"
946 FFS_ATTRIB_FIXED
= 0x04
947 FFS_ATTRIB_DATA_ALIGNMENT
= 0x38
948 FFS_ATTRIB_CHECKSUM
= 0x40
954 0x03 : "SECURITY_CORE",
959 0x08 : "COMBINED_PEIM_DRIVER",
960 0x09 : "APPLICATION",
962 0x0B : "FIRMWARE_VOLUME_IMAGE",
963 0x0C : "COMBINED_SMM_DXE",
965 0x0E : "MM_STANDALONE",
966 0x0F : "MM_CORE_STANDALONE",
980 self
.Sections
= sdict()
988 Indention
= ' ' * gIndention
990 FfsInfo
+= "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \
991 (Ffs
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
, self
.Guid
, self
.FreeSpace
, self
.Alignment
)
992 SectionInfo
= '\n'.join([str(self
.Sections
[Offset
]) for Offset
in self
.Sections
])
994 return FfsInfo
+ SectionInfo
+ "\n"
1003 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
1004 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
1006 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
1008 # Pad FFS may use the same GUID. We need to avoid it.
1009 if self
.Type
== 0xf0:
1010 self
.__ID
__ = str(uuid
.uuid1()).upper()
1012 self
.__ID
__ = self
.Guid
1014 # Traverse the SECTION. RAW and PAD do not have sections
1015 if self
.Type
not in [0xf0, 0x01] and Size
> 0 and Size
< 0xFFFFFF:
1017 SectionStartAddress
= self
._HEADER
_SIZE
_
1018 while SectionStartAddress
< EndOfFfs
:
1019 SectionObj
= Section()
1020 SectionObj
.frombuffer(self
, SectionStartAddress
)
1021 #f = open(repr(SectionObj), 'wb')
1022 #SectionObj.Size = 0
1023 #SectionObj.tofile(f)
1025 self
.Sections
[SectionStartAddress
] = SectionObj
1026 SectionStartAddress
+= len(SectionObj
)
1027 SectionStartAddress
= (SectionStartAddress
+ 3) & (~
3)
1032 def SetFreeSpace(self
, Size
):
1033 self
.FreeSpace
= Size
1036 return gGuidStringFormat
% self
.Name
1038 def _SetName(self
, Value
):
1039 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1040 self
.SetField(self
._NAME
_, 0, Value
)
1043 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1044 return self
.GetField(self
._NAME
_)
1046 def _SetSize(m
, Size
):
1048 Size2
= (Size
& 0xFF00) >> 8
1049 Size3
= (Size
& 0xFF0000) >> 16
1050 m
.SetField(m
._SIZE
_, 0, Size1
, Size2
, Size3
)
1053 Size1
, Size2
, Size3
= m
.GetField(m
._SIZE
_)
1054 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
1056 def _SetType(m
, Type
):
1057 m
.SetField(m
._TYPE
_, 0, Type
)
1060 return m
.GetField(m
._TYPE
_)[0]
1062 def _SetAttributes(self
, Value
):
1063 self
.SetField(m
._ATTR
_, 0, Value
)
1065 def _GetAttributes(self
):
1066 return self
.GetField(self
._ATTR
_)[0]
1068 def _GetFixed(self
):
1069 if (self
.Attributes
& self
.FFS_ATTRIB_FIXED
) != 0:
1073 def _GetCheckSum(self
):
1074 if (self
.Attributes
& self
.FFS_ATTRIB_CHECKSUM
) != 0:
1078 def _GetAlignment(self
):
1079 return (self
.Attributes
& self
.FFS_ATTRIB_DATA_ALIGNMENT
) >> 3
1081 def _SetState(self
, Value
):
1082 self
.SetField(m
._STATE
_, 0, Value
)
1084 def _GetState(self
):
1085 return self
.GetField(m
._STATE
_)[0]
1087 Name
= property(_GetName
, _SetName
)
1088 Guid
= property(_GetGuid
)
1089 Type
= property(_GetType
, _SetType
)
1090 Size
= property(_GetSize
, _SetSize
)
1091 Attributes
= property(_GetAttributes
, _SetAttributes
)
1092 Fixed
= property(_GetFixed
)
1093 Checksum
= property(_GetCheckSum
)
1094 Alignment
= property(_GetAlignment
)
1095 State
= property(_GetState
, _SetState
)
1097 ## FirmwareVolume() class
1099 # A class for Firmware Volume
1101 class FirmwareVolume(Image
):
1102 # Read FvLength, Attributes, HeaderLength, Checksum
1103 _HEADER_
= struct
.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")
1104 _HEADER_SIZE_
= _HEADER_
.size
1106 _FfsGuid
= "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
1108 _GUID_
= struct
.Struct("16x 1I2H8B")
1109 _LENGTH_
= struct
.Struct("16x 16x 1Q")
1110 _SIG_
= struct
.Struct("16x 16x 8x 1I")
1111 _ATTR_
= struct
.Struct("16x 16x 8x 4x 1I")
1112 _HLEN_
= struct
.Struct("16x 16x 8x 4x 4x 1H")
1113 _CHECKSUM_
= struct
.Struct("16x 16x 8x 4x 4x 2x 1H")
1115 def __init__(self
, Name
=''):
1116 Image
.__init
__(self
)
1118 self
.FfsDict
= sdict()
1119 self
.OrderedFfsDict
= sdict()
1120 self
.UnDispatchedFfsDict
= sdict()
1121 self
.ProtocolList
= sdict()
1123 def CheckArchProtocol(self
):
1124 for Item
in EotGlobalData
.gArchProtocolGuids
:
1125 if Item
.lower() not in EotGlobalData
.gProtocolList
:
1131 def ParseDepex(self
, Depex
, Type
):
1134 List
= EotGlobalData
.gPpiList
1135 if Type
== 'Protocol':
1136 List
= EotGlobalData
.gProtocolList
1141 CouldBeLoaded
= True
1142 for Index
in range(0, len(Depex
.Expression
)):
1143 Item
= Depex
.Expression
[Index
]
1146 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1147 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
1148 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
1151 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1152 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
1153 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
1156 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1157 if Guid
.lower() in List
:
1158 DepexStack
.append(True)
1159 DepexList
.append(Guid
)
1161 DepexStack
.append(False)
1162 DepexList
.append(Guid
)
1164 elif Item
== 0x03 or Item
== 0x04:
1165 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
1166 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
1168 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
1169 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
1171 DepexStack
.append(True)
1172 DepexList
.append('TRUE')
1173 DepexString
= DepexString
+ 'TRUE' + ' '
1175 DepexStack
.append(False)
1176 DepexList
.append('False')
1177 DepexString
= DepexString
+ 'FALSE' + ' '
1179 if Index
!= len(Depex
.Expression
) - 1:
1180 CouldBeLoaded
= False
1182 CouldBeLoaded
= DepexStack
.pop()
1184 CouldBeLoaded
= False
1186 DepexString
= DepexList
[0].strip()
1187 return (CouldBeLoaded
, DepexString
, FileDepex
)
1189 def Dispatch(self
, Db
= None):
1192 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
1193 # Find PeiCore, DexCore, PeiPriori, DxePriori first
1194 FfsSecCoreGuid
= None
1195 FfsPeiCoreGuid
= None
1196 FfsDxeCoreGuid
= None
1197 FfsPeiPrioriGuid
= None
1198 FfsDxePrioriGuid
= None
1199 for FfsID
in self
.UnDispatchedFfsDict
:
1200 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1201 if Ffs
.Type
== 0x03:
1202 FfsSecCoreGuid
= FfsID
1204 if Ffs
.Type
== 0x04:
1205 FfsPeiCoreGuid
= FfsID
1207 if Ffs
.Type
== 0x05:
1208 FfsDxeCoreGuid
= FfsID
1210 if Ffs
.Guid
.lower() == gPeiAprioriFileNameGuid
:
1211 FfsPeiPrioriGuid
= FfsID
1213 if Ffs
.Guid
.lower() == gAprioriGuid
:
1214 FfsDxePrioriGuid
= FfsID
1217 # Parse SEC_CORE first
1218 if FfsSecCoreGuid
is not None:
1219 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
1220 self
.LoadPpi(Db
, FfsSecCoreGuid
)
1223 if FfsPeiCoreGuid
is not None:
1224 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
1225 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
1226 if FfsPeiPrioriGuid
is not None:
1227 # Load PEIM described in priori file
1228 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
1229 if len(FfsPeiPriori
.Sections
) == 1:
1230 Section
= FfsPeiPriori
.Sections
.popitem()[1]
1231 if Section
.Type
== 0x19:
1232 GuidStruct
= struct
.Struct('1I2H8B')
1234 while len(Section
) > Start
:
1235 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
1236 GuidString
= gGuidStringFormat
% Guid
1238 if GuidString
in self
.UnDispatchedFfsDict
:
1239 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
1240 self
.LoadPpi(Db
, GuidString
)
1242 self
.DisPatchPei(Db
)
1245 if FfsDxeCoreGuid
is not None:
1246 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
1247 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
1248 if FfsDxePrioriGuid
is not None:
1249 # Load PEIM described in priori file
1250 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
1251 if len(FfsDxePriori
.Sections
) == 1:
1252 Section
= FfsDxePriori
.Sections
.popitem()[1]
1253 if Section
.Type
== 0x19:
1254 GuidStruct
= struct
.Struct('1I2H8B')
1256 while len(Section
) > Start
:
1257 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
1258 GuidString
= gGuidStringFormat
% Guid
1260 if GuidString
in self
.UnDispatchedFfsDict
:
1261 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
1262 self
.LoadProtocol(Db
, GuidString
)
1264 self
.DisPatchDxe(Db
)
1266 def LoadProtocol(self
, Db
, ModuleGuid
):
1267 SqlCommand
= """select GuidValue from Report
1268 where SourceFileFullPath in
1269 (select Value1 from Inf where BelongsToFile =
1270 (select BelongsToFile from Inf
1271 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
1273 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
1274 % (ModuleGuid
, 5001, 3007)
1275 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1276 for Record
in RecordSet
:
1277 SqlCommand
= """select Value2 from Inf where BelongsToFile =
1278 (select DISTINCT BelongsToFile from Inf
1280 (select SourceFileFullPath from Report
1281 where GuidValue like '%s' and ItemMode = 'Callback'))
1282 and Value1 = 'FILE_GUID'""" % Record
[0]
1283 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
1284 if CallBackSet
!= []:
1285 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
1287 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
1289 def LoadPpi(self
, Db
, ModuleGuid
):
1290 SqlCommand
= """select GuidValue from Report
1291 where SourceFileFullPath in
1292 (select Value1 from Inf where BelongsToFile =
1293 (select BelongsToFile from Inf
1294 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
1296 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
1297 % (ModuleGuid
, 5001, 3007)
1298 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1299 for Record
in RecordSet
:
1300 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
1302 def DisPatchDxe(self
, Db
):
1304 ScheduleList
= sdict()
1305 for FfsID
in self
.UnDispatchedFfsDict
:
1306 CouldBeLoaded
= False
1309 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1310 if Ffs
.Type
== 0x07:
1312 IsFoundDepex
= False
1313 for Section
in Ffs
.Sections
.values():
1315 if Section
.Type
== 0x13:
1317 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
1319 if Section
.Type
== 0x01:
1320 CompressSections
= Section
._SubImages
[4]
1321 for CompressSection
in CompressSections
.Sections
:
1322 if CompressSection
.Type
== 0x13:
1324 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
1326 if CompressSection
.Type
== 0x02:
1327 NewSections
= CompressSection
._SubImages
[4]
1328 for NewSection
in NewSections
.Sections
:
1329 if NewSection
.Type
== 0x13:
1331 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
1335 if not IsFoundDepex
:
1336 CouldBeLoaded
= self
.CheckArchProtocol()
1343 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
1344 NewFfs
.Depex
= DepexString
1345 if FileDepex
is not None:
1346 ScheduleList
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
1348 ScheduleList
[FfsID
] = NewFfs
1350 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
1352 for FfsID
in ScheduleList
:
1353 NewFfs
= ScheduleList
.pop(FfsID
)
1355 self
.OrderedFfsDict
[FfsID
] = NewFfs
1356 self
.LoadProtocol(Db
, FfsID
)
1358 SqlCommand
= """select Value2 from Inf
1359 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
1360 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
1361 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1363 FfsName
= RecordSet
[0][0]
1366 self
.DisPatchDxe(Db
)
1368 def DisPatchPei(self
, Db
):
1370 for FfsID
in self
.UnDispatchedFfsDict
:
1371 CouldBeLoaded
= True
1374 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1375 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
1377 for Section
in Ffs
.Sections
.values():
1378 if Section
.Type
== 0x1B:
1379 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
1382 if Section
.Type
== 0x01:
1383 CompressSections
= Section
._SubImages
[4]
1384 for CompressSection
in CompressSections
.Sections
:
1385 if CompressSection
.Type
== 0x1B:
1386 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
1388 if CompressSection
.Type
== 0x02:
1389 NewSections
= CompressSection
._SubImages
[4]
1390 for NewSection
in NewSections
.Sections
:
1391 if NewSection
.Type
== 0x1B:
1392 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
1398 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
1399 NewFfs
.Depex
= DepexString
1400 self
.OrderedFfsDict
[FfsID
] = NewFfs
1401 self
.LoadPpi(Db
, FfsID
)
1403 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
1406 self
.DisPatchPei(Db
)
1412 FvInfo
= '\n' + ' ' * gIndention
1413 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
1414 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
1416 return FvInfo
+ FfsInfo
1419 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
1421 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_+Size
])
1425 FfsStartAddress
= self
.HeaderSize
1427 while FfsStartAddress
< EndOfFv
:
1429 FfsObj
.frombuffer(self
, FfsStartAddress
)
1430 FfsId
= repr(FfsObj
)
1431 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
1432 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
1433 if LastFfsObj
is not None:
1434 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
1436 if FfsId
in self
.FfsDict
:
1437 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
1438 ExtraData
="\t%s @ %s\n\t%s @ %s" \
1439 % (FfsObj
.Guid
, FfsObj
.Offset
,
1440 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
1441 self
.FfsDict
[FfsId
] = FfsObj
1442 if LastFfsObj
is not None:
1443 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
1445 FfsStartAddress
+= len(FfsObj
)
1447 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
1448 # The next FFS must be at the latest next 8-byte aligned address
1450 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
1453 def _GetAttributes(self
):
1454 return self
.GetField(self
._ATTR
_, 0)[0]
1457 return self
.GetField(self
._LENGTH
_, 0)[0]
1459 def _GetChecksum(self
):
1460 return self
.GetField(self
._CHECKSUM
_, 0)[0]
1462 def _GetHeaderLength(self
):
1463 return self
.GetField(self
._HLEN
_, 0)[0]
1465 def _GetFileSystemGuid(self
):
1466 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
1468 Attributes
= property(_GetAttributes
)
1469 Size
= property(_GetSize
)
1470 Checksum
= property(_GetChecksum
)
1471 HeaderSize
= property(_GetHeaderLength
)
1472 FileSystemGuid
= property(_GetFileSystemGuid
)
1474 ## MultipleFv() class
1476 # A class for Multiple FV
1478 class MultipleFv(FirmwareVolume
):
1479 def __init__(self
, FvList
):
1480 FirmwareVolume
.__init
__(self
)
1482 for FvPath
in FvList
:
1483 FvName
= os
.path
.splitext(os
.path
.split(FvPath
)[1])[0]
1484 Fd
= open(FvPath
, 'rb')
1487 Buf
.fromfile(Fd
, os
.path
.getsize(FvPath
))
1491 Fv
= FirmwareVolume(FvName
)
1492 Fv
.frombuffer(Buf
, 0, len(Buf
))
1494 self
.BasicInfo
.append([Fv
.Name
, Fv
.FileSystemGuid
, Fv
.Size
])
1495 self
.FfsDict
.append(Fv
.FfsDict
)
1499 # This class is used to define Eot main entrance
1501 # @param object: Inherited from object class
1506 # @param self: The object pointer
1508 def __init__(self
, CommandLineOption
=True, IsInit
=True, SourceFileList
=None, \
1509 IncludeDirList
=None, DecFileList
=None, GuidList
=None, LogFile
=None,
1510 FvFileList
="", MapFileList
="", Report
='Report.html', Dispatch
=None):
1511 # Version and Copyright
1512 self
.VersionNumber
= ("0.02" + " " + gBUILD_VERSION
)
1513 self
.Version
= "%prog Version " + self
.VersionNumber
1514 self
.Copyright
= "Copyright (c) 2008 - 2018, Intel Corporation All rights reserved."
1515 self
.Report
= Report
1517 self
.IsInit
= IsInit
1518 self
.SourceFileList
= SourceFileList
1519 self
.IncludeDirList
= IncludeDirList
1520 self
.DecFileList
= DecFileList
1521 self
.GuidList
= GuidList
1522 self
.LogFile
= LogFile
1523 self
.FvFileList
= FvFileList
1524 self
.MapFileList
= MapFileList
1525 self
.Dispatch
= Dispatch
1527 # Check workspace environment
1528 if "EFI_SOURCE" not in os
.environ
:
1529 if "EDK_SOURCE" not in os
.environ
:
1532 EotGlobalData
.gEDK_SOURCE
= os
.path
.normpath(os
.getenv("EDK_SOURCE"))
1534 EotGlobalData
.gEFI_SOURCE
= os
.path
.normpath(os
.getenv("EFI_SOURCE"))
1535 EotGlobalData
.gEDK_SOURCE
= os
.path
.join(EotGlobalData
.gEFI_SOURCE
, 'Edk')
1537 if "WORKSPACE" not in os
.environ
:
1538 EdkLogger
.error("EOT", BuildToolError
.ATTRIBUTE_NOT_AVAILABLE
, "Environment variable not found",
1539 ExtraData
="WORKSPACE")
1541 EotGlobalData
.gWORKSPACE
= os
.path
.normpath(os
.getenv("WORKSPACE"))
1543 EotGlobalData
.gMACRO
['WORKSPACE'] = EotGlobalData
.gWORKSPACE
1544 EotGlobalData
.gMACRO
['EFI_SOURCE'] = EotGlobalData
.gEFI_SOURCE
1545 EotGlobalData
.gMACRO
['EDK_SOURCE'] = EotGlobalData
.gEDK_SOURCE
1547 # Parse the options and args
1548 if CommandLineOption
:
1552 for FvFile
in GetSplitValueList(self
.FvFileList
, ' '):
1553 FvFile
= os
.path
.normpath(FvFile
)
1554 if not os
.path
.isfile(FvFile
):
1555 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % FvFile
)
1556 EotGlobalData
.gFV_FILE
.append(FvFile
)
1558 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "The fv file list of target platform was not specified")
1560 if self
.MapFileList
:
1561 for MapFile
in GetSplitValueList(self
.MapFileList
, ' '):
1562 MapFile
= os
.path
.normpath(MapFile
)
1563 if not os
.path
.isfile(MapFile
):
1564 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % MapFile
)
1565 EotGlobalData
.gMAP_FILE
.append(MapFile
)
1567 # Generate source file list
1568 self
.GenerateSourceFileList(self
.SourceFileList
, self
.IncludeDirList
)
1570 # Generate guid list of dec file list
1571 self
.ParseDecFile(self
.DecFileList
)
1573 # Generate guid list from GUID list file
1574 self
.ParseGuidList(self
.GuidList
)
1577 EotGlobalData
.gDb
= Database
.Database(Database
.DATABASE_PATH
)
1578 EotGlobalData
.gDb
.InitDatabase(self
.IsInit
)
1580 # Build ECC database
1581 self
.BuildDatabase()
1583 # Parse Ppi/Protocol
1584 self
.ParseExecutionOrder()
1586 # Merge Identifier tables
1587 self
.GenerateQueryTable()
1589 # Generate report database
1590 self
.GenerateReportDatabase()
1599 self
.GenerateReport()
1602 self
.ConvertLogFile(self
.LogFile
)
1605 EdkLogger
.quiet("EOT FINISHED!")
1608 EotGlobalData
.gDb
.Close()
1610 ## ParseDecFile() method
1612 # parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}
1613 # The Dict is stored in EotGlobalData.gGuidDict
1615 # @param self: The object pointer
1616 # @param DecFileList: A list of all DEC files
1618 def ParseDecFile(self
, DecFileList
):
1620 path
= os
.path
.normpath(DecFileList
)
1621 lfr
= open(path
, 'rb')
1623 path
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1624 if os
.path
.exists(path
):
1625 dfr
= open(path
, 'rb')
1627 line
= CleanString(line
)
1628 list = line
.split('=')
1630 EotGlobalData
.gGuidDict
[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())
1633 ## ParseGuidList() method
1635 # Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}
1636 # The Dict is stored in EotGlobalData.gGuidDict
1638 # @param self: The object pointer
1639 # @param GuidList: A list of all GUID and its value
1641 def ParseGuidList(self
, GuidList
):
1642 Path
= os
.path
.join(EotGlobalData
.gWORKSPACE
, GuidList
)
1643 if os
.path
.isfile(Path
):
1644 for Line
in open(Path
):
1645 (GuidName
, GuidValue
) = Line
.split()
1646 EotGlobalData
.gGuidDict
[GuidName
] = GuidValue
1648 ## ConvertLogFile() method
1650 # Parse a real running log file to get real dispatch order
1651 # The result is saved to old file name + '.new'
1653 # @param self: The object pointer
1654 # @param LogFile: A real running log file name
1656 def ConvertLogFile(self
, LogFile
):
1661 lfr
= open(LogFile
, 'rb')
1662 lfw
= open(LogFile
+ '.new', 'wb')
1665 line
= line
.replace('.efi', '')
1666 index
= line
.find("Loading PEIM at ")
1668 newline
.append(line
[index
+ 55 : ])
1670 index
= line
.find("Loading driver at ")
1672 newline
.append(line
[index
+ 57 : ])
1675 for line
in newline
:
1676 lfw
.write(line
+ '\r\n')
1683 ## GenerateSourceFileList() method
1685 # Generate a list of all source files
1686 # 1. Search the file list one by one
1687 # 2. Store inf file name with source file names under it like
1688 # { INF file name: [source file1, source file2, ...]}
1689 # 3. Search the include list to find all .h files
1690 # 4. Store source file list to EotGlobalData.gSOURCE_FILES
1691 # 5. Store INF file list to EotGlobalData.gINF_FILES
1693 # @param self: The object pointer
1694 # @param SourceFileList: A list of all source files
1695 # @param IncludeFileList: A list of all include files
1697 def GenerateSourceFileList(self
, SourceFileList
, IncludeFileList
):
1698 EdkLogger
.quiet("Generating source files list ... ")
1699 mSourceFileList
= []
1703 mCurrentInfFile
= ''
1704 mCurrentSourceFileList
= []
1707 sfl
= open(SourceFileList
, 'rb')
1709 line
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1710 if line
[-2:].upper() == '.C' or line
[-2:].upper() == '.H':
1711 if line
not in mCurrentSourceFileList
:
1712 mCurrentSourceFileList
.append(line
)
1713 mSourceFileList
.append(line
)
1714 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % line
)
1715 if line
[-4:].upper() == '.INF':
1716 if mCurrentInfFile
!= '':
1717 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1718 mCurrentSourceFileList
= []
1719 mCurrentInfFile
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
))
1720 EotGlobalData
.gOP_INF
.write('%s\n' % mCurrentInfFile
)
1721 if mCurrentInfFile
not in mFileList
:
1722 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1724 # Get all include files from packages
1726 ifl
= open(IncludeFileList
, 'rb')
1728 if not line
.strip():
1730 newline
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1731 for Root
, Dirs
, Files
in os
.walk(str(newline
)):
1733 FullPath
= os
.path
.normpath(os
.path
.join(Root
, File
))
1734 if FullPath
not in mSourceFileList
and File
[-2:].upper() == '.H':
1735 mSourceFileList
.append(FullPath
)
1736 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % FullPath
)
1737 if FullPath
not in mDecFileList
and File
.upper().find('.DEC') > -1:
1738 mDecFileList
.append(FullPath
)
1740 EotGlobalData
.gSOURCE_FILES
= mSourceFileList
1741 EotGlobalData
.gOP_SOURCE_FILES
.close()
1743 EotGlobalData
.gINF_FILES
= mFileList
1744 EotGlobalData
.gOP_INF
.close()
1746 ## GenerateReport() method
1748 # Generate final HTML report
1750 # @param self: The object pointer
1752 def GenerateReport(self
):
1753 EdkLogger
.quiet("Generating report file ... ")
1754 Rep
= Report(self
.Report
, EotGlobalData
.gFV
, self
.Dispatch
)
1755 Rep
.GenerateReport()
1757 ## LoadMapInfo() method
1759 # Load map files and parse them
1761 # @param self: The object pointer
1763 def LoadMapInfo(self
):
1764 if EotGlobalData
.gMAP_FILE
!= []:
1765 EdkLogger
.quiet("Parsing Map file ... ")
1766 EotGlobalData
.gMap
= ParseMapFile(EotGlobalData
.gMAP_FILE
)
1768 ## LoadFvInfo() method
1770 # Load FV binary files and parse them
1772 # @param self: The object pointer
1774 def LoadFvInfo(self
):
1775 EdkLogger
.quiet("Parsing FV file ... ")
1776 EotGlobalData
.gFV
= MultipleFv(EotGlobalData
.gFV_FILE
)
1777 EotGlobalData
.gFV
.Dispatch(EotGlobalData
.gDb
)
1779 for Protocol
in EotGlobalData
.gProtocolList
:
1780 EotGlobalData
.gOP_UN_MATCHED_IN_LIBRARY_CALLING
.write('%s\n' %Protocol
)
1782 ## GenerateReportDatabase() method
1784 # Generate data for the information needed by report
1785 # 1. Update name, macro and value of all found PPI/PROTOCOL GUID
1786 # 2. Install hard coded PPI/PROTOCOL
1788 # @param self: The object pointer
1790 def GenerateReportDatabase(self
):
1791 EdkLogger
.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")
1793 # Update Protocol/Ppi Guid
1794 SqlCommand
= """select DISTINCT GuidName from Report"""
1795 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1796 for Record
in RecordSet
:
1797 GuidName
= Record
[0]
1802 # Find guid value defined in Dec file
1803 if GuidName
in EotGlobalData
.gGuidDict
:
1804 GuidValue
= EotGlobalData
.gGuidDict
[GuidName
]
1805 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1806 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1809 # Search defined Macros for guid name
1810 SqlCommand
="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName
1811 GuidMacroSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1812 # Ignore NULL result
1813 if not GuidMacroSet
:
1815 GuidMacro
= GuidMacroSet
[0][0].strip()
1818 # Find Guid value of Guid Macro
1819 SqlCommand
="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro
, MODEL_IDENTIFIER_MACRO_DEFINE
)
1820 GuidValueSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1821 if GuidValueSet
!= []:
1822 GuidValue
= GuidValueSet
[0][0]
1823 GuidValue
= GuidValue
[GuidValue
.find(GuidMacro
) + len(GuidMacro
) :]
1824 GuidValue
= GuidValue
.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()
1825 GuidValue
= GuidStructureStringToGuidString(GuidValue
)
1826 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1827 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1830 # Update Hard Coded Ppi/Protocol
1831 SqlCommand
= """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""
1832 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1833 for Record
in RecordSet
:
1834 if Record
[1] == 'Ppi':
1835 EotGlobalData
.gPpiList
[Record
[0].lower()] = -2
1836 if Record
[1] == 'Protocol':
1837 EotGlobalData
.gProtocolList
[Record
[0].lower()] = -2
1839 ## GenerateQueryTable() method
1841 # Generate two tables improve query performance
1843 # @param self: The object pointer
1845 def GenerateQueryTable(self
):
1846 EdkLogger
.quiet("Generating temp query table for analysis ... ")
1847 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1848 SqlCommand
= """insert into Query (Name, Modifier, Value, Model)
1849 select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \
1850 % (Identifier
[0], MODEL_IDENTIFIER_VARIABLE
, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION
)
1851 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1852 SqlCommand
= """insert into Query2 (Name, Modifier, Value, Model)
1853 select Name, Modifier, Value, Model from %s where Model = %s""" \
1854 % (Identifier
[0], MODEL_IDENTIFIER_MACRO_DEFINE
)
1855 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1857 ## ParseExecutionOrder() method
1859 # Get final execution order
1861 # 2. Search all PROTOCOL
1863 # @param self: The object pointer
1865 def ParseExecutionOrder(self
):
1866 EdkLogger
.quiet("Searching Ppi/Protocol ... ")
1867 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1868 ModuleID
, ModuleName
, ModuleGuid
, SourceFileID
, SourceFileFullPath
, ItemName
, ItemType
, ItemMode
, GuidName
, GuidMacro
, GuidValue
, BelongsToFunction
, Enabled
= \
1869 -1, '', '', -1, '', '', '', '', '', '', '', '', 0
1871 SourceFileID
= Identifier
[0].replace('Identifier', '')
1872 SourceFileFullPath
= Identifier
[1]
1873 Identifier
= Identifier
[0]
1876 ItemMode
= 'Produced'
1877 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1878 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1879 % (Identifier
, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1880 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1882 ItemMode
= 'Produced'
1883 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1884 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1885 % (Identifier
, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1886 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1888 SearchPpiCallFunction(Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1890 ItemMode
= 'Consumed'
1891 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1892 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1893 % (Identifier
, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1894 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1896 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Ppi', ItemMode
)
1898 ItemMode
= 'Callback'
1899 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1900 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1901 % (Identifier
, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1902 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1905 ItemMode
= 'Produced'
1906 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1907 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1908 % (Identifier
, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1909 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1911 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1912 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1913 % (Identifier
, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1914 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1916 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1918 ItemMode
= 'Consumed'
1919 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1920 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1921 % (Identifier
, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1922 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1924 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1925 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1926 % (Identifier
, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1927 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1929 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1931 ItemMode
= 'Callback'
1932 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1933 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1934 % (Identifier
, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1935 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1937 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1940 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)
1941 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)
1942 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)
1943 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)
1944 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)
1945 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)
1946 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)
1947 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)
1948 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)
1950 EotGlobalData
.gDb
.Conn
.commit()
1953 ## BuildDatabase() methoc
1955 # Build the database for target
1957 # @param self: The object pointer
1959 def BuildDatabase(self
):
1960 # Clean report table
1961 EotGlobalData
.gDb
.TblReport
.Drop()
1962 EotGlobalData
.gDb
.TblReport
.Create()
1966 self
.BuildMetaDataFileDatabase(EotGlobalData
.gINF_FILES
)
1967 EdkLogger
.quiet("Building database for source code ...")
1968 c
.CreateCCodeDB(EotGlobalData
.gSOURCE_FILES
)
1969 EdkLogger
.quiet("Building database for source code done!")
1971 EotGlobalData
.gIdentifierTableList
= GetTableList((MODEL_FILE_C
, MODEL_FILE_H
), 'Identifier', EotGlobalData
.gDb
)
1973 ## BuildMetaDataFileDatabase() method
1975 # Build the database for meta data files
1977 # @param self: The object pointer
1978 # @param Inf_Files: A list for all INF files
1980 def BuildMetaDataFileDatabase(self
, Inf_Files
):
1981 EdkLogger
.quiet("Building database for meta data files ...")
1982 for InfFile
in Inf_Files
:
1983 EdkLogger
.quiet("Parsing %s ..." % str(InfFile
))
1984 EdkInfParser(InfFile
, EotGlobalData
.gDb
, Inf_Files
[InfFile
], '')
1986 EotGlobalData
.gDb
.Conn
.commit()
1987 EdkLogger
.quiet("Building database for meta data files done!")
1989 ## ParseOption() method
1991 # Parse command line options
1993 # @param self: The object pointer
1995 def ParseOption(self
):
1996 (Options
, Target
) = self
.EotOptionParser()
1999 self
.SetLogLevel(Options
)
2001 if Options
.FvFileList
:
2002 self
.FvFileList
= Options
.FvFileList
2004 if Options
.MapFileList
:
2005 self
.MapFileList
= Options
.FvMapFileList
2007 if Options
.SourceFileList
:
2008 self
.SourceFileList
= Options
.SourceFileList
2010 if Options
.IncludeDirList
:
2011 self
.IncludeDirList
= Options
.IncludeDirList
2013 if Options
.DecFileList
:
2014 self
.DecFileList
= Options
.DecFileList
2016 if Options
.GuidList
:
2017 self
.GuidList
= Options
.GuidList
2020 self
.LogFile
= Options
.LogFile
2022 if Options
.keepdatabase
:
2025 ## SetLogLevel() method
2027 # Set current log level of the tool based on args
2029 # @param self: The object pointer
2030 # @param Option: The option list including log level setting
2032 def SetLogLevel(self
, Option
):
2033 if Option
.verbose
is not None:
2034 EdkLogger
.SetLevel(EdkLogger
.VERBOSE
)
2035 elif Option
.quiet
is not None:
2036 EdkLogger
.SetLevel(EdkLogger
.QUIET
)
2037 elif Option
.debug
is not None:
2038 EdkLogger
.SetLevel(Option
.debug
+ 1)
2040 EdkLogger
.SetLevel(EdkLogger
.INFO
)
2042 ## EotOptionParser() method
2044 # Using standard Python module optparse to parse command line option of this tool.
2046 # @param self: The object pointer
2048 # @retval Opt A optparse.Values object containing the parsed options
2049 # @retval Args Target of build command
2051 def EotOptionParser(self
):
2052 Parser
= OptionParser(description
= self
.Copyright
, version
= self
.Version
, prog
= "Eot.exe", usage
= "%prog [options]")
2053 Parser
.add_option("-m", "--makefile filename", action
="store", type="string", dest
='MakeFile',
2054 help="Specify a makefile for the platform.")
2055 Parser
.add_option("-c", "--dsc filename", action
="store", type="string", dest
="DscFile",
2056 help="Specify a dsc file for the platform.")
2057 Parser
.add_option("-f", "--fv filename", action
="store", type="string", dest
="FvFileList",
2058 help="Specify fv file list, quoted by \"\".")
2059 Parser
.add_option("-a", "--map filename", action
="store", type="string", dest
="MapFileList",
2060 help="Specify map file list, quoted by \"\".")
2061 Parser
.add_option("-s", "--source files", action
="store", type="string", dest
="SourceFileList",
2062 help="Specify source file list by a file")
2063 Parser
.add_option("-i", "--include dirs", action
="store", type="string", dest
="IncludeDirList",
2064 help="Specify include dir list by a file")
2065 Parser
.add_option("-e", "--dec files", action
="store", type="string", dest
="DecFileList",
2066 help="Specify dec file list by a file")
2067 Parser
.add_option("-g", "--guid list", action
="store", type="string", dest
="GuidList",
2068 help="Specify guid file list by a file")
2069 Parser
.add_option("-l", "--log filename", action
="store", type="string", dest
="LogFile",
2070 help="Specify real execution log file")
2072 Parser
.add_option("-k", "--keepdatabase", action
="store_true", type=None, help="The existing Eot database will not be cleaned except report information if this option is specified.")
2074 Parser
.add_option("-q", "--quiet", action
="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
2075 Parser
.add_option("-v", "--verbose", action
="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
2076 "including library instances selected, final dependency expression, "\
2077 "and warning messages, etc.")
2078 Parser
.add_option("-d", "--debug", action
="store", type="int", help="Enable debug messages at specified level.")
2080 (Opt
, Args
)=Parser
.parse_args()
2086 # This acts like the main() function for the script, unless it is 'import'ed into another
2089 if __name__
== '__main__':
2090 # Initialize log system
2091 EdkLogger
.Initialize()
2092 EdkLogger
.IsRaiseError
= False
2093 EdkLogger
.quiet(time
.strftime("%H:%M:%S, %b.%d %Y ", time
.localtime()) + "[00:00]" + "\n")
2095 StartTime
= time
.clock()
2097 FinishTime
= time
.clock()
2099 BuildDuration
= time
.strftime("%M:%S", time
.gmtime(int(round(FinishTime
- StartTime
))))
2100 EdkLogger
.quiet("\n%s [%s]" % (time
.strftime("%H:%M:%S, %b.%d %Y", time
.localtime()), BuildDuration
))