blob: af9aa07d82d8f24ecf77b6537ce9a6a9f17fa74c [file] [log] [blame]
From d27207ba0973ccac0508c5ab6f6fb22a17a5394c Mon Sep 17 00:00:00 2001
From: Oleksandr Tymoshenko <ovt@google.com>
Date: Wed, 10 Feb 2021 23:05:58 +0000
Subject: [PATCH 7/7] git-lakitu: fix clang relocations
- Switch to using "small" mcmodel. For a "large" model clang generates
movw/movk intructions to load addresses and relocations for
these opcodes are not representable in PE executables. Previously this
problem was worked around using -fPIC switch but latest clang version
generates mov/movk regardless PIC settings.
- Implement missing LDSTxx_ABS_LO12_NC AArch64 relocations generated by
clang in "small" model
---
conf/Makefile.common | 2 +-
grub-core/kern/arm64/dl.c | 9 +++++++++
grub-core/kern/arm64/dl_helper.c | 27 +++++++++++++++++++++++++++
include/grub/arm64/reloc.h | 6 ++++++
include/grub/elf.h | 3 +++
util/grub-mkimagexx.c | 15 +++++++++++++++
util/grub-module-verifier.c | 3 +++
7 files changed, 64 insertions(+), 1 deletion(-)
diff --git a/conf/Makefile.common b/conf/Makefile.common
index b484c5abe..94075432c 100644
--- a/conf/Makefile.common
+++ b/conf/Makefile.common
@@ -15,7 +15,7 @@ if !COND_emu
endif
endif
if COND_arm64
- CFLAGS_PLATFORM += -mcmodel=large
+ CFLAGS_PLATFORM += -mcmodel=small
endif
if COND_powerpc_ieee1275
CFLAGS_PLATFORM += -mcpu=powerpc
diff --git a/grub-core/kern/arm64/dl.c b/grub-core/kern/arm64/dl.c
index fb0337319..e5a79afc7 100644
--- a/grub-core/kern/arm64/dl.c
+++ b/grub-core/kern/arm64/dl.c
@@ -98,6 +98,15 @@ grub_arch_dl_relocate_symbols (grub_dl_t mod, void *ehdr,
case R_AARCH64_LDST64_ABS_LO12_NC:
grub_arm64_set_abs_lo12_ldst64 (place, sym_addr);
break;
+ case R_AARCH64_LDST32_ABS_LO12_NC:
+ grub_arm64_set_abs_lo12_ldst32 (place, sym_addr);
+ break;
+ case R_AARCH64_LDST16_ABS_LO12_NC:
+ grub_arm64_set_abs_lo12_ldst16 (place, sym_addr);
+ break;
+ case R_AARCH64_LDST8_ABS_LO12_NC:
+ grub_arm64_set_abs_lo12_ldst8 (place, sym_addr);
+ break;
case R_AARCH64_CALL26:
case R_AARCH64_JUMP26:
{
diff --git a/grub-core/kern/arm64/dl_helper.c b/grub-core/kern/arm64/dl_helper.c
index e00c198db..d4ec7fc26 100644
--- a/grub-core/kern/arm64/dl_helper.c
+++ b/grub-core/kern/arm64/dl_helper.c
@@ -94,6 +94,33 @@ grub_arm64_set_abs_lo12_ldst64 (grub_uint32_t *place, grub_int64_t target)
*place |= grub_cpu_to_le32 (target << 7) & ~insmask;
}
+void
+grub_arm64_set_abs_lo12_ldst32 (grub_uint32_t *place, grub_int64_t target)
+{
+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xfff003ff);
+
+ *place &= insmask;
+ *place |= grub_cpu_to_le32 (target << 8) & ~insmask;
+}
+
+void
+grub_arm64_set_abs_lo12_ldst16 (grub_uint32_t *place, grub_int64_t target)
+{
+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffe003ff);
+
+ *place &= insmask;
+ *place |= grub_cpu_to_le32 (target << 9) & ~insmask;
+}
+
+void
+grub_arm64_set_abs_lo12_ldst8 (grub_uint32_t *place, grub_int64_t target)
+{
+ const grub_uint32_t insmask = grub_cpu_to_le32_compile_time (0xffc003ff);
+
+ *place &= insmask;
+ *place |= grub_cpu_to_le32 (target << 10) & ~insmask;
+}
+
#pragma GCC diagnostic ignored "-Wcast-align"
grub_err_t
diff --git a/include/grub/arm64/reloc.h b/include/grub/arm64/reloc.h
index c8765de97..2174833d6 100644
--- a/include/grub/arm64/reloc.h
+++ b/include/grub/arm64/reloc.h
@@ -37,5 +37,11 @@ void
grub_arm64_set_abs_lo12 (grub_uint32_t *place, grub_int64_t target);
void
grub_arm64_set_abs_lo12_ldst64 (grub_uint32_t *place, grub_int64_t target);
+void
+grub_arm64_set_abs_lo12_ldst32 (grub_uint32_t *place, grub_int64_t target);
+void
+grub_arm64_set_abs_lo12_ldst16 (grub_uint32_t *place, grub_int64_t target);
+void
+grub_arm64_set_abs_lo12_ldst8 (grub_uint32_t *place, grub_int64_t target);
#endif
diff --git a/include/grub/elf.h b/include/grub/elf.h
index c478933ee..93101dee4 100644
--- a/include/grub/elf.h
+++ b/include/grub/elf.h
@@ -2072,9 +2072,12 @@ typedef Elf32_Addr Elf32_Conflict;
#define R_AARCH64_PREL32 261
#define R_AARCH64_ADR_PREL_PG_HI21 275
#define R_AARCH64_ADD_ABS_LO12_NC 277
+#define R_AARCH64_LDST8_ABS_LO12_NC 278
#define R_AARCH64_LDST64_ABS_LO12_NC 286
#define R_AARCH64_JUMP26 282 /* 26-bit relative. */
#define R_AARCH64_CALL26 283 /* 26-bit relative. */
+#define R_AARCH64_LDST16_ABS_LO12_NC 284
+#define R_AARCH64_LDST32_ABS_LO12_NC 285
#define R_AARCH64_ADR_GOT_PAGE 311
#define R_AARCH64_LD64_GOT_LO12_NC 312
#define R_AARCH64_COPY 1024 /* Copy symbol at runtime. */
diff --git a/util/grub-mkimagexx.c b/util/grub-mkimagexx.c
index 52bc9c848..38a8cc2fa 100644
--- a/util/grub-mkimagexx.c
+++ b/util/grub-mkimagexx.c
@@ -1058,6 +1058,18 @@ SUFFIX (relocate_addrs) (Elf_Ehdr *e, struct section_metadata *smd,
grub_arm64_set_abs_lo12_ldst64 ((grub_uint32_t *) target,
sym_addr);
break;
+ case R_AARCH64_LDST32_ABS_LO12_NC:
+ grub_arm64_set_abs_lo12_ldst32 ((grub_uint32_t *) target,
+ sym_addr);
+ break;
+ case R_AARCH64_LDST16_ABS_LO12_NC:
+ grub_arm64_set_abs_lo12_ldst16 ((grub_uint32_t *) target,
+ sym_addr);
+ break;
+ case R_AARCH64_LDST8_ABS_LO12_NC:
+ grub_arm64_set_abs_lo12_ldst8 ((grub_uint32_t *) target,
+ sym_addr);
+ break;
case R_AARCH64_JUMP26:
case R_AARCH64_CALL26:
{
@@ -1654,6 +1666,9 @@ translate_relocation_pe (struct translate_context *ctx,
*/
case R_AARCH64_ADD_ABS_LO12_NC:
case R_AARCH64_LDST64_ABS_LO12_NC:
+ case R_AARCH64_LDST32_ABS_LO12_NC:
+ case R_AARCH64_LDST16_ABS_LO12_NC:
+ case R_AARCH64_LDST8_ABS_LO12_NC:
break;
/* GOT is relocated separately. */
diff --git a/util/grub-module-verifier.c b/util/grub-module-verifier.c
index 163529ca9..95ef77f81 100644
--- a/util/grub-module-verifier.c
+++ b/util/grub-module-verifier.c
@@ -115,7 +115,10 @@ struct grub_module_verifier_arch archs[] = {
}, (int[]){
R_AARCH64_ADR_PREL_PG_HI21,
R_AARCH64_ADD_ABS_LO12_NC,
+ R_AARCH64_LDST8_ABS_LO12_NC,
+ R_AARCH64_LDST16_ABS_LO12_NC,
R_AARCH64_LDST64_ABS_LO12_NC,
+ R_AARCH64_LDST32_ABS_LO12_NC,
R_AARCH64_PREL32,
-1
} },
--
2.30.0.478.g8a0d178c01-goog