UINT64 FixupVal;\r
\r
switch ((*Reloc) >> 12) {\r
-\r
- case EFI_IMAGE_REL_BASED_DIR64:\r
- F64 = (UINT64 *) Fixup;\r
- *F64 = *F64 + (UINT64) Adjust;\r
- if (*FixupData != NULL) {\r
- *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));\r
- *(UINT64 *)(*FixupData) = *F64;\r
- *FixupData = *FixupData + sizeof(UINT64);\r
- }\r
- break;\r
-\r
case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
\r
//\r
\r
return RETURN_SUCCESS;\r
}\r
+\r
+/**\r
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported \r
+ does not mean the image can be executed it means the PE/COFF loader supports\r
+ loading and relocating of the image type. It's up to the caller to support\r
+ the entry point. \r
+\r
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,\r
+ & X64 images. Calling the entry point in a correct mannor is up to the \r
+ consumer of this library. This version also supports the special relocations\r
+ for Itanium. \r
+\r
+ @param Machine Machine type from the PE Header.\r
+\r
+ @return TRUE if this PE/COFF loader can load the image\r
+\r
+**/\r
+BOOLEAN\r
+PeCoffLoaderImageFormatSupported (\r
+ IN UINT16 Machine\r
+ )\r
+{\r
+ if ((Machine == EFI_IMAGE_MACHINE_IPF) || (Machine == EFI_IMAGE_MACHINE_IA32) ||\r
+ (Machine == EFI_IMAGE_MACHINE_EBC) || (Machine == EFI_IMAGE_MACHINE_X64)) {\r
+ return TRUE; \r
+ }\r
+\r
+ return FALSE;\r
+}\r
+\r
+\r
+/**\r
+ ImageRead function that operates on a memory buffer whos base is passed into\r
+ FileHandle. \r
+\r
+ @param Reloc Ponter to baes of the input stream\r
+ @param Fixup Offset to the start of the buffer\r
+ @param FixupData Number of bytes to copy into the buffer\r
+ @param Adjust Location to place results of read\r
+\r
+ @retval RETURN_SUCCESS Data is read from FileOffset from the Handle into \r
+ the buffer.\r
+**/\r
+RETURN_STATUS\r
+PeHotRelocateImageEx (\r
+ IN UINT16 *Reloc,\r
+ IN OUT CHAR8 *Fixup,\r
+ IN OUT CHAR8 **FixupData,\r
+ IN UINT64 Adjust\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Performs an IPF specific relocation fixup\r
+\r
+Arguments:\r
+\r
+ Reloc - Pointer to the relocation record\r
+\r
+ Fixup - Pointer to the address to fix up\r
+\r
+ FixupData - Pointer to a buffer to log the fixups\r
+\r
+ Adjust - The offset to adjust the fixup\r
+\r
+Returns:\r
+\r
+ None\r
+\r
+--*/\r
+{\r
+ UINT64 *F64;\r
+ UINT64 FixupVal;\r
+\r
+ switch ((*Reloc) >> 12) {\r
+ case EFI_IMAGE_REL_BASED_DIR64:\r
+ F64 = (UINT64 *) Fixup;\r
+ *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
+ if (*(UINT64 *) (*FixupData) == *F64) {\r
+ *F64 = *F64 + (UINT64) Adjust;\r
+ }\r
+\r
+ *FixupData = *FixupData + sizeof (UINT64);\r
+ break;\r
+\r
+ case EFI_IMAGE_REL_BASED_IA64_IMM64:\r
+ F64 = (UINT64 *) Fixup;\r
+ *FixupData = ALIGN_POINTER (*FixupData, sizeof (UINT64));\r
+ if (*(UINT64 *) (*FixupData) == *F64) {\r
+ //\r
+ // Align it to bundle address before fixing up the\r
+ // 64-bit immediate value of the movl instruction.\r
+ //\r
+ //\r
+ Fixup = (CHAR8 *) ((UINT64) Fixup & (UINT64)~(15));\r
+ FixupVal = (UINT64) 0;\r
+\r
+ //\r
+ // Extract the lower 32 bits of IMM64 from bundle\r
+ //\r
+ EXT_IMM64 (\r
+ FixupVal,\r
+ (UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X,\r
+ IMM64_IMM7B_SIZE_X,\r
+ IMM64_IMM7B_INST_WORD_POS_X,\r
+ IMM64_IMM7B_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64 (\r
+ FixupVal,\r
+ (UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X,\r
+ IMM64_IMM9D_SIZE_X,\r
+ IMM64_IMM9D_INST_WORD_POS_X,\r
+ IMM64_IMM9D_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64 (\r
+ FixupVal,\r
+ (UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X,\r
+ IMM64_IMM5C_SIZE_X,\r
+ IMM64_IMM5C_INST_WORD_POS_X,\r
+ IMM64_IMM5C_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64 (\r
+ FixupVal,\r
+ (UINT32 *) Fixup + IMM64_IC_INST_WORD_X,\r
+ IMM64_IC_SIZE_X,\r
+ IMM64_IC_INST_WORD_POS_X,\r
+ IMM64_IC_VAL_POS_X\r
+ );\r
+\r
+ EXT_IMM64 (\r
+ FixupVal,\r
+ (UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X,\r
+ IMM64_IMM41a_SIZE_X,\r
+ IMM64_IMM41a_INST_WORD_POS_X,\r
+ IMM64_IMM41a_VAL_POS_X\r
+ );\r
+\r
+ //\r
+ // Update 64-bit address\r
+ //\r
+ FixupVal += Adjust;\r
+\r
+ //\r
+ // Insert IMM64 into bundle\r
+ //\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM7B_INST_WORD_X),\r
+ IMM64_IMM7B_SIZE_X,\r
+ IMM64_IMM7B_INST_WORD_POS_X,\r
+ IMM64_IMM7B_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM9D_INST_WORD_X),\r
+ IMM64_IMM9D_SIZE_X,\r
+ IMM64_IMM9D_INST_WORD_POS_X,\r
+ IMM64_IMM9D_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM5C_INST_WORD_X),\r
+ IMM64_IMM5C_SIZE_X,\r
+ IMM64_IMM5C_INST_WORD_POS_X,\r
+ IMM64_IMM5C_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IC_INST_WORD_X),\r
+ IMM64_IC_SIZE_X,\r
+ IMM64_IC_INST_WORD_POS_X,\r
+ IMM64_IC_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM41a_INST_WORD_X),\r
+ IMM64_IMM41a_SIZE_X,\r
+ IMM64_IMM41a_INST_WORD_POS_X,\r
+ IMM64_IMM41a_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM41b_INST_WORD_X),\r
+ IMM64_IMM41b_SIZE_X,\r
+ IMM64_IMM41b_INST_WORD_POS_X,\r
+ IMM64_IMM41b_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_IMM41c_INST_WORD_X),\r
+ IMM64_IMM41c_SIZE_X,\r
+ IMM64_IMM41c_INST_WORD_POS_X,\r
+ IMM64_IMM41c_VAL_POS_X\r
+ );\r
+\r
+ INS_IMM64 (\r
+ FixupVal,\r
+ ((UINT32 *) Fixup + IMM64_SIGN_INST_WORD_X),\r
+ IMM64_SIGN_SIZE_X,\r
+ IMM64_SIGN_INST_WORD_POS_X,\r
+ IMM64_SIGN_VAL_POS_X\r
+ );\r
+\r
+ *(UINT64 *) (*FixupData) = *F64;\r
+ }\r
+\r
+ *FixupData = *FixupData + sizeof (UINT64);\r
+ break;\r
+\r
+ default:\r
+ DEBUG ((EFI_D_ERROR, "PeHotRelocateEx:unknown fixed type\n"));\r
+ return RETURN_UNSUPPORTED;\r
+ }\r
+\r
+ return RETURN_SUCCESS;\r
+}\r
+\r
+\r
+\r