4 # Copyright (c) 2008 - 2010, 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.
24 from UserDict
import IterableUserDict
25 from cStringIO
import StringIO
26 from array
import array
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
)