+/**\r
+ Returns the size of the PE/COFF headers\r
+\r
+ Returns the size of the PE/COFF header specified by Pe32Data.\r
+ If Pe32Data is NULL, then ASSERT().\r
+\r
+ @param Pe32Data The pointer to the PE/COFF image that is loaded in system\r
+ memory.\r
+\r
+ @return Size of PE/COFF header in bytes or zero if not a valid image.\r
+\r
+**/\r
+UINT32\r
+EFIAPI\r
+PeCoffGetSizeOfHeaders (\r
+ IN VOID *Pe32Data\r
+ )\r
+{\r
+ EFI_IMAGE_DOS_HEADER *DosHdr;\r
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;\r
+ UINTN SizeOfHeaders;\r
+\r
+ ASSERT (Pe32Data != NULL);\r
+ \r
+ DosHdr = (EFI_IMAGE_DOS_HEADER *)Pe32Data;\r
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {\r
+ //\r
+ // DOS image header is present, so read the PE header after the DOS image header.\r
+ //\r
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN) Pe32Data + (UINTN) ((DosHdr->e_lfanew) & 0x0ffff));\r
+ } else {\r
+ //\r
+ // DOS image header is not present, so PE header is at the image base.\r
+ //\r
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)Pe32Data;\r
+ }\r
+\r
+ if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {\r
+ SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;\r
+ } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {\r
+ SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;\r
+ } else {\r
+ SizeOfHeaders = 0;\r
+ }\r
+\r
+ return (UINT32) SizeOfHeaders;\r
+}\r
+\r
+/**\r
+ Returns PE/COFF image base is loaded in system memory where the input address is in.\r
+\r
+ On DEBUG build, searches the PE/COFF image base forward the input address and\r
+ returns it.\r
+\r
+ @param Address Address located in one PE/COFF image.\r
+\r
+ @retval 0 RELEASE build or cannot find the PE/COFF image base.\r
+ @retval others PE/COFF image base found.\r
+\r
+**/\r
+UINTN\r
+EFIAPI\r
+PeCoffSearchImageBase (\r
+ IN UINTN Address\r
+ )\r
+{\r
+ UINTN Pe32Data;\r