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 # SPDX-License-Identifier: BSD-2-Clause-Patent
11 from __future__
import absolute_import
12 import Common
.LongFilePathOs
as os
, time
, glob
13 import Common
.EdkLogger
as EdkLogger
14 import Eot
.EotGlobalData
as EotGlobalData
15 from optparse
import OptionParser
16 from Common
.StringUtils
import NormPath
17 from Common
import BuildToolError
18 from Common
.Misc
import GuidStructureStringToGuidString
19 from collections
import OrderedDict
as sdict
20 from Eot
.Parser
import *
21 from Eot
.InfParserLite
import EdkInfParser
22 from Common
.StringUtils
import GetSplitValueList
24 from Eot
import Database
25 from array
import array
26 from Eot
.Report
import Report
27 from Common
.BuildVersion
import gBUILD_VERSION
28 from Eot
.Parser
import ConvertGuid
29 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
34 from GenFds
.AprioriSection
import DXE_APRIORI_GUID
, PEI_APRIORI_GUID
36 gGuidStringFormat
= "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"
40 _HEADER_
= struct
.Struct("")
41 _HEADER_SIZE_
= _HEADER_
.size
43 def __new__(cls
, *args
, **kwargs
):
44 return array
.__new
__(cls
, 'B')
46 def __init__(self
, ID
=None):
48 self
._ID
_ = str(uuid
.uuid1()).upper()
55 self
._SubImages
= sdict() # {offset: Image()}
63 Len
= array
.__len
__(self
)
64 for Offset
in self
._SubImages
.keys():
65 Len
+= len(self
._SubImages
[Offset
])
69 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
72 def _Pack(self
, PadByte
=0xFF):
73 raise NotImplementedError
75 def frombuffer(self
, Buffer
, Offset
=0, Size
=None):
78 # we may need the Size information in advance if it's given
80 self
._LEN
_ = self
._Unpack
()
85 def GetField(self
, FieldStruct
, Offset
=0):
86 return FieldStruct
.unpack_from(self
, Offset
)
88 def SetField(self
, FieldStruct
, Offset
, *args
):
89 # check if there's enough space
90 Size
= FieldStruct
.size
92 self
.extend([0] * (Size
- len(self
)))
93 FieldStruct
.pack_into(self
, Offset
, *args
)
95 def _SetData(self
, Data
):
96 if len(self
) < self
._HEADER
_SIZE
_:
97 self
.extend([0] * (self
._HEADER
_SIZE
_ - len(self
)))
99 del self
[self
._HEADER
_SIZE
_:]
103 if len(self
) > self
._HEADER
_SIZE
_:
104 return self
[self
._HEADER
_SIZE
_:]
107 Data
= property(_GetData
, _SetData
)
109 ## CompressedImage() class
111 # A class for Compressed Image
113 class CompressedImage(Image
):
114 # UncompressedLength = 4-byte
115 # CompressionType = 1-byte
116 _HEADER_
= struct
.Struct("1I 1B")
117 _HEADER_SIZE_
= _HEADER_
.size
119 _ORIG_SIZE_
= struct
.Struct("1I")
120 _CMPRS_TYPE_
= struct
.Struct("4x 1B")
122 def __init__(self
, CompressedData
=None, CompressionType
=None, UncompressedLength
=None):
124 if UncompressedLength
is not None:
125 self
.UncompressedLength
= UncompressedLength
126 if CompressionType
is not None:
127 self
.CompressionType
= CompressionType
128 if CompressedData
is not None:
129 self
.Data
= CompressedData
133 S
= "algorithm=%s uncompressed=%x" % (self
.CompressionType
, self
.UncompressedLength
)
134 for Sec
in self
.Sections
:
139 def _SetOriginalSize(self
, Size
):
140 self
.SetField(self
._ORIG
_SIZE
_, 0, Size
)
142 def _GetOriginalSize(self
):
143 return self
.GetField(self
._ORIG
_SIZE
_)[0]
145 def _SetCompressionType(self
, Type
):
146 self
.SetField(self
._CMPRS
_TYPE
_, 0, Type
)
148 def _GetCompressionType(self
):
149 return self
.GetField(self
._CMPRS
_TYPE
_)[0]
151 def _GetSections(self
):
153 TmpData
= DeCompress('Efi', self
[self
._HEADER
_SIZE
_:])
155 DecData
.fromstring(TmpData
)
157 TmpData
= DeCompress('Framework', self
[self
._HEADER
_SIZE
_:])
159 DecData
.fromstring(TmpData
)
163 while Offset
< len(DecData
):
166 Sec
.frombuffer(DecData
, Offset
)
168 # the section is aligned to 4-byte boundary
171 SectionList
.append(Sec
)
174 UncompressedLength
= property(_GetOriginalSize
, _SetOriginalSize
)
175 CompressionType
= property(_GetCompressionType
, _SetCompressionType
)
176 Sections
= property(_GetSections
)
183 _HEADER_
= struct
.Struct("")
193 # keep header in this Image object
195 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
198 def _GetUiString(self
):
199 return codecs
.utf_16_decode(self
[0:-2].tostring())[0]
201 String
= property(_GetUiString
)
208 _HEADER_
= struct
.Struct("")
211 _GUID_
= struct
.Struct("1I2H8B")
212 _OPCODE_
= struct
.Struct("1B")
228 -1 : _OPCODE_
, # first one in depex must be an opcdoe
229 0x00 : _GUID_
, #"BEFORE",
230 0x01 : _GUID_
, #"AFTER",
231 0x02 : _GUID_
, #"PUSH",
232 0x03 : _OPCODE_
, #"AND",
233 0x04 : _OPCODE_
, #"OR",
234 0x05 : _OPCODE_
, #"NOT",
235 0x06 : _OPCODE_
, #"TRUE",
236 0x07 : _OPCODE_
, #"FALSE",
238 0x09 : _OPCODE_
, #"SOR"
248 Indention
= ' ' * gIndention
250 for T
in self
.Expression
:
251 if T
in self
._OPCODE
_STRING
_:
252 S
+= Indention
+ self
._OPCODE
_STRING
_[T
]
253 if T
not in [0x00, 0x01, 0x02]:
256 S
+= ' ' + gGuidStringFormat
% T
+ '\n'
261 # keep header in this Image object
263 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
266 def _GetExpression(self
):
267 if self
._ExprList
== []:
269 CurrentData
= self
._OPCODE
_
270 while Offset
< len(self
):
271 Token
= CurrentData
.unpack_from(self
, Offset
)
272 Offset
+= CurrentData
.size
275 if Token
in self
._NEXT
_:
276 CurrentData
= self
._NEXT
_[Token
]
278 CurrentData
= self
._GUID
_
280 CurrentData
= self
._OPCODE
_
281 self
._ExprList
.append(Token
)
282 if CurrentData
is None:
284 return self
._ExprList
286 Expression
= property(_GetExpression
)
288 # # FirmwareVolume() class
290 # A class for Firmware Volume
292 class FirmwareVolume(Image
):
293 # Read FvLength, Attributes, HeaderLength, Checksum
294 _HEADER_
= struct
.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")
295 _HEADER_SIZE_
= _HEADER_
.size
297 _FfsGuid
= "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
299 _GUID_
= struct
.Struct("16x 1I2H8B")
300 _LENGTH_
= struct
.Struct("16x 16x 1Q")
301 _SIG_
= struct
.Struct("16x 16x 8x 1I")
302 _ATTR_
= struct
.Struct("16x 16x 8x 4x 1I")
303 _HLEN_
= struct
.Struct("16x 16x 8x 4x 4x 1H")
304 _CHECKSUM_
= struct
.Struct("16x 16x 8x 4x 4x 2x 1H")
306 def __init__(self
, Name
=''):
309 self
.FfsDict
= sdict()
310 self
.OrderedFfsDict
= sdict()
311 self
.UnDispatchedFfsDict
= sdict()
312 self
.ProtocolList
= sdict()
314 def CheckArchProtocol(self
):
315 for Item
in EotGlobalData
.gArchProtocolGuids
:
316 if Item
.lower() not in EotGlobalData
.gProtocolList
:
320 def ParseDepex(self
, Depex
, Type
):
323 List
= EotGlobalData
.gPpiList
324 if Type
== 'Protocol':
325 List
= EotGlobalData
.gProtocolList
331 for Index
in range(0, len(Depex
.Expression
)):
332 Item
= Depex
.Expression
[Index
]
335 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
336 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
337 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
340 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
341 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
342 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
345 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
346 if Guid
.lower() in List
:
347 DepexStack
.append(True)
348 DepexList
.append(Guid
)
350 DepexStack
.append(False)
351 DepexList
.append(Guid
)
353 elif Item
== 0x03 or Item
== 0x04:
354 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
355 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
357 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
358 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
360 DepexStack
.append(True)
361 DepexList
.append('TRUE')
362 DepexString
= DepexString
+ 'TRUE' + ' '
364 DepexStack
.append(False)
365 DepexList
.append('False')
366 DepexString
= DepexString
+ 'FALSE' + ' '
368 if Index
!= len(Depex
.Expression
) - 1:
369 CouldBeLoaded
= False
371 CouldBeLoaded
= DepexStack
.pop()
373 CouldBeLoaded
= False
375 DepexString
= DepexList
[0].strip()
376 return (CouldBeLoaded
, DepexString
, FileDepex
)
378 def Dispatch(self
, Db
=None):
381 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
382 # Find PeiCore, DexCore, PeiPriori, DxePriori first
383 FfsSecCoreGuid
= None
384 FfsPeiCoreGuid
= None
385 FfsDxeCoreGuid
= None
386 FfsPeiPrioriGuid
= None
387 FfsDxePrioriGuid
= None
388 for FfsID
in list(self
.UnDispatchedFfsDict
.keys()):
389 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
391 FfsSecCoreGuid
= FfsID
394 FfsPeiCoreGuid
= FfsID
397 FfsDxeCoreGuid
= FfsID
399 if Ffs
.Guid
.lower() == PEI_APRIORI_GUID
.lower():
400 FfsPeiPrioriGuid
= FfsID
402 if Ffs
.Guid
.lower() == DXE_APRIORI_GUID
.lower():
403 FfsDxePrioriGuid
= FfsID
406 # Parse SEC_CORE first
407 if FfsSecCoreGuid
is not None:
408 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
409 self
.LoadPpi(Db
, FfsSecCoreGuid
)
412 if FfsPeiCoreGuid
is not None:
413 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
414 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
415 if FfsPeiPrioriGuid
is not None:
416 # Load PEIM described in priori file
417 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
418 if len(FfsPeiPriori
.Sections
) == 1:
419 Section
= FfsPeiPriori
.Sections
.popitem()[1]
420 if Section
.Type
== 0x19:
421 GuidStruct
= struct
.Struct('1I2H8B')
423 while len(Section
) > Start
:
424 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
425 GuidString
= gGuidStringFormat
% Guid
427 if GuidString
in self
.UnDispatchedFfsDict
:
428 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
429 self
.LoadPpi(Db
, GuidString
)
434 if FfsDxeCoreGuid
is not None:
435 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
436 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
437 if FfsDxePrioriGuid
is not None:
438 # Load PEIM described in priori file
439 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
440 if len(FfsDxePriori
.Sections
) == 1:
441 Section
= FfsDxePriori
.Sections
.popitem()[1]
442 if Section
.Type
== 0x19:
443 GuidStruct
= struct
.Struct('1I2H8B')
445 while len(Section
) > Start
:
446 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
447 GuidString
= gGuidStringFormat
% Guid
449 if GuidString
in self
.UnDispatchedFfsDict
:
450 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
451 self
.LoadProtocol(Db
, GuidString
)
455 def LoadProtocol(self
, Db
, ModuleGuid
):
456 SqlCommand
= """select GuidValue from Report
457 where SourceFileFullPath in
458 (select Value1 from Inf where BelongsToFile =
459 (select BelongsToFile from Inf
460 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
462 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
463 % (ModuleGuid
, 5001, 3007)
464 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
465 for Record
in RecordSet
:
466 SqlCommand
= """select Value2 from Inf where BelongsToFile =
467 (select DISTINCT BelongsToFile from Inf
469 (select SourceFileFullPath from Report
470 where GuidValue like '%s' and ItemMode = 'Callback'))
471 and Value1 = 'FILE_GUID'""" % Record
[0]
472 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
473 if CallBackSet
!= []:
474 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
476 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
478 def LoadPpi(self
, Db
, ModuleGuid
):
479 SqlCommand
= """select GuidValue from Report
480 where SourceFileFullPath in
481 (select Value1 from Inf where BelongsToFile =
482 (select BelongsToFile from Inf
483 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
485 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
486 % (ModuleGuid
, 5001, 3007)
487 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
488 for Record
in RecordSet
:
489 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
491 def DisPatchDxe(self
, Db
):
493 ScheduleList
= sdict()
494 for FfsID
in list(self
.UnDispatchedFfsDict
.keys()):
495 CouldBeLoaded
= False
498 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
502 for Section
in Ffs
.Sections
.values():
504 if Section
.Type
== 0x13:
506 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
508 if Section
.Type
== 0x01:
509 CompressSections
= Section
._SubImages
[4]
510 for CompressSection
in CompressSections
.Sections
:
511 if CompressSection
.Type
== 0x13:
513 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
515 if CompressSection
.Type
== 0x02:
516 NewSections
= CompressSection
._SubImages
[4]
517 for NewSection
in NewSections
.Sections
:
518 if NewSection
.Type
== 0x13:
520 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
525 CouldBeLoaded
= self
.CheckArchProtocol()
532 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
533 NewFfs
.Depex
= DepexString
534 if FileDepex
is not None:
535 ScheduleList
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
537 ScheduleList
[FfsID
] = NewFfs
539 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
541 for FfsID
in ScheduleList
.keys():
542 NewFfs
= ScheduleList
.pop(FfsID
)
544 self
.OrderedFfsDict
[FfsID
] = NewFfs
545 self
.LoadProtocol(Db
, FfsID
)
547 SqlCommand
= """select Value2 from Inf
548 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
549 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
550 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
552 FfsName
= RecordSet
[0][0]
557 def DisPatchPei(self
, Db
):
559 for FfsID
in list(self
.UnDispatchedFfsDict
.keys()):
563 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
564 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
566 for Section
in Ffs
.Sections
.values():
567 if Section
.Type
== 0x1B:
568 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
570 if Section
.Type
== 0x01:
571 CompressSections
= Section
._SubImages
[4]
572 for CompressSection
in CompressSections
.Sections
:
573 if CompressSection
.Type
== 0x1B:
574 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
576 if CompressSection
.Type
== 0x02:
577 NewSections
= CompressSection
._SubImages
[4]
578 for NewSection
in NewSections
.Sections
:
579 if NewSection
.Type
== 0x1B:
580 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
586 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
587 NewFfs
.Depex
= DepexString
588 self
.OrderedFfsDict
[FfsID
] = NewFfs
589 self
.LoadPpi(Db
, FfsID
)
591 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
600 FvInfo
= '\n' + ' ' * gIndention
601 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
602 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
604 return FvInfo
+ FfsInfo
607 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
609 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_ + Size
])
613 FfsStartAddress
= self
.HeaderSize
615 while FfsStartAddress
< EndOfFv
:
617 FfsObj
.frombuffer(self
, FfsStartAddress
)
619 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
620 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
621 if LastFfsObj
is not None:
622 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
624 if FfsId
in self
.FfsDict
:
625 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
626 ExtraData
="\t%s @ %s\n\t%s @ %s" \
627 % (FfsObj
.Guid
, FfsObj
.Offset
,
628 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
629 self
.FfsDict
[FfsId
] = FfsObj
630 if LastFfsObj
is not None:
631 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
633 FfsStartAddress
+= len(FfsObj
)
635 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
636 # The next FFS must be at the latest next 8-byte aligned address
638 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
641 def _GetAttributes(self
):
642 return self
.GetField(self
._ATTR
_, 0)[0]
645 return self
.GetField(self
._LENGTH
_, 0)[0]
647 def _GetChecksum(self
):
648 return self
.GetField(self
._CHECKSUM
_, 0)[0]
650 def _GetHeaderLength(self
):
651 return self
.GetField(self
._HLEN
_, 0)[0]
653 def _GetFileSystemGuid(self
):
654 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
656 Attributes
= property(_GetAttributes
)
657 Size
= property(_GetSize
)
658 Checksum
= property(_GetChecksum
)
659 HeaderSize
= property(_GetHeaderLength
)
660 FileSystemGuid
= property(_GetFileSystemGuid
)
662 ## GuidDefinedImage() class
664 # A class for GUID Defined Image
666 class GuidDefinedImage(Image
):
667 _HEADER_
= struct
.Struct("1I2H8B 1H 1H")
668 _HEADER_SIZE_
= _HEADER_
.size
670 _GUID_
= struct
.Struct("1I2H8B")
671 _DATA_OFFSET_
= struct
.Struct("16x 1H")
672 _ATTR_
= struct
.Struct("18x 1H")
674 CRC32_GUID
= "FC1BCDB0-7D31-49AA-936A-A4600D9DD083"
675 TIANO_COMPRESS_GUID
= 'A31280AD-481E-41B6-95E8-127F4C984779'
676 LZMA_COMPRESS_GUID
= 'EE4E5898-3914-4259-9D6E-DC7BD79403CF'
678 def __init__(self
, SectionDefinitionGuid
=None, DataOffset
=None, Attributes
=None, Data
=None):
680 if SectionDefinitionGuid
is not None:
681 self
.SectionDefinitionGuid
= SectionDefinitionGuid
682 if DataOffset
is not None:
683 self
.DataOffset
= DataOffset
684 if Attributes
is not None:
685 self
.Attributes
= Attributes
690 S
= "guid=%s" % (gGuidStringFormat
% self
.SectionDefinitionGuid
)
691 for Sec
in self
.Sections
:
696 # keep header in this Image object
698 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
701 def _SetAttribute(self
, Attribute
):
702 self
.SetField(self
._ATTR
_, 0, Attribute
)
704 def _GetAttribute(self
):
705 return self
.GetField(self
._ATTR
_)[0]
707 def _SetGuid(self
, Guid
):
708 self
.SetField(self
._GUID
_, 0, Guid
)
711 return self
.GetField(self
._GUID
_)
713 def _SetDataOffset(self
, Offset
):
714 self
.SetField(self
._DATA
_OFFSET
_, 0, Offset
)
716 def _GetDataOffset(self
):
717 return self
.GetField(self
._DATA
_OFFSET
_)[0]
719 def _GetSections(self
):
721 Guid
= gGuidStringFormat
% self
.SectionDefinitionGuid
722 if Guid
== self
.CRC32_GUID
:
723 # skip the CRC32 value, we don't do CRC32 verification here
724 Offset
= self
.DataOffset
- 4
725 while Offset
< len(self
):
728 Sec
.frombuffer(self
, Offset
)
730 # the section is aligned to 4-byte boundary
731 Offset
= (Offset
+ 3) & (~
3)
734 SectionList
.append(Sec
)
735 elif Guid
== self
.TIANO_COMPRESS_GUID
:
738 Offset
= self
.DataOffset
- 4
739 TmpData
= DeCompress('Framework', self
[self
.Offset
:])
741 DecData
.fromstring(TmpData
)
743 while Offset
< len(DecData
):
746 Sec
.frombuffer(DecData
, Offset
)
748 # the section is aligned to 4-byte boundary
749 Offset
= (Offset
+ 3) & (~
3)
752 SectionList
.append(Sec
)
755 elif Guid
== self
.LZMA_COMPRESS_GUID
:
758 Offset
= self
.DataOffset
- 4
760 TmpData
= DeCompress('Lzma', self
[self
.Offset
:])
762 DecData
.fromstring(TmpData
)
764 while Offset
< len(DecData
):
767 Sec
.frombuffer(DecData
, Offset
)
769 # the section is aligned to 4-byte boundary
770 Offset
= (Offset
+ 3) & (~
3)
773 SectionList
.append(Sec
)
779 Attributes
= property(_GetAttribute
, _SetAttribute
)
780 SectionDefinitionGuid
= property(_GetGuid
, _SetGuid
)
781 DataOffset
= property(_GetDataOffset
, _SetDataOffset
)
782 Sections
= property(_GetSections
)
786 # A class for Section
788 class Section(Image
):
791 0x01 : "COMPRESSION",
792 0x02 : "GUID_DEFINED",
798 0x15 : "USER_INTERFACE",
799 0x16 : "COMPATIBILITY16",
800 0x17 : "FIRMWARE_VOLUME_IMAGE",
801 0x18 : "FREEFORM_SUBTYPE_GUID",
806 _SectionSubImages
= {
807 0x01 : CompressedImage
,
808 0x02 : GuidDefinedImage
,
809 0x17 : FirmwareVolume
,
817 _HEADER_
= struct
.Struct("3B 1B")
818 _HEADER_SIZE_
= _HEADER_
.size
821 # _FREE_FORM_SUBTYPE_GUID_HEADER_ = struct.Struct("1I2H8B")
822 _SIZE_
= struct
.Struct("3B")
823 _TYPE_
= struct
.Struct("3x 1B")
825 def __init__(self
, Type
=None, Size
=None):
836 SectionInfo
= ' ' * gIndention
837 if self
.Type
in self
._TypeName
:
838 SectionInfo
+= "[SECTION:%s] offset=%x size=%x" % (self
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
)
840 SectionInfo
+= "[SECTION:%x<unknown>] offset=%x size=%x " % (self
.Type
, self
._OFF
_, self
.Size
)
841 for Offset
in self
._SubImages
.keys():
842 SectionInfo
+= ", " + str(self
._SubImages
[Offset
])
848 Type
, = self
._TYPE
_.unpack_from(self
._BUF
_, self
._OFF
_)
849 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
850 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
852 if Type
not in self
._SectionSubImages
:
853 # no need to extract sub-image, keep all in this Image object
854 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
856 # keep header in this Image object
857 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._HEADER
_SIZE
_])
859 # use new Image object to represent payload, which may be another kind
860 # of image such as PE32
862 PayloadOffset
= self
._HEADER
_SIZE
_
863 PayloadLen
= self
.Size
- self
._HEADER
_SIZE
_
864 Payload
= self
._SectionSubImages
[self
.Type
]()
865 Payload
.frombuffer(self
._BUF
_, self
._OFF
_ + self
._HEADER
_SIZE
_, PayloadLen
)
866 self
._SubImages
[PayloadOffset
] = Payload
870 def _SetSize(self
, Size
):
872 Size2
= (Size
& 0xFF00) >> 8
873 Size3
= (Size
& 0xFF0000) >> 16
874 self
.SetField(self
._SIZE
_, 0, Size1
, Size2
, Size3
)
877 Size1
, Size2
, Size3
= self
.GetField(self
._SIZE
_)
878 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
880 def _SetType(self
, Type
):
881 self
.SetField(self
._TYPE
_, 0, Type
)
884 return self
.GetField(self
._TYPE
_)[0]
886 def _GetAlignment(self
):
887 return self
._Alignment
889 def _SetAlignment(self
, Alignment
):
890 self
._Alignment
= Alignment
891 AlignmentMask
= Alignment
- 1
892 # section alignment is actually for payload, so we need to add header size
893 PayloadOffset
= self
._OFF
_ + self
._HEADER
_SIZE
_
894 if (PayloadOffset
& (~AlignmentMask
)) == 0:
896 NewOffset
= (PayloadOffset
+ AlignmentMask
) & (~AlignmentMask
)
897 while (NewOffset
- PayloadOffset
) < self
._HEADER
_SIZE
_:
898 NewOffset
+= self
._Alignment
901 self
.Size
= len(self
)
902 Image
.tofile(self
, f
)
903 for Offset
in self
._SubImages
:
904 self
._SubImages
[Offset
].tofile(f
)
906 Type
= property(_GetType
, _SetType
)
907 Size
= property(_GetSize
, _SetSize
)
908 Alignment
= property(_GetAlignment
, _SetAlignment
)
912 # A class for Ffs Section
915 _FfsFormat
= "24B%(payload_size)sB"
916 # skip IntegrityCheck
917 _HEADER_
= struct
.Struct("1I2H8B 2x 1B 1B 3B 1B")
918 _HEADER_SIZE_
= _HEADER_
.size
920 _NAME_
= struct
.Struct("1I2H8B")
921 _INT_CHECK_
= struct
.Struct("16x 1H")
922 _TYPE_
= struct
.Struct("18x 1B")
923 _ATTR_
= struct
.Struct("19x 1B")
924 _SIZE_
= struct
.Struct("20x 3B")
925 _STATE_
= struct
.Struct("23x 1B")
927 FFS_ATTRIB_FIXED
= 0x04
928 FFS_ATTRIB_DATA_ALIGNMENT
= 0x38
929 FFS_ATTRIB_CHECKSUM
= 0x40
935 0x03 : "SECURITY_CORE",
940 0x08 : "COMBINED_PEIM_DRIVER",
941 0x09 : "APPLICATION",
943 0x0B : "FIRMWARE_VOLUME_IMAGE",
944 0x0C : "COMBINED_SMM_DXE",
946 0x0E : "MM_STANDALONE",
947 0x0F : "MM_CORE_STANDALONE",
961 self
.Sections
= sdict()
969 Indention
= ' ' * gIndention
971 FfsInfo
+= "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \
972 (Ffs
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
, self
.Guid
, self
.FreeSpace
, self
.Alignment
)
973 SectionInfo
= '\n'.join([str(self
.Sections
[Offset
]) for Offset
in self
.Sections
.keys()])
975 return FfsInfo
+ SectionInfo
+ "\n"
984 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
985 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
987 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
989 # Pad FFS may use the same GUID. We need to avoid it.
990 if self
.Type
== 0xf0:
991 self
.__ID
__ = str(uuid
.uuid1()).upper()
993 self
.__ID
__ = self
.Guid
995 # Traverse the SECTION. RAW and PAD do not have sections
996 if self
.Type
not in [0xf0, 0x01] and Size
> 0 and Size
< 0xFFFFFF:
998 SectionStartAddress
= self
._HEADER
_SIZE
_
999 while SectionStartAddress
< EndOfFfs
:
1000 SectionObj
= Section()
1001 SectionObj
.frombuffer(self
, SectionStartAddress
)
1002 #f = open(repr(SectionObj), 'wb')
1003 #SectionObj.Size = 0
1004 #SectionObj.tofile(f)
1006 self
.Sections
[SectionStartAddress
] = SectionObj
1007 SectionStartAddress
+= len(SectionObj
)
1008 SectionStartAddress
= (SectionStartAddress
+ 3) & (~
3)
1013 def SetFreeSpace(self
, Size
):
1014 self
.FreeSpace
= Size
1017 return gGuidStringFormat
% self
.Name
1019 def _SetName(self
, Value
):
1020 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1021 self
.SetField(self
._NAME
_, 0, Value
)
1024 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1025 return self
.GetField(self
._NAME
_)
1027 def _SetSize(self
, Size
):
1029 Size2
= (Size
& 0xFF00) >> 8
1030 Size3
= (Size
& 0xFF0000) >> 16
1031 self
.SetField(self
._SIZE
_, 0, Size1
, Size2
, Size3
)
1034 Size1
, Size2
, Size3
= self
.GetField(self
._SIZE
_)
1035 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
1037 def _SetType(self
, Type
):
1038 self
.SetField(self
._TYPE
_, 0, Type
)
1041 return self
.GetField(self
._TYPE
_)[0]
1043 def _SetAttributes(self
, Value
):
1044 self
.SetField(self
._ATTR
_, 0, Value
)
1046 def _GetAttributes(self
):
1047 return self
.GetField(self
._ATTR
_)[0]
1049 def _GetFixed(self
):
1050 if (self
.Attributes
& self
.FFS_ATTRIB_FIXED
) != 0:
1054 def _GetCheckSum(self
):
1055 if (self
.Attributes
& self
.FFS_ATTRIB_CHECKSUM
) != 0:
1059 def _GetAlignment(self
):
1060 return (self
.Attributes
& self
.FFS_ATTRIB_DATA_ALIGNMENT
) >> 3
1062 def _SetState(self
, Value
):
1063 self
.SetField(self
._STATE
_, 0, Value
)
1065 def _GetState(self
):
1066 return self
.GetField(self
._STATE
_)[0]
1068 Name
= property(_GetName
, _SetName
)
1069 Guid
= property(_GetGuid
)
1070 Type
= property(_GetType
, _SetType
)
1071 Size
= property(_GetSize
, _SetSize
)
1072 Attributes
= property(_GetAttributes
, _SetAttributes
)
1073 Fixed
= property(_GetFixed
)
1074 Checksum
= property(_GetCheckSum
)
1075 Alignment
= property(_GetAlignment
)
1076 State
= property(_GetState
, _SetState
)
1079 ## MultipleFv() class
1081 # A class for Multiple FV
1083 class MultipleFv(FirmwareVolume
):
1084 def __init__(self
, FvList
):
1085 FirmwareVolume
.__init
__(self
)
1087 for FvPath
in FvList
:
1089 FvName
= os
.path
.splitext(os
.path
.split(FvPath
)[1])[0]
1091 Fd
= open(FvPath
, 'rb')
1094 Buf
.fromfile(Fd
, os
.path
.getsize(FvPath
))
1098 Fv
= FirmwareVolume(FvName
)
1099 Fv
.frombuffer(Buf
, 0, len(Buf
))
1101 self
.BasicInfo
.append([Fv
.Name
, Fv
.FileSystemGuid
, Fv
.Size
])
1102 self
.FfsDict
.update(Fv
.FfsDict
)
1106 # This class is used to define Eot main entrance
1108 # @param object: Inherited from object class
1113 # @param self: The object pointer
1115 def __init__(self
, CommandLineOption
=True, IsInit
=True, SourceFileList
=None, \
1116 IncludeDirList
=None, DecFileList
=None, GuidList
=None, LogFile
=None,
1117 FvFileList
="", MapFileList
="", Report
='Report.html', Dispatch
=None):
1118 # Version and Copyright
1119 self
.VersionNumber
= ("0.02" + " " + gBUILD_VERSION
)
1120 self
.Version
= "%prog Version " + self
.VersionNumber
1121 self
.Copyright
= "Copyright (c) 2008 - 2018, Intel Corporation All rights reserved."
1122 self
.Report
= Report
1124 self
.IsInit
= IsInit
1125 self
.SourceFileList
= SourceFileList
1126 self
.IncludeDirList
= IncludeDirList
1127 self
.DecFileList
= DecFileList
1128 self
.GuidList
= GuidList
1129 self
.LogFile
= LogFile
1130 self
.FvFileList
= FvFileList
1131 self
.MapFileList
= MapFileList
1132 self
.Dispatch
= Dispatch
1134 # Check workspace environment
1135 if "EFI_SOURCE" not in os
.environ
:
1136 if "EDK_SOURCE" not in os
.environ
:
1139 EotGlobalData
.gEDK_SOURCE
= os
.path
.normpath(os
.getenv("EDK_SOURCE"))
1141 EotGlobalData
.gEFI_SOURCE
= os
.path
.normpath(os
.getenv("EFI_SOURCE"))
1142 EotGlobalData
.gEDK_SOURCE
= os
.path
.join(EotGlobalData
.gEFI_SOURCE
, 'Edk')
1144 if "WORKSPACE" not in os
.environ
:
1145 EdkLogger
.error("EOT", BuildToolError
.ATTRIBUTE_NOT_AVAILABLE
, "Environment variable not found",
1146 ExtraData
="WORKSPACE")
1148 EotGlobalData
.gWORKSPACE
= os
.path
.normpath(os
.getenv("WORKSPACE"))
1150 EotGlobalData
.gMACRO
['WORKSPACE'] = EotGlobalData
.gWORKSPACE
1151 EotGlobalData
.gMACRO
['EFI_SOURCE'] = EotGlobalData
.gEFI_SOURCE
1152 EotGlobalData
.gMACRO
['EDK_SOURCE'] = EotGlobalData
.gEDK_SOURCE
1154 # Parse the options and args
1155 if CommandLineOption
:
1159 for FvFile
in GetSplitValueList(self
.FvFileList
, ' '):
1160 FvFile
= os
.path
.normpath(FvFile
)
1161 if not os
.path
.isfile(FvFile
):
1162 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % FvFile
)
1163 EotGlobalData
.gFV_FILE
.append(FvFile
)
1165 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "The fv file list of target platform was not specified")
1167 if self
.MapFileList
:
1168 for MapFile
in GetSplitValueList(self
.MapFileList
, ' '):
1169 MapFile
= os
.path
.normpath(MapFile
)
1170 if not os
.path
.isfile(MapFile
):
1171 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % MapFile
)
1172 EotGlobalData
.gMAP_FILE
.append(MapFile
)
1174 # Generate source file list
1175 self
.GenerateSourceFileList(self
.SourceFileList
, self
.IncludeDirList
)
1177 # Generate guid list of dec file list
1178 self
.ParseDecFile(self
.DecFileList
)
1180 # Generate guid list from GUID list file
1181 self
.ParseGuidList(self
.GuidList
)
1184 EotGlobalData
.gDb
= Database
.Database(Database
.DATABASE_PATH
)
1185 EotGlobalData
.gDb
.InitDatabase(self
.IsInit
)
1187 # Build ECC database
1188 self
.BuildDatabase()
1190 # Parse Ppi/Protocol
1191 self
.ParseExecutionOrder()
1193 # Merge Identifier tables
1194 self
.GenerateQueryTable()
1196 # Generate report database
1197 self
.GenerateReportDatabase()
1206 self
.GenerateReport()
1209 self
.ConvertLogFile(self
.LogFile
)
1212 EdkLogger
.quiet("EOT FINISHED!")
1215 EotGlobalData
.gDb
.Close()
1217 ## ParseDecFile() method
1219 # parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}
1220 # The Dict is stored in EotGlobalData.gGuidDict
1222 # @param self: The object pointer
1223 # @param DecFileList: A list of all DEC files
1225 def ParseDecFile(self
, DecFileList
):
1227 path
= os
.path
.normpath(DecFileList
)
1228 lfr
= open(path
, 'rb')
1230 path
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1231 if os
.path
.exists(path
):
1232 dfr
= open(path
, 'rb')
1234 line
= CleanString(line
)
1235 list = line
.split('=')
1237 EotGlobalData
.gGuidDict
[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())
1240 ## ParseGuidList() method
1242 # Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}
1243 # The Dict is stored in EotGlobalData.gGuidDict
1245 # @param self: The object pointer
1246 # @param GuidList: A list of all GUID and its value
1248 def ParseGuidList(self
, GuidList
):
1249 Path
= os
.path
.join(EotGlobalData
.gWORKSPACE
, GuidList
)
1250 if os
.path
.isfile(Path
):
1251 for Line
in open(Path
):
1253 (GuidName
, GuidValue
) = Line
.split()
1254 EotGlobalData
.gGuidDict
[GuidName
] = GuidValue
1256 ## ConvertLogFile() method
1258 # Parse a real running log file to get real dispatch order
1259 # The result is saved to old file name + '.new'
1261 # @param self: The object pointer
1262 # @param LogFile: A real running log file name
1264 def ConvertLogFile(self
, LogFile
):
1269 lfr
= open(LogFile
, 'rb')
1270 lfw
= open(LogFile
+ '.new', 'wb')
1273 line
= line
.replace('.efi', '')
1274 index
= line
.find("Loading PEIM at ")
1276 newline
.append(line
[index
+ 55 : ])
1278 index
= line
.find("Loading driver at ")
1280 newline
.append(line
[index
+ 57 : ])
1283 for line
in newline
:
1284 lfw
.write(line
+ '\r\n')
1291 ## GenerateSourceFileList() method
1293 # Generate a list of all source files
1294 # 1. Search the file list one by one
1295 # 2. Store inf file name with source file names under it like
1296 # { INF file name: [source file1, source file2, ...]}
1297 # 3. Search the include list to find all .h files
1298 # 4. Store source file list to EotGlobalData.gSOURCE_FILES
1299 # 5. Store INF file list to EotGlobalData.gINF_FILES
1301 # @param self: The object pointer
1302 # @param SourceFileList: A list of all source files
1303 # @param IncludeFileList: A list of all include files
1305 def GenerateSourceFileList(self
, SourceFileList
, IncludeFileList
):
1306 EdkLogger
.quiet("Generating source files list ... ")
1307 mSourceFileList
= []
1311 mCurrentInfFile
= ''
1312 mCurrentSourceFileList
= []
1315 sfl
= open(SourceFileList
, 'r')
1317 line
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1318 if line
[-2:].upper() == '.C' or line
[-2:].upper() == '.H':
1319 if line
not in mCurrentSourceFileList
:
1320 mCurrentSourceFileList
.append(line
)
1321 mSourceFileList
.append(line
)
1322 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % line
)
1323 if line
[-4:].upper() == '.INF':
1324 if mCurrentInfFile
!= '':
1325 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1326 mCurrentSourceFileList
= []
1327 mCurrentInfFile
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
))
1328 EotGlobalData
.gOP_INF
.write('%s\n' % mCurrentInfFile
)
1329 if mCurrentInfFile
not in mFileList
:
1330 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1332 # Get all include files from packages
1334 ifl
= open(IncludeFileList
, 'rb')
1336 if not line
.strip():
1338 newline
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1339 for Root
, Dirs
, Files
in os
.walk(str(newline
)):
1341 FullPath
= os
.path
.normpath(os
.path
.join(Root
, File
))
1342 if FullPath
not in mSourceFileList
and File
[-2:].upper() == '.H':
1343 mSourceFileList
.append(FullPath
)
1344 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % FullPath
)
1345 if FullPath
not in mDecFileList
and File
.upper().find('.DEC') > -1:
1346 mDecFileList
.append(FullPath
)
1348 EotGlobalData
.gSOURCE_FILES
= mSourceFileList
1349 EotGlobalData
.gOP_SOURCE_FILES
.close()
1351 EotGlobalData
.gINF_FILES
= mFileList
1352 EotGlobalData
.gOP_INF
.close()
1354 ## GenerateReport() method
1356 # Generate final HTML report
1358 # @param self: The object pointer
1360 def GenerateReport(self
):
1361 EdkLogger
.quiet("Generating report file ... ")
1362 Rep
= Report(self
.Report
, EotGlobalData
.gFV
, self
.Dispatch
)
1363 Rep
.GenerateReport()
1365 ## LoadMapInfo() method
1367 # Load map files and parse them
1369 # @param self: The object pointer
1371 def LoadMapInfo(self
):
1372 if EotGlobalData
.gMAP_FILE
!= []:
1373 EdkLogger
.quiet("Parsing Map file ... ")
1374 EotGlobalData
.gMap
= ParseMapFile(EotGlobalData
.gMAP_FILE
)
1376 ## LoadFvInfo() method
1378 # Load FV binary files and parse them
1380 # @param self: The object pointer
1382 def LoadFvInfo(self
):
1383 EdkLogger
.quiet("Parsing FV file ... ")
1384 EotGlobalData
.gFV
= MultipleFv(EotGlobalData
.gFV_FILE
)
1385 EotGlobalData
.gFV
.Dispatch(EotGlobalData
.gDb
)
1387 for Protocol
in EotGlobalData
.gProtocolList
:
1388 EotGlobalData
.gOP_UN_MATCHED_IN_LIBRARY_CALLING
.write('%s\n' %Protocol
)
1390 ## GenerateReportDatabase() method
1392 # Generate data for the information needed by report
1393 # 1. Update name, macro and value of all found PPI/PROTOCOL GUID
1394 # 2. Install hard coded PPI/PROTOCOL
1396 # @param self: The object pointer
1398 def GenerateReportDatabase(self
):
1399 EdkLogger
.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")
1401 # Update Protocol/Ppi Guid
1402 SqlCommand
= """select DISTINCT GuidName from Report"""
1403 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1404 for Record
in RecordSet
:
1405 GuidName
= Record
[0]
1410 # Find guid value defined in Dec file
1411 if GuidName
in EotGlobalData
.gGuidDict
:
1412 GuidValue
= EotGlobalData
.gGuidDict
[GuidName
]
1413 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1414 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1417 # Search defined Macros for guid name
1418 SqlCommand
="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName
1419 GuidMacroSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1420 # Ignore NULL result
1421 if not GuidMacroSet
:
1423 GuidMacro
= GuidMacroSet
[0][0].strip()
1426 # Find Guid value of Guid Macro
1427 SqlCommand
="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro
, MODEL_IDENTIFIER_MACRO_DEFINE
)
1428 GuidValueSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1429 if GuidValueSet
!= []:
1430 GuidValue
= GuidValueSet
[0][0]
1431 GuidValue
= GuidValue
[GuidValue
.find(GuidMacro
) + len(GuidMacro
) :]
1432 GuidValue
= GuidValue
.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()
1433 GuidValue
= GuidStructureStringToGuidString(GuidValue
)
1434 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1435 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1438 # Update Hard Coded Ppi/Protocol
1439 SqlCommand
= """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""
1440 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1441 for Record
in RecordSet
:
1442 if Record
[1] == 'Ppi':
1443 EotGlobalData
.gPpiList
[Record
[0].lower()] = -2
1444 if Record
[1] == 'Protocol':
1445 EotGlobalData
.gProtocolList
[Record
[0].lower()] = -2
1447 ## GenerateQueryTable() method
1449 # Generate two tables improve query performance
1451 # @param self: The object pointer
1453 def GenerateQueryTable(self
):
1454 EdkLogger
.quiet("Generating temp query table for analysis ... ")
1455 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1456 SqlCommand
= """insert into Query (Name, Modifier, Value, Model)
1457 select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \
1458 % (Identifier
[0], MODEL_IDENTIFIER_VARIABLE
, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION
)
1459 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1460 SqlCommand
= """insert into Query2 (Name, Modifier, Value, Model)
1461 select Name, Modifier, Value, Model from %s where Model = %s""" \
1462 % (Identifier
[0], MODEL_IDENTIFIER_MACRO_DEFINE
)
1463 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1465 ## ParseExecutionOrder() method
1467 # Get final execution order
1469 # 2. Search all PROTOCOL
1471 # @param self: The object pointer
1473 def ParseExecutionOrder(self
):
1474 EdkLogger
.quiet("Searching Ppi/Protocol ... ")
1475 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1476 ModuleID
, ModuleName
, ModuleGuid
, SourceFileID
, SourceFileFullPath
, ItemName
, ItemType
, ItemMode
, GuidName
, GuidMacro
, GuidValue
, BelongsToFunction
, Enabled
= \
1477 -1, '', '', -1, '', '', '', '', '', '', '', '', 0
1479 SourceFileID
= Identifier
[0].replace('Identifier', '')
1480 SourceFileFullPath
= Identifier
[1]
1481 Identifier
= Identifier
[0]
1484 ItemMode
= 'Produced'
1485 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1486 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1487 % (Identifier
, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1488 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1490 ItemMode
= 'Produced'
1491 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1492 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1493 % (Identifier
, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1494 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1496 SearchPpiCallFunction(Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1498 ItemMode
= 'Consumed'
1499 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1500 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1501 % (Identifier
, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1502 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1504 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Ppi', ItemMode
)
1506 ItemMode
= 'Callback'
1507 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1508 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1509 % (Identifier
, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1510 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1513 ItemMode
= 'Produced'
1514 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1515 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1516 % (Identifier
, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1517 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1519 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1520 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1521 % (Identifier
, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1522 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1524 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1526 ItemMode
= 'Consumed'
1527 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1528 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1529 % (Identifier
, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1530 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1532 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1533 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1534 % (Identifier
, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1535 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1537 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1539 ItemMode
= 'Callback'
1540 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1541 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1542 % (Identifier
, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1543 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1545 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1548 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)
1549 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)
1550 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)
1551 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)
1552 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)
1553 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)
1554 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)
1555 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)
1556 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)
1558 EotGlobalData
.gDb
.Conn
.commit()
1561 ## BuildDatabase() methoc
1563 # Build the database for target
1565 # @param self: The object pointer
1567 def BuildDatabase(self
):
1568 # Clean report table
1569 EotGlobalData
.gDb
.TblReport
.Drop()
1570 EotGlobalData
.gDb
.TblReport
.Create()
1574 self
.BuildMetaDataFileDatabase(EotGlobalData
.gINF_FILES
)
1575 EdkLogger
.quiet("Building database for source code ...")
1576 c
.CreateCCodeDB(EotGlobalData
.gSOURCE_FILES
)
1577 EdkLogger
.quiet("Building database for source code done!")
1579 EotGlobalData
.gIdentifierTableList
= GetTableList((MODEL_FILE_C
, MODEL_FILE_H
), 'Identifier', EotGlobalData
.gDb
)
1581 ## BuildMetaDataFileDatabase() method
1583 # Build the database for meta data files
1585 # @param self: The object pointer
1586 # @param Inf_Files: A list for all INF files
1588 def BuildMetaDataFileDatabase(self
, Inf_Files
):
1589 EdkLogger
.quiet("Building database for meta data files ...")
1590 for InfFile
in Inf_Files
:
1593 EdkLogger
.quiet("Parsing %s ..." % str(InfFile
))
1594 EdkInfParser(InfFile
, EotGlobalData
.gDb
, Inf_Files
[InfFile
])
1596 EotGlobalData
.gDb
.Conn
.commit()
1597 EdkLogger
.quiet("Building database for meta data files done!")
1599 ## ParseOption() method
1601 # Parse command line options
1603 # @param self: The object pointer
1605 def ParseOption(self
):
1606 (Options
, Target
) = self
.EotOptionParser()
1609 self
.SetLogLevel(Options
)
1611 if Options
.FvFileList
:
1612 self
.FvFileList
= Options
.FvFileList
1614 if Options
.MapFileList
:
1615 self
.MapFileList
= Options
.FvMapFileList
1617 if Options
.SourceFileList
:
1618 self
.SourceFileList
= Options
.SourceFileList
1620 if Options
.IncludeDirList
:
1621 self
.IncludeDirList
= Options
.IncludeDirList
1623 if Options
.DecFileList
:
1624 self
.DecFileList
= Options
.DecFileList
1626 if Options
.GuidList
:
1627 self
.GuidList
= Options
.GuidList
1630 self
.LogFile
= Options
.LogFile
1632 if Options
.keepdatabase
:
1635 ## SetLogLevel() method
1637 # Set current log level of the tool based on args
1639 # @param self: The object pointer
1640 # @param Option: The option list including log level setting
1642 def SetLogLevel(self
, Option
):
1643 if Option
.verbose
is not None:
1644 EdkLogger
.SetLevel(EdkLogger
.VERBOSE
)
1645 elif Option
.quiet
is not None:
1646 EdkLogger
.SetLevel(EdkLogger
.QUIET
)
1647 elif Option
.debug
is not None:
1648 EdkLogger
.SetLevel(Option
.debug
+ 1)
1650 EdkLogger
.SetLevel(EdkLogger
.INFO
)
1652 ## EotOptionParser() method
1654 # Using standard Python module optparse to parse command line option of this tool.
1656 # @param self: The object pointer
1658 # @retval Opt A optparse.Values object containing the parsed options
1659 # @retval Args Target of build command
1661 def EotOptionParser(self
):
1662 Parser
= OptionParser(description
= self
.Copyright
, version
= self
.Version
, prog
= "Eot.exe", usage
= "%prog [options]")
1663 Parser
.add_option("-m", "--makefile filename", action
="store", type="string", dest
='MakeFile',
1664 help="Specify a makefile for the platform.")
1665 Parser
.add_option("-c", "--dsc filename", action
="store", type="string", dest
="DscFile",
1666 help="Specify a dsc file for the platform.")
1667 Parser
.add_option("-f", "--fv filename", action
="store", type="string", dest
="FvFileList",
1668 help="Specify fv file list, quoted by \"\".")
1669 Parser
.add_option("-a", "--map filename", action
="store", type="string", dest
="MapFileList",
1670 help="Specify map file list, quoted by \"\".")
1671 Parser
.add_option("-s", "--source files", action
="store", type="string", dest
="SourceFileList",
1672 help="Specify source file list by a file")
1673 Parser
.add_option("-i", "--include dirs", action
="store", type="string", dest
="IncludeDirList",
1674 help="Specify include dir list by a file")
1675 Parser
.add_option("-e", "--dec files", action
="store", type="string", dest
="DecFileList",
1676 help="Specify dec file list by a file")
1677 Parser
.add_option("-g", "--guid list", action
="store", type="string", dest
="GuidList",
1678 help="Specify guid file list by a file")
1679 Parser
.add_option("-l", "--log filename", action
="store", type="string", dest
="LogFile",
1680 help="Specify real execution log file")
1682 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.")
1684 Parser
.add_option("-q", "--quiet", action
="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
1685 Parser
.add_option("-v", "--verbose", action
="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
1686 "including library instances selected, final dependency expression, "\
1687 "and warning messages, etc.")
1688 Parser
.add_option("-d", "--debug", action
="store", type="int", help="Enable debug messages at specified level.")
1690 (Opt
, Args
)=Parser
.parse_args()
1696 # This acts like the main() function for the script, unless it is 'import'ed into another
1699 if __name__
== '__main__':
1700 # Initialize log system
1701 EdkLogger
.Initialize()
1702 EdkLogger
.IsRaiseError
= False
1703 EdkLogger
.quiet(time
.strftime("%H:%M:%S, %b.%d %Y ", time
.localtime()) + "[00:00]" + "\n")
1705 StartTime
= time
.clock()
1706 Eot
= Eot(CommandLineOption
=False,
1707 SourceFileList
=r
'C:\TestEot\Source.txt',
1708 GuidList
=r
'C:\TestEot\Guid.txt',
1709 FvFileList
=r
'C:\TestEot\FVRECOVERY.Fv')
1710 FinishTime
= time
.clock()
1712 BuildDuration
= time
.strftime("%M:%S", time
.gmtime(int(round(FinishTime
- StartTime
))))
1713 EdkLogger
.quiet("\n%s [%s]" % (time
.strftime("%H:%M:%S, %b.%d %Y", time
.localtime()), BuildDuration
))