From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1 with cipher CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D83411A1ED6 for ; Wed, 5 Oct 2016 09:53:10 -0700 (PDT) Received: from orsmga004.jf.intel.com ([10.7.209.38]) by fmsmga103.fm.intel.com with ESMTP; 05 Oct 2016 09:53:10 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.31,449,1473145200"; d="scan'208";a="16974772" Received: from fmsmsx107.amr.corp.intel.com ([10.18.124.205]) by orsmga004.jf.intel.com with ESMTP; 05 Oct 2016 09:53:10 -0700 Received: from fmsmsx120.amr.corp.intel.com (10.18.124.208) by fmsmsx107.amr.corp.intel.com (10.18.124.205) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 5 Oct 2016 09:53:09 -0700 Received: from bgsmsx154.gar.corp.intel.com (10.224.48.47) by fmsmsx120.amr.corp.intel.com (10.18.124.208) with Microsoft SMTP Server (TLS) id 14.3.248.2; Wed, 5 Oct 2016 09:53:09 -0700 Received: from bgsmsx103.gar.corp.intel.com ([169.254.4.251]) by BGSMSX154.gar.corp.intel.com ([169.254.7.140]) with mapi id 14.03.0248.002; Wed, 5 Oct 2016 22:23:06 +0530 From: "Yarlagadda, Satya P" To: "Ma, Maurice" , "edk2-devel@lists.01.org" CC: "Yao, Jiewen" Thread-Topic: [edk2] [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing support Thread-Index: AQHSHp4el4UhquAg5UaoRZSnifYZaKCaE+fQ Date: Wed, 5 Oct 2016 16:53:06 +0000 Message-ID: References: <417c05153e8c89bfc8b520507c80e4b09bb87c4e.1475626650.git.maurice.ma@intel.com> In-Reply-To: <417c05153e8c89bfc8b520507c80e4b09bb87c4e.1475626650.git.maurice.ma@intel.com> Accept-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [10.223.10.10] 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: Wed, 05 Oct 2016 16:53:11 -0000 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Reviewed-by: Satya Yarlagadda -----Original Message----- From: edk2-devel [mailto:edk2-devel-bounces@lists.01.org] On Behalf Of Maur= ice Ma Sent: Wednesday, October 05, 2016 5:49 AM To: edk2-devel@lists.01.org Cc: Yao, Jiewen Subject: [edk2] [PATCH] IntelFsp2Pkg/Tools: Add PE32 section rebasing suppo= rt 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 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(-) diff --git a/IntelFsp2Pkg/Tools/SplitFspBin.py b/IntelFsp2Pkg/Tools/SplitFs= pBin.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, sel= f.DosHdr.e_lfanew) + if self.PeHdr.Signature !=3D 0x4550: + raise Exception("ERROR: Invalid PE32 header !") + if self.PeHdr.FileHeader.SizeOfOptionalHeader < EFI_IMAGE_OPTI= ONAL_HEADER32.DataDirectory.offset: + raise Exception("ERROR: Unsupported PE32 image !") + if self.PeHdr.OptionalHeader.NumberOfRvaAndSizes <=3D EFI_IMAG= E_DIRECTORY_ENTRY.BASERELOC: + raise Exception("ERROR: No relocation information availabl= e !") + 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 + sel= f.TeHdr.DataDirectoryBaseReloc.VirtualAddress + else: + rsize =3D self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_= DIRECTORY_ENTRY.BASERELOC].Size + roffset =3D=20 + self.PeHdr.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY.BASE + RELOC].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, offs= et) + blkhdr =3D PE_RELOC_BLOCK_HEADER.from_buffer(self.Data,=20 + 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 + bl= khdr.PageRVA + roff + aoff =3D blkhdr.PageRVA + roff + if self.IsTeImage(): + aoff +=3D sizeof(self.TeHdr) -=20 + self.TeHdr.StrippedSize self.RelocList.append((rtype, aoff)) offset +=3D sizeof(rdata) =20 @@ -478,10 +591,17 @@ class TeImage: else: raise Exception('ERROR: Unknown relocation type %d !' % rt= ype) =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, O= utputDir, OutputFile): delta =3D newbase - oldbase print "Rebase FSP-%c from 0x%08X to 0x%08X:" % (ftype.upper(),oldb= ase,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_SECTIO= N_TYPE.PE32]: # TE or PE32 offset =3D fd.Offset + fv.Offset + ffs.Offset + se= c.Offset + sizeof(sec.SecHdr) - telist.append ((offset, len(sec.SecData) - sizeof(= sec.SecHdr))) - elif sec.SecHdr.Type =3D=3D EFI_SECTION_TYPE.PE32: # P= E - raise Exception("ERROR: PE32 Section is not suppor= ted !") + imglist.append ((offset, len(sec.SecData) -=20 + 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,=20 + fcount) =20 (count, applied) =3D 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