* [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF @ 2022-01-12 7:44 Lixia Huang 2022-01-14 6:11 ` Bob Feng 0 siblings, 1 reply; 10+ messages in thread From: Lixia Huang @ 2022-01-12 7:44 UTC (permalink / raw) To: devel; +Cc: Lixia Huang, Liming Gao, Bob Feng, Yuwei Chen REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3802 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 <gaoliming@byosoft.com.cn> Cc: Bob Feng <bob.c.feng@intel.com> Cc: Yuwei Chen <yuwei.chen@intel.com> Signed-off-by: Lixia Huang <lisa.huang@intel.com> --- BaseTools/Source/C/GenFw/Elf64Convert.c | 254 +++++++++++++++++- BaseTools/Source/C/GenFw/ElfConvert.c | 10 + BaseTools/Source/C/GenFw/ElfConvert.h | 42 ++- BaseTools/Source/C/GenFw/GenFw.c | 11 +- .../C/Include/IndustryStandard/PeImage.h | 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 ( VOID ); +STATIC +VOID +ScanSymbol64 ( + VOID + ); + +STATIC +VOID +WriteExport64 ( + VOID + ); + 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 = 0; STATIC INT32 mRiscVPass1Offset; STATIC INT32 mRiscVPass1GotFixup; +// +// Used for Export section. +// +STATIC UINT32 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 ( ElfFunctions->SetImageSize = SetImageSize64; ElfFunctions->CleanUp = CleanUp64; + if (mExportFlag) { + ElfFunctions->ScanSymbol = ScanSymbol64; + ElfFunctions->WriteExport = WriteExport64; + } return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); } +STATIC +BOOLEAN +IsSymbolShdr ( + Elf_Shdr *Shdr + ) +{ + Elf_Shdr *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx); + + return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, ELF_SYMBOL_SECTION_NAME) == 0); +} + STATIC BOOLEAN IsDataShdr ( @@ -335,6 +370,38 @@ GetSymName ( return StrtabContents + Sym->st_name; } +// +// Get Prm Handler number and name +// +STATIC +VOID +FindPrmHandler ( + UINT64 Offset + ) +{ + PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport; + UINT32 NameOffset; + UINT32 HandlerNum; + UINT32 Index; + UINT8 SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH]; + + PrmExport = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset); + NameOffset = sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + sizeof(EFI_GUID); + + for (HandlerNum = 0; HandlerNum < PrmExport->NumberPrmHandlers; HandlerNum++) { + for (Index = 0; Index < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) { + SymName[Index] = *((UINT8 *)PrmExport + NameOffset + Index); + if (SymName[Index] == 0) { + break; + } + } + + strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName); + NameOffset += PRM_HANDLER_NAME_MAXIMUM_LENGTH + sizeof(EFI_GUID); + mExportSymNum ++; + } +} + // // Find the ELF section hosting the GOT from an ELF Rva // of a single GOT entry. Normally, GOT is placed in @@ -717,6 +784,7 @@ ScanSections64 ( UINT32 CoffEntry; UINT32 SectionCount; BOOLEAN FoundSection; + UINT32 Offset; CoffEntry = 0; mCoffOffset = 0; @@ -750,7 +818,7 @@ ScanSections64 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; } - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } } @@ -880,6 +948,16 @@ ScanSections64 ( Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); } + // + // The Symbol sections. + // + if (mExportFlag) { + mExportOffset = mCoffOffset; + mExportSize = sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1; + mCoffOffset += mExportSize; + mCoffOffset = CoffAlign(mCoffOffset); + } + // // The HII resource sections. // @@ -962,7 +1040,11 @@ ScanSections64 ( | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset; - NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset; + if(mExportFlag) { + NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mExportOffset; + } else { + NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset; + } NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; @@ -989,8 +1071,17 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + // + // If found symbol, add edata section between data and rsrc section + // + if(mExportFlag) { + Offset = mExportOffset; + } else { + Offset = mHiiRsrcOffset; + } + if ((mHiiRsrcOffset - mDataOffset) > 0) { - CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset, + CreateSectionHeader (".data", mDataOffset, Offset - mDataOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ); @@ -999,6 +1090,20 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + if(mExportFlag) { + if ((mHiiRsrcOffset - mExportOffset) > 0) { + CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - mExportOffset, + EFI_IMAGE_SCN_CNT_INITIALIZED_DATA + | EFI_IMAGE_SCN_MEM_READ); + NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size = mHiiRsrcOffset - mExportOffset; + NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = mExportOffset; + NtHdr->Pe32Plus.FileHeader.NumberOfSections++; + } else { + // Don't make a section of size 0. + NtHdr->Pe32Plus.FileHeader.NumberOfSections--; + } + } + if ((mRelocOffset - mHiiRsrcOffset) > 0) { CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA @@ -1757,4 +1862,145 @@ CleanUp64 ( } } +STATIC +VOID +ScanSymbol64 ( + VOID + ) +{ + UINT32 shIndex; + UINT32 SymIndex; + Elf_Sym *Sym; + UINT64 SymNum; + const UINT8 *SymName; + + for (shIndex = 0; shIndex < mEhdr->e_shnum; shIndex++) { + // + // Determine if this is a symbol section. + // + Elf_Shdr *shdr = GetShdrByIndex(shIndex); + if (!IsSymbolShdr(shdr)) { + continue; + } + + UINT8 *Symtab = (UINT8*)mEhdr + shdr->sh_offset; + SymNum = (shdr->sh_size) / (shdr->sh_entsize); + + // + // First Get PrmModuleExportDescriptor + // + for (SymIndex = 0; SymIndex < SymNum; SymIndex++) { + Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize); + SymName = GetSymName(Sym); + if (SymName == NULL) { + continue; + } + + if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) == 0) { + // + // Find PrmHandler Number and Name + // + FindPrmHandler(Sym->st_value); + + strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName); + mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value); + mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1; + mExportSymNum ++; + break; + } + } + + // + // Second Get PrmHandler + // + for (SymIndex = 0; SymIndex < SymNum; SymIndex++) { + UINT32 ExpIndex; + Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize); + SymName = GetSymName(Sym); + if (SymName == NULL) { + continue; + } + + for (ExpIndex = 0; ExpIndex < (mExportSymNum -1); ExpIndex++) { + if (strcmp((CHAR8*)SymName, mExportSymName[ExpIndex]) != 0) { + continue; + } + mExportRVA[ExpIndex] = (UINT32)(Sym->st_value); + mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1; + } + } + + break; + } +} + +STATIC +VOID +WriteExport64 ( + VOID + ) +{ + EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr; + EFI_IMAGE_EXPORT_DIRECTORY *ExportDir; + EFI_IMAGE_DATA_DIRECTORY *DataDir; + UINT32 FileNameOffset; + UINT32 FuncOffset; + UINT16 Index; + UINT8 *Tdata = NULL; + + ExportDir = (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset); + ExportDir->Characteristics = 0; + ExportDir->TimeDateStamp = 0; + ExportDir->MajorVersion = 0; + ExportDir->MinorVersion =0; + ExportDir->Name = 0; + ExportDir->NumberOfFunctions = mExportSymNum; + ExportDir->NumberOfNames = mExportSymNum; + ExportDir->Base = EFI_IMAGE_EXPORT_ORDINAL_BASE; + ExportDir->AddressOfFunctions = mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY); + ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum; + ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum; + + FileNameOffset = ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * mExportSymNum; + FuncOffset = FileNameOffset + strlen(mInImageName) + 1; + + // Write Input image Name RVA + Tdata = mCoffFile + 12; + *(UINT32 *)Tdata = FileNameOffset; + + // Write Input image Name + strcpy((char *)(mCoffFile + FileNameOffset), mInImageName); + + for (Index = 0; Index < mExportSymNum; Index++) { + // + // Write Export Address Table + // + Tdata = mCoffFile + ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE; + *(UINT32 *)Tdata = mExportRVA[Index]; + + // + // Write Export Name Pointer Table + // + Tdata = mCoffFile + ExportDir->AddressOfNames + Index * EFI_IMAGE_EXPORT_ADDR_SIZE; + *(UINT32 *)Tdata = FuncOffset; + + // + // Write Export Ordinal table + // + Tdata = mCoffFile + ExportDir->AddressOfNameOrdinals + Index * EFI_IMAGE_EXPORT_ORDINAL_SIZE; + *(UINT16 *)Tdata = Index; + + // + // Write Export Name Table + // + strcpy((char *)(mCoffFile + FuncOffset), mExportSymName[Index]); + FuncOffset += strlen(mExportSymName[Index]) + 1; + } + + NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset); + DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT]; + DataDir->VirtualAddress = mExportOffset; + DataDir->Size = 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 ( VerboseMsg ("Write debug info."); ElfFunctions.WriteDebug (); + // + // For PRM Driver to Write export info. + // + if (mExportFlag) { + VerboseMsg ("Scan symbol info."); + ElfFunctions.ScanSymbol (); + VerboseMsg ("Write export info."); + ElfFunctions.WriteExport (); + } + // // Make sure image size is correct before returning the new image. // 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 *mCoffFile; extern UINT32 mTableOffset; extern UINT32 mOutImageType; extern UINT32 mFileBufferSize; +extern BOOLEAN mExportFlag; // // 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 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 { + EFI_GUID PrmHandlerGuid; + CHAR8 PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH]; +} PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT; + +typedef struct { + UINT64 Signature; + UINT16 Revision; + UINT16 NumberPrmHandlers; + EFI_GUID PlatformGuid; + EFI_GUID ModuleGuid; +} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER; + +typedef struct { + PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header; + PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT PrmHandlerExportDescriptors[1]; +} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT; + +#pragma pack(pop) // // Filter Types @@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; typedef enum { SECTION_TEXT, SECTION_HII, - SECTION_DATA + SECTION_DATA, + SECTION_SYMBOL } SECTION_FILTER_TYPES; @@ -50,6 +88,8 @@ typedef struct { BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); VOID (*WriteRelocations) (); VOID (*WriteDebug) (); + VOID (*ScanSymbol) (); + VOID (*WriteExport) (); VOID (*SetImageSize) (); VOID (*CleanUp) (); diff --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 = 0; UINT32 mImageSize = 0; UINT32 mOutImageType = FW_DUMMY_IMAGE; BOOLEAN mIsConvertXip = FALSE; - +BOOLEAN mExportFlag = FALSE; STATIC EFI_STATUS @@ -1436,6 +1436,15 @@ Returns: continue; } + if (stricmp (argv[0], "--PRM") == 0) { + if (!mExportFlag) { + mExportFlag = TRUE; + } + argc --; + argv ++; + continue; + } + if (argv[0][0] == '-') { Error (NULL, 0, 1000, "Unknown 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 { UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; +// +// Based export types. +// +#define EFI_IMAGE_EXPORT_ORDINAL_BASE 1 +#define EFI_IMAGE_EXPORT_ADDR_SIZE 4 +#define EFI_IMAGE_EXPORT_ORDINAL_SIZE 2 + /// /// DLL support. /// Import Format -- 2.26.2.windows.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF 2022-01-12 7:44 [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF Lixia Huang @ 2022-01-14 6:11 ` Bob Feng 2022-01-17 3:09 ` Huang, Li-Xia 0 siblings, 1 reply; 10+ messages in thread From: Bob Feng @ 2022-01-14 6:11 UTC (permalink / raw) To: Huang, Li-Xia, devel@edk2.groups.io; +Cc: Gao, Liming, Chen, Christine 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 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; } - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } } Thanks, Bob -----Original Message----- From: Huang, Li-Xia <lisa.huang@intel.com> Sent: Wednesday, January 12, 2022 3:44 PM To: devel@edk2.groups.io Cc: Huang, Li-Xia <lisa.huang@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Feng, Bob C <bob.c.feng@intel.com>; Chen, Christine <yuwei.chen@intel.com> Subject: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3802 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 <gaoliming@byosoft.com.cn> Cc: Bob Feng <bob.c.feng@intel.com> Cc: Yuwei Chen <yuwei.chen@intel.com> Signed-off-by: Lixia Huang <lisa.huang@intel.com> --- BaseTools/Source/C/GenFw/Elf64Convert.c | 254 +++++++++++++++++- BaseTools/Source/C/GenFw/ElfConvert.c | 10 + BaseTools/Source/C/GenFw/ElfConvert.h | 42 ++- BaseTools/Source/C/GenFw/GenFw.c | 11 +- .../C/Include/IndustryStandard/PeImage.h | 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 ( VOID ); +STATIC+VOID+ScanSymbol64 (+ VOID+ );++STATIC+VOID+WriteExport64 (+ VOID+ );+ 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 = 0; STATIC INT32 mRiscVPass1Offset; STATIC INT32 mRiscVPass1GotFixup; +//+// Used for Export section.+//+STATIC UINT32 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 ( ElfFunctions->SetImageSize = SetImageSize64; ElfFunctions->CleanUp = CleanUp64; + if (mExportFlag) {+ ElfFunctions->ScanSymbol = ScanSymbol64;+ ElfFunctions->WriteExport = WriteExport64;+ } return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); } +STATIC+BOOLEAN+IsSymbolShdr (+ Elf_Shdr *Shdr+ )+{+ Elf_Shdr *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx);++ return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, ELF_SYMBOL_SECTION_NAME) == 0);+}+ STATIC BOOLEAN IsDataShdr (@@ -335,6 +370,38 @@ GetSymName ( return StrtabContents + Sym->st_name; } +//+// Get Prm Handler number and name+//+STATIC+VOID+FindPrmHandler (+ UINT64 Offset+ )+{+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport;+ UINT32 NameOffset;+ UINT32 HandlerNum;+ UINT32 Index;+ UINT8 SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];++ PrmExport = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset);+ NameOffset = sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + sizeof(EFI_GUID);++ for (HandlerNum = 0; HandlerNum < PrmExport->NumberPrmHandlers; HandlerNum++) {+ for (Index = 0; Index < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) {+ SymName[Index] = *((UINT8 *)PrmExport + NameOffset + Index);+ if (SymName[Index] == 0) {+ break;+ }+ }++ strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ NameOffset += PRM_HANDLER_NAME_MAXIMUM_LENGTH + sizeof(EFI_GUID);+ mExportSymNum ++;+ }+}+ // // Find the ELF section hosting the GOT from an ELF Rva // of a single GOT entry. Normally, GOT is placed in@@ -717,6 +784,7 @@ ScanSections64 ( UINT32 CoffEntry; UINT32 SectionCount; BOOLEAN FoundSection;+ UINT32 Offset; CoffEntry = 0; mCoffOffset = 0;@@ -750,7 +818,7 @@ ScanSections64 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; }- if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) {+ if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } }@@ -880,6 +948,16 @@ ScanSections64 ( Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); } + //+ // The Symbol sections.+ //+ if (mExportFlag) {+ mExportOffset = mCoffOffset;+ mExportSize = sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;+ mCoffOffset += mExportSize;+ mCoffOffset = CoffAlign(mCoffOffset);+ }+ // // The HII resource sections. //@@ -962,7 +1040,11 @@ ScanSections64 ( | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset;- NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;+ if(mExportFlag) {+ NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mExportOffset;+ } else {+ NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;+ } NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; @@ -989,8 +1071,17 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + //+ // If found symbol, add edata section between data and rsrc section+ //+ if(mExportFlag) {+ Offset = mExportOffset;+ } else {+ Offset = mHiiRsrcOffset;+ }+ if ((mHiiRsrcOffset - mDataOffset) > 0) {- CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset,+ CreateSectionHeader (".data", mDataOffset, Offset - mDataOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ);@@ -999,6 +1090,20 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + if(mExportFlag) {+ if ((mHiiRsrcOffset - mExportOffset) > 0) {+ CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - mExportOffset,+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA+ | EFI_IMAGE_SCN_MEM_READ);+ NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size = mHiiRsrcOffset - mExportOffset;+ NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = mExportOffset;+ NtHdr->Pe32Plus.FileHeader.NumberOfSections++;+ } else {+ // Don't make a section of size 0.+ NtHdr->Pe32Plus.FileHeader.NumberOfSections--;+ }+ }+ if ((mRelocOffset - mHiiRsrcOffset) > 0) { CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA@@ -1757,4 +1862,145 @@ CleanUp64 ( } } +STATIC+VOID+ScanSymbol64 (+ VOID+ )+{+ UINT32 shIndex;+ UINT32 SymIndex;+ Elf_Sym *Sym;+ UINT64 SymNum;+ const UINT8 *SymName;++ for (shIndex = 0; shIndex < mEhdr->e_shnum; shIndex++) {+ //+ // Determine if this is a symbol section.+ //+ Elf_Shdr *shdr = GetShdrByIndex(shIndex);+ if (!IsSymbolShdr(shdr)) {+ continue;+ }++ UINT8 *Symtab = (UINT8*)mEhdr + shdr->sh_offset;+ SymNum = (shdr->sh_size) / (shdr->sh_entsize);++ //+ // First Get PrmModuleExportDescriptor+ //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ }++ if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) == 0) {+ //+ // Find PrmHandler Number and Name+ //+ FindPrmHandler(Sym->st_value);++ strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value);+ mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1;+ mExportSymNum ++;+ break;+ }+ }++ //+ // Second Get PrmHandler+ //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ UINT32 ExpIndex;+ Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ }++ for (ExpIndex = 0; ExpIndex < (mExportSymNum -1); ExpIndex++) {+ if (strcmp((CHAR8*)SymName, mExportSymName[ExpIndex]) != 0) {+ continue;+ }+ mExportRVA[ExpIndex] = (UINT32)(Sym->st_value);+ mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1;+ }+ }++ break;+ }+}++STATIC+VOID+WriteExport64 (+ VOID+ )+{+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;+ EFI_IMAGE_EXPORT_DIRECTORY *ExportDir;+ EFI_IMAGE_DATA_DIRECTORY *DataDir;+ UINT32 FileNameOffset;+ UINT32 FuncOffset;+ UINT16 Index;+ UINT8 *Tdata = NULL;++ ExportDir = (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset);+ ExportDir->Characteristics = 0;+ ExportDir->TimeDateStamp = 0;+ ExportDir->MajorVersion = 0;+ ExportDir->MinorVersion =0;+ ExportDir->Name = 0;+ ExportDir->NumberOfFunctions = mExportSymNum;+ ExportDir->NumberOfNames = mExportSymNum;+ ExportDir->Base = EFI_IMAGE_EXPORT_ORDINAL_BASE;+ ExportDir->AddressOfFunctions = mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY);+ ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;+ ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;++ FileNameOffset = ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * mExportSymNum;+ FuncOffset = FileNameOffset + strlen(mInImageName) + 1;++ // Write Input image Name RVA+ Tdata = mCoffFile + 12;+ *(UINT32 *)Tdata = FileNameOffset;++ // Write Input image Name+ strcpy((char *)(mCoffFile + FileNameOffset), mInImageName);++ for (Index = 0; Index < mExportSymNum; Index++) {+ //+ // Write Export Address Table+ //+ Tdata = mCoffFile + ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = mExportRVA[Index];++ //+ // Write Export Name Pointer Table+ //+ Tdata = mCoffFile + ExportDir->AddressOfNames + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = FuncOffset;++ //+ // Write Export Ordinal table+ //+ Tdata = mCoffFile + ExportDir->AddressOfNameOrdinals + Index * EFI_IMAGE_EXPORT_ORDINAL_SIZE;+ *(UINT16 *)Tdata = Index;++ //+ // Write Export Name Table+ //+ strcpy((char *)(mCoffFile + FuncOffset), mExportSymName[Index]);+ FuncOffset += strlen(mExportSymName[Index]) + 1;+ }++ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);+ DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT];+ DataDir->VirtualAddress = mExportOffset;+ DataDir->Size = 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 ( VerboseMsg ("Write debug info."); ElfFunctions.WriteDebug (); + //+ // For PRM Driver to Write export info.+ //+ if (mExportFlag) {+ VerboseMsg ("Scan symbol info.");+ ElfFunctions.ScanSymbol ();+ VerboseMsg ("Write export info.");+ ElfFunctions.WriteExport ();+ }+ // // Make sure image size is correct before returning the new image. //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 *mCoffFile; extern UINT32 mTableOffset; extern UINT32 mOutImageType; extern UINT32 mFileBufferSize;+extern BOOLEAN mExportFlag; // // 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 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 {+ EFI_GUID PrmHandlerGuid;+ CHAR8 PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];+} PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT;++typedef struct {+ UINT64 Signature;+ UINT16 Revision;+ UINT16 NumberPrmHandlers;+ EFI_GUID PlatformGuid;+ EFI_GUID ModuleGuid;+} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;++typedef struct {+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header;+ PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT PrmHandlerExportDescriptors[1];+} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;++#pragma pack(pop) // // Filter Types@@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; typedef enum { SECTION_TEXT, SECTION_HII,- SECTION_DATA+ SECTION_DATA,+ SECTION_SYMBOL } SECTION_FILTER_TYPES; @@ -50,6 +88,8 @@ typedef struct { BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); VOID (*WriteRelocations) (); VOID (*WriteDebug) ();+ VOID (*ScanSymbol) ();+ VOID (*WriteExport) (); VOID (*SetImageSize) (); VOID (*CleanUp) (); diff --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 = 0; UINT32 mImageSize = 0; UINT32 mOutImageType = FW_DUMMY_IMAGE; BOOLEAN mIsConvertXip = FALSE;-+BOOLEAN mExportFlag = FALSE; STATIC EFI_STATUS@@ -1436,6 +1436,15 @@ Returns: continue; } + if (stricmp (argv[0], "--PRM") == 0) {+ if (!mExportFlag) {+ mExportFlag = TRUE;+ }+ argc --;+ argv ++;+ continue;+ }+ if (argv[0][0] == '-') { Error (NULL, 0, 1000, "Unknown 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 { UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; +//+// Based export types.+//+#define EFI_IMAGE_EXPORT_ORDINAL_BASE 1+#define EFI_IMAGE_EXPORT_ADDR_SIZE 4+#define EFI_IMAGE_EXPORT_ORDINAL_SIZE 2+ /// /// DLL support. /// Import Format-- 2.26.2.windows.1 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF 2022-01-14 6:11 ` Bob Feng @ 2022-01-17 3:09 ` Huang, Li-Xia 2022-01-18 5:20 ` 回复: " gaoliming 0 siblings, 1 reply; 10+ messages in thread From: Huang, Li-Xia @ 2022-01-17 3:09 UTC (permalink / raw) To: Feng, Bob C, devel@edk2.groups.io Cc: Gao, Liming, Chen, Christine, Wu, Yidong, Xu, Wei6, You, Benjamin [-- Attachment #1.1: Type: text/plain, Size: 18642 bytes --] Hi Bob, Thanks for your comments. 1. I will add the help information for "--PRM"; 2. @@ -750,7 +818,7 @@ ScanSections64 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; } - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } } 1) Above change is to Set mCoffAlignment to the maximum alignment of the input sections including symbol section. The symbol section will only exist with below change, so it should have no effect to other drivers. build_rule.template: <Command.GCC> $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).debug #$(OBJCOPY) --strip-unneeded -R .eh_frame ${src} $(OBJCOPY) $(OBJCOPY_STRIPFLAG) ${src} tools_def.template: *_*_*_OBJCOPY_STRIPFLAG = --strip-unneeded -R .eh_frame PrmAddrTransDsm.inf: [BuildOptions.common] ... GCC: *_*_*_OBJCOPY_STRIPFLAG == -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). [cid:image001.png@01D80B92.A248CB40] Regards, Lisa -----Original Message----- From: Feng, Bob C <bob.c.feng@intel.com> Sent: 2022年1月14日 14:12 To: Huang, Li-Xia <lisa.huang@intel.com>; devel@edk2.groups.io Cc: Gao, Liming <gaoliming@byosoft.com.cn>; Chen, Christine <yuwei.chen@intel.com> 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 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; } - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } } Thanks, Bob -----Original Message----- From: Huang, Li-Xia <lisa.huang@intel.com<mailto:lisa.huang@intel.com>> Sent: Wednesday, January 12, 2022 3:44 PM To: devel@edk2.groups.io<mailto:devel@edk2.groups.io> Cc: Huang, Li-Xia <lisa.huang@intel.com<mailto:lisa.huang@intel.com>>; Gao, Liming <gaoliming@byosoft.com.cn<mailto:gaoliming@byosoft.com.cn>>; Feng, Bob C <bob.c.feng@intel.com<mailto:bob.c.feng@intel.com>>; Chen, Christine <yuwei.chen@intel.com<mailto:yuwei.chen@intel.com>> Subject: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3802 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 <gaoliming@byosoft.com.cn<mailto:gaoliming@byosoft.com.cn>> Cc: Bob Feng <bob.c.feng@intel.com<mailto:bob.c.feng@intel.com>> Cc: Yuwei Chen <yuwei.chen@intel.com<mailto:yuwei.chen@intel.com>> Signed-off-by: Lixia Huang <lisa.huang@intel.com<mailto:lisa.huang@intel.com>> --- BaseTools/Source/C/GenFw/Elf64Convert.c | 254 +++++++++++++++++- BaseTools/Source/C/GenFw/ElfConvert.c | 10 + BaseTools/Source/C/GenFw/ElfConvert.h | 42 ++- BaseTools/Source/C/GenFw/GenFw.c | 11 +- .../C/Include/IndustryStandard/PeImage.h | 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 ( VOID ); +STATIC+VOID+ScanSymbol64 (+ VOID+ );++STATIC+VOID+WriteExport64 (+ VOID+ );+ 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 = 0; STATIC INT32 mRiscVPass1Offset; STATIC INT32 mRiscVPass1GotFixup; +//+// Used for Export section.+//+STATIC UINT32 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 ( ElfFunctions->SetImageSize = SetImageSize64; ElfFunctions->CleanUp = CleanUp64; + if (mExportFlag) {+ ElfFunctions->ScanSymbol = ScanSymbol64;+ ElfFunctions->WriteExport = WriteExport64;+ } return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); } +STATIC+BOOLEAN+IsSymbolShdr (+ Elf_Shdr *Shdr+ )+{+ Elf_Shdr *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx);++ return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, ELF_SYMBOL_SECTION_NAME) == 0);+}+ STATIC BOOLEAN IsDataShdr (@@ -335,6 +370,38 @@ GetSymName ( return StrtabContents + Sym->st_name; } +//+// Get Prm Handler number and name+//+STATIC+VOID+FindPrmHandler (+ UINT64 Offset+ )+{+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport;+ UINT32 NameOffset;+ UINT32 HandlerNum;+ UINT32 Index;+ UINT8 SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];++ PrmExport = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset);+ NameOffset = sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + sizeof(EFI_GUID);++ for (HandlerNum = 0; HandlerNum < PrmExport->NumberPrmHandlers; HandlerNum++) {+ for (Index = 0; Index < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) {+ SymName[Index] = *((UINT8 *)PrmExport + NameOffset + Index);+ if (SymName[Index] == 0) {+ break;+ }+ }++ strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ NameOffset += PRM_HANDLER_NAME_MAXIMUM_LENGTH + sizeof(EFI_GUID);+ mExportSymNum ++;+ }+}+ // // Find the ELF section hosting the GOT from an ELF Rva // of a single GOT entry. Normally, GOT is placed in@@ -717,6 +784,7 @@ ScanSections64 ( UINT32 CoffEntry; UINT32 SectionCount; BOOLEAN FoundSection;+ UINT32 Offset; CoffEntry = 0; mCoffOffset = 0;@@ -750,7 +818,7 @@ ScanSections64 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; }- if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) {+ if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } }@@ -880,6 +948,16 @@ ScanSections64 ( Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); } + //+ // The Symbol sections.+ //+ if (mExportFlag) {+ mExportOffset = mCoffOffset;+ mExportSize = sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;+ mCoffOffset += mExportSize;+ mCoffOffset = CoffAlign(mCoffOffset);+ }+ // // The HII resource sections. //@@ -962,7 +1040,11 @@ ScanSections64 ( | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset;- NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;+ if(mExportFlag) {+ NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mExportOffset;+ } else {+ NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;+ } NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; @@ -989,8 +1071,17 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + //+ // If found symbol, add edata section between data and rsrc section+ //+ if(mExportFlag) {+ Offset = mExportOffset;+ } else {+ Offset = mHiiRsrcOffset;+ }+ if ((mHiiRsrcOffset - mDataOffset) > 0) {- CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset,+ CreateSectionHeader (".data", mDataOffset, Offset - mDataOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ);@@ -999,6 +1090,20 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + if(mExportFlag) {+ if ((mHiiRsrcOffset - mExportOffset) > 0) {+ CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - mExportOffset,+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA+ | EFI_IMAGE_SCN_MEM_READ);+ NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size = mHiiRsrcOffset - mExportOffset;+ NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = mExportOffset;+ NtHdr->Pe32Plus.FileHeader.NumberOfSections++;+ } else {+ // Don't make a section of size 0.+ NtHdr->Pe32Plus.FileHeader.NumberOfSections--;+ }+ }+ if ((mRelocOffset - mHiiRsrcOffset) > 0) { CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA@@ -1757,4 +1862,145 @@ CleanUp64 ( } } +STATIC+VOID+ScanSymbol64 (+ VOID+ )+{+ UINT32 shIndex;+ UINT32 SymIndex;+ Elf_Sym *Sym;+ UINT64 SymNum;+ const UINT8 *SymName;++ for (shIndex = 0; shIndex < mEhdr->e_shnum; shIndex++) {+ //+ // Determine if this is a symbol section.+ //+ Elf_Shdr *shdr = GetShdrByIndex(shIndex);+ if (!IsSymbolShdr(shdr)) {+ continue;+ }++ UINT8 *Symtab = (UINT8*)mEhdr + shdr->sh_offset;+ SymNum = (shdr->sh_size) / (shdr->sh_entsize);++ //+ // First Get PrmModuleExportDescriptor+ //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ }++ if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) == 0) {+ //+ // Find PrmHandler Number and Name+ //+ FindPrmHandler(Sym->st_value);++ strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value);+ mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1;+ mExportSymNum ++;+ break;+ }+ }++ //+ // Second Get PrmHandler+ //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ UINT32 ExpIndex;+ Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ }++ for (ExpIndex = 0; ExpIndex < (mExportSymNum -1); ExpIndex++) {+ if (strcmp((CHAR8*)SymName, mExportSymName[ExpIndex]) != 0) {+ continue;+ }+ mExportRVA[ExpIndex] = (UINT32)(Sym->st_value);+ mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1;+ }+ }++ break;+ }+}++STATIC+VOID+WriteExport64 (+ VOID+ )+{+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;+ EFI_IMAGE_EXPORT_DIRECTORY *ExportDir;+ EFI_IMAGE_DATA_DIRECTORY *DataDir;+ UINT32 FileNameOffset;+ UINT32 FuncOffset;+ UINT16 Index;+ UINT8 *Tdata = NULL;++ ExportDir = (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset);+ ExportDir->Characteristics = 0;+ ExportDir->TimeDateStamp = 0;+ ExportDir->MajorVersion = 0;+ ExportDir->MinorVersion =0;+ ExportDir->Name = 0;+ ExportDir->NumberOfFunctions = mExportSymNum;+ ExportDir->NumberOfNames = mExportSymNum;+ ExportDir->Base = EFI_IMAGE_EXPORT_ORDINAL_BASE;+ ExportDir->AddressOfFunctions = mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY);+ ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;+ ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;++ FileNameOffset = ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * mExportSymNum;+ FuncOffset = FileNameOffset + strlen(mInImageName) + 1;++ // Write Input image Name RVA+ Tdata = mCoffFile + 12;+ *(UINT32 *)Tdata = FileNameOffset;++ // Write Input image Name+ strcpy((char *)(mCoffFile + FileNameOffset), mInImageName);++ for (Index = 0; Index < mExportSymNum; Index++) {+ //+ // Write Export Address Table+ //+ Tdata = mCoffFile + ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = mExportRVA[Index];++ //+ // Write Export Name Pointer Table+ //+ Tdata = mCoffFile + ExportDir->AddressOfNames + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = FuncOffset;++ //+ // Write Export Ordinal table+ //+ Tdata = mCoffFile + ExportDir->AddressOfNameOrdinals + Index * EFI_IMAGE_EXPORT_ORDINAL_SIZE;+ *(UINT16 *)Tdata = Index;++ //+ // Write Export Name Table+ //+ strcpy((char *)(mCoffFile + FuncOffset), mExportSymName[Index]);+ FuncOffset += strlen(mExportSymName[Index]) + 1;+ }++ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);+ DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT];+ DataDir->VirtualAddress = mExportOffset;+ DataDir->Size = 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 ( VerboseMsg ("Write debug info."); ElfFunctions.WriteDebug (); + //+ // For PRM Driver to Write export info.+ //+ if (mExportFlag) {+ VerboseMsg ("Scan symbol info.");+ ElfFunctions.ScanSymbol ();+ VerboseMsg ("Write export info.");+ ElfFunctions.WriteExport ();+ }+ // // Make sure image size is correct before returning the new image. //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 *mCoffFile; extern UINT32 mTableOffset; extern UINT32 mOutImageType; extern UINT32 mFileBufferSize;+extern BOOLEAN mExportFlag; // // 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 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 {+ EFI_GUID PrmHandlerGuid;+ CHAR8 PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];+} PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT;++typedef struct {+ UINT64 Signature;+ UINT16 Revision;+ UINT16 NumberPrmHandlers;+ EFI_GUID PlatformGuid;+ EFI_GUID ModuleGuid;+} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;++typedef struct {+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header;+ PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT PrmHandlerExportDescriptors[1];+} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;++#pragma pack(pop) // // Filter Types@@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; typedef enum { SECTION_TEXT, SECTION_HII,- SECTION_DATA+ SECTION_DATA,+ SECTION_SYMBOL } SECTION_FILTER_TYPES; @@ -50,6 +88,8 @@ typedef struct { BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); VOID (*WriteRelocations) (); VOID (*WriteDebug) ();+ VOID (*ScanSymbol) ();+ VOID (*WriteExport) (); VOID (*SetImageSize) (); VOID (*CleanUp) (); diff --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 = 0; UINT32 mImageSize = 0; UINT32 mOutImageType = FW_DUMMY_IMAGE; BOOLEAN mIsConvertXip = FALSE;-+BOOLEAN mExportFlag = FALSE; STATIC EFI_STATUS@@ -1436,6 +1436,15 @@ Returns: continue; } + if (stricmp (argv[0], "--PRM") == 0) {+ if (!mExportFlag) {+ mExportFlag = TRUE;+ }+ argc --;+ argv ++;+ continue;+ }+ if (argv[0][0] == '-') { Error (NULL, 0, 1000, "Unknown 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 { UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; +//+// Based export types.+//+#define EFI_IMAGE_EXPORT_ORDINAL_BASE 1+#define EFI_IMAGE_EXPORT_ADDR_SIZE 4+#define EFI_IMAGE_EXPORT_ORDINAL_SIZE 2+ /// /// DLL support. /// Import Format-- 2.26.2.windows.1 [-- Attachment #1.2: Type: text/html, Size: 35127 bytes --] [-- Attachment #2: image001.png --] [-- Type: image/png, Size: 75854 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* 回复: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF 2022-01-17 3:09 ` Huang, Li-Xia @ 2022-01-18 5:20 ` gaoliming 2022-01-18 6:19 ` Huang, Li-Xia 0 siblings, 1 reply; 10+ messages in thread From: gaoliming @ 2022-01-18 5:20 UTC (permalink / raw) To: devel, lisa.huang, 'Feng, Bob C' Cc: 'Chen, Christine', 'Wu, Yidong', 'Xu, Wei6', 'You, Benjamin' [-- Attachment #1.1: Type: text/plain, Size: 19168 bytes --] Lisa: Can you give more background about PRM usage? What new usage requires RPM? Can you add the detail in BZ? Thanks Liming 发件人: devel@edk2.groups.io <devel@edk2.groups.io> 代表 Huang, Li-Xia 发送时间: 2022年1月17日 11:09 收件人: Feng, Bob C <bob.c.feng@intel.com>; devel@edk2.groups.io 抄送: Gao, Liming <gaoliming@byosoft.com.cn>; Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin <benjamin.you@intel.com> 主题: Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF Hi Bob, Thanks for your comments. 1. I will add the help information for "--PRM"; 2. @@ -750,7 +818,7 @@ ScanSections64 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; } - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } } 1) Above change is to Set mCoffAlignment to the maximum alignment of the input sections including symbol section. The symbol section will only exist with below change, so it should have no effect to other drivers. build_rule.template: <Command.GCC> $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).debug #$(OBJCOPY) --strip-unneeded -R .eh_frame ${src} $(OBJCOPY) $(OBJCOPY_STRIPFLAG) ${src} tools_def.template: *_*_*_OBJCOPY_STRIPFLAG = --strip-unneeded -R .eh_frame PrmAddrTransDsm.inf: [BuildOptions.common] ... GCC: *_*_*_OBJCOPY_STRIPFLAG == -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 <bob.c.feng@intel.com <mailto:bob.c.feng@intel.com> > Sent: 2022年1月14日 14:12 To: Huang, Li-Xia <lisa.huang@intel.com <mailto:lisa.huang@intel.com> >; devel@edk2.groups.io <mailto:devel@edk2.groups.io> Cc: Gao, Liming <gaoliming@byosoft.com.cn <mailto:gaoliming@byosoft.com.cn> >; Chen, Christine <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com> > 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 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; } - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } } Thanks, Bob -----Original Message----- From: Huang, Li-Xia < <mailto:lisa.huang@intel.com> lisa.huang@intel.com> Sent: Wednesday, January 12, 2022 3:44 PM To: <mailto:devel@edk2.groups.io> devel@edk2.groups.io Cc: Huang, Li-Xia < <mailto:lisa.huang@intel.com> lisa.huang@intel.com>; Gao, Liming < <mailto:gaoliming@byosoft.com.cn> gaoliming@byosoft.com.cn>; Feng, Bob C < <mailto:bob.c.feng@intel.com> bob.c.feng@intel.com>; Chen, Christine < <mailto:yuwei.chen@intel.com> yuwei.chen@intel.com> Subject: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF REF: <https://bugzilla.tianocore.org/show_bug.cgi?id=3802> https://bugzilla.tianocore.org/show_bug.cgi?id=3802 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 < <mailto:gaoliming@byosoft.com.cn> gaoliming@byosoft.com.cn> Cc: Bob Feng < <mailto:bob.c.feng@intel.com> bob.c.feng@intel.com> Cc: Yuwei Chen < <mailto:yuwei.chen@intel.com> yuwei.chen@intel.com> Signed-off-by: Lixia Huang < <mailto:lisa.huang@intel.com> lisa.huang@intel. com> --- BaseTools/Source/C/GenFw/Elf64Convert.c | 254 +++++++++++++++++- BaseTools/Source/C/GenFw/ElfConvert.c | 10 + BaseTools/Source/C/GenFw/ElfConvert.h | 42 ++- BaseTools/Source/C/GenFw/GenFw.c | 11 +- .../C/Include/IndustryStandard/PeImage.h | 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 ( VOID ); +STATIC+VOID+ScanSymbol64 (+ VOID+ );++STATIC+VOID+WriteExport64 (+ VOID+ );+ 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 = 0; STATIC INT32 mRiscVPass1Offset; STATIC INT32 mRiscVPass1GotFixup; +//+// Used for Export section.+//+STATIC UINT32 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 ( ElfFunctions->SetImageSize = SetImageSize64; ElfFunctions->CleanUp = CleanUp64; + if (mExportFlag) {+ ElfFunctions->ScanSymbol = ScanSymbol64;+ ElfFunctions->WriteExport = WriteExport64;+ } return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); } +STATIC+BOOLEAN+IsSymbolShdr (+ Elf_Shdr *Shdr+ )+{+ Elf_Shdr *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx);++ return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, ELF_SYMBOL_SECTION_NAME) == 0);+}+ STATIC BOOLEAN IsDataShdr (@@ -335,6 +370,38 @@ GetSymName ( return StrtabContents + Sym->st_name; } +//+// Get Prm Handler number and name+//+STATIC+VOID+FindPrmHandler (+ UINT64 Offset+ )+{+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport;+ UINT32 NameOffset;+ UINT32 HandlerNum;+ UINT32 Index;+ UINT8 SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];++ PrmExport = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset);+ NameOffset = sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + sizeof(EFI_GUID);++ for (HandlerNum = 0; HandlerNum < PrmExport->NumberPrmHandlers; HandlerNum++) {+ for (Index = 0; Index < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) {+ SymName[Index] = *((UINT8 *)PrmExport + NameOffset + Index);+ if (SymName[Index] == 0) {+ break;+ }+ }++ strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ NameOffset += PRM_HANDLER_NAME_MAXIMUM_LENGTH + sizeof(EFI_GUID);+ mExportSymNum ++;+ }+}+ // // Find the ELF section hosting the GOT from an ELF Rva // of a single GOT entry. Normally, GOT is placed in@@ -717,6 +784,7 @@ ScanSections64 ( UINT32 CoffEntry; UINT32 SectionCount; BOOLEAN FoundSection;+ UINT32 Offset; CoffEntry = 0; mCoffOffset = 0;@@ -750,7 +818,7 @@ ScanSections64 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; }- if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) {+ if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } }@@ -880,6 +948,16 @@ ScanSections64 ( Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); } + //+ // The Symbol sections.+ //+ if (mExportFlag) {+ mExportOffset = mCoffOffset;+ mExportSize = sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;+ mCoffOffset += mExportSize;+ mCoffOffset = CoffAlign(mCoffOffset);+ }+ // // The HII resource sections. //@@ -962,7 +1040,11 @@ ScanSections64 ( | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset;- NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;+ if(mExportFlag) {+ NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mExportOffset;+ } else {+ NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;+ } NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; @@ -989,8 +1071,17 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + //+ // If found symbol, add edata section between data and rsrc section+ //+ if(mExportFlag) {+ Offset = mExportOffset;+ } else {+ Offset = mHiiRsrcOffset;+ }+ if ((mHiiRsrcOffset - mDataOffset) > 0) {- CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset,+ CreateSectionHeader (".data", mDataOffset, Offset - mDataOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ);@@ -999,6 +1090,20 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + if(mExportFlag) {+ if ((mHiiRsrcOffset - mExportOffset) > 0) {+ CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - mExportOffset,+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA+ | EFI_IMAGE_SCN_MEM_READ);+ NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPOR T].Size = mHiiRsrcOffset - mExportOffset;+ NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPOR T].VirtualAddress = mExportOffset;+ NtHdr->Pe32Plus.FileHeader.NumberOfSections++;+ } else {+ // Don't make a section of size 0.+ NtHdr->Pe32Plus.FileHeader.NumberOfSections--;+ }+ }+ if ((mRelocOffset - mHiiRsrcOffset) > 0) { CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA@@ -1757,4 +1862,145 @@ CleanUp64 ( } } +STATIC+VOID+ScanSymbol64 (+ VOID+ )+{+ UINT32 shIndex;+ UINT32 SymIndex;+ Elf_Sym *Sym;+ UINT64 SymNum;+ const UINT8 *SymName;++ for (shIndex = 0; shIndex < mEhdr->e_shnum; shIndex++) {+ //+ // Determine if this is a symbol section.+ //+ Elf_Shdr *shdr = GetShdrByIndex(shIndex);+ if (!IsSymbolShdr(shdr)) {+ continue;+ }++ UINT8 *Symtab = (UINT8*)mEhdr + shdr->sh_offset;+ SymNum = (shdr->sh_size) / (shdr->sh_entsize);++ //+ // First Get PrmModuleExportDescriptor+ //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ }++ if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) == 0) {+ //+ // Find PrmHandler Number and Name+ //+ FindPrmHandler(Sym->st_value);++ strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value);+ mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1;+ mExportSymNum ++;+ break;+ }+ }++ //+ // Second Get PrmHandler+ //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ UINT32 ExpIndex;+ Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ }++ for (ExpIndex = 0; ExpIndex < (mExportSymNum -1); ExpIndex++) {+ if (strcmp((CHAR8*)SymName, mExportSymName[ExpIndex]) != 0) {+ continue;+ }+ mExportRVA[ExpIndex] = (UINT32)(Sym->st_value);+ mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1;+ }+ }++ break;+ }+}++STATIC+VOID+WriteExport64 (+ VOID+ )+{+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;+ EFI_IMAGE_EXPORT_DIRECTORY *ExportDir;+ EFI_IMAGE_DATA_DIRECTORY *DataDir;+ UINT32 FileNameOffset;+ UINT32 FuncOffset;+ UINT16 Index;+ UINT8 *Tdata = NULL;++ ExportDir = (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset);+ ExportDir->Characteristics = 0;+ ExportDir->TimeDateStamp = 0;+ ExportDir->MajorVersion = 0;+ ExportDir->MinorVersion =0;+ ExportDir->Name = 0;+ ExportDir->NumberOfFunctions = mExportSymNum;+ ExportDir->NumberOfNames = mExportSymNum;+ ExportDir->Base = EFI_IMAGE_EXPORT_ORDINAL_BASE;+ ExportDir->AddressOfFunctions = mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY);+ ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;+ ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;++ FileNameOffset = ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * mExportSymNum;+ FuncOffset = FileNameOffset + strlen(mInImageName) + 1;++ // Write Input image Name RVA+ Tdata = mCoffFile + 12;+ *(UINT32 *)Tdata = FileNameOffset;++ // Write Input image Name+ strcpy((char *)(mCoffFile + FileNameOffset), mInImageName);++ for (Index = 0; Index < mExportSymNum; Index++) {+ //+ // Write Export Address Table+ //+ Tdata = mCoffFile + ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = mExportRVA[Index];++ //+ // Write Export Name Pointer Table+ //+ Tdata = mCoffFile + ExportDir->AddressOfNames + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = FuncOffset;++ //+ // Write Export Ordinal table+ //+ Tdata = mCoffFile + ExportDir->AddressOfNameOrdinals + Index * EFI_IMAGE_EXPORT_ORDINAL_SIZE;+ *(UINT16 *)Tdata = Index;++ //+ // Write Export Name Table+ //+ strcpy((char *)(mCoffFile + FuncOffset), mExportSymName[Index]);+ FuncOffset += strlen(mExportSymName[Index]) + 1;+ }++ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);+ DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPO RT];+ DataDir->VirtualAddress = mExportOffset;+ DataDir->Size = 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 ( VerboseMsg ("Write debug info."); ElfFunctions.WriteDebug (); + //+ // For PRM Driver to Write export info.+ //+ if (mExportFlag) {+ VerboseMsg ("Scan symbol info.");+ ElfFunctions.ScanSymbol ();+ VerboseMsg ("Write export info.");+ ElfFunctions.WriteExport ();+ }+ // // Make sure image size is correct before returning the new image. //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 *mCoffFile; extern UINT32 mTableOffset; extern UINT32 mOutImageType; extern UINT32 mFileBufferSize;+extern BOOLEAN mExportFlag; // // 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 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 {+ EFI_GUID PrmHandlerGuid;+ CHAR8 PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];+} PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT;++typedef struct {+ UINT64 Signature;+ UINT16 Revision;+ UINT16 NumberPrmHandlers;+ EFI_GUID PlatformGuid;+ EFI_GUID ModuleGuid;+} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;++typedef struct {+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header;+ PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT PrmHandlerExportDescriptors[1];+} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;++#pragma pack(pop) // // Filter Types@@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; typedef enum { SECTION_TEXT, SECTION_HII,- SECTION_DATA+ SECTION_DATA, + SECTION_SYMBOL } SECTION_FILTER_TYPES; @@ -50,6 +88,8 @@ typedef struct { BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); VOID (*WriteRelocations) (); VOID (*WriteDebug) ();+ VOID (*ScanSymbol) ();+ VOID (*WriteExport) (); VOID (*SetImageSize) (); VOID (*CleanUp) (); diff --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 = 0; UINT32 mImageSize = 0; UINT32 mOutImageType = FW_DUMMY_IMAGE; BOOLEAN mIsConvertXip = FALSE;-+BOOLEAN mExportFlag = FALSE; STATIC EFI_STATUS@@ -1436,6 +1436,15 @@ Returns: continue; } + if (stricmp (argv[0], "--PRM") == 0) {+ if (!mExportFlag) {+ mExportFlag = TRUE;+ }+ argc --;+ argv ++;+ continue;+ }+ if (argv[0][0] == '-') { Error (NULL, 0, 1000, "Unknown 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 { UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; +//+// Based export types.+//+#define EFI_IMAGE_EXPORT_ORDINAL_BASE 1+#define EFI_IMAGE_EXPORT_ADDR_SIZE 4+#define EFI_IMAGE_EXPORT_ORDINAL_SIZE 2+ /// /// DLL support. /// Import Format-- 2.26.2.windows.1 [-- Attachment #1.2: Type: text/html, Size: 40995 bytes --] [-- Attachment #2: image001.png --] [-- Type: image/png, Size: 75854 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF 2022-01-18 5:20 ` 回复: " gaoliming @ 2022-01-18 6:19 ` Huang, Li-Xia 2022-01-22 2:50 ` Michael Kubacki 0 siblings, 1 reply; 10+ messages in thread From: Huang, Li-Xia @ 2022-01-18 6:19 UTC (permalink / raw) To: Gao, Liming, devel@edk2.groups.io, Feng, Bob C Cc: Chen, Christine, Wu, Yidong, Xu, Wei6, You, Benjamin [-- Attachment #1.1: Type: text/plain, Size: 20224 bytes --] Hi Liming, Thanks for your feedback. I have added some detail in BZ. 😊 https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment Regards, Lisa From: gaoliming <gaoliming@byosoft.com.cn> Sent: 2022年1月18日 13:20 To: devel@edk2.groups.io; Huang, Li-Xia <lisa.huang@intel.com>; Feng, Bob C <bob.c.feng@intel.com> Cc: Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin <benjamin.you@intel.com> Subject: 回复: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF Lisa: Can you give more background about PRM usage? What new usage requires RPM? Can you add the detail in BZ? Thanks Liming 发件人: devel@edk2.groups.io<mailto:devel@edk2.groups.io> <devel@edk2.groups.io<mailto:devel@edk2.groups.io>> 代表 Huang, Li-Xia 发送时间: 2022年1月17日 11:09 收件人: Feng, Bob C <bob.c.feng@intel.com<mailto:bob.c.feng@intel.com>>; devel@edk2.groups.io<mailto:devel@edk2.groups.io> 抄送: Gao, Liming <gaoliming@byosoft.com.cn<mailto:gaoliming@byosoft.com.cn>>; Chen, Christine <yuwei.chen@intel.com<mailto:yuwei.chen@intel.com>>; Wu, Yidong <yidong.wu@intel.com<mailto:yidong.wu@intel.com>>; Xu, Wei6 <wei6.xu@intel.com<mailto:wei6.xu@intel.com>>; You, Benjamin <benjamin.you@intel.com<mailto:benjamin.you@intel.com>> 主题: Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF Hi Bob, Thanks for your comments. 1. I will add the help information for "--PRM"; 2. @@ -750,7 +818,7 @@ ScanSections64 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; } - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } } 1) Above change is to Set mCoffAlignment to the maximum alignment of the input sections including symbol section. The symbol section will only exist with below change, so it should have no effect to other drivers. build_rule.template: <Command.GCC> $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).debug #$(OBJCOPY) --strip-unneeded -R .eh_frame ${src} $(OBJCOPY) $(OBJCOPY_STRIPFLAG) ${src} tools_def.template: *_*_*_OBJCOPY_STRIPFLAG = --strip-unneeded -R .eh_frame PrmAddrTransDsm.inf: [BuildOptions.common] ... GCC: *_*_*_OBJCOPY_STRIPFLAG == -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). [cid:image001.png@01D80C6E.C2394A60] Regards, Lisa -----Original Message----- From: Feng, Bob C <bob.c.feng@intel.com<mailto:bob.c.feng@intel.com>> Sent: 2022年1月14日 14:12 To: Huang, Li-Xia <lisa.huang@intel.com<mailto:lisa.huang@intel.com>>; devel@edk2.groups.io<mailto:devel@edk2.groups.io> Cc: Gao, Liming <gaoliming@byosoft.com.cn<mailto:gaoliming@byosoft.com.cn>>; Chen, Christine <yuwei.chen@intel.com<mailto:yuwei.chen@intel.com>> 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 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; } - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } } Thanks, Bob -----Original Message----- From: Huang, Li-Xia <lisa.huang@intel.com<mailto:lisa.huang@intel.com>> Sent: Wednesday, January 12, 2022 3:44 PM To: devel@edk2.groups.io<mailto:devel@edk2.groups.io> Cc: Huang, Li-Xia <lisa.huang@intel.com<mailto:lisa.huang@intel.com>>; Gao, Liming <gaoliming@byosoft.com.cn<mailto:gaoliming@byosoft.com.cn>>; Feng, Bob C <bob.c.feng@intel.com<mailto:bob.c.feng@intel.com>>; Chen, Christine <yuwei.chen@intel.com<mailto:yuwei.chen@intel.com>> Subject: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3802 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 <gaoliming@byosoft.com.cn<mailto:gaoliming@byosoft.com.cn>> Cc: Bob Feng <bob.c.feng@intel.com<mailto:bob.c.feng@intel.com>> Cc: Yuwei Chen <yuwei.chen@intel.com<mailto:yuwei.chen@intel.com>> Signed-off-by: Lixia Huang <lisa.huang@intel.com<mailto:lisa.huang@intel.com>> --- BaseTools/Source/C/GenFw/Elf64Convert.c | 254 +++++++++++++++++- BaseTools/Source/C/GenFw/ElfConvert.c | 10 + BaseTools/Source/C/GenFw/ElfConvert.h | 42 ++- BaseTools/Source/C/GenFw/GenFw.c | 11 +- .../C/Include/IndustryStandard/PeImage.h | 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 ( VOID ); +STATIC+VOID+ScanSymbol64 (+ VOID+ );++STATIC+VOID+WriteExport64 (+ VOID+ );+ 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 = 0; STATIC INT32 mRiscVPass1Offset; STATIC INT32 mRiscVPass1GotFixup; +//+// Used for Export section.+//+STATIC UINT32 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 ( ElfFunctions->SetImageSize = SetImageSize64; ElfFunctions->CleanUp = CleanUp64; + if (mExportFlag) {+ ElfFunctions->ScanSymbol = ScanSymbol64;+ ElfFunctions->WriteExport = WriteExport64;+ } return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); } +STATIC+BOOLEAN+IsSymbolShdr (+ Elf_Shdr *Shdr+ )+{+ Elf_Shdr *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx);++ return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, ELF_SYMBOL_SECTION_NAME) == 0);+}+ STATIC BOOLEAN IsDataShdr (@@ -335,6 +370,38 @@ GetSymName ( return StrtabContents + Sym->st_name; } +//+// Get Prm Handler number and name+//+STATIC+VOID+FindPrmHandler (+ UINT64 Offset+ )+{+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport;+ UINT32 NameOffset;+ UINT32 HandlerNum;+ UINT32 Index;+ UINT8 SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];++ PrmExport = (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset);+ NameOffset = sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + sizeof(EFI_GUID);++ for (HandlerNum = 0; HandlerNum < PrmExport->NumberPrmHandlers; HandlerNum++) {+ for (Index = 0; Index < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) {+ SymName[Index] = *((UINT8 *)PrmExport + NameOffset + Index);+ if (SymName[Index] == 0) {+ break;+ }+ }++ strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ NameOffset += PRM_HANDLER_NAME_MAXIMUM_LENGTH + sizeof(EFI_GUID);+ mExportSymNum ++;+ }+}+ // // Find the ELF section hosting the GOT from an ELF Rva // of a single GOT entry. Normally, GOT is placed in@@ -717,6 +784,7 @@ ScanSections64 ( UINT32 CoffEntry; UINT32 SectionCount; BOOLEAN FoundSection;+ UINT32 Offset; CoffEntry = 0; mCoffOffset = 0;@@ -750,7 +818,7 @@ ScanSections64 ( if (shdr->sh_addralign <= mCoffAlignment) { continue; }- if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) {+ if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || IsSymbolShdr(shdr)) { mCoffAlignment = (UINT32)shdr->sh_addralign; } }@@ -880,6 +948,16 @@ ScanSections64 ( Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged into 1 data section. Source level debug might not work correctly.", mInImageName); } + //+ // The Symbol sections.+ //+ if (mExportFlag) {+ mExportOffset = mCoffOffset;+ mExportSize = sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;+ mCoffOffset += mExportSize;+ mCoffOffset = CoffAlign(mCoffOffset);+ }+ // // The HII resource sections. //@@ -962,7 +1040,11 @@ ScanSections64 ( | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset;- NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;+ if(mExportFlag) {+ NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mExportOffset;+ } else {+ NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - mDataOffset;+ } NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; @@ -989,8 +1071,17 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + //+ // If found symbol, add edata section between data and rsrc section+ //+ if(mExportFlag) {+ Offset = mExportOffset;+ } else {+ Offset = mHiiRsrcOffset;+ }+ if ((mHiiRsrcOffset - mDataOffset) > 0) {- CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - mDataOffset,+ CreateSectionHeader (".data", mDataOffset, Offset - mDataOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ);@@ -999,6 +1090,20 @@ ScanSections64 ( NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + if(mExportFlag) {+ if ((mHiiRsrcOffset - mExportOffset) > 0) {+ CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - mExportOffset,+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA+ | EFI_IMAGE_SCN_MEM_READ);+ NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size = mHiiRsrcOffset - mExportOffset;+ NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress = mExportOffset;+ NtHdr->Pe32Plus.FileHeader.NumberOfSections++;+ } else {+ // Don't make a section of size 0.+ NtHdr->Pe32Plus.FileHeader.NumberOfSections--;+ }+ }+ if ((mRelocOffset - mHiiRsrcOffset) > 0) { CreateSectionHeader (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA@@ -1757,4 +1862,145 @@ CleanUp64 ( } } +STATIC+VOID+ScanSymbol64 (+ VOID+ )+{+ UINT32 shIndex;+ UINT32 SymIndex;+ Elf_Sym *Sym;+ UINT64 SymNum;+ const UINT8 *SymName;++ for (shIndex = 0; shIndex < mEhdr->e_shnum; shIndex++) {+ //+ // Determine if this is a symbol section.+ //+ Elf_Shdr *shdr = GetShdrByIndex(shIndex);+ if (!IsSymbolShdr(shdr)) {+ continue;+ }++ UINT8 *Symtab = (UINT8*)mEhdr + shdr->sh_offset;+ SymNum = (shdr->sh_size) / (shdr->sh_entsize);++ //+ // First Get PrmModuleExportDescriptor+ //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ }++ if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) == 0) {+ //+ // Find PrmHandler Number and Name+ //+ FindPrmHandler(Sym->st_value);++ strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value);+ mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1;+ mExportSymNum ++;+ break;+ }+ }++ //+ // Second Get PrmHandler+ //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ UINT32 ExpIndex;+ Sym = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ }++ for (ExpIndex = 0; ExpIndex < (mExportSymNum -1); ExpIndex++) {+ if (strcmp((CHAR8*)SymName, mExportSymName[ExpIndex]) != 0) {+ continue;+ }+ mExportRVA[ExpIndex] = (UINT32)(Sym->st_value);+ mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1;+ }+ }++ break;+ }+}++STATIC+VOID+WriteExport64 (+ VOID+ )+{+ EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;+ EFI_IMAGE_EXPORT_DIRECTORY *ExportDir;+ EFI_IMAGE_DATA_DIRECTORY *DataDir;+ UINT32 FileNameOffset;+ UINT32 FuncOffset;+ UINT16 Index;+ UINT8 *Tdata = NULL;++ ExportDir = (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset);+ ExportDir->Characteristics = 0;+ ExportDir->TimeDateStamp = 0;+ ExportDir->MajorVersion = 0;+ ExportDir->MinorVersion =0;+ ExportDir->Name = 0;+ ExportDir->NumberOfFunctions = mExportSymNum;+ ExportDir->NumberOfNames = mExportSymNum;+ ExportDir->Base = EFI_IMAGE_EXPORT_ORDINAL_BASE;+ ExportDir->AddressOfFunctions = mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY);+ ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;+ ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;++ FileNameOffset = ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * mExportSymNum;+ FuncOffset = FileNameOffset + strlen(mInImageName) + 1;++ // Write Input image Name RVA+ Tdata = mCoffFile + 12;+ *(UINT32 *)Tdata = FileNameOffset;++ // Write Input image Name+ strcpy((char *)(mCoffFile + FileNameOffset), mInImageName);++ for (Index = 0; Index < mExportSymNum; Index++) {+ //+ // Write Export Address Table+ //+ Tdata = mCoffFile + ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = mExportRVA[Index];++ //+ // Write Export Name Pointer Table+ //+ Tdata = mCoffFile + ExportDir->AddressOfNames + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = FuncOffset;++ //+ // Write Export Ordinal table+ //+ Tdata = mCoffFile + ExportDir->AddressOfNameOrdinals + Index * EFI_IMAGE_EXPORT_ORDINAL_SIZE;+ *(UINT16 *)Tdata = Index;++ //+ // Write Export Name Table+ //+ strcpy((char *)(mCoffFile + FuncOffset), mExportSymName[Index]);+ FuncOffset += strlen(mExportSymName[Index]) + 1;+ }++ NtHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);+ DataDir = &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT];+ DataDir->VirtualAddress = mExportOffset;+ DataDir->Size = 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 ( VerboseMsg ("Write debug info."); ElfFunctions.WriteDebug (); + //+ // For PRM Driver to Write export info.+ //+ if (mExportFlag) {+ VerboseMsg ("Scan symbol info.");+ ElfFunctions.ScanSymbol ();+ VerboseMsg ("Write export info.");+ ElfFunctions.WriteExport ();+ }+ // // Make sure image size is correct before returning the new image. //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 *mCoffFile; extern UINT32 mTableOffset; extern UINT32 mOutImageType; extern UINT32 mFileBufferSize;+extern BOOLEAN mExportFlag; // // 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 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 {+ EFI_GUID PrmHandlerGuid;+ CHAR8 PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];+} PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT;++typedef struct {+ UINT64 Signature;+ UINT16 Revision;+ UINT16 NumberPrmHandlers;+ EFI_GUID PlatformGuid;+ EFI_GUID ModuleGuid;+} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;++typedef struct {+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header;+ PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT PrmHandlerExportDescriptors[1];+} PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;++#pragma pack(pop) // // Filter Types@@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; typedef enum { SECTION_TEXT, SECTION_HII,- SECTION_DATA+ SECTION_DATA,+ SECTION_SYMBOL } SECTION_FILTER_TYPES; @@ -50,6 +88,8 @@ typedef struct { BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); VOID (*WriteRelocations) (); VOID (*WriteDebug) ();+ VOID (*ScanSymbol) ();+ VOID (*WriteExport) (); VOID (*SetImageSize) (); VOID (*CleanUp) (); diff --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 = 0; UINT32 mImageSize = 0; UINT32 mOutImageType = FW_DUMMY_IMAGE; BOOLEAN mIsConvertXip = FALSE;-+BOOLEAN mExportFlag = FALSE; STATIC EFI_STATUS@@ -1436,6 +1436,15 @@ Returns: continue; } + if (stricmp (argv[0], "--PRM") == 0) {+ if (!mExportFlag) {+ mExportFlag = TRUE;+ }+ argc --;+ argv ++;+ continue;+ }+ if (argv[0][0] == '-') { Error (NULL, 0, 1000, "Unknown 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 { UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; +//+// Based export types.+//+#define EFI_IMAGE_EXPORT_ORDINAL_BASE 1+#define EFI_IMAGE_EXPORT_ADDR_SIZE 4+#define EFI_IMAGE_EXPORT_ORDINAL_SIZE 2+ /// /// DLL support. /// Import Format-- 2.26.2.windows.1 [-- Attachment #1.2: Type: text/html, Size: 43645 bytes --] [-- Attachment #2: image001.png --] [-- Type: image/png, Size: 75854 bytes --] ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF 2022-01-18 6:19 ` Huang, Li-Xia @ 2022-01-22 2:50 ` Michael Kubacki 2022-01-26 8:16 ` lisa.huang 0 siblings, 1 reply; 10+ messages in thread From: Michael Kubacki @ 2022-01-22 2:50 UTC (permalink / raw) To: devel, lisa.huang, Gao, Liming, Feng, Bob C Cc: Chen, Christine, Wu, Yidong, Xu, Wei6, You, Benjamin, mikuback@linux.microsoft.com Hi Lisa, Thank you for contributing this. Please include me on functionality related to PRM. I was using the PRM_EXPORT_API macro (https://github.com/tianocore/edk2-staging/blob/9da8abf66505d8ff636aaecc429a5237ce226650/PrmPkg/Include/Prm.h#L17) to support this on MS toolchain. It looks like this is to add similar functionality for ELF binaries using GenFw? Thanks, Michael On 1/18/2022 1:19 AM, Huang, Li-Xia wrote: > Hi Liming, > > Thanks for your feedback. > > I have added some detail in BZ. 😊 > > https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment > <https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment> > > Regards, > > Lisa > > *From:*gaoliming <gaoliming@byosoft.com.cn> > *Sent:* 2022年1月18日13:20 > *To:* devel@edk2.groups.io; Huang, Li-Xia <lisa.huang@intel.com>; Feng, > Bob C <bob.c.feng@intel.com> > *Cc:* Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong > <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin > <benjamin.you@intel.com> > *Subject:* 回复: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add > export table in PE-COFF > > Lisa: > > Can you give more background about PRM usage? What new usage requires > RPM? Can you add the detail in BZ? > > Thanks > > Liming > > *发件人**:*devel@edk2.groups.io > <mailto:devel@edk2.groups.io><devel@edk2.groups.io > <mailto:devel@edk2.groups.io>> *代表 *Huang, Li-Xia > *发送时间:* 2022年1月17日 11:09 > *收件人:* Feng, Bob C <bob.c.feng@intel.com > <mailto:bob.c.feng@intel.com>>; devel@edk2.groups.io > <mailto:devel@edk2.groups.io> > *抄送:* Gao, Liming <gaoliming@byosoft.com.cn > <mailto:gaoliming@byosoft.com.cn>>; Chen, Christine > <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>>; Wu, Yidong > <yidong.wu@intel.com <mailto:yidong.wu@intel.com>>; Xu, Wei6 > <wei6.xu@intel.com <mailto:wei6.xu@intel.com>>; You, Benjamin > <benjamin.you@intel.com <mailto:benjamin.you@intel.com>> > *主题:* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export > table in PE-COFF > > Hi Bob, > > Thanks for your comments. > > 1. I will add the help information for "--PRM"; > > 2. > > @@ -750,7 +818,7 @@ ScanSections64 ( > > if (shdr->sh_addralign <= mCoffAlignment) { > > continue; > > } > > - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { > > + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || > IsSymbolShdr(shdr)) { > > mCoffAlignment = (UINT32)shdr->sh_addralign; > > } > > } > > 1) Above change is to Set mCoffAlignment to the maximum alignment of the > input sections including symbol section. > > The symbol section will only exist with below change, so it should > have no effect to other drivers. > > build_rule.template: > > <Command.GCC> > > $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).debug > > #$(OBJCOPY) --strip-unneeded -R .eh_frame ${src} > > $(OBJCOPY) $(OBJCOPY_STRIPFLAG) ${src} > > tools_def.template: > > *_*_*_OBJCOPY_STRIPFLAG = --strip-unneeded -R .eh_frame > > PrmAddrTransDsm.inf: > > [BuildOptions.common] > > ... > > GCC: *_*_*_OBJCOPY_STRIPFLAG == -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 <bob.c.feng@intel.com <mailto:bob.c.feng@intel.com>> > Sent: 2022年1月14日 14:12 > To: Huang, Li-Xia <lisa.huang@intel.com <mailto:lisa.huang@intel.com>>; > devel@edk2.groups.io <mailto:devel@edk2.groups.io> > Cc: Gao, Liming <gaoliming@byosoft.com.cn > <mailto:gaoliming@byosoft.com.cn>>; Chen, Christine > <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>> > 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 ( > > if (shdr->sh_addralign <= mCoffAlignment) { > > continue; > > } > > - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) { > > + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || > IsSymbolShdr(shdr)) { > > mCoffAlignment = (UINT32)shdr->sh_addralign; > > } > > } > > Thanks, > > Bob > > -----Original Message----- > > From: Huang, Li-Xia <lisa.huang@intel.com <mailto:lisa.huang@intel.com>> > > Sent: Wednesday, January 12, 2022 3:44 PM > > To: devel@edk2.groups.io <mailto:devel@edk2.groups.io> > > Cc: Huang, Li-Xia <lisa.huang@intel.com <mailto:lisa.huang@intel.com>>; > Gao, Liming <gaoliming@byosoft.com.cn > <mailto:gaoliming@byosoft.com.cn>>; Feng, Bob C <bob.c.feng@intel.com > <mailto:bob.c.feng@intel.com>>; Chen, Christine <yuwei.chen@intel.com > <mailto:yuwei.chen@intel.com>> > > Subject: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export > table in PE-COFF > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3802 > <https://bugzilla.tianocore.org/show_bug.cgi?id=3802> > > 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 <gaoliming@byosoft.com.cn <mailto:gaoliming@byosoft.com.cn>> > > Cc: Bob Feng <bob.c.feng@intel.com <mailto:bob.c.feng@intel.com>> > > Cc: Yuwei Chen <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>> > > Signed-off-by: Lixia Huang <lisa.huang@intel.com > <mailto:lisa.huang@intel.com>> > > --- > > BaseTools/Source/C/GenFw/Elf64Convert.c | 254 +++++++++++++++++- > > BaseTools/Source/C/GenFw/ElfConvert.c | 10 + > > BaseTools/Source/C/GenFw/ElfConvert.h | 42 ++- > > BaseTools/Source/C/GenFw/GenFw.c | 11 +- > > .../C/Include/IndustryStandard/PeImage.h | 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 ( > > VOID ); +STATIC+VOID+ScanSymbol64 (+ VOID+ > );++STATIC+VOID+WriteExport64 (+ VOID+ );+ 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 = 0; > > STATIC INT32 mRiscVPass1Offset; STATIC INT32 > mRiscVPass1GotFixup; +//+// Used for Export section.+//+STATIC > UINT32 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 ( > > ElfFunctions->SetImageSize = SetImageSize64; ElfFunctions->CleanUp > = CleanUp64; + if (mExportFlag) {+ ElfFunctions->ScanSymbol = > ScanSymbol64;+ ElfFunctions->WriteExport = WriteExport64;+ } > return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( > > return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + > Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); } > +STATIC+BOOLEAN+IsSymbolShdr (+ Elf_Shdr *Shdr+ )+{+ Elf_Shdr > *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx);++ return (BOOLEAN) > (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, > ELF_SYMBOL_SECTION_NAME) == 0);+}+ STATIC BOOLEAN IsDataShdr (@@ -335,6 > +370,38 @@ GetSymName ( > > return StrtabContents + Sym->st_name; } +//+// Get Prm Handler > number and name+//+STATIC+VOID+FindPrmHandler (+ UINT64 Offset+ )+{+ > PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport;+ UINT32 > NameOffset;+ UINT32 HandlerNum;+ UINT32 Index;+ UINT8 > SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];++ PrmExport = > (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset);+ > NameOffset = sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + > sizeof(EFI_GUID);++ for (HandlerNum = 0; HandlerNum < > PrmExport->NumberPrmHandlers; HandlerNum++) {+ for (Index = 0; Index > < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) {+ SymName[Index] = > *((UINT8 *)PrmExport + NameOffset + Index);+ if (SymName[Index] == > 0) {+ break;+ }+ }++ strcpy(mExportSymName[mExportSymNum], > (CHAR8*)SymName);+ NameOffset += PRM_HANDLER_NAME_MAXIMUM_LENGTH + > sizeof(EFI_GUID);+ mExportSymNum ++;+ }+}+ // // Find the ELF > section hosting the GOT from an ELF Rva // of a single GOT entry. > Normally, GOT is placed in@@ -717,6 +784,7 @@ ScanSections64 ( > > UINT32 CoffEntry; > UINT32 SectionCount; > BOOLEAN FoundSection;+ > UINT32 Offset; CoffEntry = 0; mCoffOffset > = 0;@@ -750,7 +818,7 @@ ScanSections64 ( > > if (shdr->sh_addralign <= mCoffAlignment) { continue; > }- if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) > {+ if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) || > IsSymbolShdr(shdr)) { mCoffAlignment = > (UINT32)shdr->sh_addralign; } }@@ -880,6 +948,16 @@ ScanSections64 ( > > Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged > into 1 data section. Source level debug might not work correctly.", > mInImageName); } + //+ // The Symbol sections.+ //+ if > (mExportFlag) {+ mExportOffset = mCoffOffset;+ mExportSize = > sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;+ > mCoffOffset += mExportSize;+ mCoffOffset = CoffAlign(mCoffOffset);+ > }+ // // The HII resource sections. //@@ -962,7 +1040,11 @@ > ScanSections64 ( > > | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; > NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - mTextOffset;- > NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - > mDataOffset;+ if(mExportFlag) {+ > NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - > mExportOffset;+ } else {+ > NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - > mDataOffset;+ } > NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; > NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; @@ > -989,8 +1071,17 @@ ScanSections64 ( > > NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + //+ // If > found symbol, add edata section between data and rsrc section+ //+ > if(mExportFlag) {+ Offset = mExportOffset;+ } else {+ Offset = > mHiiRsrcOffset;+ }+ if ((mHiiRsrcOffset - mDataOffset) > 0) {- > CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - > mDataOffset,+ CreateSectionHeader (".data", mDataOffset, Offset - > mDataOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA > | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ);@@ -999,6 +1090,20 > @@ ScanSections64 ( > > NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + > if(mExportFlag) {+ if ((mHiiRsrcOffset - mExportOffset) > 0) {+ > CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - > mExportOffset,+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA+ | > EFI_IMAGE_SCN_MEM_READ);+ > NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].Size > = mHiiRsrcOffset - mExportOffset;+ > NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress > = mExportOffset;+ NtHdr->Pe32Plus.FileHeader.NumberOfSections++;+ } > else {+ // Don't make a section of size 0.+ > NtHdr->Pe32Plus.FileHeader.NumberOfSections--;+ }+ }+ if > ((mRelocOffset - mHiiRsrcOffset) > 0) { CreateSectionHeader > (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, > EFI_IMAGE_SCN_CNT_INITIALIZED_DATA@@ -1757,4 +1862,145 @@ CleanUp64 ( > > } } +STATIC+VOID+ScanSymbol64 (+ VOID+ )+{+ UINT32 > shIndex;+ UINT32 SymIndex;+ Elf_Sym *Sym;+ UINT64 > SymNum;+ const UINT8 *SymName;++ for (shIndex = 0; shIndex < > mEhdr->e_shnum; shIndex++) {+ //+ // Determine if this is a symbol > section.+ //+ Elf_Shdr *shdr = GetShdrByIndex(shIndex);+ if > (!IsSymbolShdr(shdr)) {+ continue;+ }++ UINT8 *Symtab = > (UINT8*)mEhdr + shdr->sh_offset;+ SymNum = (shdr->sh_size) / > (shdr->sh_entsize);++ //+ // First Get PrmModuleExportDescriptor+ > //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ Sym = > (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = > GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ > }++ if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) > == 0) {+ //+ // Find PrmHandler Number and Name+ > //+ FindPrmHandler(Sym->st_value);++ > strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ > mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value);+ mExportSize > += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + > strlen((CHAR8 *)SymName) + 1;+ mExportSymNum ++;+ > break;+ }+ }++ //+ // Second Get PrmHandler+ //+ for > (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ UINT32 > ExpIndex;+ Sym = (Elf_Sym *)(Symtab + SymIndex * > shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName == > NULL) {+ continue;+ }++ for (ExpIndex = 0; ExpIndex < > (mExportSymNum -1); ExpIndex++) {+ if (strcmp((CHAR8*)SymName, > mExportSymName[ExpIndex]) != 0) {+ continue;+ }+ > mExportRVA[ExpIndex] = (UINT32)(Sym->st_value);+ mExportSize += 2 > * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + > strlen((CHAR8 *)SymName) + 1;+ }+ }++ break;+ > }+}++STATIC+VOID+WriteExport64 (+ VOID+ )+{+ > EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;+ > EFI_IMAGE_EXPORT_DIRECTORY *ExportDir;+ > EFI_IMAGE_DATA_DIRECTORY *DataDir;+ UINT32 > FileNameOffset;+ UINT32 FuncOffset;+ > UINT16 Index;+ > UINT8 *Tdata = NULL;++ ExportDir = > (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset);+ > ExportDir->Characteristics = 0;+ ExportDir->TimeDateStamp = 0;+ > ExportDir->MajorVersion = 0;+ ExportDir->MinorVersion =0;+ > ExportDir->Name = 0;+ ExportDir->NumberOfFunctions = mExportSymNum;+ > ExportDir->NumberOfNames = mExportSymNum;+ ExportDir->Base = > EFI_IMAGE_EXPORT_ORDINAL_BASE;+ ExportDir->AddressOfFunctions = > mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY);+ > ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + > EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;+ > ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + > EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;++ FileNameOffset = > ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * > mExportSymNum;+ FuncOffset = FileNameOffset + strlen(mInImageName) + > 1;++ // Write Input image Name RVA+ Tdata = mCoffFile + 12;+ *(UINT32 > *)Tdata = FileNameOffset;++ // Write Input image Name+ strcpy((char > *)(mCoffFile + FileNameOffset), mInImageName);++ for (Index = 0; Index > < mExportSymNum; Index++) {+ //+ // Write Export Address Table+ > //+ Tdata = mCoffFile + ExportDir->AddressOfFunctions + Index * > EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = > mExportRVA[Index];++ //+ // Write Export Name Pointer Table+ > //+ Tdata = mCoffFile + ExportDir->AddressOfNames + Index * > EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = FuncOffset;++ //+ > // Write Export Ordinal table+ //+ Tdata = mCoffFile + > ExportDir->AddressOfNameOrdinals + Index * > EFI_IMAGE_EXPORT_ORDINAL_SIZE;+ *(UINT16 *)Tdata = Index;++ //+ > // Write Export Name Table+ //+ strcpy((char *)(mCoffFile + > FuncOffset), mExportSymName[Index]);+ FuncOffset += > strlen(mExportSymName[Index]) + 1;+ }++ NtHdr = > (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);+ DataDir > = > &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_EXPORT];+ > DataDir->VirtualAddress = mExportOffset;+ DataDir->Size = > 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 ( > > VerboseMsg ("Write debug info."); ElfFunctions.WriteDebug (); + > //+ // For PRM Driver to Write export info.+ //+ if (mExportFlag) > {+ VerboseMsg ("Scan symbol info.");+ ElfFunctions.ScanSymbol > ();+ VerboseMsg ("Write export info.");+ ElfFunctions.WriteExport > ();+ }+ // // Make sure image size is correct before returning the > new image. //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 *mCoffFile; extern UINT32 mTableOffset; > extern UINT32 mOutImageType; extern UINT32 mFileBufferSize;+extern > BOOLEAN mExportFlag; // // 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 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 {+ EFI_GUID > PrmHandlerGuid;+ CHAR8 > PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];+} > PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT;++typedef struct {+ > UINT64 Signature;+ > UINT16 Revision;+ > UINT16 NumberPrmHandlers;+ EFI_GUID > PlatformGuid;+ EFI_GUID ModuleGuid;+} > PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;++typedef struct {+ > PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header;+ > PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT > PrmHandlerExportDescriptors[1];+} > PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;++#pragma pack(pop) // // Filter > Types@@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; > > typedef enum { SECTION_TEXT, SECTION_HII,- SECTION_DATA+ > SECTION_DATA,+ SECTION_SYMBOL } SECTION_FILTER_TYPES; @@ -50,6 +88,8 > @@ typedef struct { > > BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); > VOID (*WriteRelocations) (); VOID (*WriteDebug) ();+ VOID > (*ScanSymbol) ();+ VOID (*WriteExport) (); VOID (*SetImageSize) > (); VOID (*CleanUp) (); diff --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 = 0; > > UINT32 mImageSize = 0; UINT32 mOutImageType = FW_DUMMY_IMAGE; BOOLEAN > mIsConvertXip = FALSE;-+BOOLEAN mExportFlag = FALSE; STATIC > EFI_STATUS@@ -1436,6 +1436,15 @@ Returns: > > continue; } + if (stricmp (argv[0], "--PRM") == 0) > {+ if (!mExportFlag) {+ mExportFlag = TRUE;+ }+ > argc --;+ argv ++;+ continue;+ }+ if (argv[0][0] == > '-') { Error (NULL, 0, 1000, "Unknown 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 { > > UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; +//+// > Based export types.+//+#define EFI_IMAGE_EXPORT_ORDINAL_BASE > 1+#define EFI_IMAGE_EXPORT_ADDR_SIZE 4+#define > EFI_IMAGE_EXPORT_ORDINAL_SIZE 2+ /// /// DLL support. /// Import > Format-- > > 2.26.2.windows.1 > > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF 2022-01-22 2:50 ` Michael Kubacki @ 2022-01-26 8:16 ` lisa.huang 2022-01-26 20:18 ` Michael Kubacki 0 siblings, 1 reply; 10+ messages in thread From: lisa.huang @ 2022-01-26 8:16 UTC (permalink / raw) To: Michael Kubacki, devel@edk2.groups.io, Gao, Liming, Feng, Bob C Cc: Chen, Christine, Wu, Yidong, Xu, Wei6, You, Benjamin, mikuback@linux.microsoft.com Hi Michael, Sure, I will include you if any update on PRM functionality. BTW, I have a question about InitializedData, does it include export section or not? Thanks. Regards, Lisa -----Original Message----- From: Michael Kubacki <michael.kubacki@outlook.com> Sent: 2022年1月22日 10:50 To: devel@edk2.groups.io; Huang, Li-Xia <lisa.huang@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Feng, Bob C <bob.c.feng@intel.com> Cc: Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin <benjamin.you@intel.com>; mikuback@linux.microsoft.com Subject: Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF Hi Lisa, Thank you for contributing this. Please include me on functionality related to PRM. I was using the PRM_EXPORT_API macro (https://github.com/tianocore/edk2-staging/blob/9da8abf66505d8ff636aaecc429a5237ce226650/PrmPkg/Include/Prm.h#L17) to support this on MS toolchain. It looks like this is to add similar functionality for ELF binaries using GenFw? Thanks, Michael On 1/18/2022 1:19 AM, Huang, Li-Xia wrote: > Hi Liming, > > Thanks for your feedback. > > I have added some detail in BZ. 😊 > > https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment > <https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment> > > Regards, > > Lisa > > *From:*gaoliming <gaoliming@byosoft.com.cn> > *Sent:* 2022年1月18日13:20 > *To:* devel@edk2.groups.io; Huang, Li-Xia <lisa.huang@intel.com>; > Feng, Bob C <bob.c.feng@intel.com> > *Cc:* Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong > <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin > <benjamin.you@intel.com> > *Subject:* 回复: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add > export table in PE-COFF > > Lisa: > > Can you give more background about PRM usage? What new usage > requires RPM? Can you add the detail in BZ? > > Thanks > > Liming > > *发件人**:*devel@edk2.groups.io > <mailto:devel@edk2.groups.io><devel@edk2.groups.io > <mailto:devel@edk2.groups.io>> *代表 *Huang, Li-Xia > *发送时间:* 2022年1月17日 11:09 > *收件人:* Feng, Bob C <bob.c.feng@intel.com > <mailto:bob.c.feng@intel.com>>; devel@edk2.groups.io > <mailto:devel@edk2.groups.io> > *抄送:* Gao, Liming <gaoliming@byosoft.com.cn > <mailto:gaoliming@byosoft.com.cn>>; Chen, Christine > <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>>; Wu, Yidong > <yidong.wu@intel.com <mailto:yidong.wu@intel.com>>; Xu, Wei6 > <wei6.xu@intel.com <mailto:wei6.xu@intel.com>>; You, Benjamin > <benjamin.you@intel.com <mailto:benjamin.you@intel.com>> > *主题:* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export > table in PE-COFF > > Hi Bob, > > Thanks for your comments. > > 1. I will add the help information for "--PRM"; > > 2. > > @@ -750,7 +818,7 @@ ScanSections64 ( > > if (shdr->sh_addralign <= mCoffAlignment) { > > continue; > > } > > - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) > { > > + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) > +|| > IsSymbolShdr(shdr)) { > > mCoffAlignment = (UINT32)shdr->sh_addralign; > > } > > } > > 1) Above change is to Set mCoffAlignment to the maximum alignment of > the input sections including symbol section. > > The symbol section will only exist with below change, so it > should have no effect to other drivers. > > build_rule.template: > > <Command.GCC> > > $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).debug > > #$(OBJCOPY) --strip-unneeded -R .eh_frame ${src} > > $(OBJCOPY) $(OBJCOPY_STRIPFLAG) ${src} > > tools_def.template: > > *_*_*_OBJCOPY_STRIPFLAG = --strip-unneeded -R .eh_frame > > PrmAddrTransDsm.inf: > > [BuildOptions.common] > > ... > > GCC: *_*_*_OBJCOPY_STRIPFLAG == -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 <bob.c.feng@intel.com <mailto:bob.c.feng@intel.com>> > Sent: 2022年1月14日 14:12 > To: Huang, Li-Xia <lisa.huang@intel.com > <mailto:lisa.huang@intel.com>>; devel@edk2.groups.io > <mailto:devel@edk2.groups.io> > Cc: Gao, Liming <gaoliming@byosoft.com.cn > <mailto:gaoliming@byosoft.com.cn>>; Chen, Christine > <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>> > 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 ( > > if (shdr->sh_addralign <= mCoffAlignment) { > > continue; > > } > > - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) > { > > + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) > +|| > IsSymbolShdr(shdr)) { > > mCoffAlignment = (UINT32)shdr->sh_addralign; > > } > > } > > Thanks, > > Bob > > -----Original Message----- > > From: Huang, Li-Xia <lisa.huang@intel.com > <mailto:lisa.huang@intel.com>> > > Sent: Wednesday, January 12, 2022 3:44 PM > > To: devel@edk2.groups.io <mailto:devel@edk2.groups.io> > > Cc: Huang, Li-Xia <lisa.huang@intel.com > <mailto:lisa.huang@intel.com>>; Gao, Liming <gaoliming@byosoft.com.cn > <mailto:gaoliming@byosoft.com.cn>>; Feng, Bob C <bob.c.feng@intel.com > <mailto:bob.c.feng@intel.com>>; Chen, Christine <yuwei.chen@intel.com > <mailto:yuwei.chen@intel.com>> > > Subject: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export > table in PE-COFF > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3802 > <https://bugzilla.tianocore.org/show_bug.cgi?id=3802> > > 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 <gaoliming@byosoft.com.cn > <mailto:gaoliming@byosoft.com.cn>> > > Cc: Bob Feng <bob.c.feng@intel.com <mailto:bob.c.feng@intel.com>> > > Cc: Yuwei Chen <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>> > > Signed-off-by: Lixia Huang <lisa.huang@intel.com > <mailto:lisa.huang@intel.com>> > > --- > > BaseTools/Source/C/GenFw/Elf64Convert.c | 254 +++++++++++++++++- > > BaseTools/Source/C/GenFw/ElfConvert.c | 10 + > > BaseTools/Source/C/GenFw/ElfConvert.h | 42 ++- > > BaseTools/Source/C/GenFw/GenFw.c | 11 +- > > .../C/Include/IndustryStandard/PeImage.h | 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 ( > > VOID ); +STATIC+VOID+ScanSymbol64 (+ VOID+ > );++STATIC+VOID+WriteExport64 (+ VOID+ );+ 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 = 0; > > STATIC INT32 mRiscVPass1Offset; STATIC INT32 > mRiscVPass1GotFixup; +//+// Used for Export section.+//+STATIC > UINT32 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 ( > > ElfFunctions->SetImageSize = SetImageSize64; > ElfFunctions->CleanUp = CleanUp64; + if (mExportFlag) {+ ElfFunctions->ScanSymbol = > ScanSymbol64;+ ElfFunctions->WriteExport = WriteExport64;+ } > return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( > > return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + > Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); } > +STATIC+BOOLEAN+IsSymbolShdr (+ Elf_Shdr *Shdr+ )+{+ Elf_Shdr > *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx);++ return (BOOLEAN) > (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, > ELF_SYMBOL_SECTION_NAME) == 0);+}+ STATIC BOOLEAN IsDataShdr (@@ > -335,6 > +370,38 @@ GetSymName ( > > return StrtabContents + Sym->st_name; } +//+// Get Prm Handler > number and name+//+STATIC+VOID+FindPrmHandler (+ UINT64 Offset+ )+{+ > PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport;+ UINT32 > NameOffset;+ UINT32 HandlerNum;+ UINT32 Index;+ UINT8 > SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];++ PrmExport = > (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset);+ > NameOffset = sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + > sizeof(EFI_GUID);++ for (HandlerNum = 0; HandlerNum < > PrmExport->NumberPrmHandlers; HandlerNum++) {+ for (Index = 0; > PrmExport->Index > < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) {+ SymName[Index] = > *((UINT8 *)PrmExport + NameOffset + Index);+ if (SymName[Index] > == > 0) {+ break;+ }+ }++ > strcpy(mExportSymName[mExportSymNum], > (CHAR8*)SymName);+ NameOffset += PRM_HANDLER_NAME_MAXIMUM_LENGTH + > sizeof(EFI_GUID);+ mExportSymNum ++;+ }+}+ // // Find the ELF > section hosting the GOT from an ELF Rva // of a single GOT entry. > Normally, GOT is placed in@@ -717,6 +784,7 @@ ScanSections64 ( > > UINT32 CoffEntry; > UINT32 SectionCount; > BOOLEAN FoundSection;+ > UINT32 Offset; CoffEntry = 0; > mCoffOffset = 0;@@ -750,7 +818,7 @@ ScanSections64 ( > > if (shdr->sh_addralign <= mCoffAlignment) { continue; > }- if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) > {+ if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) > || > IsSymbolShdr(shdr)) { mCoffAlignment = > (UINT32)shdr->sh_addralign; } }@@ -880,6 +948,16 @@ > ScanSections64 ( > > Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged > into 1 data section. Source level debug might not work correctly.", > mInImageName); } + //+ // The Symbol sections.+ //+ if > (mExportFlag) {+ mExportOffset = mCoffOffset;+ mExportSize = > sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;+ > mCoffOffset += mExportSize;+ mCoffOffset = CoffAlign(mCoffOffset);+ > }+ // // The HII resource sections. //@@ -962,7 +1040,11 @@ > ScanSections64 ( > > | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; > NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - > NtHdr->mTextOffset;- Pe32Plus.OptionalHeader.SizeOfInitializedData = > NtHdr->mRelocOffset - > mDataOffset;+ if(mExportFlag) {+ > NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - > mExportOffset;+ } else {+ > NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - > mDataOffset;+ } > NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; > NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; @@ > -989,8 +1071,17 @@ ScanSections64 ( > > NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + //+ // If > found symbol, add edata section between data and rsrc section+ //+ > if(mExportFlag) {+ Offset = mExportOffset;+ } else {+ Offset = > mHiiRsrcOffset;+ }+ if ((mHiiRsrcOffset - mDataOffset) > 0) {- > CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - > mDataOffset,+ CreateSectionHeader (".data", mDataOffset, Offset - > mDataOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA > | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ);@@ -999,6 +1090,20 > @@ ScanSections64 ( > > NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + > if(mExportFlag) {+ if ((mHiiRsrcOffset - mExportOffset) > 0) {+ > CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - > mExportOffset,+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA+ | > EFI_IMAGE_SCN_MEM_READ);+ > NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY > NtHdr->_EXPORT].Size > = mHiiRsrcOffset - mExportOffset;+ > NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY > NtHdr->_EXPORT].VirtualAddress > = mExportOffset;+ NtHdr->Pe32Plus.FileHeader.NumberOfSections++;+ } > else {+ // Don't make a section of size 0.+ > NtHdr->Pe32Plus.FileHeader.NumberOfSections--;+ }+ }+ if > ((mRelocOffset - mHiiRsrcOffset) > 0) { CreateSectionHeader > (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, > EFI_IMAGE_SCN_CNT_INITIALIZED_DATA@@ -1757,4 +1862,145 @@ CleanUp64 ( > > } } +STATIC+VOID+ScanSymbol64 (+ VOID+ )+{+ UINT32 > shIndex;+ UINT32 SymIndex;+ Elf_Sym *Sym;+ UINT64 > SymNum;+ const UINT8 *SymName;++ for (shIndex = 0; shIndex < > mEhdr->e_shnum; shIndex++) {+ //+ // Determine if this is a > mEhdr->symbol > section.+ //+ Elf_Shdr *shdr = GetShdrByIndex(shIndex);+ if > (!IsSymbolShdr(shdr)) {+ continue;+ }++ UINT8 *Symtab = > (UINT8*)mEhdr + shdr->sh_offset;+ SymNum = (shdr->sh_size) / > (shdr->sh_entsize);++ //+ // First Get PrmModuleExportDescriptor+ > //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ Sym = > (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = > GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ }++ > if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) > == 0) {+ //+ // Find PrmHandler Number and Name+ > //+ FindPrmHandler(Sym->st_value);++ > strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ > mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value);+ > mExportSize > += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + > strlen((CHAR8 *)SymName) + 1;+ mExportSymNum ++;+ > break;+ }+ }++ //+ // Second Get PrmHandler+ //+ for > (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ UINT32 > ExpIndex;+ Sym = (Elf_Sym *)(Symtab + SymIndex * > shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName > shdr->== > NULL) {+ continue;+ }++ for (ExpIndex = 0; ExpIndex > < (mExportSymNum -1); ExpIndex++) {+ if (strcmp((CHAR8*)SymName, > mExportSymName[ExpIndex]) != 0) {+ continue;+ }+ > mExportRVA[ExpIndex] = (UINT32)(Sym->st_value);+ mExportSize += > 2 > * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + > strlen((CHAR8 *)SymName) + 1;+ }+ }++ break;+ > }+}++STATIC+VOID+WriteExport64 (+ VOID+ )+{+ > EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;+ > EFI_IMAGE_EXPORT_DIRECTORY *ExportDir;+ > EFI_IMAGE_DATA_DIRECTORY *DataDir;+ UINT32 > FileNameOffset;+ UINT32 FuncOffset;+ > UINT16 Index;+ > UINT8 *Tdata = NULL;++ ExportDir = > (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset);+ > ExportDir->Characteristics = 0;+ ExportDir->TimeDateStamp = 0;+ > ExportDir->MajorVersion = 0;+ ExportDir->MinorVersion =0;+ Name = 0;+ > ExportDir->ExportDir->NumberOfFunctions = mExportSymNum;+ > ExportDir->NumberOfNames = mExportSymNum;+ ExportDir->Base = > EFI_IMAGE_EXPORT_ORDINAL_BASE;+ ExportDir->AddressOfFunctions = > mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY);+ > ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + > EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;+ > ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + > EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;++ FileNameOffset = > ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * > mExportSymNum;+ FuncOffset = FileNameOffset + strlen(mInImageName) + > 1;++ // Write Input image Name RVA+ Tdata = mCoffFile + 12;+ > *(UINT32 *)Tdata = FileNameOffset;++ // Write Input image Name+ > strcpy((char *)(mCoffFile + FileNameOffset), mInImageName);++ for > (Index = 0; Index < mExportSymNum; Index++) {+ //+ // Write > Export Address Table+ //+ Tdata = mCoffFile + > ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = > mExportRVA[Index];++ //+ // Write Export Name Pointer Table+ > //+ Tdata = mCoffFile + ExportDir->AddressOfNames + Index * > EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = FuncOffset;++ //+ > // Write Export Ordinal table+ //+ Tdata = mCoffFile + > ExportDir->AddressOfNameOrdinals + Index * > EFI_IMAGE_EXPORT_ORDINAL_SIZE;+ *(UINT16 *)Tdata = Index;++ //+ > // Write Export Name Table+ //+ strcpy((char *)(mCoffFile + > FuncOffset), mExportSymName[Index]);+ FuncOffset += > strlen(mExportSymName[Index]) + 1;+ }++ NtHdr = > (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);+ > DataDir = > &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTR > Y_EXPORT];+ > DataDir->VirtualAddress = mExportOffset;+ DataDir->Size = > 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 ( > > VerboseMsg ("Write debug info."); ElfFunctions.WriteDebug (); + > //+ // For PRM Driver to Write export info.+ //+ if (mExportFlag) > {+ VerboseMsg ("Scan symbol info.");+ ElfFunctions.ScanSymbol > ();+ VerboseMsg ("Write export info.");+ > ElfFunctions.WriteExport ();+ }+ // // Make sure image size is > correct before returning the new image. //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 *mCoffFile; extern UINT32 > mTableOffset; extern UINT32 mOutImageType; extern UINT32 > mFileBufferSize;+extern BOOLEAN mExportFlag; // // 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 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 {+ EFI_GUID > PrmHandlerGuid;+ CHAR8 > PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];+} > PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT;++typedef struct {+ > UINT64 Signature;+ > UINT16 Revision;+ > UINT16 NumberPrmHandlers;+ EFI_GUID > PlatformGuid;+ EFI_GUID ModuleGuid;+} > PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;++typedef struct {+ > PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header;+ > PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT > PrmHandlerExportDescriptors[1];+} > PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;++#pragma pack(pop) // // Filter > Types@@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; > > typedef enum { SECTION_TEXT, SECTION_HII,- SECTION_DATA+ > SECTION_DATA,+ SECTION_SYMBOL } SECTION_FILTER_TYPES; @@ -50,6 +88,8 > @@ typedef struct { > > BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); > VOID (*WriteRelocations) (); VOID (*WriteDebug) ();+ VOID > (*ScanSymbol) ();+ VOID (*WriteExport) (); VOID > (*SetImageSize) (); VOID (*CleanUp) (); diff --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 = 0; > > UINT32 mImageSize = 0; UINT32 mOutImageType = FW_DUMMY_IMAGE; BOOLEAN > mIsConvertXip = FALSE;-+BOOLEAN mExportFlag = FALSE; STATIC > EFI_STATUS@@ -1436,6 +1436,15 @@ Returns: > > continue; } + if (stricmp (argv[0], "--PRM") == 0) > {+ if (!mExportFlag) {+ mExportFlag = TRUE;+ }+ > argc --;+ argv ++;+ continue;+ }+ if (argv[0][0] == > '-') { Error (NULL, 0, 1000, "Unknown 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 { > > UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; +//+// > Based export types.+//+#define EFI_IMAGE_EXPORT_ORDINAL_BASE > 1+#define EFI_IMAGE_EXPORT_ADDR_SIZE 4+#define > EFI_IMAGE_EXPORT_ORDINAL_SIZE 2+ /// /// DLL support. /// Import > Format-- > > 2.26.2.windows.1 > > ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF 2022-01-26 8:16 ` lisa.huang @ 2022-01-26 20:18 ` Michael Kubacki 2022-01-27 3:04 ` Huang, Li-Xia 0 siblings, 1 reply; 10+ messages in thread From: Michael Kubacki @ 2022-01-26 20:18 UTC (permalink / raw) To: Huang, Li-Xia, Michael Kubacki, devel@edk2.groups.io, Gao, Liming, Feng, Bob C Cc: Chen, Christine, Wu, Yidong, Xu, Wei6, You, Benjamin Are you referring to "static data"? If so, no. That is allocated at boot 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 EDKII_DSC_PLATFORM_GUID) (https://bugzilla.tianocore.org/show_bug.cgi?id=2969) 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 PRMT it produces) https://github.com/tianocore/edk2-staging/blob/PlatformRuntimeMechanism/PrmPkg/Include/PrmExportDescriptor.h Thanks, Michael On 1/26/2022 3:16 AM, Huang, Li-Xia wrote: > Hi Michael, > > Sure, I will include you if any update on PRM functionality. > > BTW, I have a question about InitializedData, does it include export section or not? Thanks. > > Regards, > Lisa > > -----Original Message----- > From: Michael Kubacki <michael.kubacki@outlook.com> > Sent: 2022年1月22日 10:50 > To: devel@edk2.groups.io; Huang, Li-Xia <lisa.huang@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>; Feng, Bob C <bob.c.feng@intel.com> > Cc: Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin <benjamin.you@intel.com>; mikuback@linux.microsoft.com > Subject: Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF > > Hi Lisa, > > Thank you for contributing this. Please include me on functionality related to PRM. > > I was using the PRM_EXPORT_API macro > (https://github.com/tianocore/edk2-staging/blob/9da8abf66505d8ff636aaecc429a5237ce226650/PrmPkg/Include/Prm.h#L17) > to support this on MS toolchain. > > It looks like this is to add similar functionality for ELF binaries using GenFw? > > Thanks, > Michael > > On 1/18/2022 1:19 AM, Huang, Li-Xia wrote: >> Hi Liming, >> >> Thanks for your feedback. >> >> I have added some detail in BZ. 😊 >> >> https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment >> <https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment> >> >> Regards, >> >> Lisa >> >> *From:*gaoliming <gaoliming@byosoft.com.cn> >> *Sent:* 2022年1月18日13:20 >> *To:* devel@edk2.groups.io; Huang, Li-Xia <lisa.huang@intel.com>; >> Feng, Bob C <bob.c.feng@intel.com> >> *Cc:* Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong >> <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin >> <benjamin.you@intel.com> >> *Subject:* 回复: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add >> export table in PE-COFF >> >> Lisa: >> >> Can you give more background about PRM usage? What new usage >> requires RPM? Can you add the detail in BZ? >> >> Thanks >> >> Liming >> >> *发件人**:*devel@edk2.groups.io >> <mailto:devel@edk2.groups.io><devel@edk2.groups.io >> <mailto:devel@edk2.groups.io>> *代表 *Huang, Li-Xia >> *发送时间:* 2022年1月17日 11:09 >> *收件人:* Feng, Bob C <bob.c.feng@intel.com >> <mailto:bob.c.feng@intel.com>>; devel@edk2.groups.io >> <mailto:devel@edk2.groups.io> >> *抄送:* Gao, Liming <gaoliming@byosoft.com.cn >> <mailto:gaoliming@byosoft.com.cn>>; Chen, Christine >> <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>>; Wu, Yidong >> <yidong.wu@intel.com <mailto:yidong.wu@intel.com>>; Xu, Wei6 >> <wei6.xu@intel.com <mailto:wei6.xu@intel.com>>; You, Benjamin >> <benjamin.you@intel.com <mailto:benjamin.you@intel.com>> >> *主题:* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export >> table in PE-COFF >> >> Hi Bob, >> >> Thanks for your comments. >> >> 1. I will add the help information for "--PRM"; >> >> 2. >> >> @@ -750,7 +818,7 @@ ScanSections64 ( >> >> if (shdr->sh_addralign <= mCoffAlignment) { >> >> continue; >> >> } >> >> - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) >> { >> >> + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) >> +|| >> IsSymbolShdr(shdr)) { >> >> mCoffAlignment = (UINT32)shdr->sh_addralign; >> >> } >> >> } >> >> 1) Above change is to Set mCoffAlignment to the maximum alignment of >> the input sections including symbol section. >> >> The symbol section will only exist with below change, so it >> should have no effect to other drivers. >> >> build_rule.template: >> >> <Command.GCC> >> >> $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).debug >> >> #$(OBJCOPY) --strip-unneeded -R .eh_frame ${src} >> >> $(OBJCOPY) $(OBJCOPY_STRIPFLAG) ${src} >> >> tools_def.template: >> >> *_*_*_OBJCOPY_STRIPFLAG = --strip-unneeded -R .eh_frame >> >> PrmAddrTransDsm.inf: >> >> [BuildOptions.common] >> >> ... >> >> GCC: *_*_*_OBJCOPY_STRIPFLAG == -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 <bob.c.feng@intel.com <mailto:bob.c.feng@intel.com>> >> Sent: 2022年1月14日 14:12 >> To: Huang, Li-Xia <lisa.huang@intel.com >> <mailto:lisa.huang@intel.com>>; devel@edk2.groups.io >> <mailto:devel@edk2.groups.io> >> Cc: Gao, Liming <gaoliming@byosoft.com.cn >> <mailto:gaoliming@byosoft.com.cn>>; Chen, Christine >> <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>> >> 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 ( >> >> if (shdr->sh_addralign <= mCoffAlignment) { >> >> continue; >> >> } >> >> - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) >> { >> >> + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) >> +|| >> IsSymbolShdr(shdr)) { >> >> mCoffAlignment = (UINT32)shdr->sh_addralign; >> >> } >> >> } >> >> Thanks, >> >> Bob >> >> -----Original Message----- >> >> From: Huang, Li-Xia <lisa.huang@intel.com >> <mailto:lisa.huang@intel.com>> >> >> Sent: Wednesday, January 12, 2022 3:44 PM >> >> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io> >> >> Cc: Huang, Li-Xia <lisa.huang@intel.com >> <mailto:lisa.huang@intel.com>>; Gao, Liming <gaoliming@byosoft.com.cn >> <mailto:gaoliming@byosoft.com.cn>>; Feng, Bob C <bob.c.feng@intel.com >> <mailto:bob.c.feng@intel.com>>; Chen, Christine <yuwei.chen@intel.com >> <mailto:yuwei.chen@intel.com>> >> >> Subject: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export >> table in PE-COFF >> >> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3802 >> <https://bugzilla.tianocore.org/show_bug.cgi?id=3802> >> >> 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 <gaoliming@byosoft.com.cn >> <mailto:gaoliming@byosoft.com.cn>> >> >> Cc: Bob Feng <bob.c.feng@intel.com <mailto:bob.c.feng@intel.com>> >> >> Cc: Yuwei Chen <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>> >> >> Signed-off-by: Lixia Huang <lisa.huang@intel.com >> <mailto:lisa.huang@intel.com>> >> >> --- >> >> BaseTools/Source/C/GenFw/Elf64Convert.c | 254 +++++++++++++++++- >> >> BaseTools/Source/C/GenFw/ElfConvert.c | 10 + >> >> BaseTools/Source/C/GenFw/ElfConvert.h | 42 ++- >> >> BaseTools/Source/C/GenFw/GenFw.c | 11 +- >> >> .../C/Include/IndustryStandard/PeImage.h | 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 ( >> >> VOID ); +STATIC+VOID+ScanSymbol64 (+ VOID+ >> );++STATIC+VOID+WriteExport64 (+ VOID+ );+ 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 = 0; >> >> STATIC INT32 mRiscVPass1Offset; STATIC INT32 >> mRiscVPass1GotFixup; +//+// Used for Export section.+//+STATIC >> UINT32 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 ( >> >> ElfFunctions->SetImageSize = SetImageSize64; >> ElfFunctions->CleanUp = CleanUp64; + if (mExportFlag) {+ ElfFunctions->ScanSymbol = >> ScanSymbol64;+ ElfFunctions->WriteExport = WriteExport64;+ } >> return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( >> >> return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + >> Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); } >> +STATIC+BOOLEAN+IsSymbolShdr (+ Elf_Shdr *Shdr+ )+{+ Elf_Shdr >> *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx);++ return (BOOLEAN) >> (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, >> ELF_SYMBOL_SECTION_NAME) == 0);+}+ STATIC BOOLEAN IsDataShdr (@@ >> -335,6 >> +370,38 @@ GetSymName ( >> >> return StrtabContents + Sym->st_name; } +//+// Get Prm Handler >> number and name+//+STATIC+VOID+FindPrmHandler (+ UINT64 Offset+ )+{+ >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport;+ UINT32 >> NameOffset;+ UINT32 HandlerNum;+ UINT32 Index;+ UINT8 >> SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];++ PrmExport = >> (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset);+ >> NameOffset = sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + >> sizeof(EFI_GUID);++ for (HandlerNum = 0; HandlerNum < >> PrmExport->NumberPrmHandlers; HandlerNum++) {+ for (Index = 0; >> PrmExport->Index >> < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) {+ SymName[Index] = >> *((UINT8 *)PrmExport + NameOffset + Index);+ if (SymName[Index] >> == >> 0) {+ break;+ }+ }++ >> strcpy(mExportSymName[mExportSymNum], >> (CHAR8*)SymName);+ NameOffset += PRM_HANDLER_NAME_MAXIMUM_LENGTH + >> sizeof(EFI_GUID);+ mExportSymNum ++;+ }+}+ // // Find the ELF >> section hosting the GOT from an ELF Rva // of a single GOT entry. >> Normally, GOT is placed in@@ -717,6 +784,7 @@ ScanSections64 ( >> >> UINT32 CoffEntry; >> UINT32 SectionCount; >> BOOLEAN FoundSection;+ >> UINT32 Offset; CoffEntry = 0; >> mCoffOffset = 0;@@ -750,7 +818,7 @@ ScanSections64 ( >> >> if (shdr->sh_addralign <= mCoffAlignment) { continue; >> }- if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) >> {+ if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) >> || >> IsSymbolShdr(shdr)) { mCoffAlignment = >> (UINT32)shdr->sh_addralign; } }@@ -880,6 +948,16 @@ >> ScanSections64 ( >> >> Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged >> into 1 data section. Source level debug might not work correctly.", >> mInImageName); } + //+ // The Symbol sections.+ //+ if >> (mExportFlag) {+ mExportOffset = mCoffOffset;+ mExportSize = >> sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;+ >> mCoffOffset += mExportSize;+ mCoffOffset = CoffAlign(mCoffOffset);+ >> }+ // // The HII resource sections. //@@ -962,7 +1040,11 @@ >> ScanSections64 ( >> >> | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; >> NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - >> NtHdr->mTextOffset;- Pe32Plus.OptionalHeader.SizeOfInitializedData = >> NtHdr->mRelocOffset - >> mDataOffset;+ if(mExportFlag) {+ >> NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - >> mExportOffset;+ } else {+ >> NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - >> mDataOffset;+ } >> NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; >> NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; @@ >> -989,8 +1071,17 @@ ScanSections64 ( >> >> NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + //+ // If >> found symbol, add edata section between data and rsrc section+ //+ >> if(mExportFlag) {+ Offset = mExportOffset;+ } else {+ Offset = >> mHiiRsrcOffset;+ }+ if ((mHiiRsrcOffset - mDataOffset) > 0) {- >> CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - >> mDataOffset,+ CreateSectionHeader (".data", mDataOffset, Offset - >> mDataOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA >> | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ);@@ -999,6 +1090,20 >> @@ ScanSections64 ( >> >> NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + >> if(mExportFlag) {+ if ((mHiiRsrcOffset - mExportOffset) > 0) {+ >> CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - >> mExportOffset,+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA+ | >> EFI_IMAGE_SCN_MEM_READ);+ >> NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY >> NtHdr->_EXPORT].Size >> = mHiiRsrcOffset - mExportOffset;+ >> NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY >> NtHdr->_EXPORT].VirtualAddress >> = mExportOffset;+ NtHdr->Pe32Plus.FileHeader.NumberOfSections++;+ } >> else {+ // Don't make a section of size 0.+ >> NtHdr->Pe32Plus.FileHeader.NumberOfSections--;+ }+ }+ if >> ((mRelocOffset - mHiiRsrcOffset) > 0) { CreateSectionHeader >> (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, >> EFI_IMAGE_SCN_CNT_INITIALIZED_DATA@@ -1757,4 +1862,145 @@ CleanUp64 ( >> >> } } +STATIC+VOID+ScanSymbol64 (+ VOID+ )+{+ UINT32 >> shIndex;+ UINT32 SymIndex;+ Elf_Sym *Sym;+ UINT64 >> SymNum;+ const UINT8 *SymName;++ for (shIndex = 0; shIndex < >> mEhdr->e_shnum; shIndex++) {+ //+ // Determine if this is a >> mEhdr->symbol >> section.+ //+ Elf_Shdr *shdr = GetShdrByIndex(shIndex);+ if >> (!IsSymbolShdr(shdr)) {+ continue;+ }++ UINT8 *Symtab = >> (UINT8*)mEhdr + shdr->sh_offset;+ SymNum = (shdr->sh_size) / >> (shdr->sh_entsize);++ //+ // First Get PrmModuleExportDescriptor+ >> //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ Sym = >> (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = >> GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ }++ >> if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) >> == 0) {+ //+ // Find PrmHandler Number and Name+ >> //+ FindPrmHandler(Sym->st_value);++ >> strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ >> mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value);+ >> mExportSize >> += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + >> strlen((CHAR8 *)SymName) + 1;+ mExportSymNum ++;+ >> break;+ }+ }++ //+ // Second Get PrmHandler+ //+ for >> (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ UINT32 >> ExpIndex;+ Sym = (Elf_Sym *)(Symtab + SymIndex * >> shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName >> shdr->== >> NULL) {+ continue;+ }++ for (ExpIndex = 0; ExpIndex >> < (mExportSymNum -1); ExpIndex++) {+ if (strcmp((CHAR8*)SymName, >> mExportSymName[ExpIndex]) != 0) {+ continue;+ }+ >> mExportRVA[ExpIndex] = (UINT32)(Sym->st_value);+ mExportSize += >> 2 >> * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + >> strlen((CHAR8 *)SymName) + 1;+ }+ }++ break;+ >> }+}++STATIC+VOID+WriteExport64 (+ VOID+ )+{+ >> EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;+ >> EFI_IMAGE_EXPORT_DIRECTORY *ExportDir;+ >> EFI_IMAGE_DATA_DIRECTORY *DataDir;+ UINT32 >> FileNameOffset;+ UINT32 FuncOffset;+ >> UINT16 Index;+ >> UINT8 *Tdata = NULL;++ ExportDir = >> (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset);+ >> ExportDir->Characteristics = 0;+ ExportDir->TimeDateStamp = 0;+ >> ExportDir->MajorVersion = 0;+ ExportDir->MinorVersion =0;+ Name = 0;+ >> ExportDir->ExportDir->NumberOfFunctions = mExportSymNum;+ >> ExportDir->NumberOfNames = mExportSymNum;+ ExportDir->Base = >> EFI_IMAGE_EXPORT_ORDINAL_BASE;+ ExportDir->AddressOfFunctions = >> mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY);+ >> ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + >> EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;+ >> ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + >> EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;++ FileNameOffset = >> ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * >> mExportSymNum;+ FuncOffset = FileNameOffset + strlen(mInImageName) + >> 1;++ // Write Input image Name RVA+ Tdata = mCoffFile + 12;+ >> *(UINT32 *)Tdata = FileNameOffset;++ // Write Input image Name+ >> strcpy((char *)(mCoffFile + FileNameOffset), mInImageName);++ for >> (Index = 0; Index < mExportSymNum; Index++) {+ //+ // Write >> Export Address Table+ //+ Tdata = mCoffFile + >> ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = >> mExportRVA[Index];++ //+ // Write Export Name Pointer Table+ >> //+ Tdata = mCoffFile + ExportDir->AddressOfNames + Index * >> EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = FuncOffset;++ //+ >> // Write Export Ordinal table+ //+ Tdata = mCoffFile + >> ExportDir->AddressOfNameOrdinals + Index * >> EFI_IMAGE_EXPORT_ORDINAL_SIZE;+ *(UINT16 *)Tdata = Index;++ //+ >> // Write Export Name Table+ //+ strcpy((char *)(mCoffFile + >> FuncOffset), mExportSymName[Index]);+ FuncOffset += >> strlen(mExportSymName[Index]) + 1;+ }++ NtHdr = >> (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);+ >> DataDir = >> &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTR >> Y_EXPORT];+ >> DataDir->VirtualAddress = mExportOffset;+ DataDir->Size = >> 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 ( >> >> VerboseMsg ("Write debug info."); ElfFunctions.WriteDebug (); + >> //+ // For PRM Driver to Write export info.+ //+ if (mExportFlag) >> {+ VerboseMsg ("Scan symbol info.");+ ElfFunctions.ScanSymbol >> ();+ VerboseMsg ("Write export info.");+ >> ElfFunctions.WriteExport ();+ }+ // // Make sure image size is >> correct before returning the new image. //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 *mCoffFile; extern UINT32 >> mTableOffset; extern UINT32 mOutImageType; extern UINT32 >> mFileBufferSize;+extern BOOLEAN mExportFlag; // // 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 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 {+ EFI_GUID >> PrmHandlerGuid;+ CHAR8 >> PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];+} >> PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT;++typedef struct {+ >> UINT64 Signature;+ >> UINT16 Revision;+ >> UINT16 NumberPrmHandlers;+ EFI_GUID >> PlatformGuid;+ EFI_GUID ModuleGuid;+} >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;++typedef struct {+ >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header;+ >> PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT >> PrmHandlerExportDescriptors[1];+} >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;++#pragma pack(pop) // // Filter >> Types@@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; >> >> typedef enum { SECTION_TEXT, SECTION_HII,- SECTION_DATA+ >> SECTION_DATA,+ SECTION_SYMBOL } SECTION_FILTER_TYPES; @@ -50,6 +88,8 >> @@ typedef struct { >> >> BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); >> VOID (*WriteRelocations) (); VOID (*WriteDebug) ();+ VOID >> (*ScanSymbol) ();+ VOID (*WriteExport) (); VOID >> (*SetImageSize) (); VOID (*CleanUp) (); diff --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 = 0; >> >> UINT32 mImageSize = 0; UINT32 mOutImageType = FW_DUMMY_IMAGE; BOOLEAN >> mIsConvertXip = FALSE;-+BOOLEAN mExportFlag = FALSE; STATIC >> EFI_STATUS@@ -1436,6 +1436,15 @@ Returns: >> >> continue; } + if (stricmp (argv[0], "--PRM") == 0) >> {+ if (!mExportFlag) {+ mExportFlag = TRUE;+ }+ >> argc --;+ argv ++;+ continue;+ }+ if (argv[0][0] == >> '-') { Error (NULL, 0, 1000, "Unknown 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 { >> >> UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; +//+// >> Based export types.+//+#define EFI_IMAGE_EXPORT_ORDINAL_BASE >> 1+#define EFI_IMAGE_EXPORT_ADDR_SIZE 4+#define >> EFI_IMAGE_EXPORT_ORDINAL_SIZE 2+ /// /// DLL support. /// Import >> Format-- >> >> 2.26.2.windows.1 >> >> ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF 2022-01-26 20:18 ` Michael Kubacki @ 2022-01-27 3:04 ` Huang, Li-Xia 2022-01-27 16:02 ` Michael Kubacki 0 siblings, 1 reply; 10+ messages in thread From: Huang, Li-Xia @ 2022-01-27 3:04 UTC (permalink / raw) To: Michael Kubacki, Michael Kubacki, devel@edk2.groups.io, Gao, Liming, Feng, Bob C Cc: Chen, Christine, Wu, Yidong, Xu, Wei6, You, Benjamin Hi Michael, Thanks for your response. Sorry I didn't give enough context for my question, I mean the ' SizeOfInitializedData' in Optional header of PE-COFF file. SizeOfInitializedData The size of the initialized data section, or the sum of all such sections if there are multiple data sections. I had an experiment, compare the .efi files generated by MSVC tool - one with PRM exports and the other without, the size of InitializedData in optional header becomes larger with PRM exports. So it shows that export table will be included in initialized data. #if defined(_MSC_VER) #define PRM_EXPORT_API __declspec(dllexport) #else #define PRM_EXPORT_API #endif Regards, Lisa -----Original Message----- From: Michael Kubacki <mikuback@linux.microsoft.com> Sent: 2022年1月27日 4:19 To: Huang, Li-Xia <lisa.huang@intel.com>; Michael Kubacki <michael.kubacki@outlook.com>; devel@edk2.groups.io; Gao, Liming <gaoliming@byosoft.com.cn>; Feng, Bob C <bob.c.feng@intel.com> Cc: Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin <benjamin.you@intel.com> Subject: Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF Are you referring to "static data"? If so, no. That is allocated at boot 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 EDKII_DSC_PLATFORM_GUID) (https://bugzilla.tianocore.org/show_bug.cgi?id=2969) 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 PRMT it produces) https://github.com/tianocore/edk2-staging/blob/PlatformRuntimeMechanism/PrmPkg/Include/PrmExportDescriptor.h Thanks, Michael On 1/26/2022 3:16 AM, Huang, Li-Xia wrote: > Hi Michael, > > Sure, I will include you if any update on PRM functionality. > > BTW, I have a question about InitializedData, does it include export section or not? Thanks. > > Regards, > Lisa > > -----Original Message----- > From: Michael Kubacki <michael.kubacki@outlook.com> > Sent: 2022年1月22日 10:50 > To: devel@edk2.groups.io; Huang, Li-Xia <lisa.huang@intel.com>; Gao, > Liming <gaoliming@byosoft.com.cn>; Feng, Bob C <bob.c.feng@intel.com> > Cc: Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong > <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin > <benjamin.you@intel.com>; mikuback@linux.microsoft.com > Subject: Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add > export table in PE-COFF > > Hi Lisa, > > Thank you for contributing this. Please include me on functionality related to PRM. > > I was using the PRM_EXPORT_API macro > (https://github.com/tianocore/edk2-staging/blob/9da8abf66505d8ff636aae > cc429a5237ce226650/PrmPkg/Include/Prm.h#L17) > to support this on MS toolchain. > > It looks like this is to add similar functionality for ELF binaries using GenFw? > > Thanks, > Michael > > On 1/18/2022 1:19 AM, Huang, Li-Xia wrote: >> Hi Liming, >> >> Thanks for your feedback. >> >> I have added some detail in BZ. 😊 >> >> https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment >> <https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment> >> >> Regards, >> >> Lisa >> >> *From:*gaoliming <gaoliming@byosoft.com.cn> >> *Sent:* 2022年1月18日13:20 >> *To:* devel@edk2.groups.io; Huang, Li-Xia <lisa.huang@intel.com>; >> Feng, Bob C <bob.c.feng@intel.com> >> *Cc:* Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong >> <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin >> <benjamin.you@intel.com> >> *Subject:* 回复: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add >> export table in PE-COFF >> >> Lisa: >> >> Can you give more background about PRM usage? What new usage >> requires RPM? Can you add the detail in BZ? >> >> Thanks >> >> Liming >> >> *发件人**:*devel@edk2.groups.io >> <mailto:devel@edk2.groups.io><devel@edk2.groups.io >> <mailto:devel@edk2.groups.io>> *代表 *Huang, Li-Xia >> *发送时间:* 2022年1月17日 11:09 >> *收件人:* Feng, Bob C <bob.c.feng@intel.com >> <mailto:bob.c.feng@intel.com>>; devel@edk2.groups.io >> <mailto:devel@edk2.groups.io> >> *抄送:* Gao, Liming <gaoliming@byosoft.com.cn >> <mailto:gaoliming@byosoft.com.cn>>; Chen, Christine >> <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>>; Wu, Yidong >> <yidong.wu@intel.com <mailto:yidong.wu@intel.com>>; Xu, Wei6 >> <wei6.xu@intel.com <mailto:wei6.xu@intel.com>>; You, Benjamin >> <benjamin.you@intel.com <mailto:benjamin.you@intel.com>> >> *主题:* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export >> table in PE-COFF >> >> Hi Bob, >> >> Thanks for your comments. >> >> 1. I will add the help information for "--PRM"; >> >> 2. >> >> @@ -750,7 +818,7 @@ ScanSections64 ( >> >> if (shdr->sh_addralign <= mCoffAlignment) { >> >> continue; >> >> } >> >> - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) >> { >> >> + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) >> +|| >> IsSymbolShdr(shdr)) { >> >> mCoffAlignment = (UINT32)shdr->sh_addralign; >> >> } >> >> } >> >> 1) Above change is to Set mCoffAlignment to the maximum alignment of >> the input sections including symbol section. >> >> The symbol section will only exist with below change, so it >> should have no effect to other drivers. >> >> build_rule.template: >> >> <Command.GCC> >> >> $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).debug >> >> #$(OBJCOPY) --strip-unneeded -R .eh_frame ${src} >> >> $(OBJCOPY) $(OBJCOPY_STRIPFLAG) ${src} >> >> tools_def.template: >> >> *_*_*_OBJCOPY_STRIPFLAG = --strip-unneeded -R .eh_frame >> >> PrmAddrTransDsm.inf: >> >> [BuildOptions.common] >> >> ... >> >> GCC: *_*_*_OBJCOPY_STRIPFLAG == -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 <bob.c.feng@intel.com >> <mailto:bob.c.feng@intel.com>> >> Sent: 2022年1月14日 14:12 >> To: Huang, Li-Xia <lisa.huang@intel.com >> <mailto:lisa.huang@intel.com>>; devel@edk2.groups.io >> <mailto:devel@edk2.groups.io> >> Cc: Gao, Liming <gaoliming@byosoft.com.cn >> <mailto:gaoliming@byosoft.com.cn>>; Chen, Christine >> <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>> >> 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 ( >> >> if (shdr->sh_addralign <= mCoffAlignment) { >> >> continue; >> >> } >> >> - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) >> { >> >> + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) >> +|| >> IsSymbolShdr(shdr)) { >> >> mCoffAlignment = (UINT32)shdr->sh_addralign; >> >> } >> >> } >> >> Thanks, >> >> Bob >> >> -----Original Message----- >> >> From: Huang, Li-Xia <lisa.huang@intel.com >> <mailto:lisa.huang@intel.com>> >> >> Sent: Wednesday, January 12, 2022 3:44 PM >> >> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io> >> >> Cc: Huang, Li-Xia <lisa.huang@intel.com >> <mailto:lisa.huang@intel.com>>; Gao, Liming <gaoliming@byosoft.com.cn >> <mailto:gaoliming@byosoft.com.cn>>; Feng, Bob C <bob.c.feng@intel.com >> <mailto:bob.c.feng@intel.com>>; Chen, Christine <yuwei.chen@intel.com >> <mailto:yuwei.chen@intel.com>> >> >> Subject: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export >> table in PE-COFF >> >> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3802 >> <https://bugzilla.tianocore.org/show_bug.cgi?id=3802> >> >> 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 <gaoliming@byosoft.com.cn >> <mailto:gaoliming@byosoft.com.cn>> >> >> Cc: Bob Feng <bob.c.feng@intel.com <mailto:bob.c.feng@intel.com>> >> >> Cc: Yuwei Chen <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>> >> >> Signed-off-by: Lixia Huang <lisa.huang@intel.com >> <mailto:lisa.huang@intel.com>> >> >> --- >> >> BaseTools/Source/C/GenFw/Elf64Convert.c | 254 >> +++++++++++++++++- >> >> BaseTools/Source/C/GenFw/ElfConvert.c | 10 + >> >> BaseTools/Source/C/GenFw/ElfConvert.h | 42 ++- >> >> BaseTools/Source/C/GenFw/GenFw.c | 11 +- >> >> .../C/Include/IndustryStandard/PeImage.h | 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 ( >> >> VOID ); +STATIC+VOID+ScanSymbol64 (+ VOID+ >> );++STATIC+VOID+WriteExport64 (+ VOID+ );+ 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 = 0; >> >> STATIC INT32 mRiscVPass1Offset; STATIC INT32 >> mRiscVPass1GotFixup; +//+// Used for Export section.+//+STATIC >> UINT32 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 ( >> >> ElfFunctions->SetImageSize = SetImageSize64; >> ElfFunctions->CleanUp = CleanUp64; + if (mExportFlag) {+ >> ElfFunctions->ElfFunctions->ScanSymbol = >> ScanSymbol64;+ ElfFunctions->WriteExport = WriteExport64;+ } >> return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( >> >> return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + >> Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); } >> +STATIC+BOOLEAN+IsSymbolShdr (+ Elf_Shdr *Shdr+ )+{+ Elf_Shdr >> *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx);++ return (BOOLEAN) >> (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, >> ELF_SYMBOL_SECTION_NAME) == 0);+}+ STATIC BOOLEAN IsDataShdr (@@ >> -335,6 >> +370,38 @@ GetSymName ( >> >> return StrtabContents + Sym->st_name; } +//+// Get Prm Handler >> number and name+//+STATIC+VOID+FindPrmHandler (+ UINT64 Offset+ >> )+{+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport;+ UINT32 >> NameOffset;+ UINT32 HandlerNum;+ UINT32 Index;+ UINT8 >> SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];++ PrmExport = >> (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset);+ >> NameOffset = sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + >> sizeof(EFI_GUID);++ for (HandlerNum = 0; HandlerNum < >> PrmExport->NumberPrmHandlers; HandlerNum++) {+ for (Index = 0; >> PrmExport->Index >> < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) {+ SymName[Index] = >> *((UINT8 *)PrmExport + NameOffset + Index);+ if (SymName[Index] >> == >> 0) {+ break;+ }+ }++ >> strcpy(mExportSymName[mExportSymNum], >> (CHAR8*)SymName);+ NameOffset += PRM_HANDLER_NAME_MAXIMUM_LENGTH + >> sizeof(EFI_GUID);+ mExportSymNum ++;+ }+}+ // // Find the ELF >> section hosting the GOT from an ELF Rva // of a single GOT entry. >> Normally, GOT is placed in@@ -717,6 +784,7 @@ ScanSections64 ( >> >> UINT32 CoffEntry; >> UINT32 SectionCount; BOOLEAN >> FoundSection;+ >> UINT32 Offset; CoffEntry = 0; mCoffOffset >> = 0;@@ -750,7 +818,7 @@ ScanSections64 ( >> >> if (shdr->sh_addralign <= mCoffAlignment) { continue; >> }- if (IsTextShdr(shdr) || IsDataShdr(shdr) || >> IsHiiRsrcShdr(shdr)) {+ if (IsTextShdr(shdr) || IsDataShdr(shdr) >> || IsHiiRsrcShdr(shdr) >> || >> IsSymbolShdr(shdr)) { mCoffAlignment = >> (UINT32)shdr->sh_addralign; } }@@ -880,6 +948,16 @@ >> ScanSections64 ( >> >> Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged >> into 1 data section. Source level debug might not work correctly.", >> mInImageName); } + //+ // The Symbol sections.+ //+ if >> (mExportFlag) {+ mExportOffset = mCoffOffset;+ mExportSize = >> sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;+ >> mCoffOffset += mExportSize;+ mCoffOffset = >> CoffAlign(mCoffOffset);+ }+ // // The HII resource sections. >> //@@ -962,7 +1040,11 @@ >> ScanSections64 ( >> >> | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; >> NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - >> NtHdr->mTextOffset;- Pe32Plus.OptionalHeader.SizeOfInitializedData = >> NtHdr->mRelocOffset - >> mDataOffset;+ if(mExportFlag) {+ >> NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - >> mExportOffset;+ } else {+ >> NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - >> mDataOffset;+ } >> NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; >> NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; @@ >> -989,8 +1071,17 @@ ScanSections64 ( >> >> NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + //+ // >> If found symbol, add edata section between data and rsrc section+ >> //+ >> if(mExportFlag) {+ Offset = mExportOffset;+ } else {+ Offset = >> mHiiRsrcOffset;+ }+ if ((mHiiRsrcOffset - mDataOffset) > 0) {- >> CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - >> mDataOffset,+ CreateSectionHeader (".data", mDataOffset, Offset - >> mDataOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA >> | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ);@@ -999,6 >> | +1090,20 >> @@ ScanSections64 ( >> >> NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + >> if(mExportFlag) {+ if ((mHiiRsrcOffset - mExportOffset) > 0) {+ >> CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - >> mExportOffset,+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA+ | >> EFI_IMAGE_SCN_MEM_READ);+ >> NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTR >> NtHdr->Y >> NtHdr->_EXPORT].Size >> = mHiiRsrcOffset - mExportOffset;+ >> NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTR >> NtHdr->Y >> NtHdr->_EXPORT].VirtualAddress >> = mExportOffset;+ NtHdr->Pe32Plus.FileHeader.NumberOfSections++;+ >> } else {+ // Don't make a section of size 0.+ >> NtHdr->Pe32Plus.FileHeader.NumberOfSections--;+ }+ }+ if >> ((mRelocOffset - mHiiRsrcOffset) > 0) { CreateSectionHeader >> (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, >> EFI_IMAGE_SCN_CNT_INITIALIZED_DATA@@ -1757,4 +1862,145 @@ CleanUp64 ( >> >> } } +STATIC+VOID+ScanSymbol64 (+ VOID+ )+{+ UINT32 shIndex;+ >> UINT32 SymIndex;+ Elf_Sym *Sym;+ UINT64 SymNum;+ const >> UINT8 *SymName;++ for (shIndex = 0; shIndex < >> mEhdr->e_shnum; shIndex++) {+ //+ // Determine if this is a >> mEhdr->symbol >> section.+ //+ Elf_Shdr *shdr = GetShdrByIndex(shIndex);+ if >> (!IsSymbolShdr(shdr)) {+ continue;+ }++ UINT8 *Symtab = >> (UINT8*)mEhdr + shdr->sh_offset;+ SymNum = (shdr->sh_size) / >> (shdr->sh_entsize);++ //+ // First Get PrmModuleExportDescriptor+ >> //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ Sym >> = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = >> GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ >> }++ if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) >> == 0) {+ //+ // Find PrmHandler Number and Name+ //+ >> FindPrmHandler(Sym->st_value);++ >> strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ >> mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value);+ mExportSize >> += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + >> strlen((CHAR8 *)SymName) + 1;+ mExportSymNum ++;+ break;+ >> }+ }++ //+ // Second Get PrmHandler+ //+ for (SymIndex = >> 0; SymIndex < SymNum; SymIndex++) {+ UINT32 ExpIndex;+ Sym >> = (Elf_Sym *)(Symtab + SymIndex * >> shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName >> shdr->== >> NULL) {+ continue;+ }++ for (ExpIndex = 0; >> ExpIndex < (mExportSymNum -1); ExpIndex++) {+ if >> (strcmp((CHAR8*)SymName, >> mExportSymName[ExpIndex]) != 0) {+ continue;+ }+ >> mExportRVA[ExpIndex] = (UINT32)(Sym->st_value);+ mExportSize >> += >> 2 >> * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + >> strlen((CHAR8 *)SymName) + 1;+ }+ }++ break;+ >> }+}++STATIC+VOID+WriteExport64 (+ VOID+ )+{+ >> EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;+ >> EFI_IMAGE_EXPORT_DIRECTORY *ExportDir;+ >> EFI_IMAGE_DATA_DIRECTORY *DataDir;+ UINT32 FileNameOffset;+ UINT32 >> FuncOffset;+ >> UINT16 Index;+ >> UINT8 *Tdata = NULL;++ ExportDir = >> (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset);+ >> ExportDir->Characteristics = 0;+ ExportDir->TimeDateStamp = 0;+ >> ExportDir->MajorVersion = 0;+ ExportDir->MinorVersion =0;+ Name = >> ExportDir->0;+ >> ExportDir->ExportDir->NumberOfFunctions = mExportSymNum;+ >> ExportDir->NumberOfNames = mExportSymNum;+ ExportDir->Base = >> EFI_IMAGE_EXPORT_ORDINAL_BASE;+ ExportDir->AddressOfFunctions = >> mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY);+ >> ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + >> EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;+ >> ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + >> EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;++ FileNameOffset = >> ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * >> mExportSymNum;+ FuncOffset = FileNameOffset + strlen(mInImageName) + >> 1;++ // Write Input image Name RVA+ Tdata = mCoffFile + 12;+ >> *(UINT32 *)Tdata = FileNameOffset;++ // Write Input image Name+ >> strcpy((char *)(mCoffFile + FileNameOffset), mInImageName);++ for >> (Index = 0; Index < mExportSymNum; Index++) {+ //+ // Write >> Export Address Table+ //+ Tdata = mCoffFile + >> ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ >> ExportDir->*(UINT32 *)Tdata = >> mExportRVA[Index];++ //+ // Write Export Name Pointer Table+ >> //+ Tdata = mCoffFile + ExportDir->AddressOfNames + Index * >> EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = FuncOffset;++ //+ >> // Write Export Ordinal table+ //+ Tdata = mCoffFile + >> ExportDir->AddressOfNameOrdinals + Index * >> EFI_IMAGE_EXPORT_ORDINAL_SIZE;+ *(UINT16 *)Tdata = Index;++ //+ >> // Write Export Name Table+ //+ strcpy((char *)(mCoffFile + >> FuncOffset), mExportSymName[Index]);+ FuncOffset += >> strlen(mExportSymName[Index]) + 1;+ }++ NtHdr = >> (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);+ >> DataDir = >> &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENT >> R >> Y_EXPORT];+ >> DataDir->VirtualAddress = mExportOffset;+ DataDir->Size = >> 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 ( >> >> VerboseMsg ("Write debug info."); ElfFunctions.WriteDebug (); >> + //+ // For PRM Driver to Write export info.+ //+ if >> (mExportFlag) {+ VerboseMsg ("Scan symbol info.");+ >> ElfFunctions.ScanSymbol ();+ VerboseMsg ("Write export info.");+ >> ElfFunctions.WriteExport ();+ }+ // // Make sure image size is >> correct before returning the new image. //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 *mCoffFile; extern UINT32 >> mTableOffset; extern UINT32 mOutImageType; extern UINT32 >> mFileBufferSize;+extern BOOLEAN mExportFlag; // // 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 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 {+ EFI_GUID >> PrmHandlerGuid;+ CHAR8 >> PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];+} >> PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT;++typedef struct {+ >> UINT64 Signature;+ >> UINT16 Revision;+ >> UINT16 NumberPrmHandlers;+ EFI_GUID >> PlatformGuid;+ EFI_GUID ModuleGuid;+} >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;++typedef struct {+ >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header;+ >> PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT >> PrmHandlerExportDescriptors[1];+} >> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;++#pragma pack(pop) // // Filter >> Types@@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; >> >> typedef enum { SECTION_TEXT, SECTION_HII,- SECTION_DATA+ >> SECTION_DATA,+ SECTION_SYMBOL } SECTION_FILTER_TYPES; @@ -50,6 >> +88,8 @@ typedef struct { >> >> BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); >> VOID (*WriteRelocations) (); VOID (*WriteDebug) ();+ VOID >> (*ScanSymbol) ();+ VOID (*WriteExport) (); VOID >> (*SetImageSize) (); VOID (*CleanUp) (); diff --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 = 0; >> >> UINT32 mImageSize = 0; UINT32 mOutImageType = FW_DUMMY_IMAGE; BOOLEAN >> mIsConvertXip = FALSE;-+BOOLEAN mExportFlag = FALSE; STATIC >> EFI_STATUS@@ -1436,6 +1436,15 @@ Returns: >> >> continue; } + if (stricmp (argv[0], "--PRM") == 0) {+ >> if (!mExportFlag) {+ mExportFlag = TRUE;+ }+ argc --;+ >> argv ++;+ continue;+ }+ if (argv[0][0] == >> '-') { Error (NULL, 0, 1000, "Unknown 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 { >> >> UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; >> +//+// Based export types.+//+#define EFI_IMAGE_EXPORT_ORDINAL_BASE >> 1+#define EFI_IMAGE_EXPORT_ADDR_SIZE 4+#define >> EFI_IMAGE_EXPORT_ORDINAL_SIZE 2+ /// /// DLL support. /// Import >> Format-- >> >> 2.26.2.windows.1 >> >> ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF 2022-01-27 3:04 ` Huang, Li-Xia @ 2022-01-27 16:02 ` Michael Kubacki 0 siblings, 0 replies; 10+ messages in thread From: Michael Kubacki @ 2022-01-27 16:02 UTC (permalink / raw) To: Huang, Li-Xia, Michael Kubacki, devel@edk2.groups.io, Gao, Liming, Feng, Bob C Cc: Chen, Christine, Wu, Yidong, Xu, Wei6, You, Benjamin Got it, thanks for the update. On 1/26/2022 10:04 PM, Huang, Li-Xia wrote: > Hi Michael, > > Thanks for your response. > > Sorry I didn't give enough context for my question, I mean the ' SizeOfInitializedData' in Optional header of PE-COFF file. > SizeOfInitializedData > The size of the initialized data section, or the sum of all such sections if there are multiple data sections. > > I had an experiment, compare the .efi files generated by MSVC tool - one with PRM exports and the other without, the size of InitializedData in optional header becomes larger with PRM exports. So it shows that export table will be included in initialized data. > #if defined(_MSC_VER) > #define PRM_EXPORT_API __declspec(dllexport) > #else > #define PRM_EXPORT_API > #endif > > Regards, > Lisa > > -----Original Message----- > From: Michael Kubacki <mikuback@linux.microsoft.com> > Sent: 2022年1月27日 4:19 > To: Huang, Li-Xia <lisa.huang@intel.com>; Michael Kubacki <michael.kubacki@outlook.com>; devel@edk2.groups.io; Gao, Liming <gaoliming@byosoft.com.cn>; Feng, Bob C <bob.c.feng@intel.com> > Cc: Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin <benjamin.you@intel.com> > Subject: Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF > > Are you referring to "static data"? If so, no. That is allocated at boot 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 > EDKII_DSC_PLATFORM_GUID) > (https://bugzilla.tianocore.org/show_bug.cgi?id=2969) > 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 PRMT it produces) > > https://github.com/tianocore/edk2-staging/blob/PlatformRuntimeMechanism/PrmPkg/Include/PrmExportDescriptor.h > > Thanks, > Michael > > On 1/26/2022 3:16 AM, Huang, Li-Xia wrote: >> Hi Michael, >> >> Sure, I will include you if any update on PRM functionality. >> >> BTW, I have a question about InitializedData, does it include export section or not? Thanks. >> >> Regards, >> Lisa >> >> -----Original Message----- >> From: Michael Kubacki <michael.kubacki@outlook.com> >> Sent: 2022年1月22日 10:50 >> To: devel@edk2.groups.io; Huang, Li-Xia <lisa.huang@intel.com>; Gao, >> Liming <gaoliming@byosoft.com.cn>; Feng, Bob C <bob.c.feng@intel.com> >> Cc: Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong >> <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin >> <benjamin.you@intel.com>; mikuback@linux.microsoft.com >> Subject: Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add >> export table in PE-COFF >> >> Hi Lisa, >> >> Thank you for contributing this. Please include me on functionality related to PRM. >> >> I was using the PRM_EXPORT_API macro >> (https://github.com/tianocore/edk2-staging/blob/9da8abf66505d8ff636aae >> cc429a5237ce226650/PrmPkg/Include/Prm.h#L17) >> to support this on MS toolchain. >> >> It looks like this is to add similar functionality for ELF binaries using GenFw? >> >> Thanks, >> Michael >> >> On 1/18/2022 1:19 AM, Huang, Li-Xia wrote: >>> Hi Liming, >>> >>> Thanks for your feedback. >>> >>> I have added some detail in BZ. 😊 >>> >>> https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment >>> <https://bugzilla.tianocore.org/show_bug.cgi?id=3802#add_comment> >>> >>> Regards, >>> >>> Lisa >>> >>> *From:*gaoliming <gaoliming@byosoft.com.cn> >>> *Sent:* 2022年1月18日13:20 >>> *To:* devel@edk2.groups.io; Huang, Li-Xia <lisa.huang@intel.com>; >>> Feng, Bob C <bob.c.feng@intel.com> >>> *Cc:* Chen, Christine <yuwei.chen@intel.com>; Wu, Yidong >>> <yidong.wu@intel.com>; Xu, Wei6 <wei6.xu@intel.com>; You, Benjamin >>> <benjamin.you@intel.com> >>> *Subject:* 回复: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add >>> export table in PE-COFF >>> >>> Lisa: >>> >>> Can you give more background about PRM usage? What new usage >>> requires RPM? Can you add the detail in BZ? >>> >>> Thanks >>> >>> Liming >>> >>> *发件人**:*devel@edk2.groups.io >>> <mailto:devel@edk2.groups.io><devel@edk2.groups.io >>> <mailto:devel@edk2.groups.io>> *代表 *Huang, Li-Xia >>> *发送时间:* 2022年1月17日 11:09 >>> *收件人:* Feng, Bob C <bob.c.feng@intel.com >>> <mailto:bob.c.feng@intel.com>>; devel@edk2.groups.io >>> <mailto:devel@edk2.groups.io> >>> *抄送:* Gao, Liming <gaoliming@byosoft.com.cn >>> <mailto:gaoliming@byosoft.com.cn>>; Chen, Christine >>> <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>>; Wu, Yidong >>> <yidong.wu@intel.com <mailto:yidong.wu@intel.com>>; Xu, Wei6 >>> <wei6.xu@intel.com <mailto:wei6.xu@intel.com>>; You, Benjamin >>> <benjamin.you@intel.com <mailto:benjamin.you@intel.com>> >>> *主题:* Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export >>> table in PE-COFF >>> >>> Hi Bob, >>> >>> Thanks for your comments. >>> >>> 1. I will add the help information for "--PRM"; >>> >>> 2. >>> >>> @@ -750,7 +818,7 @@ ScanSections64 ( >>> >>> if (shdr->sh_addralign <= mCoffAlignment) { >>> >>> continue; >>> >>> } >>> >>> - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) >>> { >>> >>> + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) >>> +|| >>> IsSymbolShdr(shdr)) { >>> >>> mCoffAlignment = (UINT32)shdr->sh_addralign; >>> >>> } >>> >>> } >>> >>> 1) Above change is to Set mCoffAlignment to the maximum alignment of >>> the input sections including symbol section. >>> >>> The symbol section will only exist with below change, so it >>> should have no effect to other drivers. >>> >>> build_rule.template: >>> >>> <Command.GCC> >>> >>> $(CP) ${src} $(DEBUG_DIR)(+)$(MODULE_NAME).debug >>> >>> #$(OBJCOPY) --strip-unneeded -R .eh_frame ${src} >>> >>> $(OBJCOPY) $(OBJCOPY_STRIPFLAG) ${src} >>> >>> tools_def.template: >>> >>> *_*_*_OBJCOPY_STRIPFLAG = --strip-unneeded -R .eh_frame >>> >>> PrmAddrTransDsm.inf: >>> >>> [BuildOptions.common] >>> >>> ... >>> >>> GCC: *_*_*_OBJCOPY_STRIPFLAG == -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 <bob.c.feng@intel.com >>> <mailto:bob.c.feng@intel.com>> >>> Sent: 2022年1月14日 14:12 >>> To: Huang, Li-Xia <lisa.huang@intel.com >>> <mailto:lisa.huang@intel.com>>; devel@edk2.groups.io >>> <mailto:devel@edk2.groups.io> >>> Cc: Gao, Liming <gaoliming@byosoft.com.cn >>> <mailto:gaoliming@byosoft.com.cn>>; Chen, Christine >>> <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>> >>> 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 ( >>> >>> if (shdr->sh_addralign <= mCoffAlignment) { >>> >>> continue; >>> >>> } >>> >>> - if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr)) >>> { >>> >>> + if (IsTextShdr(shdr) || IsDataShdr(shdr) || IsHiiRsrcShdr(shdr) >>> +|| >>> IsSymbolShdr(shdr)) { >>> >>> mCoffAlignment = (UINT32)shdr->sh_addralign; >>> >>> } >>> >>> } >>> >>> Thanks, >>> >>> Bob >>> >>> -----Original Message----- >>> >>> From: Huang, Li-Xia <lisa.huang@intel.com >>> <mailto:lisa.huang@intel.com>> >>> >>> Sent: Wednesday, January 12, 2022 3:44 PM >>> >>> To: devel@edk2.groups.io <mailto:devel@edk2.groups.io> >>> >>> Cc: Huang, Li-Xia <lisa.huang@intel.com >>> <mailto:lisa.huang@intel.com>>; Gao, Liming <gaoliming@byosoft.com.cn >>> <mailto:gaoliming@byosoft.com.cn>>; Feng, Bob C <bob.c.feng@intel.com >>> <mailto:bob.c.feng@intel.com>>; Chen, Christine <yuwei.chen@intel.com >>> <mailto:yuwei.chen@intel.com>> >>> >>> Subject: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export >>> table in PE-COFF >>> >>> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3802 >>> <https://bugzilla.tianocore.org/show_bug.cgi?id=3802> >>> >>> 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 <gaoliming@byosoft.com.cn >>> <mailto:gaoliming@byosoft.com.cn>> >>> >>> Cc: Bob Feng <bob.c.feng@intel.com <mailto:bob.c.feng@intel.com>> >>> >>> Cc: Yuwei Chen <yuwei.chen@intel.com <mailto:yuwei.chen@intel.com>> >>> >>> Signed-off-by: Lixia Huang <lisa.huang@intel.com >>> <mailto:lisa.huang@intel.com>> >>> >>> --- >>> >>> BaseTools/Source/C/GenFw/Elf64Convert.c | 254 >>> +++++++++++++++++- >>> >>> BaseTools/Source/C/GenFw/ElfConvert.c | 10 + >>> >>> BaseTools/Source/C/GenFw/ElfConvert.h | 42 ++- >>> >>> BaseTools/Source/C/GenFw/GenFw.c | 11 +- >>> >>> .../C/Include/IndustryStandard/PeImage.h | 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 ( >>> >>> VOID ); +STATIC+VOID+ScanSymbol64 (+ VOID+ >>> );++STATIC+VOID+WriteExport64 (+ VOID+ );+ 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 = 0; >>> >>> STATIC INT32 mRiscVPass1Offset; STATIC INT32 >>> mRiscVPass1GotFixup; +//+// Used for Export section.+//+STATIC >>> UINT32 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 ( >>> >>> ElfFunctions->SetImageSize = SetImageSize64; >>> ElfFunctions->CleanUp = CleanUp64; + if (mExportFlag) {+ >>> ElfFunctions->ElfFunctions->ScanSymbol = >>> ScanSymbol64;+ ElfFunctions->WriteExport = WriteExport64;+ } >>> return TRUE; } @@ -263,6 +287,17 @@ IsHiiRsrcShdr ( >>> >>> return (BOOLEAN) (strcmp((CHAR8*)mEhdr + Namedr->sh_offset + >>> Shdr->sh_name, ELF_HII_SECTION_NAME) == 0); } >>> +STATIC+BOOLEAN+IsSymbolShdr (+ Elf_Shdr *Shdr+ )+{+ Elf_Shdr >>> *Namehdr = GetShdrByIndex(mEhdr->e_shstrndx);++ return (BOOLEAN) >>> (strcmp((CHAR8*)mEhdr + Namehdr->sh_offset + Shdr->sh_name, >>> ELF_SYMBOL_SECTION_NAME) == 0);+}+ STATIC BOOLEAN IsDataShdr (@@ >>> -335,6 >>> +370,38 @@ GetSymName ( >>> >>> return StrtabContents + Sym->st_name; } +//+// Get Prm Handler >>> number and name+//+STATIC+VOID+FindPrmHandler (+ UINT64 Offset+ >>> )+{+ PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER *PrmExport;+ UINT32 >>> NameOffset;+ UINT32 HandlerNum;+ UINT32 Index;+ UINT8 >>> SymName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];++ PrmExport = >>> (PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER*)(mCoffFile + Offset);+ >>> NameOffset = sizeof(PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER) + >>> sizeof(EFI_GUID);++ for (HandlerNum = 0; HandlerNum < >>> PrmExport->NumberPrmHandlers; HandlerNum++) {+ for (Index = 0; >>> PrmExport->Index >>> < PRM_HANDLER_NAME_MAXIMUM_LENGTH; Index++) {+ SymName[Index] = >>> *((UINT8 *)PrmExport + NameOffset + Index);+ if (SymName[Index] >>> == >>> 0) {+ break;+ }+ }++ >>> strcpy(mExportSymName[mExportSymNum], >>> (CHAR8*)SymName);+ NameOffset += PRM_HANDLER_NAME_MAXIMUM_LENGTH + >>> sizeof(EFI_GUID);+ mExportSymNum ++;+ }+}+ // // Find the ELF >>> section hosting the GOT from an ELF Rva // of a single GOT entry. >>> Normally, GOT is placed in@@ -717,6 +784,7 @@ ScanSections64 ( >>> >>> UINT32 CoffEntry; >>> UINT32 SectionCount; BOOLEAN >>> FoundSection;+ >>> UINT32 Offset; CoffEntry = 0; mCoffOffset >>> = 0;@@ -750,7 +818,7 @@ ScanSections64 ( >>> >>> if (shdr->sh_addralign <= mCoffAlignment) { continue; >>> }- if (IsTextShdr(shdr) || IsDataShdr(shdr) || >>> IsHiiRsrcShdr(shdr)) {+ if (IsTextShdr(shdr) || IsDataShdr(shdr) >>> || IsHiiRsrcShdr(shdr) >>> || >>> IsSymbolShdr(shdr)) { mCoffAlignment = >>> (UINT32)shdr->sh_addralign; } }@@ -880,6 +948,16 @@ >>> ScanSections64 ( >>> >>> Warning (NULL, 0, 0, NULL, "Multiple sections in %s are merged >>> into 1 data section. Source level debug might not work correctly.", >>> mInImageName); } + //+ // The Symbol sections.+ //+ if >>> (mExportFlag) {+ mExportOffset = mCoffOffset;+ mExportSize = >>> sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;+ >>> mCoffOffset += mExportSize;+ mCoffOffset = >>> CoffAlign(mCoffOffset);+ }+ // // The HII resource sections. >>> //@@ -962,7 +1040,11 @@ >>> ScanSections64 ( >>> >>> | EFI_IMAGE_FILE_LARGE_ADDRESS_AWARE; >>> NtHdr->Pe32Plus.OptionalHeader.SizeOfCode = mDataOffset - >>> NtHdr->mTextOffset;- Pe32Plus.OptionalHeader.SizeOfInitializedData = >>> NtHdr->mRelocOffset - >>> mDataOffset;+ if(mExportFlag) {+ >>> NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - >>> mExportOffset;+ } else {+ >>> NtHdr->Pe32Plus.OptionalHeader.SizeOfInitializedData = mRelocOffset - >>> mDataOffset;+ } >>> NtHdr->Pe32Plus.OptionalHeader.SizeOfUninitializedData = 0; >>> NtHdr->Pe32Plus.OptionalHeader.AddressOfEntryPoint = CoffEntry; @@ >>> -989,8 +1071,17 @@ ScanSections64 ( >>> >>> NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + //+ // >>> If found symbol, add edata section between data and rsrc section+ >>> //+ >>> if(mExportFlag) {+ Offset = mExportOffset;+ } else {+ Offset = >>> mHiiRsrcOffset;+ }+ if ((mHiiRsrcOffset - mDataOffset) > 0) {- >>> CreateSectionHeader (".data", mDataOffset, mHiiRsrcOffset - >>> mDataOffset,+ CreateSectionHeader (".data", mDataOffset, Offset - >>> mDataOffset, EFI_IMAGE_SCN_CNT_INITIALIZED_DATA >>> | EFI_IMAGE_SCN_MEM_WRITE | EFI_IMAGE_SCN_MEM_READ);@@ -999,6 >>> | +1090,20 >>> @@ ScanSections64 ( >>> >>> NtHdr->Pe32Plus.FileHeader.NumberOfSections--; } + >>> if(mExportFlag) {+ if ((mHiiRsrcOffset - mExportOffset) > 0) {+ >>> CreateSectionHeader (".edata", mExportOffset, mHiiRsrcOffset - >>> mExportOffset,+ EFI_IMAGE_SCN_CNT_INITIALIZED_DATA+ | >>> EFI_IMAGE_SCN_MEM_READ);+ >>> NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTR >>> NtHdr->Y >>> NtHdr->_EXPORT].Size >>> = mHiiRsrcOffset - mExportOffset;+ >>> NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTR >>> NtHdr->Y >>> NtHdr->_EXPORT].VirtualAddress >>> = mExportOffset;+ NtHdr->Pe32Plus.FileHeader.NumberOfSections++;+ >>> } else {+ // Don't make a section of size 0.+ >>> NtHdr->Pe32Plus.FileHeader.NumberOfSections--;+ }+ }+ if >>> ((mRelocOffset - mHiiRsrcOffset) > 0) { CreateSectionHeader >>> (".rsrc", mHiiRsrcOffset, mRelocOffset - mHiiRsrcOffset, >>> EFI_IMAGE_SCN_CNT_INITIALIZED_DATA@@ -1757,4 +1862,145 @@ CleanUp64 ( >>> >>> } } +STATIC+VOID+ScanSymbol64 (+ VOID+ )+{+ UINT32 shIndex;+ >>> UINT32 SymIndex;+ Elf_Sym *Sym;+ UINT64 SymNum;+ const >>> UINT8 *SymName;++ for (shIndex = 0; shIndex < >>> mEhdr->e_shnum; shIndex++) {+ //+ // Determine if this is a >>> mEhdr->symbol >>> section.+ //+ Elf_Shdr *shdr = GetShdrByIndex(shIndex);+ if >>> (!IsSymbolShdr(shdr)) {+ continue;+ }++ UINT8 *Symtab = >>> (UINT8*)mEhdr + shdr->sh_offset;+ SymNum = (shdr->sh_size) / >>> (shdr->sh_entsize);++ //+ // First Get PrmModuleExportDescriptor+ >>> //+ for (SymIndex = 0; SymIndex < SymNum; SymIndex++) {+ Sym >>> = (Elf_Sym *)(Symtab + SymIndex * shdr->sh_entsize);+ SymName = >>> GetSymName(Sym);+ if (SymName == NULL) {+ continue;+ >>> }++ if (strcmp((CHAR8*)SymName, PRM_MODULE_EXPORT_DESCRIPTOR_NAME) >>> == 0) {+ //+ // Find PrmHandler Number and Name+ //+ >>> FindPrmHandler(Sym->st_value);++ >>> strcpy(mExportSymName[mExportSymNum], (CHAR8*)SymName);+ >>> mExportRVA[mExportSymNum] = (UINT32)(Sym->st_value);+ mExportSize >>> += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + >>> strlen((CHAR8 *)SymName) + 1;+ mExportSymNum ++;+ break;+ >>> }+ }++ //+ // Second Get PrmHandler+ //+ for (SymIndex = >>> 0; SymIndex < SymNum; SymIndex++) {+ UINT32 ExpIndex;+ Sym >>> = (Elf_Sym *)(Symtab + SymIndex * >>> shdr->sh_entsize);+ SymName = GetSymName(Sym);+ if (SymName >>> shdr->== >>> NULL) {+ continue;+ }++ for (ExpIndex = 0; >>> ExpIndex < (mExportSymNum -1); ExpIndex++) {+ if >>> (strcmp((CHAR8*)SymName, >>> mExportSymName[ExpIndex]) != 0) {+ continue;+ }+ >>> mExportRVA[ExpIndex] = (UINT32)(Sym->st_value);+ mExportSize >>> += >>> 2 >>> * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + >>> strlen((CHAR8 *)SymName) + 1;+ }+ }++ break;+ >>> }+}++STATIC+VOID+WriteExport64 (+ VOID+ )+{+ >>> EFI_IMAGE_OPTIONAL_HEADER_UNION *NtHdr;+ >>> EFI_IMAGE_EXPORT_DIRECTORY *ExportDir;+ >>> EFI_IMAGE_DATA_DIRECTORY *DataDir;+ UINT32 FileNameOffset;+ UINT32 >>> FuncOffset;+ >>> UINT16 Index;+ >>> UINT8 *Tdata = NULL;++ ExportDir = >>> (EFI_IMAGE_EXPORT_DIRECTORY*)(mCoffFile + mExportOffset);+ >>> ExportDir->Characteristics = 0;+ ExportDir->TimeDateStamp = 0;+ >>> ExportDir->MajorVersion = 0;+ ExportDir->MinorVersion =0;+ Name = >>> ExportDir->0;+ >>> ExportDir->ExportDir->NumberOfFunctions = mExportSymNum;+ >>> ExportDir->NumberOfNames = mExportSymNum;+ ExportDir->Base = >>> EFI_IMAGE_EXPORT_ORDINAL_BASE;+ ExportDir->AddressOfFunctions = >>> mExportOffset + sizeof(EFI_IMAGE_EXPORT_DIRECTORY);+ >>> ExportDir->AddressOfNames = ExportDir->AddressOfFunctions + >>> EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;+ >>> ExportDir->AddressOfNameOrdinals = ExportDir->AddressOfNames + >>> EFI_IMAGE_EXPORT_ADDR_SIZE * mExportSymNum;++ FileNameOffset = >>> ExportDir->AddressOfNameOrdinals + EFI_IMAGE_EXPORT_ORDINAL_SIZE * >>> mExportSymNum;+ FuncOffset = FileNameOffset + strlen(mInImageName) + >>> 1;++ // Write Input image Name RVA+ Tdata = mCoffFile + 12;+ >>> *(UINT32 *)Tdata = FileNameOffset;++ // Write Input image Name+ >>> strcpy((char *)(mCoffFile + FileNameOffset), mInImageName);++ for >>> (Index = 0; Index < mExportSymNum; Index++) {+ //+ // Write >>> Export Address Table+ //+ Tdata = mCoffFile + >>> ExportDir->AddressOfFunctions + Index * EFI_IMAGE_EXPORT_ADDR_SIZE;+ >>> ExportDir->*(UINT32 *)Tdata = >>> mExportRVA[Index];++ //+ // Write Export Name Pointer Table+ >>> //+ Tdata = mCoffFile + ExportDir->AddressOfNames + Index * >>> EFI_IMAGE_EXPORT_ADDR_SIZE;+ *(UINT32 *)Tdata = FuncOffset;++ //+ >>> // Write Export Ordinal table+ //+ Tdata = mCoffFile + >>> ExportDir->AddressOfNameOrdinals + Index * >>> EFI_IMAGE_EXPORT_ORDINAL_SIZE;+ *(UINT16 *)Tdata = Index;++ //+ >>> // Write Export Name Table+ //+ strcpy((char *)(mCoffFile + >>> FuncOffset), mExportSymName[Index]);+ FuncOffset += >>> strlen(mExportSymName[Index]) + 1;+ }++ NtHdr = >>> (EFI_IMAGE_OPTIONAL_HEADER_UNION *)(mCoffFile + mNtHdrOffset);+ >>> DataDir = >>> &NtHdr->Pe32Plus.OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENT >>> R >>> Y_EXPORT];+ >>> DataDir->VirtualAddress = mExportOffset;+ DataDir->Size = >>> 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 ( >>> >>> VerboseMsg ("Write debug info."); ElfFunctions.WriteDebug (); >>> + //+ // For PRM Driver to Write export info.+ //+ if >>> (mExportFlag) {+ VerboseMsg ("Scan symbol info.");+ >>> ElfFunctions.ScanSymbol ();+ VerboseMsg ("Write export info.");+ >>> ElfFunctions.WriteExport ();+ }+ // // Make sure image size is >>> correct before returning the new image. //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 *mCoffFile; extern UINT32 >>> mTableOffset; extern UINT32 mOutImageType; extern UINT32 >>> mFileBufferSize;+extern BOOLEAN mExportFlag; // // 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 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 {+ EFI_GUID >>> PrmHandlerGuid;+ CHAR8 >>> PrmHandlerName[PRM_HANDLER_NAME_MAXIMUM_LENGTH];+} >>> PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT;++typedef struct {+ >>> UINT64 Signature;+ >>> UINT16 Revision;+ >>> UINT16 NumberPrmHandlers;+ EFI_GUID >>> PlatformGuid;+ EFI_GUID ModuleGuid;+} >>> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER;++typedef struct {+ >>> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT_HEADER Header;+ >>> PRM_HANDLER_EXPORT_DESCRIPTOR_STRUCT >>> PrmHandlerExportDescriptors[1];+} >>> PRM_MODULE_EXPORT_DESCRIPTOR_STRUCT;++#pragma pack(pop) // // Filter >>> Types@@ -38,7 +75,8 @@ extern UINT32 mFileBufferSize; >>> >>> typedef enum { SECTION_TEXT, SECTION_HII,- SECTION_DATA+ >>> SECTION_DATA,+ SECTION_SYMBOL } SECTION_FILTER_TYPES; @@ -50,6 >>> +88,8 @@ typedef struct { >>> >>> BOOLEAN (*WriteSections) (SECTION_FILTER_TYPES FilterType); >>> VOID (*WriteRelocations) (); VOID (*WriteDebug) ();+ VOID >>> (*ScanSymbol) ();+ VOID (*WriteExport) (); VOID >>> (*SetImageSize) (); VOID (*CleanUp) (); diff --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 = 0; >>> >>> UINT32 mImageSize = 0; UINT32 mOutImageType = FW_DUMMY_IMAGE; BOOLEAN >>> mIsConvertXip = FALSE;-+BOOLEAN mExportFlag = FALSE; STATIC >>> EFI_STATUS@@ -1436,6 +1436,15 @@ Returns: >>> >>> continue; } + if (stricmp (argv[0], "--PRM") == 0) {+ >>> if (!mExportFlag) {+ mExportFlag = TRUE;+ }+ argc --;+ >>> argv ++;+ continue;+ }+ if (argv[0][0] == >>> '-') { Error (NULL, 0, 1000, "Unknown 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 { >>> >>> UINT32 AddressOfNameOrdinals; } EFI_IMAGE_EXPORT_DIRECTORY; >>> +//+// Based export types.+//+#define EFI_IMAGE_EXPORT_ORDINAL_BASE >>> 1+#define EFI_IMAGE_EXPORT_ADDR_SIZE 4+#define >>> EFI_IMAGE_EXPORT_ORDINAL_SIZE 2+ /// /// DLL support. /// Import >>> Format-- >>> >>> 2.26.2.windows.1 >>> >>> ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2022-01-27 16:02 UTC | newest] Thread overview: 10+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2022-01-12 7:44 [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF Lixia Huang 2022-01-14 6:11 ` Bob Feng 2022-01-17 3:09 ` Huang, Li-Xia 2022-01-18 5:20 ` 回复: " gaoliming 2022-01-18 6:19 ` Huang, Li-Xia 2022-01-22 2:50 ` Michael Kubacki 2022-01-26 8:16 ` lisa.huang 2022-01-26 20:18 ` Michael Kubacki 2022-01-27 3:04 ` Huang, Li-Xia 2022-01-27 16:02 ` Michael Kubacki
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox