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 import Eot
.EotGlobalData
as 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 Eot
.Parser
import *
26 from Eot
.InfParserLite
import EdkInfParser
27 from Common
.StringUtils
import GetSplitValueList
29 from Eot
import Database
30 from array
import array
31 from Eot
.Report
import Report
32 from Common
.BuildVersion
import gBUILD_VERSION
33 from Eot
.Parser
import ConvertGuid
34 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
39 from GenFds
.AprioriSection
import DXE_APRIORI_GUID
, PEI_APRIORI_GUID
41 gGuidStringFormat
= "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"
45 _HEADER_
= struct
.Struct("")
46 _HEADER_SIZE_
= _HEADER_
.size
48 def __new__(cls
, *args
, **kwargs
):
49 return array
.__new
__(cls
, 'B')
51 def __init__(self
, ID
=None):
53 self
._ID
_ = str(uuid
.uuid1()).upper()
60 self
._SubImages
= sdict() # {offset: Image()}
68 Len
= array
.__len
__(self
)
69 for Offset
in self
._SubImages
.keys():
70 Len
+= len(self
._SubImages
[Offset
])
74 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
77 def _Pack(self
, PadByte
=0xFF):
78 raise NotImplementedError
80 def frombuffer(self
, Buffer
, Offset
=0, Size
=None):
83 # we may need the Size information in advance if it's given
85 self
._LEN
_ = self
._Unpack
()
90 def GetField(self
, FieldStruct
, Offset
=0):
91 return FieldStruct
.unpack_from(self
, Offset
)
93 def SetField(self
, FieldStruct
, Offset
, *args
):
94 # check if there's enough space
95 Size
= FieldStruct
.size
97 self
.extend([0] * (Size
- len(self
)))
98 FieldStruct
.pack_into(self
, Offset
, *args
)
100 def _SetData(self
, Data
):
101 if len(self
) < self
._HEADER
_SIZE
_:
102 self
.extend([0] * (self
._HEADER
_SIZE
_ - len(self
)))
104 del self
[self
._HEADER
_SIZE
_:]
108 if len(self
) > self
._HEADER
_SIZE
_:
109 return self
[self
._HEADER
_SIZE
_:]
112 Data
= property(_GetData
, _SetData
)
114 ## CompressedImage() class
116 # A class for Compressed Image
118 class CompressedImage(Image
):
119 # UncompressedLength = 4-byte
120 # CompressionType = 1-byte
121 _HEADER_
= struct
.Struct("1I 1B")
122 _HEADER_SIZE_
= _HEADER_
.size
124 _ORIG_SIZE_
= struct
.Struct("1I")
125 _CMPRS_TYPE_
= struct
.Struct("4x 1B")
127 def __init__(self
, CompressedData
=None, CompressionType
=None, UncompressedLength
=None):
129 if UncompressedLength
is not None:
130 self
.UncompressedLength
= UncompressedLength
131 if CompressionType
is not None:
132 self
.CompressionType
= CompressionType
133 if CompressedData
is not None:
134 self
.Data
= CompressedData
138 S
= "algorithm=%s uncompressed=%x" % (self
.CompressionType
, self
.UncompressedLength
)
139 for Sec
in self
.Sections
:
144 def _SetOriginalSize(self
, Size
):
145 self
.SetField(self
._ORIG
_SIZE
_, 0, Size
)
147 def _GetOriginalSize(self
):
148 return self
.GetField(self
._ORIG
_SIZE
_)[0]
150 def _SetCompressionType(self
, Type
):
151 self
.SetField(self
._CMPRS
_TYPE
_, 0, Type
)
153 def _GetCompressionType(self
):
154 return self
.GetField(self
._CMPRS
_TYPE
_)[0]
156 def _GetSections(self
):
158 TmpData
= DeCompress('Efi', self
[self
._HEADER
_SIZE
_:])
160 DecData
.fromstring(TmpData
)
162 TmpData
= DeCompress('Framework', self
[self
._HEADER
_SIZE
_:])
164 DecData
.fromstring(TmpData
)
168 while Offset
< len(DecData
):
171 Sec
.frombuffer(DecData
, Offset
)
173 # the section is aligned to 4-byte boundary
176 SectionList
.append(Sec
)
179 UncompressedLength
= property(_GetOriginalSize
, _SetOriginalSize
)
180 CompressionType
= property(_GetCompressionType
, _SetCompressionType
)
181 Sections
= property(_GetSections
)
188 _HEADER_
= struct
.Struct("")
198 # keep header in this Image object
200 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
203 def _GetUiString(self
):
204 return codecs
.utf_16_decode(self
[0:-2].tostring())[0]
206 String
= property(_GetUiString
)
213 _HEADER_
= struct
.Struct("")
216 _GUID_
= struct
.Struct("1I2H8B")
217 _OPCODE_
= struct
.Struct("1B")
233 -1 : _OPCODE_
, # first one in depex must be an opcdoe
234 0x00 : _GUID_
, #"BEFORE",
235 0x01 : _GUID_
, #"AFTER",
236 0x02 : _GUID_
, #"PUSH",
237 0x03 : _OPCODE_
, #"AND",
238 0x04 : _OPCODE_
, #"OR",
239 0x05 : _OPCODE_
, #"NOT",
240 0x06 : _OPCODE_
, #"TRUE",
241 0x07 : _OPCODE_
, #"FALSE",
243 0x09 : _OPCODE_
, #"SOR"
253 Indention
= ' ' * gIndention
255 for T
in self
.Expression
:
256 if T
in self
._OPCODE
_STRING
_:
257 S
+= Indention
+ self
._OPCODE
_STRING
_[T
]
258 if T
not in [0x00, 0x01, 0x02]:
261 S
+= ' ' + gGuidStringFormat
% T
+ '\n'
266 # keep header in this Image object
268 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
271 def _GetExpression(self
):
272 if self
._ExprList
== []:
274 CurrentData
= self
._OPCODE
_
275 while Offset
< len(self
):
276 Token
= CurrentData
.unpack_from(self
, Offset
)
277 Offset
+= CurrentData
.size
280 if Token
in self
._NEXT
_:
281 CurrentData
= self
._NEXT
_[Token
]
283 CurrentData
= self
._GUID
_
285 CurrentData
= self
._OPCODE
_
286 self
._ExprList
.append(Token
)
287 if CurrentData
is None:
289 return self
._ExprList
291 Expression
= property(_GetExpression
)
293 # # FirmwareVolume() class
295 # A class for Firmware Volume
297 class FirmwareVolume(Image
):
298 # Read FvLength, Attributes, HeaderLength, Checksum
299 _HEADER_
= struct
.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")
300 _HEADER_SIZE_
= _HEADER_
.size
302 _FfsGuid
= "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
304 _GUID_
= struct
.Struct("16x 1I2H8B")
305 _LENGTH_
= struct
.Struct("16x 16x 1Q")
306 _SIG_
= struct
.Struct("16x 16x 8x 1I")
307 _ATTR_
= struct
.Struct("16x 16x 8x 4x 1I")
308 _HLEN_
= struct
.Struct("16x 16x 8x 4x 4x 1H")
309 _CHECKSUM_
= struct
.Struct("16x 16x 8x 4x 4x 2x 1H")
311 def __init__(self
, Name
=''):
314 self
.FfsDict
= sdict()
315 self
.OrderedFfsDict
= sdict()
316 self
.UnDispatchedFfsDict
= sdict()
317 self
.ProtocolList
= sdict()
319 def CheckArchProtocol(self
):
320 for Item
in EotGlobalData
.gArchProtocolGuids
:
321 if Item
.lower() not in EotGlobalData
.gProtocolList
:
325 def ParseDepex(self
, Depex
, Type
):
328 List
= EotGlobalData
.gPpiList
329 if Type
== 'Protocol':
330 List
= EotGlobalData
.gProtocolList
336 for Index
in range(0, len(Depex
.Expression
)):
337 Item
= Depex
.Expression
[Index
]
340 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
341 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
342 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
345 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
346 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
347 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
350 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
351 if Guid
.lower() in List
:
352 DepexStack
.append(True)
353 DepexList
.append(Guid
)
355 DepexStack
.append(False)
356 DepexList
.append(Guid
)
358 elif Item
== 0x03 or Item
== 0x04:
359 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
360 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
362 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
363 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
365 DepexStack
.append(True)
366 DepexList
.append('TRUE')
367 DepexString
= DepexString
+ 'TRUE' + ' '
369 DepexStack
.append(False)
370 DepexList
.append('False')
371 DepexString
= DepexString
+ 'FALSE' + ' '
373 if Index
!= len(Depex
.Expression
) - 1:
374 CouldBeLoaded
= False
376 CouldBeLoaded
= DepexStack
.pop()
378 CouldBeLoaded
= False
380 DepexString
= DepexList
[0].strip()
381 return (CouldBeLoaded
, DepexString
, FileDepex
)
383 def Dispatch(self
, Db
=None):
386 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
387 # Find PeiCore, DexCore, PeiPriori, DxePriori first
388 FfsSecCoreGuid
= None
389 FfsPeiCoreGuid
= None
390 FfsDxeCoreGuid
= None
391 FfsPeiPrioriGuid
= None
392 FfsDxePrioriGuid
= None
393 for FfsID
in self
.UnDispatchedFfsDict
.keys():
394 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
396 FfsSecCoreGuid
= FfsID
399 FfsPeiCoreGuid
= FfsID
402 FfsDxeCoreGuid
= FfsID
404 if Ffs
.Guid
.lower() == PEI_APRIORI_GUID
.lower():
405 FfsPeiPrioriGuid
= FfsID
407 if Ffs
.Guid
.lower() == DXE_APRIORI_GUID
.lower():
408 FfsDxePrioriGuid
= FfsID
411 # Parse SEC_CORE first
412 if FfsSecCoreGuid
is not None:
413 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
414 self
.LoadPpi(Db
, FfsSecCoreGuid
)
417 if FfsPeiCoreGuid
is not None:
418 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
419 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
420 if FfsPeiPrioriGuid
is not None:
421 # Load PEIM described in priori file
422 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
423 if len(FfsPeiPriori
.Sections
) == 1:
424 Section
= FfsPeiPriori
.Sections
.popitem()[1]
425 if Section
.Type
== 0x19:
426 GuidStruct
= struct
.Struct('1I2H8B')
428 while len(Section
) > Start
:
429 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
430 GuidString
= gGuidStringFormat
% Guid
432 if GuidString
in self
.UnDispatchedFfsDict
:
433 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
434 self
.LoadPpi(Db
, GuidString
)
439 if FfsDxeCoreGuid
is not None:
440 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
441 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
442 if FfsDxePrioriGuid
is not None:
443 # Load PEIM described in priori file
444 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
445 if len(FfsDxePriori
.Sections
) == 1:
446 Section
= FfsDxePriori
.Sections
.popitem()[1]
447 if Section
.Type
== 0x19:
448 GuidStruct
= struct
.Struct('1I2H8B')
450 while len(Section
) > Start
:
451 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
452 GuidString
= gGuidStringFormat
% Guid
454 if GuidString
in self
.UnDispatchedFfsDict
:
455 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
456 self
.LoadProtocol(Db
, GuidString
)
460 def LoadProtocol(self
, Db
, ModuleGuid
):
461 SqlCommand
= """select GuidValue from Report
462 where SourceFileFullPath in
463 (select Value1 from Inf where BelongsToFile =
464 (select BelongsToFile from Inf
465 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
467 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
468 % (ModuleGuid
, 5001, 3007)
469 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
470 for Record
in RecordSet
:
471 SqlCommand
= """select Value2 from Inf where BelongsToFile =
472 (select DISTINCT BelongsToFile from Inf
474 (select SourceFileFullPath from Report
475 where GuidValue like '%s' and ItemMode = 'Callback'))
476 and Value1 = 'FILE_GUID'""" % Record
[0]
477 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
478 if CallBackSet
!= []:
479 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
481 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
483 def LoadPpi(self
, Db
, ModuleGuid
):
484 SqlCommand
= """select GuidValue from Report
485 where SourceFileFullPath in
486 (select Value1 from Inf where BelongsToFile =
487 (select BelongsToFile from Inf
488 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
490 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
491 % (ModuleGuid
, 5001, 3007)
492 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
493 for Record
in RecordSet
:
494 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
496 def DisPatchDxe(self
, Db
):
498 ScheduleList
= sdict()
499 for FfsID
in self
.UnDispatchedFfsDict
.keys():
500 CouldBeLoaded
= False
503 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
507 for Section
in Ffs
.Sections
.values():
509 if Section
.Type
== 0x13:
511 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
513 if Section
.Type
== 0x01:
514 CompressSections
= Section
._SubImages
[4]
515 for CompressSection
in CompressSections
.Sections
:
516 if CompressSection
.Type
== 0x13:
518 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
520 if CompressSection
.Type
== 0x02:
521 NewSections
= CompressSection
._SubImages
[4]
522 for NewSection
in NewSections
.Sections
:
523 if NewSection
.Type
== 0x13:
525 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
530 CouldBeLoaded
= self
.CheckArchProtocol()
537 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
538 NewFfs
.Depex
= DepexString
539 if FileDepex
is not None:
540 ScheduleList
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
542 ScheduleList
[FfsID
] = NewFfs
544 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
546 for FfsID
in ScheduleList
.keys():
547 NewFfs
= ScheduleList
.pop(FfsID
)
549 self
.OrderedFfsDict
[FfsID
] = NewFfs
550 self
.LoadProtocol(Db
, FfsID
)
552 SqlCommand
= """select Value2 from Inf
553 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
554 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
555 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
557 FfsName
= RecordSet
[0][0]
562 def DisPatchPei(self
, Db
):
564 for FfsID
in self
.UnDispatchedFfsDict
.keys():
568 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
569 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
571 for Section
in Ffs
.Sections
.values():
572 if Section
.Type
== 0x1B:
573 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
575 if Section
.Type
== 0x01:
576 CompressSections
= Section
._SubImages
[4]
577 for CompressSection
in CompressSections
.Sections
:
578 if CompressSection
.Type
== 0x1B:
579 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
581 if CompressSection
.Type
== 0x02:
582 NewSections
= CompressSection
._SubImages
[4]
583 for NewSection
in NewSections
.Sections
:
584 if NewSection
.Type
== 0x1B:
585 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
591 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
592 NewFfs
.Depex
= DepexString
593 self
.OrderedFfsDict
[FfsID
] = NewFfs
594 self
.LoadPpi(Db
, FfsID
)
596 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
605 FvInfo
= '\n' + ' ' * gIndention
606 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
607 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
609 return FvInfo
+ FfsInfo
612 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
614 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_ + Size
])
618 FfsStartAddress
= self
.HeaderSize
620 while FfsStartAddress
< EndOfFv
:
622 FfsObj
.frombuffer(self
, FfsStartAddress
)
624 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
625 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
626 if LastFfsObj
is not None:
627 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
629 if FfsId
in self
.FfsDict
:
630 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
631 ExtraData
="\t%s @ %s\n\t%s @ %s" \
632 % (FfsObj
.Guid
, FfsObj
.Offset
,
633 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
634 self
.FfsDict
[FfsId
] = FfsObj
635 if LastFfsObj
is not None:
636 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
638 FfsStartAddress
+= len(FfsObj
)
640 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
641 # The next FFS must be at the latest next 8-byte aligned address
643 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
646 def _GetAttributes(self
):
647 return self
.GetField(self
._ATTR
_, 0)[0]
650 return self
.GetField(self
._LENGTH
_, 0)[0]
652 def _GetChecksum(self
):
653 return self
.GetField(self
._CHECKSUM
_, 0)[0]
655 def _GetHeaderLength(self
):
656 return self
.GetField(self
._HLEN
_, 0)[0]
658 def _GetFileSystemGuid(self
):
659 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
661 Attributes
= property(_GetAttributes
)
662 Size
= property(_GetSize
)
663 Checksum
= property(_GetChecksum
)
664 HeaderSize
= property(_GetHeaderLength
)
665 FileSystemGuid
= property(_GetFileSystemGuid
)
667 ## GuidDefinedImage() class
669 # A class for GUID Defined Image
671 class GuidDefinedImage(Image
):
672 _HEADER_
= struct
.Struct("1I2H8B 1H 1H")
673 _HEADER_SIZE_
= _HEADER_
.size
675 _GUID_
= struct
.Struct("1I2H8B")
676 _DATA_OFFSET_
= struct
.Struct("16x 1H")
677 _ATTR_
= struct
.Struct("18x 1H")
679 CRC32_GUID
= "FC1BCDB0-7D31-49AA-936A-A4600D9DD083"
680 TIANO_COMPRESS_GUID
= 'A31280AD-481E-41B6-95E8-127F4C984779'
681 LZMA_COMPRESS_GUID
= 'EE4E5898-3914-4259-9D6E-DC7BD79403CF'
683 def __init__(self
, SectionDefinitionGuid
=None, DataOffset
=None, Attributes
=None, Data
=None):
685 if SectionDefinitionGuid
is not None:
686 self
.SectionDefinitionGuid
= SectionDefinitionGuid
687 if DataOffset
is not None:
688 self
.DataOffset
= DataOffset
689 if Attributes
is not None:
690 self
.Attributes
= Attributes
695 S
= "guid=%s" % (gGuidStringFormat
% self
.SectionDefinitionGuid
)
696 for Sec
in self
.Sections
:
701 # keep header in this Image object
703 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
706 def _SetAttribute(self
, Attribute
):
707 self
.SetField(self
._ATTR
_, 0, Attribute
)
709 def _GetAttribute(self
):
710 return self
.GetField(self
._ATTR
_)[0]
712 def _SetGuid(self
, Guid
):
713 self
.SetField(self
._GUID
_, 0, Guid
)
716 return self
.GetField(self
._GUID
_)
718 def _SetDataOffset(self
, Offset
):
719 self
.SetField(self
._DATA
_OFFSET
_, 0, Offset
)
721 def _GetDataOffset(self
):
722 return self
.GetField(self
._DATA
_OFFSET
_)[0]
724 def _GetSections(self
):
726 Guid
= gGuidStringFormat
% self
.SectionDefinitionGuid
727 if Guid
== self
.CRC32_GUID
:
728 # skip the CRC32 value, we don't do CRC32 verification here
729 Offset
= self
.DataOffset
- 4
730 while Offset
< len(self
):
733 Sec
.frombuffer(self
, Offset
)
735 # the section is aligned to 4-byte boundary
736 Offset
= (Offset
+ 3) & (~
3)
739 SectionList
.append(Sec
)
740 elif Guid
== self
.TIANO_COMPRESS_GUID
:
743 Offset
= self
.DataOffset
- 4
744 TmpData
= DeCompress('Framework', self
[self
.Offset
:])
746 DecData
.fromstring(TmpData
)
748 while Offset
< len(DecData
):
751 Sec
.frombuffer(DecData
, Offset
)
753 # the section is aligned to 4-byte boundary
754 Offset
= (Offset
+ 3) & (~
3)
757 SectionList
.append(Sec
)
760 elif Guid
== self
.LZMA_COMPRESS_GUID
:
763 Offset
= self
.DataOffset
- 4
765 TmpData
= DeCompress('Lzma', self
[self
.Offset
:])
767 DecData
.fromstring(TmpData
)
769 while Offset
< len(DecData
):
772 Sec
.frombuffer(DecData
, Offset
)
774 # the section is aligned to 4-byte boundary
775 Offset
= (Offset
+ 3) & (~
3)
778 SectionList
.append(Sec
)
784 Attributes
= property(_GetAttribute
, _SetAttribute
)
785 SectionDefinitionGuid
= property(_GetGuid
, _SetGuid
)
786 DataOffset
= property(_GetDataOffset
, _SetDataOffset
)
787 Sections
= property(_GetSections
)
791 # A class for Section
793 class Section(Image
):
796 0x01 : "COMPRESSION",
797 0x02 : "GUID_DEFINED",
803 0x15 : "USER_INTERFACE",
804 0x16 : "COMPATIBILITY16",
805 0x17 : "FIRMWARE_VOLUME_IMAGE",
806 0x18 : "FREEFORM_SUBTYPE_GUID",
811 _SectionSubImages
= {
812 0x01 : CompressedImage
,
813 0x02 : GuidDefinedImage
,
814 0x17 : FirmwareVolume
,
822 _HEADER_
= struct
.Struct("3B 1B")
823 _HEADER_SIZE_
= _HEADER_
.size
826 # _FREE_FORM_SUBTYPE_GUID_HEADER_ = struct.Struct("1I2H8B")
827 _SIZE_
= struct
.Struct("3B")
828 _TYPE_
= struct
.Struct("3x 1B")
830 def __init__(self
, Type
=None, Size
=None):
841 SectionInfo
= ' ' * gIndention
842 if self
.Type
in self
._TypeName
:
843 SectionInfo
+= "[SECTION:%s] offset=%x size=%x" % (self
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
)
845 SectionInfo
+= "[SECTION:%x<unknown>] offset=%x size=%x " % (self
.Type
, self
._OFF
_, self
.Size
)
846 for Offset
in self
._SubImages
.keys():
847 SectionInfo
+= ", " + str(self
._SubImages
[Offset
])
853 Type
, = self
._TYPE
_.unpack_from(self
._BUF
_, self
._OFF
_)
854 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
855 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
857 if Type
not in self
._SectionSubImages
:
858 # no need to extract sub-image, keep all in this Image object
859 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
861 # keep header in this Image object
862 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._HEADER
_SIZE
_])
864 # use new Image object to represent payload, which may be another kind
865 # of image such as PE32
867 PayloadOffset
= self
._HEADER
_SIZE
_
868 PayloadLen
= self
.Size
- self
._HEADER
_SIZE
_
869 Payload
= self
._SectionSubImages
[self
.Type
]()
870 Payload
.frombuffer(self
._BUF
_, self
._OFF
_ + self
._HEADER
_SIZE
_, PayloadLen
)
871 self
._SubImages
[PayloadOffset
] = Payload
875 def _SetSize(self
, Size
):
877 Size2
= (Size
& 0xFF00) >> 8
878 Size3
= (Size
& 0xFF0000) >> 16
879 self
.SetField(self
._SIZE
_, 0, Size1
, Size2
, Size3
)
882 Size1
, Size2
, Size3
= self
.GetField(self
._SIZE
_)
883 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
885 def _SetType(self
, Type
):
886 self
.SetField(self
._TYPE
_, 0, Type
)
889 return self
.GetField(self
._TYPE
_)[0]
891 def _GetAlignment(self
):
892 return self
._Alignment
894 def _SetAlignment(self
, Alignment
):
895 self
._Alignment
= Alignment
896 AlignmentMask
= Alignment
- 1
897 # section alignment is actually for payload, so we need to add header size
898 PayloadOffset
= self
._OFF
_ + self
._HEADER
_SIZE
_
899 if (PayloadOffset
& (~AlignmentMask
)) == 0:
901 NewOffset
= (PayloadOffset
+ AlignmentMask
) & (~AlignmentMask
)
902 while (NewOffset
- PayloadOffset
) < self
._HEADER
_SIZE
_:
903 NewOffset
+= self
._Alignment
906 self
.Size
= len(self
)
907 Image
.tofile(self
, f
)
908 for Offset
in self
._SubImages
:
909 self
._SubImages
[Offset
].tofile(f
)
911 Type
= property(_GetType
, _SetType
)
912 Size
= property(_GetSize
, _SetSize
)
913 Alignment
= property(_GetAlignment
, _SetAlignment
)
917 # A class for Ffs Section
920 _FfsFormat
= "24B%(payload_size)sB"
921 # skip IntegrityCheck
922 _HEADER_
= struct
.Struct("1I2H8B 2x 1B 1B 3B 1B")
923 _HEADER_SIZE_
= _HEADER_
.size
925 _NAME_
= struct
.Struct("1I2H8B")
926 _INT_CHECK_
= struct
.Struct("16x 1H")
927 _TYPE_
= struct
.Struct("18x 1B")
928 _ATTR_
= struct
.Struct("19x 1B")
929 _SIZE_
= struct
.Struct("20x 3B")
930 _STATE_
= struct
.Struct("23x 1B")
932 VTF_GUID
= "1BA0062E-C779-4582-8566-336AE8F78F09"
934 FFS_ATTRIB_FIXED
= 0x04
935 FFS_ATTRIB_DATA_ALIGNMENT
= 0x38
936 FFS_ATTRIB_CHECKSUM
= 0x40
942 0x03 : "SECURITY_CORE",
947 0x08 : "COMBINED_PEIM_DRIVER",
948 0x09 : "APPLICATION",
950 0x0B : "FIRMWARE_VOLUME_IMAGE",
951 0x0C : "COMBINED_SMM_DXE",
953 0x0E : "MM_STANDALONE",
954 0x0F : "MM_CORE_STANDALONE",
968 self
.Sections
= sdict()
976 Indention
= ' ' * gIndention
978 FfsInfo
+= "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \
979 (Ffs
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
, self
.Guid
, self
.FreeSpace
, self
.Alignment
)
980 SectionInfo
= '\n'.join([str(self
.Sections
[Offset
]) for Offset
in self
.Sections
.keys()])
982 return FfsInfo
+ SectionInfo
+ "\n"
991 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
992 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
994 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
996 # Pad FFS may use the same GUID. We need to avoid it.
997 if self
.Type
== 0xf0:
998 self
.__ID
__ = str(uuid
.uuid1()).upper()
1000 self
.__ID
__ = self
.Guid
1002 # Traverse the SECTION. RAW and PAD do not have sections
1003 if self
.Type
not in [0xf0, 0x01] and Size
> 0 and Size
< 0xFFFFFF:
1005 SectionStartAddress
= self
._HEADER
_SIZE
_
1006 while SectionStartAddress
< EndOfFfs
:
1007 SectionObj
= Section()
1008 SectionObj
.frombuffer(self
, SectionStartAddress
)
1009 #f = open(repr(SectionObj), 'wb')
1010 #SectionObj.Size = 0
1011 #SectionObj.tofile(f)
1013 self
.Sections
[SectionStartAddress
] = SectionObj
1014 SectionStartAddress
+= len(SectionObj
)
1015 SectionStartAddress
= (SectionStartAddress
+ 3) & (~
3)
1020 def SetFreeSpace(self
, Size
):
1021 self
.FreeSpace
= Size
1024 return gGuidStringFormat
% self
.Name
1026 def _SetName(self
, Value
):
1027 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1028 self
.SetField(self
._NAME
_, 0, Value
)
1031 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1032 return self
.GetField(self
._NAME
_)
1034 def _SetSize(self
, Size
):
1036 Size2
= (Size
& 0xFF00) >> 8
1037 Size3
= (Size
& 0xFF0000) >> 16
1038 self
.SetField(self
._SIZE
_, 0, Size1
, Size2
, Size3
)
1041 Size1
, Size2
, Size3
= self
.GetField(self
._SIZE
_)
1042 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
1044 def _SetType(self
, Type
):
1045 self
.SetField(self
._TYPE
_, 0, Type
)
1048 return self
.GetField(self
._TYPE
_)[0]
1050 def _SetAttributes(self
, Value
):
1051 self
.SetField(self
._ATTR
_, 0, Value
)
1053 def _GetAttributes(self
):
1054 return self
.GetField(self
._ATTR
_)[0]
1056 def _GetFixed(self
):
1057 if (self
.Attributes
& self
.FFS_ATTRIB_FIXED
) != 0:
1061 def _GetCheckSum(self
):
1062 if (self
.Attributes
& self
.FFS_ATTRIB_CHECKSUM
) != 0:
1066 def _GetAlignment(self
):
1067 return (self
.Attributes
& self
.FFS_ATTRIB_DATA_ALIGNMENT
) >> 3
1069 def _SetState(self
, Value
):
1070 self
.SetField(self
._STATE
_, 0, Value
)
1072 def _GetState(self
):
1073 return self
.GetField(self
._STATE
_)[0]
1075 Name
= property(_GetName
, _SetName
)
1076 Guid
= property(_GetGuid
)
1077 Type
= property(_GetType
, _SetType
)
1078 Size
= property(_GetSize
, _SetSize
)
1079 Attributes
= property(_GetAttributes
, _SetAttributes
)
1080 Fixed
= property(_GetFixed
)
1081 Checksum
= property(_GetCheckSum
)
1082 Alignment
= property(_GetAlignment
)
1083 State
= property(_GetState
, _SetState
)
1086 _FfsGuid
= "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
1088 _GUID_
= struct
.Struct("16x 1I2H8B")
1089 _LENGTH_
= struct
.Struct("16x 16x 1Q")
1090 _SIG_
= struct
.Struct("16x 16x 8x 1I")
1091 _ATTR_
= struct
.Struct("16x 16x 8x 4x 1I")
1092 _HLEN_
= struct
.Struct("16x 16x 8x 4x 4x 1H")
1093 _CHECKSUM_
= struct
.Struct("16x 16x 8x 4x 4x 2x 1H")
1095 def __init__(self
, Name
=''):
1096 Image
.__init
__(self
)
1098 self
.FfsDict
= sdict()
1099 self
.OrderedFfsDict
= sdict()
1100 self
.UnDispatchedFfsDict
= sdict()
1101 self
.ProtocolList
= sdict()
1103 def CheckArchProtocol(self
):
1104 for Item
in EotGlobalData
.gArchProtocolGuids
:
1105 if Item
.lower() not in EotGlobalData
.gProtocolList
:
1109 def ParseDepex(self
, Depex
, Type
):
1112 List
= EotGlobalData
.gPpiList
1113 if Type
== 'Protocol':
1114 List
= EotGlobalData
.gProtocolList
1119 CouldBeLoaded
= True
1120 for Index
in range(0, len(Depex
.Expression
)):
1121 Item
= Depex
.Expression
[Index
]
1124 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1125 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
1126 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
1129 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1130 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
1131 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
1134 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
1135 if Guid
.lower() in List
:
1136 DepexStack
.append(True)
1137 DepexList
.append(Guid
)
1139 DepexStack
.append(False)
1140 DepexList
.append(Guid
)
1142 elif Item
== 0x03 or Item
== 0x04:
1143 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
1144 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
1146 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
1147 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
1149 DepexStack
.append(True)
1150 DepexList
.append('TRUE')
1151 DepexString
= DepexString
+ 'TRUE' + ' '
1153 DepexStack
.append(False)
1154 DepexList
.append('False')
1155 DepexString
= DepexString
+ 'FALSE' + ' '
1157 if Index
!= len(Depex
.Expression
) - 1:
1158 CouldBeLoaded
= False
1160 CouldBeLoaded
= DepexStack
.pop()
1162 CouldBeLoaded
= False
1164 DepexString
= DepexList
[0].strip()
1165 return (CouldBeLoaded
, DepexString
, FileDepex
)
1167 def Dispatch(self
, Db
= None):
1170 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
1171 # Find PeiCore, DexCore, PeiPriori, DxePriori first
1172 FfsSecCoreGuid
= None
1173 FfsPeiCoreGuid
= None
1174 FfsDxeCoreGuid
= None
1175 FfsPeiPrioriGuid
= None
1176 FfsDxePrioriGuid
= None
1177 for FfsID
in self
.UnDispatchedFfsDict
:
1178 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1179 if Ffs
.Type
== 0x03:
1180 FfsSecCoreGuid
= FfsID
1182 if Ffs
.Type
== 0x04:
1183 FfsPeiCoreGuid
= FfsID
1185 if Ffs
.Type
== 0x05:
1186 FfsDxeCoreGuid
= FfsID
1188 if Ffs
.Guid
.lower() == PEI_APRIORI_GUID
.lower():
1189 FfsPeiPrioriGuid
= FfsID
1191 if Ffs
.Guid
.lower() == DXE_APRIORI_GUID
.lower():
1192 FfsDxePrioriGuid
= FfsID
1195 # Parse SEC_CORE first
1196 if FfsSecCoreGuid
is not None:
1197 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
1198 self
.LoadPpi(Db
, FfsSecCoreGuid
)
1201 if FfsPeiCoreGuid
is not None:
1202 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
1203 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
1204 if FfsPeiPrioriGuid
is not None:
1205 # Load PEIM described in priori file
1206 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
1207 if len(FfsPeiPriori
.Sections
) == 1:
1208 Section
= FfsPeiPriori
.Sections
.popitem()[1]
1209 if Section
.Type
== 0x19:
1210 GuidStruct
= struct
.Struct('1I2H8B')
1212 while len(Section
) > Start
:
1213 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
1214 GuidString
= gGuidStringFormat
% Guid
1216 if GuidString
in self
.UnDispatchedFfsDict
:
1217 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
1218 self
.LoadPpi(Db
, GuidString
)
1220 self
.DisPatchPei(Db
)
1223 if FfsDxeCoreGuid
is not None:
1224 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
1225 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
1226 if FfsDxePrioriGuid
is not None:
1227 # Load PEIM described in priori file
1228 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
1229 if len(FfsDxePriori
.Sections
) == 1:
1230 Section
= FfsDxePriori
.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
.LoadProtocol(Db
, GuidString
)
1242 self
.DisPatchDxe(Db
)
1244 def LoadProtocol(self
, Db
, ModuleGuid
):
1245 SqlCommand
= """select GuidValue from Report
1246 where SourceFileFullPath in
1247 (select Value1 from Inf where BelongsToFile =
1248 (select BelongsToFile from Inf
1249 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
1251 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
1252 % (ModuleGuid
, 5001, 3007)
1253 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1254 for Record
in RecordSet
:
1255 SqlCommand
= """select Value2 from Inf where BelongsToFile =
1256 (select DISTINCT BelongsToFile from Inf
1258 (select SourceFileFullPath from Report
1259 where GuidValue like '%s' and ItemMode = 'Callback'))
1260 and Value1 = 'FILE_GUID'""" % Record
[0]
1261 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
1262 if CallBackSet
!= []:
1263 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
1265 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
1267 def LoadPpi(self
, Db
, ModuleGuid
):
1268 SqlCommand
= """select GuidValue from Report
1269 where SourceFileFullPath in
1270 (select Value1 from Inf where BelongsToFile =
1271 (select BelongsToFile from Inf
1272 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
1274 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
1275 % (ModuleGuid
, 5001, 3007)
1276 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1277 for Record
in RecordSet
:
1278 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
1280 def DisPatchDxe(self
, Db
):
1282 ScheduleList
= sdict()
1283 for FfsID
in self
.UnDispatchedFfsDict
:
1284 CouldBeLoaded
= False
1287 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1288 if Ffs
.Type
== 0x07:
1290 IsFoundDepex
= False
1291 for Section
in Ffs
.Sections
.values():
1293 if Section
.Type
== 0x13:
1295 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
1297 if Section
.Type
== 0x01:
1298 CompressSections
= Section
._SubImages
[4]
1299 for CompressSection
in CompressSections
.Sections
:
1300 if CompressSection
.Type
== 0x13:
1302 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
1304 if CompressSection
.Type
== 0x02:
1305 NewSections
= CompressSection
._SubImages
[4]
1306 for NewSection
in NewSections
.Sections
:
1307 if NewSection
.Type
== 0x13:
1309 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
1313 if not IsFoundDepex
:
1314 CouldBeLoaded
= self
.CheckArchProtocol()
1321 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
1322 NewFfs
.Depex
= DepexString
1323 if FileDepex
is not None:
1324 ScheduleList
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
1326 ScheduleList
[FfsID
] = NewFfs
1328 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
1330 for FfsID
in ScheduleList
:
1331 NewFfs
= ScheduleList
.pop(FfsID
)
1333 self
.OrderedFfsDict
[FfsID
] = NewFfs
1334 self
.LoadProtocol(Db
, FfsID
)
1336 SqlCommand
= """select Value2 from Inf
1337 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
1338 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
1339 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
1341 FfsName
= RecordSet
[0][0]
1344 self
.DisPatchDxe(Db
)
1346 def DisPatchPei(self
, Db
):
1348 for FfsID
in self
.UnDispatchedFfsDict
:
1349 CouldBeLoaded
= True
1352 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
1353 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
1355 for Section
in Ffs
.Sections
.values():
1356 if Section
.Type
== 0x1B:
1357 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
1359 if Section
.Type
== 0x01:
1360 CompressSections
= Section
._SubImages
[4]
1361 for CompressSection
in CompressSections
.Sections
:
1362 if CompressSection
.Type
== 0x1B:
1363 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
1365 if CompressSection
.Type
== 0x02:
1366 NewSections
= CompressSection
._SubImages
[4]
1367 for NewSection
in NewSections
.Sections
:
1368 if NewSection
.Type
== 0x1B:
1369 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
1375 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
1376 NewFfs
.Depex
= DepexString
1377 self
.OrderedFfsDict
[FfsID
] = NewFfs
1378 self
.LoadPpi(Db
, FfsID
)
1380 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
1383 self
.DisPatchPei(Db
)
1389 FvInfo
= '\n' + ' ' * gIndention
1390 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
1391 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
1393 return FvInfo
+ FfsInfo
1396 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
1398 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_+Size
])
1402 FfsStartAddress
= self
.HeaderSize
1404 while FfsStartAddress
< EndOfFv
:
1406 FfsObj
.frombuffer(self
, FfsStartAddress
)
1407 FfsId
= repr(FfsObj
)
1408 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
1409 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
1410 if LastFfsObj
is not None:
1411 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
1413 if FfsId
in self
.FfsDict
:
1414 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
1415 ExtraData
="\t%s @ %s\n\t%s @ %s" \
1416 % (FfsObj
.Guid
, FfsObj
.Offset
,
1417 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
1418 self
.FfsDict
[FfsId
] = FfsObj
1419 if LastFfsObj
is not None:
1420 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
1422 FfsStartAddress
+= len(FfsObj
)
1424 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
1425 # The next FFS must be at the latest next 8-byte aligned address
1427 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
1430 def _GetAttributes(self
):
1431 return self
.GetField(self
._ATTR
_, 0)[0]
1434 return self
.GetField(self
._LENGTH
_, 0)[0]
1436 def _GetChecksum(self
):
1437 return self
.GetField(self
._CHECKSUM
_, 0)[0]
1439 def _GetHeaderLength(self
):
1440 return self
.GetField(self
._HLEN
_, 0)[0]
1442 def _GetFileSystemGuid(self
):
1443 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
1445 Attributes
= property(_GetAttributes
)
1446 Size
= property(_GetSize
)
1447 Checksum
= property(_GetChecksum
)
1448 HeaderSize
= property(_GetHeaderLength
)
1449 FileSystemGuid
= property(_GetFileSystemGuid
)
1451 ## MultipleFv() class
1453 # A class for Multiple FV
1455 class MultipleFv(FirmwareVolume
):
1456 def __init__(self
, FvList
):
1457 FirmwareVolume
.__init
__(self
)
1459 for FvPath
in FvList
:
1461 FvName
= os
.path
.splitext(os
.path
.split(FvPath
)[1])[0]
1463 Fd
= open(FvPath
, 'rb')
1466 Buf
.fromfile(Fd
, os
.path
.getsize(FvPath
))
1470 Fv
= FirmwareVolume(FvName
)
1471 Fv
.frombuffer(Buf
, 0, len(Buf
))
1473 self
.BasicInfo
.append([Fv
.Name
, Fv
.FileSystemGuid
, Fv
.Size
])
1474 self
.FfsDict
.append(Fv
.FfsDict
)
1478 # This class is used to define Eot main entrance
1480 # @param object: Inherited from object class
1485 # @param self: The object pointer
1487 def __init__(self
, CommandLineOption
=True, IsInit
=True, SourceFileList
=None, \
1488 IncludeDirList
=None, DecFileList
=None, GuidList
=None, LogFile
=None,
1489 FvFileList
="", MapFileList
="", Report
='Report.html', Dispatch
=None):
1490 # Version and Copyright
1491 self
.VersionNumber
= ("0.02" + " " + gBUILD_VERSION
)
1492 self
.Version
= "%prog Version " + self
.VersionNumber
1493 self
.Copyright
= "Copyright (c) 2008 - 2018, Intel Corporation All rights reserved."
1494 self
.Report
= Report
1496 self
.IsInit
= IsInit
1497 self
.SourceFileList
= SourceFileList
1498 self
.IncludeDirList
= IncludeDirList
1499 self
.DecFileList
= DecFileList
1500 self
.GuidList
= GuidList
1501 self
.LogFile
= LogFile
1502 self
.FvFileList
= FvFileList
1503 self
.MapFileList
= MapFileList
1504 self
.Dispatch
= Dispatch
1506 # Check workspace environment
1507 if "EFI_SOURCE" not in os
.environ
:
1508 if "EDK_SOURCE" not in os
.environ
:
1511 EotGlobalData
.gEDK_SOURCE
= os
.path
.normpath(os
.getenv("EDK_SOURCE"))
1513 EotGlobalData
.gEFI_SOURCE
= os
.path
.normpath(os
.getenv("EFI_SOURCE"))
1514 EotGlobalData
.gEDK_SOURCE
= os
.path
.join(EotGlobalData
.gEFI_SOURCE
, 'Edk')
1516 if "WORKSPACE" not in os
.environ
:
1517 EdkLogger
.error("EOT", BuildToolError
.ATTRIBUTE_NOT_AVAILABLE
, "Environment variable not found",
1518 ExtraData
="WORKSPACE")
1520 EotGlobalData
.gWORKSPACE
= os
.path
.normpath(os
.getenv("WORKSPACE"))
1522 EotGlobalData
.gMACRO
['WORKSPACE'] = EotGlobalData
.gWORKSPACE
1523 EotGlobalData
.gMACRO
['EFI_SOURCE'] = EotGlobalData
.gEFI_SOURCE
1524 EotGlobalData
.gMACRO
['EDK_SOURCE'] = EotGlobalData
.gEDK_SOURCE
1526 # Parse the options and args
1527 if CommandLineOption
:
1531 for FvFile
in GetSplitValueList(self
.FvFileList
, ' '):
1532 FvFile
= os
.path
.normpath(FvFile
)
1533 if not os
.path
.isfile(FvFile
):
1534 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % FvFile
)
1535 EotGlobalData
.gFV_FILE
.append(FvFile
)
1537 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "The fv file list of target platform was not specified")
1539 if self
.MapFileList
:
1540 for MapFile
in GetSplitValueList(self
.MapFileList
, ' '):
1541 MapFile
= os
.path
.normpath(MapFile
)
1542 if not os
.path
.isfile(MapFile
):
1543 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % MapFile
)
1544 EotGlobalData
.gMAP_FILE
.append(MapFile
)
1546 # Generate source file list
1547 self
.GenerateSourceFileList(self
.SourceFileList
, self
.IncludeDirList
)
1549 # Generate guid list of dec file list
1550 self
.ParseDecFile(self
.DecFileList
)
1552 # Generate guid list from GUID list file
1553 self
.ParseGuidList(self
.GuidList
)
1556 EotGlobalData
.gDb
= Database
.Database(Database
.DATABASE_PATH
)
1557 EotGlobalData
.gDb
.InitDatabase(self
.IsInit
)
1559 # Build ECC database
1560 self
.BuildDatabase()
1562 # Parse Ppi/Protocol
1563 self
.ParseExecutionOrder()
1565 # Merge Identifier tables
1566 self
.GenerateQueryTable()
1568 # Generate report database
1569 self
.GenerateReportDatabase()
1578 self
.GenerateReport()
1581 self
.ConvertLogFile(self
.LogFile
)
1584 EdkLogger
.quiet("EOT FINISHED!")
1587 EotGlobalData
.gDb
.Close()
1589 ## ParseDecFile() method
1591 # parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}
1592 # The Dict is stored in EotGlobalData.gGuidDict
1594 # @param self: The object pointer
1595 # @param DecFileList: A list of all DEC files
1597 def ParseDecFile(self
, DecFileList
):
1599 path
= os
.path
.normpath(DecFileList
)
1600 lfr
= open(path
, 'rb')
1602 path
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1603 if os
.path
.exists(path
):
1604 dfr
= open(path
, 'rb')
1606 line
= CleanString(line
)
1607 list = line
.split('=')
1609 EotGlobalData
.gGuidDict
[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())
1612 ## ParseGuidList() method
1614 # Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}
1615 # The Dict is stored in EotGlobalData.gGuidDict
1617 # @param self: The object pointer
1618 # @param GuidList: A list of all GUID and its value
1620 def ParseGuidList(self
, GuidList
):
1621 Path
= os
.path
.join(EotGlobalData
.gWORKSPACE
, GuidList
)
1622 if os
.path
.isfile(Path
):
1623 for Line
in open(Path
):
1625 (GuidName
, GuidValue
) = Line
.split()
1626 EotGlobalData
.gGuidDict
[GuidName
] = GuidValue
1628 ## ConvertLogFile() method
1630 # Parse a real running log file to get real dispatch order
1631 # The result is saved to old file name + '.new'
1633 # @param self: The object pointer
1634 # @param LogFile: A real running log file name
1636 def ConvertLogFile(self
, LogFile
):
1641 lfr
= open(LogFile
, 'rb')
1642 lfw
= open(LogFile
+ '.new', 'wb')
1645 line
= line
.replace('.efi', '')
1646 index
= line
.find("Loading PEIM at ")
1648 newline
.append(line
[index
+ 55 : ])
1650 index
= line
.find("Loading driver at ")
1652 newline
.append(line
[index
+ 57 : ])
1655 for line
in newline
:
1656 lfw
.write(line
+ '\r\n')
1663 ## GenerateSourceFileList() method
1665 # Generate a list of all source files
1666 # 1. Search the file list one by one
1667 # 2. Store inf file name with source file names under it like
1668 # { INF file name: [source file1, source file2, ...]}
1669 # 3. Search the include list to find all .h files
1670 # 4. Store source file list to EotGlobalData.gSOURCE_FILES
1671 # 5. Store INF file list to EotGlobalData.gINF_FILES
1673 # @param self: The object pointer
1674 # @param SourceFileList: A list of all source files
1675 # @param IncludeFileList: A list of all include files
1677 def GenerateSourceFileList(self
, SourceFileList
, IncludeFileList
):
1678 EdkLogger
.quiet("Generating source files list ... ")
1679 mSourceFileList
= []
1683 mCurrentInfFile
= ''
1684 mCurrentSourceFileList
= []
1687 sfl
= open(SourceFileList
, 'r')
1689 line
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1690 if line
[-2:].upper() == '.C' or line
[-2:].upper() == '.H':
1691 if line
not in mCurrentSourceFileList
:
1692 mCurrentSourceFileList
.append(line
)
1693 mSourceFileList
.append(line
)
1694 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % line
)
1695 if line
[-4:].upper() == '.INF':
1696 if mCurrentInfFile
!= '':
1697 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1698 mCurrentSourceFileList
= []
1699 mCurrentInfFile
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
))
1700 EotGlobalData
.gOP_INF
.write('%s\n' % mCurrentInfFile
)
1701 if mCurrentInfFile
not in mFileList
:
1702 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1704 # Get all include files from packages
1706 ifl
= open(IncludeFileList
, 'rb')
1708 if not line
.strip():
1710 newline
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1711 for Root
, Dirs
, Files
in os
.walk(str(newline
)):
1713 FullPath
= os
.path
.normpath(os
.path
.join(Root
, File
))
1714 if FullPath
not in mSourceFileList
and File
[-2:].upper() == '.H':
1715 mSourceFileList
.append(FullPath
)
1716 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % FullPath
)
1717 if FullPath
not in mDecFileList
and File
.upper().find('.DEC') > -1:
1718 mDecFileList
.append(FullPath
)
1720 EotGlobalData
.gSOURCE_FILES
= mSourceFileList
1721 EotGlobalData
.gOP_SOURCE_FILES
.close()
1723 EotGlobalData
.gINF_FILES
= mFileList
1724 EotGlobalData
.gOP_INF
.close()
1726 ## GenerateReport() method
1728 # Generate final HTML report
1730 # @param self: The object pointer
1732 def GenerateReport(self
):
1733 EdkLogger
.quiet("Generating report file ... ")
1734 Rep
= Report(self
.Report
, EotGlobalData
.gFV
, self
.Dispatch
)
1735 Rep
.GenerateReport()
1737 ## LoadMapInfo() method
1739 # Load map files and parse them
1741 # @param self: The object pointer
1743 def LoadMapInfo(self
):
1744 if EotGlobalData
.gMAP_FILE
!= []:
1745 EdkLogger
.quiet("Parsing Map file ... ")
1746 EotGlobalData
.gMap
= ParseMapFile(EotGlobalData
.gMAP_FILE
)
1748 ## LoadFvInfo() method
1750 # Load FV binary files and parse them
1752 # @param self: The object pointer
1754 def LoadFvInfo(self
):
1755 EdkLogger
.quiet("Parsing FV file ... ")
1756 EotGlobalData
.gFV
= MultipleFv(EotGlobalData
.gFV_FILE
)
1757 EotGlobalData
.gFV
.Dispatch(EotGlobalData
.gDb
)
1759 for Protocol
in EotGlobalData
.gProtocolList
:
1760 EotGlobalData
.gOP_UN_MATCHED_IN_LIBRARY_CALLING
.write('%s\n' %Protocol
)
1762 ## GenerateReportDatabase() method
1764 # Generate data for the information needed by report
1765 # 1. Update name, macro and value of all found PPI/PROTOCOL GUID
1766 # 2. Install hard coded PPI/PROTOCOL
1768 # @param self: The object pointer
1770 def GenerateReportDatabase(self
):
1771 EdkLogger
.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")
1773 # Update Protocol/Ppi Guid
1774 SqlCommand
= """select DISTINCT GuidName from Report"""
1775 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1776 for Record
in RecordSet
:
1777 GuidName
= Record
[0]
1782 # Find guid value defined in Dec file
1783 if GuidName
in EotGlobalData
.gGuidDict
:
1784 GuidValue
= EotGlobalData
.gGuidDict
[GuidName
]
1785 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1786 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1789 # Search defined Macros for guid name
1790 SqlCommand
="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName
1791 GuidMacroSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1792 # Ignore NULL result
1793 if not GuidMacroSet
:
1795 GuidMacro
= GuidMacroSet
[0][0].strip()
1798 # Find Guid value of Guid Macro
1799 SqlCommand
="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro
, MODEL_IDENTIFIER_MACRO_DEFINE
)
1800 GuidValueSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1801 if GuidValueSet
!= []:
1802 GuidValue
= GuidValueSet
[0][0]
1803 GuidValue
= GuidValue
[GuidValue
.find(GuidMacro
) + len(GuidMacro
) :]
1804 GuidValue
= GuidValue
.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()
1805 GuidValue
= GuidStructureStringToGuidString(GuidValue
)
1806 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1807 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1810 # Update Hard Coded Ppi/Protocol
1811 SqlCommand
= """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""
1812 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1813 for Record
in RecordSet
:
1814 if Record
[1] == 'Ppi':
1815 EotGlobalData
.gPpiList
[Record
[0].lower()] = -2
1816 if Record
[1] == 'Protocol':
1817 EotGlobalData
.gProtocolList
[Record
[0].lower()] = -2
1819 ## GenerateQueryTable() method
1821 # Generate two tables improve query performance
1823 # @param self: The object pointer
1825 def GenerateQueryTable(self
):
1826 EdkLogger
.quiet("Generating temp query table for analysis ... ")
1827 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1828 SqlCommand
= """insert into Query (Name, Modifier, Value, Model)
1829 select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \
1830 % (Identifier
[0], MODEL_IDENTIFIER_VARIABLE
, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION
)
1831 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1832 SqlCommand
= """insert into Query2 (Name, Modifier, Value, Model)
1833 select Name, Modifier, Value, Model from %s where Model = %s""" \
1834 % (Identifier
[0], MODEL_IDENTIFIER_MACRO_DEFINE
)
1835 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1837 ## ParseExecutionOrder() method
1839 # Get final execution order
1841 # 2. Search all PROTOCOL
1843 # @param self: The object pointer
1845 def ParseExecutionOrder(self
):
1846 EdkLogger
.quiet("Searching Ppi/Protocol ... ")
1847 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1848 ModuleID
, ModuleName
, ModuleGuid
, SourceFileID
, SourceFileFullPath
, ItemName
, ItemType
, ItemMode
, GuidName
, GuidMacro
, GuidValue
, BelongsToFunction
, Enabled
= \
1849 -1, '', '', -1, '', '', '', '', '', '', '', '', 0
1851 SourceFileID
= Identifier
[0].replace('Identifier', '')
1852 SourceFileFullPath
= Identifier
[1]
1853 Identifier
= Identifier
[0]
1856 ItemMode
= 'Produced'
1857 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1858 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1859 % (Identifier
, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1860 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1862 ItemMode
= 'Produced'
1863 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1864 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1865 % (Identifier
, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1866 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1868 SearchPpiCallFunction(Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1870 ItemMode
= 'Consumed'
1871 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1872 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1873 % (Identifier
, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1874 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1876 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Ppi', ItemMode
)
1878 ItemMode
= 'Callback'
1879 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1880 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1881 % (Identifier
, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1882 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1885 ItemMode
= 'Produced'
1886 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1887 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1888 % (Identifier
, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1889 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1891 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1892 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1893 % (Identifier
, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1894 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1896 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1898 ItemMode
= 'Consumed'
1899 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1900 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1901 % (Identifier
, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1902 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1904 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1905 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1906 % (Identifier
, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1907 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1909 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1911 ItemMode
= 'Callback'
1912 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1913 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1914 % (Identifier
, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1915 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1917 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1920 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)
1921 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)
1922 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)
1923 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)
1924 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)
1925 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)
1926 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)
1927 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)
1928 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)
1930 EotGlobalData
.gDb
.Conn
.commit()
1933 ## BuildDatabase() methoc
1935 # Build the database for target
1937 # @param self: The object pointer
1939 def BuildDatabase(self
):
1940 # Clean report table
1941 EotGlobalData
.gDb
.TblReport
.Drop()
1942 EotGlobalData
.gDb
.TblReport
.Create()
1946 self
.BuildMetaDataFileDatabase(EotGlobalData
.gINF_FILES
)
1947 EdkLogger
.quiet("Building database for source code ...")
1948 c
.CreateCCodeDB(EotGlobalData
.gSOURCE_FILES
)
1949 EdkLogger
.quiet("Building database for source code done!")
1951 EotGlobalData
.gIdentifierTableList
= GetTableList((MODEL_FILE_C
, MODEL_FILE_H
), 'Identifier', EotGlobalData
.gDb
)
1953 ## BuildMetaDataFileDatabase() method
1955 # Build the database for meta data files
1957 # @param self: The object pointer
1958 # @param Inf_Files: A list for all INF files
1960 def BuildMetaDataFileDatabase(self
, Inf_Files
):
1961 EdkLogger
.quiet("Building database for meta data files ...")
1962 for InfFile
in Inf_Files
:
1965 EdkLogger
.quiet("Parsing %s ..." % str(InfFile
))
1966 EdkInfParser(InfFile
, EotGlobalData
.gDb
, Inf_Files
[InfFile
], '')
1968 EotGlobalData
.gDb
.Conn
.commit()
1969 EdkLogger
.quiet("Building database for meta data files done!")
1971 ## ParseOption() method
1973 # Parse command line options
1975 # @param self: The object pointer
1977 def ParseOption(self
):
1978 (Options
, Target
) = self
.EotOptionParser()
1981 self
.SetLogLevel(Options
)
1983 if Options
.FvFileList
:
1984 self
.FvFileList
= Options
.FvFileList
1986 if Options
.MapFileList
:
1987 self
.MapFileList
= Options
.FvMapFileList
1989 if Options
.SourceFileList
:
1990 self
.SourceFileList
= Options
.SourceFileList
1992 if Options
.IncludeDirList
:
1993 self
.IncludeDirList
= Options
.IncludeDirList
1995 if Options
.DecFileList
:
1996 self
.DecFileList
= Options
.DecFileList
1998 if Options
.GuidList
:
1999 self
.GuidList
= Options
.GuidList
2002 self
.LogFile
= Options
.LogFile
2004 if Options
.keepdatabase
:
2007 ## SetLogLevel() method
2009 # Set current log level of the tool based on args
2011 # @param self: The object pointer
2012 # @param Option: The option list including log level setting
2014 def SetLogLevel(self
, Option
):
2015 if Option
.verbose
is not None:
2016 EdkLogger
.SetLevel(EdkLogger
.VERBOSE
)
2017 elif Option
.quiet
is not None:
2018 EdkLogger
.SetLevel(EdkLogger
.QUIET
)
2019 elif Option
.debug
is not None:
2020 EdkLogger
.SetLevel(Option
.debug
+ 1)
2022 EdkLogger
.SetLevel(EdkLogger
.INFO
)
2024 ## EotOptionParser() method
2026 # Using standard Python module optparse to parse command line option of this tool.
2028 # @param self: The object pointer
2030 # @retval Opt A optparse.Values object containing the parsed options
2031 # @retval Args Target of build command
2033 def EotOptionParser(self
):
2034 Parser
= OptionParser(description
= self
.Copyright
, version
= self
.Version
, prog
= "Eot.exe", usage
= "%prog [options]")
2035 Parser
.add_option("-m", "--makefile filename", action
="store", type="string", dest
='MakeFile',
2036 help="Specify a makefile for the platform.")
2037 Parser
.add_option("-c", "--dsc filename", action
="store", type="string", dest
="DscFile",
2038 help="Specify a dsc file for the platform.")
2039 Parser
.add_option("-f", "--fv filename", action
="store", type="string", dest
="FvFileList",
2040 help="Specify fv file list, quoted by \"\".")
2041 Parser
.add_option("-a", "--map filename", action
="store", type="string", dest
="MapFileList",
2042 help="Specify map file list, quoted by \"\".")
2043 Parser
.add_option("-s", "--source files", action
="store", type="string", dest
="SourceFileList",
2044 help="Specify source file list by a file")
2045 Parser
.add_option("-i", "--include dirs", action
="store", type="string", dest
="IncludeDirList",
2046 help="Specify include dir list by a file")
2047 Parser
.add_option("-e", "--dec files", action
="store", type="string", dest
="DecFileList",
2048 help="Specify dec file list by a file")
2049 Parser
.add_option("-g", "--guid list", action
="store", type="string", dest
="GuidList",
2050 help="Specify guid file list by a file")
2051 Parser
.add_option("-l", "--log filename", action
="store", type="string", dest
="LogFile",
2052 help="Specify real execution log file")
2054 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.")
2056 Parser
.add_option("-q", "--quiet", action
="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
2057 Parser
.add_option("-v", "--verbose", action
="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
2058 "including library instances selected, final dependency expression, "\
2059 "and warning messages, etc.")
2060 Parser
.add_option("-d", "--debug", action
="store", type="int", help="Enable debug messages at specified level.")
2062 (Opt
, Args
)=Parser
.parse_args()
2068 # This acts like the main() function for the script, unless it is 'import'ed into another
2071 if __name__
== '__main__':
2072 # Initialize log system
2073 EdkLogger
.Initialize()
2074 EdkLogger
.IsRaiseError
= False
2075 EdkLogger
.quiet(time
.strftime("%H:%M:%S, %b.%d %Y ", time
.localtime()) + "[00:00]" + "\n")
2077 StartTime
= time
.clock()
2078 Eot
= Eot(CommandLineOption
=False,
2079 SourceFileList
=r
'C:\TestEot\Source.txt',
2080 GuidList
=r
'C:\TestEot\Guid.txt',
2081 FvFileList
=r
'C:\TestEot\FVRECOVERY.Fv')
2082 FinishTime
= time
.clock()
2084 BuildDuration
= time
.strftime("%M:%S", time
.gmtime(int(round(FinishTime
- StartTime
))))
2085 EdkLogger
.quiet("\n%s [%s]" % (time
.strftime("%H:%M:%S, %b.%d %Y", time
.localtime()), BuildDuration
))