| 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 |
| |