[PATCH 1/3] BaseTools/GenFv: Add PE/COFF resource sections injection to GenFw


Andrew Fish
 

BZ: https://bugzilla.tianocore.org/show_bug.cgi?id=3D557

The XCODE toolchain does not suport injecting resource sections via
libraries so add --rc to GenFw to inject $(MODULE_NAME)hii.rc into
the final PE/COFF image.

Since moving exiting code around would break source level debugging
we must reuse an existing empty section, or add a new section header.
If there is not space to add a new section header append to the
last section. The resource entry if found via a directory entry
so the PE/COFF loading code does not depend on the section type.

Signed-off-by: Andrew Fish <afish@...>
Cc: Bob Feng <bob.c.feng@...>
Cc: Liming Gao <liming.gao@...>
---
BaseTools/Source/C/GenFw/GenFw.c | 370 +++++++++++++++++++++++++++++++
1 file changed, 370 insertions(+)

diff --git a/BaseTools/Source/C/GenFw/GenFw.c b/BaseTools/Source/C/GenFw/Ge=
nFw.c
index 8cab70ba4d5f..748af5dff259 100644
--- a/BaseTools/Source/C/GenFw/GenFw.c
+++ b/BaseTools/Source/C/GenFw/GenFw.c
@@ -96,6 +96,16 @@ ZeroDebugData (
BOOLEAN ZeroDebug=0D
);=0D
=0D
+STATIC=0D
+EFI_STATUS=0D
+PatchResourceData (=0D
+ IN UINT32 Type,=0D
+ IN UINT8 *ResourceData,=0D
+ IN UINT32 ResourceDataSize,=0D
+ IN OUT UINT8 **PeCoff,=0D
+ IN OUT UINT32 *PeCoffSize=0D
+ );=0D
+=0D
STATIC=0D
EFI_STATUS=0D
SetStamp (=0D
@@ -267,6 +277,11 @@ Returns:
except for -o option. It is a action option.\n\=0D
If it is combined with other action options, the l=
ater\n\=0D
input action option will override the previous one=
.\n");=0D
+ fprintf (stdout, " --rc FlieName Append a Hii resource section =
to the\n\=0D
+ last PE/COFF section. The FileName is the resource=
section to append\n\=0D
+ If FileName does not exist this operation is skipp=
ed. This feature is\n\=0D
+ only intended for toolchains, like XCODE, that don=
't suport $(RC).\n\=0D
+ This option can only be combined with -e\n");=0D
fprintf (stdout, " --rebase NewAddress Rebase image to new base addre=
ss. New address \n\=0D
is also set to the first none code section header.=
\n\=0D
It can't be combined with other action options\n\=
=0D
@@ -1059,10 +1074,12 @@ Returns:
CHAR8 **InputFileName;=0D
char *OutImageName;=0D
char *ModuleType;=0D
+ char *RcFileName;=0D
CHAR8 *TimeStamp;=0D
FILE *fpIn;=0D
FILE *fpOut;=0D
FILE *fpInOut;=0D
+ FILE *fpRc;=0D
UINT32 Data;=0D
UINT32 *DataPointer;=0D
UINT32 *OldDataPointer;=0D
@@ -1080,6 +1097,8 @@ Returns:
UINT32 OutputFileLength;=0D
UINT8 *InputFileBuffer;=0D
UINT32 InputFileLength;=0D
+ UINT8 *RcFileBuffer;=0D
+ UINT32 RcFileLength;=0D
RUNTIME_FUNCTION *RuntimeFunction;=0D
UNWIND_INFO *UnwindInfo;=0D
STATUS Status;=0D
@@ -1116,6 +1135,7 @@ Returns:
time_t OutputFileTime;=0D
struct stat Stat_Buf;=0D
BOOLEAN ZeroDebugFlag;=0D
+ BOOLEAN InsertRcFile;=0D
=0D
SetUtilityName (UTILITY_NAME);=0D
=0D
@@ -1128,6 +1148,7 @@ Returns:
mInImageName =3D NULL;=0D
OutImageName =3D NULL;=0D
ModuleType =3D NULL;=0D
+ RcFileName =3D NULL;=0D
Type =3D 0;=0D
Status =3D STATUS_SUCCESS;=0D
FileBuffer =3D NULL;=0D
@@ -1164,6 +1185,7 @@ Returns:
InputFileTime =3D 0;=0D
OutputFileTime =3D 0;=0D
ZeroDebugFlag =3D FALSE;=0D
+ InsertRcFile =3D FALSE;=0D
=0D
if (argc =3D=3D 1) {=0D
Error (NULL, 0, 1001, "Missing options", "No input options.");=0D
@@ -1436,6 +1458,20 @@ Returns:
continue;=0D
}=0D
=0D
+ if (stricmp (argv[0], "--rc") =3D=3D 0) {=0D
+ RcFileName =3D argv[1];=0D
+ argc -=3D 2;=0D
+ argv +=3D 2;=0D
+=0D
+ if (stat (RcFileName, &Stat_Buf) =3D=3D 0) {=0D
+ //=0D
+ // File exists=0D
+ //=0D
+ InsertRcFile =3D TRUE;=0D
+ }=0D
+ continue;=0D
+ }=0D
+=0D
if (argv[0][0] =3D=3D '-') {=0D
Error (NULL, 0, 1000, "Unknown option", argv[0]);=0D
goto Finish;=0D
@@ -1568,6 +1604,10 @@ Returns:
break;=0D
}=0D
=0D
+ if (InsertRcFile) {=0D
+ VerboseMsg ("RC input file %s", RcFileName);=0D
+ }=0D
+=0D
if (ReplaceFlag) {=0D
VerboseMsg ("Overwrite the input file with the output content.");=0D
}=0D
@@ -2052,6 +2092,52 @@ Returns:
}=0D
}=0D
=0D
+ //=0D
+ // Insert Resources into the image.=0D
+ //=0D
+ if (InsertRcFile) {=0D
+ fpRc =3D fopen (LongFilePath (RcFileName), "rb");=0D
+ if (fpRc =3D=3D NULL) {=0D
+ Error (NULL, 0, 0001, "Error opening file", RcFileName);=0D
+ goto Finish;=0D
+ }=0D
+=0D
+ RcFileLength =3D _filelength (fileno (fpRc));=0D
+ RcFileBuffer =3D malloc (RcFileLength);=0D
+ if (FileBuffer =3D=3D NULL) {=0D
+ Error (NULL, 0, 4001, "Resource", "memory cannot be allocated!");=0D
+ fclose (fpRc);=0D
+ goto Finish;=0D
+ }=0D
+=0D
+ fread (RcFileBuffer, 1, RcFileLength, fpRc);=0D
+ fclose (fpRc);=0D
+=0D
+ Status =3D PatchResourceData (Type, RcFileBuffer, RcFileLength, &FileB=
uffer, &FileLength);=0D
+ if (EFI_ERROR (Status)) {=0D
+ Error (NULL, 0, 3000, "Invalid", "RC Patch Data Error status is 0x%x=
", (int) Status);=0D
+ goto Finish;=0D
+ }=0D
+=0D
+ fpOut =3D fopen (LongFilePath (OutImageName), "wb");=0D
+ if (fpOut =3D=3D NULL) {=0D
+ Error (NULL, 0, 0001, "Error opening output file", OutImageName);=0D
+ goto Finish;=0D
+ }=0D
+=0D
+ fwrite (FileBuffer, 1, FileLength, fpOut);=0D
+=0D
+ fclose (fpOut);=0D
+ fpOut =3D NULL;=0D
+ VerboseMsg ("the size of output file is %u bytes", (unsigned) FileLeng=
th);=0D
+=0D
+ //=0D
+ // Write the updated Image=0D
+ //=0D
+ goto Finish;=0D
+ }=0D
+=0D
+=0D
//=0D
// Convert ELF image to PeImage=0D
//=0D
@@ -2761,6 +2847,290 @@ Finish:
return GetUtilityStatus ();=0D
}=0D
=0D
+#define ALIGN_VALUE(Value, Alignment) ((Value) + (((Alignment) - (Value)) =
& ((Alignment) - 1)))=0D
+=0D
+STATIC=0D
+EFI_STATUS=0D
+PatchResourceData (=0D
+ IN UINT32 Type,=0D
+ IN UINT8 *ResourceData,=0D
+ IN UINT32 ResourceDataSize,=0D
+ IN OUT UINT8 **PeCoff,=0D
+ IN OUT UINT32 *PeCoffSize=0D
+ )=0D
+/*++=0D
+=0D
+Routine Description:=0D
+=0D
+ Embed Resource data into a PE/COFF image.=0D
+=0D
+ If there is free space between the header and the image add a new=0D
+ .rsrc section to the PE/COFF image. If no space exists then append=0D
+ the resource data to the last section.=0D
+=0D
+Arguments:=0D
+=0D
+ Type - If not zero them update PE/COFF header module type.=0D
+ ResourceData - *hii.rc data to insert into the image.=0D
+ ResourceDataSize - Size of ResourceData in bytes.=0D
+ PeCoff - On input existing PE/COFF, on output input PE/COFF wi=
th=0D
+ ResourceData embedded.=0D
+ PeCoffSize - Size of PeCoff in bytes.=0D
+=0D
+Returns:=0D
+=0D
+ EFI_ABORTED - PeImage is invalid.=0D
+ EFI_SUCCESS - Zero debug data successfully.=0D
+=0D
+--*/=0D
+{=0D
+ UINT8 *FileBuffer;=0D
+ UINT32 FileBufferSize;=0D
+ EFI_IMAGE_DOS_HEADER *DosHdr;=0D
+ EFI_IMAGE_FILE_HEADER *FileHdr;=0D
+ EFI_IMAGE_OPTIONAL_HEADER32 *Optional32Hdr;=0D
+ EFI_IMAGE_OPTIONAL_HEADER64 *Optional64Hdr;=0D
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;=0D
+ UINT32 FileAlignment;=0D
+ UINT32 Max;=0D
+ INTN LastSection;=0D
+ INTN EmptySection;=0D
+ UINT32 ActualHeaderSize;=0D
+ UINT32 StartingPeCoffSize;=0D
+ UINT32 NewHeaderSize;=0D
+ CHAR8 *Base;=0D
+ EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;=0D
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry;=0D
+ EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;=0D
+ EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;=0D
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;=0D
+ CHAR16 *String;=0D
+ UINT32 Offset;=0D
+ UINT32 Index;=0D
+=0D
+ //=0D
+ // Grow the file in units of FileAlignment=0D
+ //=0D
+ DosHdr =3D (EFI_IMAGE_DOS_HEADER *) *PeCoff;=0D
+ if (DosHdr->e_magic !=3D EFI_IMAGE_DOS_SIGNATURE) {=0D
+ // NO DOS header, must start with PE/COFF header=0D
+ FileHdr =3D (EFI_IMAGE_FILE_HEADER *)(*PeCoff + sizeof (UINT32));=0D
+ } else {=0D
+ FileHdr =3D (EFI_IMAGE_FILE_HEADER *)(*PeCoff + DosHdr->e_lfanew + si=
zeof (UINT32));=0D
+ }=0D
+=0D
+ Optional32Hdr =3D (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + si=
zeof (EFI_IMAGE_FILE_HEADER));=0D
+ Optional64Hdr =3D (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + si=
zeof (EFI_IMAGE_FILE_HEADER));=0D
+ if (Optional32Hdr->Magic =3D=3D EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {=0D
+ FileAlignment =3D Optional32Hdr->FileAlignment;=0D
+ SectionHeader =3D (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional=
32Hdr + FileHdr->SizeOfOptionalHeader);=0D
+ } else {=0D
+ FileAlignment =3D Optional64Hdr->FileAlignment;=0D
+ SectionHeader =3D (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional=
64Hdr + FileHdr->SizeOfOptionalHeader);=0D
+ }=0D
+=0D
+ LastSection =3D -1;=0D
+ for (Index =3D 0, Max =3D 0; Index < FileHdr->NumberOfSections; Index++)=
{=0D
+ if (SectionHeader[Index].PointerToRawData > Max) {=0D
+ Max =3D SectionHeader[Index].PointerToRawData;=0D
+ LastSection =3D Index;=0D
+ }=0D
+ }=0D
+=0D
+ EmptySection =3D -1;=0D
+ for (Index =3D 0; Index < FileHdr->NumberOfSections; Index++) {=0D
+ if ((SectionHeader[Index].Misc.VirtualSize =3D=3D 0) && (SectionHeader=
[Index].SizeOfRawData =3D=3D 0)) {=0D
+ //=0D
+ // No Data or Zero Fill so we can repurpose this entry.=0D
+ //=0D
+ EmptySection =3D Index;=0D
+ break;=0D
+ }=0D
+ }=0D
+=0D
+ if (EmptySection =3D=3D -1) {=0D
+ ActualHeaderSize =3D (UINTN)(&SectionHeader[FileHdr->NumberOfSections]=
) - (UINTN)*PeCoff;=0D
+ if ((ActualHeaderSize + sizeof (EFI_IMAGE_SECTION_HEADER)) <=3D Option=
al32Hdr->SizeOfHeaders) {=0D
+ //=0D
+ // There is space to inject a new section.=0D
+ //=0D
+ FileHdr->NumberOfSections +=3D 1;=0D
+ EmptySection =3D Index;=0D
+ }=0D
+ }=0D
+=0D
+ StartingPeCoffSize =3D SectionHeader[LastSection].PointerToRawData + Sec=
tionHeader[LastSection].SizeOfRawData;=0D
+ if (SectionHeader[LastSection].Misc.VirtualSize > SectionHeader[LastSect=
ion].SizeOfRawData) {=0D
+ StartingPeCoffSize +=3D SectionHeader[LastSection].Misc.VirtualSize - =
SectionHeader[LastSection].SizeOfRawData;=0D
+ }=0D
+=0D
+ FileBufferSize =3D ALIGN_VALUE(StartingPeCoffSize + ResourceDataSize=
, FileAlignment);=0D
+ FileBuffer =3D malloc (FileBufferSize);=0D
+ if (FileBuffer =3D=3D NULL) {=0D
+ return RETURN_OUT_OF_RESOURCES;=0D
+ }=0D
+ memset (FileBuffer, 0, FileBufferSize);=0D
+=0D
+ //=0D
+ // Append the Resource Data to the end of the PE/COFF image.=0D
+ //=0D
+ NewHeaderSize =3D Optional32Hdr->SizeOfHeaders;=0D
+ CopyMem (FileBuffer, *PeCoff, (StartingPeCoffSize > *PeCoffSize) ? *PeC=
offSize: StartingPeCoffSize);=0D
+ CopyMem (FileBuffer + StartingPeCoffSize, ResourceData, ResourceDataSize=
);=0D
+=0D
+ free (*PeCoff);=0D
+ *PeCoff =3D FileBuffer;=0D
+ *PeCoffSize =3D FileBufferSize;=0D
+=0D
+ DosHdr =3D (EFI_IMAGE_DOS_HEADER *)FileBuffer;=0D
+ if (DosHdr->e_magic !=3D EFI_IMAGE_DOS_SIGNATURE) {=0D
+ // NO DOS header, must start with PE/COFF header=0D
+ FileHdr =3D (EFI_IMAGE_FILE_HEADER *)(FileBuffer + sizeof (UINT32));=
=0D
+ } else {=0D
+ FileHdr =3D (EFI_IMAGE_FILE_HEADER *)(FileBuffer + DosHdr->e_lfanew +=
sizeof (UINT32));=0D
+ }=0D
+=0D
+ //=0D
+ // Get Resource EntryTable offset, and Section header=0D
+ //=0D
+ Optional32Hdr =3D (EFI_IMAGE_OPTIONAL_HEADER32 *) ((UINT8*) FileHdr + si=
zeof (EFI_IMAGE_FILE_HEADER));=0D
+ Optional64Hdr =3D (EFI_IMAGE_OPTIONAL_HEADER64 *) ((UINT8*) FileHdr + si=
zeof (EFI_IMAGE_FILE_HEADER));=0D
+ DirectoryEntry =3D NULL;=0D
+ if (Optional32Hdr->Magic =3D=3D EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {=0D
+ SectionHeader =3D (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional32Hd=
r + FileHdr->SizeOfOptionalHeader);=0D
+ if (Optional32Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RES=
OURCE) {=0D
+ DirectoryEntry =3D &Optional32Hdr->DataDirectory[EFI_IMAGE_DIRECTORY=
_ENTRY_RESOURCE];=0D
+ }=0D
+ } else {=0D
+ SectionHeader =3D (EFI_IMAGE_SECTION_HEADER *) ((UINT8 *) Optional64Hd=
r + FileHdr->SizeOfOptionalHeader);=0D
+ if (Optional64Hdr->NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_RES=
OURCE) {=0D
+ DirectoryEntry =3D &Optional64Hdr->DataDirectory[EFI_IMAGE_DIRECTORY=
_ENTRY_RESOURCE];=0D
+ }=0D
+ }=0D
+=0D
+ if (DirectoryEntry =3D=3D NULL) {=0D
+ return RETURN_OUT_OF_RESOURCES;=0D
+ }=0D
+=0D
+ if (EmptySection !=3D -1) {=0D
+ //=0D
+ // Create a new section=0D
+ //=0D
+ CopyMem (SectionHeader[EmptySection].Name, ".rsrc\0\0\0", EFI_IMAGE_SI=
ZEOF_SHORT_NAME);=0D
+ SectionHeader[EmptySection].Misc.VirtualSize =3D ResourceDataSize;=0D
+ SectionHeader[EmptySection].VirtualAddress =3D StartingPeCoffSize;=0D
+ SectionHeader[EmptySection].SizeOfRawData =3D ALIGN_VALUE(ResourceD=
ataSize, FileAlignment);=0D
+ SectionHeader[EmptySection].PointerToRawData =3D StartingPeCoffSize;=0D
+=0D
+ SectionHeader[EmptySection].Characteristics =3D EFI_IMAGE_SCN_MEM_EXE=
CUTE | EFI_IMAGE_SCN_MEM_READ;=0D
+ SectionHeader[EmptySection].Characteristics |=3D EFI_IMAGE_SCN_CNT_INI=
TIALIZED_DATA | EFI_IMAGE_SCN_CNT_CODE;=0D
+=0D
+ DirectoryEntry->VirtualAddress =3D SectionHeader[EmptySection].Virtual=
Address;=0D
+ } else {=0D
+ //=0D
+ // Grow the last section to include the resources.=0D
+ // For Xcode this is always the .debug section.=0D
+ //=0D
+ SectionHeader[LastSection].SizeOfRawData =3D ALIGN_VALUE(SectionHeader=
[LastSection].SizeOfRawData + ResourceDataSize, FileAlignment);=0D
+=0D
+ //=0D
+ // Make sure the Virtual Size uses the file aligned actual size, since=
we are growing the file.=0D
+ //=0D
+ SectionHeader[LastSection].Misc.VirtualSize =3D SectionHeader[LastSect=
ion].SizeOfRawData;=0D
+=0D
+ DirectoryEntry->VirtualAddress =3D StartingPeCoffSize;=0D
+ }=0D
+ DirectoryEntry->Size =3D ResourceDataSize;=0D
+=0D
+ Optional32Hdr->SizeOfImage =3D ALIGN_VALUE(*PeCoffSize, Optional32Hdr->S=
ectionAlignment);=0D
+ if (Type !=3D 0) {=0D
+ Optional32Hdr->Subsystem =3D Type;=0D
+ }=0D
+=0D
+ //=0D
+ // It looks like the ResourceDataEntry->OffsetToData is relative to the =
rc file,=0D
+ // but PeCoffLoaderLoadImage() assumes it is a PE/COFF VirtualAddress so=
we need=0D
+ // to fix it up. Walk the ResourceDataEntry just like PeCoffLoaderLoadIm=
age() and=0D
+ // patch it.=0D
+ //=0D
+ Base =3D (CHAR8 *)(FileBuffer + StartingPeCoffSize);=0D
+ ResourceDirectory =3D (EFI_IMAGE_RESOURCE_DIRECTORY *)Base;=0D
+ ResourceDirectoryEntry =3D (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *)(Resour=
ceDirectory + 1);=0D
+=0D
+ for (Index =3D 0; Index < ResourceDirectory->NumberOfNamedEntries; Index=
++) {=0D
+ if (ResourceDirectoryEntry->u1.s.NameIsString) {=0D
+ //=0D
+ // Check the ResourceDirectoryEntry->u1.s.NameOffset before use it.=
=0D
+ //=0D
+ if (ResourceDirectoryEntry->u1.s.NameOffset >=3D DirectoryEntry->Siz=
e) {=0D
+ return RETURN_UNSUPPORTED;=0D
+ }=0D
+ ResourceDirectoryString =3D (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) =
(Base + ResourceDirectoryEntry->u1.s.NameOffset);=0D
+ String =3D &ResourceDirectoryString->String[0];=0D
+=0D
+ if (ResourceDirectoryString->Length =3D=3D 3 &&=0D
+ String[0] =3D=3D L'H' &&=0D
+ String[1] =3D=3D L'I' &&=0D
+ String[2] =3D=3D L'I') {=0D
+ //=0D
+ // Resource Type "HII" found=0D
+ //=0D
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {=0D
+ //=0D
+ // Move to next level - resource Name=0D
+ //=0D
+ if (ResourceDirectoryEntry->u2.s.OffsetToDirectory >=3D Director=
yEntry->Size) {=0D
+ return RETURN_UNSUPPORTED;=0D
+ }=0D
+ ResourceDirectory =3D (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + R=
esourceDirectoryEntry->u2.s.OffsetToDirectory);=0D
+ Offset =3D ResourceDirectoryEntry->u2.s.OffsetToDirectory + size=
of (EFI_IMAGE_RESOURCE_DIRECTORY) +=0D
+ sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * (Resource=
Directory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries);=0D
+ if (Offset > DirectoryEntry->Size) {=0D
+ return RETURN_UNSUPPORTED;=0D
+ }=0D
+ ResourceDirectoryEntry =3D (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *=
) (ResourceDirectory + 1);=0D
+=0D
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {=0D
+ //=0D
+ // Move to next level - resource Language=0D
+ //=0D
+ if (ResourceDirectoryEntry->u2.s.OffsetToDirectory >=3D Direct=
oryEntry->Size) {=0D
+ return RETURN_UNSUPPORTED;=0D
+ }=0D
+ ResourceDirectory =3D (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base +=
ResourceDirectoryEntry->u2.s.OffsetToDirectory);=0D
+ Offset =3D ResourceDirectoryEntry->u2.s.OffsetToDirectory + si=
zeof (EFI_IMAGE_RESOURCE_DIRECTORY) +=0D
+ sizeof (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY) * (Resour=
ceDirectory->NumberOfNamedEntries + ResourceDirectory->NumberOfIdEntries);=
=0D
+ if (Offset > DirectoryEntry->Size) {=0D
+ return RETURN_UNSUPPORTED;=0D
+ }=0D
+ ResourceDirectoryEntry =3D (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY=
*) (ResourceDirectory + 1);=0D
+ }=0D
+ }=0D
+=0D
+ //=0D
+ // Now it ought to be resource Data=0D
+ //=0D
+ if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) {=0D
+ if (ResourceDirectoryEntry->u2.OffsetToData >=3D DirectoryEntry-=
Size) {=0D
+ return RETURN_UNSUPPORTED;=0D
+ }=0D
+ ResourceDataEntry =3D (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (Base + =
ResourceDirectoryEntry->u2.OffsetToData);=0D
+=0D
+ //=0D
+ // Adjust OffsetToData to be a PE/COFF Virtual address in the up=
dated image.=0D
+ //=0D
+ ResourceDataEntry->OffsetToData +=3D (UINTN)DirectoryEntry->Vir=
tualAddress;=0D
+ break;=0D
+ }=0D
+ }=0D
+ }=0D
+ ResourceDirectoryEntry++;=0D
+ }=0D
+=0D
+ return EFI_SUCCESS;=0D
+}=0D
+=0D
+=0D
STATIC=0D
EFI_STATUS=0D
ZeroDebugData (=0D
--=20
2.24.1 (Apple Git-126)

Join devel@edk2.groups.io to automatically receive all group messages.