[PATCH 1/3] arm64/kexec-arm64: add support for R_AARCH64_LDST128_ABS_LO12_NC rela

Pingfan Liu piliu at redhat.com
Wed Mar 30 20:38:05 PDT 2022


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>
To: kexec at lists.infradead.org
---
 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