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
) {
47 Value
= (UINT32
)(RV_X(*RiscVHi20Fixup
, 12, 20) << 12);
48 Value2
= (UINT32
)(RV_X(*(UINT32
*)Fixup
, 20, 12));
49 if (Value2
& (RISCV_IMM_REACH
/2)) {
50 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));
62 case EFI_IMAGE_REL_BASED_RISCV_LOW12S
:
63 RiscVHi20Fixup
= (UINT32
*)(*(UINT64
*)(*FixupData
));
64 if (RiscVHi20Fixup
!= NULL
) {
65 Value
= (UINT32
)(RV_X(*RiscVHi20Fixup
, 12, 20) << 12);
66 Value2
= (UINT32
)(RV_X(*(UINT32
*)Fixup
, 7, 5) | (RV_X(*(UINT32
*)Fixup
, 25, 7) << 5));
67 if (Value2
& (RISCV_IMM_REACH
/2)) {
68 Value2
|= ~(RISCV_IMM_REACH
-1);
71 Value
+= (UINT32
)Adjust
;
72 Value2
= RISCV_CONST_HIGH_PART (Value
);
73 *(UINT32
*)RiscVHi20Fixup
= (RV_X (Value2
, 12, 20) << 12) | \
74 (RV_X (*(UINT32
*)RiscVHi20Fixup
, 0, 12));
75 Value2
= *(UINT32
*)Fixup
& 0x01fff07f;
76 Value
&= RISCV_IMM_REACH
- 1;
77 *(UINT32
*)Fixup
= Value2
| (UINT32
)(((RV_X(Value
, 0, 5) << 7) | (RV_X(Value
, 5, 7) << 25)));
82 return RETURN_UNSUPPORTED
;
85 return RETURN_SUCCESS
;
89 Returns TRUE if the machine type of PE/COFF image is supported. Supported
90 does not mean the image can be executed it means the PE/COFF loader supports
91 loading and relocating of the image type. It's up to the caller to support
94 @param Machine Machine type from the PE Header.
96 @return TRUE if this PE/COFF loader can load the image
100 PeCoffLoaderImageFormatSupported (
104 if (Machine
== IMAGE_FILE_MACHINE_RISCV64
) {
112 Performs an Itanium-based specific re-relocation fixup and is a no-op on other
113 instruction sets. This is used to re-relocated the image into the EFI virtual
114 space for runtime calls.
116 @param Reloc The pointer to the relocation record.
117 @param Fixup The pointer to the address to fix up.
118 @param FixupData The pointer to a buffer to log the fixups.
119 @param Adjust The offset to adjust the fixup.
125 PeHotRelocateImageEx (
128 IN OUT CHAR8
**FixupData
,
132 return RETURN_UNSUPPORTED
;