From: "Yao, Jiewen" <jiewen.yao@intel.com>
To: "Ma, Maurice" <maurice.ma@intel.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>
Subject: Re: [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support
Date: Fri, 7 Oct 2016 13:13:40 +0000 [thread overview]
Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503869DA38@shsmsx102.ccr.corp.intel.com> (raw)
In-Reply-To: <417c05153e8c89bfc8b520507c80e4b09bb87c4e.1475626650.git.maurice.ma@intel.com>
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
prev parent reply other threads:[~2016-10-07 13:13 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
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 message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=74D8A39837DF1E4DA445A8C0B3885C503869DA38@shsmsx102.ccr.corp.intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox