diff options
author | Pingfan Liu <piliu@redhat.com> | 2022-03-31 11:38:05 +0800 |
---|---|---|
committer | Simon Horman <horms@verge.net.au> | 2022-04-01 15:52:47 +0200 |
commit | 8e3f663a4dfe39b303e25ea2b945a4fab9fef7ae (patch) | |
tree | c5522a8c77e124031b7ee4f86f45a8e5168888fd /kexec | |
parent | 36805fe6ba339a02fa177467f753604d8cbf7b15 (diff) |
arm64/kexec-arm64: add support for R_AARCH64_LDST128_ABS_LO12_NC rela
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@redhat.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'kexec')
-rw-r--r-- | kexec/arch/arm64/kexec-arm64.c | 16 |
1 files changed, 16 insertions, 0 deletions
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 @@ -1250,6 +1250,10 @@ void machine_apply_elf_rel(struct mem_ehdr *ehdr, struct mem_sym *UNUSED(sym), # 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; uint32_t *loc32; uint64_t *location = (uint64_t *)ptr; @@ -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; |