[PATCH] arm64/kexec-arm64: add support for R_AARCH64_LDST128_ABS_LO12_NC rela
Pingfan Liu
piliu at redhat.com
Wed Mar 30 18:22:33 PDT 2022
Sorry for forgetting to add the address of the mailing list.
On Thu, Mar 31, 2022 at 9:18 AM Pingfan Liu <piliu at redhat.com> wrote:
>
> GCC 12 has some changes, which affects the generated AArch64 code of kexec-tools.
> Accordingly, a new rel type R_AARCH64_LDST128_ABS_LO12_NC is confronted
> by machine_apply_elf_rel() on AArch64. This fails the load of kernel
> with the message "machine_apply_elf_rel: ERROR Unknown type: 299"
>
> Citing from objdump -rDSl purgatory/purgatory.ro
>
> 0000000000000f80 <sha256_starts>:
> sha256_starts():
> f80: 90000001 adrp x1, 0 <verify_sha256_digest>
> f80: R_AARCH64_ADR_PREL_PG_HI21 .text+0xfa0
> f84: a9007c1f stp xzr, xzr, [x0]
> f88: 3dc00021 ldr q1, [x1]
> f88: R_AARCH64_LDST128_ABS_LO12_NC .text+0xfa0
> f8c: 90000001 adrp x1, 0 <verify_sha256_digest>
> f8c: R_AARCH64_ADR_PREL_PG_HI21 .text+0xfb0
> f90: 3dc00020 ldr q0, [x1]
> f90: R_AARCH64_LDST128_ABS_LO12_NC .text+0xfb0
> f94: ad008001 stp q1, q0, [x0, #16]
> f98: d65f03c0 ret
> f9c: d503201f nop
> fa0: 6a09e667 .inst 0x6a09e667 ; undefined
> fa4: bb67ae85 .inst 0xbb67ae85 ; undefined
> fa8: 3c6ef372 .inst 0x3c6ef372 ; undefined
> fac: a54ff53a ld3w {z26.s-z28.s}, p5/z, [x9, #-3, mul vl]
> fb0: 510e527f sub wsp, w19, #0x394
> fb4: 9b05688c madd x12, x4, x5, x26
> fb8: 1f83d9ab .inst 0x1f83d9ab ; undefined
> fbc: 5be0cd19 .inst 0x5be0cd19 ; undefined
>
> Here, gcc generates codes, which make loads and stores carried out using
> the 128-bits floating-point registers. And a new rel type
> R_AARCH64_LDST128_ABS_LO12_NC should be handled.
>
> Make machine_apply_elf_rel() coped with this new reloc, so kexec-tools
> can work smoothly.
>
> Signed-off-by: Pingfan Liu <piliu at redhat.com>
> Cc: Geoff Levand <geoff at infradead.org>
> Cc: Catalin Marinas <catalin.marinas at arm.com>
> Cc: Simon Horman <horms at verge.net.au>
> ---
> kexec/arch/arm64/kexec-arm64.c | 16 ++++++++++++++++
> 1 file changed, 16 insertions(+)
>
> diff --git a/kexec/arch/arm64/kexec-arm64.c b/kexec/arch/arm64/kexec-arm64.c
> index 9dd072c..e25f600 100644
> --- a/kexec/arch/arm64/kexec-arm64.c
> +++ b/kexec/arch/arm64/kexec-arm64.c
> @@ -1248,6 +1248,10 @@ void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *UNUSED(sym),
>
> #if !defined(R_AARCH64_LDST64_ABS_LO12_NC)
> # define R_AARCH64_LDST64_ABS_LO12_NC 286
> +#endif
> +
> +#if !defined(R_AARCH64_LDST128_ABS_LO12_NC)
> +# define R_AARCH64_LDST128_ABS_LO12_NC 299
> #endif
>
> uint64_t *loc64;
> @@ -1309,6 +1313,7 @@ void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *UNUSED(sym),
> *loc32 = cpu_to_le32(le32_to_cpu(*loc32)
> + (((value - address) >> 2) & 0x3ffffff));
> break;
> + /* encode imm field with bits [11:3] of value */
> case R_AARCH64_LDST64_ABS_LO12_NC:
> if (value & 7)
> die("%s: ERROR Unaligned value: %lx\n", __func__,
> @@ -1318,6 +1323,17 @@ void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *UNUSED(sym),
> *loc32 = cpu_to_le32(le32_to_cpu(*loc32)
> + ((value & 0xff8) << (10 - 3)));
> break;
> +
> + /* encode imm field with bits [11:4] of value */
> + case R_AARCH64_LDST128_ABS_LO12_NC:
> + if (value & 15)
> + die("%s: ERROR Unaligned value: %lx\n", __func__,
> + value);
> + type = "LDST128_ABS_LO12_NC";
> + loc32 = ptr;
> + imm = value & 0xff0;
> + *loc32 = cpu_to_le32(le32_to_cpu(*loc32) + (imm << (10 - 4)));
> + break;
> default:
> die("%s: ERROR Unknown type: %lu\n", __func__, r_type);
> break;
> --
> 2.31.1
>
More information about the kexec
mailing list