/edk2/EdkCompatibilityPkg/Foundation/Library/Pei/PeiLib/Ipf/PeCoffLoaderEx.c

https://gitlab.com/envieidoc/Clover · C · 268 lines · 154 code · 35 blank · 79 comment · 7 complexity · 103c8c267ded2b3121548024be81a9f4 MD5 · raw file

  1. /*++
  2. Copyright (c) 2004 - 2006, Intel Corporation. All rights reserved.<BR>
  3. This program and the accompanying materials
  4. are licensed and made available under the terms and conditions of the BSD License
  5. which accompanies this distribution. The full text of the license may be found at
  6. http://opensource.org/licenses/bsd-license.php
  7. THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  8. WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
  9. Module Name:
  10. PeCoffLoaderEx.c
  11. Abstract:
  12. Fixes Intel Itanium(TM) specific relocation types
  13. Revision History
  14. --*/
  15. #include "TianoCommon.h"
  16. #include "EfiImage.h"
  17. #define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
  18. Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)
  19. #define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
  20. *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \
  21. ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)
  22. #define IMM64_IMM7B_INST_WORD_X 3
  23. #define IMM64_IMM7B_SIZE_X 7
  24. #define IMM64_IMM7B_INST_WORD_POS_X 4
  25. #define IMM64_IMM7B_VAL_POS_X 0
  26. #define IMM64_IMM9D_INST_WORD_X 3
  27. #define IMM64_IMM9D_SIZE_X 9
  28. #define IMM64_IMM9D_INST_WORD_POS_X 18
  29. #define IMM64_IMM9D_VAL_POS_X 7
  30. #define IMM64_IMM5C_INST_WORD_X 3
  31. #define IMM64_IMM5C_SIZE_X 5
  32. #define IMM64_IMM5C_INST_WORD_POS_X 13
  33. #define IMM64_IMM5C_VAL_POS_X 16
  34. #define IMM64_IC_INST_WORD_X 3
  35. #define IMM64_IC_SIZE_X 1
  36. #define IMM64_IC_INST_WORD_POS_X 12
  37. #define IMM64_IC_VAL_POS_X 21
  38. #define IMM64_IMM41a_INST_WORD_X 1
  39. #define IMM64_IMM41a_SIZE_X 10
  40. #define IMM64_IMM41a_INST_WORD_POS_X 14
  41. #define IMM64_IMM41a_VAL_POS_X 22
  42. #define IMM64_IMM41b_INST_WORD_X 1
  43. #define IMM64_IMM41b_SIZE_X 8
  44. #define IMM64_IMM41b_INST_WORD_POS_X 24
  45. #define IMM64_IMM41b_VAL_POS_X 32
  46. #define IMM64_IMM41c_INST_WORD_X 2
  47. #define IMM64_IMM41c_SIZE_X 23
  48. #define IMM64_IMM41c_INST_WORD_POS_X 0
  49. #define IMM64_IMM41c_VAL_POS_X 40
  50. #define IMM64_SIGN_INST_WORD_X 3
  51. #define IMM64_SIGN_SIZE_X 1
  52. #define IMM64_SIGN_INST_WORD_POS_X 27
  53. #define IMM64_SIGN_VAL_POS_X 63
  54. EFI_STATUS
  55. PeCoffLoaderRelocateImageEx (
  56. IN UINT16 *Reloc,
  57. IN OUT CHAR8 *Fixup,
  58. IN OUT CHAR8 **FixupData,
  59. IN UINT64 Adjust
  60. )
  61. /*++
  62. Routine Description:
  63. Performs an Itanium-based specific relocation fixup
  64. Arguments:
  65. Reloc - Pointer to the relocation record
  66. Fixup - Pointer to the address to fix up
  67. FixupData - Pointer to a buffer to log the fixups
  68. Adjust - The offset to adjust the fixup
  69. Returns:
  70. Status code
  71. --*/
  72. {
  73. UINT64 *F64;
  74. UINT64 FixupVal;
  75. switch ((*Reloc) >> 12) {
  76. case EFI_IMAGE_REL_BASED_IA64_IMM64:
  77. //
  78. // Align it to bundle address before fixing up the
  79. // 64-bit immediate value of the movl instruction.
  80. //
  81. Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));
  82. FixupVal = (UINT64)0;
  83. //
  84. // Extract the lower 32 bits of IMM64 from bundle
  85. //
  86. EXT_IMM64(FixupVal,
  87. (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,
  88. IMM64_IMM7B_SIZE_X,
  89. IMM64_IMM7B_INST_WORD_POS_X,
  90. IMM64_IMM7B_VAL_POS_X
  91. );
  92. EXT_IMM64(FixupVal,
  93. (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,
  94. IMM64_IMM9D_SIZE_X,
  95. IMM64_IMM9D_INST_WORD_POS_X,
  96. IMM64_IMM9D_VAL_POS_X
  97. );
  98. EXT_IMM64(FixupVal,
  99. (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,
  100. IMM64_IMM5C_SIZE_X,
  101. IMM64_IMM5C_INST_WORD_POS_X,
  102. IMM64_IMM5C_VAL_POS_X
  103. );
  104. EXT_IMM64(FixupVal,
  105. (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,
  106. IMM64_IC_SIZE_X,
  107. IMM64_IC_INST_WORD_POS_X,
  108. IMM64_IC_VAL_POS_X
  109. );
  110. EXT_IMM64(FixupVal,
  111. (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,
  112. IMM64_IMM41a_SIZE_X,
  113. IMM64_IMM41a_INST_WORD_POS_X,
  114. IMM64_IMM41a_VAL_POS_X
  115. );
  116. //
  117. // Update 64-bit address
  118. //
  119. FixupVal += Adjust;
  120. //
  121. // Insert IMM64 into bundle
  122. //
  123. INS_IMM64(FixupVal,
  124. ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),
  125. IMM64_IMM7B_SIZE_X,
  126. IMM64_IMM7B_INST_WORD_POS_X,
  127. IMM64_IMM7B_VAL_POS_X
  128. );
  129. INS_IMM64(FixupVal,
  130. ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),
  131. IMM64_IMM9D_SIZE_X,
  132. IMM64_IMM9D_INST_WORD_POS_X,
  133. IMM64_IMM9D_VAL_POS_X
  134. );
  135. INS_IMM64(FixupVal,
  136. ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),
  137. IMM64_IMM5C_SIZE_X,
  138. IMM64_IMM5C_INST_WORD_POS_X,
  139. IMM64_IMM5C_VAL_POS_X
  140. );
  141. INS_IMM64(FixupVal,
  142. ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),
  143. IMM64_IC_SIZE_X,
  144. IMM64_IC_INST_WORD_POS_X,
  145. IMM64_IC_VAL_POS_X
  146. );
  147. INS_IMM64(FixupVal,
  148. ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),
  149. IMM64_IMM41a_SIZE_X,
  150. IMM64_IMM41a_INST_WORD_POS_X,
  151. IMM64_IMM41a_VAL_POS_X
  152. );
  153. INS_IMM64(FixupVal,
  154. ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),
  155. IMM64_IMM41b_SIZE_X,
  156. IMM64_IMM41b_INST_WORD_POS_X,
  157. IMM64_IMM41b_VAL_POS_X
  158. );
  159. INS_IMM64(FixupVal,
  160. ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),
  161. IMM64_IMM41c_SIZE_X,
  162. IMM64_IMM41c_INST_WORD_POS_X,
  163. IMM64_IMM41c_VAL_POS_X
  164. );
  165. INS_IMM64(FixupVal,
  166. ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),
  167. IMM64_SIGN_SIZE_X,
  168. IMM64_SIGN_INST_WORD_POS_X,
  169. IMM64_SIGN_VAL_POS_X
  170. );
  171. F64 = (UINT64 *) Fixup;
  172. if (*FixupData != NULL) {
  173. *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
  174. *(UINT64 *)(*FixupData) = *F64;
  175. *FixupData = *FixupData + sizeof(UINT64);
  176. }
  177. break;
  178. default:
  179. return EFI_UNSUPPORTED;
  180. }
  181. return EFI_SUCCESS;
  182. }
  183. BOOLEAN
  184. PeCoffLoaderImageFormatSupported (
  185. IN UINT16 Machine
  186. )
  187. /*++
  188. Routine Description:
  189. Returns TRUE if the machine type of PE/COFF image is supported. Supported
  190. does not mean the image can be executed it means the PE/COFF loader supports
  191. loading and relocating of the image type. It's up to the caller to support
  192. the entry point.
  193. This function implies the basic PE/COFF loader/relocator supports IPF, EBC,
  194. images. Calling the entry point in a correct mannor is up to the
  195. consumer of this library.
  196. Arguments:
  197. Machine - Machine type from the PE Header.
  198. Returns:
  199. TRUE - if this PE/COFF loader can load the image
  200. FALSE - if this PE/COFF loader cannot load the image
  201. --*/
  202. {
  203. if ((Machine == EFI_IMAGE_MACHINE_IA64) || (Machine == EFI_IMAGE_MACHINE_EBC)) {
  204. return TRUE;
  205. }
  206. return FALSE;
  207. }