strace/strace-5.14-loongarch64.patch
Hui Li 148826cb1e Add support for loongarch64
Signed-off-by: Hui Li <lihui@loongson.cn>
(cherry picked from commit 4db4362c6bfeb4ef0bb62e43c2b7701458d0ce4e)
2023-01-12 15:12:21 +08:00

601 lines
18 KiB
Diff

From da451baee5e701949fd570904998d456c8bdc744 Mon Sep 17 00:00:00 2001
From: Hui Li <lihui@loongson.cn>
Date: Tue, 10 Jan 2023 06:13:10 +0800
Subject: [PATCH 1/2] Add support for 64-bit LoongArch architecture
Signed-off-by: Hui Li <lihui@loongson.cn>
---
NEWS | 1 +
configure | 7 +++
configure.ac | 5 ++
src/Makefile.am | 15 +++++
src/linux/loongarch64/arch_defs_.h | 8 +++
src/linux/loongarch64/arch_fpregset.c | 36 +++++++++++
src/linux/loongarch64/arch_fpregset.h | 15 +++++
src/linux/loongarch64/arch_prstatus_regset.c | 49 +++++++++++++++
src/linux/loongarch64/arch_prstatus_regset.h | 15 +++++
src/linux/loongarch64/arch_regs.c | 11 ++++
src/linux/loongarch64/get_error.c | 19 ++++++
src/linux/loongarch64/get_scno.c | 14 +++++
src/linux/loongarch64/get_syscall_args.c | 19 ++++++
src/linux/loongarch64/ioctls_arch0.h | 1 +
src/linux/loongarch64/ioctls_inc0.h | 1 +
src/linux/loongarch64/raw_syscall.h | 29 +++++++++
src/linux/loongarch64/set_error.c | 20 ++++++
src/linux/loongarch64/set_scno.c | 15 +++++
src/linux/loongarch64/syscallent.h | 8 +++
src/xlat/audit_arch.in | 2 +
src/xlat/elf_em.in | 1 +
tests/ptrace.c | 65 +++++++++++++++++++-
22 files changed, 355 insertions(+), 1 deletion(-)
create mode 100644 src/linux/loongarch64/arch_defs_.h
create mode 100644 src/linux/loongarch64/arch_fpregset.c
create mode 100644 src/linux/loongarch64/arch_fpregset.h
create mode 100644 src/linux/loongarch64/arch_prstatus_regset.c
create mode 100644 src/linux/loongarch64/arch_prstatus_regset.h
create mode 100644 src/linux/loongarch64/arch_regs.c
create mode 100644 src/linux/loongarch64/get_error.c
create mode 100644 src/linux/loongarch64/get_scno.c
create mode 100644 src/linux/loongarch64/get_syscall_args.c
create mode 100644 src/linux/loongarch64/ioctls_arch0.h
create mode 100644 src/linux/loongarch64/ioctls_inc0.h
create mode 100644 src/linux/loongarch64/raw_syscall.h
create mode 100644 src/linux/loongarch64/set_error.c
create mode 100644 src/linux/loongarch64/set_scno.c
create mode 100644 src/linux/loongarch64/syscallent.h
diff --git a/NEWS b/NEWS
index f88de1d..d6727a4 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,7 @@ Noteworthy changes in release 5.14 (2021-09-02)
* Updated lists of BPF_*, IORING_*, MADV_*, MOUNT_ATTR_*, SCTP_*,
and UFFD_* constants.
* Updated lists of ioctl commands from Linux 5.14.
+ * Added 64-bit LoongArch architecture support.
* Bug fixes
* Fixed build using bionic libc.
diff --git a/configure b/configure
index f19e397..88cd0b9 100755
--- a/configure
+++ b/configure
@@ -6049,6 +6049,13 @@ ia64)
$as_echo "#define IA64 1" >>confdefs.h
+ ;;
+loongarch64)
+ arch=loongarch64
+ karch=loongarch
+
+$as_echo "#define LOONGARCH64 1" >>confdefs.h
+
;;
m68k)
arch=m68k
diff --git a/configure.ac b/configure.ac
index 2771c0f..def3bb2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -110,6 +110,11 @@ ia64)
arch=ia64
AC_DEFINE([IA64], 1, [Define for the IA64 architecture.])
;;
+loongarch64)
+ arch=loongarch64
+ karch=loongarch
+ AC_DEFINE([LOONGARCH64], 1, [Define for the 64-bit LoongArch architecture.])
+ ;;
m68k)
arch=m68k
AC_DEFINE([M68K], 1, [Define for the m68k architecture.])
diff --git a/src/Makefile.am b/src/Makefile.am
index b7e74a7..dc38851 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -634,6 +634,21 @@ EXTRA_DIST = \
linux/ia64/syscallent.h \
linux/ia64/syscallent_base_nr.h \
linux/ia64/userent.h \
+ linux/loongarch64/arch_defs_.h \
+ linux/loongarch64/arch_fpregset.c \
+ linux/loongarch64/arch_fpregset.h \
+ linux/loongarch64/arch_prstatus_regset.c \
+ linux/loongarch64/arch_prstatus_regset.h \
+ linux/loongarch64/arch_regs.c \
+ linux/loongarch64/get_error.c \
+ linux/loongarch64/get_scno.c \
+ linux/loongarch64/get_syscall_args.c \
+ linux/loongarch64/ioctls_arch0.h \
+ linux/loongarch64/ioctls_inc0.h \
+ linux/loongarch64/raw_syscall.h \
+ linux/loongarch64/set_error.c \
+ linux/loongarch64/set_scno.c \
+ linux/loongarch64/syscallent.h \
linux/m68k/arch_defs_.h \
linux/m68k/arch_regs.c \
linux/m68k/arch_rt_sigframe.c \
diff --git a/src/linux/loongarch64/arch_defs_.h b/src/linux/loongarch64/arch_defs_.h
new file mode 100644
index 0000000..ffb5733
--- /dev/null
+++ b/src/linux/loongarch64/arch_defs_.h
@@ -0,0 +1,8 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#define PERSONALITY0_AUDIT_ARCH { AUDIT_ARCH_LOONGARCH64, 0 }
diff --git a/src/linux/loongarch64/arch_fpregset.c b/src/linux/loongarch64/arch_fpregset.c
new file mode 100644
index 0000000..b17a407
--- /dev/null
+++ b/src/linux/loongarch64/arch_fpregset.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+static void
+arch_decode_fpregset(struct tcb *const tcp,
+ const kernel_ulong_t addr,
+ const kernel_ulong_t size)
+{
+ struct_fpregset regs;
+ const size_t fetch_size = MIN(sizeof(regs), size);
+
+ if (!size || size & 7) {
+ printaddr(addr);
+ } else if (!umoven_or_printaddr(tcp, addr, fetch_size, &regs)) {
+ tprint_struct_begin();
+ PRINT_FIELD_ARRAY_UPTO(regs, fpr, fetch_size / 8, tcp,
+ print_xint64_array_member);
+ if (fetch_size > offsetof(struct_fpregset, fcc)) {
+ tprint_struct_next();
+ PRINT_FIELD_X(regs, fcc);
+ }
+ if (fetch_size > offsetof(struct_fpregset, fcsr)) {
+ tprint_struct_next();
+ PRINT_FIELD_X(regs, fcsr);
+ }
+ if (size > sizeof(regs)) {
+ tprint_struct_next();
+ tprint_more_data_follows();
+ }
+ tprint_struct_end();
+ }
+}
diff --git a/src/linux/loongarch64/arch_fpregset.h b/src/linux/loongarch64/arch_fpregset.h
new file mode 100644
index 0000000..998b40f
--- /dev/null
+++ b/src/linux/loongarch64/arch_fpregset.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef STRACE_ARCH_FPREGSET_H
+# define STRACE_ARCH_FPREGSET_H
+
+typedef struct user_fp_state struct_fpregset;
+
+# define HAVE_ARCH_FPREGSET 1
+
+#endif /* !STRACE_ARCH_FPREGSET_H */
diff --git a/src/linux/loongarch64/arch_prstatus_regset.c b/src/linux/loongarch64/arch_prstatus_regset.c
new file mode 100644
index 0000000..f5a0c57
--- /dev/null
+++ b/src/linux/loongarch64/arch_prstatus_regset.c
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+static void
+arch_decode_prstatus_regset(struct tcb *const tcp,
+ const kernel_ulong_t addr,
+ const kernel_ulong_t size)
+{
+ struct_prstatus_regset regs;
+ const size_t fetch_size = MIN(sizeof(regs), size);
+
+ if (!size || size & 7) {
+ printaddr(addr);
+ } else if (!umoven_or_printaddr(tcp, addr, fetch_size, &regs)) {
+ tprint_struct_begin();
+ PRINT_FIELD_ARRAY_UPTO(regs, regs,
+ fetch_size / 8, tcp,
+ print_xint64_array_member);
+ if (fetch_size > offsetof(struct_prstatus_regset, orig_a0)) {
+ tprint_struct_next();
+ PRINT_FIELD_X(regs, orig_a0);
+ }
+ if (fetch_size > offsetof(struct_prstatus_regset, csr_era)) {
+ tprint_struct_next();
+ PRINT_FIELD_X(regs, csr_era);
+ }
+ if (fetch_size > offsetof(struct_prstatus_regset, csr_badv)) {
+ tprint_struct_next();
+ PRINT_FIELD_X(regs, csr_badv);
+ }
+ const size_t offset_of_reserved =
+ offsetof(struct_prstatus_regset, reserved);
+ if (fetch_size > offset_of_reserved) {
+ tprint_struct_next();
+ PRINT_FIELD_ARRAY_UPTO(regs, reserved,
+ (fetch_size - offset_of_reserved) / 8,
+ tcp, print_xint64_array_member);
+ }
+ if (size > sizeof(regs)) {
+ tprint_struct_next();
+ tprint_more_data_follows();
+ }
+ tprint_struct_end();
+ }
+}
diff --git a/src/linux/loongarch64/arch_prstatus_regset.h b/src/linux/loongarch64/arch_prstatus_regset.h
new file mode 100644
index 0000000..e7eb64b
--- /dev/null
+++ b/src/linux/loongarch64/arch_prstatus_regset.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef STRACE_ARCH_PRSTATUS_REGSET_H
+# define STRACE_ARCH_PRSTATUS_REGSET_H
+
+typedef struct user_pt_regs struct_prstatus_regset;
+
+# define HAVE_ARCH_PRSTATUS_REGSET 1
+
+#endif /* !STRACE_ARCH_PRSTATUS_REGSET_H */
diff --git a/src/linux/loongarch64/arch_regs.c b/src/linux/loongarch64/arch_regs.c
new file mode 100644
index 0000000..509ac8e
--- /dev/null
+++ b/src/linux/loongarch64/arch_regs.c
@@ -0,0 +1,11 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+static struct user_pt_regs loongarch_regs;
+#define ARCH_REGS_FOR_GETREGSET loongarch_regs
+#define ARCH_PC_REG loongarch_regs.csr_era
+#define ARCH_SP_REG loongarch_regs.regs[3]
diff --git a/src/linux/loongarch64/get_error.c b/src/linux/loongarch64/get_error.c
new file mode 100644
index 0000000..b52ae28
--- /dev/null
+++ b/src/linux/loongarch64/get_error.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "negated_errno.h"
+
+static void
+arch_get_error(struct tcb *tcp, const bool check_errno)
+{
+ if (check_errno && is_negated_errno(loongarch_regs.regs[4])) {
+ tcp->u_rval = -1;
+ tcp->u_error = -loongarch_regs.regs[4];
+ } else {
+ tcp->u_rval = loongarch_regs.regs[4];
+ }
+}
diff --git a/src/linux/loongarch64/get_scno.c b/src/linux/loongarch64/get_scno.c
new file mode 100644
index 0000000..cb0f42c
--- /dev/null
+++ b/src/linux/loongarch64/get_scno.c
@@ -0,0 +1,14 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+/* Return codes: 1 - ok, 0 - ignore, other - error. */
+static int
+arch_get_scno(struct tcb *tcp)
+{
+ tcp->scno = loongarch_regs.regs[11];
+ return 1;
+}
diff --git a/src/linux/loongarch64/get_syscall_args.c b/src/linux/loongarch64/get_syscall_args.c
new file mode 100644
index 0000000..e97aa72
--- /dev/null
+++ b/src/linux/loongarch64/get_syscall_args.c
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+/* Return -1 on error or 1 on success (never 0!). */
+static int
+arch_get_syscall_args(struct tcb *tcp)
+{
+ tcp->u_arg[0] = loongarch_regs.orig_a0;
+ tcp->u_arg[1] = loongarch_regs.regs[5];
+ tcp->u_arg[2] = loongarch_regs.regs[6];
+ tcp->u_arg[3] = loongarch_regs.regs[7];
+ tcp->u_arg[4] = loongarch_regs.regs[8];
+ tcp->u_arg[5] = loongarch_regs.regs[9];
+ return 1;
+}
diff --git a/src/linux/loongarch64/ioctls_arch0.h b/src/linux/loongarch64/ioctls_arch0.h
new file mode 100644
index 0000000..59d8aaa
--- /dev/null
+++ b/src/linux/loongarch64/ioctls_arch0.h
@@ -0,0 +1 @@
+/* Generated by ioctls_gen.sh from definitions found in $linux/arch/loongarch/include/ tree. */
diff --git a/src/linux/loongarch64/ioctls_inc0.h b/src/linux/loongarch64/ioctls_inc0.h
new file mode 100644
index 0000000..6028afb
--- /dev/null
+++ b/src/linux/loongarch64/ioctls_inc0.h
@@ -0,0 +1 @@
+#include "../64/ioctls_inc.h"
diff --git a/src/linux/loongarch64/raw_syscall.h b/src/linux/loongarch64/raw_syscall.h
new file mode 100644
index 0000000..1227778
--- /dev/null
+++ b/src/linux/loongarch64/raw_syscall.h
@@ -0,0 +1,29 @@
+/*
+ * Raw syscalls.
+ *
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef STRACE_RAW_SYSCALL_H
+# define STRACE_RAW_SYSCALL_H
+
+# include "kernel_types.h"
+
+static inline kernel_ulong_t
+raw_syscall_0(const kernel_ulong_t nr, kernel_ulong_t *err)
+{
+ *err = 0;
+ register kernel_ulong_t a7 __asm__("a7") = nr;
+ register kernel_ulong_t a0 __asm__("a0");
+ __asm__ __volatile__("syscall 0"
+ : "=r"(a0)
+ : "r"(a7)
+ : "memory");
+ return a0;
+}
+# define raw_syscall_0 raw_syscall_0
+
+#endif /* !STRACE_RAW_SYSCALL_H */
diff --git a/src/linux/loongarch64/set_error.c b/src/linux/loongarch64/set_error.c
new file mode 100644
index 0000000..aa83a3e
--- /dev/null
+++ b/src/linux/loongarch64/set_error.c
@@ -0,0 +1,20 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+static int
+arch_set_error(struct tcb *tcp)
+{
+ loongarch_regs.regs[4] = -tcp->u_error;
+ return set_regs(tcp->pid);
+}
+
+static int
+arch_set_success(struct tcb *tcp)
+{
+ loongarch_regs.regs[4] = tcp->u_rval;
+ return set_regs(tcp->pid);
+}
diff --git a/src/linux/loongarch64/set_scno.c b/src/linux/loongarch64/set_scno.c
new file mode 100644
index 0000000..d338f20
--- /dev/null
+++ b/src/linux/loongarch64/set_scno.c
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+static int
+arch_set_scno(struct tcb *tcp, kernel_ulong_t scno)
+{
+ if (ptrace_syscall_info_is_valid() && get_regs(tcp) < 0)
+ return -1;
+ loongarch_regs.regs[11] = scno;
+ return set_regs(tcp->pid);
+}
diff --git a/src/linux/loongarch64/syscallent.h b/src/linux/loongarch64/syscallent.h
new file mode 100644
index 0000000..5ab228b
--- /dev/null
+++ b/src/linux/loongarch64/syscallent.h
@@ -0,0 +1,8 @@
+/*
+ * Copyright (c) 2021-2022 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "../64/syscallent.h"
diff --git a/src/xlat/audit_arch.in b/src/xlat/audit_arch.in
index 63d3fe5..0760eb7 100644
--- a/src/xlat/audit_arch.in
+++ b/src/xlat/audit_arch.in
@@ -25,6 +25,8 @@ AUDIT_ARCH_H8300 (EM_H8_300) /* Removed in v3.13-rc1~130^2~2 */
AUDIT_ARCH_HEXAGON (EM_HEXAGON)
AUDIT_ARCH_I386 (EM_386|__AUDIT_ARCH_LE)
AUDIT_ARCH_IA64 (EM_IA_64|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
+AUDIT_ARCH_LOONGARCH32 (EM_LOONGARCH|__AUDIT_ARCH_LE)
+AUDIT_ARCH_LOONGARCH64 (EM_LOONGARCH|__AUDIT_ARCH_64BIT|__AUDIT_ARCH_LE)
AUDIT_ARCH_M32R (EM_M32R)
AUDIT_ARCH_M68K (EM_68K)
AUDIT_ARCH_MICROBLAZE (EM_MICROBLAZE)
diff --git a/src/xlat/elf_em.in b/src/xlat/elf_em.in
index 9ffbcd6..18f4c9a 100644
--- a/src/xlat/elf_em.in
+++ b/src/xlat/elf_em.in
@@ -190,6 +190,7 @@ EM_AMDGPU 224 /* AMD GPU architecture */
EM_RISCV 243 /* RISC-V */
EM_BPF 247 /* Linux BPF - in-kernel virtual machine */
EM_CSKY 252 /* C-SKY */
+EM_LOONGARCH 258 /* LoongArch */
EM_AVR32 0x18ad /* Atmel AVR32, removed in v4.12-rc1~159^2~5 */
EM_FRV 0x5441 /* Fujitsu FR-V */
EM_OR32 0x8472 /* arch/openrisc/include/uapi/asm/elf.h */
diff --git a/tests/ptrace.c b/tests/ptrace.c
index 8c98219..235aed9 100644
--- a/tests/ptrace.c
+++ b/tests/ptrace.c
@@ -185,7 +185,7 @@ test_peeksiginfo(int pid, const unsigned long bad_request)
# define TRACEE_REGS_STRUCT struct pt_regs
#elif defined __arm__
# define TRACEE_REGS_STRUCT struct pt_regs
-#elif defined __arm64__ || defined __aarch64__
+#elif defined __arm64__ || defined __aarch64__ || defined __loongarch__
# define TRACEE_REGS_STRUCT struct user_pt_regs
#elif defined __s390__ || defined __s390x__
# define TRACEE_REGS_STRUCT s390_regs
@@ -826,11 +826,51 @@ print_prstatus_regset(const void *const rs, const size_t size)
PRINT_FIELD_X(*regs, cp0_cause);
}
+# elif defined __loongarch__
+
+ if (size > offsetof(TRACEE_REGS_STRUCT, regs)) {
+ const size_t len = size - offsetof(TRACEE_REGS_STRUCT, regs);
+ fputs("regs=[", stdout);
+ for (unsigned int i = 0; i < ARRAY_SIZE(regs->regs); ++i) {
+ if (len > i * sizeof(regs->regs[i])) {
+ if (i)
+ fputs(", ", stdout);
+ PRINT_VAL_X(regs->regs[i]);
+ }
+ }
+ fputs("]", stdout);
+ }
+ if (size >= offsetofend(TRACEE_REGS_STRUCT, orig_a0)) {
+ fputs(", ", stdout);
+ PRINT_FIELD_X(*regs, orig_a0);
+ }
+ if (size >= offsetofend(TRACEE_REGS_STRUCT, csr_era)) {
+ fputs(", ", stdout);
+ PRINT_FIELD_X(*regs, csr_era);
+ }
+ if (size >= offsetofend(TRACEE_REGS_STRUCT, csr_badv)) {
+ fputs(", ", stdout);
+ PRINT_FIELD_X(*regs, csr_badv);
+ }
+ if (size > offsetof(TRACEE_REGS_STRUCT, reserved)) {
+ const size_t len = size - offsetof(TRACEE_REGS_STRUCT, reserved);
+ fputs(", reserved=[", stdout);
+ for (unsigned int i = 0; i < ARRAY_SIZE(regs->reserved); ++i) {
+ if (len > i * sizeof(regs->reserved[i])) {
+ if (i)
+ fputs(", ", stdout);
+ PRINT_VAL_X(regs->reserved[i]);
+ }
+ }
+ fputs("]", stdout);
+ }
+
# endif /*
__aarch64__ ||
__arm64__ ||
__arm__ ||
__i386__ ||
+ __loongarch__ ||
__mips__ ||
__powerpc64__ ||
__powerpc__ ||
@@ -1066,6 +1106,8 @@ typedef struct {
uint64_t fpscr;
} ppc_fpregs_struct;
# define TRACEE_REGS_STRUCT ppc_fpregs_struct
+#elif defined __loongarch__
+# define TRACEE_REGS_STRUCT struct user_fp_state
#endif
static void
@@ -1209,8 +1251,29 @@ print_fpregset(const void *const rs, const size_t size)
PRINT_FIELD_X(*regs, fpscr);
}
+# elif defined __loongarch__
+
+ fputs("fpr=[", stdout);
+ for (unsigned int i = 0; i < ARRAY_SIZE(regs->fpr); ++i) {
+ if (size > i * sizeof(regs->fpr[i])) {
+ if (i)
+ fputs(", ", stdout);
+ PRINT_VAL_X(regs->fpr[i]);
+ }
+ }
+ fputs("]", stdout);
+ if (size >= offsetofend(TRACEE_REGS_STRUCT, fcc)) {
+ fputs(", ", stdout);
+ PRINT_FIELD_X(*regs, fcc);
+ }
+ if (size >= offsetofend(TRACEE_REGS_STRUCT, fcsr)) {
+ fputs(", ", stdout);
+ PRINT_FIELD_X(*regs, fcsr);
+ }
+
# endif /*
__i386__ ||
+ __loongarch__ ||
__powerpc64__ ||
__powerpc__ ||
__x86_64__
--
2.38.0