+EFI_STATUS\r
+FfsRebaseImageRead (\r
+ IN VOID *FileHandle,\r
+ IN UINTN FileOffset,\r
+ IN OUT UINT32 *ReadSize,\r
+ OUT VOID *Buffer\r
+ )\r
+ /*++\r
+\r
+ Routine Description:\r
+\r
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file\r
+\r
+ Arguments:\r
+\r
+ FileHandle - The handle to the PE/COFF file\r
+\r
+ FileOffset - The offset, in bytes, into the file to read\r
+\r
+ ReadSize - The number of bytes to read from the file starting at FileOffset\r
+\r
+ Buffer - A pointer to the buffer to read the data into.\r
+\r
+ Returns:\r
+\r
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset\r
+\r
+ --*/\r
+{\r
+ CHAR8 *Destination8;\r
+ CHAR8 *Source8;\r
+ UINT32 Length;\r
+\r
+ Destination8 = Buffer;\r
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);\r
+ Length = *ReadSize;\r
+ while (Length--) {\r
+ *(Destination8++) = *(Source8++);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+STATIC\r
+EFI_STATUS\r
+GetAlignmentFromFile(char *InFile, UINT32 *Alignment)\r
+ /*\r
+ InFile is input file for getting alignment\r
+ return the alignment\r
+ */\r
+{\r
+ FILE *InFileHandle;\r
+ UINT8 *PeFileBuffer;\r
+ UINTN PeFileSize;\r
+ UINT32 CurSecHdrSize;\r
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
+ EFI_COMMON_SECTION_HEADER *CommonHeader;\r
+ EFI_STATUS Status;\r
+\r
+ InFileHandle = NULL;\r
+ PeFileBuffer = NULL;\r
+ *Alignment = 0;\r
+\r
+ memset (&ImageContext, 0, sizeof (ImageContext));\r
+\r
+ InFileHandle = fopen(LongFilePath(InFile), "rb");\r
+ if (InFileHandle == NULL){\r
+ Error (NULL, 0, 0001, "Error opening file", InFile);\r
+ return EFI_ABORTED;\r
+ }\r
+ PeFileSize = _filelength (fileno(InFileHandle));\r
+ PeFileBuffer = (UINT8 *) malloc (PeFileSize);\r
+ if (PeFileBuffer == NULL) {\r
+ fclose (InFileHandle);\r
+ Error(NULL, 0, 4001, "Resource", "memory cannot be allocated of %s", InFileHandle);\r
+ return EFI_OUT_OF_RESOURCES;\r
+ }\r
+ fread (PeFileBuffer, sizeof (UINT8), PeFileSize, InFileHandle);\r
+ fclose (InFileHandle);\r
+ CommonHeader = (EFI_COMMON_SECTION_HEADER *) PeFileBuffer;\r
+ CurSecHdrSize = GetSectionHeaderLength(CommonHeader);\r
+ ImageContext.Handle = (VOID *) ((UINTN)PeFileBuffer + CurSecHdrSize);\r
+ ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE)FfsRebaseImageRead;\r
+ Status = PeCoffLoaderGetImageInfo(&ImageContext);\r
+ if (EFI_ERROR (Status)) {\r
+ Error (NULL, 0, 3000, "Invalid PeImage", "The input file is %s and return status is %x", InFile, (int) Status);\r
+ return Status;\r
+ }\r
+ *Alignment = ImageContext.SectionAlignment;\r
+ // Free the allocated memory resource\r
+ if (PeFileBuffer != NULL) {\r
+ free (PeFileBuffer);\r
+ PeFileBuffer = NULL;\r
+ }\r
+ return EFI_SUCCESS;\r
+}\r
+\r