2 # This file is used to be the main entrance of EOT tool
4 # Copyright (c) 2008 - 2018, Intel Corporation. All rights reserved.<BR>
5 # This program and the accompanying materials
6 # are licensed and made available under the terms and conditions of the BSD License
7 # which accompanies this distribution. The full text of the license may be found at
8 # http://opensource.org/licenses/bsd-license.php
10 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 from __future__
import absolute_import
18 import Common
.LongFilePathOs
as os
, time
, glob
19 import Common
.EdkLogger
as EdkLogger
20 from Eot
import EotGlobalData
21 from optparse
import OptionParser
22 from Common
.StringUtils
import NormPath
23 from Common
import BuildToolError
24 from Common
.Misc
import GuidStructureStringToGuidString
, sdict
25 from 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
40 gGuidStringFormat
= "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"
41 gPeiAprioriFileNameGuid
= '1b45cc0a-156a-428a-af62-49864da0e6e6'
42 gAprioriGuid
= 'fc510ee7-ffdc-11d4-bd41-0080c73c8881'
46 _HEADER_
= struct
.Struct("")
47 _HEADER_SIZE_
= _HEADER_
.size
49 def __new__(cls
, *args
, **kwargs
):
50 return array
.__new
__(cls
, 'B')
52 def __init__(self
, ID
=None):
54 self
._ID
_ = str(uuid
.uuid1()).upper()
61 self
._SubImages
= sdict() # {offset: Image()}
69 Len
= array
.__len
__(self
)
70 for Offset
in self
._SubImages
.keys():
71 Len
+= len(self
._SubImages
[Offset
])
75 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
78 def _Pack(self
, PadByte
=0xFF):
79 raise NotImplementedError
81 def frombuffer(self
, Buffer
, Offset
=0, Size
=None):
84 # we may need the Size information in advance if it's given
86 self
._LEN
_ = self
._Unpack
()
91 def GetField(self
, FieldStruct
, Offset
=0):
92 return FieldStruct
.unpack_from(self
, Offset
)
94 def SetField(self
, FieldStruct
, Offset
, *args
):
95 # check if there's enough space
96 Size
= FieldStruct
.size
98 self
.extend([0] * (Size
- len(self
)))
99 FieldStruct
.pack_into(self
, Offset
, *args
)
101 def _SetData(self
, Data
):
102 if len(self
) < self
._HEADER
_SIZE
_:
103 self
.extend([0] * (self
._HEADER
_SIZE
_ - len(self
)))
105 del self
[self
._HEADER
_SIZE
_:]
109 if len(self
) > self
._HEADER
_SIZE
_:
110 return self
[self
._HEADER
_SIZE
_:]
113 Data
= property(_GetData
, _SetData
)
115 ## CompressedImage() class
117 # A class for Compressed Image
119 class CompressedImage(Image
):
120 # UncompressedLength = 4-byte
121 # CompressionType = 1-byte
122 _HEADER_
= struct
.Struct("1I 1B")
123 _HEADER_SIZE_
= _HEADER_
.size
125 _ORIG_SIZE_
= struct
.Struct("1I")
126 _CMPRS_TYPE_
= struct
.Struct("4x 1B")
128 def __init__(self
, CompressedData
=None, CompressionType
=None, UncompressedLength
=None):
130 if UncompressedLength
is not None:
131 self
.UncompressedLength
= UncompressedLength
132 if CompressionType
is not None:
133 self
.CompressionType
= CompressionType
134 if CompressedData
is not None:
135 self
.Data
= CompressedData
139 S
= "algorithm=%s uncompressed=%x" % (self
.CompressionType
, self
.UncompressedLength
)
140 for Sec
in self
.Sections
:
145 def _SetOriginalSize(self
, Size
):
146 self
.SetField(self
._ORIG
_SIZE
_, 0, Size
)
148 def _GetOriginalSize(self
):
149 return self
.GetField(self
._ORIG
_SIZE
_)[0]
151 def _SetCompressionType(self
, Type
):
152 self
.SetField(self
._CMPRS
_TYPE
_, 0, Type
)
154 def _GetCompressionType(self
):
155 return self
.GetField(self
._CMPRS
_TYPE
_)[0]
157 def _GetSections(self
):
159 TmpData
= DeCompress('Efi', self
[self
._HEADER
_SIZE
_:])
161 DecData
.fromstring(TmpData
)
163 TmpData
= DeCompress('Framework', self
[self
._HEADER
_SIZE
_:])
165 DecData
.fromstring(TmpData
)
169 while Offset
< len(DecData
):
172 Sec
.frombuffer(DecData
, Offset
)
174 # the section is aligned to 4-byte boundary
177 SectionList
.append(Sec
)
180 UncompressedLength
= property(_GetOriginalSize
, _SetOriginalSize
)
181 CompressionType
= property(_GetCompressionType
, _SetCompressionType
)
182 Sections
= property(_GetSections
)
189 _HEADER_
= struct
.Struct("")
199 # keep header in this Image object
201 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
204 def _GetUiString(self
):
205 return codecs
.utf_16_decode(self
[0:-2].tostring())[0]
207 String
= property(_GetUiString
)
214 _HEADER_
= struct
.Struct("")
217 _GUID_
= struct
.Struct("1I2H8B")
218 _OPCODE_
= struct
.Struct("1B")
234 -1 : _OPCODE_
, # first one in depex must be an opcdoe
235 0x00 : _GUID_
, #"BEFORE",
236 0x01 : _GUID_
, #"AFTER",
237 0x02 : _GUID_
, #"PUSH",
238 0x03 : _OPCODE_
, #"AND",
239 0x04 : _OPCODE_
, #"OR",
240 0x05 : _OPCODE_
, #"NOT",
241 0x06 : _OPCODE_
, #"TRUE",
242 0x07 : _OPCODE_
, #"FALSE",
244 0x09 : _OPCODE_
, #"SOR"
254 Indention
= ' ' * gIndention
256 for T
in self
.Expression
:
257 if T
in self
._OPCODE
_STRING
_:
258 S
+= Indention
+ self
._OPCODE
_STRING
_[T
]
259 if T
not in [0x00, 0x01, 0x02]:
262 S
+= ' ' + gGuidStringFormat
% T
+ '\n'
267 # keep header in this Image object
269 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
272 def _GetExpression(self
):
273 if self
._ExprList
== []:
275 CurrentData
= self
._OPCODE
_
276 while Offset
< len(self
):
277 Token
= CurrentData
.unpack_from(self
, Offset
)
278 Offset
+= CurrentData
.size
281 if Token
in self
._NEXT
_:
282 CurrentData
= self
._NEXT
_[Token
]
284 CurrentData
= self
._GUID
_
286 CurrentData
= self
._OPCODE
_
287 self
._ExprList
.append(Token
)
288 if CurrentData
is None:
290 return self
._ExprList
292 Expression
= property(_GetExpression
)
294 # # FirmwareVolume() class
296 # A class for Firmware Volume
298 class FirmwareVolume(Image
):
299 # Read FvLength, Attributes, HeaderLength, Checksum
300 _HEADER_
= struct
.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")
301 _HEADER_SIZE_
= _HEADER_
.size
303 _FfsGuid
= "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
305 _GUID_
= struct
.Struct("16x 1I2H8B")
306 _LENGTH_
= struct
.Struct("16x 16x 1Q")
307 _SIG_
= struct
.Struct("16x 16x 8x 1I")
308 _ATTR_
= struct
.Struct("16x 16x 8x 4x 1I")
309 _HLEN_
= struct
.Struct("16x 16x 8x 4x 4x 1H")
310 _CHECKSUM_
= struct
.Struct("16x 16x 8x 4x 4x 2x 1H")
312 def __init__(self
, Name
=''):
315 self
.FfsDict
= sdict()
316 self
.OrderedFfsDict
= sdict()
317 self
.UnDispatchedFfsDict
= sdict()
318 self
.ProtocolList
= sdict()
320 def CheckArchProtocol(self
):
321 for Item
in EotGlobalData
.gArchProtocolGuids
:
322 if Item
.lower() not in EotGlobalData
.gProtocolList
:
326 def ParseDepex(self
, Depex
, Type
):
329 List
= EotGlobalData
.gPpiList
330 if Type
== 'Protocol':
331 List
= EotGlobalData
.gProtocolList
337 for Index
in range(0, len(Depex
.Expression
)):
338 Item
= Depex
.Expression
[Index
]
341 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
342 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
343 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
346 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
347 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
348 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
351 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
352 if Guid
.lower() in List
:
353 DepexStack
.append(True)
354 DepexList
.append(Guid
)
356 DepexStack
.append(False)
357 DepexList
.append(Guid
)
359 elif Item
== 0x03 or Item
== 0x04:
360 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
361 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
363 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
364 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
366 DepexStack
.append(True)
367 DepexList
.append('TRUE')
368 DepexString
= DepexString
+ 'TRUE' + ' '
370 DepexStack
.append(False)
371 DepexList
.append('False')
372 DepexString
= DepexString
+ 'FALSE' + ' '
374 if Index
!= len(Depex
.Expression
) - 1:
375 CouldBeLoaded
= False
377 CouldBeLoaded
= DepexStack
.pop()
379 CouldBeLoaded
= False
381 DepexString
= DepexList
[0].strip()
382 return (CouldBeLoaded
, DepexString
, FileDepex
)
384 def Dispatch(self
, Db
=None):
387 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
388 # Find PeiCore, DexCore, PeiPriori, DxePriori first
389 FfsSecCoreGuid
= None
390 FfsPeiCoreGuid
= None
391 FfsDxeCoreGuid
= None
392 FfsPeiPrioriGuid
= None
393 FfsDxePrioriGuid
= None
394 for FfsID
in self
.UnDispatchedFfsDict
.keys():
395 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
397 FfsSecCoreGuid
= FfsID
400 FfsPeiCoreGuid
= FfsID
403 FfsDxeCoreGuid
= FfsID
405 if Ffs
.Guid
.lower() == gPeiAprioriFileNameGuid
:
406 FfsPeiPrioriGuid
= FfsID
408 if Ffs
.Guid
.lower() == gAprioriGuid
:
409 FfsDxePrioriGuid
= FfsID
412 # Parse SEC_CORE first
413 if FfsSecCoreGuid
is not None:
414 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
415 self
.LoadPpi(Db
, FfsSecCoreGuid
)
418 if FfsPeiCoreGuid
is not None:
419 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
420 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
421 if FfsPeiPrioriGuid
is not None:
422 # Load PEIM described in priori file
423 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
424 if len(FfsPeiPriori
.Sections
) == 1:
425 Section
= FfsPeiPriori
.Sections
.popitem()[1]
426 if Section
.Type
== 0x19:
427 GuidStruct
= struct
.Struct('1I2H8B')
429 while len(Section
) > Start
:
430 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
431 GuidString
= gGuidStringFormat
% Guid
433 if GuidString
in self
.UnDispatchedFfsDict
:
434 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
435 self
.LoadPpi(Db
, GuidString
)
440 if FfsDxeCoreGuid
is not None:
441 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
442 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
443 if FfsDxePrioriGuid
is not None:
444 # Load PEIM described in priori file
445 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
446 if len(FfsDxePriori
.Sections
) == 1:
447 Section
= FfsDxePriori
.Sections
.popitem()[1]
448 if Section
.Type
== 0x19:
449 GuidStruct
= struct
.Struct('1I2H8B')
451 while len(Section
) > Start
:
452 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
453 GuidString
= gGuidStringFormat
% Guid
455 if GuidString
in self
.UnDispatchedFfsDict
:
456 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
457 self
.LoadProtocol(Db
, GuidString
)
461 def LoadProtocol(self
, Db
, ModuleGuid
):
462 SqlCommand
= """select GuidValue from Report
463 where SourceFileFullPath in
464 (select Value1 from Inf where BelongsToFile =
465 (select BelongsToFile from Inf
466 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
468 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
469 % (ModuleGuid
, 5001, 3007)
470 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
471 for Record
in RecordSet
:
472 SqlCommand
= """select Value2 from Inf where BelongsToFile =
473 (select DISTINCT BelongsToFile from Inf
475 (select SourceFileFullPath from Report
476 where GuidValue like '%s' and ItemMode = 'Callback'))
477 and Value1 = 'FILE_GUID'""" % Record
[0]
478 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
479 if CallBackSet
!= []:
480 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
482 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
484 def LoadPpi(self
, Db
, ModuleGuid
):
485 SqlCommand
= """select GuidValue from Report
486 where SourceFileFullPath in
487 (select Value1 from Inf where BelongsToFile =
488 (select BelongsToFile from Inf
489 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
491 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
492 % (ModuleGuid
, 5001, 3007)
493 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
494 for Record
in RecordSet
:
495 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
497 def DisPatchDxe(self
, Db
):
499 ScheduleList
= sdict()
500 for FfsID
in self
.UnDispatchedFfsDict
.keys():
501 CouldBeLoaded
= False
504 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
508 for Section
in Ffs
.Sections
.values():
510 if Section
.Type
== 0x13:
512 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
514 if Section
.Type
== 0x01:
515 CompressSections
= Section
._SubImages
[4]
516 for CompressSection
in CompressSections
.Sections
:
517 if CompressSection
.Type
== 0x13:
519 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
521 if CompressSection
.Type
== 0x02:
522 NewSections
= CompressSection
._SubImages
[4]
523 for NewSection
in NewSections
.Sections
:
524 if NewSection
.Type
== 0x13:
526 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
531 CouldBeLoaded
= self
.CheckArchProtocol()
538 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
539 NewFfs
.Depex
= DepexString
540 if FileDepex
is not None:
541 ScheduleList
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
543 ScheduleList
[FfsID
] = NewFfs
545 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
547 for FfsID
in ScheduleList
.keys():
548 NewFfs
= ScheduleList
.pop(FfsID
)
550 self
.OrderedFfsDict
[FfsID
] = NewFfs
551 self
.LoadProtocol(Db
, FfsID
)
553 SqlCommand
= """select Value2 from Inf
554 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
555 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
556 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
558 FfsName
= RecordSet
[0][0]
563 def DisPatchPei(self
, Db
):
565 for FfsID
in self
.UnDispatchedFfsDict
.keys():
569 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
570 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
572 for Section
in Ffs
.Sections
.values():
573 if Section
.Type
== 0x1B:
574 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
576 if Section
.Type
== 0x01:
577 CompressSections
= Section
._SubImages
[4]
578 for CompressSection
in CompressSections
.Sections
:
579 if CompressSection
.Type
== 0x1B:
580 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
582 if CompressSection
.Type
== 0x02:
583 NewSections
= CompressSection
._SubImages
[4]
584 for NewSection
in NewSections
.Sections
:
585 if NewSection
.Type
== 0x1B:
586 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
592 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
593 NewFfs
.Depex
= DepexString
594 self
.OrderedFfsDict
[FfsID
] = NewFfs
595 self
.LoadPpi(Db
, FfsID
)
597 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
606 FvInfo
= '\n' + ' ' * gIndention
607 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
608 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
610 return FvInfo
+ FfsInfo
613 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
615 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_ + Size
])
619 FfsStartAddress
= self
.HeaderSize
621 while FfsStartAddress
< EndOfFv
:
623 FfsObj
.frombuffer(self
, FfsStartAddress
)
625 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
626 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
627 if LastFfsObj
is not None:
628 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
630 if FfsId
in self
.FfsDict
:
631 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
632 ExtraData
="\t%s @ %s\n\t%s @ %s" \
633 % (FfsObj
.Guid
, FfsObj
.Offset
,
634 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
635 self
.FfsDict
[FfsId
] = FfsObj
636 if LastFfsObj
is not None:
637 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
639 FfsStartAddress
+= len(FfsObj
)
641 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
642 # The next FFS must be at the latest next 8-byte aligned address
644 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
647 def _GetAttributes(self
):
648 return self
.GetField(self
._ATTR
_, 0)[0]
651 return self
.GetField(self
._LENGTH
_, 0)[0]
653 def _GetChecksum(self
):
654 return self
.GetField(self
._CHECKSUM
_, 0)[0]
656 def _GetHeaderLength(self
):
657 return self
.GetField(self
._HLEN
_, 0)[0]
659 def _GetFileSystemGuid(self
):
660 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
662 Attributes
= property(_GetAttributes
)
663 Size
= property(_GetSize
)
664 Checksum
= property(_GetChecksum
)
665 HeaderSize
= property(_GetHeaderLength
)
666 FileSystemGuid
= property(_GetFileSystemGuid
)
668 ## GuidDefinedImage() class
670 # A class for GUID Defined Image
672 class GuidDefinedImage(Image
):
673 _HEADER_
= struct
.Struct("1I2H8B 1H 1H")
674 _HEADER_SIZE_
= _HEADER_
.size
676 _GUID_
= struct
.Struct("1I2H8B")
677 _DATA_OFFSET_
= struct
.Struct("16x 1H")
678 _ATTR_
= struct
.Struct("18x 1H")
680 CRC32_GUID
= "FC1BCDB0-7D31-49AA-936A-A4600D9DD083"
681 TIANO_COMPRESS_GUID
= 'A31280AD-481E-41B6-95E8-127F4C984779'
682 LZMA_COMPRESS_GUID
= 'EE4E5898-3914-4259-9D6E-DC7BD79403CF'
684 def __init__(self
, SectionDefinitionGuid
=None, DataOffset
=None, Attributes
=None, Data
=None):
686 if SectionDefinitionGuid
is not None:
687 self
.SectionDefinitionGuid
= SectionDefinitionGuid
688 if DataOffset
is not None:
689 self
.DataOffset
= DataOffset
690 if Attributes
is not None:
691 self
.Attributes
= Attributes
696 S
= "guid=%s" % (gGuidStringFormat
% self
.SectionDefinitionGuid
)
697 for Sec
in self
.Sections
:
702 # keep header in this Image object
704 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._LEN
_])
707 def _SetAttribute(self
, Attribute
):
708 self
.SetField(self
._ATTR
_, 0, Attribute
)
710 def _GetAttribute(self
):
711 return self
.GetField(self
._ATTR
_)[0]
713 def _SetGuid(self
, Guid
):
714 self
.SetField(self
._GUID
_, 0, Guid
)
717 return self
.GetField(self
._GUID
_)
719 def _SetDataOffset(self
, Offset
):
720 self
.SetField(self
._DATA
_OFFSET
_, 0, Offset
)
722 def _GetDataOffset(self
):
723 return self
.GetField(self
._DATA
_OFFSET
_)[0]
725 def _GetSections(self
):
727 Guid
= gGuidStringFormat
% self
.SectionDefinitionGuid
728 if Guid
== self
.CRC32_GUID
:
729 # skip the CRC32 value, we don't do CRC32 verification here
730 Offset
= self
.DataOffset
- 4
731 while Offset
< len(self
):
734 Sec
.frombuffer(self
, Offset
)
736 # the section is aligned to 4-byte boundary
737 Offset
= (Offset
+ 3) & (~
3)
740 SectionList
.append(Sec
)
741 elif Guid
== self
.TIANO_COMPRESS_GUID
:
744 Offset
= self
.DataOffset
- 4
745 TmpData
= DeCompress('Framework', self
[self
.Offset
:])
747 DecData
.fromstring(TmpData
)
749 while Offset
< len(DecData
):
752 Sec
.frombuffer(DecData
, Offset
)
754 # the section is aligned to 4-byte boundary
755 Offset
= (Offset
+ 3) & (~
3)
758 SectionList
.append(Sec
)
761 elif Guid
== self
.LZMA_COMPRESS_GUID
:
764 Offset
= self
.DataOffset
- 4
766 TmpData
= DeCompress('Lzma', self
[self
.Offset
:])
768 DecData
.fromstring(TmpData
)
770 while Offset
< len(DecData
):
773 Sec
.frombuffer(DecData
, Offset
)
775 # the section is aligned to 4-byte boundary
776 Offset
= (Offset
+ 3) & (~
3)
779 SectionList
.append(Sec
)
785 Attributes
= property(_GetAttribute
, _SetAttribute
)
786 SectionDefinitionGuid
= property(_GetGuid
, _SetGuid
)
787 DataOffset
= property(_GetDataOffset
, _SetDataOffset
)
788 Sections
= property(_GetSections
)
792 # A class for Section
794 class Section(Image
):
797 0x01 : "COMPRESSION",
798 0x02 : "GUID_DEFINED",
804 0x15 : "USER_INTERFACE",
805 0x16 : "COMPATIBILITY16",
806 0x17 : "FIRMWARE_VOLUME_IMAGE",
807 0x18 : "FREEFORM_SUBTYPE_GUID",
812 _SectionSubImages
= {
813 0x01 : CompressedImage
,
814 0x02 : GuidDefinedImage
,
815 0x17 : FirmwareVolume
,
823 _HEADER_
= struct
.Struct("3B 1B")
824 _HEADER_SIZE_
= _HEADER_
.size
827 # _FREE_FORM_SUBTYPE_GUID_HEADER_ = struct.Struct("1I2H8B")
828 _SIZE_
= struct
.Struct("3B")
829 _TYPE_
= struct
.Struct("3x 1B")
831 def __init__(self
, Type
=None, Size
=None):
842 SectionInfo
= ' ' * gIndention
843 if self
.Type
in self
._TypeName
:
844 SectionInfo
+= "[SECTION:%s] offset=%x size=%x" % (self
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
)
846 SectionInfo
+= "[SECTION:%x<unknown>] offset=%x size=%x " % (self
.Type
, self
._OFF
_, self
.Size
)
847 for Offset
in self
._SubImages
.keys():
848 SectionInfo
+= ", " + str(self
._SubImages
[Offset
])
854 Type
, = self
._TYPE
_.unpack_from(self
._BUF
_, self
._OFF
_)
855 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
856 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
858 if Type
not in self
._SectionSubImages
:
859 # no need to extract sub-image, keep all in this Image object
860 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
862 # keep header in this Image object
863 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + self
._HEADER
_SIZE
_])
865 # use new Image object to represent payload, which may be another kind
866 # of image such as PE32
868 PayloadOffset
= self
._HEADER
_SIZE
_
869 PayloadLen
= self
.Size
- self
._HEADER
_SIZE
_
870 Payload
= self
._SectionSubImages
[self
.Type
]()
871 Payload
.frombuffer(self
._BUF
_, self
._OFF
_ + self
._HEADER
_SIZE
_, PayloadLen
)
872 self
._SubImages
[PayloadOffset
] = Payload
876 def _SetSize(self
, Size
):
878 Size2
= (Size
& 0xFF00) >> 8
879 Size3
= (Size
& 0xFF0000) >> 16
880 self
.SetField(self
._SIZE
_, 0, Size1
, Size2
, Size3
)
883 Size1
, Size2
, Size3
= self
.GetField(self
._SIZE
_)
884 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
886 def _SetType(self
, Type
):
887 self
.SetField(self
._TYPE
_, 0, Type
)
890 return self
.GetField(self
._TYPE
_)[0]
892 def _GetAlignment(self
):
893 return self
._Alignment
895 def _SetAlignment(self
, Alignment
):
896 self
._Alignment
= Alignment
897 AlignmentMask
= Alignment
- 1
898 # section alignment is actually for payload, so we need to add header size
899 PayloadOffset
= self
._OFF
_ + self
._HEADER
_SIZE
_
900 if (PayloadOffset
& (~AlignmentMask
)) == 0:
902 NewOffset
= (PayloadOffset
+ AlignmentMask
) & (~AlignmentMask
)
903 while (NewOffset
- PayloadOffset
) < self
._HEADER
_SIZE
_:
904 NewOffset
+= self
._Alignment
907 self
.Size
= len(self
)
908 Image
.tofile(self
, f
)
909 for Offset
in self
._SubImages
:
910 self
._SubImages
[Offset
].tofile(f
)
912 Type
= property(_GetType
, _SetType
)
913 Size
= property(_GetSize
, _SetSize
)
914 Alignment
= property(_GetAlignment
, _SetAlignment
)
918 # A class for Ffs Section
921 _FfsFormat
= "24B%(payload_size)sB"
922 # skip IntegrityCheck
923 _HEADER_
= struct
.Struct("1I2H8B 2x 1B 1B 3B 1B")
924 _HEADER_SIZE_
= _HEADER_
.size
926 _NAME_
= struct
.Struct("1I2H8B")
927 _INT_CHECK_
= struct
.Struct("16x 1H")
928 _TYPE_
= struct
.Struct("18x 1B")
929 _ATTR_
= struct
.Struct("19x 1B")
930 _SIZE_
= struct
.Struct("20x 3B")
931 _STATE_
= struct
.Struct("23x 1B")
933 VTF_GUID
= "1BA0062E-C779-4582-8566-336AE8F78F09"
935 FFS_ATTRIB_FIXED
= 0x04
936 FFS_ATTRIB_DATA_ALIGNMENT
= 0x38
937 FFS_ATTRIB_CHECKSUM
= 0x40
943 0x03 : "SECURITY_CORE",
948 0x08 : "COMBINED_PEIM_DRIVER",
949 0x09 : "APPLICATION",
951 0x0B : "FIRMWARE_VOLUME_IMAGE",
952 0x0C : "COMBINED_SMM_DXE",
954 0x0E : "MM_STANDALONE",
955 0x0F : "MM_CORE_STANDALONE",
969 self
.Sections
= sdict()
977 Indention
= ' ' * gIndention
979 FfsInfo
+= "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \
980 (Ffs
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
, self
.Guid
, self
.FreeSpace
, self
.Alignment
)
981 SectionInfo
= '\n'.join([str(self
.Sections
[Offset
]) for Offset
in self
.Sections
.keys()])
983 return FfsInfo
+ SectionInfo
+ "\n"
992 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
993 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
995 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
997 # Pad FFS may use the same GUID. We need to avoid it.
998 if self
.Type
== 0xf0:
999 self
.__ID
__ = str(uuid
.uuid1()).upper()
1001 self
.__ID
__ = self
.Guid
1003 # Traverse the SECTION. RAW and PAD do not have sections
1004 if self
.Type
not in [0xf0, 0x01] and Size
> 0 and Size
< 0xFFFFFF:
1006 SectionStartAddress
= self
._HEADER
_SIZE
_
1007 while SectionStartAddress
< EndOfFfs
:
1008 SectionObj
= Section()
1009 SectionObj
.frombuffer(self
, SectionStartAddress
)
1010 #f = open(repr(SectionObj), 'wb')
1011 #SectionObj.Size = 0
1012 #SectionObj.tofile(f)
1014 self
.Sections
[SectionStartAddress
] = SectionObj
1015 SectionStartAddress
+= len(SectionObj
)
1016 SectionStartAddress
= (SectionStartAddress
+ 3) & (~
3)
1021 def SetFreeSpace(self
, Size
):
1022 self
.FreeSpace
= Size
1025 return gGuidStringFormat
% self
.Name
1027 def _SetName(self
, Value
):
1028 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1029 self
.SetField(self
._NAME
_, 0, Value
)
1032 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1033 return self
.GetField(self
._NAME
_)
1035 def _SetSize(self
, Size
):
1037 Size2
= (Size
& 0xFF00) >> 8
1038 Size3
= (Size
& 0xFF0000) >> 16
1039 self
.SetField(self
._SIZE
_, 0, Size1
, Size2
, Size3
)
1042 Size1
, Size2
, Size3
= self
.GetField(self
._SIZE
_)
1043 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
1045 def _SetType(self
, Type
):
1046 self
.SetField(self
._TYPE
_, 0, Type
)
1049 return self
.GetField(self
._TYPE
_)[0]
1051 def _SetAttributes(self
, Value
):
1052 self
.SetField(self
._ATTR
_, 0, Value
)
1054 def _GetAttributes(self
):
1055 return self
.GetField(self
._ATTR
_)[0]
1057 def _GetFixed(self
):
1058 if (self
.Attributes
& self
.FFS_ATTRIB_FIXED
) != 0:
1062 def _GetCheckSum(self
):
1063 if (self
.Attributes
& self
.FFS_ATTRIB_CHECKSUM
) != 0:
1067 def _GetAlignment(self
):
1068 return (self
.Attributes
& self
.FFS_ATTRIB_DATA_ALIGNMENT
) >> 3
1070 def _SetState(self
, Value
):
1071 self
.SetField(self
._STATE
_, 0, Value
)
1073 def _GetState(self
):
1074 return self
.GetField(self
._STATE
_)[0]
1076 Name
= property(_GetName
, _SetName
)
1077 Guid
= property(_GetGuid
)
1078 Type
= property(_GetType
, _SetType
)
1079 Size
= property(_GetSize
, _SetSize
)
1080 Attributes
= property(_GetAttributes
, _SetAttributes
)
1081 Fixed
= property(_GetFixed
)
1082 Checksum
= property(_GetCheckSum
)
1083 Alignment
= property(_GetAlignment
)
1084 State
= property(_GetState
, _SetState
)
1087 ## MultipleFv() class
1089 # A class for Multiple FV
1091 class MultipleFv(FirmwareVolume
):
1092 def __init__(self
, FvList
):
1093 FirmwareVolume
.__init
__(self
)
1095 for FvPath
in FvList
:
1097 FvName
= os
.path
.splitext(os
.path
.split(FvPath
)[1])[0]
1099 Fd
= open(FvPath
, 'rb')
1102 Buf
.fromfile(Fd
, os
.path
.getsize(FvPath
))
1106 Fv
= FirmwareVolume(FvName
)
1107 Fv
.frombuffer(Buf
, 0, len(Buf
))
1109 self
.BasicInfo
.append([Fv
.Name
, Fv
.FileSystemGuid
, Fv
.Size
])
1110 self
.FfsDict
.append(Fv
.FfsDict
)
1114 # This class is used to define Eot main entrance
1116 # @param object: Inherited from object class
1121 # @param self: The object pointer
1123 def __init__(self
, CommandLineOption
=True, IsInit
=True, SourceFileList
=None, \
1124 IncludeDirList
=None, DecFileList
=None, GuidList
=None, LogFile
=None,
1125 FvFileList
="", MapFileList
="", Report
='Report.html', Dispatch
=None):
1126 # Version and Copyright
1127 self
.VersionNumber
= ("0.02" + " " + gBUILD_VERSION
)
1128 self
.Version
= "%prog Version " + self
.VersionNumber
1129 self
.Copyright
= "Copyright (c) 2008 - 2018, Intel Corporation All rights reserved."
1130 self
.Report
= Report
1132 self
.IsInit
= IsInit
1133 self
.SourceFileList
= SourceFileList
1134 self
.IncludeDirList
= IncludeDirList
1135 self
.DecFileList
= DecFileList
1136 self
.GuidList
= GuidList
1137 self
.LogFile
= LogFile
1138 self
.FvFileList
= FvFileList
1139 self
.MapFileList
= MapFileList
1140 self
.Dispatch
= Dispatch
1142 # Check workspace environment
1143 if "EFI_SOURCE" not in os
.environ
:
1144 if "EDK_SOURCE" not in os
.environ
:
1147 EotGlobalData
.gEDK_SOURCE
= os
.path
.normpath(os
.getenv("EDK_SOURCE"))
1149 EotGlobalData
.gEFI_SOURCE
= os
.path
.normpath(os
.getenv("EFI_SOURCE"))
1150 EotGlobalData
.gEDK_SOURCE
= os
.path
.join(EotGlobalData
.gEFI_SOURCE
, 'Edk')
1152 if "WORKSPACE" not in os
.environ
:
1153 EdkLogger
.error("EOT", BuildToolError
.ATTRIBUTE_NOT_AVAILABLE
, "Environment variable not found",
1154 ExtraData
="WORKSPACE")
1156 EotGlobalData
.gWORKSPACE
= os
.path
.normpath(os
.getenv("WORKSPACE"))
1158 EotGlobalData
.gMACRO
['WORKSPACE'] = EotGlobalData
.gWORKSPACE
1159 EotGlobalData
.gMACRO
['EFI_SOURCE'] = EotGlobalData
.gEFI_SOURCE
1160 EotGlobalData
.gMACRO
['EDK_SOURCE'] = EotGlobalData
.gEDK_SOURCE
1162 # Parse the options and args
1163 if CommandLineOption
:
1167 for FvFile
in GetSplitValueList(self
.FvFileList
, ' '):
1168 FvFile
= os
.path
.normpath(FvFile
)
1169 if not os
.path
.isfile(FvFile
):
1170 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % FvFile
)
1171 EotGlobalData
.gFV_FILE
.append(FvFile
)
1173 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "The fv file list of target platform was not specified")
1175 if self
.MapFileList
:
1176 for MapFile
in GetSplitValueList(self
.MapFileList
, ' '):
1177 MapFile
= os
.path
.normpath(MapFile
)
1178 if not os
.path
.isfile(MapFile
):
1179 EdkLogger
.error("Eot", EdkLogger
.EOT_ERROR
, "Can not find file %s " % MapFile
)
1180 EotGlobalData
.gMAP_FILE
.append(MapFile
)
1182 # Generate source file list
1183 self
.GenerateSourceFileList(self
.SourceFileList
, self
.IncludeDirList
)
1185 # Generate guid list of dec file list
1186 self
.ParseDecFile(self
.DecFileList
)
1188 # Generate guid list from GUID list file
1189 self
.ParseGuidList(self
.GuidList
)
1192 EotGlobalData
.gDb
= Database
.Database(Database
.DATABASE_PATH
)
1193 EotGlobalData
.gDb
.InitDatabase(self
.IsInit
)
1195 # Build ECC database
1196 self
.BuildDatabase()
1198 # Parse Ppi/Protocol
1199 self
.ParseExecutionOrder()
1201 # Merge Identifier tables
1202 self
.GenerateQueryTable()
1204 # Generate report database
1205 self
.GenerateReportDatabase()
1214 self
.GenerateReport()
1217 self
.ConvertLogFile(self
.LogFile
)
1220 EdkLogger
.quiet("EOT FINISHED!")
1223 EotGlobalData
.gDb
.Close()
1225 ## ParseDecFile() method
1227 # parse DEC file and get all GUID names with GUID values as {GuidName : GuidValue}
1228 # The Dict is stored in EotGlobalData.gGuidDict
1230 # @param self: The object pointer
1231 # @param DecFileList: A list of all DEC files
1233 def ParseDecFile(self
, DecFileList
):
1235 path
= os
.path
.normpath(DecFileList
)
1236 lfr
= open(path
, 'rb')
1238 path
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1239 if os
.path
.exists(path
):
1240 dfr
= open(path
, 'rb')
1242 line
= CleanString(line
)
1243 list = line
.split('=')
1245 EotGlobalData
.gGuidDict
[list[0].strip()] = GuidStructureStringToGuidString(list[1].strip())
1248 ## ParseGuidList() method
1250 # Parse Guid list and get all GUID names with GUID values as {GuidName : GuidValue}
1251 # The Dict is stored in EotGlobalData.gGuidDict
1253 # @param self: The object pointer
1254 # @param GuidList: A list of all GUID and its value
1256 def ParseGuidList(self
, GuidList
):
1257 Path
= os
.path
.join(EotGlobalData
.gWORKSPACE
, GuidList
)
1258 if os
.path
.isfile(Path
):
1259 for Line
in open(Path
):
1261 (GuidName
, GuidValue
) = Line
.split()
1262 EotGlobalData
.gGuidDict
[GuidName
] = GuidValue
1264 ## ConvertLogFile() method
1266 # Parse a real running log file to get real dispatch order
1267 # The result is saved to old file name + '.new'
1269 # @param self: The object pointer
1270 # @param LogFile: A real running log file name
1272 def ConvertLogFile(self
, LogFile
):
1277 lfr
= open(LogFile
, 'rb')
1278 lfw
= open(LogFile
+ '.new', 'wb')
1281 line
= line
.replace('.efi', '')
1282 index
= line
.find("Loading PEIM at ")
1284 newline
.append(line
[index
+ 55 : ])
1286 index
= line
.find("Loading driver at ")
1288 newline
.append(line
[index
+ 57 : ])
1291 for line
in newline
:
1292 lfw
.write(line
+ '\r\n')
1299 ## GenerateSourceFileList() method
1301 # Generate a list of all source files
1302 # 1. Search the file list one by one
1303 # 2. Store inf file name with source file names under it like
1304 # { INF file name: [source file1, source file2, ...]}
1305 # 3. Search the include list to find all .h files
1306 # 4. Store source file list to EotGlobalData.gSOURCE_FILES
1307 # 5. Store INF file list to EotGlobalData.gINF_FILES
1309 # @param self: The object pointer
1310 # @param SourceFileList: A list of all source files
1311 # @param IncludeFileList: A list of all include files
1313 def GenerateSourceFileList(self
, SourceFileList
, IncludeFileList
):
1314 EdkLogger
.quiet("Generating source files list ... ")
1315 mSourceFileList
= []
1319 mCurrentInfFile
= ''
1320 mCurrentSourceFileList
= []
1323 sfl
= open(SourceFileList
, 'r')
1325 line
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1326 if line
[-2:].upper() == '.C' or line
[-2:].upper() == '.H':
1327 if line
not in mCurrentSourceFileList
:
1328 mCurrentSourceFileList
.append(line
)
1329 mSourceFileList
.append(line
)
1330 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % line
)
1331 if line
[-4:].upper() == '.INF':
1332 if mCurrentInfFile
!= '':
1333 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1334 mCurrentSourceFileList
= []
1335 mCurrentInfFile
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
))
1336 EotGlobalData
.gOP_INF
.write('%s\n' % mCurrentInfFile
)
1337 if mCurrentInfFile
not in mFileList
:
1338 mFileList
[mCurrentInfFile
] = mCurrentSourceFileList
1340 # Get all include files from packages
1342 ifl
= open(IncludeFileList
, 'rb')
1344 if not line
.strip():
1346 newline
= os
.path
.normpath(os
.path
.join(EotGlobalData
.gWORKSPACE
, line
.strip()))
1347 for Root
, Dirs
, Files
in os
.walk(str(newline
)):
1349 FullPath
= os
.path
.normpath(os
.path
.join(Root
, File
))
1350 if FullPath
not in mSourceFileList
and File
[-2:].upper() == '.H':
1351 mSourceFileList
.append(FullPath
)
1352 EotGlobalData
.gOP_SOURCE_FILES
.write('%s\n' % FullPath
)
1353 if FullPath
not in mDecFileList
and File
.upper().find('.DEC') > -1:
1354 mDecFileList
.append(FullPath
)
1356 EotGlobalData
.gSOURCE_FILES
= mSourceFileList
1357 EotGlobalData
.gOP_SOURCE_FILES
.close()
1359 EotGlobalData
.gINF_FILES
= mFileList
1360 EotGlobalData
.gOP_INF
.close()
1362 ## GenerateReport() method
1364 # Generate final HTML report
1366 # @param self: The object pointer
1368 def GenerateReport(self
):
1369 EdkLogger
.quiet("Generating report file ... ")
1370 Rep
= Report(self
.Report
, EotGlobalData
.gFV
, self
.Dispatch
)
1371 Rep
.GenerateReport()
1373 ## LoadMapInfo() method
1375 # Load map files and parse them
1377 # @param self: The object pointer
1379 def LoadMapInfo(self
):
1380 if EotGlobalData
.gMAP_FILE
!= []:
1381 EdkLogger
.quiet("Parsing Map file ... ")
1382 EotGlobalData
.gMap
= ParseMapFile(EotGlobalData
.gMAP_FILE
)
1384 ## LoadFvInfo() method
1386 # Load FV binary files and parse them
1388 # @param self: The object pointer
1390 def LoadFvInfo(self
):
1391 EdkLogger
.quiet("Parsing FV file ... ")
1392 EotGlobalData
.gFV
= MultipleFv(EotGlobalData
.gFV_FILE
)
1393 EotGlobalData
.gFV
.Dispatch(EotGlobalData
.gDb
)
1395 for Protocol
in EotGlobalData
.gProtocolList
:
1396 EotGlobalData
.gOP_UN_MATCHED_IN_LIBRARY_CALLING
.write('%s\n' %Protocol
)
1398 ## GenerateReportDatabase() method
1400 # Generate data for the information needed by report
1401 # 1. Update name, macro and value of all found PPI/PROTOCOL GUID
1402 # 2. Install hard coded PPI/PROTOCOL
1404 # @param self: The object pointer
1406 def GenerateReportDatabase(self
):
1407 EdkLogger
.quiet("Generating the cross-reference table of GUID for Ppi/Protocol ... ")
1409 # Update Protocol/Ppi Guid
1410 SqlCommand
= """select DISTINCT GuidName from Report"""
1411 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1412 for Record
in RecordSet
:
1413 GuidName
= Record
[0]
1418 # Find guid value defined in Dec file
1419 if GuidName
in EotGlobalData
.gGuidDict
:
1420 GuidValue
= EotGlobalData
.gGuidDict
[GuidName
]
1421 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1422 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1425 # Search defined Macros for guid name
1426 SqlCommand
="""select DISTINCT Value, Modifier from Query where Name like '%s'""" % GuidName
1427 GuidMacroSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1428 # Ignore NULL result
1429 if not GuidMacroSet
:
1431 GuidMacro
= GuidMacroSet
[0][0].strip()
1434 # Find Guid value of Guid Macro
1435 SqlCommand
="""select DISTINCT Value from Query2 where Value like '%%%s%%' and Model = %s""" % (GuidMacro
, MODEL_IDENTIFIER_MACRO_DEFINE
)
1436 GuidValueSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1437 if GuidValueSet
!= []:
1438 GuidValue
= GuidValueSet
[0][0]
1439 GuidValue
= GuidValue
[GuidValue
.find(GuidMacro
) + len(GuidMacro
) :]
1440 GuidValue
= GuidValue
.lower().replace('\\', '').replace('\r', '').replace('\n', '').replace('l', '').strip()
1441 GuidValue
= GuidStructureStringToGuidString(GuidValue
)
1442 SqlCommand
= """update Report set GuidMacro = '%s', GuidValue = '%s' where GuidName = '%s'""" %(GuidMacro
, GuidValue
, GuidName
)
1443 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1446 # Update Hard Coded Ppi/Protocol
1447 SqlCommand
= """select DISTINCT GuidValue, ItemType from Report where ModuleID = -2 and ItemMode = 'Produced'"""
1448 RecordSet
= EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1449 for Record
in RecordSet
:
1450 if Record
[1] == 'Ppi':
1451 EotGlobalData
.gPpiList
[Record
[0].lower()] = -2
1452 if Record
[1] == 'Protocol':
1453 EotGlobalData
.gProtocolList
[Record
[0].lower()] = -2
1455 ## GenerateQueryTable() method
1457 # Generate two tables improve query performance
1459 # @param self: The object pointer
1461 def GenerateQueryTable(self
):
1462 EdkLogger
.quiet("Generating temp query table for analysis ... ")
1463 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1464 SqlCommand
= """insert into Query (Name, Modifier, Value, Model)
1465 select Name, Modifier, Value, Model from %s where (Model = %s or Model = %s)""" \
1466 % (Identifier
[0], MODEL_IDENTIFIER_VARIABLE
, MODEL_IDENTIFIER_ASSIGNMENT_EXPRESSION
)
1467 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1468 SqlCommand
= """insert into Query2 (Name, Modifier, Value, Model)
1469 select Name, Modifier, Value, Model from %s where Model = %s""" \
1470 % (Identifier
[0], MODEL_IDENTIFIER_MACRO_DEFINE
)
1471 EotGlobalData
.gDb
.TblReport
.Exec(SqlCommand
)
1473 ## ParseExecutionOrder() method
1475 # Get final execution order
1477 # 2. Search all PROTOCOL
1479 # @param self: The object pointer
1481 def ParseExecutionOrder(self
):
1482 EdkLogger
.quiet("Searching Ppi/Protocol ... ")
1483 for Identifier
in EotGlobalData
.gIdentifierTableList
:
1484 ModuleID
, ModuleName
, ModuleGuid
, SourceFileID
, SourceFileFullPath
, ItemName
, ItemType
, ItemMode
, GuidName
, GuidMacro
, GuidValue
, BelongsToFunction
, Enabled
= \
1485 -1, '', '', -1, '', '', '', '', '', '', '', '', 0
1487 SourceFileID
= Identifier
[0].replace('Identifier', '')
1488 SourceFileFullPath
= Identifier
[1]
1489 Identifier
= Identifier
[0]
1492 ItemMode
= 'Produced'
1493 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1494 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1495 % (Identifier
, '.InstallPpi', '->InstallPpi', 'PeiInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1496 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1498 ItemMode
= 'Produced'
1499 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1500 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1501 % (Identifier
, '.ReInstallPpi', '->ReInstallPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1502 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1504 SearchPpiCallFunction(Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1506 ItemMode
= 'Consumed'
1507 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1508 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1509 % (Identifier
, '.LocatePpi', '->LocatePpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1510 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1512 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Ppi', ItemMode
)
1514 ItemMode
= 'Callback'
1515 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1516 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1517 % (Identifier
, '.NotifyPpi', '->NotifyPpi', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1518 SearchPpi(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
)
1521 ItemMode
= 'Produced'
1522 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1523 where (Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1524 % (Identifier
, '.InstallProtocolInterface', '.ReInstallProtocolInterface', '->InstallProtocolInterface', '->ReInstallProtocolInterface', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1525 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1527 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1528 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1529 % (Identifier
, '.InstallMultipleProtocolInterfaces', '->InstallMultipleProtocolInterfaces', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1530 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 2)
1532 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1534 ItemMode
= 'Consumed'
1535 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1536 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1537 % (Identifier
, '.LocateProtocol', '->LocateProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1538 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1540 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1541 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1542 % (Identifier
, '.HandleProtocol', '->HandleProtocol', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1543 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 1)
1545 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1547 ItemMode
= 'Callback'
1548 SqlCommand
= """select Value, Name, BelongsToFile, StartLine, EndLine from %s
1549 where (Name like '%%%s%%' or Name like '%%%s%%') and Model = %s""" \
1550 % (Identifier
, '.RegisterProtocolNotify', '->RegisterProtocolNotify', MODEL_IDENTIFIER_FUNCTION_CALLING
)
1551 SearchProtocols(SqlCommand
, Identifier
, SourceFileID
, SourceFileFullPath
, ItemMode
, 0)
1553 SearchFunctionCalling(Identifier
, SourceFileID
, SourceFileFullPath
, 'Protocol', ItemMode
)
1556 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiSecPlatformInformationPpiGuid', '', '', '', 0)
1557 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gEfiNtLoadAsDllPpiGuid', '', '', '', 0)
1558 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtPeiLoadFileGuid', '', '', '', 0)
1559 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtAutoScanPpiGuid', '', '', '', 0)
1560 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gNtFwhPpiGuid', '', '', '', 0)
1561 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiNtThunkPpiGuid', '', '', '', 0)
1562 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiPlatformTypePpiGuid', '', '', '', 0)
1563 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiFrequencySelectionCpuPpiGuid', '', '', '', 0)
1564 EotGlobalData
.gDb
.TblReport
.Insert(-2, '', '', -1, '', '', 'Ppi', 'Produced', 'gPeiCachePpiGuid', '', '', '', 0)
1566 EotGlobalData
.gDb
.Conn
.commit()
1569 ## BuildDatabase() methoc
1571 # Build the database for target
1573 # @param self: The object pointer
1575 def BuildDatabase(self
):
1576 # Clean report table
1577 EotGlobalData
.gDb
.TblReport
.Drop()
1578 EotGlobalData
.gDb
.TblReport
.Create()
1582 self
.BuildMetaDataFileDatabase(EotGlobalData
.gINF_FILES
)
1583 EdkLogger
.quiet("Building database for source code ...")
1584 c
.CreateCCodeDB(EotGlobalData
.gSOURCE_FILES
)
1585 EdkLogger
.quiet("Building database for source code done!")
1587 EotGlobalData
.gIdentifierTableList
= GetTableList((MODEL_FILE_C
, MODEL_FILE_H
), 'Identifier', EotGlobalData
.gDb
)
1589 ## BuildMetaDataFileDatabase() method
1591 # Build the database for meta data files
1593 # @param self: The object pointer
1594 # @param Inf_Files: A list for all INF files
1596 def BuildMetaDataFileDatabase(self
, Inf_Files
):
1597 EdkLogger
.quiet("Building database for meta data files ...")
1598 for InfFile
in Inf_Files
:
1601 EdkLogger
.quiet("Parsing %s ..." % str(InfFile
))
1602 EdkInfParser(InfFile
, EotGlobalData
.gDb
, Inf_Files
[InfFile
], '')
1604 EotGlobalData
.gDb
.Conn
.commit()
1605 EdkLogger
.quiet("Building database for meta data files done!")
1607 ## ParseOption() method
1609 # Parse command line options
1611 # @param self: The object pointer
1613 def ParseOption(self
):
1614 (Options
, Target
) = self
.EotOptionParser()
1617 self
.SetLogLevel(Options
)
1619 if Options
.FvFileList
:
1620 self
.FvFileList
= Options
.FvFileList
1622 if Options
.MapFileList
:
1623 self
.MapFileList
= Options
.FvMapFileList
1625 if Options
.SourceFileList
:
1626 self
.SourceFileList
= Options
.SourceFileList
1628 if Options
.IncludeDirList
:
1629 self
.IncludeDirList
= Options
.IncludeDirList
1631 if Options
.DecFileList
:
1632 self
.DecFileList
= Options
.DecFileList
1634 if Options
.GuidList
:
1635 self
.GuidList
= Options
.GuidList
1638 self
.LogFile
= Options
.LogFile
1640 if Options
.keepdatabase
:
1643 ## SetLogLevel() method
1645 # Set current log level of the tool based on args
1647 # @param self: The object pointer
1648 # @param Option: The option list including log level setting
1650 def SetLogLevel(self
, Option
):
1651 if Option
.verbose
is not None:
1652 EdkLogger
.SetLevel(EdkLogger
.VERBOSE
)
1653 elif Option
.quiet
is not None:
1654 EdkLogger
.SetLevel(EdkLogger
.QUIET
)
1655 elif Option
.debug
is not None:
1656 EdkLogger
.SetLevel(Option
.debug
+ 1)
1658 EdkLogger
.SetLevel(EdkLogger
.INFO
)
1660 ## EotOptionParser() method
1662 # Using standard Python module optparse to parse command line option of this tool.
1664 # @param self: The object pointer
1666 # @retval Opt A optparse.Values object containing the parsed options
1667 # @retval Args Target of build command
1669 def EotOptionParser(self
):
1670 Parser
= OptionParser(description
= self
.Copyright
, version
= self
.Version
, prog
= "Eot.exe", usage
= "%prog [options]")
1671 Parser
.add_option("-m", "--makefile filename", action
="store", type="string", dest
='MakeFile',
1672 help="Specify a makefile for the platform.")
1673 Parser
.add_option("-c", "--dsc filename", action
="store", type="string", dest
="DscFile",
1674 help="Specify a dsc file for the platform.")
1675 Parser
.add_option("-f", "--fv filename", action
="store", type="string", dest
="FvFileList",
1676 help="Specify fv file list, quoted by \"\".")
1677 Parser
.add_option("-a", "--map filename", action
="store", type="string", dest
="MapFileList",
1678 help="Specify map file list, quoted by \"\".")
1679 Parser
.add_option("-s", "--source files", action
="store", type="string", dest
="SourceFileList",
1680 help="Specify source file list by a file")
1681 Parser
.add_option("-i", "--include dirs", action
="store", type="string", dest
="IncludeDirList",
1682 help="Specify include dir list by a file")
1683 Parser
.add_option("-e", "--dec files", action
="store", type="string", dest
="DecFileList",
1684 help="Specify dec file list by a file")
1685 Parser
.add_option("-g", "--guid list", action
="store", type="string", dest
="GuidList",
1686 help="Specify guid file list by a file")
1687 Parser
.add_option("-l", "--log filename", action
="store", type="string", dest
="LogFile",
1688 help="Specify real execution log file")
1690 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.")
1692 Parser
.add_option("-q", "--quiet", action
="store_true", type=None, help="Disable all messages except FATAL ERRORS.")
1693 Parser
.add_option("-v", "--verbose", action
="store_true", type=None, help="Turn on verbose output with informational messages printed, "\
1694 "including library instances selected, final dependency expression, "\
1695 "and warning messages, etc.")
1696 Parser
.add_option("-d", "--debug", action
="store", type="int", help="Enable debug messages at specified level.")
1698 (Opt
, Args
)=Parser
.parse_args()
1704 # This acts like the main() function for the script, unless it is 'import'ed into another
1707 if __name__
== '__main__':
1708 # Initialize log system
1709 EdkLogger
.Initialize()
1710 EdkLogger
.IsRaiseError
= False
1711 EdkLogger
.quiet(time
.strftime("%H:%M:%S, %b.%d %Y ", time
.localtime()) + "[00:00]" + "\n")
1713 StartTime
= time
.clock()
1714 Eot
= Eot(CommandLineOption
=False,
1715 SourceFileList
=r
'C:\TestEot\Source.txt',
1716 GuidList
=r
'C:\TestEot\Guid.txt',
1717 FvFileList
=r
'C:\TestEot\FVRECOVERY.Fv')
1718 FinishTime
= time
.clock()
1720 BuildDuration
= time
.strftime("%M:%S", time
.gmtime(int(round(FinishTime
- StartTime
))))
1721 EdkLogger
.quiet("\n%s [%s]" % (time
.strftime("%H:%M:%S, %b.%d %Y", time
.localtime()), BuildDuration
))