From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from linux.microsoft.com (linux.microsoft.com [13.77.154.182]) by mx.groups.io with SMTP id smtpd.web09.18473.1643228316450209083 for ; Wed, 26 Jan 2022 12:18:36 -0800 Authentication-Results: mx.groups.io; dkim=fail reason="body hash did not verify" header.i=@linux.microsoft.com header.s=default header.b=T77/bdk2; spf=pass (domain: linux.microsoft.com, ip: 13.77.154.182, mailfrom: mikuback@linux.microsoft.com) Received: from [10.0.0.19] (c-73-27-179-174.hsd1.fl.comcast.net [73.27.179.174]) by linux.microsoft.com (Postfix) with ESMTPSA id D3F0020B6C61; Wed, 26 Jan 2022 12:18:34 -0800 (PST) DKIM-Filter: OpenDKIM Filter v2.11.0 linux.microsoft.com D3F0020B6C61 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux.microsoft.com; s=default; t=1643228315; bh=Z4yXkCRvTwAFRT6bVWQvWJeJ18PymV1qKuPO7rJRMEU=; h=Date:Subject:To:Cc:References:From:In-Reply-To:From; b=T77/bdk2eHkSpD9W25PZGcMscwExVJKB0vrggLJSrnGorFlrdDWyzjv3pzt3o5X2C zA4SDu0v5Mze94i++0YRBouwvkN/bjHgAG879dk7C2Mf061Ip92jPG2KJ9HfaLpmaU Z1lcRYA9z3Xi5qjYE30jP8pHfIGqVNwdUyygpPA0= Message-ID: Date: Wed, 26 Jan 2022 15:18:33 -0500 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Thunderbird/91.5.0 Subject: Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF To: "Huang, Li-Xia" , Michael Kubacki , "devel@edk2.groups.io" , "Gao, Liming" , "Feng, Bob C" Cc: "Chen, Christine" , "Wu, Yidong" , "Xu, Wei6" , "You, Benjamin" References: <20220112074423.5075-1-lisa.huang@intel.com> <002001d80c2b$150f2230$3f2d6690$@byosoft.com.cn> From: "Michael Kubacki" In-Reply-To: Content-Language: en-US Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: quoted-printable Are you referring to "static data"? If so, no. That is allocated at boot=20 time and placed into the appropriate handler information structures. The items in the export table for a given PRM Module are: 1. PRM handler count 2. Platform GUID (automatically applied from the DSC=20 EDKII_DSC_PLATFORM_GUID) (https://bugzilla.tianocore.org/show_bug.cgi?id=3D2969) 3. The PRM Module GUID 4. A list of PRM handler GUID<->PRM handler names (used by FW discovery to map handler in export to GUID entry in the=20 PRMT it produces) https://github.com/tianocore/edk2-staging/blob/PlatformRuntimeMechanism/Prm= Pkg/Include/PrmExportDescriptor.h Thanks, Michael On 1/26/2022 3:16 AM, Huang, Li-Xia wrote: > Hi Michael, >=20 > Sure, I will include you if any update on PRM functionality. >=20 > BTW, I have a question about InitializedData, does it include export sect= ion or not? Thanks. >=20 > Regards, > Lisa >=20 > -----Original Message----- > From: Michael Kubacki > Sent: 2022=E5=B9=B41=E6=9C=8822=E6=97=A5 10:50 > To: devel@edk2.groups.io; Huang, Li-Xia ; Gao, Limi= ng ; Feng, Bob C > Cc: Chen, Christine ; Wu, Yidong ; Xu, Wei6 ; You, Benjamin ; = mikuback@linux.microsoft.com > Subject: Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export t= able in PE-COFF >=20 > Hi Lisa, >=20 > Thank you for contributing this. Please include me on functionality relat= ed to PRM. >=20 > I was using the PRM_EXPORT_API macro > (https://github.com/tianocore/edk2-staging/blob/9da8abf66505d8ff636aaecc4= 29a5237ce226650/PrmPkg/Include/Prm.h#L17) > to support this on MS toolchain. >=20 > It looks like this is to add similar functionality for ELF binaries using= GenFw? >=20 > Thanks, > Michael >=20 > On 1/18/2022 1:19 AM, Huang, Li-Xia wrote: >> Hi Liming, >> >> Thanks for your feedback. >> >> I have added some detail in BZ. =F0=9F=98=8A >> >> https://bugzilla.tianocore.org/show_bug.cgi?id=3D3802#add_comment >> >> >> Regards, >> >> Lisa >> >> *From:*gaoliming >> *Sent:* 2022=E5=B9=B41=E6=9C=8818=E6=97=A513:20 >> *To:* devel@edk2.groups.io; Huang, Li-Xia ; >> Feng, Bob C >> *Cc:* Chen, Christine ; Wu, Yidong >> ; Xu, Wei6 ; You, Benjamin >> >> *Subject:* =E5=9B=9E=E5=A4=8D: [edk2-devel][PATCH] BaseTools/GenFw: Enha= nce to add >> export table in PE-COFF >> >> Lisa: >> >> =C2=A0Can you give more background about PRM usage? What new usage >> requires RPM? Can you add the detail in BZ? >> >> Thanks >> >> Liming >> >> *=E5=8F=91=E4=BB=B6=E4=BA=BA**:*devel@edk2.groups.io >> > > *=E4=BB=A3=E8=A1=A8 *Huang, Li-Xia >> *=E5=8F=91=E9=80=81=E6=97=B6=E9=97=B4:* 2022=E5=B9=B41=E6=9C=8817=E6=97= =A5 11:09 >> *=E6=94=B6=E4=BB=B6=E4=BA=BA:* Feng, Bob C > >; devel@edk2.groups.io >> >> *=E6=8A=84=E9=80=81:* Gao, Liming > >; Chen, Christine >> >; Wu, Yidong >> >; Xu, Wei6 >> >; You, Benjamin >> > >> *=E4=B8=BB=E9=A2=98:* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance t= o add export >> table in PE-COFF >> >> Hi Bob, >> >> Thanks for your comments. >> >> 1.=C2=A0 I will add the help information for "--PRM"; >> >> 2. >> >> @@ -750,7 +818,7 @@ ScanSections64 ( >> >> =C2=A0=C2=A0=C2=A0=C2=A0 if (shdr->sh_addralign <=3D mCoffAlignment) { >> >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 continue; >> >> =C2=A0=C2=A0=C2=A0=C2=A0 } >> >> -=C2=A0=C2=A0=C2=A0 if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsr= cShdr(shdr)) >> { >> >> +=C2=A0=C2=A0=C2=A0 if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsr= cShdr(shdr) >> +|| >> IsSymbolShdr(shdr)) { >> >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mCoffAlignment =3D (UINT32)shdr->= sh_addralign; >> >> =C2=A0=C2=A0=C2=A0=C2=A0 } >> >> =C2=A0=C2=A0 } >> >> 1) Above change is to Set mCoffAlignment to the maximum alignment of >> the input sections including symbol section. >> >> =C2=A0=C2=A0=C2=A0=C2=A0The symbol section will only exist with below = change, so it >> should have no effect to other drivers. >> >> build_rule.template: >> >> =C2=A0=C2=A0=C2=A0 >> >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 $(CP) ${src} $(DEBUG_DIR)(+= )$(MODULE_NAME).debug >> >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 #$(OBJCOPY) --strip-unneede= d -R .eh_frame ${src} >> >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 $(OBJCOPY) $(OBJCOPY_STRIPF= LAG) ${src} >> >> tools_def.template: >> >> *_*_*_OBJCOPY_STRIPFLAG=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 =3D --strip-unneeded -R .eh_frame >> >> PrmAddrTransDsm.inf: >> >> [BuildOptions.common] >> >> ... >> >> =C2=A0 GCC: *_*_*_OBJCOPY_STRIPFLAG =3D=3D -R .eh_frame >> >> 2) For PRM driver, sh_addralign of symbol section is 8, and less than >> other sections such as Text and Data (sh_addralign is 4096). >> >> Regards, >> >> Lisa >> >> -----Original Message----- >> From: Feng, Bob C > >> Sent: 2022=E5=B9=B41=E6=9C=8814=E6=97=A5 14:12 >> To: Huang, Li-Xia > >; devel@edk2.groups.io >> >> Cc: Gao, Liming > >; Chen, Christine >> > >> Subject: RE: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add >> export table in PE-COFF >> >> Hi Lixia, >> >> This patch introduce a new command line option --PRM. Could you add >> the help information about --PRM? >> >> Could you provide more information about the below change? Would there >> be side-effect? >> >> @@ -750,7 +818,7 @@ ScanSections64 ( >> >> =C2=A0=C2=A0=C2=A0=C2=A0 if (shdr->sh_addralign <=3D mCoffAlignment) { >> >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 continue; >> >> =C2=A0=C2=A0=C2=A0=C2=A0 } >> >> -=C2=A0=C2=A0=C2=A0 if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsr= cShdr(shdr)) >> { >> >> +=C2=A0=C2=A0=C2=A0 if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsr= cShdr(shdr) >> +|| >> IsSymbolShdr(shdr)) { >> >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mCoffAlignment =3D (UINT32)shdr->= sh_addralign; >> >> =C2=A0=C2=A0=C2=A0=C2=A0 } >> >> =C2=A0=C2=A0 } >> >> Thanks, >> >> Bob >> >> -----Original Message----- >> >> From: Huang, Li-Xia > > >> >> Sent: Wednesday, January 12, 2022 3:44 PM >> >> To: devel@edk2.groups.io >> >> Cc: Huang, Li-Xia > >; Gao, Liming > >; Feng, Bob C > >; Chen, Christine > > >> >> Subject: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export >> table in PE-COFF >> >> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3D3802 >> >> >> Since PRM module needs to support export table in PE-COFF, we'll >> enhance GenFw tool to support this. >> >> Add one export flag in GenFw tool. If export flag is set: >> >> Step1: Scan ELF symbol table based on PRM module descriptor to get >> descriptor offset address; >> >> Step2: Find PRM handlers number and name in COFF file based on the >> address from step1; >> >> Step3: Write PRM info such as handler name and export RVA into COFF >> export table. >> >> Cc: Liming Gao > > >> >> Cc: Bob Feng > >> >> Cc: Yuwei Chen > >> >> Signed-off-by: Lixia Huang > > >> >> --- >> >> BaseTools/Source/C/GenFw/Elf64Convert.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 | 254 +++++++++++++++++- >> >> BaseTools/Source/C/GenFw/ElfConvert.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0 10 + >> >> BaseTools/Source/C/GenFw/ElfConvert.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0 |=C2=A0 42 ++- >> >> BaseTools/Source/C/GenFw/GenFw.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |=C2=A0 11 +- >> >> .../C/Include/IndustryStandard/PeImage.h=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 |= =C2=A0=C2=A0 7 + >> >> 5 files changed, 318 insertions(+), 6 deletions(-) >> >> diff --git a/BaseTools/Source/C/GenFw/Elf64Convert.c >> b/BaseTools/Source/C/GenFw/Elf64Convert.c >> >> index 0bb3ead228..0079507356 100644 >> >> --- a/BaseTools/Source/C/GenFw/Elf64Convert.c >> >> +++ b/BaseTools/Source/C/GenFw/Elf64Convert.c >> >> @@ -56,6 +56,18 @@ WriteDebug64 ( >> >> =C2=A0=C2=A0 VOID=C2=A0=C2=A0 ); +STATIC+VOID+ScanSymbol64 (+=C2=A0 VO= ID+ >> );++STATIC+VOID+WriteExport64 (+=C2=A0 VOID+=C2=A0 );+ STATIC VOID >> SetImageSize64 (@@ -122,7 +134,7 @@ STATIC UINT32 mDataOffset; >> >> STATIC UINT32 mHiiRsrcOffset; STATIC UINT32 mRelocOffset; STATIC >> UINT32 mDebugOffset;-+STATIC UINT32 mExportOffset; // // Used for >> RISC-V relocations. //@@ -132,6 +144,14 @@ STATIC Elf64_Half >> mRiscVPass1SymSecIndex =3D 0; >> >> STATIC INT32=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mRiscVPass1Offset; STAT= IC INT32 >> mRiscVPass1GotFixup; +//+// Used for Export section.+//+STATIC >> UINT32=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mExportSize;+STATIC UINT32 >> mExportRVA[PRM_MODULE_EXPORT_SYMBOL_NUM];+STATIC UINT32 >> mExportSymNum;+STATIC CHAR8 >> mExportSymName[PRM_MODULE_EXPORT_SYMBOL_NUM][PRM_HANDLER_NAME_MAXIMUM_ >> LENGTH];+ // // Initialization Function //@@ -200,6 +220,10 @@ >> InitializeElf64 ( >> >> =C2=A0=C2=A0 ElfFunctions->SetImageSize =3D SetImageSize64; >> ElfFunctions->CleanUp =3D CleanUp64; +=C2=A0 if (mExportFlag) {+=C2=A0= =C2=A0=C2=A0 ElfFunctions->ScanSymbol =3D >> ScanSymbol64;+=C2=A0=C2=A0=C2=A0 ElfFunctions->WriteExport =3D WriteExpo= rt64;+=C2=A0 } >> return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( >> >> =C2=A0=C2=A0 return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offse= t + >> Shdr->sh_name, ELF_HII_SECTION_NAME) =3D=3D 0); } >> +STATIC+BOOLEAN+IsSymbolShdr (+=C2=A0 Elf_Shdr *Shdr+=C2=A0 )+{+=C2=A0 E= lf_Shdr >> *Namehdr =3D GetShdrByIndex(mEhdr->e_shstrndx);++=C2=A0 return (BOOLEAN) >> (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, >> ELF_SYMBOL_SECTION_NAME) =3D=3D 0);+}+ STATIC BOOLEAN IsDataShdr (@@ >> -335,6 >> +370,38 @@ GetSymName ( >> >> =C2=A0=C2=A0 return StrtabContents + Sym->st_name; } +//+// Get Prm Ha= ndler >> number and name+//+STATIC+VOID+FindPrmHandler (+=C2=A0 UINT64 Offset+=C2= =A0 )+{+ >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport;+=C2=A0 UINT32 >> NameOffset;+=C2=A0 UINT32=C2=A0=C2=A0 HandlerNum;+ UINT32=C2=A0=C2=A0 In= dex;+=C2=A0 UINT8 >> SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];++=C2=A0 PrmExport =3D >> (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset);+ >> NameOffset =3D sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + >> sizeof(EFI_GUID);++=C2=A0 for (HandlerNum =3D 0; HandlerNum < >> PrmExport->NumberPrmHandlers; HandlerNum++) {+=C2=A0=C2=A0=C2=A0 for (In= dex =3D 0; >> PrmExport->Index >> < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) {+=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 SymName[Index] =3D >> *((UINT8 *)PrmExport + NameOffset + Index);+=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 if (SymName[Index] >> =3D=3D >> 0) {+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 break;+ }+=C2=A0=C2=A0= =C2=A0 }++ >> strcpy(mExportSymName[mExportSymNum], >> (CHAR8*)SymName);+=C2=A0=C2=A0=C2=A0 NameOffset +=3D PRM_HANDLER_NAME_MA= XIMUM_LENGTH + >> sizeof(EFI_GUID);+=C2=A0=C2=A0=C2=A0 mExportSymNum ++;+=C2=A0 }+}+ // //= Find the ELF >> section hosting the GOT from an ELF Rva //=C2=A0=C2=A0 of a single GOT e= ntry. >> Normally, GOT is placed in@@ -717,6 +784,7 @@ ScanSections64 ( >> >> =C2=A0=C2=A0 UINT32=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 CoffEntry; >> UINT32=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 SectionCount; >> BOOLEAN=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 FoundSection;+ >> UINT32=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 Offset;=C2=A0=C2=A0=C2=A0 CoffEntry =3D 0; >> mCoffOffset =3D 0;@@ -750,7 +818,7 @@ ScanSections64 ( >> >> =C2=A0=C2=A0=C2=A0=C2=A0 if (shdr->sh_addralign <=3D mCoffAlignment) {= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 continue; >> }-=C2=A0=C2=A0=C2=A0 if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRs= rcShdr(shdr)) >> {+=C2=A0=C2=A0=C2=A0 if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRs= rcShdr(shdr) >> || >> IsSymbolShdr(shdr)) {=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 mCoffAlignment= =3D >> (UINT32)shdr->sh_addralign;=C2=A0=C2=A0=C2=A0=C2=A0 }=C2=A0=C2=A0 }@@ -8= 80,6 +948,16 @@ >> ScanSections64 ( >> >> =C2=A0=C2=A0=C2=A0=C2=A0 Warning (NULL, 0, 0, NULL, "Multiple sections= in %s are merged >> into 1 data section. Source level debug might not work correctly.", >> mInImageName);=C2=A0=C2=A0 } +=C2=A0 //+=C2=A0 //=C2=A0 The Symbol secti= ons.+=C2=A0 //+=C2=A0 if >> (mExportFlag) {+=C2=A0=C2=A0=C2=A0 mExportOffset =3D mCoffOffset;+=C2=A0= =C2=A0=C2=A0 mExportSize =3D >> sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;+ >> mCoffOffset +=3D mExportSize;+=C2=A0=C2=A0=C2=A0 mCoffOffset =3D CoffAli= gn(mCoffOffset);+ >> }+=C2=A0=C2=A0 //=C2=A0=C2=A0 //=C2=A0 The HII resource sections.=C2=A0= =C2=A0 //@@ -962,7 +1040,11 @@ >> ScanSections64 ( >> >> =C2=A0=C2=A0=C2=A0=C2=A0 | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; >> NtHdr->Pe32Plus.OptionalHeader.SizeOfCode =3D mDataOffset - >> NtHdr->mTextOffset;- Pe32Plus.OptionalHeader.SizeOfInitializedData =3D >> NtHdr->mRelocOffset - >> mDataOffset;+=C2=A0 if(mExportFlag) {+ >> NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData =3D mRelocOffset - >> mExportOffset;+=C2=A0 } else {+ >> NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData =3D mRelocOffset - >> mDataOffset;+=C2=A0 } >> NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData =3D 0; >> NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint =3D CoffEntry; @@ >> -989,8 +1071,17 @@ ScanSections64 ( >> >> =C2=A0=C2=A0=C2=A0=C2=A0 NtHdr->Pe32Plus.FileHeader.NumberOfSections--= ;=C2=A0=C2=A0 } +=C2=A0 //+=C2=A0 // If >> found symbol, add edata section between data and rsrc section+=C2=A0 //+ >> if(mExportFlag) {+=C2=A0=C2=A0=C2=A0 Offset =3D mExportOffset;+=C2=A0 } = else {+=C2=A0=C2=A0=C2=A0 Offset =3D >> mHiiRsrcOffset;+=C2=A0 }+=C2=A0=C2=A0 if ((mHiiRsrcOffset - mDataOffset)= > 0) {- >> CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - >> mDataOffset,+=C2=A0=C2=A0=C2=A0 CreateSectionHeader (".data", mDataOffse= t, Offset - >> mDataOffset,=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0 EFI_IMAGE_SCN_CNT_INITIALIZED_DATA >> | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ);@@ -999,6 +1090,20 >> @@ ScanSections64 ( >> >> =C2=A0=C2=A0=C2=A0=C2=A0 NtHdr->Pe32Plus.FileHeader.NumberOfSections--= ;=C2=A0=C2=A0 } + >> if(mExportFlag) {+=C2=A0=C2=A0=C2=A0 if ((mHiiRsrcOffset - mExportOffset= ) > 0) {+ >> CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - >> mExportOffset,+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 EFI_IMAGE_SCN_CNT_INITIALIZED_DATA+ | >> EFI_IMAGE_SCN_MEM_READ);+ >> NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY >> NtHdr->_EXPORT].Size >> =3D mHiiRsrcOffset - mExportOffset;+ >> NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY >> NtHdr->_EXPORT].VirtualAddress >> =3D mExportOffset;+ NtHdr->Pe32Plus.FileHeader.NumberOfSections++;+=C2= =A0=C2=A0=C2=A0 } >> else {+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // Don't make a section of size 0.= + >> NtHdr->Pe32Plus.FileHeader.NumberOfSections--;+=C2=A0=C2=A0=C2=A0 }+=C2= =A0 }+=C2=A0=C2=A0 if >> ((mRelocOffset - mHiiRsrcOffset) > 0) {=C2=A0=C2=A0=C2=A0=C2=A0 CreateSe= ctionHeader >> (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, >> EFI_IMAGE_SCN_CNT_INITIALIZED_DATA@@ -1757,4 +1862,145 @@ CleanUp64 ( >> >> =C2=A0=C2=A0 } } +STATIC+VOID+ScanSymbol64 (+=C2=A0 VOID+=C2=A0 )+{+= =C2=A0 UINT32 >> shIndex;+=C2=A0 UINT32=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 SymIndex;+=C2=A0 El= f_Sym=C2=A0=C2=A0=C2=A0=C2=A0 *Sym;+=C2=A0 UINT64 >> SymNum;+=C2=A0 const UINT8 *SymName;++=C2=A0 for (shIndex =3D 0; shIndex= < >> mEhdr->e_shnum; shIndex++) {+=C2=A0=C2=A0=C2=A0 //+=C2=A0=C2=A0=C2=A0 //= Determine if this is a >> mEhdr->symbol >> section.+=C2=A0=C2=A0=C2=A0 //+=C2=A0=C2=A0=C2=A0 Elf_Shdr *shdr =3D Get= ShdrByIndex(shIndex);+=C2=A0=C2=A0=C2=A0 if >> (!IsSymbolShdr(shdr)) {+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 continue;+=C2=A0= =C2=A0=C2=A0 }++=C2=A0=C2=A0=C2=A0 UINT8=C2=A0=C2=A0=C2=A0 *Symtab =3D >> (UINT8*)mEhdr + shdr->sh_offset;+=C2=A0=C2=A0=C2=A0 SymNum =3D (shdr->sh= _size) / >> (shdr->sh_entsize);++ //+=C2=A0=C2=A0=C2=A0 // First Get PrmModuleExport= Descriptor+ >> //+=C2=A0=C2=A0=C2=A0 for (SymIndex =3D 0; SymIndex < SymNum; SymIndex++= ) {+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Sym =3D >> (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 SymName =3D >> GetSymName(Sym);+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (SymName =3D=3D NULL)= {+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 continue;+ }++ >> if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) >> =3D=3D 0) {+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 //+=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 // Find PrmHandler Number and Name+ >> //+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 FindPrmHandler(Sym->st_val= ue);++ >> strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ >> mExportRVA[mExportSymNum] =3D (UINT32)(Sym->st_value);+ >> mExportSize >> +=3D 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + >> strlen((CHAR8 *)SymName) + 1;+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= mExportSymNum ++;+ >> break;+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }+=C2=A0=C2=A0=C2=A0 }++=C2=A0=C2= =A0=C2=A0 //+=C2=A0=C2=A0=C2=A0 // Second Get PrmHandler+ //+=C2=A0=C2=A0= =C2=A0 for >> (SymIndex =3D 0; SymIndex < SymNum; SymIndex++) {+=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 UINT32 >> ExpIndex;+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Sym =3D (Elf_Sym *)(Symtab + Sy= mIndex * >> shdr->sh_entsize);+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 SymName =3D GetSymName= (Sym);+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (SymName >> shdr->=3D=3D >> NULL) {+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 continue;= +=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }++=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 for (ExpI= ndex =3D 0; ExpIndex >> < (mExportSymNum -1); ExpIndex++) {+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 if (strcmp((CHAR8*)SymName, >> mExportSymName[ExpIndex]) !=3D 0) {+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0 continue;+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }+ >> mExportRVA[ExpIndex] =3D (UINT32)(Sym->st_value);+=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 mExportSize +=3D >> 2 >> * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + >> strlen((CHAR8 *)SymName) + 1;+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 }+=C2=A0=C2= =A0=C2=A0 }++=C2=A0=C2=A0=C2=A0 break;+ >> }+}++STATIC+VOID+WriteExport64 (+=C2=A0 VOID+=C2=A0 )+{+ >> EFI_IMAGE_OPTIONAL_HEADER_UNION=C2=A0=C2=A0=C2=A0=C2=A0 *NtHdr;+ >> EFI_IMAGE_EXPORT_DIRECTORY=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 *ExportDir;+ >> EFI_IMAGE_DATA_DIRECTORY *DataDir;+=C2=A0 UINT32 >> FileNameOffset;+=C2=A0 UINT32=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 FuncOffset;+ >> UINT16=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0 =C2=A0=C2=A0Index;+ >> UINT8=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 *Tdata =3D NULL;++=C2=A0 ExportDir = =3D >> (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset);+ >> ExportDir->Characteristics =3D 0;+=C2=A0 ExportDir->TimeDateStamp =3D 0;= + >> ExportDir->MajorVersion =3D 0;+=C2=A0 ExportDir->MinorVersion =3D0;+ Nam= e =3D 0;+ >> ExportDir->ExportDir->NumberOfFunctions =3D mExportSymNum;+ >> ExportDir->NumberOfNames =3D mExportSymNum;+ ExportDir->Base =3D >> EFI_IMAGE_EXPORT_ORDINAL_BASE;+=C2=A0 ExportDir->AddressOfFunctions =3D >> mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY);+ >> ExportDir->AddressOfNames =3D ExportDir->AddressOfFunctions + >> EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;+ >> ExportDir->AddressOfNameOrdinals =3D ExportDir->AddressOfNames + >> EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;++=C2=A0 FileNameOffset =3D >> ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * >> mExportSymNum;+=C2=A0 FuncOffset =3D FileNameOffset + strlen(mInImageNam= e) + >> 1;++=C2=A0 // Write Input image Name RVA+=C2=A0 Tdata =3D mCoffFile + 12= ;+ >> *(UINT32 *)Tdata =3D FileNameOffset;++=C2=A0 // Write Input image Name+ >> strcpy((char *)(mCoffFile + FileNameOffset), mInImageName);++=C2=A0 for >> (Index =3D 0; Index < mExportSymNum; Index++) {+=C2=A0=C2=A0=C2=A0 //+= =C2=A0=C2=A0=C2=A0 // Write >> Export Address Table+ //+=C2=A0=C2=A0=C2=A0 Tdata =3D mCoffFile + >> ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+=C2= =A0=C2=A0=C2=A0 *(UINT32 *)Tdata =3D >> mExportRVA[Index];++=C2=A0=C2=A0=C2=A0 //+=C2=A0=C2=A0=C2=A0 // Write Ex= port Name Pointer Table+ >> //+=C2=A0=C2=A0=C2=A0 Tdata =3D mCoffFile + ExportDir->AddressOfNames + = Index * >> EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata =3D FuncOffset;++=C2=A0=C2= =A0=C2=A0 //+ >> // Write Export Ordinal table+=C2=A0=C2=A0=C2=A0 //+=C2=A0=C2=A0=C2=A0 T= data =3D mCoffFile + >> ExportDir->AddressOfNameOrdinals + Index * >> EFI_IMAGE_EXPORT_ORDINAL_SIZE;+=C2=A0=C2=A0=C2=A0 *(UINT16 *)Tdata =3D I= ndex;++=C2=A0=C2=A0=C2=A0 //+ >> // Write Export Name Table+=C2=A0=C2=A0=C2=A0 //+ strcpy((char *)(mCoffF= ile + >> FuncOffset), mExportSymName[Index]);+=C2=A0=C2=A0=C2=A0 FuncOffset +=3D >> strlen(mExportSymName[Index]) + 1;+=C2=A0 }++=C2=A0 NtHdr =3D >> (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);+ >> DataDir =3D >> &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTR >> Y_EXPORT];+ >> DataDir->VirtualAddress =3D mExportOffset;+ =C2=A0DataDir->Size =3D >> mExportSize;++} diff --git a/BaseTools/Source/C/GenFw/ElfConvert.c >> b/BaseTools/Source/C/GenFw/ElfConvert.c >> >> index 7db8721167..795cdbd743 100644 >> >> --- a/BaseTools/Source/C/GenFw/ElfConvert.c >> >> +++ b/BaseTools/Source/C/GenFw/ElfConvert.c >> >> @@ -223,6 +223,16 @@ ConvertElf ( >> >> =C2=A0=C2=A0 VerboseMsg ("Write debug info.");=C2=A0=C2=A0 ElfFunction= s.WriteDebug (); + >> //+=C2=A0 // For PRM Driver to Write export info.+=C2=A0 //+=C2=A0 if (m= ExportFlag) >> {+=C2=A0=C2=A0=C2=A0 VerboseMsg ("Scan symbol info.");+=C2=A0=C2=A0=C2= =A0 ElfFunctions.ScanSymbol >> ();+=C2=A0=C2=A0=C2=A0 VerboseMsg ("Write export info.");+ >> ElfFunctions.WriteExport ();+=C2=A0 }+=C2=A0=C2=A0 //=C2=A0=C2=A0 // Mak= e sure image size is >> correct before returning the new image.=C2=A0=C2=A0 //diff --git >> a/BaseTools/Source/C/GenFw/ElfConvert.h >> b/BaseTools/Source/C/GenFw/ElfConvert.h >> >> index 801e8de4a2..7920765fbb 100644 >> >> --- a/BaseTools/Source/C/GenFw/ElfConvert.h >> >> +++ b/BaseTools/Source/C/GenFw/ElfConvert.h >> >> @@ -24,6 +24,7 @@ extern UINT8=C2=A0 *mCoffFile;=C2=A0 extern UINT32 >> mTableOffset; extern UINT32 mOutImageType; extern UINT32 >> mFileBufferSize;+extern BOOLEAN mExportFlag; =C2=A0// // Common EFI >> specific data.@@ -31,6 +32,42 @@ extern UINT32 mFileBufferSize; >> >> #define ELF_HII_SECTION_NAME ".hii" #define ELF_STRTAB_SECTION_NAME >> ".strtab" #define MAX_COFF_ALIGNMENT 0x10000+#define >> ELF_SYMBOL_SECTION_NAME ".symtab"++//+// Platform Runtime Mechanism >> (PRM) specific data.+//+#define PRM_MODULE_EXPORT_SYMBOL_NUM >> 10+#define PRM_HANDLER_NAME_MAXIMUM_LENGTH 128++#define >> PRM_MODULE_EXPORT_DESCRIPTOR_NAME >> "PrmModuleExportDescriptor"+#define >> PRM_MODULE_EXPORT_DESCRIPTOR_SIGNATURE=C2=A0=C2=A0=C2=A0 SIGNATURE_64 ('= P', 'R', 'M', >> '_', 'M', 'E', 'D', 'T')+#define PRM_MODULE_EXPORT_REVISION 0x0++//+// >> Platform Runtime Mechanism (PRM) Export Descriptor Structures+//+#pragma >> pack(push, 1)++typedef struct {+=C2=A0 EFI_GUID >> =C2=A0PrmHandlerGuid;+=C2=A0 CHAR8 >> PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];+} >> PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT;++typedef struct {+ >> UINT64=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Signature;+ >> UINT16=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Revision;+ >> UINT16=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 NumberPrmHandlers;+=C2=A0 EFI= _GUID >> PlatformGuid;+=C2=A0 EFI_GUID=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 ModuleGuid;+} >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;++typedef struct {+ >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER=C2=A0 Header;+ >> PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT >> PrmHandlerExportDescriptors[1];+} >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;++#pragma pack(pop)=C2=A0 // // Filt= er >> Types@@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; >> >> typedef enum { =C2=A0=C2=A0SECTION_TEXT,=C2=A0=C2=A0 SECTION_HII,-=C2=A0= SECTION_DATA+ >> SECTION_DATA,+=C2=A0 SECTION_SYMBOL=C2=A0 } SECTION_FILTER_TYPES; @@ -50= ,6 +88,8 >> @@ typedef struct { >> >> =C2=A0=C2=A0 BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES=C2=A0 Filt= erType); >> VOID=C2=A0=C2=A0=C2=A0 (*WriteRelocations) ();=C2=A0=C2=A0 VOID=C2=A0=C2= =A0=C2=A0 (*WriteDebug) ();+=C2=A0 VOID >> (*ScanSymbol) ();+=C2=A0 VOID=C2=A0=C2=A0=C2=A0 (*WriteExport) ();=C2=A0= =C2=A0 VOID >> (*SetImageSize) ();=C2=A0=C2=A0 VOID=C2=A0=C2=A0=C2=A0 (*CleanUp) (); di= ff --git >> a/BaseTools/Source/C/GenFw/GenFw.c b/BaseTools/Source/C/GenFw/GenFw.c >> >> index 8cab70ba4d..c7de5b89d8 100644 >> >> --- a/BaseTools/Source/C/GenFw/GenFw.c >> >> +++ b/BaseTools/Source/C/GenFw/GenFw.c >> >> @@ -87,7 +87,7 @@ UINT32 mImageTimeStamp =3D 0; >> >> UINT32 mImageSize =3D 0; UINT32 mOutImageType =3D FW_DUMMY_IMAGE; BOOLEA= N >> mIsConvertXip =3D FALSE;-+BOOLEAN mExportFlag =3D FALSE;=C2=A0 STATIC >> EFI_STATUS@@ -1436,6 +1436,15 @@ Returns: >> >> =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 continue;=C2=A0=C2=A0=C2=A0=C2=A0= } +=C2=A0=C2=A0=C2=A0 if (stricmp (argv[0], "--PRM") =3D=3D 0) >> {+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 if (!mExportFlag) {+=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0 mExportFlag =3D TRUE;+=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0 }+ >> argc --;+=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 argv ++;+=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0 continue;+=C2=A0=C2=A0=C2=A0 }+=C2=A0=C2=A0=C2=A0=C2=A0 if (argv[= 0][0] =3D=3D >> '-') {=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0 Error (NULL, 0, 1000, "Unknow= n option", argv[0]); >> goto Finish;diff --git >> a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h >> b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h >> >> index f17b8ee19b..21c968e650 100644 >> >> --- a/BaseTools/Source/C/Include/IndustryStandard/PeImage.h >> >> +++ b/BaseTools/Source/C/Include/IndustryStandard/PeImage.h >> >> @@ -571,6 +571,13 @@ typedef struct { >> >> =C2=A0=C2=A0 UINT32=C2=A0 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DI= RECTORY; +//+// >> Based export types.+//+#define EFI_IMAGE_EXPORT_ORDINAL_BASE >> 1+#define EFI_IMAGE_EXPORT_ADDR_SIZE=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0 4+#define >> EFI_IMAGE_EXPORT_ORDINAL_SIZE=C2=A0=C2=A0=C2=A0=C2=A0 2+ /// /// DLL sup= port. /// Import >> Format-- >> >> 2.26.2.windows.1 >> >>=20