Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BaseTools/Plugin/FlattenPdbs/FlattenPdbs_plug_in.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

{
"scope": "global",
"id": "flatten-pdbs",
"name": "Flatten PDBs UEFI Build Plugin",
"module": "FlattenPdbs"
}
79 changes: 56 additions & 23 deletions BaseTools/Source/C/GenFw/Elf64Convert.c
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ InitializeElf64 (

if (mExportFlag) {
if ((mEhdr->e_machine != EM_X86_64) && (mEhdr->e_machine != EM_AARCH64)) {
Error (NULL, 0, 3000, "Unsupported", "--prm option currently only supports X64 and AArch64 archs.");
Error (NULL, 0, 3000, "Unsupported", "--prm/--export-symbol option currently only supports X64 and AArch64 archs.");
return FALSE;
}
}
Expand Down Expand Up @@ -1038,13 +1038,26 @@ ScanSections64 (
//
if (mExportFlag) {
UINT32 SymIndex;
UINT32 ExpIndex;
Elf_Sym *Sym;
UINT64 SymNum;
const UINT8 *SymName;

mExportOffset = mCoffOffset;
mExportSize = sizeof(EFI_IMAGE_EXPORT_DIRECTORY) + strlen(mInImageName) + 1;

//
// If explicit export symbols are specified, pre-populate mExportSymName
//
if (mExplicitExportSymbolCount > 0) {
for (ExpIndex = 0; ExpIndex < mExplicitExportSymbolCount; ExpIndex++) {
strncpy(mExportSymName[ExpIndex], mExplicitExportSymbols[ExpIndex], PRM_HANDLER_NAME_MAXIMUM_LENGTH - 1);
mExportSymName[ExpIndex][PRM_HANDLER_NAME_MAXIMUM_LENGTH - 1] = '\0';
mExportRVA[ExpIndex] = 0; // Will be filled in below
}
mExportSymNum = mExplicitExportSymbolCount;
}

for (i = 0; i < mEhdr->e_shnum; i++) {

//
Expand All @@ -1059,52 +1072,72 @@ ScanSections64 (
SymNum = (shdr->sh_size) / (shdr->sh_entsize);

//
// First Get PrmModuleExportDescriptor
// If using PRM mechanism, 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 (mExplicitExportSymbolCount == 0) {
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);
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;
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
// Find RVAs for all export symbols (works for both PRM and explicit modes)
//
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++) {
for (ExpIndex = 0; ExpIndex < mExportSymNum; 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;
//
// For explicit mode, only update if RVA not yet set
// For PRM mode, skip the descriptor (last entry) as it's already set
//
if ((mExplicitExportSymbolCount > 0 && mExportRVA[ExpIndex] == 0) ||
(mExplicitExportSymbolCount == 0 && ExpIndex < mExportSymNum - 1)) {
mExportRVA[ExpIndex] = (UINT32)(Sym->st_value);
mExportSize += 2 * EFI_IMAGE_EXPORT_ADDR_SIZE + EFI_IMAGE_EXPORT_ORDINAL_SIZE + strlen((CHAR8 *)SymName) + 1;
}
}
}

break;
}

//
// Verify all requested symbols were found (for explicit export mode)
//
if (mExplicitExportSymbolCount > 0) {
for (ExpIndex = 0; ExpIndex < mExportSymNum; ExpIndex++) {
if (mExportRVA[ExpIndex] == 0) {
Error (NULL, 0, 3000, "Invalid", "Symbol '%s' not found in ELF file.", mExportSymName[ExpIndex]);
assert (FALSE);
}
}
}

mCoffOffset += mExportSize;
mCoffOffset = CoffAlign(mCoffOffset);
}
Expand Down
2 changes: 2 additions & 0 deletions BaseTools/Source/C/GenFw/ElfConvert.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ extern UINT32 mOutImageType;
extern UINT32 mFileBufferSize;
extern BOOLEAN mExportFlag;
extern BOOLEAN mBuildIdFlag;
extern UINT32 mExplicitExportSymbolCount;
extern CHAR8 *mExplicitExportSymbols[];

//
// Common EFI specific data.
Expand Down
28 changes: 28 additions & 0 deletions BaseTools/Source/C/GenFw/GenFw.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent
#include "EfiUtilityMsgs.h"

#include "GenFw.h"
#include "ElfConvert.h"

//
// Version of this utility
Expand Down Expand Up @@ -91,6 +92,12 @@ BOOLEAN mExportFlag = FALSE;
BOOLEAN mNoNxCompat = FALSE;
BOOLEAN mBuildIdFlag = FALSE;

//
// Explicit export symbol support
//
UINT32 mExplicitExportSymbolCount = 0;
CHAR8 *mExplicitExportSymbols[PRM_MODULE_EXPORT_SYMBOL_NUM];

STATIC
EFI_STATUS
ZeroDebugData (
Expand Down Expand Up @@ -285,6 +292,10 @@ Routine Description:
write export table into PE-COFF.\n\
This option can be used together with -e.\n\
It doesn't work for other options.\n");
fprintf (stdout, " --export-symbol=NAME Export the specified symbol to PE-COFF export table.\n\
Can be specified multiple times for multiple symbols.\n\
This option can be used together with -e.\n\
It doesn't work for other options.\n");
fprintf (stdout, " --nonxcompat Do not set the IMAGE_DLLCHARACTERISTICS_NX_COMPAT bit \n\
of the optional header in the PE header even if the \n\
requirements are met.\n");
Expand Down Expand Up @@ -1516,6 +1527,23 @@ Routine Description:
continue;
}

if (strnicmp (argv[0], "--export-symbol=", 16) == 0) {
if (mExplicitExportSymbolCount >= PRM_MODULE_EXPORT_SYMBOL_NUM) {
Error (NULL, 0, 1003, "Invalid option", "Too many --export-symbol options (max %d)", PRM_MODULE_EXPORT_SYMBOL_NUM);
goto Finish;
}
mExplicitExportSymbols[mExplicitExportSymbolCount] = argv[0] + 16;
if (strlen(mExplicitExportSymbols[mExplicitExportSymbolCount]) == 0) {
Error (NULL, 0, 1003, "Invalid option value", "--export-symbol requires a symbol name");
goto Finish;
}
mExplicitExportSymbolCount++;
mExportFlag = TRUE;
argc --;
argv ++;
continue;
}

if (stricmp (argv[0], "--nonxcompat") == 0) {
mNoNxCompat = TRUE;
argc --;
Expand Down