From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from ma1-aaemail-dr-lapp02.apple.com (ma1-aaemail-dr-lapp02.apple.com [17.171.2.68]) by mx.groups.io with SMTP id smtpd.web11.21356.1590355275807364840 for ; Sun, 24 May 2020 14:21:16 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@apple.com header.s=20180706 header.b=UM0uI0R+; spf=pass (domain: apple.com, ip: 17.171.2.68, mailfrom: afish@apple.com) Received: from pps.filterd (ma1-aaemail-dr-lapp02.apple.com [127.0.0.1]) by ma1-aaemail-dr-lapp02.apple.com (8.16.0.42/8.16.0.42) with SMTP id 04OLAGnM023177; Sun, 24 May 2020 14:21:14 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=apple.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=20180706; bh=ZRX0QQ5aeLvC4CmUL3CXVSkx1kJuOsqCrWa+h5BydsE=; b=UM0uI0R+PE4u8+98gPUuFAiFIhBD7s+hV1g3foc0pdNJ+B+fu5q3mzQxoOMF1eK15Rrm BHjBHEF7rtTy/fS/Vero+7UmiAuvDwd+brcy1m18X7gZfvpYzs1TZEGPDWN870lpDjcr e3Yj5QbqNfYSmGC92WfKcZ6j0RQM64tjFJ5roW/toBi/BDs59ZYVcKGYnqgk6kq1XNvA Jv12xvyCqJFOYnhsKcoPKdiMsLqjTAaapIY/PCjxsIYnGbZc1cGol1cRmmg1aRFYBwpL 6cogTQIOXeK96tQC2T9krreuio/9x+ccBc6L6qcWnR0NW5KC8DTdi6O5czG9IE7xgsV8 tg== Received: from rn-mailsvcp-mta-lapp02.rno.apple.com (rn-mailsvcp-mta-lapp02.rno.apple.com [10.225.203.150]) by ma1-aaemail-dr-lapp02.apple.com with ESMTP id 3170grn9sn-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128 verify=NO); Sun, 24 May 2020 14:21:14 -0700 Received: from rn-mailsvcp-relay-lapp04.rno.apple.com (rn-mailsvcp-relay-lapp04.rno.apple.com [17.179.253.13]) by rn-mailsvcp-mta-lapp02.rno.apple.com (Oracle Communications Messaging Server 8.1.0.5.20200312 64bit (built Mar 12 2020)) with ESMTPS id <0QAU00BJ6TZDWO30@rn-mailsvcp-mta-lapp02.rno.apple.com>; Sun, 24 May 2020 14:21:13 -0700 (PDT) Received: from process_milters-daemon.rn-mailsvcp-relay-lapp04.rno.apple.com by rn-mailsvcp-relay-lapp04.rno.apple.com (Oracle Communications Messaging Server 8.1.0.5.20200312 64bit (built Mar 12 2020)) id <0QAU00E00TRDPY00@rn-mailsvcp-relay-lapp04.rno.apple.com>; Sun, 24 May 2020 14:21:13 -0700 (PDT) X-Va-A: X-Va-T-CD: 678bf7de5df0d9ff994f556fd1b44182 X-Va-E-CD: cf4fecb9c8a9b19ae262ca5c785189cb X-Va-R-CD: 2e8edd17abd14281c501635b68a4ee23 X-Va-CD: 0 X-Va-ID: 7e891096-42ac-4ee6-8d62-48946b9a8b61 X-V-A: X-V-T-CD: 678bf7de5df0d9ff994f556fd1b44182 X-V-E-CD: cf4fecb9c8a9b19ae262ca5c785189cb X-V-R-CD: 2e8edd17abd14281c501635b68a4ee23 X-V-CD: 0 X-V-ID: 59ca96ee-5bea-4a19-906e-afd27c112981 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-24_07:2020-05-22,2020-05-24 signatures=0 Received: from rn-mailsvcp-relay-lapp02.rno.apple.com (unknown [17.235.51.71]) by rn-mailsvcp-relay-lapp04.rno.apple.com (Oracle Communications Messaging Server 8.1.0.5.20200312 64bit (built Mar 12 2020)) with ESMTP id <0QAU00NJ9TYDAE00@rn-mailsvcp-relay-lapp04.rno.apple.com>; Sun, 24 May 2020 14:21:13 -0700 (PDT) From: "Andrew Fish" To: devel@edk2.groups.io Cc: Andrew Fish , Bob Feng , Liming Gao Subject: [PATCH 1/3] BaseTools/GenFv: Add PE/COFF resource sections injection to GenFw Date: Sun, 24 May 2020 14:20:09 -0700 Message-id: <7471ab95f62b357b59ef22bb1c59ccea43f785a3.1590354726.git.afish@apple.com> X-Mailer: git-send-email 2.24.1 (Apple Git-126) In-reply-to: References: MIME-version: 1.0 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-24_07:2020-05-22,2020-05-24 signatures=0 Content-transfer-encoding: quoted-printable 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 Cc: Bob Feng Cc: 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)