[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v12 06/10] LoongArch: Add awareness for LoongArch relocations
From: |
Xiaotian Wu |
Subject: |
[PATCH v12 06/10] LoongArch: Add awareness for LoongArch relocations |
Date: |
Mon, 5 Dec 2022 18:46:34 +0800 |
Signed-off-by: Xiaotian Wu <wuxiaotian@loongson.cn>
Signed-off-by: Zhou Yang <zhouyang@loongson.cn>
---
grub-core/kern/dl.c | 9 +-
grub-core/kern/loongarch64/dl.c | 102 +++++++++++++
grub-core/kern/loongarch64/dl_helper.c | 202 +++++++++++++++++++++++++
include/grub/dl.h | 1 +
include/grub/loongarch64/reloc.h | 107 +++++++++++++
util/grub-mkimagexx.c | 79 ++++++++++
util/grub-module-verifier.c | 26 ++++
7 files changed, 523 insertions(+), 3 deletions(-)
create mode 100644 grub-core/kern/loongarch64/dl.c
create mode 100644 grub-core/kern/loongarch64/dl_helper.c
create mode 100644 include/grub/loongarch64/reloc.h
diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
index e447fd0fa..0bf40caa6 100644
--- a/grub-core/kern/dl.c
+++ b/grub-core/kern/dl.c
@@ -225,7 +225,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
unsigned i;
const Elf_Shdr *s;
grub_size_t tsize = 0, talign = 1;
-#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
+ !defined (__loongarch__)
grub_size_t tramp;
grub_size_t got;
grub_err_t err;
@@ -241,7 +242,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
talign = s->sh_addralign;
}
-#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
+ !defined (__loongarch__)
err = grub_arch_dl_get_tramp_got_size (e, &tramp, &got);
if (err)
return err;
@@ -304,7 +306,8 @@ grub_dl_load_segments (grub_dl_t mod, const Elf_Ehdr *e)
mod->segment = seg;
}
}
-#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv)
+#if !defined (__i386__) && !defined (__x86_64__) && !defined(__riscv) && \
+ !defined (__loongarch__)
ptr = (char *) ALIGN_UP ((grub_addr_t) ptr, GRUB_ARCH_DL_TRAMP_ALIGN);
mod->tramp = ptr;
mod->trampptr = ptr;
diff --git a/grub-core/kern/loongarch64/dl.c b/grub-core/kern/loongarch64/dl.c
new file mode 100644
index 000000000..3a6aa91cd
--- /dev/null
+++ b/grub-core/kern/loongarch64/dl.c
@@ -0,0 +1,102 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/types.h>
+#include <grub/mm.h>
+#include <grub/i18n.h>
+#include <grub/cpu/reloc.h>
+
+/* Check if EHDR is a valid ELF header. */
+grub_err_t
+grub_arch_dl_check_header (void *ehdr)
+{
+ Elf_Ehdr *e = ehdr;
+
+ /* Check the magic numbers. */
+ if (e->e_ident[EI_CLASS] != ELFCLASS64
+ || e->e_ident[EI_DATA] != ELFDATA2LSB || e->e_machine != EM_LOONGARCH)
+ return grub_error (GRUB_ERR_BAD_OS, N_("invalid arch-dependent ELF
magic"));
+
+ return GRUB_ERR_NONE;
+}
+
+#pragma GCC diagnostic ignored "-Wcast-align"
+
+/*
+ * Unified function for both REL and RELA.
+ */
+grub_err_t
+grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
+ Elf_Shdr *s, grub_dl_segment_t seg)
+{
+ Elf_Rel *rel, *max;
+ struct grub_loongarch64_stack stack;
+ grub_loongarch64_stack_init (&stack);
+
+ for (rel = (Elf_Rel *) ((char *) ehdr + s->sh_offset),
+ max = (Elf_Rel *) ((char *) rel + s->sh_size);
+ rel < max;
+ rel = (Elf_Rel *) ((char *) rel + s->sh_entsize))
+ {
+ Elf_Sym *sym;
+ grub_uint64_t *place;
+ grub_uint64_t sym_addr;
+
+ if (rel->r_offset >= seg->size)
+ return grub_error (GRUB_ERR_BAD_MODULE,
+ "reloc offset is outside the segment");
+
+ sym = (Elf_Sym *) ((char*)mod->symtab
+ + mod->symsize * ELF_R_SYM (rel->r_info));
+
+ sym_addr = sym->st_value;
+ if (s->sh_type == SHT_RELA)
+ sym_addr += ((Elf_Rela *) rel)->r_addend;
+
+ place = (grub_uint64_t *) ((grub_addr_t)seg->addr + rel->r_offset);
+
+ switch (ELF_R_TYPE (rel->r_info))
+ {
+ case R_LARCH_64:
+ *place = sym_addr;
+ break;
+ case R_LARCH_MARK_LA:
+ break;
+ case R_LARCH_SOP_PUSH_PCREL:
+ case R_LARCH_SOP_PUSH_PLT_PCREL:
+ grub_loongarch64_sop_push (&stack, sym_addr - (grub_uint64_t)place);
+ break;
+ GRUB_LOONGARCH64_RELOCATION (&stack, place, sym_addr)
+ default:
+ {
+ char rel_info[17]; /* log16(2^64) = 16, plus NUL. */
+
+ grub_snprintf (rel_info, sizeof (rel_info) - 1, "%"
PRIxGRUB_UINT64_T,
+ (grub_uint64_t) ELF_R_TYPE (rel->r_info));
+ return grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
+ N_("relocation 0x%s is not implemented yet"),
rel_info);
+ }
+ break;
+ }
+ }
+ return GRUB_ERR_NONE;
+}
diff --git a/grub-core/kern/loongarch64/dl_helper.c
b/grub-core/kern/loongarch64/dl_helper.c
new file mode 100644
index 000000000..627d1fff2
--- /dev/null
+++ b/grub-core/kern/loongarch64/dl_helper.c
@@ -0,0 +1,202 @@
+/* dl_helper.c - relocation helper functions for modules and grub-mkimage */
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/dl.h>
+#include <grub/elf.h>
+#include <grub/misc.h>
+#include <grub/err.h>
+#include <grub/mm.h>
+#include <grub/i18n.h>
+#include <grub/loongarch64/reloc.h>
+
+static void grub_loongarch64_stack_push (grub_loongarch64_stack_t stack,
grub_uint64_t x);
+static grub_uint64_t grub_loongarch64_stack_pop (grub_loongarch64_stack_t
stack);
+
+void
+grub_loongarch64_stack_init (grub_loongarch64_stack_t stack)
+{
+ stack->top = -1;
+ stack->count = LOONGARCH64_STACK_MAX;
+}
+
+static void
+grub_loongarch64_stack_push (grub_loongarch64_stack_t stack, grub_uint64_t x)
+{
+ if (stack->top == stack->count)
+ return;
+ stack->data[++stack->top] = x;
+}
+
+static grub_uint64_t
+grub_loongarch64_stack_pop (grub_loongarch64_stack_t stack)
+{
+ if (stack->top == -1)
+ return -1;
+ return stack->data[stack->top--];
+}
+
+void
+grub_loongarch64_sop_push (grub_loongarch64_stack_t stack, grub_int64_t offset)
+{
+ grub_loongarch64_stack_push (stack, offset);
+}
+
+/* opr2 = pop (), opr1 = pop (), push (opr1 - opr2) */
+void
+grub_loongarch64_sop_sub (grub_loongarch64_stack_t stack)
+{
+ grub_uint64_t a, b;
+ b = grub_loongarch64_stack_pop (stack);
+ a = grub_loongarch64_stack_pop (stack);
+ grub_loongarch64_stack_push (stack, a - b);
+}
+
+/* opr2 = pop (), opr1 = pop (), push (opr1 << opr2) */
+void
+grub_loongarch64_sop_sl (grub_loongarch64_stack_t stack)
+{
+ grub_uint64_t a, b;
+ b = grub_loongarch64_stack_pop (stack);
+ a = grub_loongarch64_stack_pop (stack);
+ grub_loongarch64_stack_push (stack, a << b);
+}
+
+/* opr2 = pop (), opr1 = pop (), push (opr1 >> opr2) */
+void
+grub_loongarch64_sop_sr (grub_loongarch64_stack_t stack)
+{
+ grub_uint64_t a, b;
+ b = grub_loongarch64_stack_pop (stack);
+ a = grub_loongarch64_stack_pop (stack);
+ grub_loongarch64_stack_push (stack, a >> b);
+}
+
+/* opr2 = pop (), opr1 = pop (), push (opr1 + opr2) */
+void
+grub_loongarch64_sop_add (grub_loongarch64_stack_t stack)
+{
+ grub_uint64_t a, b;
+ b = grub_loongarch64_stack_pop (stack);
+ a = grub_loongarch64_stack_pop (stack);
+ grub_loongarch64_stack_push (stack, a + b);
+}
+
+/* opr2 = pop (), opr1 = pop (), push (opr1 & opr2) */
+void
+grub_loongarch64_sop_and (grub_loongarch64_stack_t stack)
+{
+ grub_uint64_t a, b;
+ b = grub_loongarch64_stack_pop (stack);
+ a = grub_loongarch64_stack_pop (stack);
+ grub_loongarch64_stack_push (stack, a & b);
+}
+
+/* opr3 = pop (), opr2 = pop (), opr1 = pop (), push (opr1 ? opr2 : opr3) */
+void
+grub_loongarch64_sop_if_else (grub_loongarch64_stack_t stack)
+{
+ grub_uint64_t a, b, c;
+ c = grub_loongarch64_stack_pop (stack);
+ b = grub_loongarch64_stack_pop (stack);
+ a = grub_loongarch64_stack_pop (stack);
+
+ if (a) {
+ grub_loongarch64_stack_push (stack, b);
+ } else {
+ grub_loongarch64_stack_push (stack, c);
+ }
+}
+
+/* opr1 = pop (), (*(uint32_t *) PC) [14 ... 10] = opr1 [4 ... 0] */
+void
+grub_loongarch64_sop_32_s_10_5 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place)
+{
+ grub_uint64_t a = grub_loongarch64_stack_pop (stack);
+ *place |= ((a & 0x1f) << 10);
+}
+
+/* opr1 = pop (), (*(uint32_t *) PC) [21 ... 10] = opr1 [11 ... 0] */
+void
+grub_loongarch64_sop_32_u_10_12 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place)
+{
+ grub_uint64_t a = grub_loongarch64_stack_pop (stack);
+ *place = *place | ((a & 0xfff) << 10);
+}
+
+/* opr1 = pop (), (*(uint32_t *) PC) [21 ... 10] = opr1 [11 ... 0] */
+void
+grub_loongarch64_sop_32_s_10_12 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place)
+{
+ grub_uint64_t a = grub_loongarch64_stack_pop (stack);
+ *place = (*place) | ((a & 0xfff) << 10);
+}
+
+/* opr1 = pop (), (*(uint32_t *) PC) [25 ... 10] = opr1 [15 ... 0] */
+void
+grub_loongarch64_sop_32_s_10_16 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place)
+{
+ grub_uint64_t a = grub_loongarch64_stack_pop (stack);
+ *place = (*place) | ((a & 0xffff) << 10);
+}
+
+/* opr1 = pop (), (*(uint32_t *) PC) [25 ... 10] = opr1 [17 ... 2] */
+void
+grub_loongarch64_sop_32_s_10_16_s2 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place)
+{
+ grub_uint64_t a = grub_loongarch64_stack_pop (stack);
+ *place = (*place) | (((a >> 2) & 0xffff) << 10);
+}
+
+/* opr1 = pop (), (*(uint32_t *) PC) [24 ... 5] = opr1 [19 ... 0] */
+void
+grub_loongarch64_sop_32_s_5_20 (grub_loongarch64_stack_t stack, grub_uint64_t
*place)
+{
+ grub_uint64_t a = grub_loongarch64_stack_pop (stack);
+ *place = (*place) | ((a & 0xfffff)<<5);
+}
+
+/* opr1 = pop (), (*(uint32_t *) PC) [4 ... 0] = opr1 [22 ... 18] */
+void
+grub_loongarch64_sop_32_s_0_5_10_16_s2 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place)
+{
+ grub_uint64_t a = grub_loongarch64_stack_pop (stack);
+
+ *place =(*place) | (((a >> 2) & 0xffff) << 10);
+ *place =(*place) | ((a >> 18) & 0x1f);
+}
+
+/*
+ opr1 = pop ()
+ (*(uint32_t *) PC) [9 ... 0] = opr1 [27 ... 18],
+ (*(uint32_t *) PC) [25 ... 10] = opr1 [17 ... 2]
+*/
+void
+grub_loongarch64_sop_32_s_0_10_10_16_s2 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place)
+{
+ grub_uint64_t a = grub_loongarch64_stack_pop (stack);
+ *place =(*place) | (((a >> 2) & 0xffff) << 10);
+ *place =(*place) | ((a >> 18) & 0x3ff);
+}
diff --git a/include/grub/dl.h b/include/grub/dl.h
index acb4d4232..cf79b1ce1 100644
--- a/include/grub/dl.h
+++ b/include/grub/dl.h
@@ -300,6 +300,7 @@ grub_arch_dl_get_tramp_got_size (const void *ehdr,
grub_size_t *tramp,
#endif
#if defined (__aarch64__) || defined (__sparc__) || \
+ defined (__loongarch64) || \
(defined(__riscv) && (__riscv_xlen == 64))
#define GRUB_ARCH_DL_TRAMP_ALIGN 8
#define GRUB_ARCH_DL_GOT_ALIGN 8
diff --git a/include/grub/loongarch64/reloc.h b/include/grub/loongarch64/reloc.h
new file mode 100644
index 000000000..0b7d66ddc
--- /dev/null
+++ b/include/grub/loongarch64/reloc.h
@@ -0,0 +1,107 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2022 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_LOONGARCH64_RELOC_H
+#define GRUB_LOONGARCH64_RELOC_H 1
+#include <grub/types.h>
+
+#define LOONGARCH64_STACK_MAX 16
+
+struct grub_loongarch64_stack
+{
+ grub_uint64_t data[LOONGARCH64_STACK_MAX];
+ int count;
+ int top;
+};
+
+typedef struct grub_loongarch64_stack* grub_loongarch64_stack_t;
+
+void grub_loongarch64_stack_init (grub_loongarch64_stack_t stack);
+void grub_loongarch64_sop_push (grub_loongarch64_stack_t stack,
+ grub_int64_t offset);
+void grub_loongarch64_sop_sub (grub_loongarch64_stack_t stack);
+void grub_loongarch64_sop_sl (grub_loongarch64_stack_t stack);
+void grub_loongarch64_sop_sr (grub_loongarch64_stack_t stack);
+void grub_loongarch64_sop_add (grub_loongarch64_stack_t stack);
+void grub_loongarch64_sop_and (grub_loongarch64_stack_t stack);
+void grub_loongarch64_sop_if_else (grub_loongarch64_stack_t stack);
+void grub_loongarch64_sop_32_s_10_5 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place);
+void grub_loongarch64_sop_32_u_10_12 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place);
+void grub_loongarch64_sop_32_s_10_12 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place);
+void grub_loongarch64_sop_32_s_10_16 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place);
+void grub_loongarch64_sop_32_s_10_16_s2 (grub_loongarch64_stack_t
stack,
+ grub_uint64_t *place);
+void grub_loongarch64_sop_32_s_5_20 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place);
+void grub_loongarch64_sop_32_s_0_5_10_16_s2 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place);
+void grub_loongarch64_sop_32_s_0_10_10_16_s2 (grub_loongarch64_stack_t stack,
+ grub_uint64_t *place);
+
+#define GRUB_LOONGARCH64_RELOCATION(STACK, PLACE, OFFSET) \
+ case R_LARCH_SOP_PUSH_ABSOLUTE: \
+ grub_loongarch64_sop_push (STACK, OFFSET); \
+ break; \
+ case R_LARCH_SOP_SUB: \
+ grub_loongarch64_sop_sub (STACK); \
+ break; \
+ case R_LARCH_SOP_SL: \
+ grub_loongarch64_sop_sl (STACK); \
+ break; \
+ case R_LARCH_SOP_SR: \
+ grub_loongarch64_sop_sr (STACK); \
+ break; \
+ case R_LARCH_SOP_ADD: \
+ grub_loongarch64_sop_add (STACK); \
+ break; \
+ case R_LARCH_SOP_AND: \
+ grub_loongarch64_sop_and (STACK); \
+ break; \
+ case R_LARCH_SOP_IF_ELSE: \
+ grub_loongarch64_sop_if_else (STACK); \
+ break; \
+ case R_LARCH_SOP_POP_32_S_10_5: \
+ grub_loongarch64_sop_32_s_10_5 (STACK, PLACE); \
+ break; \
+ case R_LARCH_SOP_POP_32_U_10_12: \
+ grub_loongarch64_sop_32_u_10_12 (STACK, PLACE); \
+ break; \
+ case R_LARCH_SOP_POP_32_S_10_12: \
+ grub_loongarch64_sop_32_s_10_12 (STACK, PLACE); \
+ break; \
+ case R_LARCH_SOP_POP_32_S_10_16: \
+ grub_loongarch64_sop_32_s_10_16 (STACK, PLACE); \
+ break; \
+ case R_LARCH_SOP_POP_32_S_10_16_S2: \
+ grub_loongarch64_sop_32_s_10_16_s2 (STACK, PLACE); \
+ break; \
+ case R_LARCH_SOP_POP_32_S_5_20: \
+ grub_loongarch64_sop_32_s_5_20 (STACK, PLACE); \
+ break; \
+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2: \
+ grub_loongarch64_sop_32_s_0_5_10_16_s2 (STACK, PLACE); \
+ break; \
+ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2: \
+ grub_loongarch64_sop_32_s_0_10_10_16_s2 (STACK, PLACE); \
+ break;
+
+#endif /* GRUB_LOONGARCH64_RELOC_H */
diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
index a1927e786..358b9ab47 100644
--- a/util/grub-mkimagexx.c
+++ b/util/grub-mkimagexx.c
@@ -44,6 +44,7 @@
#include <grub/arm/reloc.h>
#include <grub/arm64/reloc.h>
#include <grub/ia64/reloc.h>
+#include <grub/loongarch64/reloc.h>
#include <grub/osdep/hostfile.h>
#include <grub/util/install.h>
#include <grub/util/mkimage.h>
@@ -784,6 +785,8 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct
section_metadata *smd,
struct grub_ia64_trampoline *tr = (void *) (pe_target + tramp_off);
grub_uint64_t *gpptr = (void *) (pe_target + got_off);
unsigned unmatched_adr_got_page = 0;
+ struct grub_loongarch64_stack stack;
+ grub_loongarch64_stack_init (&stack);
#define MASK19 ((1 << 19) - 1)
#else
grub_uint32_t *tr = (void *) (pe_target + tramp_off);
@@ -1123,6 +1126,31 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct
section_metadata *smd,
}
break;
}
+ case EM_LOONGARCH:
+ {
+ sym_addr += addend;
+ switch (ELF_R_TYPE (info))
+ {
+ case R_LARCH_64:
+ *target = grub_host_to_target64 (grub_target_to_host64
(*target) + sym_addr);
+ break;
+ case R_LARCH_MARK_LA:
+ break;
+ case R_LARCH_SOP_PUSH_PCREL:
+ case R_LARCH_SOP_PUSH_PLT_PCREL:
+ grub_loongarch64_sop_push (&stack, sym_addr
+ -(target_section_addr
+ +offset
+ +image_target->vaddr_offset));
+ break;
+ GRUB_LOONGARCH64_RELOCATION (&stack, target, sym_addr)
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented
yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
+ break;
+ }
#endif
#if defined(MKIMAGE_ELF32)
case EM_ARM:
@@ -1667,6 +1695,57 @@ translate_relocation_pe (struct translate_context *ctx,
(unsigned int) ELF_R_TYPE (info));
break;
}
+#endif /* defined(MKIMAGE_ELF64) */
+ break;
+ case EM_LOONGARCH:
+#if defined(MKIMAGE_ELF64)
+ switch (ELF_R_TYPE (info))
+ {
+ case R_LARCH_64:
+ {
+ ctx->current_address = add_fixup_entry (&ctx->lst,
+ GRUB_PE32_REL_BASED_DIR64,
+ addr, 0,
ctx->current_address,
+ image_target);
+ }
+ break;
+ case R_LARCH_MARK_LA:
+ {
+ ctx->current_address = add_fixup_entry (&ctx->lst,
+
GRUB_PE32_REL_BASED_LOONGARCH64_MARK_LA,
+ addr, 0,
ctx->current_address,
+ image_target);
+ }
+ break;
+ /* Relative relocations do not require fixup entries. */
+ case R_LARCH_NONE:
+ case R_LARCH_SOP_PUSH_PCREL:
+ case R_LARCH_SOP_PUSH_ABSOLUTE:
+ case R_LARCH_SOP_PUSH_PLT_PCREL:
+ case R_LARCH_SOP_SUB:
+ case R_LARCH_SOP_SL:
+ case R_LARCH_SOP_SR:
+ case R_LARCH_SOP_ADD:
+ case R_LARCH_SOP_AND:
+ case R_LARCH_SOP_IF_ELSE:
+ case R_LARCH_SOP_POP_32_S_10_5:
+ case R_LARCH_SOP_POP_32_U_10_12:
+ case R_LARCH_SOP_POP_32_S_10_12:
+ case R_LARCH_SOP_POP_32_S_10_16:
+ case R_LARCH_SOP_POP_32_S_10_16_S2:
+ case R_LARCH_SOP_POP_32_S_5_20:
+ case R_LARCH_SOP_POP_32_S_0_5_10_16_S2:
+ case R_LARCH_SOP_POP_32_S_0_10_10_16_S2:
+ grub_util_info (" %s: not adding fixup: 0x%08x : 0x%08x",
+ __FUNCTION__,
+ (unsigned int) addr,
+ (unsigned int) ctx->current_address);
+ break;
+ default:
+ grub_util_error (_("relocation 0x%x is not implemented yet"),
+ (unsigned int) ELF_R_TYPE (info));
+ break;
+ }
#endif /* defined(MKIMAGE_ELF64) */
break;
#if defined(MKIMAGE_ELF32)
diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c
index 163529ca9..b510461fa 100644
--- a/util/grub-module-verifier.c
+++ b/util/grub-module-verifier.c
@@ -119,6 +119,32 @@ struct grub_module_verifier_arch archs[] = {
R_AARCH64_PREL32,
-1
} },
+ { "loongarch64", 8, 0, EM_LOONGARCH, GRUB_MODULE_VERIFY_SUPPORTS_REL |
GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
+ R_LARCH_NONE,
+ R_LARCH_64,
+ R_LARCH_MARK_LA,
+ R_LARCH_SOP_PUSH_PCREL,
+ R_LARCH_SOP_PUSH_ABSOLUTE,
+ R_LARCH_SOP_PUSH_PLT_PCREL,
+ R_LARCH_SOP_SUB,
+ R_LARCH_SOP_SL,
+ R_LARCH_SOP_SR,
+ R_LARCH_SOP_ADD,
+ R_LARCH_SOP_AND,
+ R_LARCH_SOP_IF_ELSE,
+ R_LARCH_SOP_POP_32_S_10_5,
+ R_LARCH_SOP_POP_32_U_10_12,
+ R_LARCH_SOP_POP_32_S_10_12,
+ R_LARCH_SOP_POP_32_S_10_16,
+ R_LARCH_SOP_POP_32_S_10_16_S2,
+ R_LARCH_SOP_POP_32_S_5_20,
+ R_LARCH_SOP_POP_32_S_0_5_10_16_S2,
+ R_LARCH_SOP_POP_32_S_0_10_10_16_S2,
+ -1
+ }, (int[]){
+ -1
+ }
+ },
{ "riscv32", 4, 0, EM_RISCV, GRUB_MODULE_VERIFY_SUPPORTS_REL |
GRUB_MODULE_VERIFY_SUPPORTS_RELA, (int[]){
R_RISCV_32,
R_RISCV_64,
--
2.38.1
- [PATCH v12 00/10] Add support for LoongArch, Xiaotian Wu, 2022/12/05
- [PATCH v12 01/10] PE: Add LoongArch definitions, Xiaotian Wu, 2022/12/05
- [PATCH v12 03/10] LoongArch: Add setjmp implementation, Xiaotian Wu, 2022/12/05
- [PATCH v12 05/10] LoongArch: Add efi stubs kernel loader support, Xiaotian Wu, 2022/12/05
- [PATCH v12 06/10] LoongArch: Add awareness for LoongArch relocations,
Xiaotian Wu <=
- [PATCH v12 02/10] Add LoongArch definitions, Xiaotian Wu, 2022/12/05
- [PATCH v12 04/10] LoongArch: Add early startup code, Xiaotian Wu, 2022/12/05