4 # Copyright (c) 2008 - 2014, 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.
16 import Common
.LongFilePathOs
as os
24 from UserDict
import IterableUserDict
25 from cStringIO
import StringIO
26 from array
import array
27 from Common
.LongFilePathSupport
import OpenLongFilePath
as open
28 from CommonDataClass
import *
29 from Common
.Misc
import sdict
, GuidStructureStringToGuidString
31 import Common
.EdkLogger
as EdkLogger
36 gFfsPrintTitle
= "%-36s %-21s %8s %8s %8s %-4s %-36s" % ("GUID", "TYPE", "OFFSET", "SIZE", "FREE", "ALIGN", "NAME")
37 gFfsPrintFormat
= "%36s %-21s %8X %8X %8X %4s %-36s"
38 gGuidStringFormat
= "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X"
39 gPeiAprioriFileNameGuid
= '1b45cc0a-156a-428a-af62-49864da0e6e6'
40 gAprioriGuid
= 'fc510ee7-ffdc-11d4-bd41-0080c73c8881'
48 _HEADER_
= struct
.Struct("")
49 _HEADER_SIZE_
= _HEADER_
.size
51 def __new__(cls
, *args
, **kwargs
):
52 return array
.__new
__(cls
, 'B')
54 def __init__(m
, ID
=None):
56 m
._ID
_ = str(uuid
.uuid1()).upper()
63 m
._SubImages
= sdict() # {offset: Image()}
65 array
.__init
__(m
, 'B')
71 Len
= array
.__len
__(m
)
72 for Offset
in m
._SubImages
:
73 Len
+= len(m
._SubImages
[Offset
])
77 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._LEN
_])
80 def _Pack(m
, PadByte
=0xFF):
81 raise NotImplementedError
83 def frombuffer(m
, Buffer
, Offset
=0, Size
=None):
86 # we may need the Size information in advance if it's given
93 def GetField(m
, FieldStruct
, Offset
=0):
94 return FieldStruct
.unpack_from(m
, Offset
)
96 def SetField(m
, FieldStruct
, Offset
, *args
):
97 # check if there's enough space
98 Size
= FieldStruct
.size
100 m
.extend([0] * (Size
- len(m
)))
101 FieldStruct
.pack_into(m
, Offset
, *args
)
103 def _SetData(m
, Data
):
104 if len(m
) < m
._HEADER
_SIZE
_:
105 m
.extend([0] * (m
._HEADER
_SIZE
_ - len(m
)))
107 del m
[m
._HEADER
_SIZE
_:]
111 if len(m
) > m
._HEADER
_SIZE
_:
112 return m
[m
._HEADER
_SIZE
_:]
115 Data
= property(_GetData
, _SetData
)
117 ## FirmwareVolume() class
119 # A class for Firmware Volume
121 class FirmwareVolume(Image
):
122 # Read FvLength, Attributes, HeaderLength, Checksum
123 _HEADER_
= struct
.Struct("16x 1I2H8B 1Q 4x 1I 1H 1H")
124 _HEADER_SIZE_
= _HEADER_
.size
126 _FfsGuid
= "8C8CE578-8A3D-4F1C-9935-896185C32DD3"
128 _GUID_
= struct
.Struct("16x 1I2H8B")
129 _LENGTH_
= struct
.Struct("16x 16x 1Q")
130 _SIG_
= struct
.Struct("16x 16x 8x 1I")
131 _ATTR_
= struct
.Struct("16x 16x 8x 4x 1I")
132 _HLEN_
= struct
.Struct("16x 16x 8x 4x 4x 1H")
133 _CHECKSUM_
= struct
.Struct("16x 16x 8x 4x 4x 2x 1H")
135 def __init__(self
, Name
=''):
138 self
.FfsDict
= sdict()
139 self
.OrderedFfsDict
= sdict()
140 self
.UnDispatchedFfsDict
= sdict()
141 self
.NoDepexFfsDict
= sdict()
142 self
.ProtocolList
= sdict()
144 def CheckArchProtocol(self
):
145 for Item
in EotGlobalData
.gArchProtocolGuids
:
146 if Item
.lower() not in EotGlobalData
.gProtocolList
:
152 def ParseDepex(self
, Depex
, Type
):
155 List
= EotGlobalData
.gPpiList
156 if Type
== 'Protocol':
157 List
= EotGlobalData
.gProtocolList
163 for Index
in range(0, len(Depex
.Expression
)):
164 Item
= Depex
.Expression
[Index
]
167 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
168 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
169 return (True, 'BEFORE %s' % Guid
, [Guid
, 'BEFORE'])
172 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
173 if Guid
in self
.OrderedFfsDict
and Depex
.Expression
[Index
+ 1] == 0x08:
174 return (True, 'AFTER %s' % Guid
, [Guid
, 'AFTER'])
177 Guid
= gGuidStringFormat
% Depex
.Expression
[Index
]
178 if Guid
.lower() in List
:
179 DepexStack
.append(True)
180 DepexList
.append(Guid
)
182 DepexStack
.append(False)
183 DepexList
.append(Guid
)
185 elif Item
== 0x03 or Item
== 0x04:
186 DepexStack
.append(eval(str(DepexStack
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
187 DepexList
.append(str(DepexList
.pop()) + ' ' + Depex
._OPCODE
_STRING
_[Item
].upper() + ' ' + str(DepexList
.pop()))
189 DepexStack
.append(eval(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexStack
.pop())))
190 DepexList
.append(Depex
._OPCODE
_STRING
_[Item
].lower() + ' ' + str(DepexList
.pop()))
192 DepexStack
.append(True)
193 DepexList
.append('TRUE')
194 DepexString
= DepexString
+ 'TRUE' + ' '
196 DepexStack
.append(False)
197 DepexList
.append('False')
198 DepexString
= DepexString
+ 'FALSE' + ' '
200 if Index
!= len(Depex
.Expression
) - 1:
201 CouldBeLoaded
= False
203 CouldBeLoaded
= DepexStack
.pop()
205 CouldBeLoaded
= False
207 DepexString
= DepexList
[0].strip()
208 return (CouldBeLoaded
, DepexString
, FileDepex
)
210 def Dispatch(self
, Db
= None):
213 self
.UnDispatchedFfsDict
= copy
.copy(self
.FfsDict
)
214 # Find PeiCore, DexCore, PeiPriori, DxePriori first
215 FfsSecCoreGuid
= None
216 FfsPeiCoreGuid
= None
217 FfsDxeCoreGuid
= None
218 FfsPeiPrioriGuid
= None
219 FfsDxePrioriGuid
= None
220 for FfsID
in self
.UnDispatchedFfsDict
:
221 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
223 FfsSecCoreGuid
= FfsID
226 FfsPeiCoreGuid
= FfsID
229 FfsDxeCoreGuid
= FfsID
231 if Ffs
.Guid
.lower() == gPeiAprioriFileNameGuid
:
232 FfsPeiPrioriGuid
= FfsID
234 if Ffs
.Guid
.lower() == gAprioriGuid
:
235 FfsDxePrioriGuid
= FfsID
238 # Parse SEC_CORE first
239 if FfsSecCoreGuid
!= None:
240 self
.OrderedFfsDict
[FfsSecCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsSecCoreGuid
)
241 self
.LoadPpi(Db
, FfsSecCoreGuid
)
244 if FfsPeiCoreGuid
!= None:
245 self
.OrderedFfsDict
[FfsPeiCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsPeiCoreGuid
)
246 self
.LoadPpi(Db
, FfsPeiCoreGuid
)
247 if FfsPeiPrioriGuid
!= None:
248 # Load PEIM described in priori file
249 FfsPeiPriori
= self
.UnDispatchedFfsDict
.pop(FfsPeiPrioriGuid
)
250 if len(FfsPeiPriori
.Sections
) == 1:
251 Section
= FfsPeiPriori
.Sections
.popitem()[1]
252 if Section
.Type
== 0x19:
253 GuidStruct
= struct
.Struct('1I2H8B')
255 while len(Section
) > Start
:
256 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
257 GuidString
= gGuidStringFormat
% Guid
259 if GuidString
in self
.UnDispatchedFfsDict
:
260 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
261 self
.LoadPpi(Db
, GuidString
)
266 if FfsDxeCoreGuid
!= None:
267 self
.OrderedFfsDict
[FfsDxeCoreGuid
] = self
.UnDispatchedFfsDict
.pop(FfsDxeCoreGuid
)
268 self
.LoadProtocol(Db
, FfsDxeCoreGuid
)
269 if FfsDxePrioriGuid
!= None:
270 # Load PEIM described in priori file
271 FfsDxePriori
= self
.UnDispatchedFfsDict
.pop(FfsDxePrioriGuid
)
272 if len(FfsDxePriori
.Sections
) == 1:
273 Section
= FfsDxePriori
.Sections
.popitem()[1]
274 if Section
.Type
== 0x19:
275 GuidStruct
= struct
.Struct('1I2H8B')
277 while len(Section
) > Start
:
278 Guid
= GuidStruct
.unpack_from(Section
[Start
: Start
+ 16])
279 GuidString
= gGuidStringFormat
% Guid
281 if GuidString
in self
.UnDispatchedFfsDict
:
282 self
.OrderedFfsDict
[GuidString
] = self
.UnDispatchedFfsDict
.pop(GuidString
)
283 self
.LoadProtocol(Db
, GuidString
)
287 def DisPatchNoDepexFfs(self
, Db
):
288 # Last Load Drivers without Depex
289 for FfsID
in self
.NoDepexFfsDict
:
290 NewFfs
= self
.NoDepexFfsDict
.pop(FfsID
)
291 self
.OrderedFfsDict
[FfsID
] = NewFfs
292 self
.LoadProtocol(Db
, FfsID
)
296 def LoadCallbackProtocol(self
):
298 for Protocol
in self
.ProtocolList
:
299 for Callback
in self
.ProtocolList
[Protocol
][1]:
300 if Callback
[0] not in self
.OrderedFfsDict
.keys():
304 EotGlobalData
.gProtocolList
[Protocol
.lower()] = self
.ProtocolList
[Protocol
][0]
305 self
.ProtocolList
.pop(Protocol
)
307 def LoadProtocol(self
, Db
, ModuleGuid
):
308 SqlCommand
= """select GuidValue from Report
309 where SourceFileFullPath in
310 (select Value1 from Inf where BelongsToFile =
311 (select BelongsToFile from Inf
312 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
314 and ItemType = 'Protocol' and ItemMode = 'Produced'""" \
315 % (ModuleGuid
, 5001, 3007)
316 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
317 for Record
in RecordSet
:
318 SqlCommand
= """select Value2 from Inf where BelongsToFile =
319 (select DISTINCT BelongsToFile from Inf
321 (select SourceFileFullPath from Report
322 where GuidValue like '%s' and ItemMode = 'Callback'))
323 and Value1 = 'FILE_GUID'""" % Record
[0]
324 CallBackSet
= Db
.TblReport
.Exec(SqlCommand
)
325 if CallBackSet
!= []:
326 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
328 EotGlobalData
.gProtocolList
[Record
[0].lower()] = ModuleGuid
330 def LoadPpi(self
, Db
, ModuleGuid
):
331 SqlCommand
= """select GuidValue from Report
332 where SourceFileFullPath in
333 (select Value1 from Inf where BelongsToFile =
334 (select BelongsToFile from Inf
335 where Value1 = 'FILE_GUID' and Value2 like '%s' and Model = %s)
337 and ItemType = 'Ppi' and ItemMode = 'Produced'""" \
338 % (ModuleGuid
, 5001, 3007)
339 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
340 for Record
in RecordSet
:
341 EotGlobalData
.gPpiList
[Record
[0].lower()] = ModuleGuid
343 def DisPatchDxe(self
, Db
):
345 ScheduleList
= sdict()
346 for FfsID
in self
.UnDispatchedFfsDict
:
347 CouldBeLoaded
= False
350 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
354 for Section
in Ffs
.Sections
.values():
356 if Section
.Type
== 0x13:
358 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Protocol')
360 if Section
.Type
== 0x01:
361 CompressSections
= Section
._SubImages
[4]
362 for CompressSection
in CompressSections
.Sections
:
363 if CompressSection
.Type
== 0x13:
365 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Protocol')
367 if CompressSection
.Type
== 0x02:
368 NewSections
= CompressSection
._SubImages
[4]
369 for NewSection
in NewSections
.Sections
:
370 if NewSection
.Type
== 0x13:
372 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Protocol')
377 CouldBeLoaded
= self
.CheckArchProtocol()
384 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
385 NewFfs
.Depex
= DepexString
386 if FileDepex
!= None:
387 ScheduleList
.insert
.insert(FileDepex
[1], FfsID
, NewFfs
, FileDepex
[0])
389 ScheduleList
[FfsID
] = NewFfs
391 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
393 for FfsID
in ScheduleList
:
394 NewFfs
= ScheduleList
.pop(FfsID
)
396 self
.OrderedFfsDict
[FfsID
] = NewFfs
397 self
.LoadProtocol(Db
, FfsID
)
399 SqlCommand
= """select Value2 from Inf
400 where BelongsToFile = (select BelongsToFile from Inf where Value1 = 'FILE_GUID' and lower(Value2) = lower('%s') and Model = %s)
401 and Model = %s and Value1='BASE_NAME'""" % (FfsID
, 5001, 5001)
402 RecordSet
= Db
.TblReport
.Exec(SqlCommand
)
404 FfsName
= RecordSet
[0][0]
409 def DisPatchPei(self
, Db
):
411 for FfsID
in self
.UnDispatchedFfsDict
:
415 Ffs
= self
.UnDispatchedFfsDict
[FfsID
]
416 if Ffs
.Type
== 0x06 or Ffs
.Type
== 0x08:
418 for Section
in Ffs
.Sections
.values():
419 if Section
.Type
== 0x1B:
420 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(Section
._SubImages
[4], 'Ppi')
423 if Section
.Type
== 0x01:
424 CompressSections
= Section
._SubImages
[4]
425 for CompressSection
in CompressSections
.Sections
:
426 if CompressSection
.Type
== 0x1B:
427 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(CompressSection
._SubImages
[4], 'Ppi')
429 if CompressSection
.Type
== 0x02:
430 NewSections
= CompressSection
._SubImages
[4]
431 for NewSection
in NewSections
.Sections
:
432 if NewSection
.Type
== 0x1B:
433 CouldBeLoaded
, DepexString
, FileDepex
= self
.ParseDepex(NewSection
._SubImages
[4], 'Ppi')
439 NewFfs
= self
.UnDispatchedFfsDict
.pop(FfsID
)
440 NewFfs
.Depex
= DepexString
441 self
.OrderedFfsDict
[FfsID
] = NewFfs
442 self
.LoadPpi(Db
, FfsID
)
444 self
.UnDispatchedFfsDict
[FfsID
].Depex
= DepexString
453 FvInfo
= '\n' + ' ' * gIndention
454 FvInfo
+= "[FV:%s] file_system=%s size=%x checksum=%s\n" % (self
.Name
, self
.FileSystemGuid
, self
.Size
, self
.Checksum
)
455 FfsInfo
= "\n".join([str(self
.FfsDict
[FfsId
]) for FfsId
in self
.FfsDict
])
457 return FvInfo
+ FfsInfo
460 Size
= self
._LENGTH
_.unpack_from(self
._BUF
_, self
._OFF
_)[0]
462 self
.extend(self
._BUF
_[self
._OFF
_:self
._OFF
_+Size
])
466 FfsStartAddress
= self
.HeaderSize
468 while FfsStartAddress
< EndOfFv
:
470 FfsObj
.frombuffer(self
, FfsStartAddress
)
472 if ((self
.Attributes
& 0x00000800) != 0 and len(FfsObj
) == 0xFFFFFF) \
473 or ((self
.Attributes
& 0x00000800) == 0 and len(FfsObj
) == 0):
474 if LastFfsObj
!= None:
475 LastFfsObj
.FreeSpace
= EndOfFv
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
477 if FfsId
in self
.FfsDict
:
478 EdkLogger
.error("FV", 0, "Duplicate GUID in FFS",
479 ExtraData
="\t%s @ %s\n\t%s @ %s" \
480 % (FfsObj
.Guid
, FfsObj
.Offset
,
481 self
.FfsDict
[FfsId
].Guid
, self
.FfsDict
[FfsId
].Offset
))
482 self
.FfsDict
[FfsId
] = FfsObj
483 if LastFfsObj
!= None:
484 LastFfsObj
.FreeSpace
= FfsStartAddress
- LastFfsObj
._OFF
_ - len(LastFfsObj
)
486 FfsStartAddress
+= len(FfsObj
)
488 # align to next 8-byte aligned address: A = (A + 8 - 1) & (~(8 - 1))
489 # The next FFS must be at the latest next 8-byte aligned address
491 FfsStartAddress
= (FfsStartAddress
+ 7) & (~
7)
494 def _GetAttributes(self
):
495 return self
.GetField(self
._ATTR
_, 0)[0]
498 return self
.GetField(self
._LENGTH
_, 0)[0]
500 def _GetChecksum(self
):
501 return self
.GetField(self
._CHECKSUM
_, 0)[0]
503 def _GetHeaderLength(self
):
504 return self
.GetField(self
._HLEN
_, 0)[0]
506 def _GetFileSystemGuid(self
):
507 return gGuidStringFormat
% self
.GetField(self
._GUID
_, 0)
509 Attributes
= property(_GetAttributes
)
510 Size
= property(_GetSize
)
511 Checksum
= property(_GetChecksum
)
512 HeaderSize
= property(_GetHeaderLength
)
513 FileSystemGuid
= property(_GetFileSystemGuid
)
515 ## CompressedImage() class
517 # A class for Compressed Image
519 class CompressedImage(Image
):
520 # UncompressedLength = 4-byte
521 # CompressionType = 1-byte
522 _HEADER_
= struct
.Struct("1I 1B")
523 _HEADER_SIZE_
= _HEADER_
.size
525 _ORIG_SIZE_
= struct
.Struct("1I")
526 _CMPRS_TYPE_
= struct
.Struct("4x 1B")
528 def __init__(m
, CompressedData
=None, CompressionType
=None, UncompressedLength
=None):
530 if UncompressedLength
!= None:
531 m
.UncompressedLength
= UncompressedLength
532 if CompressionType
!= None:
533 m
.CompressionType
= CompressionType
534 if CompressedData
!= None:
535 m
.Data
= CompressedData
539 S
= "algorithm=%s uncompressed=%x" % (m
.CompressionType
, m
.UncompressedLength
)
540 for Sec
in m
.Sections
:
545 def _SetOriginalSize(m
, Size
):
546 m
.SetField(m
._ORIG
_SIZE
_, 0, Size
)
548 def _GetOriginalSize(m
):
549 return m
.GetField(m
._ORIG
_SIZE
_)[0]
551 def _SetCompressionType(m
, Type
):
552 m
.SetField(m
._CMPRS
_TYPE
_, 0, Type
)
554 def _GetCompressionType(m
):
555 return m
.GetField(m
._CMPRS
_TYPE
_)[0]
560 TmpData
= EfiCompressor
.FrameworkDecompress(
562 len(m
) - m
._HEADER
_SIZE
_
565 DecData
.fromstring(TmpData
)
568 TmpData
= EfiCompressor
.UefiDecompress(
570 len(m
) - m
._HEADER
_SIZE
_
573 DecData
.fromstring(TmpData
)
577 while Offset
< len(DecData
):
580 Sec
.frombuffer(DecData
, Offset
)
582 # the section is aligned to 4-byte boundary
585 SectionList
.append(Sec
)
588 UncompressedLength
= property(_GetOriginalSize
, _SetOriginalSize
)
589 CompressionType
= property(_GetCompressionType
, _SetCompressionType
)
590 Sections
= property(_GetSections
)
592 ## GuidDefinedImage() class
594 # A class for GUID Defined Image
596 class GuidDefinedImage(Image
):
597 _HEADER_
= struct
.Struct("1I2H8B 1H 1H")
598 _HEADER_SIZE_
= _HEADER_
.size
600 _GUID_
= struct
.Struct("1I2H8B")
601 _DATA_OFFSET_
= struct
.Struct("16x 1H")
602 _ATTR_
= struct
.Struct("18x 1H")
604 CRC32_GUID
= "FC1BCDB0-7D31-49AA-936A-A4600D9DD083"
605 TIANO_COMPRESS_GUID
= 'A31280AD-481E-41B6-95E8-127F4C984779'
606 LZMA_COMPRESS_GUID
= 'EE4E5898-3914-4259-9D6E-DC7BD79403CF'
608 def __init__(m
, SectionDefinitionGuid
=None, DataOffset
=None, Attributes
=None, Data
=None):
610 if SectionDefinitionGuid
!= None:
611 m
.SectionDefinitionGuid
= SectionDefinitionGuid
612 if DataOffset
!= None:
613 m
.DataOffset
= DataOffset
614 if Attributes
!= None:
615 m
.Attributes
= Attributes
620 S
= "guid=%s" % (gGuidStringFormat
% m
.SectionDefinitionGuid
)
621 for Sec
in m
.Sections
:
626 # keep header in this Image object
628 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._LEN
_])
631 def _SetAttribute(m
, Attribute
):
632 m
.SetField(m
._ATTR
_, 0, Attribute
)
634 def _GetAttribute(m
):
635 return m
.GetField(m
._ATTR
_)[0]
637 def _SetGuid(m
, Guid
):
638 m
.SetField(m
._GUID
_, 0, Guid
)
641 return m
.GetField(m
._GUID
_)
643 def _SetDataOffset(m
, Offset
):
644 m
.SetField(m
._DATA
_OFFSET
_, 0, Offset
)
646 def _GetDataOffset(m
):
647 return m
.GetField(m
._DATA
_OFFSET
_)[0]
651 Guid
= gGuidStringFormat
% m
.SectionDefinitionGuid
652 if Guid
== m
.CRC32_GUID
:
653 # skip the CRC32 value, we don't do CRC32 verification here
654 Offset
= m
.DataOffset
- 4
655 while Offset
< len(m
):
658 Sec
.frombuffer(m
, Offset
)
660 # the section is aligned to 4-byte boundary
661 Offset
= (Offset
+ 3) & (~
3)
664 SectionList
.append(Sec
)
665 elif Guid
== m
.TIANO_COMPRESS_GUID
:
669 Offset
= m
.DataOffset
- 4
670 TmpData
= EfiCompressor
.FrameworkDecompress(m
[Offset
:], len(m
)-Offset
)
672 DecData
.fromstring(TmpData
)
674 while Offset
< len(DecData
):
677 Sec
.frombuffer(DecData
, Offset
)
679 # the section is aligned to 4-byte boundary
680 Offset
= (Offset
+ 3) & (~
3)
683 SectionList
.append(Sec
)
686 elif Guid
== m
.LZMA_COMPRESS_GUID
:
688 import LzmaCompressor
690 Offset
= m
.DataOffset
- 4
691 TmpData
= LzmaCompressor
.LzmaDecompress(m
[Offset
:], len(m
)-Offset
)
693 DecData
.fromstring(TmpData
)
695 while Offset
< len(DecData
):
698 Sec
.frombuffer(DecData
, Offset
)
700 # the section is aligned to 4-byte boundary
701 Offset
= (Offset
+ 3) & (~
3)
704 SectionList
.append(Sec
)
710 Attributes
= property(_GetAttribute
, _SetAttribute
)
711 SectionDefinitionGuid
= property(_GetGuid
, _SetGuid
)
712 DataOffset
= property(_GetDataOffset
, _SetDataOffset
)
713 Sections
= property(_GetSections
)
720 _HEADER_
= struct
.Struct("")
723 _GUID_
= struct
.Struct("1I2H8B")
724 _OPCODE_
= struct
.Struct("1B")
740 -1 : _OPCODE_
, # first one in depex must be an opcdoe
741 0x00 : _GUID_
, #"BEFORE",
742 0x01 : _GUID_
, #"AFTER",
743 0x02 : _GUID_
, #"PUSH",
744 0x03 : _OPCODE_
, #"AND",
745 0x04 : _OPCODE_
, #"OR",
746 0x05 : _OPCODE_
, #"NOT",
747 0x06 : _OPCODE_
, #"TRUE",
748 0x07 : _OPCODE_
, #"FALSE",
750 0x09 : _OPCODE_
, #"SOR"
760 Indention
= ' ' * gIndention
762 for T
in m
.Expression
:
763 if T
in m
._OPCODE
_STRING
_:
764 S
+= Indention
+ m
._OPCODE
_STRING
_[T
]
765 if T
not in [0x00, 0x01, 0x02]:
768 S
+= ' ' + gGuidStringFormat
% T
+ '\n'
773 # keep header in this Image object
775 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._LEN
_])
778 def _GetExpression(m
):
779 if m
._ExprList
== []:
781 CurrentData
= m
._OPCODE
_
782 while Offset
< len(m
):
783 Token
= CurrentData
.unpack_from(m
, Offset
)
784 Offset
+= CurrentData
.size
787 if Token
in m
._NEXT
_:
788 CurrentData
= m
._NEXT
_[Token
]
790 CurrentData
= m
._GUID
_
792 CurrentData
= m
._OPCODE
_
793 m
._ExprList
.append(Token
)
794 if CurrentData
== None:
798 Expression
= property(_GetExpression
)
805 _HEADER_
= struct
.Struct("")
815 # keep header in this Image object
817 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._LEN
_])
821 return codecs
.utf_16_decode(m
[0:-2].tostring())[0]
823 String
= property(_GetUiString
)
827 # A class for Section
829 class Section(Image
):
832 0x01 : "COMPRESSION",
833 0x02 : "GUID_DEFINED",
839 0x15 : "USER_INTERFACE",
840 0x16 : "COMPATIBILITY16",
841 0x17 : "FIRMWARE_VOLUME_IMAGE",
842 0x18 : "FREEFORM_SUBTYPE_GUID",
847 _SectionSubImages
= {
848 0x01 : CompressedImage
,
849 0x02 : GuidDefinedImage
,
850 0x17 : FirmwareVolume
,
858 _HEADER_
= struct
.Struct("3B 1B")
859 _HEADER_SIZE_
= _HEADER_
.size
862 # _FREE_FORM_SUBTYPE_GUID_HEADER_ = struct.Struct("1I2H8B")
864 _SIZE_
= struct
.Struct("3B")
865 _TYPE_
= struct
.Struct("3x 1B")
867 def __init__(m
, Type
=None, Size
=None):
878 SectionInfo
= ' ' * gIndention
879 if m
.Type
in m
._TypeName
:
880 SectionInfo
+= "[SECTION:%s] offset=%x size=%x" % (m
._TypeName
[m
.Type
], m
._OFF
_, m
.Size
)
882 SectionInfo
+= "[SECTION:%x<unknown>] offset=%x size=%x " % (m
.Type
, m
._OFF
_, m
.Size
)
883 for Offset
in m
._SubImages
:
884 SectionInfo
+= ", " + str(m
._SubImages
[Offset
])
890 Type
, = m
._TYPE
_.unpack_from(m
._BUF
_, m
._OFF
_)
891 Size1
, Size2
, Size3
= m
._SIZE
_.unpack_from(m
._BUF
_, m
._OFF
_)
892 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
894 if Type
not in m
._SectionSubImages
:
895 # no need to extract sub-image, keep all in this Image object
896 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + Size
])
898 # keep header in this Image object
899 m
.extend(m
._BUF
_[m
._OFF
_ : m
._OFF
_ + m
._HEADER
_SIZE
_])
901 # use new Image object to represent payload, which may be another kind
902 # of image such as PE32
904 PayloadOffset
= m
._HEADER
_SIZE
_
905 PayloadLen
= m
.Size
- m
._HEADER
_SIZE
_
906 Payload
= m
._SectionSubImages
[m
.Type
]()
907 Payload
.frombuffer(m
._BUF
_, m
._OFF
_ + m
._HEADER
_SIZE
_, PayloadLen
)
908 m
._SubImages
[PayloadOffset
] = Payload
912 def _SetSize(m
, Size
):
914 Size2
= (Size
& 0xFF00) >> 8
915 Size3
= (Size
& 0xFF0000) >> 16
916 m
.SetField(m
._SIZE
_, 0, Size1
, Size2
, Size3
)
919 Size1
, Size2
, Size3
= m
.GetField(m
._SIZE
_)
920 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
922 def _SetType(m
, Type
):
923 m
.SetField(m
._TYPE
_, 0, Type
)
926 return m
.GetField(m
._TYPE
_)[0]
928 def _GetAlignment(m
):
931 def _SetAlignment(m
, Alignment
):
932 m
._Alignment
= Alignment
933 AlignmentMask
= Alignment
- 1
934 # section alignment is actually for payload, so we need to add header size
935 PayloadOffset
= m
._OFF
_ + m
._HEADER
_SIZE
_
936 if (PayloadOffset
& (~AlignmentMask
)) == 0:
938 NewOffset
= (PayloadOffset
+ AlignmentMask
) & (~AlignmentMask
)
939 while (NewOffset
- PayloadOffset
) < m
._HEADER
_SIZE
_:
940 NewOffset
+= m
._Alignment
945 for Offset
in m
._SubImages
:
946 m
._SubImages
[Offset
].tofile(f
)
948 Type
= property(_GetType
, _SetType
)
949 Size
= property(_GetSize
, _SetSize
)
950 Alignment
= property(_GetAlignment
, _SetAlignment
)
951 # SubTypeGuid = property(_GetGuid, _SetGuid)
953 ## PadSection() class
955 # A class for Pad Section
957 class PadSection(Section
):
958 def __init__(m
, Size
):
962 m
.Data
= [0] * (Size
- m
._HEADER
_SIZE
_)
966 # A class for Ffs Section
969 _FfsFormat
= "24B%(payload_size)sB"
970 # skip IntegrityCheck
971 _HEADER_
= struct
.Struct("1I2H8B 2x 1B 1B 3B 1B")
972 _HEADER_SIZE_
= _HEADER_
.size
974 _NAME_
= struct
.Struct("1I2H8B")
975 _INT_CHECK_
= struct
.Struct("16x 1H")
976 _TYPE_
= struct
.Struct("18x 1B")
977 _ATTR_
= struct
.Struct("19x 1B")
978 _SIZE_
= struct
.Struct("20x 3B")
979 _STATE_
= struct
.Struct("23x 1B")
981 VTF_GUID
= "1BA0062E-C779-4582-8566-336AE8F78F09"
983 FFS_ATTRIB_FIXED
= 0x04
984 FFS_ATTRIB_DATA_ALIGNMENT
= 0x38
985 FFS_ATTRIB_CHECKSUM
= 0x40
991 0x03 : "SECURITY_CORE",
996 0x08 : "COMBINED_PEIM_DRIVER",
997 0x09 : "APPLICATION",
999 0x0B : "FIRMWARE_VOLUME_IMAGE",
1000 0x0C : "COMBINED_SMM_DXE",
1012 Image
.__init
__(self
)
1015 self
.Sections
= sdict()
1023 Indention
= ' ' * gIndention
1025 FfsInfo
+= "[FFS:%s] offset=%x size=%x guid=%s free_space=%x alignment=%s\n" % \
1026 (Ffs
._TypeName
[self
.Type
], self
._OFF
_, self
.Size
, self
.Guid
, self
.FreeSpace
, self
.Alignment
)
1027 SectionInfo
= '\n'.join([str(self
.Sections
[Offset
]) for Offset
in self
.Sections
])
1029 return FfsInfo
+ SectionInfo
+ "\n"
1038 Size1
, Size2
, Size3
= self
._SIZE
_.unpack_from(self
._BUF
_, self
._OFF
_)
1039 Size
= Size1
+ (Size2
<< 8) + (Size3
<< 16)
1041 self
.extend(self
._BUF
_[self
._OFF
_ : self
._OFF
_ + Size
])
1043 # Pad FFS may use the same GUID. We need to avoid it.
1044 if self
.Type
== 0xf0:
1045 self
.__ID
__ = str(uuid
.uuid1()).upper()
1047 self
.__ID
__ = self
.Guid
1049 # Traverse the SECTION. RAW and PAD do not have sections
1050 if self
.Type
not in [0xf0, 0x01] and Size
> 0 and Size
< 0xFFFFFF:
1052 SectionStartAddress
= self
._HEADER
_SIZE
_
1053 while SectionStartAddress
< EndOfFfs
:
1054 SectionObj
= Section()
1055 SectionObj
.frombuffer(self
, SectionStartAddress
)
1056 #f = open(repr(SectionObj), 'wb')
1057 #SectionObj.Size = 0
1058 #SectionObj.tofile(f)
1060 self
.Sections
[SectionStartAddress
] = SectionObj
1061 SectionStartAddress
+= len(SectionObj
)
1062 SectionStartAddress
= (SectionStartAddress
+ 3) & (~
3)
1067 def SetFreeSpace(self
, Size
):
1068 self
.FreeSpace
= Size
1071 return gGuidStringFormat
% self
.Name
1073 def _SetName(self
, Value
):
1074 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1075 self
.SetField(self
._NAME
_, 0, Value
)
1078 # Guid1, Guid2, Guid3, Guid4, Guid5, Guid6, Guid7, Guid8, Guid9, Guid10, Guid11
1079 return self
.GetField(self
._NAME
_)
1081 def _SetSize(m
, Size
):
1083 Size2
= (Size
& 0xFF00) >> 8
1084 Size3
= (Size
& 0xFF0000) >> 16
1085 m
.SetField(m
._SIZE
_, 0, Size1
, Size2
, Size3
)
1088 Size1
, Size2
, Size3
= m
.GetField(m
._SIZE
_)
1089 return Size1
+ (Size2
<< 8) + (Size3
<< 16)
1091 def _SetType(m
, Type
):
1092 m
.SetField(m
._TYPE
_, 0, Type
)
1095 return m
.GetField(m
._TYPE
_)[0]
1097 def _SetAttributes(self
, Value
):
1098 self
.SetField(m
._ATTR
_, 0, Value
)
1100 def _GetAttributes(self
):
1101 return self
.GetField(self
._ATTR
_)[0]
1103 def _GetFixed(self
):
1104 if (self
.Attributes
& self
.FFS_ATTRIB_FIXED
) != 0:
1108 def _GetCheckSum(self
):
1109 if (self
.Attributes
& self
.FFS_ATTRIB_CHECKSUM
) != 0:
1113 def _GetAlignment(self
):
1114 return (self
.Attributes
& self
.FFS_ATTRIB_DATA_ALIGNMENT
) >> 3
1116 def _SetState(self
, Value
):
1117 self
.SetField(m
._STATE
_, 0, Value
)
1119 def _GetState(self
):
1120 return self
.GetField(m
._STATE
_)[0]
1122 Name
= property(_GetName
, _SetName
)
1123 Guid
= property(_GetGuid
)
1124 Type
= property(_GetType
, _SetType
)
1125 Size
= property(_GetSize
, _SetSize
)
1126 Attributes
= property(_GetAttributes
, _SetAttributes
)
1127 Fixed
= property(_GetFixed
)
1128 Checksum
= property(_GetCheckSum
)
1129 Alignment
= property(_GetAlignment
)
1130 State
= property(_GetState
, _SetState
)
1134 # A class for PE Image
1138 # just extract e_lfanew
1140 _DosHeaderFormat
= "60x 1I"
1144 # SizeOfOptionalHeader
1146 _FileHeaderFormat
= "4x 1H 1H 4x 4x 4x 1H 2x"
1152 # NumberOfRvaAndSizes
1154 _OptionalHeader32Format
= "1H 54x 1I 1I 1I 24x 1I"
1155 _OptionalHeader64Format
= ""
1156 def __init__(self
, Buf
, Offset
, Size
):
1157 self
.Offset
= Offset
1159 self
.Machine
= 0x014c # IA32
1160 self
.NumberOfSections
= 0
1161 self
.SizeOfImage
= 0
1162 self
.SizeOfOptionalHeader
= 0
1164 self
._PeImageBuf
= Buf
1165 self
._SectionList
= []
1167 self
._DosHeader
= struct
.Struct(PeImage
._DosHeaderFormat
)
1168 self
._FileHeader
= struct
.Struct(PeImage
._FileHeaderFormat
)
1169 self
._OptionalHeader
32 = struct
.Struct(PeImage
._OptionalHeader
32Format
)
1182 # from DOS header, get the offset of PE header
1183 FileHeaderOffset
, = self
._DosHeader
.unpack_from(self
._PeImageBuf
, self
.Offset
)
1184 if FileHeaderOffset
< struct
.calcsize(self
._DosHeaderFormat
):
1185 EdkLogger
.error("PE+", 0, "Invalid offset of IMAGE_FILE_HEADER: %s" % FileHeaderOffset
)
1187 # from FILE header, get the optional header size
1188 self
.Machine
, self
.NumberOfSections
, self
.SizeOfOptionalHeader
= \
1189 self
._FileHeader
.unpack_from(self
._PeImageBuf
, self
.Offset
+ FileHeaderOffset
)
1191 print "Machine=%x NumberOfSections=%x SizeOfOptionalHeader=%x" % (self
.Machine
, self
.NumberOfSections
, self
.SizeOfOptionalHeader
)
1192 # optional header follows the FILE header
1193 OptionalHeaderOffset
= FileHeaderOffset
+ struct
.calcsize(self
._FileHeaderFormat
)
1194 Magic
, self
.SizeOfImage
, SizeOfHeaders
, self
.Checksum
, NumberOfRvaAndSizes
= \
1195 self
._OptionalHeader
32.unpack_from(self
._PeImageBuf
, self
.Offset
+ OptionalHeaderOffset
)
1196 print "Magic=%x SizeOfImage=%x SizeOfHeaders=%x, Checksum=%x, NumberOfRvaAndSizes=%x" % (Magic
, self
.SizeOfImage
, SizeOfHeaders
, self
.Checksum
, NumberOfRvaAndSizes
)
1198 PeImageSectionTableOffset
= OptionalHeaderOffset
+ self
.SizeOfOptionalHeader
1199 PeSections
= PeSectionTable(self
._PeImageBuf
, self
.Offset
+ PeImageSectionTableOffset
, self
.NumberOfSections
)
1201 print "%x" % PeSections
.GetFileAddress(0x3920)
1203 ## PeSectionTable() class
1205 # A class for PE Section Table
1207 class PeSectionTable
:
1208 def __init__(self
, Buf
, Offset
, NumberOfSections
):
1209 self
._SectionList
= []
1211 SectionHeaderOffset
= Offset
1212 for TableIndex
in range(0, NumberOfSections
):
1213 SectionHeader
= PeSectionHeader(Buf
, SectionHeaderOffset
)
1214 self
._SectionList
.append(SectionHeader
)
1215 SectionHeaderOffset
+= len(SectionHeader
)
1218 def GetFileAddress(self
, Rva
):
1219 for PeSection
in self
._SectionList
:
1220 if Rva
in PeSection
:
1221 return PeSection
[Rva
]
1223 ## PeSectionHeader() class
1225 # A class for PE Section Header
1227 class PeSectionHeader
:
1233 _HeaderFormat
= "12x 1I 1I 1I 16x"
1234 _HeaderLength
= struct
.calcsize(_HeaderFormat
)
1236 def __init__(self
, Buf
, Offset
):
1237 self
.VirtualAddressStart
, self
.SizeOfRawData
, self
.PointerToRawData
= \
1238 struct
.unpack_from(self
._HeaderFormat
, Buf
, Offset
)
1239 self
.VirtualAddressEnd
= self
.VirtualAddressStart
+ self
.SizeOfRawData
- 1
1242 return "VirtualAddress=%x, SizeOfRawData=%x, PointerToRawData=%x" % (self
.VirtualAddressStart
, self
.SizeOfRawData
, self
.PointerToRawData
)
1245 return self
._HeaderLength
1247 def __contains__(self
, Rva
):
1248 return Rva
>= self
.VirtualAddressStart
and Rva
<= self
.VirtualAddressEnd
1250 def __getitem__(self
, Rva
):
1251 return Rva
- self
.VirtualAddressStart
+ self
.PointerToRawData
1255 # A class for Link Map
1259 "MSFT" : re
.compile("Address +Publics by Value +Rva\+Base +Lib:Object"),
1260 "GCC" : re
.compile("^\.(text|bss|data|edata)"),
1264 "MSFT" : re
.compile("([0-9a-f]+):([0-9a-f]+)\s+_+([0-9A-Za-z]+)\s+([0-9a-f]+)\s+"),
1265 "GCC" : re
.compile("^(\.\w)?\s+(0x[0-9a-f]+)\s+_+([0-9A-Za-z]+)"),
1268 def __init__(self
, MapFile
, MapType
="MSFT"):
1270 self
.MapType
= MapType
1271 self
._Globals
= {} # global:RVA
1276 MapFile
= open(self
.File
, 'r')
1277 MappingTitle
= self
._StartFlag
[self
.MapType
]
1278 MappingFormat
= self
._MappingFormat
[self
.MapType
]
1279 MappingStart
= False
1281 for Line
in MapFile
:
1283 if not MappingStart
:
1284 if MappingTitle
.match(Line
) != None:
1287 ResultList
= MappingFormat
.findall(Line
)
1288 if len(ResultList
) == 0 or len(ResultList
[0]) != 4:
1290 self
._Globals
[ResultList
[2]] = int(ResultList
[3], 16)
1291 EdkLogger
.verbose(ResultList
[0])
1295 def __contains__(self
, Var
):
1296 return Var
in self
._Globals
1298 def __getitem__(self
, Var
):
1299 if Var
not in self
._Globals
:
1301 return self
._Globals
[Var
]
1303 ## MultipleFv() class
1305 # A class for Multiple FV
1307 class MultipleFv(FirmwareVolume
):
1308 def __init__(self
, FvList
):
1309 FirmwareVolume
.__init
__(self
)
1311 for FvPath
in FvList
:
1312 FvName
= os
.path
.splitext(os
.path
.split(FvPath
)[1])[0]
1313 Fd
= open(FvPath
, 'rb')
1316 Buf
.fromfile(Fd
, os
.path
.getsize(FvPath
))
1320 Fv
= FirmwareVolume(FvName
)
1321 Fv
.frombuffer(Buf
, 0, len(Buf
))
1323 self
.BasicInfo
.append([Fv
.Name
, Fv
.FileSystemGuid
, Fv
.Size
])
1324 self
.FfsDict
.append(Fv
.FfsDict
)
1326 # Version and Copyright
1327 __version_number__
= "0.01"
1328 __version__
= "%prog Version " + __version_number__
1329 __copyright__
= "Copyright (c) 2008, Intel Corporation. All rights reserved."
1331 ## Parse command line options
1333 # Using standard Python module optparse to parse command line option of this tool.
1335 # @retval Options A optparse.Values object containing the parsed options
1336 # @retval InputFile Path of file to be trimmed
1340 make_option("-a", "--arch", dest
="Arch",
1341 help="The input file is preprocessed source code, including C or assembly code"),
1342 make_option("-p", "--platform", dest
="ActivePlatform",
1343 help="The input file is preprocessed VFR file"),
1344 make_option("-m", "--module", dest
="ActiveModule",
1345 help="Convert standard hex format (0xabcd) to MASM format (abcdh)"),
1346 make_option("-f", "--FDF-file", dest
="FdfFile",
1347 help="Convert standard hex format (0xabcd) to MASM format (abcdh)"),
1348 make_option("-o", "--output", dest
="OutputDirectory",
1349 help="File to store the trimmed content"),
1350 make_option("-t", "--toolchain-tag", dest
="ToolChain",
1352 make_option("-k", "--msft", dest
="MakefileType", action
="store_const", const
="nmake",
1354 make_option("-g", "--gcc", dest
="MakefileType", action
="store_const", const
="gmake",
1356 make_option("-v", "--verbose", dest
="LogLevel", action
="store_const", const
=EdkLogger
.VERBOSE
,
1357 help="Run verbosely"),
1358 make_option("-d", "--debug", dest
="LogLevel", type="int",
1359 help="Run with debug information"),
1360 make_option("-q", "--quiet", dest
="LogLevel", action
="store_const", const
=EdkLogger
.QUIET
,
1361 help="Run quietly"),
1362 make_option("-?", action
="help", help="show this help message and exit"),
1365 # use clearer usage to override default usage message
1366 UsageString
= "%prog [-a ARCH] [-p PLATFORM] [-m MODULE] [-t TOOLCHAIN_TAG] [-k] [-g] [-v|-d <debug_level>|-q] [-o <output_directory>] [GenC|GenMake]"
1368 Parser
= OptionParser(description
=__copyright__
, version
=__version__
, option_list
=OptionList
, usage
=UsageString
)
1369 Parser
.set_defaults(Arch
=[])
1370 Parser
.set_defaults(ActivePlatform
=None)
1371 Parser
.set_defaults(ActiveModule
=None)
1372 Parser
.set_defaults(OutputDirectory
="build")
1373 Parser
.set_defaults(FdfFile
=None)
1374 Parser
.set_defaults(ToolChain
="MYTOOLS")
1375 if sys
.platform
== "win32":
1376 Parser
.set_defaults(MakefileType
="nmake")
1378 Parser
.set_defaults(MakefileType
="gmake")
1379 Parser
.set_defaults(LogLevel
=EdkLogger
.INFO
)
1381 Options
, Args
= Parser
.parse_args()
1385 Options
.Target
= "genmake"
1386 sys
.argv
.append("genmake")
1387 elif len(Args
) == 1:
1388 Options
.Target
= Args
[0].lower()
1389 if Options
.Target
not in ["genc", "genmake"]:
1390 EdkLogger
.error("AutoGen", OPTION_NOT_SUPPORTED
, "Not supported target",
1391 ExtraData
="%s\n\n%s" % (Options
.Target
, Parser
.get_usage()))
1393 EdkLogger
.error("AutoGen", OPTION_NOT_SUPPORTED
, "Too many targets",
1394 ExtraData
=Parser
.get_usage())
1400 # This method mainly dispatch specific methods per the command line options.
1401 # If no error found, return zero value so the caller of this tool can know
1402 # if it's executed successfully or not.
1404 # @retval 0 Tool was successful
1405 # @retval 1 Tool failed
1408 from build
import build
1410 Option
= GetOptions()
1412 except Exception, e
:
1418 # This acts like the main() function for the script, unless it is 'import'ed into another script.
1419 if __name__
== '__main__':
1420 EdkLogger
.Initialize()
1423 if len(sys
.argv
) > 1:
1424 FilePath
= sys
.argv
[1]
1425 if FilePath
.lower().endswith(".fv"):
1426 fd
= open(FilePath
, 'rb')
1429 buf
.fromfile(fd
, os
.path
.getsize(FilePath
))
1433 fv
= FirmwareVolume("FVRECOVERY")
1434 fv
.frombuffer(buf
, 0, len(buf
))
1437 elif FilePath
.endswith(".efi"):
1438 fd
= open(FilePath
, 'rb')
1440 Size
= os
.path
.getsize(FilePath
)
1443 buf
.fromfile(fd
, Size
)
1447 PeSection
= Section(Type
=0x10)
1448 PeSection
.Data
= buf
1449 sf
, ext
= os
.path
.splitext(os
.path
.basename(FilePath
))
1451 PeSection
.tofile(open(sf
, 'wb'))
1452 elif FilePath
.endswith(".map"):
1453 mf
= LinkMap(FilePath
)