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 <[email protected]>
Sent: Wednesday, January 12, 2022 3:44 PM
To: [email protected]
Cc: Huang, Li-Xia <[email protected]>; Gao, Liming
<[email protected]>; Feng, Bob C <[email protected]>; Chen, Christine
<[email protected]>
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 <[email protected]>
Cc: Bob Feng <[email protected]>
Cc: Yuwei Chen <[email protected]>
Signed-off-by: Lixia Huang <[email protected]>
---
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/21656
Group Owner: [email protected]
Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-