2 PE/Coff loader for RISC-V PE image
4 Portions Copyright (c) 2020, Hewlett Packard Enterprise Development LP. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
7 #include "BasePeCoffLibInternals.h"
8 #include <Library/BaseLib.h>
11 Performs an RISC-V specific relocation fixup and is a no-op on
12 other instruction sets.
13 RISC-V splits 32-bit fixup into 20bit and 12-bit with two relocation
14 types. We have to know the lower 12-bit fixup first then we can deal
15 carry over on high 20-bit fixup. So we log the high 20-bit in
18 @param Reloc The pointer to the relocation record.
19 @param Fixup The pointer to the address to fix up.
20 @param FixupData The pointer to a buffer to log the fixups.
21 @param Adjust The offset to adjust the fixup.
27 PeCoffLoaderRelocateImageEx (
30 IN OUT CHAR8
**FixupData
,
36 UINT32
*RiscVHi20Fixup
;
38 switch ((*Reloc
) >> 12) {
39 case EFI_IMAGE_REL_BASED_RISCV_HI20
:
40 *(UINT64
*)(*FixupData
) = (UINT64
)(UINTN
)Fixup
;
43 case EFI_IMAGE_REL_BASED_RISCV_LOW12I
:
44 RiscVHi20Fixup
= (UINT32
*)(*(UINT64
*)(*FixupData
));
45 if (RiscVHi20Fixup
!= NULL
) {
46 Value
= (UINT32
)(RV_X (*RiscVHi20Fixup
, 12, 20) << 12);
47 Value2
= (UINT32
)(RV_X (*(UINT32
*)Fixup
, 20, 12));
48 if (Value2
& (RISCV_IMM_REACH
/2)) {
49 Value2
|= ~(RISCV_IMM_REACH
-1);
53 Value
+= (UINT32
)Adjust
;
54 Value2
= RISCV_CONST_HIGH_PART (Value
);
55 *(UINT32
*)RiscVHi20Fixup
= (RV_X (Value2
, 12, 20) << 12) | \
56 (RV_X (*(UINT32
*)RiscVHi20Fixup
, 0, 12));
57 *(UINT32
*)Fixup
= (RV_X (Value
, 0, 12) << 20) | \
58 (RV_X (*(UINT32
*)Fixup
, 0, 20));
63 case EFI_IMAGE_REL_BASED_RISCV_LOW12S
:
64 RiscVHi20Fixup
= (UINT32
*)(*(UINT64
*)(*FixupData
));
65 if (RiscVHi20Fixup
!= NULL
) {
66 Value
= (UINT32
)(RV_X (*RiscVHi20Fixup
, 12, 20) << 12);
67 Value2
= (UINT32
)(RV_X (*(UINT32
*)Fixup
, 7, 5) | (RV_X (*(UINT32
*)Fixup
, 25, 7) << 5));
68 if (Value2
& (RISCV_IMM_REACH
/2)) {
69 Value2
|= ~(RISCV_IMM_REACH
-1);
73 Value
+= (UINT32
)Adjust
;
74 Value2
= RISCV_CONST_HIGH_PART (Value
);
75 *(UINT32
*)RiscVHi20Fixup
= (RV_X (Value2
, 12, 20) << 12) | \
76 (RV_X (*(UINT32
*)RiscVHi20Fixup
, 0, 12));
77 Value2
= *(UINT32
*)Fixup
& 0x01fff07f;
78 Value
&= RISCV_IMM_REACH
- 1;
79 *(UINT32
*)Fixup
= Value2
| (UINT32
)(((RV_X (Value
, 0, 5) << 7) | (RV_X (Value
, 5, 7) << 25)));
85 return RETURN_UNSUPPORTED
;
88 return RETURN_SUCCESS
;
92 Returns TRUE if the machine type of PE/COFF image is supported. Supported
93 does not mean the image can be executed it means the PE/COFF loader supports
94 loading and relocating of the image type. It's up to the caller to support
97 @param Machine Machine type from the PE Header.
99 @return TRUE if this PE/COFF loader can load the image
103 PeCoffLoaderImageFormatSupported (
107 if (Machine
== IMAGE_FILE_MACHINE_RISCV64
) {
115 Performs an Itanium-based specific re-relocation fixup and is a no-op on other
116 instruction sets. This is used to re-relocated the image into the EFI virtual
117 space for runtime calls.
119 @param Reloc The pointer to the relocation record.
120 @param Fixup The pointer to the address to fix up.
121 @param FixupData The pointer to a buffer to log the fixups.
122 @param Adjust The offset to adjust the fixup.
128 PeHotRelocateImageEx (
131 IN OUT CHAR8
**FixupData
,
135 return RETURN_UNSUPPORTED
;