[edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF

Lixia Huang posted 1 patch 1 week, 5 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/edk2 tags/patchew/20220112074423.5075-1-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(-)

[edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF

Posted by Lixia Huang 1 week, 5 days ago
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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#85618): https://edk2.groups.io/g/devel/message/85618
Mute This Topic: https://groups.io/mt/88373239/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF

Posted by Bob Feng 1 week, 3 days ago
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



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#85708): https://edk2.groups.io/g/devel/message/85708
Mute This Topic: https://groups.io/mt/88373239/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF

Posted by Huang, Li-Xia 1 week, 1 day ago
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




-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#85725): https://edk2.groups.io/g/devel/message/85725
Mute This Topic: https://groups.io/mt/88373239/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


回复: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF

Posted by gaoliming 1 week ago
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

 





-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#85770): https://edk2.groups.io/g/devel/message/85770
Mute This Topic: https://groups.io/mt/88503416/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF

Posted by Huang, Li-Xia 6 days, 23 hours ago
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





-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#85800): https://edk2.groups.io/g/devel/message/85800
Mute This Topic: https://groups.io/mt/88528314/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-


Re: [edk2-devel][PATCH] BaseTools/GenFw: Enhance to add export table in PE-COFF

Posted by Michael Kubacki 3 days, 3 hours ago
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
> 
> 


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#85943): https://edk2.groups.io/g/devel/message/85943
Mute This Topic: https://groups.io/mt/88528314/1787277
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [importer@patchew.org]
-=-=-=-=-=-=-=-=-=-=-=-