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 ## MultipleFv() class
1088 # A class for Multiple FV
1090 class MultipleFv(FirmwareVolume
):
1091 def __init__(self
, FvList
):
1092 FirmwareVolume
.__init
__(self
)
1094 for FvPath
in FvList
:
1096 FvName
= os
.path
.splitext(os
.path
.split(FvPath
)[1])[0]
1098 Fd
= open(FvPath
, 'rb')
1101 Buf
.fromfile(Fd
, os
.path
.getsize(FvPath
))
1105 Fv
= FirmwareVolume(FvName
)
1106 Fv
.frombuffer(Buf
, 0, len(Buf
))
1108 self
.BasicInfo
.append([Fv
.Name
, Fv
.FileSystemGuid
, Fv
.Size
])
1109 self
.FfsDict
.append(Fv
.FfsDict
)
1113 # This class is used to define Eot main entrance
1115 # @param object: Inherited from object class
1120 # @param self: The object pointer
1122 def __init__(self
, CommandLineOption
=True, IsInit
=True, SourceFileList
=None, \
1123 IncludeDirList
=None, DecFileList
=None, GuidList
=None, LogFile
=None,
1124 FvFileList
="", MapFileList
="", Report
='Report.html', Dispatch
=None):
1125 # Version and Copyright
1126 self
.VersionNumber
= ("0.02" + " " + gBUILD_VERSION
)
1127 self
.Version
= "%prog Version " + self
.VersionNumber
1128 self
.Copyright
= "Copyright (c) 2008 - 2018, Intel Corporation All rights reserved."
1129 self
.Report
= Report
1131 self
.IsInit
= IsInit
1132 self
.SourceFileList
= SourceFileList
1133 self
.IncludeDirList
= IncludeDirList
1134 self
.DecFileList
= DecFileList
1135 self
.GuidList
= GuidList
1136 self
.LogFile
= LogFile
1137 self
.FvFileList
= FvFileList
1138 self
.MapFileList
= MapFileList
1139 self
.Dispatch
= Dispatch
1141 # Check workspace environment
1142 if "EFI_SOURCE" not in os
.environ
:
1143 if "EDK_SOURCE" not in os
.environ
:
1146 EotGlobalData
.gEDK_SOURCE
= os
.path
.normpath(os
.getenv("EDK_SOURCE"))
1148 EotGlobalData
.gEFI_SOURCE
= os
.path
.normpath(os
.getenv("EFI_SOURCE"))
1149 EotGlobalData
.gEDK_SOURCE
= os
.path
.join(EotGlobalData
.gEFI_SOURCE
, 'Edk')
1151 if "WORKSPACE" not in os
.environ
:
1152 EdkLogger
.error("EOT", BuildToolError
.ATTRIBUTE_NOT_AVAILABLE
, "Environment variable not found",
1153 ExtraData
="WORKSPACE")
1155 EotGlobalData
.gWORKSPACE
= os
.path
.normpath(os
.getenv("WORKSPACE"))
1157 EotGlobalData
.gMACRO
['WORKSPACE'] = EotGlobalData
.gWORKSPACE
1158 EotGlobalData
.gMACRO
['EFI_SOURCE'] = EotGlobalData
.gEFI_SOURCE
1159 EotGlobalData
.gMACRO
['EDK_SOURCE'] = EotGlobalData
.gEDK_SOURCE
1161 # Parse the options and args
1162 if CommandLineOption
:
1166 for FvFile
in GetSplitValueList(self
.FvFileList
, ' '):
1167 FvFile
= os
.path
.normpath(FvFile
)
1168 if not os
.path
.isfile(FvFile
):
1169 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % FvFile
)
1170 EotGlobalData
.gFV_FILE
.append(FvFile
)
1172 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "The fv file list of target platform was not specified")
1174 if self
.MapFileList
:
1175 for MapFile
in GetSplitValueList(self
.MapFileList
, ' '):
1176 MapFile
= os
.path
.normpath(MapFile
)
1177 if not os
.path
.isfile(MapFile
):
1178 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % MapFile
)
1179 EotGlobalData
.gMAP_FILE
.append(MapFile
)
1181 # Generate source file list
1182 self
.GenerateSourceFileList(self
.SourceFileList
, self
.IncludeDirList
)
1184 # Generate guid list of dec file list
1185 self
.ParseDecFile(self
.DecFileList
)
1187 # Generate guid list from GUID list file
1188 self
.ParseGuidList(self
.GuidList
)
1191 EotGlobalData
.gDb
= Database
.Database(Database
.DATABASE_PATH
)
1192 EotGlobalData
.gDb
.InitDatabase(self
.IsInit
)
1194 # Build ECC database
1195 self
.BuildDatabase()
1197 # Parse Ppi/Protocol
1198 self
.ParseExecutionOrder()
1200 # Merge Identifier tables
1201 self
.GenerateQueryTable()
1203 # Generate report database
1204 self
.GenerateReportDatabase()
1213 self
.GenerateReport()
1216 self
.ConvertLogFile(self
.LogFile
)
1219 EdkLogger
.quiet("EOT FINISHED!")
1222 EotGlobalData
.gDb
.Close()
1224 ## ParseDecFile() method
1226 # parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}
1227 # The Dict is stored in EotGlobalData.gGuidDict
1229 # @param self: The object pointer
1230 # @param DecFileList: A list of all DEC files
1232 def ParseDecFile(self
, DecFileList
):
1234 path
= os
.path
.normpath(DecFileList
)
1235 lfr
= open(path
, 'rb')
1237 path
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1238 if os
.path
.exists(path
):
1239 dfr
= open(path
, 'rb')
1241 line
= CleanString(line
)
1242 list = line
.split('=')
1244 EotGlobalData
.gGuidDict
[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())
1247 ## ParseGuidList() method
1249 # Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}
1250 # The Dict is stored in EotGlobalData.gGuidDict
1252 # @param self: The object pointer
1253 # @param GuidList: A list of all GUID and its value
1255 def ParseGuidList(self
, GuidList
):
1256 Path
= os
.path
.join(EotGlobalData
.gWORKSPACE
, GuidList
)
1257 if os
.path
.isfile(Path
):
1258 for Line
in open(Path
):
1260 (GuidName
, GuidValue
) = Line
.split()
1261 EotGlobalData
.gGuidDict
[GuidName
] = GuidValue
1263 ## ConvertLogFile() method
1265 # Parse a real running log file to get real dispatch order
1266 # The result is saved to old file name + '.new'
1268 # @param self: The object pointer
1269 # @param LogFile: A real running log file name
1271 def ConvertLogFile(self
, LogFile
):
1276 lfr
= open(LogFile
, 'rb')
1277 lfw
= open(LogFile
+ '.new', 'wb')
1280 line
= line
.replace('.efi', '')
1281 index
= line
.find("Loading PEIM at ")
1283 newline
.append(line
[index
+ 55 : ])
1285 index
= line
.find("Loading driver at ")
1287 newline
.append(line
[index
+ 57 : ])
1290 for line
in newline
:
1291 lfw
.write(line
+ '\r\n')
1298 ## GenerateSourceFileList() method
1300 # Generate a list of all source files
1301 # 1. Search the file list one by one
1302 # 2. Store inf file name with source file names under it like
1303 # { INF file name: [source file1, source file2, ...]}
1304 # 3. Search the include list to find all .h files
1305 # 4. Store source file list to EotGlobalData.gSOURCE_FILES
1306 # 5. Store INF file list to EotGlobalData.gINF_FILES
1308 # @param self: The object pointer
1309 # @param SourceFileList: A list of all source files
1310 # @param IncludeFileList: A list of all include files
1312 def GenerateSourceFileList(self
, SourceFileList
, IncludeFileList
):
1313 EdkLogger
.quiet("Generating source files list ... ")
1314 mSourceFileList
= []
1318 mCurrentInfFile
= ''
1319 mCurrentSourceFileList
= []
1322 sfl
= open(SourceFileList
, 'r')
1324 line
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1325 if line
[-2:].upper() == '.C' or line
[-2:].upper() == '.H':
1326 if line
not in mCurrentSourceFileList
:
1327 mCurrentSourceFileList
.append(line
)
1328 mSourceFileList
.append(line
)
1329 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % line
)
1330 if line
[-4:].upper() == '.INF':
1331 if mCurrentInfFile
!= '':
1332 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1333 mCurrentSourceFileList
= []
1334 mCurrentInfFile
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
))
1335 EotGlobalData
.gOP_INF
.write('%s\n' % mCurrentInfFile
)
1336 if mCurrentInfFile
not in mFileList
:
1337 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1339 # Get all include files from packages
1341 ifl
= open(IncludeFileList
, 'rb')
1343 if not line
.strip():
1345 newline
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1346 for Root
, Dirs
, Files
in os
.walk(str(newline
)):
1348 FullPath
= os
.path
.normpath(os
.path
.join(Root
, File
))
1349 if FullPath
not in mSourceFileList
and File
[-2:].upper() == '.H':
1350 mSourceFileList
.append(FullPath
)
1351 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % FullPath
)
1352 if FullPath
not in mDecFileList
and File
.upper().find('.DEC') > -1:
1353 mDecFileList
.append(FullPath
)
1355 EotGlobalData
.gSOURCE_FILES
= mSourceFileList
1356 EotGlobalData
.gOP_SOURCE_FILES
.close()
1358 EotGlobalData
.gINF_FILES
= mFileList
1359 EotGlobalData
.gOP_INF
.close()
1361 ## GenerateReport() method
1363 # Generate final HTML report
1365 # @param self: The object pointer
1367 def GenerateReport(self
):
1368 EdkLogger
.quiet("Generating report file ... ")
1369 Rep
= Report(self
.Report
, EotGlobalData
.gFV
, self
.Dispatch
)
1370 Rep
.GenerateReport()
1372 ## LoadMapInfo() method
1374 # Load map files and parse them
1376 # @param self: The object pointer
1378 def LoadMapInfo(self
):
1379 if EotGlobalData
.gMAP_FILE
!= []:
1380 EdkLogger
.quiet("Parsing Map file ... ")
1381 EotGlobalData
.gMap
= ParseMapFile(EotGlobalData
.gMAP_FILE
)
1383 ## LoadFvInfo() method
1385 # Load FV binary files and parse them
1387 # @param self: The object pointer
1389 def LoadFvInfo(self
):
1390 EdkLogger
.quiet("Parsing FV file ... ")
1391 EotGlobalData
.gFV
= MultipleFv(EotGlobalData
.gFV_FILE
)
1392 EotGlobalData
.gFV
.Dispatch(EotGlobalData
.gDb
)
1394 for Protocol
in EotGlobalData
.gProtocolList
:
1395 EotGlobalData
.gOP_UN_MATCHED_IN_LIBRARY_CALLING
.write('%s\n' %Protocol
)
1397 ## GenerateReportDatabase() method
1399 # Generate data for the information needed by report
1400 # 1. Update name, macro and value of all found PPI/PROTOCOL GUID
1401 # 2. Install hard coded PPI/PROTOCOL
1403 # @param self: The object pointer
1405 def GenerateReportDatabase(self
):
1406 EdkLogger
.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")
1408 # Update Protocol/Ppi Guid
1409 SqlCommand
= """select DISTINCT GuidName from Report"""
1410 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1411 for Record
in RecordSet
:
1412 GuidName
= Record
[0]
1417 # Find guid value defined in Dec file
1418 if GuidName
in EotGlobalData
.gGuidDict
:
1419 GuidValue
= EotGlobalData
.gGuidDict
[GuidName
]
1420 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1421 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1424 # Search defined Macros for guid name
1425 SqlCommand
="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName
1426 GuidMacroSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1427 # Ignore NULL result
1428 if not GuidMacroSet
:
1430 GuidMacro
= GuidMacroSet
[0][0].strip()
1433 # Find Guid value of Guid Macro
1434 SqlCommand
="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro
, MODEL_IDENTIFIER_MACRO_DEFINE
)
1435 GuidValueSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1436 if GuidValueSet
!= []:
1437 GuidValue
= GuidValueSet
[0][0]
1438 GuidValue
= GuidValue
[GuidValue
.find(GuidMacro
) + len(GuidMacro
) :]
1439 GuidValue
= GuidValue
.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()
1440 GuidValue
= GuidStructureStringToGuidString(GuidValue
)
1441 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1442 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1445 # Update Hard Coded Ppi/Protocol
1446 SqlCommand
= """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""
1447 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1448 for Record
in RecordSet
:
1449 if Record
[1] == 'Ppi':
1450 EotGlobalData
.gPpiList
[Record
[0].lower()] = -2
1451 if Record
[1] == 'Protocol':
1452 EotGlobalData
.gProtocolList
[Record
[0].lower()] = -2
1454 ## GenerateQueryTable() method
1456 # Generate two tables improve query performance
1458 # @param self: The object pointer
1460 def GenerateQueryTable(self
):
1461 EdkLogger
.quiet("Generating temp query table for analysis ... ")
1462 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1463 SqlCommand
= """insert into Query (Name, Modifier, Value, Model)
1464 select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \
1465 % (Identifier
[0], MODEL_IDENTIFIER_VARIABLE
, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION
)
1466 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1467 SqlCommand
= """insert into Query2 (Name, Modifier, Value, Model)
1468 select Name, Modifier, Value, Model from %s where Model = %s""" \
1469 % (Identifier
[0], MODEL_IDENTIFIER_MACRO_DEFINE
)
1470 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1472 ## ParseExecutionOrder() method
1474 # Get final execution order
1476 # 2. Search all PROTOCOL
1478 # @param self: The object pointer
1480 def ParseExecutionOrder(self
):
1481 EdkLogger
.quiet("Searching Ppi/Protocol ... ")
1482 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1483 ModuleID
, ModuleName
, ModuleGuid
, SourceFileID
, SourceFileFullPath
, ItemName
, ItemType
, ItemMode
, GuidName
, GuidMacro
, GuidValue
, BelongsToFunction
, Enabled
= \
1484 -1, '', '', -1, '', '', '', '', '', '', '', '', 0
1486 SourceFileID
= Identifier
[0].replace('Identifier', '')
1487 SourceFileFullPath
= Identifier
[1]
1488 Identifier
= Identifier
[0]
1491 ItemMode
= 'Produced'
1492 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1493 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1494 % (Identifier
, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1495 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1497 ItemMode
= 'Produced'
1498 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1499 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1500 % (Identifier
, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1501 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1503 SearchPpiCallFunction(Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1505 ItemMode
= 'Consumed'
1506 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1507 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1508 % (Identifier
, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1509 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1511 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Ppi', ItemMode
)
1513 ItemMode
= 'Callback'
1514 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1515 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1516 % (Identifier
, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1517 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1520 ItemMode
= 'Produced'
1521 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1522 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1523 % (Identifier
, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1524 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1526 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1527 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1528 % (Identifier
, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1529 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1531 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1533 ItemMode
= 'Consumed'
1534 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1535 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1536 % (Identifier
, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1537 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1539 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1540 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1541 % (Identifier
, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1542 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1544 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1546 ItemMode
= 'Callback'
1547 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1548 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1549 % (Identifier
, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1550 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1552 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1555 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)
1556 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)
1557 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)
1558 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)
1559 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)
1560 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)
1561 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)
1562 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)
1563 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)
1565 EotGlobalData
.gDb
.Conn
.commit()
1568 ## BuildDatabase() methoc
1570 # Build the database for target
1572 # @param self: The object pointer
1574 def BuildDatabase(self
):
1575 # Clean report table
1576 EotGlobalData
.gDb
.TblReport
.Drop()
1577 EotGlobalData
.gDb
.TblReport
.Create()
1581 self
.BuildMetaDataFileDatabase(EotGlobalData
.gINF_FILES
)
1582 EdkLogger
.quiet("Building database for source code ...")
1583 c
.CreateCCodeDB(EotGlobalData
.gSOURCE_FILES
)
1584 EdkLogger
.quiet("Building database for source code done!")
1586 EotGlobalData
.gIdentifierTableList
= GetTableList((MODEL_FILE_C
, MODEL_FILE_H
), 'Identifier', EotGlobalData
.gDb
)
1588 ## BuildMetaDataFileDatabase() method
1590 # Build the database for meta data files
1592 # @param self: The object pointer
1593 # @param Inf_Files: A list for all INF files
1595 def BuildMetaDataFileDatabase(self
, Inf_Files
):
1596 EdkLogger
.quiet("Building database for meta data files ...")
1597 for InfFile
in Inf_Files
:
1600 EdkLogger
.quiet("Parsing %s ..." % str(InfFile
))
1601 EdkInfParser(InfFile
, EotGlobalData
.gDb
, Inf_Files
[InfFile
], '')
1603 EotGlobalData
.gDb
.Conn
.commit()
1604 EdkLogger
.quiet("Building database for meta data files done!")
1606 ## ParseOption() method
1608 # Parse command line options
1610 # @param self: The object pointer
1612 def ParseOption(self
):
1613 (Options
, Target
) = self
.EotOptionParser()
1616 self
.SetLogLevel(Options
)
1618 if Options
.FvFileList
:
1619 self
.FvFileList
= Options
.FvFileList
1621 if Options
.MapFileList
:
1622 self
.MapFileList
= Options
.FvMapFileList
1624 if Options
.SourceFileList
:
1625 self
.SourceFileList
= Options
.SourceFileList
1627 if Options
.IncludeDirList
:
1628 self
.IncludeDirList
= Options
.IncludeDirList
1630 if Options
.DecFileList
:
1631 self
.DecFileList
= Options
.DecFileList
1633 if Options
.GuidList
:
1634 self
.GuidList
= Options
.GuidList
1637 self
.LogFile
= Options
.LogFile
1639 if Options
.keepdatabase
:
1642 ## SetLogLevel() method
1644 # Set current log level of the tool based on args
1646 # @param self: The object pointer
1647 # @param Option: The option list including log level setting
1649 def SetLogLevel(self
, Option
):
1650 if Option
.verbose
is not None:
1651 EdkLogger
.SetLevel(EdkLogger
.VERBOSE
)
1652 elif Option
.quiet
is not None:
1653 EdkLogger
.SetLevel(EdkLogger
.QUIET
)
1654 elif Option
.debug
is not None:
1655 EdkLogger
.SetLevel(Option
.debug
+ 1)
1657 EdkLogger
.SetLevel(EdkLogger
.INFO
)
1659 ## EotOptionParser() method
1661 # Using standard Python module optparse to parse command line option of this tool.
1663 # @param self: The object pointer
1665 # @retval Opt A optparse.Values object containing the parsed options
1666 # @retval Args Target of build command
1668 def EotOptionParser(self
):
1669 Parser
= OptionParser(description
= self
.Copyright
, version
= self
.Version
, prog
= "Eot.exe", usage
= "%prog [options]")
1670 Parser
.add_option("-m", "--makefile filename", action
="store", type="string", dest
='MakeFile',
1671 help="Specify a makefile for the platform.")
1672 Parser
.add_option("-c", "--dsc filename", action
="store", type="string", dest
="DscFile",
1673 help="Specify a dsc file for the platform.")
1674 Parser
.add_option("-f", "--fv filename", action
="store", type="string", dest
="FvFileList",
1675 help="Specify fv file list, quoted by \"\".")
1676 Parser
.add_option("-a", "--map filename", action
="store", type="string", dest
="MapFileList",
1677 help="Specify map file list, quoted by \"\".")
1678 Parser
.add_option("-s", "--source files", action
="store", type="string", dest
="SourceFileList",
1679 help="Specify source file list by a file")
1680 Parser
.add_option("-i", "--include dirs", action
="store", type="string", dest
="IncludeDirList",
1681 help="Specify include dir list by a file")
1682 Parser
.add_option("-e", "--dec files", action
="store", type="string", dest
="DecFileList",
1683 help="Specify dec file list by a file")
1684 Parser
.add_option("-g", "--guid list", action
="store", type="string", dest
="GuidList",
1685 help="Specify guid file list by a file")
1686 Parser
.add_option("-l", "--log filename", action
="store", type="string", dest
="LogFile",
1687 help="Specify real execution log file")
1689 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.")
1691 Parser
.add_option("-q", "--quiet", action
="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
1692 Parser
.add_option("-v", "--verbose", action
="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
1693 "including library instances selected, final dependency expression, "\
1694 "and warning messages, etc.")
1695 Parser
.add_option("-d", "--debug", action
="store", type="int", help="Enable debug messages at specified level.")
1697 (Opt
, Args
)=Parser
.parse_args()
1703 # This acts like the main() function for the script, unless it is 'import'ed into another
1706 if __name__
== '__main__':
1707 # Initialize log system
1708 EdkLogger
.Initialize()
1709 EdkLogger
.IsRaiseError
= False
1710 EdkLogger
.quiet(time
.strftime("%H:%M:%S, %b.%d %Y ", time
.localtime()) + "[00:00]" + "\n")
1712 StartTime
= time
.clock()
1713 Eot
= Eot(CommandLineOption
=False,
1714 SourceFileList
=r
'C:\TestEot\Source.txt',
1715 GuidList
=r
'C:\TestEot\Guid.txt',
1716 FvFileList
=r
'C:\TestEot\FVRECOVERY.Fv')
1717 FinishTime
= time
.clock()
1719 BuildDuration
= time
.strftime("%M:%S", time
.gmtime(int(round(FinishTime
- StartTime
))))
1720 EdkLogger
.quiet("\n%s [%s]" % (time
.strftime("%H:%M:%S, %b.%d %Y", time
.localtime()), BuildDuration
))