From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga05.intel.com (mga05.intel.com [192.55.52.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id 70CB11A1E05 for ; Fri, 7 Oct 2016 06:13:43 -0700 (PDT) Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga105.fm.intel.com with ESMTP; 07 Oct 2016 06:13:43 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,308,1473145200"; d="scan'208";a="1067421206" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by fmsmga002.fm.intel.com with ESMTP; 07 Oct 2016 06:13:43 -0700 Received: from fmsmsx112.amr.corp.intel.com (10.18.116.6) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.248.2; Fri, 7 Oct 2016 06:13:42 -0700 Received: from shsmsx103.ccr.corp.intel.com (10.239.4.69) by FMSMSX112.amr.corp.intel.com (10.18.116.6) with Microsoft SMTP Server (TLS) id 14.3.248.2; Fri, 7 Oct 2016 06:13:42 -0700 Received: from shsmsx102.ccr.corp.intel.com ([169.254.2.15]) by SHSMSX103.ccr.corp.intel.com ([169.254.4.234]) with mapi id 14.03.0248.002; Fri, 7 Oct 2016 21:13:40 +0800 From: "Yao, Jiewen" To: "Ma, Maurice" , "edk2-devel@lists.01.org" Thread-Topic: [edk2] [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support Thread-Index: AQHSHp4ZpdcHlxeCEkWjM0IGDXWKDKCc+/Wg Date: Fri, 7 Oct 2016 13:13:40 +0000 Message-ID: <74D8A39837DF1E4DA445A8C0B3885C503869DA38@shsmsx102.ccr.corp.intel.com> References: <417c05153e8c89bfc8b520507c80e4b09bb87c4e.1475626650.git.maurice.ma@intel.com> In-Reply-To: <417c05153e8c89bfc8b520507c80e4b09bb87c4e.1475626650.git.maurice.ma@intel.com> Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Subject: Re: [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 07 Oct 2016 13:13:43 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable 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 ; Yao, Jiewen > ; Mudusuru, Giri P > Subject: [edk2] [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing > support >=20 > The current SplitFspBin.py can only support TE image format > rebasing in an FSP binary. This patch adds PE32 image format > rebasing support. >=20 > Cc: Jiewen Yao > Cc: Giri P Mudusuru > Contributed-under: TianoCore Contribution Agreement 1.0 > Signed-off-by: Maurice Ma > --- > IntelFsp2Pkg/Tools/SplitFspBin.py | 174 > +++++++++++++++++++++++++++++++------- > 1 file changed, 145 insertions(+), 29 deletions(-) >=20 > 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) > ] >=20 > +class EFI_IMAGE_DOS_HEADER(Structure): > + _fields_ =3D [ > + ('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_ =3D [ > + ('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_ =3D [ > ('PageRVA', c_uint32), > ('BlockSize', c_uint32) > ] >=20 > +class EFI_IMAGE_OPTIONAL_HEADER32(Structure): > + _fields_ =3D [ > + ('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_ =3D [ > + ('Signature', c_uint32), > + ('FileHeader', EFI_IMAGE_FILE_HEADER), > + ('OptionalHeader', EFI_IMAGE_OPTIONAL_HEADER32) > + ] > + > + > +class EFI_IMAGE_DIRECTORY_ENTRY: > + EXPORT =3D 0 > + IMPORT =3D 1 > + RESOURCE =3D 2 > + EXCEPTION =3D 3 > + SECURITY =3D 4 > + BASERELOC =3D 5 > + DEBUG =3D 6 > + COPYRIGHT =3D 7 > + GLOBALPTR =3D 8 > + TLS =3D 9 > + LOAD_CONFIG =3D 10 > + > class EFI_FV_FILETYPE: > ALL =3D 0x00 > RAW =3D 0x01 > @@ -431,26 +521,47 @@ class FirmwareDevice: > raise Exception("ERROR: Incorrect FV size in > image !") > self.CheckFsp () >=20 > -class TeImage: > - def __init__(self, offset, tedata): > - self.Offset =3D offset > - self.TeHdr =3D EFI_TE_IMAGE_HEADER.from_buffer (tedata, 0) > - self.TeData =3D tedata > +class PeTeImage: > + def __init__(self, offset, data): > + self.Offset =3D offset > + tehdr =3D EFI_TE_IMAGE_HEADER.from_buffer (data, 0) > + if tehdr.Signature =3D=3D 'VZ': # TE image > + self.TeHdr =3D tehdr > + elif tehdr.Signature =3D=3D 'MZ': # PE32 image > + self.TeHdr =3D None > + self.DosHdr =3D EFI_IMAGE_DOS_HEADER.from_buffer (data, > 0) > + self.PeHdr =3D EFI_IMAGE_NT_HEADERS32.from_buffer > (data, self.DosHdr.e_lfanew) > + if self.PeHdr.Signature !=3D 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 <=3D > EFI_IMAGE_DIRECTORY_ENTRY.BASERELOC: > + raise Exception("ERROR: No relocation information > available !") > + self.Offset =3D offset > + self.Data =3D data > self.RelocList =3D [] >=20 > + def IsTeImage(self): > + return self.TeHdr is not None > + > def ParseReloc(self): > - rsize =3D self.TeHdr.DataDirectoryBaseReloc.Size > - roffset =3D sizeof(self.TeHdr) - self.TeHdr.StrippedSize + > self.TeHdr.DataDirectoryBaseReloc.VirtualAddress > + if self.IsTeImage(): > + rsize =3D self.TeHdr.DataDirectoryBaseReloc.Size > + roffset =3D sizeof(self.TeHdr) - self.TeHdr.StrippedSize + > self.TeHdr.DataDirectoryBaseReloc.VirtualAddress > + else: > + rsize =3D > self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BA > SERELOC].Size > + roffset =3D > self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BA > SERELOC].VirtualAddress > + > alignment =3D 4 > offset =3D roffset > while offset < roffset + rsize: > offset =3D AlignPtr(offset, 4) > - blkhdr =3D PE_RELOC_BLOCK_HEADER.from_buffer(self.TeData, > offset) > + blkhdr =3D PE_RELOC_BLOCK_HEADER.from_buffer(self.Data, > offset) > offset +=3D sizeof(blkhdr) > # Read relocation type,offset pairs > rlen =3D blkhdr.BlockSize - > sizeof(PE_RELOC_BLOCK_HEADER) > rnum =3D rlen/sizeof(c_uint16) > - rdata =3D (c_uint16 * rnum).from_buffer(self.TeData, offset) > + rdata =3D (c_uint16 * rnum).from_buffer(self.Data, offset) > for each in rdata: > roff =3D each & 0xfff > rtype =3D each >> 12 > @@ -459,7 +570,9 @@ class TeImage: > if rtype !=3D 3: # IMAGE_REL_BASED_HIGHLOW > raise Exception("ERROR: Unsupported relocation > type %d!" % rtype) > # Calculate the offset of the relocation > - aoff =3D sizeof(self.TeHdr) - self.TeHdr.StrippedSize + > blkhdr.PageRVA + roff > + aoff =3D blkhdr.PageRVA + roff > + if self.IsTeImage(): > + aoff +=3D sizeof(self.TeHdr) - self.TeHdr.StrippedSi= ze > self.RelocList.append((rtype, aoff)) > offset +=3D sizeof(rdata) >=20 > @@ -478,10 +591,17 @@ class TeImage: > else: > raise Exception('ERROR: Unknown relocation > type %d !' % rtype) >=20 > - tehdr =3D self.TeHdr > - tehdr.ImageBase +=3D delta > - offset =3D self.Offset > - fdbin[offset:offset+sizeof(tehdr)] =3D bytearray(tehdr) > + if self.IsTeImage(): > + offset =3D self.Offset + > EFI_TE_IMAGE_HEADER.ImageBase.offset > + size =3D EFI_TE_IMAGE_HEADER.ImageBase.size > + else: > + offset =3D self.Offset + self.DosHdr.e_lfanew > + offset +=3D EFI_IMAGE_NT_HEADERS32.OptionalHeader.offset > + offset +=3D > EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.offset > + size =3D > EFI_IMAGE_OPTIONAL_HEADER32.ImageBase.size > + > + value =3D Bytes2Val(fdbin[offset:offset+size]) + delta > + fdbin[offset:offset+size] =3D Val2Bytes(value, size) >=20 > return count >=20 > @@ -588,28 +708,24 @@ def RebaseFspBin (FspBinary, FspComponent, > FspBase, OutputDir, OutputFile): > delta =3D newbase - oldbase > print "Rebase FSP-%c from 0x%08X to 0x%08X:" % > (ftype.upper(),oldbase,newbase) >=20 > - telist =3D [] > + imglist =3D [] > for fvidx in fsp.FvIdxList: > fv =3D fd.FvList[fvidx] > for ffs in fv.FfsList: > for sec in ffs.SecList: > - if sec.SecHdr.Type =3D=3D EFI_SECTION_TYPE.TE: # > TE > + if sec.SecHdr.Type in [EFI_SECTION_TYPE.TE, > EFI_SECTION_TYPE.PE32]: # TE or PE32 > offset =3D fd.Offset + fv.Offset + ffs.Offset + > sec.Offset + sizeof(sec.SecHdr) > - telist.append ((offset, len(sec.SecData) - > sizeof(sec.SecHdr))) > - elif sec.SecHdr.Type =3D=3D EFI_SECTION_TYPE.PE32: # > PE > - raise Exception("ERROR: PE32 Section is not > supported !") > + imglist.append ((offset, len(sec.SecData) - > sizeof(sec.SecHdr))) >=20 > fcount =3D 0 > - tecount =3D 0 > - for (teoffset, telen) in telist: > - tehdr =3D EFI_TE_IMAGE_HEADER.from_buffer (fd.FdData, > teoffset) > - if 'VZ' !=3D tehdr.Signature: > - raise Exception("ERROR: Invalid TE header !") > - te =3D TeImage(teoffset, fd.FdData[teoffset:teoffset + telen= ]) > - te.ParseReloc() > - tecount +=3D te.Rebase(delta, newfspbin) > - fcount +=3D 1 > - print " Patched %d entries in %d TE images." % (tecount, fcount= ) > + pcount =3D 0 > + for (offset, length) in imglist: > + img =3D PeTeImage(offset, fd.FdData[offset:offset + length]) > + img.ParseReloc() > + pcount +=3D img.Rebase(delta, newfspbin) > + fcount +=3D 1 > + > + print " Patched %d entries in %d TE/PE32 images." % (pcount, > fcount) >=20 > (count, applied) =3D fsp.Patch(delta, newfspbin) > print " Patched %d entries using FSP patch table." % applied > -- > 1.9.5.msysgit.0