* [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support
@ 2016-10-05 0:18 Maurice Ma
2016-10-05 16:53 ` Yarlagadda, Satya P
2016-10-07 13:13 ` Yao, Jiewen
0 siblings, 2 replies; 3+ messages in thread
From: Maurice Ma @ 2016-10-05 0:18 UTC (permalink / raw)
To: edk2-devel; +Cc: Maurice Ma, Jiewen Yao, Giri P Mudusuru
The current SplitFspBin.py can only support TE image format
rebasing in an FSP binary. This patch adds PE32 image format
rebasing support.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Maurice Ma <maurice.ma@intel.com>
---
IntelFsp2Pkg/Tools/SplitFspBin.py | 174 +++++++++++++++++++++++++++++++-------
1 file changed, 145 insertions(+), 29 deletions(-)
diff --git a/IntelFsp2Pkg/Tools/SplitFspBin.py b/IntelFsp2Pkg/Tools/SplitFspBin.py
index ef759f0dc46a..e4c3aa6d0b28 100644
--- a/IntelFsp2Pkg/Tools/SplitFspBin.py
+++ b/IntelFsp2Pkg/Tools/SplitFspBin.py
@@ -159,12 +159,102 @@ class EFI_TE_IMAGE_HEADER(Structure):
('DataDirectoryDebug', EFI_IMAGE_DATA_DIRECTORY)
]
+class EFI_IMAGE_DOS_HEADER(Structure):
+ _fields_ = [
+ ('e_magic', c_uint16),
+ ('e_cblp', c_uint16),
+ ('e_cp', c_uint16),
+ ('e_crlc', c_uint16),
+ ('e_cparhdr', c_uint16),
+ ('e_minalloc', c_uint16),
+ ('e_maxalloc', c_uint16),
+ ('e_ss', c_uint16),
+ ('e_sp', c_uint16),
+ ('e_csum', c_uint16),
+ ('e_ip', c_uint16),
+ ('e_cs', c_uint16),
+ ('e_lfarlc', c_uint16),
+ ('e_ovno', c_uint16),
+ ('e_res', ARRAY(c_uint16, 4)),
+ ('e_oemid', c_uint16),
+ ('e_oeminfo', c_uint16),
+ ('e_res2', ARRAY(c_uint16, 10)),
+ ('e_lfanew', c_uint16)
+ ]
+
+class EFI_IMAGE_FILE_HEADER(Structure):
+ _fields_ = [
+ ('Machine', c_uint16),
+ ('NumberOfSections', c_uint16),
+ ('TimeDateStamp', c_uint32),
+ ('PointerToSymbolTable', c_uint32),
+ ('NumberOfSymbols', c_uint32),
+ ('SizeOfOptionalHeader', c_uint16),
+ ('Characteristics', c_uint16)
+ ]
+
class PE_RELOC_BLOCK_HEADER(Structure):
_fields_ = [
('PageRVA', c_uint32),
('BlockSize', c_uint32)
]
+class EFI_IMAGE_OPTIONAL_HEADER32(Structure):
+ _fields_ = [
+ ('Magic', c_uint16),
+ ('MajorLinkerVersion', c_uint8),
+ ('MinorLinkerVersion', c_uint8),
+ ('SizeOfCode', c_uint32),
+ ('SizeOfInitializedData', c_uint32),
+ ('SizeOfUninitializedData', c_uint32),
+ ('AddressOfEntryPoint', c_uint32),
+ ('BaseOfCode', c_uint32),
+ ('BaseOfData', c_uint32),
+ ('ImageBase', c_uint32),
+ ('SectionAlignment', c_uint32),
+ ('FileAlignment', c_uint32),
+ ('MajorOperatingSystemVersion', c_uint16),
+ ('MinorOperatingSystemVersion', c_uint16),
+ ('MajorImageVersion', c_uint16),
+ ('MinorImageVersion', c_uint16),
+ ('MajorSubsystemVersion', c_uint16),
+ ('MinorSubsystemVersion', c_uint16),
+ ('Win32VersionValue', c_uint32),
+ ('SizeOfImage', c_uint32),
+ ('SizeOfHeaders', c_uint32),
+ ('CheckSum' , c_uint32),
+ ('Subsystem', c_uint16),
+ ('DllCharacteristics', c_uint16),
+ ('SizeOfStackReserve', c_uint32),
+ ('SizeOfStackCommit' , c_uint32),
+ ('SizeOfHeapReserve', c_uint32),
+ ('SizeOfHeapCommit' , c_uint32),
+ ('LoaderFlags' , c_uint32),
+ ('NumberOfRvaAndSizes', c_uint32),
+ ('DataDirectory', ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
+ ]
+
+class EFI_IMAGE_NT_HEADERS32(Structure):
+ _fields_ = [
+ ('Signature', c_uint32),
+ ('FileHeader', EFI_IMAGE_FILE_HEADER),
+ ('OptionalHeader', EFI_IMAGE_OPTIONAL_HEADER32)
+ ]
+
+
+class EFI_IMAGE_DIRECTORY_ENTRY:
+ EXPORT = 0
+ IMPORT = 1
+ RESOURCE = 2
+ EXCEPTION = 3
+ SECURITY = 4
+ BASERELOC = 5
+ DEBUG = 6
+ COPYRIGHT = 7
+ GLOBALPTR = 8
+ TLS = 9
+ LOAD_CONFIG = 10
+
class EFI_FV_FILETYPE:
ALL = 0x00
RAW = 0x01
@@ -431,26 +521,47 @@ class FirmwareDevice:
raise Exception("ERROR: Incorrect FV size in image !")
self.CheckFsp ()
-class TeImage:
- def __init__(self, offset, tedata):
- self.Offset = offset
- self.TeHdr = EFI_TE_IMAGE_HEADER.from_buffer (tedata, 0)
- self.TeData = tedata
+class PeTeImage:
+ def __init__(self, offset, data):
+ self.Offset = offset
+ tehdr = EFI_TE_IMAGE_HEADER.from_buffer (data, 0)
+ if tehdr.Signature == 'VZ': # TE image
+ self.TeHdr = tehdr
+ elif tehdr.Signature == 'MZ': # PE32 image
+ self.TeHdr = None
+ self.DosHdr = EFI_IMAGE_DOS_HEADER.from_buffer (data, 0)
+ self.PeHdr = EFI_IMAGE_NT_HEADERS32.from_buffer (data, self.DosHdr.e_lfanew)
+ if self.PeHdr.Signature != 0x4550:
+ raise Exception("ERROR: Invalid PE32 header !")
+ if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:
+ raise Exception("ERROR: Unsupported PE32 image !")
+ if self.PeHdr.OptionalHeader.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
+ raise Exception("ERROR: No relocation information available !")
+ self.Offset = offset
+ self.Data = data
self.RelocList = []
+ def IsTeImage(self):
+ return self.TeHdr is not None
+
def ParseReloc(self):
- rsize = self.TeHdr.DataDirectoryBaseReloc.Size
- roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
+ if self.IsTeImage():
+ rsize = self.TeHdr.DataDirectoryBaseReloc.Size
+ roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
+ else:
+ rsize = self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
+ roffset = self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].VirtualAddress
+
alignment = 4
offset = roffset
while offset < roffset + rsize:
offset = AlignPtr(offset, 4)
- blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.TeData, offset)
+ blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.Data, offset)
offset += sizeof(blkhdr)
# Read relocation type,offset pairs
rlen = blkhdr.BlockSize - sizeof(PE_RELOC_BLOCK_HEADER)
rnum = rlen/sizeof(c_uint16)
- rdata = (c_uint16 * rnum).from_buffer(self.TeData, offset)
+ rdata = (c_uint16 * rnum).from_buffer(self.Data, offset)
for each in rdata:
roff = each & 0xfff
rtype = each >> 12
@@ -459,7 +570,9 @@ class TeImage:
if rtype != 3: # IMAGE_REL_BASED_HIGHLOW
raise Exception("ERROR: Unsupported relocation type %d!" % rtype)
# Calculate the offset of the relocation
- aoff = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + blkhdr.PageRVA + roff
+ aoff = blkhdr.PageRVA + roff
+ if self.IsTeImage():
+ aoff += sizeof(self.TeHdr) - self.TeHdr.StrippedSize
self.RelocList.append((rtype, aoff))
offset += sizeof(rdata)
@@ -478,10 +591,17 @@ class TeImage:
else:
raise Exception('ERROR: Unknown relocation type %d !' % rtype)
- tehdr = self.TeHdr
- tehdr.ImageBase += delta
- offset = self.Offset
- fdbin[offset:offset+sizeof(tehdr)] = bytearray(tehdr)
+ if self.IsTeImage():
+ offset = self.Offset + EFI_TE_IMAGE_HEADER.ImageBase.offset
+ size = EFI_TE_IMAGE_HEADER.ImageBase.size
+ else:
+ offset = self.Offset + self.DosHdr.e_lfanew
+ offset += EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset
+ offset += EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset
+ size = EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size
+
+ value = Bytes2Val(fdbin[offset:offset+size]) + delta
+ fdbin[offset:offset+size] = Val2Bytes(value, size)
return count
@@ -588,28 +708,24 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
delta = newbase - oldbase
print "Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase)
- telist = []
+ imglist = []
for fvidx in fsp.FvIdxList:
fv = fd.FvList[fvidx]
for ffs in fv.FfsList:
for sec in ffs.SecList:
- if sec.SecHdr.Type == EFI_SECTION_TYPE.TE: # TE
+ if sec.SecHdr.Type in [EFI_SECTION_TYPE.TE, EFI_SECTION_TYPE.PE32]: # TE or PE32
offset = fd.Offset + fv.Offset + ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
- telist.append ((offset, len(sec.SecData) - sizeof(sec.SecHdr)))
- elif sec.SecHdr.Type == EFI_SECTION_TYPE.PE32: # PE
- raise Exception("ERROR: PE32 Section is not supported !")
+ imglist.append ((offset, len(sec.SecData) - sizeof(sec.SecHdr)))
fcount = 0
- tecount = 0
- for (teoffset, telen) in telist:
- tehdr = EFI_TE_IMAGE_HEADER.from_buffer (fd.FdData, teoffset)
- if 'VZ' != tehdr.Signature:
- raise Exception("ERROR: Invalid TE header !")
- te = TeImage(teoffset, fd.FdData[teoffset:teoffset + telen])
- te.ParseReloc()
- tecount += te.Rebase(delta, newfspbin)
- fcount += 1
- print " Patched %d entries in %d TE images." % (tecount, fcount)
+ pcount = 0
+ for (offset, length) in imglist:
+ img = PeTeImage(offset, fd.FdData[offset:offset + length])
+ img.ParseReloc()
+ pcount += img.Rebase(delta, newfspbin)
+ fcount += 1
+
+ print " Patched %d entries in %d TE/PE32 images." % (pcount, fcount)
(count, applied) = fsp.Patch(delta, newfspbin)
print " Patched %d entries using FSP patch table." % applied
--
1.9.5.msysgit.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support
2016-10-05 0:18 [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support Maurice Ma
@ 2016-10-05 16:53 ` Yarlagadda, Satya P
2016-10-07 13:13 ` Yao, Jiewen
1 sibling, 0 replies; 3+ messages in thread
From: Yarlagadda, Satya P @ 2016-10-05 16:53 UTC (permalink / raw)
To: Ma, Maurice, edk2-devel@lists.01.org; +Cc: Yao, Jiewen
Reviewed-by: Satya Yarlagadda <Satya.p.yarlagadda@intel.com>
-----Original Message-----
From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Maurice Ma
Sent: Wednesday, October 05, 2016 5:49 AM
To: edk2-devel@lists.01.org
Cc: Yao, Jiewen <jiewen.yao@intel.com>
Subject: [edk2] [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support
The current SplitFspBin.py can only support TE image format rebasing in an FSP binary. This patch adds PE32 image format rebasing support.
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Maurice Ma <maurice.ma@intel.com>
---
IntelFsp2Pkg/Tools/SplitFspBin.py | 174 +++++++++++++++++++++++++++++++-------
1 file changed, 145 insertions(+), 29 deletions(-)
diff --git a/IntelFsp2Pkg/Tools/SplitFspBin.py b/IntelFsp2Pkg/Tools/SplitFspBin.py
index ef759f0dc46a..e4c3aa6d0b28 100644
--- a/IntelFsp2Pkg/Tools/SplitFspBin.py
+++ b/IntelFsp2Pkg/Tools/SplitFspBin.py
@@ -159,12 +159,102 @@ class EFI_TE_IMAGE_HEADER(Structure):
('DataDirectoryDebug', EFI_IMAGE_DATA_DIRECTORY)
]
+class EFI_IMAGE_DOS_HEADER(Structure):
+ _fields_ = [
+ ('e_magic', c_uint16),
+ ('e_cblp', c_uint16),
+ ('e_cp', c_uint16),
+ ('e_crlc', c_uint16),
+ ('e_cparhdr', c_uint16),
+ ('e_minalloc', c_uint16),
+ ('e_maxalloc', c_uint16),
+ ('e_ss', c_uint16),
+ ('e_sp', c_uint16),
+ ('e_csum', c_uint16),
+ ('e_ip', c_uint16),
+ ('e_cs', c_uint16),
+ ('e_lfarlc', c_uint16),
+ ('e_ovno', c_uint16),
+ ('e_res', ARRAY(c_uint16, 4)),
+ ('e_oemid', c_uint16),
+ ('e_oeminfo', c_uint16),
+ ('e_res2', ARRAY(c_uint16, 10)),
+ ('e_lfanew', c_uint16)
+ ]
+
+class EFI_IMAGE_FILE_HEADER(Structure):
+ _fields_ = [
+ ('Machine', c_uint16),
+ ('NumberOfSections', c_uint16),
+ ('TimeDateStamp', c_uint32),
+ ('PointerToSymbolTable', c_uint32),
+ ('NumberOfSymbols', c_uint32),
+ ('SizeOfOptionalHeader', c_uint16),
+ ('Characteristics', c_uint16)
+ ]
+
class PE_RELOC_BLOCK_HEADER(Structure):
_fields_ = [
('PageRVA', c_uint32),
('BlockSize', c_uint32)
]
+class EFI_IMAGE_OPTIONAL_HEADER32(Structure):
+ _fields_ = [
+ ('Magic', c_uint16),
+ ('MajorLinkerVersion', c_uint8),
+ ('MinorLinkerVersion', c_uint8),
+ ('SizeOfCode', c_uint32),
+ ('SizeOfInitializedData', c_uint32),
+ ('SizeOfUninitializedData', c_uint32),
+ ('AddressOfEntryPoint', c_uint32),
+ ('BaseOfCode', c_uint32),
+ ('BaseOfData', c_uint32),
+ ('ImageBase', c_uint32),
+ ('SectionAlignment', c_uint32),
+ ('FileAlignment', c_uint32),
+ ('MajorOperatingSystemVersion', c_uint16),
+ ('MinorOperatingSystemVersion', c_uint16),
+ ('MajorImageVersion', c_uint16),
+ ('MinorImageVersion', c_uint16),
+ ('MajorSubsystemVersion', c_uint16),
+ ('MinorSubsystemVersion', c_uint16),
+ ('Win32VersionValue', c_uint32),
+ ('SizeOfImage', c_uint32),
+ ('SizeOfHeaders', c_uint32),
+ ('CheckSum' , c_uint32),
+ ('Subsystem', c_uint16),
+ ('DllCharacteristics', c_uint16),
+ ('SizeOfStackReserve', c_uint32),
+ ('SizeOfStackCommit' , c_uint32),
+ ('SizeOfHeapReserve', c_uint32),
+ ('SizeOfHeapCommit' , c_uint32),
+ ('LoaderFlags' , c_uint32),
+ ('NumberOfRvaAndSizes', c_uint32),
+ ('DataDirectory', ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
+ ]
+
+class EFI_IMAGE_NT_HEADERS32(Structure):
+ _fields_ = [
+ ('Signature', c_uint32),
+ ('FileHeader', EFI_IMAGE_FILE_HEADER),
+ ('OptionalHeader', EFI_IMAGE_OPTIONAL_HEADER32)
+ ]
+
+
+class EFI_IMAGE_DIRECTORY_ENTRY:
+ EXPORT = 0
+ IMPORT = 1
+ RESOURCE = 2
+ EXCEPTION = 3
+ SECURITY = 4
+ BASERELOC = 5
+ DEBUG = 6
+ COPYRIGHT = 7
+ GLOBALPTR = 8
+ TLS = 9
+ LOAD_CONFIG = 10
+
class EFI_FV_FILETYPE:
ALL = 0x00
RAW = 0x01
@@ -431,26 +521,47 @@ class FirmwareDevice:
raise Exception("ERROR: Incorrect FV size in image !")
self.CheckFsp ()
-class TeImage:
- def __init__(self, offset, tedata):
- self.Offset = offset
- self.TeHdr = EFI_TE_IMAGE_HEADER.from_buffer (tedata, 0)
- self.TeData = tedata
+class PeTeImage:
+ def __init__(self, offset, data):
+ self.Offset = offset
+ tehdr = EFI_TE_IMAGE_HEADER.from_buffer (data, 0)
+ if tehdr.Signature == 'VZ': # TE image
+ self.TeHdr = tehdr
+ elif tehdr.Signature == 'MZ': # PE32 image
+ self.TeHdr = None
+ self.DosHdr = EFI_IMAGE_DOS_HEADER.from_buffer (data, 0)
+ self.PeHdr = EFI_IMAGE_NT_HEADERS32.from_buffer (data, self.DosHdr.e_lfanew)
+ if self.PeHdr.Signature != 0x4550:
+ raise Exception("ERROR: Invalid PE32 header !")
+ if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:
+ raise Exception("ERROR: Unsupported PE32 image !")
+ if self.PeHdr.OptionalHeader.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
+ raise Exception("ERROR: No relocation information available !")
+ self.Offset = offset
+ self.Data = data
self.RelocList = []
+ def IsTeImage(self):
+ return self.TeHdr is not None
+
def ParseReloc(self):
- rsize = self.TeHdr.DataDirectoryBaseReloc.Size
- roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
+ if self.IsTeImage():
+ rsize = self.TeHdr.DataDirectoryBaseReloc.Size
+ roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
+ else:
+ rsize = self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC].Size
+ roffset =
+ self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASE
+ RELOC].VirtualAddress
+
alignment = 4
offset = roffset
while offset < roffset + rsize:
offset = AlignPtr(offset, 4)
- blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.TeData, offset)
+ blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.Data,
+ offset)
offset += sizeof(blkhdr)
# Read relocation type,offset pairs
rlen = blkhdr.BlockSize - sizeof(PE_RELOC_BLOCK_HEADER)
rnum = rlen/sizeof(c_uint16)
- rdata = (c_uint16 * rnum).from_buffer(self.TeData, offset)
+ rdata = (c_uint16 * rnum).from_buffer(self.Data, offset)
for each in rdata:
roff = each & 0xfff
rtype = each >> 12
@@ -459,7 +570,9 @@ class TeImage:
if rtype != 3: # IMAGE_REL_BASED_HIGHLOW
raise Exception("ERROR: Unsupported relocation type %d!" % rtype)
# Calculate the offset of the relocation
- aoff = sizeof(self.TeHdr) - self.TeHdr.StrippedSize + blkhdr.PageRVA + roff
+ aoff = blkhdr.PageRVA + roff
+ if self.IsTeImage():
+ aoff += sizeof(self.TeHdr) -
+ self.TeHdr.StrippedSize
self.RelocList.append((rtype, aoff))
offset += sizeof(rdata)
@@ -478,10 +591,17 @@ class TeImage:
else:
raise Exception('ERROR: Unknown relocation type %d !' % rtype)
- tehdr = self.TeHdr
- tehdr.ImageBase += delta
- offset = self.Offset
- fdbin[offset:offset+sizeof(tehdr)] = bytearray(tehdr)
+ if self.IsTeImage():
+ offset = self.Offset + EFI_TE_IMAGE_HEADER.ImageBase.offset
+ size = EFI_TE_IMAGE_HEADER.ImageBase.size
+ else:
+ offset = self.Offset + self.DosHdr.e_lfanew
+ offset += EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset
+ offset += EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset
+ size = EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size
+
+ value = Bytes2Val(fdbin[offset:offset+size]) + delta
+ fdbin[offset:offset+size] = Val2Bytes(value, size)
return count
@@ -588,28 +708,24 @@ def RebaseFspBin (FspBinary, FspComponent, FspBase, OutputDir, OutputFile):
delta = newbase - oldbase
print "Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldbase,newbase)
- telist = []
+ imglist = []
for fvidx in fsp.FvIdxList:
fv = fd.FvList[fvidx]
for ffs in fv.FfsList:
for sec in ffs.SecList:
- if sec.SecHdr.Type == EFI_SECTION_TYPE.TE: # TE
+ if sec.SecHdr.Type in [EFI_SECTION_TYPE.TE, EFI_SECTION_TYPE.PE32]: # TE or PE32
offset = fd.Offset + fv.Offset + ffs.Offset + sec.Offset + sizeof(sec.SecHdr)
- telist.append ((offset, len(sec.SecData) - sizeof(sec.SecHdr)))
- elif sec.SecHdr.Type == EFI_SECTION_TYPE.PE32: # PE
- raise Exception("ERROR: PE32 Section is not supported !")
+ imglist.append ((offset, len(sec.SecData) -
+ sizeof(sec.SecHdr)))
fcount = 0
- tecount = 0
- for (teoffset, telen) in telist:
- tehdr = EFI_TE_IMAGE_HEADER.from_buffer (fd.FdData, teoffset)
- if 'VZ' != tehdr.Signature:
- raise Exception("ERROR: Invalid TE header !")
- te = TeImage(teoffset, fd.FdData[teoffset:teoffset + telen])
- te.ParseReloc()
- tecount += te.Rebase(delta, newfspbin)
- fcount += 1
- print " Patched %d entries in %d TE images." % (tecount, fcount)
+ pcount = 0
+ for (offset, length) in imglist:
+ img = PeTeImage(offset, fd.FdData[offset:offset + length])
+ img.ParseReloc()
+ pcount += img.Rebase(delta, newfspbin)
+ fcount += 1
+
+ print " Patched %d entries in %d TE/PE32 images." % (pcount,
+ fcount)
(count, applied) = fsp.Patch(delta, newfspbin)
print " Patched %d entries using FSP patch table." % applied
--
1.9.5.msysgit.0
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support
2016-10-05 0:18 [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support Maurice Ma
2016-10-05 16:53 ` Yarlagadda, Satya P
@ 2016-10-07 13:13 ` Yao, Jiewen
1 sibling, 0 replies; 3+ messages in thread
From: Yao, Jiewen @ 2016-10-07 13:13 UTC (permalink / raw)
To: Ma, Maurice, edk2-devel@lists.01.org
Reviewed-by: Jiewen.yao@intel.com
> -----Original Message-----
> From: Ma, Maurice
> Sent: Wednesday, October 5, 2016 8:19 AM
> To: edk2-devel@lists.01.org
> Cc: Ma, Maurice <maurice.ma@intel.com>; Yao, Jiewen
> <jiewen.yao@intel.com>; Mudusuru, Giri P <giri.p.mudusuru@intel.com>
> Subject: [edk2] [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing
> support
>
> The current SplitFspBin.py can only support TE image format
> rebasing in an FSP binary. This patch adds PE32 image format
> rebasing support.
>
> Cc: Jiewen Yao <jiewen.yao@intel.com>
> Cc: Giri P Mudusuru <giri.p.mudusuru@intel.com>
> Contributed-under: TianoCore Contribution Agreement 1.0
> Signed-off-by: Maurice Ma <maurice.ma@intel.com>
> ---
> IntelFsp2Pkg/Tools/SplitFspBin.py | 174
> +++++++++++++++++++++++++++++++-------
> 1 file changed, 145 insertions(+), 29 deletions(-)
>
> diff --git a/IntelFsp2Pkg/Tools/SplitFspBin.py
> b/IntelFsp2Pkg/Tools/SplitFspBin.py
> index ef759f0dc46a..e4c3aa6d0b28 100644
> --- a/IntelFsp2Pkg/Tools/SplitFspBin.py
> +++ b/IntelFsp2Pkg/Tools/SplitFspBin.py
> @@ -159,12 +159,102 @@ class EFI_TE_IMAGE_HEADER(Structure):
> ('DataDirectoryDebug', EFI_IMAGE_DATA_DIRECTORY)
> ]
>
> +class EFI_IMAGE_DOS_HEADER(Structure):
> + _fields_ = [
> + ('e_magic', c_uint16),
> + ('e_cblp', c_uint16),
> + ('e_cp', c_uint16),
> + ('e_crlc', c_uint16),
> + ('e_cparhdr', c_uint16),
> + ('e_minalloc', c_uint16),
> + ('e_maxalloc', c_uint16),
> + ('e_ss', c_uint16),
> + ('e_sp', c_uint16),
> + ('e_csum', c_uint16),
> + ('e_ip', c_uint16),
> + ('e_cs', c_uint16),
> + ('e_lfarlc', c_uint16),
> + ('e_ovno', c_uint16),
> + ('e_res', ARRAY(c_uint16, 4)),
> + ('e_oemid', c_uint16),
> + ('e_oeminfo', c_uint16),
> + ('e_res2', ARRAY(c_uint16, 10)),
> + ('e_lfanew', c_uint16)
> + ]
> +
> +class EFI_IMAGE_FILE_HEADER(Structure):
> + _fields_ = [
> + ('Machine', c_uint16),
> + ('NumberOfSections', c_uint16),
> + ('TimeDateStamp', c_uint32),
> + ('PointerToSymbolTable', c_uint32),
> + ('NumberOfSymbols', c_uint32),
> + ('SizeOfOptionalHeader', c_uint16),
> + ('Characteristics', c_uint16)
> + ]
> +
> class PE_RELOC_BLOCK_HEADER(Structure):
> _fields_ = [
> ('PageRVA', c_uint32),
> ('BlockSize', c_uint32)
> ]
>
> +class EFI_IMAGE_OPTIONAL_HEADER32(Structure):
> + _fields_ = [
> + ('Magic', c_uint16),
> + ('MajorLinkerVersion', c_uint8),
> + ('MinorLinkerVersion', c_uint8),
> + ('SizeOfCode', c_uint32),
> + ('SizeOfInitializedData', c_uint32),
> + ('SizeOfUninitializedData', c_uint32),
> + ('AddressOfEntryPoint', c_uint32),
> + ('BaseOfCode', c_uint32),
> + ('BaseOfData', c_uint32),
> + ('ImageBase', c_uint32),
> + ('SectionAlignment', c_uint32),
> + ('FileAlignment', c_uint32),
> + ('MajorOperatingSystemVersion', c_uint16),
> + ('MinorOperatingSystemVersion', c_uint16),
> + ('MajorImageVersion', c_uint16),
> + ('MinorImageVersion', c_uint16),
> + ('MajorSubsystemVersion', c_uint16),
> + ('MinorSubsystemVersion', c_uint16),
> + ('Win32VersionValue', c_uint32),
> + ('SizeOfImage', c_uint32),
> + ('SizeOfHeaders', c_uint32),
> + ('CheckSum' , c_uint32),
> + ('Subsystem', c_uint16),
> + ('DllCharacteristics', c_uint16),
> + ('SizeOfStackReserve', c_uint32),
> + ('SizeOfStackCommit' , c_uint32),
> + ('SizeOfHeapReserve', c_uint32),
> + ('SizeOfHeapCommit' , c_uint32),
> + ('LoaderFlags' , c_uint32),
> + ('NumberOfRvaAndSizes', c_uint32),
> + ('DataDirectory',
> ARRAY(EFI_IMAGE_DATA_DIRECTORY, 16))
> + ]
> +
> +class EFI_IMAGE_NT_HEADERS32(Structure):
> + _fields_ = [
> + ('Signature', c_uint32),
> + ('FileHeader', EFI_IMAGE_FILE_HEADER),
> + ('OptionalHeader', EFI_IMAGE_OPTIONAL_HEADER32)
> + ]
> +
> +
> +class EFI_IMAGE_DIRECTORY_ENTRY:
> + EXPORT = 0
> + IMPORT = 1
> + RESOURCE = 2
> + EXCEPTION = 3
> + SECURITY = 4
> + BASERELOC = 5
> + DEBUG = 6
> + COPYRIGHT = 7
> + GLOBALPTR = 8
> + TLS = 9
> + LOAD_CONFIG = 10
> +
> class EFI_FV_FILETYPE:
> ALL = 0x00
> RAW = 0x01
> @@ -431,26 +521,47 @@ class FirmwareDevice:
> raise Exception("ERROR: Incorrect FV size in
> image !")
> self.CheckFsp ()
>
> -class TeImage:
> - def __init__(self, offset, tedata):
> - self.Offset = offset
> - self.TeHdr = EFI_TE_IMAGE_HEADER.from_buffer (tedata, 0)
> - self.TeData = tedata
> +class PeTeImage:
> + def __init__(self, offset, data):
> + self.Offset = offset
> + tehdr = EFI_TE_IMAGE_HEADER.from_buffer (data, 0)
> + if tehdr.Signature == 'VZ': # TE image
> + self.TeHdr = tehdr
> + elif tehdr.Signature == 'MZ': # PE32 image
> + self.TeHdr = None
> + self.DosHdr = EFI_IMAGE_DOS_HEADER.from_buffer (data,
> 0)
> + self.PeHdr = EFI_IMAGE_NT_HEADERS32.from_buffer
> (data, self.DosHdr.e_lfanew)
> + if self.PeHdr.Signature != 0x4550:
> + raise Exception("ERROR: Invalid PE32 header !")
> + if self.PeHdr.FileHeader.SizeOfOptionalHeader <
> EFI_IMAGE_OPTIONAL_HEADER32.DataDirectory.offset:
> + raise Exception("ERROR: Unsupported PE32 image !")
> + if self.PeHdr.OptionalHeader.NumberOfRvaAndSizes <=
> EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC:
> + raise Exception("ERROR: No relocation information
> available !")
> + self.Offset = offset
> + self.Data = data
> self.RelocList = []
>
> + def IsTeImage(self):
> + return self.TeHdr is not None
> +
> def ParseReloc(self):
> - rsize = self.TeHdr.DataDirectoryBaseReloc.Size
> - roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize +
> self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
> + if self.IsTeImage():
> + rsize = self.TeHdr.DataDirectoryBaseReloc.Size
> + roffset = sizeof(self.TeHdr) - self.TeHdr.StrippedSize +
> self.TeHdr.DataDirectoryBaseReloc.VirtualAddress
> + else:
> + rsize =
> self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BA
> SERELOC].Size
> + roffset =
> self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BA
> SERELOC].VirtualAddress
> +
> alignment = 4
> offset = roffset
> while offset < roffset + rsize:
> offset = AlignPtr(offset, 4)
> - blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.TeData,
> offset)
> + blkhdr = PE_RELOC_BLOCK_HEADER.from_buffer(self.Data,
> offset)
> offset += sizeof(blkhdr)
> # Read relocation type,offset pairs
> rlen = blkhdr.BlockSize -
> sizeof(PE_RELOC_BLOCK_HEADER)
> rnum = rlen/sizeof(c_uint16)
> - rdata = (c_uint16 * rnum).from_buffer(self.TeData, offset)
> + rdata = (c_uint16 * rnum).from_buffer(self.Data, offset)
> for each in rdata:
> roff = each & 0xfff
> rtype = each >> 12
> @@ -459,7 +570,9 @@ class TeImage:
> if rtype != 3: # IMAGE_REL_BASED_HIGHLOW
> raise Exception("ERROR: Unsupported relocation
> type %d!" % rtype)
> # Calculate the offset of the relocation
> - aoff = sizeof(self.TeHdr) - self.TeHdr.StrippedSize +
> blkhdr.PageRVA + roff
> + aoff = blkhdr.PageRVA + roff
> + if self.IsTeImage():
> + aoff += sizeof(self.TeHdr) - self.TeHdr.StrippedSize
> self.RelocList.append((rtype, aoff))
> offset += sizeof(rdata)
>
> @@ -478,10 +591,17 @@ class TeImage:
> else:
> raise Exception('ERROR: Unknown relocation
> type %d !' % rtype)
>
> - tehdr = self.TeHdr
> - tehdr.ImageBase += delta
> - offset = self.Offset
> - fdbin[offset:offset+sizeof(tehdr)] = bytearray(tehdr)
> + if self.IsTeImage():
> + offset = self.Offset +
> EFI_TE_IMAGE_HEADER.ImageBase.offset
> + size = EFI_TE_IMAGE_HEADER.ImageBase.size
> + else:
> + offset = self.Offset + self.DosHdr.e_lfanew
> + offset += EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset
> + offset +=
> EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset
> + size =
> EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size
> +
> + value = Bytes2Val(fdbin[offset:offset+size]) + delta
> + fdbin[offset:offset+size] = Val2Bytes(value, size)
>
> return count
>
> @@ -588,28 +708,24 @@ def RebaseFspBin (FspBinary, FspComponent,
> FspBase, OutputDir, OutputFile):
> delta = newbase - oldbase
> print "Rebase FSP-%c from 0x%08X to 0x%08X:" %
> (ftype.upper(),oldbase,newbase)
>
> - telist = []
> + imglist = []
> for fvidx in fsp.FvIdxList:
> fv = fd.FvList[fvidx]
> for ffs in fv.FfsList:
> for sec in ffs.SecList:
> - if sec.SecHdr.Type == EFI_SECTION_TYPE.TE: #
> TE
> + if sec.SecHdr.Type in [EFI_SECTION_TYPE.TE,
> EFI_SECTION_TYPE.PE32]: # TE or PE32
> offset = fd.Offset + fv.Offset + ffs.Offset +
> sec.Offset + sizeof(sec.SecHdr)
> - telist.append ((offset, len(sec.SecData) -
> sizeof(sec.SecHdr)))
> - elif sec.SecHdr.Type == EFI_SECTION_TYPE.PE32: #
> PE
> - raise Exception("ERROR: PE32 Section is not
> supported !")
> + imglist.append ((offset, len(sec.SecData) -
> sizeof(sec.SecHdr)))
>
> fcount = 0
> - tecount = 0
> - for (teoffset, telen) in telist:
> - tehdr = EFI_TE_IMAGE_HEADER.from_buffer (fd.FdData,
> teoffset)
> - if 'VZ' != tehdr.Signature:
> - raise Exception("ERROR: Invalid TE header !")
> - te = TeImage(teoffset, fd.FdData[teoffset:teoffset + telen])
> - te.ParseReloc()
> - tecount += te.Rebase(delta, newfspbin)
> - fcount += 1
> - print " Patched %d entries in %d TE images." % (tecount, fcount)
> + pcount = 0
> + for (offset, length) in imglist:
> + img = PeTeImage(offset, fd.FdData[offset:offset + length])
> + img.ParseReloc()
> + pcount += img.Rebase(delta, newfspbin)
> + fcount += 1
> +
> + print " Patched %d entries in %d TE/PE32 images." % (pcount,
> fcount)
>
> (count, applied) = fsp.Patch(delta, newfspbin)
> print " Patched %d entries using FSP patch table." % applied
> --
> 1.9.5.msysgit.0
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-10-07 13:13 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-10-05 0:18 [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support Maurice Ma
2016-10-05 16:53 ` Yarlagadda, Satya P
2016-10-07 13:13 ` Yao, Jiewen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox