return EFI_SUCCESS;\r
}\r
\r
-EFI_STATUS\r
-RebaseFfsFile (\r
- IN OUT EFI_FFS_FILE_HEADER *FfsFile,\r
- IN EFI_PHYSICAL_ADDRESS BaseAddress\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
- This function determines if a file is XIP and should be rebased. It will\r
- rebase any PE32 sections found in the file using the base address.\r
-\r
-Arguments:\r
-\r
- FfsFile A pointer to Ffs file image.\r
- BaseAddress The base address to use for rebasing the file image.\r
-\r
-Returns:\r
-\r
- EFI_SUCCESS The image was properly rebased.\r
- EFI_INVALID_PARAMETER An input parameter is invalid.\r
- EFI_ABORTED An error occurred while rebasing the input file image.\r
- EFI_OUT_OF_RESOURCES Could not allocate a required resource.\r
-\r
---*/\r
-{\r
- EFI_STATUS Status;\r
- PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;\r
- UINTN MemoryImagePointer;\r
- UINTN MemoryImagePointerAligned;\r
-\r
- EFI_PHYSICAL_ADDRESS ImageAddress;\r
- UINT64 ImageSize;\r
- EFI_PHYSICAL_ADDRESS EntryPoint;\r
-\r
- UINT32 Pe32FileSize;\r
- UINT32 NewPe32BaseAddress;\r
-\r
- UINTN Index;\r
- EFI_FILE_SECTION_POINTER CurrentPe32Section;\r
- UINT8 FileGuidString[80];\r
-\r
- //\r
- // Verify input parameters\r
- //\r
- if (FfsFile == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- //\r
- // Convert the GUID to a string so we can at least report which file\r
- // if we find an error.\r
- //\r
- PrintGuidToBuffer (&FfsFile->Name, FileGuidString, sizeof (FileGuidString), TRUE);\r
-\r
- //\r
- // Do some nominal checks on the file, then check for XIP.\r
- //\r
- Status = VerifyFfsFile (FfsFile);\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 0, "invalid FFS file", FileGuidString);\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (FfsFile->Type != EFI_FV_FILETYPE_SECURITY_CORE &&\r
- FfsFile->Type != EFI_FV_FILETYPE_PEI_CORE &&\r
- FfsFile->Type != EFI_FV_FILETYPE_PEIM\r
- ) {\r
- //\r
- // File is not XIP, so don't rebase\r
- //\r
- return EFI_SUCCESS;\r
- }\r
- //\r
- // Rebase each PE32 section\r
- //\r
- for (Index = 1;; Index++) {\r
- Status = GetSectionByType (FfsFile, EFI_SECTION_PE32, Index, &CurrentPe32Section);\r
- if (EFI_ERROR (Status)) {\r
- break;\r
- }\r
- //\r
- // Calculate the PE32 base address, the FFS file base plus the offset of the PE32 section\r
- //\r
- NewPe32BaseAddress = ((UINT32) BaseAddress) + ((UINTN) CurrentPe32Section.Pe32Section - (UINTN) FfsFile);\r
-\r
- //\r
- // Initialize context\r
- //\r
- memset (&ImageContext, 0, sizeof (ImageContext));\r
- ImageContext.Handle = (VOID *) ((UINTN) CurrentPe32Section.Pe32Section + sizeof (EFI_PE32_SECTION));\r
- ImageContext.ImageRead = (PE_COFF_LOADER_READ_FILE) FfsRebaseImageRead;\r
-\r
- Status = PeCoffLoaderGetImageInfo (&ImageContext);\r
-\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 0, "GetImageInfo() failed", FileGuidString);\r
- return Status;\r
- }\r
- //\r
- // Allocate a buffer for the image to be loaded into.\r
- //\r
- Pe32FileSize = GetLength (CurrentPe32Section.Pe32Section->CommonHeader.Size);\r
- MemoryImagePointer = (UINTN) (malloc (Pe32FileSize + 0x1000));\r
- MemoryImagePointerAligned = (MemoryImagePointer + 0x0FFF) & (-1 << 12);\r
- if (MemoryImagePointerAligned == 0) {\r
- Error (NULL, 0, 0, "memory allocation failure", NULL);\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- //\r
- // bugbug\r
- //\r
- ImageContext.ImageAddress = MemoryImagePointerAligned;\r
- Status = PeCoffLoaderLoadImage (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 0, "LoadImage() failure", FileGuidString);\r
- free ((VOID *) MemoryImagePointer);\r
- return Status;\r
- }\r
-\r
- Status = PeCoffLoaderRelocateImage (&ImageContext);\r
- if (EFI_ERROR (Status)) {\r
- Error (NULL, 0, 0, "RelocateImage() failure", FileGuidString);\r
- free ((VOID *) MemoryImagePointer);\r
- return Status;\r
- }\r
-\r
- ImageAddress = ImageContext.ImageAddress;\r
- ImageSize = ImageContext.ImageSize;\r
- EntryPoint = ImageContext.EntryPoint;\r
-\r
- if (ImageSize > Pe32FileSize) {\r
- Error (\r
- NULL,\r
- 0,\r
- 0,\r
- "rebased PE32 is larger than original PE32 image",\r
- "0x%X > 0x%X on file %s",\r
- ImageSize,\r
- Pe32FileSize,\r
- FileGuidString\r
- );\r
- free ((VOID *) MemoryImagePointer);\r
- return EFI_ABORTED;\r
- }\r
-\r
- memcpy (CurrentPe32Section.Pe32Section, (VOID *) MemoryImagePointerAligned, Pe32FileSize);\r
-\r
- free ((VOID *) MemoryImagePointer);\r
- }\r
- //\r
- // the above for loop will always exit with EFI_NOT_FOUND if it completes\r
- // normally. If Index == 1 at exit, then no PE32 sections were found. If it\r
- // exits with any other error code, then something broke...\r
- //\r
- if (Status != EFI_NOT_FOUND) {\r
- Error (NULL, 0, 0, "failed to parse PE32 section", FileGuidString);\r
- return Status;\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
\r
EFI_STATUS\r
AddSymFile (\r