riscv: Add support for HI20 PE relocations
authorAlexander Graf <agraf@suse.de>
Tue, 5 Jun 2018 17:20:32 +0000 (19:20 +0200)
committerAlexander Graf <agraf@suse.de>
Thu, 14 Jun 2018 08:52:14 +0000 (10:52 +0200)
The PE standard allows for HI20/LOW12 relocations. Within the efi_loader
target we always know that our relocation target is 4k aligned, so we
don't need to worry about the LOW12 part.

This patch adds support for the respective relocations. With this and a
few grub patches I have cooking in parallel I'm able to run grub on RISC-V.

Signed-off-by: Alexander Graf <agraf@suse.de>
include/pe.h
lib/efi_loader/efi_image_loader.c

index d73eb142cb3a85a8de3584876e586cb9bd768b39..36e1908b7eafeb32c2032efcf49a0d3f4f48ad5c 100644 (file)
@@ -201,10 +201,13 @@ typedef struct _IMAGE_RELOCATION
 #define IMAGE_REL_BASED_MIPS_JMPADDR            5
 #define IMAGE_REL_BASED_ARM_MOV32A              5 /* yes, 5 too */
 #define IMAGE_REL_BASED_ARM_MOV32               5 /* yes, 5 too */
+#define IMAGE_REL_BASED_RISCV_HI20             5 /* yes, 5 too */
 #define IMAGE_REL_BASED_SECTION                 6
 #define IMAGE_REL_BASED_REL                     7
 #define IMAGE_REL_BASED_ARM_MOV32T              7 /* yes, 7 too */
 #define IMAGE_REL_BASED_THUMB_MOV32             7 /* yes, 7 too */
+#define IMAGE_REL_BASED_RISCV_LOW12I           7 /* yes, 7 too */
+#define IMAGE_REL_BASED_RISCV_LOW12S           8
 #define IMAGE_REL_BASED_MIPS_JMPADDR16          9
 #define IMAGE_REL_BASED_IA64_IMM64              9 /* yes, 9 too */
 #define IMAGE_REL_BASED_DIR64                   10
index 3cffe9ef46182dc0fe02bfbbb5e3303facea1563..ecdb77e5b6bfcdfb0a0e7bb5a472ef1c33be99d2 100644 (file)
@@ -126,6 +126,20 @@ static efi_status_t efi_loader_relocate(const IMAGE_BASE_RELOCATION *rel,
                        case IMAGE_REL_BASED_DIR64:
                                *x64 += (uint64_t)delta;
                                break;
+#ifdef __riscv
+                       case IMAGE_REL_BASED_RISCV_HI20:
+                               *x32 = ((*x32 & 0xfffff000) + (uint32_t)delta) |
+                                       (*x32 & 0x00000fff);
+                               break;
+                       case IMAGE_REL_BASED_RISCV_LOW12I:
+                       case IMAGE_REL_BASED_RISCV_LOW12S:
+                               /* We know that we're 4k aligned */
+                               if (delta & 0xfff) {
+                                       printf("Unsupported reloc offset\n");
+                                       return EFI_LOAD_ERROR;
+                               }
+                               break;
+#endif
                        default:
                                printf("Unknown Relocation off %x type %x\n",
                                       offset, type);