* [PULL 01/46] semihosting: Retrieve stack top from image_info
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 02/46] semihosting: Initialize heap once per process Richard Henderson
` (45 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Remove the write-once field TaskState.stack_base, and use the
same value from struct image_info.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/qemu.h | 1 -
linux-user/aarch64/cpu_loop.c | 1 -
linux-user/arm/cpu_loop.c | 1 -
linux-user/m68k/cpu_loop.c | 1 -
linux-user/riscv/cpu_loop.c | 1 -
semihosting/arm-compat-semi.c | 6 +++++-
6 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 0b19fa43e6..b6621536b3 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -127,7 +127,6 @@ struct TaskState {
abi_ulong heap_base;
abi_ulong heap_limit;
#endif
- abi_ulong stack_base;
int used; /* non zero if used */
struct image_info *info;
struct linux_binprm *bprm;
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index fea43cefa6..b65999a75b 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -168,7 +168,6 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
qemu_guest_getrandom_nofail(&env->keys, sizeof(env->keys));
}
- ts->stack_base = info->start_stack;
ts->heap_base = info->brk;
/* This will be filled in on the first SYS_HEAPINFO call. */
ts->heap_limit = 0;
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index 33f63951a9..e40d6beafa 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -504,7 +504,6 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
arm_rebuild_hflags(env);
#endif
- ts->stack_base = info->start_stack;
ts->heap_base = info->brk;
/* This will be filled in on the first SYS_HEAPINFO call. */
ts->heap_limit = 0;
diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c
index 5da91b997a..3aaaf02ca4 100644
--- a/linux-user/m68k/cpu_loop.c
+++ b/linux-user/m68k/cpu_loop.c
@@ -117,7 +117,6 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
env->aregs[7] = regs->usp;
env->sr = regs->sr;
- ts->stack_base = info->start_stack;
ts->heap_base = info->brk;
/* This will be filled in on the first SYS_HEAPINFO call. */
ts->heap_limit = 0;
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 3ac8bbfec1..541de765ff 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -109,7 +109,6 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
exit(EXIT_FAILURE);
}
- ts->stack_base = info->start_stack;
ts->heap_base = info->brk;
/* This will be filled in on the first SYS_HEAPINFO call. */
ts->heap_limit = 0;
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index 86e5260e50..bc04b02eba 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -696,7 +696,11 @@ void do_common_semihosting(CPUState *cs)
retvals[0] = ts->heap_base;
retvals[1] = ts->heap_limit;
- retvals[2] = ts->stack_base;
+ /*
+ * Note that semihosting is *not* thread aware.
+ * Always return the stack base of the main thread.
+ */
+ retvals[2] = ts->info->start_stack;
retvals[3] = 0; /* Stack limit. */
#else
retvals[0] = info.heapbase; /* Heap Base */
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 02/46] semihosting: Initialize heap once per process
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
2025-08-27 23:19 ` [PULL 01/46] semihosting: Retrieve stack top from image_info Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 03/46] linux-user: Create target/elfload.c files Richard Henderson
` (44 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
While semihosting isn't really thread aware, the current
implementation allocates space for the heap per-thread.
Remove the heap_base and heap_limit fields from TaskState.
Replace with static variables within do_common_semihosting.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/qemu.h | 5 -----
linux-user/aarch64/cpu_loop.c | 7 -------
linux-user/arm/cpu_loop.c | 25 +++++++++++--------------
linux-user/m68k/cpu_loop.c | 8 --------
linux-user/riscv/cpu_loop.c | 4 ----
semihosting/arm-compat-semi.c | 22 +++++++++-------------
6 files changed, 20 insertions(+), 51 deletions(-)
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index b6621536b3..4d6fad28c6 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -121,11 +121,6 @@ struct TaskState {
abi_ulong child_tidptr;
#ifdef TARGET_M68K
abi_ulong tp_value;
-#endif
-#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_RISCV)
- /* Extra fields for semihosted binaries. */
- abi_ulong heap_base;
- abi_ulong heap_limit;
#endif
int used; /* non zero if used */
struct image_info *info;
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index b65999a75b..030a630c93 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -140,9 +140,6 @@ void cpu_loop(CPUARMState *env)
void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
{
ARMCPU *cpu = env_archcpu(env);
- CPUState *cs = env_cpu(env);
- TaskState *ts = get_task_state(cs);
- struct image_info *info = ts->info;
int i;
if (!(arm_feature(env, ARM_FEATURE_AARCH64))) {
@@ -167,8 +164,4 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
if (cpu_isar_feature(aa64_pauth, cpu)) {
qemu_guest_getrandom_nofail(&env->keys, sizeof(env->keys));
}
-
- ts->heap_base = info->brk;
- /* This will be filled in on the first SYS_HEAPINFO call. */
- ts->heap_limit = 0;
}
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index e40d6beafa..9d54422736 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -492,19 +492,16 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
for(i = 0; i < 16; i++) {
env->regs[i] = regs->uregs[i];
}
-#if TARGET_BIG_ENDIAN
- /* Enable BE8. */
- if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4
- && (info->elf_flags & EF_ARM_BE8)) {
- env->uncached_cpsr |= CPSR_E;
- env->cp15.sctlr_el[1] |= SCTLR_E0E;
- } else {
- env->cp15.sctlr_el[1] |= SCTLR_B;
- }
- arm_rebuild_hflags(env);
-#endif
- ts->heap_base = info->brk;
- /* This will be filled in on the first SYS_HEAPINFO call. */
- ts->heap_limit = 0;
+ if (TARGET_BIG_ENDIAN) {
+ /* Enable BE8. */
+ if (EF_ARM_EABI_VERSION(info->elf_flags) >= EF_ARM_EABI_VER4
+ && (info->elf_flags & EF_ARM_BE8)) {
+ env->uncached_cpsr |= CPSR_E;
+ env->cp15.sctlr_el[1] |= SCTLR_E0E;
+ } else {
+ env->cp15.sctlr_el[1] |= SCTLR_B;
+ }
+ arm_rebuild_hflags(env);
+ }
}
diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c
index 3aaaf02ca4..23693f3358 100644
--- a/linux-user/m68k/cpu_loop.c
+++ b/linux-user/m68k/cpu_loop.c
@@ -94,10 +94,6 @@ void cpu_loop(CPUM68KState *env)
void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
{
- CPUState *cpu = env_cpu(env);
- TaskState *ts = get_task_state(cpu);
- struct image_info *info = ts->info;
-
env->pc = regs->pc;
env->dregs[0] = regs->d0;
env->dregs[1] = regs->d1;
@@ -116,8 +112,4 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
env->aregs[6] = regs->a6;
env->aregs[7] = regs->usp;
env->sr = regs->sr;
-
- ts->heap_base = info->brk;
- /* This will be filled in on the first SYS_HEAPINFO call. */
- ts->heap_limit = 0;
}
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 541de765ff..2dd30c7b28 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -108,8 +108,4 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
error_report("Incompatible ELF: RVE cpu requires RVE ABI binary");
exit(EXIT_FAILURE);
}
-
- ts->heap_base = info->brk;
- /* This will be filled in on the first SYS_HEAPINFO call. */
- ts->heap_limit = 0;
}
diff --git a/semihosting/arm-compat-semi.c b/semihosting/arm-compat-semi.c
index bc04b02eba..bcd13cd6df 100644
--- a/semihosting/arm-compat-semi.c
+++ b/semihosting/arm-compat-semi.c
@@ -666,7 +666,7 @@ void do_common_semihosting(CPUState *cs)
int i;
#ifdef CONFIG_USER_ONLY
TaskState *ts = get_task_state(cs);
- target_ulong limit;
+ static abi_ulong heapbase, heaplimit;
#else
LayoutInfo info = common_semi_find_bases(cs);
#endif
@@ -678,24 +678,20 @@ void do_common_semihosting(CPUState *cs)
* Some C libraries assume the heap immediately follows .bss, so
* allocate it using sbrk.
*/
- if (!ts->heap_limit) {
- abi_ulong ret;
-
- ts->heap_base = do_brk(0);
- limit = ts->heap_base + COMMON_SEMI_HEAP_SIZE;
+ if (!heaplimit) {
+ heapbase = do_brk(0);
/* Try a big heap, and reduce the size if that fails. */
- for (;;) {
- ret = do_brk(limit);
+ for (abi_ulong size = COMMON_SEMI_HEAP_SIZE; ; size >>= 1) {
+ abi_ulong limit = heapbase + size;
+ abi_ulong ret = do_brk(limit);
if (ret >= limit) {
+ heaplimit = limit;
break;
}
- limit = (ts->heap_base >> 1) + (limit >> 1);
}
- ts->heap_limit = limit;
}
-
- retvals[0] = ts->heap_base;
- retvals[1] = ts->heap_limit;
+ retvals[0] = heapbase;
+ retvals[1] = heaplimit;
/*
* Note that semihosting is *not* thread aware.
* Always return the stack base of the main thread.
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 03/46] linux-user: Create target/elfload.c files
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
2025-08-27 23:19 ` [PULL 01/46] semihosting: Retrieve stack top from image_info Richard Henderson
2025-08-27 23:19 ` [PULL 02/46] semihosting: Initialize heap once per process Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 04/46] linux-user: Move ppc uabi/asm/elf.h workaround to osdep.h Richard Henderson
` (43 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Prepare to split the main linux-user/elfload.c.
Create empty files for each target, and add the common build rule.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/elfload.c | 1 +
linux-user/alpha/elfload.c | 1 +
linux-user/arm/elfload.c | 1 +
linux-user/hexagon/elfload.c | 1 +
linux-user/hppa/elfload.c | 1 +
linux-user/i386/elfload.c | 1 +
linux-user/loongarch64/elfload.c | 1 +
linux-user/m68k/elfload.c | 1 +
linux-user/microblaze/elfload.c | 1 +
linux-user/mips/elfload.c | 1 +
linux-user/mips64/elfload.c | 1 +
linux-user/openrisc/elfload.c | 1 +
linux-user/ppc/elfload.c | 1 +
linux-user/riscv/elfload.c | 1 +
linux-user/s390x/elfload.c | 1 +
linux-user/sh4/elfload.c | 1 +
linux-user/sparc/elfload.c | 1 +
linux-user/x86_64/elfload.c | 1 +
linux-user/xtensa/elfload.c | 1 +
meson.build | 6 +++++-
20 files changed, 24 insertions(+), 1 deletion(-)
create mode 100644 linux-user/aarch64/elfload.c
create mode 100644 linux-user/alpha/elfload.c
create mode 100644 linux-user/arm/elfload.c
create mode 100644 linux-user/hexagon/elfload.c
create mode 100644 linux-user/hppa/elfload.c
create mode 100644 linux-user/i386/elfload.c
create mode 100644 linux-user/loongarch64/elfload.c
create mode 100644 linux-user/m68k/elfload.c
create mode 100644 linux-user/microblaze/elfload.c
create mode 100644 linux-user/mips/elfload.c
create mode 100644 linux-user/mips64/elfload.c
create mode 100644 linux-user/openrisc/elfload.c
create mode 100644 linux-user/ppc/elfload.c
create mode 100644 linux-user/riscv/elfload.c
create mode 100644 linux-user/s390x/elfload.c
create mode 100644 linux-user/sh4/elfload.c
create mode 100644 linux-user/sparc/elfload.c
create mode 100644 linux-user/x86_64/elfload.c
create mode 100644 linux-user/xtensa/elfload.c
diff --git a/linux-user/aarch64/elfload.c b/linux-user/aarch64/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/aarch64/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/alpha/elfload.c b/linux-user/alpha/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/alpha/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/arm/elfload.c b/linux-user/arm/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/arm/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/hexagon/elfload.c b/linux-user/hexagon/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/hexagon/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/hppa/elfload.c b/linux-user/hppa/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/hppa/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/i386/elfload.c b/linux-user/i386/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/i386/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/loongarch64/elfload.c b/linux-user/loongarch64/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/loongarch64/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/m68k/elfload.c b/linux-user/m68k/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/m68k/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/microblaze/elfload.c b/linux-user/microblaze/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/microblaze/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/mips/elfload.c b/linux-user/mips/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/mips/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/mips64/elfload.c b/linux-user/mips64/elfload.c
new file mode 100644
index 0000000000..b719555e65
--- /dev/null
+++ b/linux-user/mips64/elfload.c
@@ -0,0 +1 @@
+#include "../mips/elfload.c"
diff --git a/linux-user/openrisc/elfload.c b/linux-user/openrisc/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/openrisc/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/ppc/elfload.c b/linux-user/ppc/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/ppc/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/riscv/elfload.c b/linux-user/riscv/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/riscv/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/s390x/elfload.c b/linux-user/s390x/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/s390x/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/sh4/elfload.c b/linux-user/sh4/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/sh4/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/sparc/elfload.c b/linux-user/sparc/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/sparc/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/x86_64/elfload.c b/linux-user/x86_64/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/x86_64/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/linux-user/xtensa/elfload.c b/linux-user/xtensa/elfload.c
new file mode 100644
index 0000000000..73fa78ef14
--- /dev/null
+++ b/linux-user/xtensa/elfload.c
@@ -0,0 +1 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
diff --git a/meson.build b/meson.build
index 50c774a195..0d42de61ae 100644
--- a/meson.build
+++ b/meson.build
@@ -4327,7 +4327,11 @@ foreach target : target_dirs
)
if 'CONFIG_LINUX_USER' in config_target
dir = base_dir / abi
- arch_srcs += files(dir / 'signal.c', dir / 'cpu_loop.c')
+ arch_srcs += files(
+ dir / 'cpu_loop.c',
+ dir / 'elfload.c',
+ dir / 'signal.c',
+ )
if config_target.has_key('TARGET_SYSTBL_ABI')
arch_srcs += \
syscall_nr_generators[abi].process(base_dir / abi / config_target['TARGET_SYSTBL'],
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 04/46] linux-user: Move ppc uabi/asm/elf.h workaround to osdep.h
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (2 preceding siblings ...)
2025-08-27 23:19 ` [PULL 03/46] linux-user: Create target/elfload.c files Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 05/46] linux-user: Move get_elf_cpu_model to target/elfload.c Richard Henderson
` (42 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Move the workaround out of linux-user/elfload.c, so that
we don't have to replicate it in many places. Place it
immediately after the include of <signal.h>, which draws
in the relevant symbols.
Note that ARCH_DLINFO is not defined by the kernel header,
and so there's no need to undef it either.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/qemu/osdep.h | 8 ++++++++
hw/core/loader.c | 4 ----
linux-user/elfload.c | 10 ----------
3 files changed, 8 insertions(+), 14 deletions(-)
diff --git a/include/qemu/osdep.h b/include/qemu/osdep.h
index 96fe51bc39..be3460b32f 100644
--- a/include/qemu/osdep.h
+++ b/include/qemu/osdep.h
@@ -133,6 +133,14 @@ QEMU_EXTERN_C int daemon(int, int);
#include <setjmp.h>
#include <signal.h>
+/*
+ * Avoid conflict with linux/arch/powerpc/include/uapi/asm/elf.h, included
+ * from <asm/sigcontext.h>, but we might as well do this unconditionally.
+ */
+#undef ELF_CLASS
+#undef ELF_DATA
+#undef ELF_ARCH
+
#ifdef CONFIG_IOVEC
#include <sys/uio.h>
#endif
diff --git a/hw/core/loader.c b/hw/core/loader.c
index e7056ba4bd..524af6f14a 100644
--- a/hw/core/loader.c
+++ b/hw/core/loader.c
@@ -295,10 +295,6 @@ static void *load_at(int fd, off_t offset, size_t size)
return ptr;
}
-#ifdef ELF_CLASS
-#undef ELF_CLASS
-#endif
-
#define ELF_CLASS ELFCLASS32
#include "elf.h"
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ea214105ff..4ca8c39dc2 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -35,16 +35,6 @@
#include "target/arm/cpu-features.h"
#endif
-#ifdef _ARCH_PPC64
-#undef ARCH_DLINFO
-#undef ELF_PLATFORM
-#undef ELF_HWCAP
-#undef ELF_HWCAP2
-#undef ELF_CLASS
-#undef ELF_DATA
-#undef ELF_ARCH
-#endif
-
#ifndef TARGET_ARCH_HAS_SIGTRAMP_PAGE
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 05/46] linux-user: Move get_elf_cpu_model to target/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (3 preceding siblings ...)
2025-08-27 23:19 ` [PULL 04/46] linux-user: Move ppc uabi/asm/elf.h workaround to osdep.h Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 06/46] linux-user: Move get_elf_hwcap to {i386, x86_64}/elfload.c Richard Henderson
` (41 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Rename from cpu_get_model to emphasize that this is an elf-specific
function. Declare the function once in loader.h.
This frees up target_elf.h for other uses.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/target_elf.h | 5 +---
linux-user/alpha/target_elf.h | 5 +---
linux-user/arm/target_elf.h | 5 +---
linux-user/hexagon/target_elf.h | 29 -------------------
linux-user/hppa/target_elf.h | 5 +---
linux-user/i386/target_elf.h | 5 +---
linux-user/loader.h | 3 ++
linux-user/loongarch64/target_elf.h | 5 +---
linux-user/m68k/target_elf.h | 9 ------
linux-user/microblaze/target_elf.h | 5 +---
linux-user/mips/target_elf.h | 11 +-------
linux-user/mips64/target_elf.h | 27 +-----------------
linux-user/openrisc/target_elf.h | 5 +---
linux-user/ppc/target_elf.h | 9 +-----
linux-user/riscv/target_elf.h | 5 +---
linux-user/s390x/target_elf.h | 5 +---
linux-user/sh4/target_elf.h | 5 +---
linux-user/sparc/target_elf.h | 9 +-----
linux-user/x86_64/target_elf.h | 5 +---
linux-user/xtensa/target_elf.h | 5 ----
linux-user/aarch64/elfload.c | 10 +++++++
linux-user/alpha/elfload.c | 10 +++++++
linux-user/arm/elfload.c | 10 +++++++
linux-user/hexagon/elfload.c | 34 +++++++++++++++++++++++
linux-user/hppa/elfload.c | 10 +++++++
linux-user/i386/elfload.c | 10 +++++++
linux-user/loongarch64/elfload.c | 10 +++++++
linux-user/m68k/elfload.c | 17 ++++++++++++
linux-user/main.c | 3 +-
linux-user/microblaze/elfload.c | 10 +++++++
linux-user/mips/elfload.c | 43 +++++++++++++++++++++++++++++
linux-user/openrisc/elfload.c | 10 +++++++
linux-user/ppc/elfload.c | 14 ++++++++++
linux-user/riscv/elfload.c | 10 +++++++
linux-user/s390x/elfload.c | 10 +++++++
linux-user/sh4/elfload.c | 10 +++++++
linux-user/sparc/elfload.c | 14 ++++++++++
linux-user/x86_64/elfload.c | 10 +++++++
linux-user/xtensa/elfload.c | 10 +++++++
39 files changed, 272 insertions(+), 145 deletions(-)
diff --git a/linux-user/aarch64/target_elf.h b/linux-user/aarch64/target_elf.h
index a7eb962fba..d955b3d07f 100644
--- a/linux-user/aarch64/target_elf.h
+++ b/linux-user/aarch64/target_elf.h
@@ -7,8 +7,5 @@
#ifndef AARCH64_TARGET_ELF_H
#define AARCH64_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "any";
-}
+
#endif
diff --git a/linux-user/alpha/target_elf.h b/linux-user/alpha/target_elf.h
index b77d638f6d..52b68680ad 100644
--- a/linux-user/alpha/target_elf.h
+++ b/linux-user/alpha/target_elf.h
@@ -7,8 +7,5 @@
#ifndef ALPHA_TARGET_ELF_H
#define ALPHA_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "ev67";
-}
+
#endif
diff --git a/linux-user/arm/target_elf.h b/linux-user/arm/target_elf.h
index 58ff6a0986..2abb27a733 100644
--- a/linux-user/arm/target_elf.h
+++ b/linux-user/arm/target_elf.h
@@ -7,8 +7,5 @@
#ifndef ARM_TARGET_ELF_H
#define ARM_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "any";
-}
+
#endif
diff --git a/linux-user/hexagon/target_elf.h b/linux-user/hexagon/target_elf.h
index 36056fc9f0..eccf207f6b 100644
--- a/linux-user/hexagon/target_elf.h
+++ b/linux-user/hexagon/target_elf.h
@@ -18,33 +18,4 @@
#ifndef HEXAGON_TARGET_ELF_H
#define HEXAGON_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- static char buf[32];
- int err;
-
- /* For now, treat anything newer than v5 as a v73 */
- /* FIXME - Disable instructions that are newer than the specified arch */
- if (eflags == 0x04 || /* v5 */
- eflags == 0x05 || /* v55 */
- eflags == 0x60 || /* v60 */
- eflags == 0x61 || /* v61 */
- eflags == 0x62 || /* v62 */
- eflags == 0x65 || /* v65 */
- eflags == 0x66 || /* v66 */
- eflags == 0x67 || /* v67 */
- eflags == 0x8067 || /* v67t */
- eflags == 0x68 || /* v68 */
- eflags == 0x69 || /* v69 */
- eflags == 0x71 || /* v71 */
- eflags == 0x8071 || /* v71t */
- eflags == 0x73 /* v73 */
- ) {
- return "v73";
- }
-
- err = snprintf(buf, sizeof(buf), "unknown (0x%x)", eflags);
- return err >= 0 && err < sizeof(buf) ? buf : "unknown";
-}
-
#endif
diff --git a/linux-user/hppa/target_elf.h b/linux-user/hppa/target_elf.h
index 19cae8bd65..5826ca2cd2 100644
--- a/linux-user/hppa/target_elf.h
+++ b/linux-user/hppa/target_elf.h
@@ -7,8 +7,5 @@
#ifndef HPPA_TARGET_ELF_H
#define HPPA_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "hppa";
-}
+
#endif
diff --git a/linux-user/i386/target_elf.h b/linux-user/i386/target_elf.h
index 238a9aba73..e6f0d8fa4e 100644
--- a/linux-user/i386/target_elf.h
+++ b/linux-user/i386/target_elf.h
@@ -7,8 +7,5 @@
#ifndef I386_TARGET_ELF_H
#define I386_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "max";
-}
+
#endif
diff --git a/linux-user/loader.h b/linux-user/loader.h
index e102e6f410..75ee9975a0 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -98,6 +98,9 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src,
extern unsigned long guest_stack_size;
+/* Note that Elf32 and Elf64 use uint32_t for e_flags. */
+const char *get_elf_cpu_model(uint32_t eflags);
+
#if defined(TARGET_S390X) || defined(TARGET_AARCH64) || defined(TARGET_ARM)
uint32_t get_elf_hwcap(void);
const char *elf_hwcap_str(uint32_t bit);
diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h
index 95c3f05a46..39a08d35d9 100644
--- a/linux-user/loongarch64/target_elf.h
+++ b/linux-user/loongarch64/target_elf.h
@@ -5,8 +5,5 @@
#ifndef LOONGARCH_TARGET_ELF_H
#define LOONGARCH_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "la464";
-}
+
#endif
diff --git a/linux-user/m68k/target_elf.h b/linux-user/m68k/target_elf.h
index 998fe0fe2f..62ff9d38d4 100644
--- a/linux-user/m68k/target_elf.h
+++ b/linux-user/m68k/target_elf.h
@@ -7,14 +7,5 @@
#ifndef M68K_TARGET_ELF_H
#define M68K_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- if (eflags == 0 || (eflags & EF_M68K_M68000)) {
- /* 680x0 */
- return "m68040";
- }
- /* Coldfire */
- return "any";
-}
#endif
diff --git a/linux-user/microblaze/target_elf.h b/linux-user/microblaze/target_elf.h
index 8a8f1debff..bfe2997fd2 100644
--- a/linux-user/microblaze/target_elf.h
+++ b/linux-user/microblaze/target_elf.h
@@ -7,8 +7,5 @@
#ifndef MICROBLAZE_TARGET_ELF_H
#define MICROBLAZE_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "any";
-}
+
#endif
diff --git a/linux-user/mips/target_elf.h b/linux-user/mips/target_elf.h
index 71a32315a8..febf710c7a 100644
--- a/linux-user/mips/target_elf.h
+++ b/linux-user/mips/target_elf.h
@@ -7,14 +7,5 @@
#ifndef MIPS_TARGET_ELF_H
#define MIPS_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) {
- return "mips32r6-generic";
- }
- if (eflags & EF_MIPS_NAN2008) {
- return "P5600";
- }
- return "24Kf";
-}
+
#endif
diff --git a/linux-user/mips64/target_elf.h b/linux-user/mips64/target_elf.h
index 502af9d278..02e6d14840 100644
--- a/linux-user/mips64/target_elf.h
+++ b/linux-user/mips64/target_elf.h
@@ -7,30 +7,5 @@
#ifndef MIPS64_TARGET_ELF_H
#define MIPS64_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- switch (eflags & EF_MIPS_MACH) {
- case EF_MIPS_MACH_OCTEON:
- case EF_MIPS_MACH_OCTEON2:
- case EF_MIPS_MACH_OCTEON3:
- return "Octeon68XX";
- case EF_MIPS_MACH_LS2E:
- return "Loongson-2E";
- case EF_MIPS_MACH_LS2F:
- return "Loongson-2F";
- case EF_MIPS_MACH_LS3A:
- return "Loongson-3A1000";
- default:
- break;
- }
- switch (eflags & EF_MIPS_ARCH) {
- case EF_MIPS_ARCH_64R6:
- return "I6400";
- case EF_MIPS_ARCH_64R2:
- return "MIPS64R2-generic";
- default:
- break;
- }
- return "5KEf";
-}
+
#endif
diff --git a/linux-user/openrisc/target_elf.h b/linux-user/openrisc/target_elf.h
index 265ecd3079..b34f2ff672 100644
--- a/linux-user/openrisc/target_elf.h
+++ b/linux-user/openrisc/target_elf.h
@@ -7,8 +7,5 @@
#ifndef OPENRISC_TARGET_ELF_H
#define OPENRISC_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "any";
-}
+
#endif
diff --git a/linux-user/ppc/target_elf.h b/linux-user/ppc/target_elf.h
index 0616618854..8c0a8ea431 100644
--- a/linux-user/ppc/target_elf.h
+++ b/linux-user/ppc/target_elf.h
@@ -7,12 +7,5 @@
#ifndef PPC_TARGET_ELF_H
#define PPC_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
-#ifdef TARGET_PPC64
- return "POWER9";
-#else
- return "750";
-#endif
-}
+
#endif
diff --git a/linux-user/riscv/target_elf.h b/linux-user/riscv/target_elf.h
index dedd5956f3..bfe86105d0 100644
--- a/linux-user/riscv/target_elf.h
+++ b/linux-user/riscv/target_elf.h
@@ -7,8 +7,5 @@
#ifndef RISCV_TARGET_ELF_H
#define RISCV_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "max";
-}
+
#endif
diff --git a/linux-user/s390x/target_elf.h b/linux-user/s390x/target_elf.h
index 8114b59c1d..e51b053339 100644
--- a/linux-user/s390x/target_elf.h
+++ b/linux-user/s390x/target_elf.h
@@ -7,8 +7,5 @@
#ifndef S390X_TARGET_ELF_H
#define S390X_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "qemu";
-}
+
#endif
diff --git a/linux-user/sh4/target_elf.h b/linux-user/sh4/target_elf.h
index f485e0cef2..d17011bd75 100644
--- a/linux-user/sh4/target_elf.h
+++ b/linux-user/sh4/target_elf.h
@@ -7,8 +7,5 @@
#ifndef SH4_TARGET_ELF_H
#define SH4_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "sh7785";
-}
+
#endif
diff --git a/linux-user/sparc/target_elf.h b/linux-user/sparc/target_elf.h
index a510ceb612..7e46748d26 100644
--- a/linux-user/sparc/target_elf.h
+++ b/linux-user/sparc/target_elf.h
@@ -7,12 +7,5 @@
#ifndef SPARC_TARGET_ELF_H
#define SPARC_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
-#ifdef TARGET_SPARC64
- return "TI UltraSparc II";
-#else
- return "Fujitsu MB86904";
-#endif
-}
+
#endif
diff --git a/linux-user/x86_64/target_elf.h b/linux-user/x86_64/target_elf.h
index 3f628f8d66..5849f96350 100644
--- a/linux-user/x86_64/target_elf.h
+++ b/linux-user/x86_64/target_elf.h
@@ -7,8 +7,5 @@
#ifndef X86_64_TARGET_ELF_H
#define X86_64_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return "max";
-}
+
#endif
diff --git a/linux-user/xtensa/target_elf.h b/linux-user/xtensa/target_elf.h
index a9a3fabd89..2c55c22e14 100644
--- a/linux-user/xtensa/target_elf.h
+++ b/linux-user/xtensa/target_elf.h
@@ -8,9 +8,4 @@
#ifndef XTENSA_TARGET_ELF_H
#define XTENSA_TARGET_ELF_H
-static inline const char *cpu_get_model(uint32_t eflags)
-{
- return XTENSA_DEFAULT_CPU_MODEL;
-}
-
#endif
diff --git a/linux-user/aarch64/elfload.c b/linux-user/aarch64/elfload.c
index 73fa78ef14..b92442dfeb 100644
--- a/linux-user/aarch64/elfload.c
+++ b/linux-user/aarch64/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "any";
+}
diff --git a/linux-user/alpha/elfload.c b/linux-user/alpha/elfload.c
index 73fa78ef14..1e44475c47 100644
--- a/linux-user/alpha/elfload.c
+++ b/linux-user/alpha/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "ev67";
+}
diff --git a/linux-user/arm/elfload.c b/linux-user/arm/elfload.c
index 73fa78ef14..b92442dfeb 100644
--- a/linux-user/arm/elfload.c
+++ b/linux-user/arm/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "any";
+}
diff --git a/linux-user/hexagon/elfload.c b/linux-user/hexagon/elfload.c
index 73fa78ef14..d8b545032a 100644
--- a/linux-user/hexagon/elfload.c
+++ b/linux-user/hexagon/elfload.c
@@ -1 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ static char buf[32];
+ int err;
+
+ /* For now, treat anything newer than v5 as a v73 */
+ /* FIXME - Disable instructions that are newer than the specified arch */
+ if (eflags == 0x04 || /* v5 */
+ eflags == 0x05 || /* v55 */
+ eflags == 0x60 || /* v60 */
+ eflags == 0x61 || /* v61 */
+ eflags == 0x62 || /* v62 */
+ eflags == 0x65 || /* v65 */
+ eflags == 0x66 || /* v66 */
+ eflags == 0x67 || /* v67 */
+ eflags == 0x8067 || /* v67t */
+ eflags == 0x68 || /* v68 */
+ eflags == 0x69 || /* v69 */
+ eflags == 0x71 || /* v71 */
+ eflags == 0x8071 || /* v71t */
+ eflags == 0x73 /* v73 */
+ ) {
+ return "v73";
+ }
+
+ err = snprintf(buf, sizeof(buf), "unknown (0x%x)", eflags);
+ return err >= 0 && err < sizeof(buf) ? buf : "unknown";
+}
diff --git a/linux-user/hppa/elfload.c b/linux-user/hppa/elfload.c
index 73fa78ef14..2274fcbde4 100644
--- a/linux-user/hppa/elfload.c
+++ b/linux-user/hppa/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "hppa";
+}
diff --git a/linux-user/i386/elfload.c b/linux-user/i386/elfload.c
index 73fa78ef14..f92adb7308 100644
--- a/linux-user/i386/elfload.c
+++ b/linux-user/i386/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "max";
+}
diff --git a/linux-user/loongarch64/elfload.c b/linux-user/loongarch64/elfload.c
index 73fa78ef14..874dc4c230 100644
--- a/linux-user/loongarch64/elfload.c
+++ b/linux-user/loongarch64/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "la464";
+}
diff --git a/linux-user/m68k/elfload.c b/linux-user/m68k/elfload.c
index 73fa78ef14..561ac5b3b3 100644
--- a/linux-user/m68k/elfload.c
+++ b/linux-user/m68k/elfload.c
@@ -1 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+#include "elf.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ if (eflags == 0 || (eflags & EF_M68K_M68000)) {
+ /* 680x0 */
+ return "m68040";
+ }
+
+ /* Coldfire */
+ return "any";
+}
diff --git a/linux-user/main.c b/linux-user/main.c
index 68972f00a1..ad1a29d198 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -49,7 +49,6 @@
#include "qemu/guest-random.h"
#include "elf.h"
#include "trace/control.h"
-#include "target_elf.h"
#include "user/cpu_loop.h"
#include "crypto/init.h"
#include "fd-trans.h"
@@ -809,7 +808,7 @@ int main(int argc, char **argv, char **envp)
}
if (cpu_model == NULL) {
- cpu_model = cpu_get_model(get_elf_eflags(execfd));
+ cpu_model = get_elf_cpu_model(get_elf_eflags(execfd));
}
cpu_type = parse_cpu_option(cpu_model);
diff --git a/linux-user/microblaze/elfload.c b/linux-user/microblaze/elfload.c
index 73fa78ef14..b92442dfeb 100644
--- a/linux-user/microblaze/elfload.c
+++ b/linux-user/microblaze/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "any";
+}
diff --git a/linux-user/mips/elfload.c b/linux-user/mips/elfload.c
index 73fa78ef14..04e3b76740 100644
--- a/linux-user/mips/elfload.c
+++ b/linux-user/mips/elfload.c
@@ -1 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+#include "elf.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+#ifdef TARGET_MIPS64
+ switch (eflags & EF_MIPS_MACH) {
+ case EF_MIPS_MACH_OCTEON:
+ case EF_MIPS_MACH_OCTEON2:
+ case EF_MIPS_MACH_OCTEON3:
+ return "Octeon68XX";
+ case EF_MIPS_MACH_LS2E:
+ return "Loongson-2E";
+ case EF_MIPS_MACH_LS2F:
+ return "Loongson-2F";
+ case EF_MIPS_MACH_LS3A:
+ return "Loongson-3A1000";
+ default:
+ break;
+ }
+ switch (eflags & EF_MIPS_ARCH) {
+ case EF_MIPS_ARCH_64R6:
+ return "I6400";
+ case EF_MIPS_ARCH_64R2:
+ return "MIPS64R2-generic";
+ default:
+ break;
+ }
+ return "5KEf";
+#else
+ if ((eflags & EF_MIPS_ARCH) == EF_MIPS_ARCH_32R6) {
+ return "mips32r6-generic";
+ }
+ if (eflags & EF_MIPS_NAN2008) {
+ return "P5600";
+ }
+ return "24Kf";
+#endif
+}
diff --git a/linux-user/openrisc/elfload.c b/linux-user/openrisc/elfload.c
index 73fa78ef14..b92442dfeb 100644
--- a/linux-user/openrisc/elfload.c
+++ b/linux-user/openrisc/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "any";
+}
diff --git a/linux-user/ppc/elfload.c b/linux-user/ppc/elfload.c
index 73fa78ef14..7775dc06fa 100644
--- a/linux-user/ppc/elfload.c
+++ b/linux-user/ppc/elfload.c
@@ -1 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+#ifdef TARGET_PPC64
+ return "POWER9";
+#else
+ return "750";
+#endif
+}
diff --git a/linux-user/riscv/elfload.c b/linux-user/riscv/elfload.c
index 73fa78ef14..f92adb7308 100644
--- a/linux-user/riscv/elfload.c
+++ b/linux-user/riscv/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "max";
+}
diff --git a/linux-user/s390x/elfload.c b/linux-user/s390x/elfload.c
index 73fa78ef14..989953a247 100644
--- a/linux-user/s390x/elfload.c
+++ b/linux-user/s390x/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "qemu";
+}
diff --git a/linux-user/sh4/elfload.c b/linux-user/sh4/elfload.c
index 73fa78ef14..546034ec07 100644
--- a/linux-user/sh4/elfload.c
+++ b/linux-user/sh4/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "sh7785";
+}
diff --git a/linux-user/sparc/elfload.c b/linux-user/sparc/elfload.c
index 73fa78ef14..243e6f9b66 100644
--- a/linux-user/sparc/elfload.c
+++ b/linux-user/sparc/elfload.c
@@ -1 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+#ifdef TARGET_SPARC64
+ return "TI UltraSparc II";
+#else
+ return "Fujitsu MB86904";
+#endif
+}
diff --git a/linux-user/x86_64/elfload.c b/linux-user/x86_64/elfload.c
index 73fa78ef14..f92adb7308 100644
--- a/linux-user/x86_64/elfload.c
+++ b/linux-user/x86_64/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return "max";
+}
diff --git a/linux-user/xtensa/elfload.c b/linux-user/xtensa/elfload.c
index 73fa78ef14..e35ba69a10 100644
--- a/linux-user/xtensa/elfload.c
+++ b/linux-user/xtensa/elfload.c
@@ -1 +1,11 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include "qemu/osdep.h"
+#include "qemu.h"
+#include "loader.h"
+
+
+const char *get_elf_cpu_model(uint32_t eflags)
+{
+ return XTENSA_DEFAULT_CPU_MODEL;
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 06/46] linux-user: Move get_elf_hwcap to {i386, x86_64}/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (4 preceding siblings ...)
2025-08-27 23:19 ` [PULL 05/46] linux-user: Move get_elf_cpu_model to target/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 07/46] linux-user: Move hwcap functions to {arm, aarch64}/elfload.c Richard Henderson
` (40 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Change the return type to abi_ulong, and pass in the cpu.
Duplicate the one line function between i386 and x86_64,
as most other additions to elfload.c won't be common.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/i386/target_elf.h | 2 ++
linux-user/loader.h | 3 +++
linux-user/x86_64/target_elf.h | 2 ++
linux-user/elfload.c | 9 +--------
linux-user/i386/elfload.c | 5 +++++
linux-user/x86_64/elfload.c | 5 +++++
6 files changed, 18 insertions(+), 8 deletions(-)
diff --git a/linux-user/i386/target_elf.h b/linux-user/i386/target_elf.h
index e6f0d8fa4e..802395af3a 100644
--- a/linux-user/i386/target_elf.h
+++ b/linux-user/i386/target_elf.h
@@ -8,4 +8,6 @@
#ifndef I386_TARGET_ELF_H
#define I386_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+
#endif
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 75ee9975a0..457bb36daa 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -101,6 +101,9 @@ extern unsigned long guest_stack_size;
/* Note that Elf32 and Elf64 use uint32_t for e_flags. */
const char *get_elf_cpu_model(uint32_t eflags);
+#if defined(TARGET_I386) || defined(TARGET_X86_64)
+abi_ulong get_elf_hwcap(CPUState *cs);
+#endif
#if defined(TARGET_S390X) || defined(TARGET_AARCH64) || defined(TARGET_ARM)
uint32_t get_elf_hwcap(void);
const char *elf_hwcap_str(uint32_t bit);
diff --git a/linux-user/x86_64/target_elf.h b/linux-user/x86_64/target_elf.h
index 5849f96350..03483bad57 100644
--- a/linux-user/x86_64/target_elf.h
+++ b/linux-user/x86_64/target_elf.h
@@ -8,4 +8,6 @@
#ifndef X86_64_TARGET_ELF_H
#define X86_64_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 4ca8c39dc2..0c62c249e9 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -148,14 +148,7 @@ typedef abi_int target_pid_t;
#ifdef TARGET_I386
-#define ELF_HWCAP get_elf_hwcap()
-
-static uint32_t get_elf_hwcap(void)
-{
- X86CPU *cpu = X86_CPU(thread_cpu);
-
- return cpu->env.features[FEAT_1_EDX];
-}
+#define ELF_HWCAP get_elf_hwcap(thread_cpu)
#ifdef TARGET_X86_64
#define ELF_CLASS ELFCLASS64
diff --git a/linux-user/i386/elfload.c b/linux-user/i386/elfload.c
index f92adb7308..f99336e73c 100644
--- a/linux-user/i386/elfload.c
+++ b/linux-user/i386/elfload.c
@@ -9,3 +9,8 @@ const char *get_elf_cpu_model(uint32_t eflags)
{
return "max";
}
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+ return cpu_env(cs)->features[FEAT_1_EDX];
+}
diff --git a/linux-user/x86_64/elfload.c b/linux-user/x86_64/elfload.c
index f92adb7308..f99336e73c 100644
--- a/linux-user/x86_64/elfload.c
+++ b/linux-user/x86_64/elfload.c
@@ -9,3 +9,8 @@ const char *get_elf_cpu_model(uint32_t eflags)
{
return "max";
}
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+ return cpu_env(cs)->features[FEAT_1_EDX];
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 07/46] linux-user: Move hwcap functions to {arm, aarch64}/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (5 preceding siblings ...)
2025-08-27 23:19 ` [PULL 06/46] linux-user: Move get_elf_hwcap to {i386, x86_64}/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 08/46] linux-user: Move get_elf_hwcap to sparc/elfload.c Richard Henderson
` (39 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
For get_elf_hwcap and get_elf_hwcap2, change the return type to
abi_ulong, and pass in the cpu. We must do these targets at the
same time because of the ifdef dependency between TARGET_AARCH64
and TARGET_ARM.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/target_elf.h | 3 +
linux-user/arm/target_elf.h | 3 +
linux-user/arm/target_proc.h | 4 +-
linux-user/loader.h | 10 +-
linux-user/aarch64/elfload.c | 333 +++++++++++++++++++++
linux-user/arm/elfload.c | 161 ++++++++++
linux-user/elfload.c | 505 +-------------------------------
7 files changed, 510 insertions(+), 509 deletions(-)
diff --git a/linux-user/aarch64/target_elf.h b/linux-user/aarch64/target_elf.h
index d955b3d07f..77108f3cb0 100644
--- a/linux-user/aarch64/target_elf.h
+++ b/linux-user/aarch64/target_elf.h
@@ -8,4 +8,7 @@
#ifndef AARCH64_TARGET_ELF_H
#define AARCH64_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+#define HAVE_ELF_HWCAP2 1
+
#endif
diff --git a/linux-user/arm/target_elf.h b/linux-user/arm/target_elf.h
index 2abb27a733..90470bd87b 100644
--- a/linux-user/arm/target_elf.h
+++ b/linux-user/arm/target_elf.h
@@ -8,4 +8,7 @@
#ifndef ARM_TARGET_ELF_H
#define ARM_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+#define HAVE_ELF_HWCAP2 1
+
#endif
diff --git a/linux-user/arm/target_proc.h b/linux-user/arm/target_proc.h
index ac75af9ca6..a4cd6948c6 100644
--- a/linux-user/arm/target_proc.h
+++ b/linux-user/arm/target_proc.h
@@ -10,8 +10,8 @@ static int open_cpuinfo(CPUArchState *cpu_env, int fd)
{
ARMCPU *cpu = env_archcpu(cpu_env);
int arch, midr_rev, midr_part, midr_var, midr_impl;
- target_ulong elf_hwcap = get_elf_hwcap();
- target_ulong elf_hwcap2 = get_elf_hwcap2();
+ target_ulong elf_hwcap = get_elf_hwcap(env_cpu(cpu_env));
+ target_ulong elf_hwcap2 = get_elf_hwcap2(env_cpu(cpu_env));
const char *elf_name;
int num_cpus, len_part, len_var;
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 457bb36daa..151a06f5db 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -101,16 +101,14 @@ extern unsigned long guest_stack_size;
/* Note that Elf32 and Elf64 use uint32_t for e_flags. */
const char *get_elf_cpu_model(uint32_t eflags);
-#if defined(TARGET_I386) || defined(TARGET_X86_64)
+#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_ARM)
abi_ulong get_elf_hwcap(CPUState *cs);
+abi_ulong get_elf_hwcap2(CPUState *cs);
#endif
-#if defined(TARGET_S390X) || defined(TARGET_AARCH64) || defined(TARGET_ARM)
+#if defined(TARGET_S390X)
uint32_t get_elf_hwcap(void);
+#endif
const char *elf_hwcap_str(uint32_t bit);
-#endif
-#if defined(TARGET_AARCH64) || defined(TARGET_ARM)
-uint64_t get_elf_hwcap2(void);
const char *elf_hwcap2_str(uint32_t bit);
-#endif
#endif /* LINUX_USER_LOADER_H */
diff --git a/linux-user/aarch64/elfload.c b/linux-user/aarch64/elfload.c
index b92442dfeb..92c8ea62c6 100644
--- a/linux-user/aarch64/elfload.c
+++ b/linux-user/aarch64/elfload.c
@@ -3,9 +3,342 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
+#include "target/arm/cpu-features.h"
const char *get_elf_cpu_model(uint32_t eflags)
{
return "any";
}
+
+enum {
+ ARM_HWCAP_A64_FP = 1 << 0,
+ ARM_HWCAP_A64_ASIMD = 1 << 1,
+ ARM_HWCAP_A64_EVTSTRM = 1 << 2,
+ ARM_HWCAP_A64_AES = 1 << 3,
+ ARM_HWCAP_A64_PMULL = 1 << 4,
+ ARM_HWCAP_A64_SHA1 = 1 << 5,
+ ARM_HWCAP_A64_SHA2 = 1 << 6,
+ ARM_HWCAP_A64_CRC32 = 1 << 7,
+ ARM_HWCAP_A64_ATOMICS = 1 << 8,
+ ARM_HWCAP_A64_FPHP = 1 << 9,
+ ARM_HWCAP_A64_ASIMDHP = 1 << 10,
+ ARM_HWCAP_A64_CPUID = 1 << 11,
+ ARM_HWCAP_A64_ASIMDRDM = 1 << 12,
+ ARM_HWCAP_A64_JSCVT = 1 << 13,
+ ARM_HWCAP_A64_FCMA = 1 << 14,
+ ARM_HWCAP_A64_LRCPC = 1 << 15,
+ ARM_HWCAP_A64_DCPOP = 1 << 16,
+ ARM_HWCAP_A64_SHA3 = 1 << 17,
+ ARM_HWCAP_A64_SM3 = 1 << 18,
+ ARM_HWCAP_A64_SM4 = 1 << 19,
+ ARM_HWCAP_A64_ASIMDDP = 1 << 20,
+ ARM_HWCAP_A64_SHA512 = 1 << 21,
+ ARM_HWCAP_A64_SVE = 1 << 22,
+ ARM_HWCAP_A64_ASIMDFHM = 1 << 23,
+ ARM_HWCAP_A64_DIT = 1 << 24,
+ ARM_HWCAP_A64_USCAT = 1 << 25,
+ ARM_HWCAP_A64_ILRCPC = 1 << 26,
+ ARM_HWCAP_A64_FLAGM = 1 << 27,
+ ARM_HWCAP_A64_SSBS = 1 << 28,
+ ARM_HWCAP_A64_SB = 1 << 29,
+ ARM_HWCAP_A64_PACA = 1 << 30,
+ ARM_HWCAP_A64_PACG = 1ULL << 31,
+ ARM_HWCAP_A64_GCS = 1ULL << 32,
+ ARM_HWCAP_A64_CMPBR = 1ULL << 33,
+ ARM_HWCAP_A64_FPRCVT = 1ULL << 34,
+ ARM_HWCAP_A64_F8MM8 = 1ULL << 35,
+ ARM_HWCAP_A64_F8MM4 = 1ULL << 36,
+ ARM_HWCAP_A64_SVE_F16MM = 1ULL << 37,
+ ARM_HWCAP_A64_SVE_ELTPERM = 1ULL << 38,
+ ARM_HWCAP_A64_SVE_AES2 = 1ULL << 39,
+ ARM_HWCAP_A64_SVE_BFSCALE = 1ULL << 40,
+ ARM_HWCAP_A64_SVE2P2 = 1ULL << 41,
+ ARM_HWCAP_A64_SME2P2 = 1ULL << 42,
+ ARM_HWCAP_A64_SME_SBITPERM = 1ULL << 43,
+ ARM_HWCAP_A64_SME_AES = 1ULL << 44,
+ ARM_HWCAP_A64_SME_SFEXPA = 1ULL << 45,
+ ARM_HWCAP_A64_SME_STMOP = 1ULL << 46,
+ ARM_HWCAP_A64_SME_SMOP4 = 1ULL << 47,
+
+ ARM_HWCAP2_A64_DCPODP = 1 << 0,
+ ARM_HWCAP2_A64_SVE2 = 1 << 1,
+ ARM_HWCAP2_A64_SVEAES = 1 << 2,
+ ARM_HWCAP2_A64_SVEPMULL = 1 << 3,
+ ARM_HWCAP2_A64_SVEBITPERM = 1 << 4,
+ ARM_HWCAP2_A64_SVESHA3 = 1 << 5,
+ ARM_HWCAP2_A64_SVESM4 = 1 << 6,
+ ARM_HWCAP2_A64_FLAGM2 = 1 << 7,
+ ARM_HWCAP2_A64_FRINT = 1 << 8,
+ ARM_HWCAP2_A64_SVEI8MM = 1 << 9,
+ ARM_HWCAP2_A64_SVEF32MM = 1 << 10,
+ ARM_HWCAP2_A64_SVEF64MM = 1 << 11,
+ ARM_HWCAP2_A64_SVEBF16 = 1 << 12,
+ ARM_HWCAP2_A64_I8MM = 1 << 13,
+ ARM_HWCAP2_A64_BF16 = 1 << 14,
+ ARM_HWCAP2_A64_DGH = 1 << 15,
+ ARM_HWCAP2_A64_RNG = 1 << 16,
+ ARM_HWCAP2_A64_BTI = 1 << 17,
+ ARM_HWCAP2_A64_MTE = 1 << 18,
+ ARM_HWCAP2_A64_ECV = 1 << 19,
+ ARM_HWCAP2_A64_AFP = 1 << 20,
+ ARM_HWCAP2_A64_RPRES = 1 << 21,
+ ARM_HWCAP2_A64_MTE3 = 1 << 22,
+ ARM_HWCAP2_A64_SME = 1 << 23,
+ ARM_HWCAP2_A64_SME_I16I64 = 1 << 24,
+ ARM_HWCAP2_A64_SME_F64F64 = 1 << 25,
+ ARM_HWCAP2_A64_SME_I8I32 = 1 << 26,
+ ARM_HWCAP2_A64_SME_F16F32 = 1 << 27,
+ ARM_HWCAP2_A64_SME_B16F32 = 1 << 28,
+ ARM_HWCAP2_A64_SME_F32F32 = 1 << 29,
+ ARM_HWCAP2_A64_SME_FA64 = 1 << 30,
+ ARM_HWCAP2_A64_WFXT = 1ULL << 31,
+ ARM_HWCAP2_A64_EBF16 = 1ULL << 32,
+ ARM_HWCAP2_A64_SVE_EBF16 = 1ULL << 33,
+ ARM_HWCAP2_A64_CSSC = 1ULL << 34,
+ ARM_HWCAP2_A64_RPRFM = 1ULL << 35,
+ ARM_HWCAP2_A64_SVE2P1 = 1ULL << 36,
+ ARM_HWCAP2_A64_SME2 = 1ULL << 37,
+ ARM_HWCAP2_A64_SME2P1 = 1ULL << 38,
+ ARM_HWCAP2_A64_SME_I16I32 = 1ULL << 39,
+ ARM_HWCAP2_A64_SME_BI32I32 = 1ULL << 40,
+ ARM_HWCAP2_A64_SME_B16B16 = 1ULL << 41,
+ ARM_HWCAP2_A64_SME_F16F16 = 1ULL << 42,
+ ARM_HWCAP2_A64_MOPS = 1ULL << 43,
+ ARM_HWCAP2_A64_HBC = 1ULL << 44,
+ ARM_HWCAP2_A64_SVE_B16B16 = 1ULL << 45,
+ ARM_HWCAP2_A64_LRCPC3 = 1ULL << 46,
+ ARM_HWCAP2_A64_LSE128 = 1ULL << 47,
+ ARM_HWCAP2_A64_FPMR = 1ULL << 48,
+ ARM_HWCAP2_A64_LUT = 1ULL << 49,
+ ARM_HWCAP2_A64_FAMINMAX = 1ULL << 50,
+ ARM_HWCAP2_A64_F8CVT = 1ULL << 51,
+ ARM_HWCAP2_A64_F8FMA = 1ULL << 52,
+ ARM_HWCAP2_A64_F8DP4 = 1ULL << 53,
+ ARM_HWCAP2_A64_F8DP2 = 1ULL << 54,
+ ARM_HWCAP2_A64_F8E4M3 = 1ULL << 55,
+ ARM_HWCAP2_A64_F8E5M2 = 1ULL << 56,
+ ARM_HWCAP2_A64_SME_LUTV2 = 1ULL << 57,
+ ARM_HWCAP2_A64_SME_F8F16 = 1ULL << 58,
+ ARM_HWCAP2_A64_SME_F8F32 = 1ULL << 59,
+ ARM_HWCAP2_A64_SME_SF8FMA = 1ULL << 60,
+ ARM_HWCAP2_A64_SME_SF8DP4 = 1ULL << 61,
+ ARM_HWCAP2_A64_SME_SF8DP2 = 1ULL << 62,
+ ARM_HWCAP2_A64_POE = 1ULL << 63,
+};
+
+#define GET_FEATURE_ID(feat, hwcap) \
+ do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ abi_ulong hwcaps = 0;
+
+ hwcaps |= ARM_HWCAP_A64_FP;
+ hwcaps |= ARM_HWCAP_A64_ASIMD;
+ hwcaps |= ARM_HWCAP_A64_CPUID;
+
+ /* probe for the extra features */
+
+ GET_FEATURE_ID(aa64_aes, ARM_HWCAP_A64_AES);
+ GET_FEATURE_ID(aa64_pmull, ARM_HWCAP_A64_PMULL);
+ GET_FEATURE_ID(aa64_sha1, ARM_HWCAP_A64_SHA1);
+ GET_FEATURE_ID(aa64_sha256, ARM_HWCAP_A64_SHA2);
+ GET_FEATURE_ID(aa64_sha512, ARM_HWCAP_A64_SHA512);
+ GET_FEATURE_ID(aa64_crc32, ARM_HWCAP_A64_CRC32);
+ GET_FEATURE_ID(aa64_sha3, ARM_HWCAP_A64_SHA3);
+ GET_FEATURE_ID(aa64_sm3, ARM_HWCAP_A64_SM3);
+ GET_FEATURE_ID(aa64_sm4, ARM_HWCAP_A64_SM4);
+ GET_FEATURE_ID(aa64_fp16, ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
+ GET_FEATURE_ID(aa64_atomics, ARM_HWCAP_A64_ATOMICS);
+ GET_FEATURE_ID(aa64_lse2, ARM_HWCAP_A64_USCAT);
+ GET_FEATURE_ID(aa64_rdm, ARM_HWCAP_A64_ASIMDRDM);
+ GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
+ GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
+ GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
+ GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
+ GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
+ GET_FEATURE_ID(aa64_dit, ARM_HWCAP_A64_DIT);
+ GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
+ GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
+ GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
+ GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
+ GET_FEATURE_ID(aa64_rcpc_8_3, ARM_HWCAP_A64_LRCPC);
+ GET_FEATURE_ID(aa64_rcpc_8_4, ARM_HWCAP_A64_ILRCPC);
+
+ return hwcaps;
+}
+
+abi_ulong get_elf_hwcap2(CPUState *cs)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ abi_ulong hwcaps = 0;
+
+ GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
+ GET_FEATURE_ID(aa64_sve2, ARM_HWCAP2_A64_SVE2);
+ GET_FEATURE_ID(aa64_sve2_aes, ARM_HWCAP2_A64_SVEAES);
+ GET_FEATURE_ID(aa64_sve2_pmull128, ARM_HWCAP2_A64_SVEPMULL);
+ GET_FEATURE_ID(aa64_sve2_bitperm, ARM_HWCAP2_A64_SVEBITPERM);
+ GET_FEATURE_ID(aa64_sve2_sha3, ARM_HWCAP2_A64_SVESHA3);
+ GET_FEATURE_ID(aa64_sve2_sm4, ARM_HWCAP2_A64_SVESM4);
+ GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
+ GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
+ GET_FEATURE_ID(aa64_sve_i8mm, ARM_HWCAP2_A64_SVEI8MM);
+ GET_FEATURE_ID(aa64_sve_f32mm, ARM_HWCAP2_A64_SVEF32MM);
+ GET_FEATURE_ID(aa64_sve_f64mm, ARM_HWCAP2_A64_SVEF64MM);
+ GET_FEATURE_ID(aa64_sve_bf16, ARM_HWCAP2_A64_SVEBF16);
+ GET_FEATURE_ID(aa64_i8mm, ARM_HWCAP2_A64_I8MM);
+ GET_FEATURE_ID(aa64_bf16, ARM_HWCAP2_A64_BF16);
+ GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
+ GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
+ GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
+ GET_FEATURE_ID(aa64_mte3, ARM_HWCAP2_A64_MTE3);
+ GET_FEATURE_ID(aa64_sme, (ARM_HWCAP2_A64_SME |
+ ARM_HWCAP2_A64_SME_F32F32 |
+ ARM_HWCAP2_A64_SME_B16F32 |
+ ARM_HWCAP2_A64_SME_F16F32 |
+ ARM_HWCAP2_A64_SME_I8I32));
+ GET_FEATURE_ID(aa64_sme_f64f64, ARM_HWCAP2_A64_SME_F64F64);
+ GET_FEATURE_ID(aa64_sme_i16i64, ARM_HWCAP2_A64_SME_I16I64);
+ GET_FEATURE_ID(aa64_sme_fa64, ARM_HWCAP2_A64_SME_FA64);
+ GET_FEATURE_ID(aa64_hbc, ARM_HWCAP2_A64_HBC);
+ GET_FEATURE_ID(aa64_mops, ARM_HWCAP2_A64_MOPS);
+ GET_FEATURE_ID(aa64_sve2p1, ARM_HWCAP2_A64_SVE2P1);
+ GET_FEATURE_ID(aa64_sme2, (ARM_HWCAP2_A64_SME2 |
+ ARM_HWCAP2_A64_SME_I16I32 |
+ ARM_HWCAP2_A64_SME_BI32I32));
+ GET_FEATURE_ID(aa64_sme2p1, ARM_HWCAP2_A64_SME2P1);
+ GET_FEATURE_ID(aa64_sme_b16b16, ARM_HWCAP2_A64_SME_B16B16);
+ GET_FEATURE_ID(aa64_sme_f16f16, ARM_HWCAP2_A64_SME_F16F16);
+ GET_FEATURE_ID(aa64_sve_b16b16, ARM_HWCAP2_A64_SVE_B16B16);
+
+ return hwcaps;
+}
+
+const char *elf_hwcap_str(uint32_t bit)
+{
+ static const char * const hwcap_str[] = {
+ [__builtin_ctz(ARM_HWCAP_A64_FP )] = "fp",
+ [__builtin_ctz(ARM_HWCAP_A64_ASIMD )] = "asimd",
+ [__builtin_ctz(ARM_HWCAP_A64_EVTSTRM )] = "evtstrm",
+ [__builtin_ctz(ARM_HWCAP_A64_AES )] = "aes",
+ [__builtin_ctz(ARM_HWCAP_A64_PMULL )] = "pmull",
+ [__builtin_ctz(ARM_HWCAP_A64_SHA1 )] = "sha1",
+ [__builtin_ctz(ARM_HWCAP_A64_SHA2 )] = "sha2",
+ [__builtin_ctz(ARM_HWCAP_A64_CRC32 )] = "crc32",
+ [__builtin_ctz(ARM_HWCAP_A64_ATOMICS )] = "atomics",
+ [__builtin_ctz(ARM_HWCAP_A64_FPHP )] = "fphp",
+ [__builtin_ctz(ARM_HWCAP_A64_ASIMDHP )] = "asimdhp",
+ [__builtin_ctz(ARM_HWCAP_A64_CPUID )] = "cpuid",
+ [__builtin_ctz(ARM_HWCAP_A64_ASIMDRDM)] = "asimdrdm",
+ [__builtin_ctz(ARM_HWCAP_A64_JSCVT )] = "jscvt",
+ [__builtin_ctz(ARM_HWCAP_A64_FCMA )] = "fcma",
+ [__builtin_ctz(ARM_HWCAP_A64_LRCPC )] = "lrcpc",
+ [__builtin_ctz(ARM_HWCAP_A64_DCPOP )] = "dcpop",
+ [__builtin_ctz(ARM_HWCAP_A64_SHA3 )] = "sha3",
+ [__builtin_ctz(ARM_HWCAP_A64_SM3 )] = "sm3",
+ [__builtin_ctz(ARM_HWCAP_A64_SM4 )] = "sm4",
+ [__builtin_ctz(ARM_HWCAP_A64_ASIMDDP )] = "asimddp",
+ [__builtin_ctz(ARM_HWCAP_A64_SHA512 )] = "sha512",
+ [__builtin_ctz(ARM_HWCAP_A64_SVE )] = "sve",
+ [__builtin_ctz(ARM_HWCAP_A64_ASIMDFHM)] = "asimdfhm",
+ [__builtin_ctz(ARM_HWCAP_A64_DIT )] = "dit",
+ [__builtin_ctz(ARM_HWCAP_A64_USCAT )] = "uscat",
+ [__builtin_ctz(ARM_HWCAP_A64_ILRCPC )] = "ilrcpc",
+ [__builtin_ctz(ARM_HWCAP_A64_FLAGM )] = "flagm",
+ [__builtin_ctz(ARM_HWCAP_A64_SSBS )] = "ssbs",
+ [__builtin_ctz(ARM_HWCAP_A64_SB )] = "sb",
+ [__builtin_ctz(ARM_HWCAP_A64_PACA )] = "paca",
+ [__builtin_ctz(ARM_HWCAP_A64_PACG )] = "pacg",
+ [__builtin_ctzll(ARM_HWCAP_A64_GCS )] = "gcs",
+ [__builtin_ctzll(ARM_HWCAP_A64_CMPBR )] = "cmpbr",
+ [__builtin_ctzll(ARM_HWCAP_A64_FPRCVT)] = "fprcvt",
+ [__builtin_ctzll(ARM_HWCAP_A64_F8MM8 )] = "f8mm8",
+ [__builtin_ctzll(ARM_HWCAP_A64_F8MM4 )] = "f8mm4",
+ [__builtin_ctzll(ARM_HWCAP_A64_SVE_F16MM)] = "svef16mm",
+ [__builtin_ctzll(ARM_HWCAP_A64_SVE_ELTPERM)] = "sveeltperm",
+ [__builtin_ctzll(ARM_HWCAP_A64_SVE_AES2)] = "sveaes2",
+ [__builtin_ctzll(ARM_HWCAP_A64_SVE_BFSCALE)] = "svebfscale",
+ [__builtin_ctzll(ARM_HWCAP_A64_SVE2P2)] = "sve2p2",
+ [__builtin_ctzll(ARM_HWCAP_A64_SME2P2)] = "sme2p2",
+ [__builtin_ctzll(ARM_HWCAP_A64_SME_SBITPERM)] = "smesbitperm",
+ [__builtin_ctzll(ARM_HWCAP_A64_SME_AES)] = "smeaes",
+ [__builtin_ctzll(ARM_HWCAP_A64_SME_SFEXPA)] = "smesfexpa",
+ [__builtin_ctzll(ARM_HWCAP_A64_SME_STMOP)] = "smestmop",
+ [__builtin_ctzll(ARM_HWCAP_A64_SME_SMOP4)] = "smesmop4",
+ };
+
+ return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
+}
+
+const char *elf_hwcap2_str(uint32_t bit)
+{
+ static const char * const hwcap_str[] = {
+ [__builtin_ctz(ARM_HWCAP2_A64_DCPODP )] = "dcpodp",
+ [__builtin_ctz(ARM_HWCAP2_A64_SVE2 )] = "sve2",
+ [__builtin_ctz(ARM_HWCAP2_A64_SVEAES )] = "sveaes",
+ [__builtin_ctz(ARM_HWCAP2_A64_SVEPMULL )] = "svepmull",
+ [__builtin_ctz(ARM_HWCAP2_A64_SVEBITPERM )] = "svebitperm",
+ [__builtin_ctz(ARM_HWCAP2_A64_SVESHA3 )] = "svesha3",
+ [__builtin_ctz(ARM_HWCAP2_A64_SVESM4 )] = "svesm4",
+ [__builtin_ctz(ARM_HWCAP2_A64_FLAGM2 )] = "flagm2",
+ [__builtin_ctz(ARM_HWCAP2_A64_FRINT )] = "frint",
+ [__builtin_ctz(ARM_HWCAP2_A64_SVEI8MM )] = "svei8mm",
+ [__builtin_ctz(ARM_HWCAP2_A64_SVEF32MM )] = "svef32mm",
+ [__builtin_ctz(ARM_HWCAP2_A64_SVEF64MM )] = "svef64mm",
+ [__builtin_ctz(ARM_HWCAP2_A64_SVEBF16 )] = "svebf16",
+ [__builtin_ctz(ARM_HWCAP2_A64_I8MM )] = "i8mm",
+ [__builtin_ctz(ARM_HWCAP2_A64_BF16 )] = "bf16",
+ [__builtin_ctz(ARM_HWCAP2_A64_DGH )] = "dgh",
+ [__builtin_ctz(ARM_HWCAP2_A64_RNG )] = "rng",
+ [__builtin_ctz(ARM_HWCAP2_A64_BTI )] = "bti",
+ [__builtin_ctz(ARM_HWCAP2_A64_MTE )] = "mte",
+ [__builtin_ctz(ARM_HWCAP2_A64_ECV )] = "ecv",
+ [__builtin_ctz(ARM_HWCAP2_A64_AFP )] = "afp",
+ [__builtin_ctz(ARM_HWCAP2_A64_RPRES )] = "rpres",
+ [__builtin_ctz(ARM_HWCAP2_A64_MTE3 )] = "mte3",
+ [__builtin_ctz(ARM_HWCAP2_A64_SME )] = "sme",
+ [__builtin_ctz(ARM_HWCAP2_A64_SME_I16I64 )] = "smei16i64",
+ [__builtin_ctz(ARM_HWCAP2_A64_SME_F64F64 )] = "smef64f64",
+ [__builtin_ctz(ARM_HWCAP2_A64_SME_I8I32 )] = "smei8i32",
+ [__builtin_ctz(ARM_HWCAP2_A64_SME_F16F32 )] = "smef16f32",
+ [__builtin_ctz(ARM_HWCAP2_A64_SME_B16F32 )] = "smeb16f32",
+ [__builtin_ctz(ARM_HWCAP2_A64_SME_F32F32 )] = "smef32f32",
+ [__builtin_ctz(ARM_HWCAP2_A64_SME_FA64 )] = "smefa64",
+ [__builtin_ctz(ARM_HWCAP2_A64_WFXT )] = "wfxt",
+ [__builtin_ctzll(ARM_HWCAP2_A64_EBF16 )] = "ebf16",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SVE_EBF16 )] = "sveebf16",
+ [__builtin_ctzll(ARM_HWCAP2_A64_CSSC )] = "cssc",
+ [__builtin_ctzll(ARM_HWCAP2_A64_RPRFM )] = "rprfm",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SVE2P1 )] = "sve2p1",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME2 )] = "sme2",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME2P1 )] = "sme2p1",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME_I16I32 )] = "smei16i32",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME_BI32I32)] = "smebi32i32",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME_B16B16 )] = "smeb16b16",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME_F16F16 )] = "smef16f16",
+ [__builtin_ctzll(ARM_HWCAP2_A64_MOPS )] = "mops",
+ [__builtin_ctzll(ARM_HWCAP2_A64_HBC )] = "hbc",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SVE_B16B16 )] = "sveb16b16",
+ [__builtin_ctzll(ARM_HWCAP2_A64_LRCPC3 )] = "lrcpc3",
+ [__builtin_ctzll(ARM_HWCAP2_A64_LSE128 )] = "lse128",
+ [__builtin_ctzll(ARM_HWCAP2_A64_FPMR )] = "fpmr",
+ [__builtin_ctzll(ARM_HWCAP2_A64_LUT )] = "lut",
+ [__builtin_ctzll(ARM_HWCAP2_A64_FAMINMAX )] = "faminmax",
+ [__builtin_ctzll(ARM_HWCAP2_A64_F8CVT )] = "f8cvt",
+ [__builtin_ctzll(ARM_HWCAP2_A64_F8FMA )] = "f8fma",
+ [__builtin_ctzll(ARM_HWCAP2_A64_F8DP4 )] = "f8dp4",
+ [__builtin_ctzll(ARM_HWCAP2_A64_F8DP2 )] = "f8dp2",
+ [__builtin_ctzll(ARM_HWCAP2_A64_F8E4M3 )] = "f8e4m3",
+ [__builtin_ctzll(ARM_HWCAP2_A64_F8E5M2 )] = "f8e5m2",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME_LUTV2 )] = "smelutv2",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME_F8F16 )] = "smef8f16",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME_F8F32 )] = "smef8f32",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME_SF8DP4 )] = "smesf8dp4",
+ [__builtin_ctzll(ARM_HWCAP2_A64_SME_SF8DP2 )] = "smesf8dp2",
+ [__builtin_ctzll(ARM_HWCAP2_A64_POE )] = "poe",
+ };
+
+ return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
+}
diff --git a/linux-user/arm/elfload.c b/linux-user/arm/elfload.c
index b92442dfeb..c7561b005b 100644
--- a/linux-user/arm/elfload.c
+++ b/linux-user/arm/elfload.c
@@ -3,9 +3,170 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
+#include "target/arm/cpu-features.h"
const char *get_elf_cpu_model(uint32_t eflags)
{
return "any";
}
+
+enum
+{
+ ARM_HWCAP_ARM_SWP = 1 << 0,
+ ARM_HWCAP_ARM_HALF = 1 << 1,
+ ARM_HWCAP_ARM_THUMB = 1 << 2,
+ ARM_HWCAP_ARM_26BIT = 1 << 3,
+ ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
+ ARM_HWCAP_ARM_FPA = 1 << 5,
+ ARM_HWCAP_ARM_VFP = 1 << 6,
+ ARM_HWCAP_ARM_EDSP = 1 << 7,
+ ARM_HWCAP_ARM_JAVA = 1 << 8,
+ ARM_HWCAP_ARM_IWMMXT = 1 << 9,
+ ARM_HWCAP_ARM_CRUNCH = 1 << 10,
+ ARM_HWCAP_ARM_THUMBEE = 1 << 11,
+ ARM_HWCAP_ARM_NEON = 1 << 12,
+ ARM_HWCAP_ARM_VFPv3 = 1 << 13,
+ ARM_HWCAP_ARM_VFPv3D16 = 1 << 14,
+ ARM_HWCAP_ARM_TLS = 1 << 15,
+ ARM_HWCAP_ARM_VFPv4 = 1 << 16,
+ ARM_HWCAP_ARM_IDIVA = 1 << 17,
+ ARM_HWCAP_ARM_IDIVT = 1 << 18,
+ ARM_HWCAP_ARM_VFPD32 = 1 << 19,
+ ARM_HWCAP_ARM_LPAE = 1 << 20,
+ ARM_HWCAP_ARM_EVTSTRM = 1 << 21,
+ ARM_HWCAP_ARM_FPHP = 1 << 22,
+ ARM_HWCAP_ARM_ASIMDHP = 1 << 23,
+ ARM_HWCAP_ARM_ASIMDDP = 1 << 24,
+ ARM_HWCAP_ARM_ASIMDFHM = 1 << 25,
+ ARM_HWCAP_ARM_ASIMDBF16 = 1 << 26,
+ ARM_HWCAP_ARM_I8MM = 1 << 27,
+};
+
+enum {
+ ARM_HWCAP2_ARM_AES = 1 << 0,
+ ARM_HWCAP2_ARM_PMULL = 1 << 1,
+ ARM_HWCAP2_ARM_SHA1 = 1 << 2,
+ ARM_HWCAP2_ARM_SHA2 = 1 << 3,
+ ARM_HWCAP2_ARM_CRC32 = 1 << 4,
+ ARM_HWCAP2_ARM_SB = 1 << 5,
+ ARM_HWCAP2_ARM_SSBS = 1 << 6,
+};
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ abi_ulong hwcaps = 0;
+
+ hwcaps |= ARM_HWCAP_ARM_SWP;
+ hwcaps |= ARM_HWCAP_ARM_HALF;
+ hwcaps |= ARM_HWCAP_ARM_THUMB;
+ hwcaps |= ARM_HWCAP_ARM_FAST_MULT;
+
+ /* probe for the extra features */
+#define GET_FEATURE(feat, hwcap) \
+ do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
+
+#define GET_FEATURE_ID(feat, hwcap) \
+ do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
+
+ /* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */
+ GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
+ GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
+ GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
+ GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
+ GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
+ GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
+ GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
+ GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
+ GET_FEATURE_ID(aa32_vfp, ARM_HWCAP_ARM_VFP);
+
+ if (cpu_isar_feature(aa32_fpsp_v3, cpu) ||
+ cpu_isar_feature(aa32_fpdp_v3, cpu)) {
+ hwcaps |= ARM_HWCAP_ARM_VFPv3;
+ if (cpu_isar_feature(aa32_simd_r32, cpu)) {
+ hwcaps |= ARM_HWCAP_ARM_VFPD32;
+ } else {
+ hwcaps |= ARM_HWCAP_ARM_VFPv3D16;
+ }
+ }
+ GET_FEATURE_ID(aa32_simdfmac, ARM_HWCAP_ARM_VFPv4);
+ /*
+ * MVFR1.FPHP and .SIMDHP must be in sync, and QEMU uses the same
+ * isar_feature function for both. The kernel reports them as two hwcaps.
+ */
+ GET_FEATURE_ID(aa32_fp16_arith, ARM_HWCAP_ARM_FPHP);
+ GET_FEATURE_ID(aa32_fp16_arith, ARM_HWCAP_ARM_ASIMDHP);
+ GET_FEATURE_ID(aa32_dp, ARM_HWCAP_ARM_ASIMDDP);
+ GET_FEATURE_ID(aa32_fhm, ARM_HWCAP_ARM_ASIMDFHM);
+ GET_FEATURE_ID(aa32_bf16, ARM_HWCAP_ARM_ASIMDBF16);
+ GET_FEATURE_ID(aa32_i8mm, ARM_HWCAP_ARM_I8MM);
+
+ return hwcaps;
+}
+
+abi_ulong get_elf_hwcap2(CPUState *cs)
+{
+ ARMCPU *cpu = ARM_CPU(cs);
+ abi_ulong hwcaps = 0;
+
+ GET_FEATURE_ID(aa32_aes, ARM_HWCAP2_ARM_AES);
+ GET_FEATURE_ID(aa32_pmull, ARM_HWCAP2_ARM_PMULL);
+ GET_FEATURE_ID(aa32_sha1, ARM_HWCAP2_ARM_SHA1);
+ GET_FEATURE_ID(aa32_sha2, ARM_HWCAP2_ARM_SHA2);
+ GET_FEATURE_ID(aa32_crc32, ARM_HWCAP2_ARM_CRC32);
+ GET_FEATURE_ID(aa32_sb, ARM_HWCAP2_ARM_SB);
+ GET_FEATURE_ID(aa32_ssbs, ARM_HWCAP2_ARM_SSBS);
+ return hwcaps;
+}
+
+const char *elf_hwcap_str(uint32_t bit)
+{
+ static const char *hwcap_str[] = {
+ [__builtin_ctz(ARM_HWCAP_ARM_SWP )] = "swp",
+ [__builtin_ctz(ARM_HWCAP_ARM_HALF )] = "half",
+ [__builtin_ctz(ARM_HWCAP_ARM_THUMB )] = "thumb",
+ [__builtin_ctz(ARM_HWCAP_ARM_26BIT )] = "26bit",
+ [__builtin_ctz(ARM_HWCAP_ARM_FAST_MULT)] = "fast_mult",
+ [__builtin_ctz(ARM_HWCAP_ARM_FPA )] = "fpa",
+ [__builtin_ctz(ARM_HWCAP_ARM_VFP )] = "vfp",
+ [__builtin_ctz(ARM_HWCAP_ARM_EDSP )] = "edsp",
+ [__builtin_ctz(ARM_HWCAP_ARM_JAVA )] = "java",
+ [__builtin_ctz(ARM_HWCAP_ARM_IWMMXT )] = "iwmmxt",
+ [__builtin_ctz(ARM_HWCAP_ARM_CRUNCH )] = "crunch",
+ [__builtin_ctz(ARM_HWCAP_ARM_THUMBEE )] = "thumbee",
+ [__builtin_ctz(ARM_HWCAP_ARM_NEON )] = "neon",
+ [__builtin_ctz(ARM_HWCAP_ARM_VFPv3 )] = "vfpv3",
+ [__builtin_ctz(ARM_HWCAP_ARM_VFPv3D16 )] = "vfpv3d16",
+ [__builtin_ctz(ARM_HWCAP_ARM_TLS )] = "tls",
+ [__builtin_ctz(ARM_HWCAP_ARM_VFPv4 )] = "vfpv4",
+ [__builtin_ctz(ARM_HWCAP_ARM_IDIVA )] = "idiva",
+ [__builtin_ctz(ARM_HWCAP_ARM_IDIVT )] = "idivt",
+ [__builtin_ctz(ARM_HWCAP_ARM_VFPD32 )] = "vfpd32",
+ [__builtin_ctz(ARM_HWCAP_ARM_LPAE )] = "lpae",
+ [__builtin_ctz(ARM_HWCAP_ARM_EVTSTRM )] = "evtstrm",
+ [__builtin_ctz(ARM_HWCAP_ARM_FPHP )] = "fphp",
+ [__builtin_ctz(ARM_HWCAP_ARM_ASIMDHP )] = "asimdhp",
+ [__builtin_ctz(ARM_HWCAP_ARM_ASIMDDP )] = "asimddp",
+ [__builtin_ctz(ARM_HWCAP_ARM_ASIMDFHM )] = "asimdfhm",
+ [__builtin_ctz(ARM_HWCAP_ARM_ASIMDBF16)] = "asimdbf16",
+ [__builtin_ctz(ARM_HWCAP_ARM_I8MM )] = "i8mm",
+ };
+
+ return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
+}
+
+const char *elf_hwcap2_str(uint32_t bit)
+{
+ static const char *hwcap_str[] = {
+ [__builtin_ctz(ARM_HWCAP2_ARM_AES )] = "aes",
+ [__builtin_ctz(ARM_HWCAP2_ARM_PMULL)] = "pmull",
+ [__builtin_ctz(ARM_HWCAP2_ARM_SHA1 )] = "sha1",
+ [__builtin_ctz(ARM_HWCAP2_ARM_SHA2 )] = "sha2",
+ [__builtin_ctz(ARM_HWCAP2_ARM_CRC32)] = "crc32",
+ [__builtin_ctz(ARM_HWCAP2_ARM_SB )] = "sb",
+ [__builtin_ctz(ARM_HWCAP2_ARM_SSBS )] = "ssbs",
+ };
+
+ return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
+}
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 0c62c249e9..149d1313c0 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -401,48 +401,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUARMState *en
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-enum
-{
- ARM_HWCAP_ARM_SWP = 1 << 0,
- ARM_HWCAP_ARM_HALF = 1 << 1,
- ARM_HWCAP_ARM_THUMB = 1 << 2,
- ARM_HWCAP_ARM_26BIT = 1 << 3,
- ARM_HWCAP_ARM_FAST_MULT = 1 << 4,
- ARM_HWCAP_ARM_FPA = 1 << 5,
- ARM_HWCAP_ARM_VFP = 1 << 6,
- ARM_HWCAP_ARM_EDSP = 1 << 7,
- ARM_HWCAP_ARM_JAVA = 1 << 8,
- ARM_HWCAP_ARM_IWMMXT = 1 << 9,
- ARM_HWCAP_ARM_CRUNCH = 1 << 10,
- ARM_HWCAP_ARM_THUMBEE = 1 << 11,
- ARM_HWCAP_ARM_NEON = 1 << 12,
- ARM_HWCAP_ARM_VFPv3 = 1 << 13,
- ARM_HWCAP_ARM_VFPv3D16 = 1 << 14,
- ARM_HWCAP_ARM_TLS = 1 << 15,
- ARM_HWCAP_ARM_VFPv4 = 1 << 16,
- ARM_HWCAP_ARM_IDIVA = 1 << 17,
- ARM_HWCAP_ARM_IDIVT = 1 << 18,
- ARM_HWCAP_ARM_VFPD32 = 1 << 19,
- ARM_HWCAP_ARM_LPAE = 1 << 20,
- ARM_HWCAP_ARM_EVTSTRM = 1 << 21,
- ARM_HWCAP_ARM_FPHP = 1 << 22,
- ARM_HWCAP_ARM_ASIMDHP = 1 << 23,
- ARM_HWCAP_ARM_ASIMDDP = 1 << 24,
- ARM_HWCAP_ARM_ASIMDFHM = 1 << 25,
- ARM_HWCAP_ARM_ASIMDBF16 = 1 << 26,
- ARM_HWCAP_ARM_I8MM = 1 << 27,
-};
-
-enum {
- ARM_HWCAP2_ARM_AES = 1 << 0,
- ARM_HWCAP2_ARM_PMULL = 1 << 1,
- ARM_HWCAP2_ARM_SHA1 = 1 << 2,
- ARM_HWCAP2_ARM_SHA2 = 1 << 3,
- ARM_HWCAP2_ARM_CRC32 = 1 << 4,
- ARM_HWCAP2_ARM_SB = 1 << 5,
- ARM_HWCAP2_ARM_SSBS = 1 << 6,
-};
-
/* The commpage only exists for 32 bit kernels */
#define HI_COMMPAGE (intptr_t)0xffff0f00u
@@ -491,129 +449,8 @@ static bool init_guest_commpage(void)
return true;
}
-#define ELF_HWCAP get_elf_hwcap()
-#define ELF_HWCAP2 get_elf_hwcap2()
-
-uint32_t get_elf_hwcap(void)
-{
- ARMCPU *cpu = ARM_CPU(thread_cpu);
- uint32_t hwcaps = 0;
-
- hwcaps |= ARM_HWCAP_ARM_SWP;
- hwcaps |= ARM_HWCAP_ARM_HALF;
- hwcaps |= ARM_HWCAP_ARM_THUMB;
- hwcaps |= ARM_HWCAP_ARM_FAST_MULT;
-
- /* probe for the extra features */
-#define GET_FEATURE(feat, hwcap) \
- do { if (arm_feature(&cpu->env, feat)) { hwcaps |= hwcap; } } while (0)
-
-#define GET_FEATURE_ID(feat, hwcap) \
- do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
-
- /* EDSP is in v5TE and above, but all our v5 CPUs are v5TE */
- GET_FEATURE(ARM_FEATURE_V5, ARM_HWCAP_ARM_EDSP);
- GET_FEATURE(ARM_FEATURE_IWMMXT, ARM_HWCAP_ARM_IWMMXT);
- GET_FEATURE(ARM_FEATURE_THUMB2EE, ARM_HWCAP_ARM_THUMBEE);
- GET_FEATURE(ARM_FEATURE_NEON, ARM_HWCAP_ARM_NEON);
- GET_FEATURE(ARM_FEATURE_V6K, ARM_HWCAP_ARM_TLS);
- GET_FEATURE(ARM_FEATURE_LPAE, ARM_HWCAP_ARM_LPAE);
- GET_FEATURE_ID(aa32_arm_div, ARM_HWCAP_ARM_IDIVA);
- GET_FEATURE_ID(aa32_thumb_div, ARM_HWCAP_ARM_IDIVT);
- GET_FEATURE_ID(aa32_vfp, ARM_HWCAP_ARM_VFP);
-
- if (cpu_isar_feature(aa32_fpsp_v3, cpu) ||
- cpu_isar_feature(aa32_fpdp_v3, cpu)) {
- hwcaps |= ARM_HWCAP_ARM_VFPv3;
- if (cpu_isar_feature(aa32_simd_r32, cpu)) {
- hwcaps |= ARM_HWCAP_ARM_VFPD32;
- } else {
- hwcaps |= ARM_HWCAP_ARM_VFPv3D16;
- }
- }
- GET_FEATURE_ID(aa32_simdfmac, ARM_HWCAP_ARM_VFPv4);
- /*
- * MVFR1.FPHP and .SIMDHP must be in sync, and QEMU uses the same
- * isar_feature function for both. The kernel reports them as two hwcaps.
- */
- GET_FEATURE_ID(aa32_fp16_arith, ARM_HWCAP_ARM_FPHP);
- GET_FEATURE_ID(aa32_fp16_arith, ARM_HWCAP_ARM_ASIMDHP);
- GET_FEATURE_ID(aa32_dp, ARM_HWCAP_ARM_ASIMDDP);
- GET_FEATURE_ID(aa32_fhm, ARM_HWCAP_ARM_ASIMDFHM);
- GET_FEATURE_ID(aa32_bf16, ARM_HWCAP_ARM_ASIMDBF16);
- GET_FEATURE_ID(aa32_i8mm, ARM_HWCAP_ARM_I8MM);
-
- return hwcaps;
-}
-
-uint64_t get_elf_hwcap2(void)
-{
- ARMCPU *cpu = ARM_CPU(thread_cpu);
- uint64_t hwcaps = 0;
-
- GET_FEATURE_ID(aa32_aes, ARM_HWCAP2_ARM_AES);
- GET_FEATURE_ID(aa32_pmull, ARM_HWCAP2_ARM_PMULL);
- GET_FEATURE_ID(aa32_sha1, ARM_HWCAP2_ARM_SHA1);
- GET_FEATURE_ID(aa32_sha2, ARM_HWCAP2_ARM_SHA2);
- GET_FEATURE_ID(aa32_crc32, ARM_HWCAP2_ARM_CRC32);
- GET_FEATURE_ID(aa32_sb, ARM_HWCAP2_ARM_SB);
- GET_FEATURE_ID(aa32_ssbs, ARM_HWCAP2_ARM_SSBS);
- return hwcaps;
-}
-
-const char *elf_hwcap_str(uint32_t bit)
-{
- static const char *hwcap_str[] = {
- [__builtin_ctz(ARM_HWCAP_ARM_SWP )] = "swp",
- [__builtin_ctz(ARM_HWCAP_ARM_HALF )] = "half",
- [__builtin_ctz(ARM_HWCAP_ARM_THUMB )] = "thumb",
- [__builtin_ctz(ARM_HWCAP_ARM_26BIT )] = "26bit",
- [__builtin_ctz(ARM_HWCAP_ARM_FAST_MULT)] = "fast_mult",
- [__builtin_ctz(ARM_HWCAP_ARM_FPA )] = "fpa",
- [__builtin_ctz(ARM_HWCAP_ARM_VFP )] = "vfp",
- [__builtin_ctz(ARM_HWCAP_ARM_EDSP )] = "edsp",
- [__builtin_ctz(ARM_HWCAP_ARM_JAVA )] = "java",
- [__builtin_ctz(ARM_HWCAP_ARM_IWMMXT )] = "iwmmxt",
- [__builtin_ctz(ARM_HWCAP_ARM_CRUNCH )] = "crunch",
- [__builtin_ctz(ARM_HWCAP_ARM_THUMBEE )] = "thumbee",
- [__builtin_ctz(ARM_HWCAP_ARM_NEON )] = "neon",
- [__builtin_ctz(ARM_HWCAP_ARM_VFPv3 )] = "vfpv3",
- [__builtin_ctz(ARM_HWCAP_ARM_VFPv3D16 )] = "vfpv3d16",
- [__builtin_ctz(ARM_HWCAP_ARM_TLS )] = "tls",
- [__builtin_ctz(ARM_HWCAP_ARM_VFPv4 )] = "vfpv4",
- [__builtin_ctz(ARM_HWCAP_ARM_IDIVA )] = "idiva",
- [__builtin_ctz(ARM_HWCAP_ARM_IDIVT )] = "idivt",
- [__builtin_ctz(ARM_HWCAP_ARM_VFPD32 )] = "vfpd32",
- [__builtin_ctz(ARM_HWCAP_ARM_LPAE )] = "lpae",
- [__builtin_ctz(ARM_HWCAP_ARM_EVTSTRM )] = "evtstrm",
- [__builtin_ctz(ARM_HWCAP_ARM_FPHP )] = "fphp",
- [__builtin_ctz(ARM_HWCAP_ARM_ASIMDHP )] = "asimdhp",
- [__builtin_ctz(ARM_HWCAP_ARM_ASIMDDP )] = "asimddp",
- [__builtin_ctz(ARM_HWCAP_ARM_ASIMDFHM )] = "asimdfhm",
- [__builtin_ctz(ARM_HWCAP_ARM_ASIMDBF16)] = "asimdbf16",
- [__builtin_ctz(ARM_HWCAP_ARM_I8MM )] = "i8mm",
- };
-
- return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
-}
-
-const char *elf_hwcap2_str(uint32_t bit)
-{
- static const char *hwcap_str[] = {
- [__builtin_ctz(ARM_HWCAP2_ARM_AES )] = "aes",
- [__builtin_ctz(ARM_HWCAP2_ARM_PMULL)] = "pmull",
- [__builtin_ctz(ARM_HWCAP2_ARM_SHA1 )] = "sha1",
- [__builtin_ctz(ARM_HWCAP2_ARM_SHA2 )] = "sha2",
- [__builtin_ctz(ARM_HWCAP2_ARM_CRC32)] = "crc32",
- [__builtin_ctz(ARM_HWCAP2_ARM_SB )] = "sb",
- [__builtin_ctz(ARM_HWCAP2_ARM_SSBS )] = "ssbs",
- };
-
- return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
-}
-
-#undef GET_FEATURE
-#undef GET_FEATURE_ID
+#define ELF_HWCAP get_elf_hwcap(thread_cpu)
+#define ELF_HWCAP2 get_elf_hwcap2(thread_cpu)
#define ELF_PLATFORM get_elf_platform()
@@ -702,342 +539,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-enum {
- ARM_HWCAP_A64_FP = 1 << 0,
- ARM_HWCAP_A64_ASIMD = 1 << 1,
- ARM_HWCAP_A64_EVTSTRM = 1 << 2,
- ARM_HWCAP_A64_AES = 1 << 3,
- ARM_HWCAP_A64_PMULL = 1 << 4,
- ARM_HWCAP_A64_SHA1 = 1 << 5,
- ARM_HWCAP_A64_SHA2 = 1 << 6,
- ARM_HWCAP_A64_CRC32 = 1 << 7,
- ARM_HWCAP_A64_ATOMICS = 1 << 8,
- ARM_HWCAP_A64_FPHP = 1 << 9,
- ARM_HWCAP_A64_ASIMDHP = 1 << 10,
- ARM_HWCAP_A64_CPUID = 1 << 11,
- ARM_HWCAP_A64_ASIMDRDM = 1 << 12,
- ARM_HWCAP_A64_JSCVT = 1 << 13,
- ARM_HWCAP_A64_FCMA = 1 << 14,
- ARM_HWCAP_A64_LRCPC = 1 << 15,
- ARM_HWCAP_A64_DCPOP = 1 << 16,
- ARM_HWCAP_A64_SHA3 = 1 << 17,
- ARM_HWCAP_A64_SM3 = 1 << 18,
- ARM_HWCAP_A64_SM4 = 1 << 19,
- ARM_HWCAP_A64_ASIMDDP = 1 << 20,
- ARM_HWCAP_A64_SHA512 = 1 << 21,
- ARM_HWCAP_A64_SVE = 1 << 22,
- ARM_HWCAP_A64_ASIMDFHM = 1 << 23,
- ARM_HWCAP_A64_DIT = 1 << 24,
- ARM_HWCAP_A64_USCAT = 1 << 25,
- ARM_HWCAP_A64_ILRCPC = 1 << 26,
- ARM_HWCAP_A64_FLAGM = 1 << 27,
- ARM_HWCAP_A64_SSBS = 1 << 28,
- ARM_HWCAP_A64_SB = 1 << 29,
- ARM_HWCAP_A64_PACA = 1 << 30,
- ARM_HWCAP_A64_PACG = 1ULL << 31,
- ARM_HWCAP_A64_GCS = 1ULL << 32,
- ARM_HWCAP_A64_CMPBR = 1ULL << 33,
- ARM_HWCAP_A64_FPRCVT = 1ULL << 34,
- ARM_HWCAP_A64_F8MM8 = 1ULL << 35,
- ARM_HWCAP_A64_F8MM4 = 1ULL << 36,
- ARM_HWCAP_A64_SVE_F16MM = 1ULL << 37,
- ARM_HWCAP_A64_SVE_ELTPERM = 1ULL << 38,
- ARM_HWCAP_A64_SVE_AES2 = 1ULL << 39,
- ARM_HWCAP_A64_SVE_BFSCALE = 1ULL << 40,
- ARM_HWCAP_A64_SVE2P2 = 1ULL << 41,
- ARM_HWCAP_A64_SME2P2 = 1ULL << 42,
- ARM_HWCAP_A64_SME_SBITPERM = 1ULL << 43,
- ARM_HWCAP_A64_SME_AES = 1ULL << 44,
- ARM_HWCAP_A64_SME_SFEXPA = 1ULL << 45,
- ARM_HWCAP_A64_SME_STMOP = 1ULL << 46,
- ARM_HWCAP_A64_SME_SMOP4 = 1ULL << 47,
-
- ARM_HWCAP2_A64_DCPODP = 1 << 0,
- ARM_HWCAP2_A64_SVE2 = 1 << 1,
- ARM_HWCAP2_A64_SVEAES = 1 << 2,
- ARM_HWCAP2_A64_SVEPMULL = 1 << 3,
- ARM_HWCAP2_A64_SVEBITPERM = 1 << 4,
- ARM_HWCAP2_A64_SVESHA3 = 1 << 5,
- ARM_HWCAP2_A64_SVESM4 = 1 << 6,
- ARM_HWCAP2_A64_FLAGM2 = 1 << 7,
- ARM_HWCAP2_A64_FRINT = 1 << 8,
- ARM_HWCAP2_A64_SVEI8MM = 1 << 9,
- ARM_HWCAP2_A64_SVEF32MM = 1 << 10,
- ARM_HWCAP2_A64_SVEF64MM = 1 << 11,
- ARM_HWCAP2_A64_SVEBF16 = 1 << 12,
- ARM_HWCAP2_A64_I8MM = 1 << 13,
- ARM_HWCAP2_A64_BF16 = 1 << 14,
- ARM_HWCAP2_A64_DGH = 1 << 15,
- ARM_HWCAP2_A64_RNG = 1 << 16,
- ARM_HWCAP2_A64_BTI = 1 << 17,
- ARM_HWCAP2_A64_MTE = 1 << 18,
- ARM_HWCAP2_A64_ECV = 1 << 19,
- ARM_HWCAP2_A64_AFP = 1 << 20,
- ARM_HWCAP2_A64_RPRES = 1 << 21,
- ARM_HWCAP2_A64_MTE3 = 1 << 22,
- ARM_HWCAP2_A64_SME = 1 << 23,
- ARM_HWCAP2_A64_SME_I16I64 = 1 << 24,
- ARM_HWCAP2_A64_SME_F64F64 = 1 << 25,
- ARM_HWCAP2_A64_SME_I8I32 = 1 << 26,
- ARM_HWCAP2_A64_SME_F16F32 = 1 << 27,
- ARM_HWCAP2_A64_SME_B16F32 = 1 << 28,
- ARM_HWCAP2_A64_SME_F32F32 = 1 << 29,
- ARM_HWCAP2_A64_SME_FA64 = 1 << 30,
- ARM_HWCAP2_A64_WFXT = 1ULL << 31,
- ARM_HWCAP2_A64_EBF16 = 1ULL << 32,
- ARM_HWCAP2_A64_SVE_EBF16 = 1ULL << 33,
- ARM_HWCAP2_A64_CSSC = 1ULL << 34,
- ARM_HWCAP2_A64_RPRFM = 1ULL << 35,
- ARM_HWCAP2_A64_SVE2P1 = 1ULL << 36,
- ARM_HWCAP2_A64_SME2 = 1ULL << 37,
- ARM_HWCAP2_A64_SME2P1 = 1ULL << 38,
- ARM_HWCAP2_A64_SME_I16I32 = 1ULL << 39,
- ARM_HWCAP2_A64_SME_BI32I32 = 1ULL << 40,
- ARM_HWCAP2_A64_SME_B16B16 = 1ULL << 41,
- ARM_HWCAP2_A64_SME_F16F16 = 1ULL << 42,
- ARM_HWCAP2_A64_MOPS = 1ULL << 43,
- ARM_HWCAP2_A64_HBC = 1ULL << 44,
- ARM_HWCAP2_A64_SVE_B16B16 = 1ULL << 45,
- ARM_HWCAP2_A64_LRCPC3 = 1ULL << 46,
- ARM_HWCAP2_A64_LSE128 = 1ULL << 47,
- ARM_HWCAP2_A64_FPMR = 1ULL << 48,
- ARM_HWCAP2_A64_LUT = 1ULL << 49,
- ARM_HWCAP2_A64_FAMINMAX = 1ULL << 50,
- ARM_HWCAP2_A64_F8CVT = 1ULL << 51,
- ARM_HWCAP2_A64_F8FMA = 1ULL << 52,
- ARM_HWCAP2_A64_F8DP4 = 1ULL << 53,
- ARM_HWCAP2_A64_F8DP2 = 1ULL << 54,
- ARM_HWCAP2_A64_F8E4M3 = 1ULL << 55,
- ARM_HWCAP2_A64_F8E5M2 = 1ULL << 56,
- ARM_HWCAP2_A64_SME_LUTV2 = 1ULL << 57,
- ARM_HWCAP2_A64_SME_F8F16 = 1ULL << 58,
- ARM_HWCAP2_A64_SME_F8F32 = 1ULL << 59,
- ARM_HWCAP2_A64_SME_SF8FMA = 1ULL << 60,
- ARM_HWCAP2_A64_SME_SF8DP4 = 1ULL << 61,
- ARM_HWCAP2_A64_SME_SF8DP2 = 1ULL << 62,
- ARM_HWCAP2_A64_POE = 1ULL << 63,
-};
-
-#define ELF_HWCAP get_elf_hwcap()
-#define ELF_HWCAP2 get_elf_hwcap2()
-
-#define GET_FEATURE_ID(feat, hwcap) \
- do { if (cpu_isar_feature(feat, cpu)) { hwcaps |= hwcap; } } while (0)
-
-uint32_t get_elf_hwcap(void)
-{
- ARMCPU *cpu = ARM_CPU(thread_cpu);
- uint32_t hwcaps = 0;
-
- hwcaps |= ARM_HWCAP_A64_FP;
- hwcaps |= ARM_HWCAP_A64_ASIMD;
- hwcaps |= ARM_HWCAP_A64_CPUID;
-
- /* probe for the extra features */
-
- GET_FEATURE_ID(aa64_aes, ARM_HWCAP_A64_AES);
- GET_FEATURE_ID(aa64_pmull, ARM_HWCAP_A64_PMULL);
- GET_FEATURE_ID(aa64_sha1, ARM_HWCAP_A64_SHA1);
- GET_FEATURE_ID(aa64_sha256, ARM_HWCAP_A64_SHA2);
- GET_FEATURE_ID(aa64_sha512, ARM_HWCAP_A64_SHA512);
- GET_FEATURE_ID(aa64_crc32, ARM_HWCAP_A64_CRC32);
- GET_FEATURE_ID(aa64_sha3, ARM_HWCAP_A64_SHA3);
- GET_FEATURE_ID(aa64_sm3, ARM_HWCAP_A64_SM3);
- GET_FEATURE_ID(aa64_sm4, ARM_HWCAP_A64_SM4);
- GET_FEATURE_ID(aa64_fp16, ARM_HWCAP_A64_FPHP | ARM_HWCAP_A64_ASIMDHP);
- GET_FEATURE_ID(aa64_atomics, ARM_HWCAP_A64_ATOMICS);
- GET_FEATURE_ID(aa64_lse2, ARM_HWCAP_A64_USCAT);
- GET_FEATURE_ID(aa64_rdm, ARM_HWCAP_A64_ASIMDRDM);
- GET_FEATURE_ID(aa64_dp, ARM_HWCAP_A64_ASIMDDP);
- GET_FEATURE_ID(aa64_fcma, ARM_HWCAP_A64_FCMA);
- GET_FEATURE_ID(aa64_sve, ARM_HWCAP_A64_SVE);
- GET_FEATURE_ID(aa64_pauth, ARM_HWCAP_A64_PACA | ARM_HWCAP_A64_PACG);
- GET_FEATURE_ID(aa64_fhm, ARM_HWCAP_A64_ASIMDFHM);
- GET_FEATURE_ID(aa64_dit, ARM_HWCAP_A64_DIT);
- GET_FEATURE_ID(aa64_jscvt, ARM_HWCAP_A64_JSCVT);
- GET_FEATURE_ID(aa64_sb, ARM_HWCAP_A64_SB);
- GET_FEATURE_ID(aa64_condm_4, ARM_HWCAP_A64_FLAGM);
- GET_FEATURE_ID(aa64_dcpop, ARM_HWCAP_A64_DCPOP);
- GET_FEATURE_ID(aa64_rcpc_8_3, ARM_HWCAP_A64_LRCPC);
- GET_FEATURE_ID(aa64_rcpc_8_4, ARM_HWCAP_A64_ILRCPC);
-
- return hwcaps;
-}
-
-uint64_t get_elf_hwcap2(void)
-{
- ARMCPU *cpu = ARM_CPU(thread_cpu);
- uint64_t hwcaps = 0;
-
- GET_FEATURE_ID(aa64_dcpodp, ARM_HWCAP2_A64_DCPODP);
- GET_FEATURE_ID(aa64_sve2, ARM_HWCAP2_A64_SVE2);
- GET_FEATURE_ID(aa64_sve2_aes, ARM_HWCAP2_A64_SVEAES);
- GET_FEATURE_ID(aa64_sve2_pmull128, ARM_HWCAP2_A64_SVEPMULL);
- GET_FEATURE_ID(aa64_sve2_bitperm, ARM_HWCAP2_A64_SVEBITPERM);
- GET_FEATURE_ID(aa64_sve2_sha3, ARM_HWCAP2_A64_SVESHA3);
- GET_FEATURE_ID(aa64_sve2_sm4, ARM_HWCAP2_A64_SVESM4);
- GET_FEATURE_ID(aa64_condm_5, ARM_HWCAP2_A64_FLAGM2);
- GET_FEATURE_ID(aa64_frint, ARM_HWCAP2_A64_FRINT);
- GET_FEATURE_ID(aa64_sve_i8mm, ARM_HWCAP2_A64_SVEI8MM);
- GET_FEATURE_ID(aa64_sve_f32mm, ARM_HWCAP2_A64_SVEF32MM);
- GET_FEATURE_ID(aa64_sve_f64mm, ARM_HWCAP2_A64_SVEF64MM);
- GET_FEATURE_ID(aa64_sve_bf16, ARM_HWCAP2_A64_SVEBF16);
- GET_FEATURE_ID(aa64_i8mm, ARM_HWCAP2_A64_I8MM);
- GET_FEATURE_ID(aa64_bf16, ARM_HWCAP2_A64_BF16);
- GET_FEATURE_ID(aa64_rndr, ARM_HWCAP2_A64_RNG);
- GET_FEATURE_ID(aa64_bti, ARM_HWCAP2_A64_BTI);
- GET_FEATURE_ID(aa64_mte, ARM_HWCAP2_A64_MTE);
- GET_FEATURE_ID(aa64_mte3, ARM_HWCAP2_A64_MTE3);
- GET_FEATURE_ID(aa64_sme, (ARM_HWCAP2_A64_SME |
- ARM_HWCAP2_A64_SME_F32F32 |
- ARM_HWCAP2_A64_SME_B16F32 |
- ARM_HWCAP2_A64_SME_F16F32 |
- ARM_HWCAP2_A64_SME_I8I32));
- GET_FEATURE_ID(aa64_sme_f64f64, ARM_HWCAP2_A64_SME_F64F64);
- GET_FEATURE_ID(aa64_sme_i16i64, ARM_HWCAP2_A64_SME_I16I64);
- GET_FEATURE_ID(aa64_sme_fa64, ARM_HWCAP2_A64_SME_FA64);
- GET_FEATURE_ID(aa64_hbc, ARM_HWCAP2_A64_HBC);
- GET_FEATURE_ID(aa64_mops, ARM_HWCAP2_A64_MOPS);
- GET_FEATURE_ID(aa64_sve2p1, ARM_HWCAP2_A64_SVE2P1);
- GET_FEATURE_ID(aa64_sme2, (ARM_HWCAP2_A64_SME2 |
- ARM_HWCAP2_A64_SME_I16I32 |
- ARM_HWCAP2_A64_SME_BI32I32));
- GET_FEATURE_ID(aa64_sme2p1, ARM_HWCAP2_A64_SME2P1);
- GET_FEATURE_ID(aa64_sme_b16b16, ARM_HWCAP2_A64_SME_B16B16);
- GET_FEATURE_ID(aa64_sme_f16f16, ARM_HWCAP2_A64_SME_F16F16);
- GET_FEATURE_ID(aa64_sve_b16b16, ARM_HWCAP2_A64_SVE_B16B16);
-
- return hwcaps;
-}
-
-const char *elf_hwcap_str(uint32_t bit)
-{
- static const char * const hwcap_str[] = {
- [__builtin_ctz(ARM_HWCAP_A64_FP )] = "fp",
- [__builtin_ctz(ARM_HWCAP_A64_ASIMD )] = "asimd",
- [__builtin_ctz(ARM_HWCAP_A64_EVTSTRM )] = "evtstrm",
- [__builtin_ctz(ARM_HWCAP_A64_AES )] = "aes",
- [__builtin_ctz(ARM_HWCAP_A64_PMULL )] = "pmull",
- [__builtin_ctz(ARM_HWCAP_A64_SHA1 )] = "sha1",
- [__builtin_ctz(ARM_HWCAP_A64_SHA2 )] = "sha2",
- [__builtin_ctz(ARM_HWCAP_A64_CRC32 )] = "crc32",
- [__builtin_ctz(ARM_HWCAP_A64_ATOMICS )] = "atomics",
- [__builtin_ctz(ARM_HWCAP_A64_FPHP )] = "fphp",
- [__builtin_ctz(ARM_HWCAP_A64_ASIMDHP )] = "asimdhp",
- [__builtin_ctz(ARM_HWCAP_A64_CPUID )] = "cpuid",
- [__builtin_ctz(ARM_HWCAP_A64_ASIMDRDM)] = "asimdrdm",
- [__builtin_ctz(ARM_HWCAP_A64_JSCVT )] = "jscvt",
- [__builtin_ctz(ARM_HWCAP_A64_FCMA )] = "fcma",
- [__builtin_ctz(ARM_HWCAP_A64_LRCPC )] = "lrcpc",
- [__builtin_ctz(ARM_HWCAP_A64_DCPOP )] = "dcpop",
- [__builtin_ctz(ARM_HWCAP_A64_SHA3 )] = "sha3",
- [__builtin_ctz(ARM_HWCAP_A64_SM3 )] = "sm3",
- [__builtin_ctz(ARM_HWCAP_A64_SM4 )] = "sm4",
- [__builtin_ctz(ARM_HWCAP_A64_ASIMDDP )] = "asimddp",
- [__builtin_ctz(ARM_HWCAP_A64_SHA512 )] = "sha512",
- [__builtin_ctz(ARM_HWCAP_A64_SVE )] = "sve",
- [__builtin_ctz(ARM_HWCAP_A64_ASIMDFHM)] = "asimdfhm",
- [__builtin_ctz(ARM_HWCAP_A64_DIT )] = "dit",
- [__builtin_ctz(ARM_HWCAP_A64_USCAT )] = "uscat",
- [__builtin_ctz(ARM_HWCAP_A64_ILRCPC )] = "ilrcpc",
- [__builtin_ctz(ARM_HWCAP_A64_FLAGM )] = "flagm",
- [__builtin_ctz(ARM_HWCAP_A64_SSBS )] = "ssbs",
- [__builtin_ctz(ARM_HWCAP_A64_SB )] = "sb",
- [__builtin_ctz(ARM_HWCAP_A64_PACA )] = "paca",
- [__builtin_ctz(ARM_HWCAP_A64_PACG )] = "pacg",
- [__builtin_ctzll(ARM_HWCAP_A64_GCS )] = "gcs",
- [__builtin_ctzll(ARM_HWCAP_A64_CMPBR )] = "cmpbr",
- [__builtin_ctzll(ARM_HWCAP_A64_FPRCVT)] = "fprcvt",
- [__builtin_ctzll(ARM_HWCAP_A64_F8MM8 )] = "f8mm8",
- [__builtin_ctzll(ARM_HWCAP_A64_F8MM4 )] = "f8mm4",
- [__builtin_ctzll(ARM_HWCAP_A64_SVE_F16MM)] = "svef16mm",
- [__builtin_ctzll(ARM_HWCAP_A64_SVE_ELTPERM)] = "sveeltperm",
- [__builtin_ctzll(ARM_HWCAP_A64_SVE_AES2)] = "sveaes2",
- [__builtin_ctzll(ARM_HWCAP_A64_SVE_BFSCALE)] = "svebfscale",
- [__builtin_ctzll(ARM_HWCAP_A64_SVE2P2)] = "sve2p2",
- [__builtin_ctzll(ARM_HWCAP_A64_SME2P2)] = "sme2p2",
- [__builtin_ctzll(ARM_HWCAP_A64_SME_SBITPERM)] = "smesbitperm",
- [__builtin_ctzll(ARM_HWCAP_A64_SME_AES)] = "smeaes",
- [__builtin_ctzll(ARM_HWCAP_A64_SME_SFEXPA)] = "smesfexpa",
- [__builtin_ctzll(ARM_HWCAP_A64_SME_STMOP)] = "smestmop",
- [__builtin_ctzll(ARM_HWCAP_A64_SME_SMOP4)] = "smesmop4",
- };
-
- return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
-}
-
-const char *elf_hwcap2_str(uint32_t bit)
-{
- static const char * const hwcap_str[] = {
- [__builtin_ctz(ARM_HWCAP2_A64_DCPODP )] = "dcpodp",
- [__builtin_ctz(ARM_HWCAP2_A64_SVE2 )] = "sve2",
- [__builtin_ctz(ARM_HWCAP2_A64_SVEAES )] = "sveaes",
- [__builtin_ctz(ARM_HWCAP2_A64_SVEPMULL )] = "svepmull",
- [__builtin_ctz(ARM_HWCAP2_A64_SVEBITPERM )] = "svebitperm",
- [__builtin_ctz(ARM_HWCAP2_A64_SVESHA3 )] = "svesha3",
- [__builtin_ctz(ARM_HWCAP2_A64_SVESM4 )] = "svesm4",
- [__builtin_ctz(ARM_HWCAP2_A64_FLAGM2 )] = "flagm2",
- [__builtin_ctz(ARM_HWCAP2_A64_FRINT )] = "frint",
- [__builtin_ctz(ARM_HWCAP2_A64_SVEI8MM )] = "svei8mm",
- [__builtin_ctz(ARM_HWCAP2_A64_SVEF32MM )] = "svef32mm",
- [__builtin_ctz(ARM_HWCAP2_A64_SVEF64MM )] = "svef64mm",
- [__builtin_ctz(ARM_HWCAP2_A64_SVEBF16 )] = "svebf16",
- [__builtin_ctz(ARM_HWCAP2_A64_I8MM )] = "i8mm",
- [__builtin_ctz(ARM_HWCAP2_A64_BF16 )] = "bf16",
- [__builtin_ctz(ARM_HWCAP2_A64_DGH )] = "dgh",
- [__builtin_ctz(ARM_HWCAP2_A64_RNG )] = "rng",
- [__builtin_ctz(ARM_HWCAP2_A64_BTI )] = "bti",
- [__builtin_ctz(ARM_HWCAP2_A64_MTE )] = "mte",
- [__builtin_ctz(ARM_HWCAP2_A64_ECV )] = "ecv",
- [__builtin_ctz(ARM_HWCAP2_A64_AFP )] = "afp",
- [__builtin_ctz(ARM_HWCAP2_A64_RPRES )] = "rpres",
- [__builtin_ctz(ARM_HWCAP2_A64_MTE3 )] = "mte3",
- [__builtin_ctz(ARM_HWCAP2_A64_SME )] = "sme",
- [__builtin_ctz(ARM_HWCAP2_A64_SME_I16I64 )] = "smei16i64",
- [__builtin_ctz(ARM_HWCAP2_A64_SME_F64F64 )] = "smef64f64",
- [__builtin_ctz(ARM_HWCAP2_A64_SME_I8I32 )] = "smei8i32",
- [__builtin_ctz(ARM_HWCAP2_A64_SME_F16F32 )] = "smef16f32",
- [__builtin_ctz(ARM_HWCAP2_A64_SME_B16F32 )] = "smeb16f32",
- [__builtin_ctz(ARM_HWCAP2_A64_SME_F32F32 )] = "smef32f32",
- [__builtin_ctz(ARM_HWCAP2_A64_SME_FA64 )] = "smefa64",
- [__builtin_ctz(ARM_HWCAP2_A64_WFXT )] = "wfxt",
- [__builtin_ctzll(ARM_HWCAP2_A64_EBF16 )] = "ebf16",
- [__builtin_ctzll(ARM_HWCAP2_A64_SVE_EBF16 )] = "sveebf16",
- [__builtin_ctzll(ARM_HWCAP2_A64_CSSC )] = "cssc",
- [__builtin_ctzll(ARM_HWCAP2_A64_RPRFM )] = "rprfm",
- [__builtin_ctzll(ARM_HWCAP2_A64_SVE2P1 )] = "sve2p1",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME2 )] = "sme2",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME2P1 )] = "sme2p1",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME_I16I32 )] = "smei16i32",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME_BI32I32)] = "smebi32i32",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME_B16B16 )] = "smeb16b16",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME_F16F16 )] = "smef16f16",
- [__builtin_ctzll(ARM_HWCAP2_A64_MOPS )] = "mops",
- [__builtin_ctzll(ARM_HWCAP2_A64_HBC )] = "hbc",
- [__builtin_ctzll(ARM_HWCAP2_A64_SVE_B16B16 )] = "sveb16b16",
- [__builtin_ctzll(ARM_HWCAP2_A64_LRCPC3 )] = "lrcpc3",
- [__builtin_ctzll(ARM_HWCAP2_A64_LSE128 )] = "lse128",
- [__builtin_ctzll(ARM_HWCAP2_A64_FPMR )] = "fpmr",
- [__builtin_ctzll(ARM_HWCAP2_A64_LUT )] = "lut",
- [__builtin_ctzll(ARM_HWCAP2_A64_FAMINMAX )] = "faminmax",
- [__builtin_ctzll(ARM_HWCAP2_A64_F8CVT )] = "f8cvt",
- [__builtin_ctzll(ARM_HWCAP2_A64_F8FMA )] = "f8fma",
- [__builtin_ctzll(ARM_HWCAP2_A64_F8DP4 )] = "f8dp4",
- [__builtin_ctzll(ARM_HWCAP2_A64_F8DP2 )] = "f8dp2",
- [__builtin_ctzll(ARM_HWCAP2_A64_F8E4M3 )] = "f8e4m3",
- [__builtin_ctzll(ARM_HWCAP2_A64_F8E5M2 )] = "f8e5m2",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME_LUTV2 )] = "smelutv2",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME_F8F16 )] = "smef8f16",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME_F8F32 )] = "smef8f32",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME_SF8DP4 )] = "smesf8dp4",
- [__builtin_ctzll(ARM_HWCAP2_A64_SME_SF8DP2 )] = "smesf8dp2",
- [__builtin_ctzll(ARM_HWCAP2_A64_POE )] = "poe",
- };
-
- return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
-}
-
-#undef GET_FEATURE_ID
+#define ELF_HWCAP get_elf_hwcap(thread_cpu)
+#define ELF_HWCAP2 get_elf_hwcap2(thread_cpu)
#if TARGET_BIG_ENDIAN
# define VDSO_HEADER "vdso-be.c.inc"
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 08/46] linux-user: Move get_elf_hwcap to sparc/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (6 preceding siblings ...)
2025-08-27 23:19 ` [PULL 07/46] linux-user: Move hwcap functions to {arm, aarch64}/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 09/46] linux-user: Move hwcap functions to ppc/elfload.c Richard Henderson
` (38 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Change the return type to abi_ulong, and pass in the cpu.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loader.h | 3 ++-
linux-user/sparc/target_elf.h | 2 ++
linux-user/elfload.c | 30 +-----------------------------
linux-user/sparc/elfload.c | 27 +++++++++++++++++++++++++++
4 files changed, 32 insertions(+), 30 deletions(-)
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 151a06f5db..2c8414e0e5 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -101,7 +101,8 @@ extern unsigned long guest_stack_size;
/* Note that Elf32 and Elf64 use uint32_t for e_flags. */
const char *get_elf_cpu_model(uint32_t eflags);
-#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_ARM)
+#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_ARM) \
+ || defined(TARGET_SPARC)
abi_ulong get_elf_hwcap(CPUState *cs);
abi_ulong get_elf_hwcap2(CPUState *cs);
#endif
diff --git a/linux-user/sparc/target_elf.h b/linux-user/sparc/target_elf.h
index 7e46748d26..b7544db0a1 100644
--- a/linux-user/sparc/target_elf.h
+++ b/linux-user/sparc/target_elf.h
@@ -8,4 +8,6 @@
#ifndef SPARC_TARGET_ELF_H
#define SPARC_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 149d1313c0..16709865f7 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -565,35 +565,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
# define ELF_ARCH EM_SPARCV9
#endif
-#include "elf.h"
-
-#define ELF_HWCAP get_elf_hwcap()
-
-static uint32_t get_elf_hwcap(void)
-{
- /* There are not many sparc32 hwcap bits -- we have all of them. */
- uint32_t r = HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
- HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV;
-
-#ifdef TARGET_SPARC64
- CPUSPARCState *env = cpu_env(thread_cpu);
- uint32_t features = env->def.features;
-
- r |= HWCAP_SPARC_V9 | HWCAP_SPARC_V8PLUS;
- /* 32x32 multiply and divide are efficient. */
- r |= HWCAP_SPARC_MUL32 | HWCAP_SPARC_DIV32;
- /* We don't have an internal feature bit for this. */
- r |= HWCAP_SPARC_POPC;
- r |= features & CPU_FEATURE_FSMULD ? HWCAP_SPARC_FSMULD : 0;
- r |= features & CPU_FEATURE_VIS1 ? HWCAP_SPARC_VIS : 0;
- r |= features & CPU_FEATURE_VIS2 ? HWCAP_SPARC_VIS2 : 0;
- r |= features & CPU_FEATURE_FMAF ? HWCAP_SPARC_FMAF : 0;
- r |= features & CPU_FEATURE_VIS3 ? HWCAP_SPARC_VIS3 : 0;
- r |= features & CPU_FEATURE_IMA ? HWCAP_SPARC_IMA : 0;
-#endif
-
- return r;
-}
+#define ELF_HWCAP get_elf_hwcap(thread_cpu)
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
diff --git a/linux-user/sparc/elfload.c b/linux-user/sparc/elfload.c
index 243e6f9b66..32ca1b05b1 100644
--- a/linux-user/sparc/elfload.c
+++ b/linux-user/sparc/elfload.c
@@ -3,6 +3,7 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
+#include "elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@@ -13,3 +14,29 @@ const char *get_elf_cpu_model(uint32_t eflags)
return "Fujitsu MB86904";
#endif
}
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+ /* There are not many sparc32 hwcap bits -- we have all of them. */
+ uint32_t r = HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR |
+ HWCAP_SPARC_SWAP | HWCAP_SPARC_MULDIV;
+
+#ifdef TARGET_SPARC64
+ CPUSPARCState *env = cpu_env(cs);
+ uint32_t features = env->def.features;
+
+ r |= HWCAP_SPARC_V9 | HWCAP_SPARC_V8PLUS;
+ /* 32x32 multiply and divide are efficient. */
+ r |= HWCAP_SPARC_MUL32 | HWCAP_SPARC_DIV32;
+ /* We don't have an internal feature bit for this. */
+ r |= HWCAP_SPARC_POPC;
+ r |= features & CPU_FEATURE_FSMULD ? HWCAP_SPARC_FSMULD : 0;
+ r |= features & CPU_FEATURE_VIS1 ? HWCAP_SPARC_VIS : 0;
+ r |= features & CPU_FEATURE_VIS2 ? HWCAP_SPARC_VIS2 : 0;
+ r |= features & CPU_FEATURE_FMAF ? HWCAP_SPARC_FMAF : 0;
+ r |= features & CPU_FEATURE_VIS3 ? HWCAP_SPARC_VIS3 : 0;
+ r |= features & CPU_FEATURE_IMA ? HWCAP_SPARC_IMA : 0;
+#endif
+
+ return r;
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 09/46] linux-user: Move hwcap functions to ppc/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (7 preceding siblings ...)
2025-08-27 23:19 ` [PULL 08/46] linux-user: Move get_elf_hwcap to sparc/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 10/46] linux-user: Move get_elf_hwcap to loongarch64/elfload.c Richard Henderson
` (37 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Change the return type to abi_ulong, and pass in the cpu.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loader.h | 2 +-
linux-user/ppc/target_elf.h | 3 +
linux-user/elfload.c | 116 +-----------------------------------
linux-user/ppc/elfload.c | 116 ++++++++++++++++++++++++++++++++++++
4 files changed, 122 insertions(+), 115 deletions(-)
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 2c8414e0e5..818c5e6d7d 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -102,7 +102,7 @@ extern unsigned long guest_stack_size;
const char *get_elf_cpu_model(uint32_t eflags);
#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_ARM) \
- || defined(TARGET_SPARC)
+ || defined(TARGET_SPARC) || defined(TARGET_PPC)
abi_ulong get_elf_hwcap(CPUState *cs);
abi_ulong get_elf_hwcap2(CPUState *cs);
#endif
diff --git a/linux-user/ppc/target_elf.h b/linux-user/ppc/target_elf.h
index 8c0a8ea431..4203a89d66 100644
--- a/linux-user/ppc/target_elf.h
+++ b/linux-user/ppc/target_elf.h
@@ -8,4 +8,7 @@
#ifndef PPC_TARGET_ELF_H
#define PPC_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+#define HAVE_ELF_HWCAP2 1
+
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 16709865f7..843b1f7b6c 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -598,120 +598,8 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_ARCH EM_PPC
-/* Feature masks for the Aux Vector Hardware Capabilities (AT_HWCAP).
- See arch/powerpc/include/asm/cputable.h. */
-enum {
- QEMU_PPC_FEATURE_32 = 0x80000000,
- QEMU_PPC_FEATURE_64 = 0x40000000,
- QEMU_PPC_FEATURE_601_INSTR = 0x20000000,
- QEMU_PPC_FEATURE_HAS_ALTIVEC = 0x10000000,
- QEMU_PPC_FEATURE_HAS_FPU = 0x08000000,
- QEMU_PPC_FEATURE_HAS_MMU = 0x04000000,
- QEMU_PPC_FEATURE_HAS_4xxMAC = 0x02000000,
- QEMU_PPC_FEATURE_UNIFIED_CACHE = 0x01000000,
- QEMU_PPC_FEATURE_HAS_SPE = 0x00800000,
- QEMU_PPC_FEATURE_HAS_EFP_SINGLE = 0x00400000,
- QEMU_PPC_FEATURE_HAS_EFP_DOUBLE = 0x00200000,
- QEMU_PPC_FEATURE_NO_TB = 0x00100000,
- QEMU_PPC_FEATURE_POWER4 = 0x00080000,
- QEMU_PPC_FEATURE_POWER5 = 0x00040000,
- QEMU_PPC_FEATURE_POWER5_PLUS = 0x00020000,
- QEMU_PPC_FEATURE_CELL = 0x00010000,
- QEMU_PPC_FEATURE_BOOKE = 0x00008000,
- QEMU_PPC_FEATURE_SMT = 0x00004000,
- QEMU_PPC_FEATURE_ICACHE_SNOOP = 0x00002000,
- QEMU_PPC_FEATURE_ARCH_2_05 = 0x00001000,
- QEMU_PPC_FEATURE_PA6T = 0x00000800,
- QEMU_PPC_FEATURE_HAS_DFP = 0x00000400,
- QEMU_PPC_FEATURE_POWER6_EXT = 0x00000200,
- QEMU_PPC_FEATURE_ARCH_2_06 = 0x00000100,
- QEMU_PPC_FEATURE_HAS_VSX = 0x00000080,
- QEMU_PPC_FEATURE_PSERIES_PERFMON_COMPAT = 0x00000040,
-
- QEMU_PPC_FEATURE_TRUE_LE = 0x00000002,
- QEMU_PPC_FEATURE_PPC_LE = 0x00000001,
-
- /* Feature definitions in AT_HWCAP2. */
- QEMU_PPC_FEATURE2_ARCH_2_07 = 0x80000000, /* ISA 2.07 */
- QEMU_PPC_FEATURE2_HAS_HTM = 0x40000000, /* Hardware Transactional Memory */
- QEMU_PPC_FEATURE2_HAS_DSCR = 0x20000000, /* Data Stream Control Register */
- QEMU_PPC_FEATURE2_HAS_EBB = 0x10000000, /* Event Base Branching */
- QEMU_PPC_FEATURE2_HAS_ISEL = 0x08000000, /* Integer Select */
- QEMU_PPC_FEATURE2_HAS_TAR = 0x04000000, /* Target Address Register */
- QEMU_PPC_FEATURE2_VEC_CRYPTO = 0x02000000,
- QEMU_PPC_FEATURE2_HTM_NOSC = 0x01000000,
- QEMU_PPC_FEATURE2_ARCH_3_00 = 0x00800000, /* ISA 3.00 */
- QEMU_PPC_FEATURE2_HAS_IEEE128 = 0x00400000, /* VSX IEEE Bin Float 128-bit */
- QEMU_PPC_FEATURE2_DARN = 0x00200000, /* darn random number insn */
- QEMU_PPC_FEATURE2_SCV = 0x00100000, /* scv syscall */
- QEMU_PPC_FEATURE2_HTM_NO_SUSPEND = 0x00080000, /* TM w/o suspended state */
- QEMU_PPC_FEATURE2_ARCH_3_1 = 0x00040000, /* ISA 3.1 */
- QEMU_PPC_FEATURE2_MMA = 0x00020000, /* Matrix-Multiply Assist */
-};
-
-#define ELF_HWCAP get_elf_hwcap()
-
-static uint32_t get_elf_hwcap(void)
-{
- PowerPCCPU *cpu = POWERPC_CPU(thread_cpu);
- uint32_t features = 0;
-
- /* We don't have to be terribly complete here; the high points are
- Altivec/FP/SPE support. Anything else is just a bonus. */
-#define GET_FEATURE(flag, feature) \
- do { if (cpu->env.insns_flags & flag) { features |= feature; } } while (0)
-#define GET_FEATURE2(flags, feature) \
- do { \
- if ((cpu->env.insns_flags2 & flags) == flags) { \
- features |= feature; \
- } \
- } while (0)
- GET_FEATURE(PPC_64B, QEMU_PPC_FEATURE_64);
- GET_FEATURE(PPC_FLOAT, QEMU_PPC_FEATURE_HAS_FPU);
- GET_FEATURE(PPC_ALTIVEC, QEMU_PPC_FEATURE_HAS_ALTIVEC);
- GET_FEATURE(PPC_SPE, QEMU_PPC_FEATURE_HAS_SPE);
- GET_FEATURE(PPC_SPE_SINGLE, QEMU_PPC_FEATURE_HAS_EFP_SINGLE);
- GET_FEATURE(PPC_SPE_DOUBLE, QEMU_PPC_FEATURE_HAS_EFP_DOUBLE);
- GET_FEATURE(PPC_BOOKE, QEMU_PPC_FEATURE_BOOKE);
- GET_FEATURE(PPC_405_MAC, QEMU_PPC_FEATURE_HAS_4xxMAC);
- GET_FEATURE2(PPC2_DFP, QEMU_PPC_FEATURE_HAS_DFP);
- GET_FEATURE2(PPC2_VSX, QEMU_PPC_FEATURE_HAS_VSX);
- GET_FEATURE2((PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 |
- PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206),
- QEMU_PPC_FEATURE_ARCH_2_06);
-#undef GET_FEATURE
-#undef GET_FEATURE2
-
- return features;
-}
-
-#define ELF_HWCAP2 get_elf_hwcap2()
-
-static uint32_t get_elf_hwcap2(void)
-{
- PowerPCCPU *cpu = POWERPC_CPU(thread_cpu);
- uint32_t features = 0;
-
-#define GET_FEATURE(flag, feature) \
- do { if (cpu->env.insns_flags & flag) { features |= feature; } } while (0)
-#define GET_FEATURE2(flag, feature) \
- do { if (cpu->env.insns_flags2 & flag) { features |= feature; } } while (0)
-
- GET_FEATURE(PPC_ISEL, QEMU_PPC_FEATURE2_HAS_ISEL);
- GET_FEATURE2(PPC2_BCTAR_ISA207, QEMU_PPC_FEATURE2_HAS_TAR);
- GET_FEATURE2((PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
- PPC2_ISA207S), QEMU_PPC_FEATURE2_ARCH_2_07 |
- QEMU_PPC_FEATURE2_VEC_CRYPTO);
- GET_FEATURE2(PPC2_ISA300, QEMU_PPC_FEATURE2_ARCH_3_00 |
- QEMU_PPC_FEATURE2_DARN | QEMU_PPC_FEATURE2_HAS_IEEE128);
- GET_FEATURE2(PPC2_ISA310, QEMU_PPC_FEATURE2_ARCH_3_1 |
- QEMU_PPC_FEATURE2_MMA);
-
-#undef GET_FEATURE
-#undef GET_FEATURE2
-
- return features;
-}
+#define ELF_HWCAP get_elf_hwcap(thread_cpu)
+#define ELF_HWCAP2 get_elf_hwcap2(thread_cpu)
/*
* The requirements here are:
diff --git a/linux-user/ppc/elfload.c b/linux-user/ppc/elfload.c
index 7775dc06fa..a214675650 100644
--- a/linux-user/ppc/elfload.c
+++ b/linux-user/ppc/elfload.c
@@ -13,3 +13,119 @@ const char *get_elf_cpu_model(uint32_t eflags)
return "750";
#endif
}
+
+/*
+ * Feature masks for the Aux Vector Hardware Capabilities (AT_HWCAP).
+ * See arch/powerpc/include/asm/cputable.h.
+ */
+enum {
+ QEMU_PPC_FEATURE_32 = 0x80000000,
+ QEMU_PPC_FEATURE_64 = 0x40000000,
+ QEMU_PPC_FEATURE_601_INSTR = 0x20000000,
+ QEMU_PPC_FEATURE_HAS_ALTIVEC = 0x10000000,
+ QEMU_PPC_FEATURE_HAS_FPU = 0x08000000,
+ QEMU_PPC_FEATURE_HAS_MMU = 0x04000000,
+ QEMU_PPC_FEATURE_HAS_4xxMAC = 0x02000000,
+ QEMU_PPC_FEATURE_UNIFIED_CACHE = 0x01000000,
+ QEMU_PPC_FEATURE_HAS_SPE = 0x00800000,
+ QEMU_PPC_FEATURE_HAS_EFP_SINGLE = 0x00400000,
+ QEMU_PPC_FEATURE_HAS_EFP_DOUBLE = 0x00200000,
+ QEMU_PPC_FEATURE_NO_TB = 0x00100000,
+ QEMU_PPC_FEATURE_POWER4 = 0x00080000,
+ QEMU_PPC_FEATURE_POWER5 = 0x00040000,
+ QEMU_PPC_FEATURE_POWER5_PLUS = 0x00020000,
+ QEMU_PPC_FEATURE_CELL = 0x00010000,
+ QEMU_PPC_FEATURE_BOOKE = 0x00008000,
+ QEMU_PPC_FEATURE_SMT = 0x00004000,
+ QEMU_PPC_FEATURE_ICACHE_SNOOP = 0x00002000,
+ QEMU_PPC_FEATURE_ARCH_2_05 = 0x00001000,
+ QEMU_PPC_FEATURE_PA6T = 0x00000800,
+ QEMU_PPC_FEATURE_HAS_DFP = 0x00000400,
+ QEMU_PPC_FEATURE_POWER6_EXT = 0x00000200,
+ QEMU_PPC_FEATURE_ARCH_2_06 = 0x00000100,
+ QEMU_PPC_FEATURE_HAS_VSX = 0x00000080,
+ QEMU_PPC_FEATURE_PSERIES_PERFMON_COMPAT = 0x00000040,
+
+ QEMU_PPC_FEATURE_TRUE_LE = 0x00000002,
+ QEMU_PPC_FEATURE_PPC_LE = 0x00000001,
+
+ /* Feature definitions in AT_HWCAP2. */
+ QEMU_PPC_FEATURE2_ARCH_2_07 = 0x80000000, /* ISA 2.07 */
+ QEMU_PPC_FEATURE2_HAS_HTM = 0x40000000, /* Hardware Transactional Memory */
+ QEMU_PPC_FEATURE2_HAS_DSCR = 0x20000000, /* Data Stream Control Register */
+ QEMU_PPC_FEATURE2_HAS_EBB = 0x10000000, /* Event Base Branching */
+ QEMU_PPC_FEATURE2_HAS_ISEL = 0x08000000, /* Integer Select */
+ QEMU_PPC_FEATURE2_HAS_TAR = 0x04000000, /* Target Address Register */
+ QEMU_PPC_FEATURE2_VEC_CRYPTO = 0x02000000,
+ QEMU_PPC_FEATURE2_HTM_NOSC = 0x01000000,
+ QEMU_PPC_FEATURE2_ARCH_3_00 = 0x00800000, /* ISA 3.00 */
+ QEMU_PPC_FEATURE2_HAS_IEEE128 = 0x00400000, /* VSX IEEE Bin Float 128-bit */
+ QEMU_PPC_FEATURE2_DARN = 0x00200000, /* darn random number insn */
+ QEMU_PPC_FEATURE2_SCV = 0x00100000, /* scv syscall */
+ QEMU_PPC_FEATURE2_HTM_NO_SUSPEND = 0x00080000, /* TM w/o suspended state */
+ QEMU_PPC_FEATURE2_ARCH_3_1 = 0x00040000, /* ISA 3.1 */
+ QEMU_PPC_FEATURE2_MMA = 0x00020000, /* Matrix-Multiply Assist */
+};
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ uint32_t features = 0;
+
+ /*
+ * We don't have to be terribly complete here; the high points are
+ * Altivec/FP/SPE support. Anything else is just a bonus.
+ */
+#define GET_FEATURE(flag, feature) \
+ do { if (cpu->env.insns_flags & flag) { features |= feature; } } while (0)
+#define GET_FEATURE2(flags, feature) \
+ do { \
+ if ((cpu->env.insns_flags2 & flags) == flags) { \
+ features |= feature; \
+ } \
+ } while (0)
+ GET_FEATURE(PPC_64B, QEMU_PPC_FEATURE_64);
+ GET_FEATURE(PPC_FLOAT, QEMU_PPC_FEATURE_HAS_FPU);
+ GET_FEATURE(PPC_ALTIVEC, QEMU_PPC_FEATURE_HAS_ALTIVEC);
+ GET_FEATURE(PPC_SPE, QEMU_PPC_FEATURE_HAS_SPE);
+ GET_FEATURE(PPC_SPE_SINGLE, QEMU_PPC_FEATURE_HAS_EFP_SINGLE);
+ GET_FEATURE(PPC_SPE_DOUBLE, QEMU_PPC_FEATURE_HAS_EFP_DOUBLE);
+ GET_FEATURE(PPC_BOOKE, QEMU_PPC_FEATURE_BOOKE);
+ GET_FEATURE(PPC_405_MAC, QEMU_PPC_FEATURE_HAS_4xxMAC);
+ GET_FEATURE2(PPC2_DFP, QEMU_PPC_FEATURE_HAS_DFP);
+ GET_FEATURE2(PPC2_VSX, QEMU_PPC_FEATURE_HAS_VSX);
+ GET_FEATURE2((PPC2_PERM_ISA206 | PPC2_DIVE_ISA206 | PPC2_ATOMIC_ISA206 |
+ PPC2_FP_CVT_ISA206 | PPC2_FP_TST_ISA206),
+ QEMU_PPC_FEATURE_ARCH_2_06);
+
+#undef GET_FEATURE
+#undef GET_FEATURE2
+
+ return features;
+}
+
+abi_ulong get_elf_hwcap2(CPUState *cs)
+{
+ PowerPCCPU *cpu = POWERPC_CPU(cs);
+ uint32_t features = 0;
+
+#define GET_FEATURE(flag, feature) \
+ do { if (cpu->env.insns_flags & flag) { features |= feature; } } while (0)
+#define GET_FEATURE2(flag, feature) \
+ do { if (cpu->env.insns_flags2 & flag) { features |= feature; } } while (0)
+
+ GET_FEATURE(PPC_ISEL, QEMU_PPC_FEATURE2_HAS_ISEL);
+ GET_FEATURE2(PPC2_BCTAR_ISA207, QEMU_PPC_FEATURE2_HAS_TAR);
+ GET_FEATURE2((PPC2_BCTAR_ISA207 | PPC2_LSQ_ISA207 | PPC2_ALTIVEC_207 |
+ PPC2_ISA207S), QEMU_PPC_FEATURE2_ARCH_2_07 |
+ QEMU_PPC_FEATURE2_VEC_CRYPTO);
+ GET_FEATURE2(PPC2_ISA300, QEMU_PPC_FEATURE2_ARCH_3_00 |
+ QEMU_PPC_FEATURE2_DARN | QEMU_PPC_FEATURE2_HAS_IEEE128);
+ GET_FEATURE2(PPC2_ISA310, QEMU_PPC_FEATURE2_ARCH_3_1 |
+ QEMU_PPC_FEATURE2_MMA);
+
+#undef GET_FEATURE
+#undef GET_FEATURE2
+
+ return features;
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 10/46] linux-user: Move get_elf_hwcap to loongarch64/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (8 preceding siblings ...)
2025-08-27 23:19 ` [PULL 09/46] linux-user: Move hwcap functions to ppc/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 11/46] linux-user: Move get_elf_hwcap to mips/elfload.c Richard Henderson
` (36 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Change the return type to abi_ulong, and pass in the cpu.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loader.h | 3 +-
linux-user/loongarch64/target_elf.h | 2 ++
linux-user/elfload.c | 49 +----------------------------
linux-user/loongarch64/elfload.c | 47 +++++++++++++++++++++++++++
4 files changed, 52 insertions(+), 49 deletions(-)
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 818c5e6d7d..92b6d41145 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -102,7 +102,8 @@ extern unsigned long guest_stack_size;
const char *get_elf_cpu_model(uint32_t eflags);
#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_ARM) \
- || defined(TARGET_SPARC) || defined(TARGET_PPC)
+ || defined(TARGET_SPARC) || defined(TARGET_PPC) \
+ || defined(TARGET_LOONGARCH64)
abi_ulong get_elf_hwcap(CPUState *cs);
abi_ulong get_elf_hwcap2(CPUState *cs);
#endif
diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h
index 39a08d35d9..037740d36f 100644
--- a/linux-user/loongarch64/target_elf.h
+++ b/linux-user/loongarch64/target_elf.h
@@ -6,4 +6,6 @@
#ifndef LOONGARCH_TARGET_ELF_H
#define LOONGARCH_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 843b1f7b6c..574b37a22c 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -725,54 +725,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-#define ELF_HWCAP get_elf_hwcap()
-
-/* See arch/loongarch/include/uapi/asm/hwcap.h */
-enum {
- HWCAP_LOONGARCH_CPUCFG = (1 << 0),
- HWCAP_LOONGARCH_LAM = (1 << 1),
- HWCAP_LOONGARCH_UAL = (1 << 2),
- HWCAP_LOONGARCH_FPU = (1 << 3),
- HWCAP_LOONGARCH_LSX = (1 << 4),
- HWCAP_LOONGARCH_LASX = (1 << 5),
- HWCAP_LOONGARCH_CRC32 = (1 << 6),
- HWCAP_LOONGARCH_COMPLEX = (1 << 7),
- HWCAP_LOONGARCH_CRYPTO = (1 << 8),
- HWCAP_LOONGARCH_LVZ = (1 << 9),
- HWCAP_LOONGARCH_LBT_X86 = (1 << 10),
- HWCAP_LOONGARCH_LBT_ARM = (1 << 11),
- HWCAP_LOONGARCH_LBT_MIPS = (1 << 12),
-};
-
-static uint32_t get_elf_hwcap(void)
-{
- LoongArchCPU *cpu = LOONGARCH_CPU(thread_cpu);
- uint32_t hwcaps = 0;
-
- hwcaps |= HWCAP_LOONGARCH_CRC32;
-
- if (FIELD_EX32(cpu->env.cpucfg[1], CPUCFG1, UAL)) {
- hwcaps |= HWCAP_LOONGARCH_UAL;
- }
-
- if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, FP)) {
- hwcaps |= HWCAP_LOONGARCH_FPU;
- }
-
- if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LAM)) {
- hwcaps |= HWCAP_LOONGARCH_LAM;
- }
-
- if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) {
- hwcaps |= HWCAP_LOONGARCH_LSX;
- }
-
- if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LASX)) {
- hwcaps |= HWCAP_LOONGARCH_LASX;
- }
-
- return hwcaps;
-}
+#define ELF_HWCAP get_elf_hwcap(thread_cpu)
#define ELF_PLATFORM "loongarch"
diff --git a/linux-user/loongarch64/elfload.c b/linux-user/loongarch64/elfload.c
index 874dc4c230..ee4a85b8d6 100644
--- a/linux-user/loongarch64/elfload.c
+++ b/linux-user/loongarch64/elfload.c
@@ -9,3 +9,50 @@ const char *get_elf_cpu_model(uint32_t eflags)
{
return "la464";
}
+
+/* See arch/loongarch/include/uapi/asm/hwcap.h */
+enum {
+ HWCAP_LOONGARCH_CPUCFG = (1 << 0),
+ HWCAP_LOONGARCH_LAM = (1 << 1),
+ HWCAP_LOONGARCH_UAL = (1 << 2),
+ HWCAP_LOONGARCH_FPU = (1 << 3),
+ HWCAP_LOONGARCH_LSX = (1 << 4),
+ HWCAP_LOONGARCH_LASX = (1 << 5),
+ HWCAP_LOONGARCH_CRC32 = (1 << 6),
+ HWCAP_LOONGARCH_COMPLEX = (1 << 7),
+ HWCAP_LOONGARCH_CRYPTO = (1 << 8),
+ HWCAP_LOONGARCH_LVZ = (1 << 9),
+ HWCAP_LOONGARCH_LBT_X86 = (1 << 10),
+ HWCAP_LOONGARCH_LBT_ARM = (1 << 11),
+ HWCAP_LOONGARCH_LBT_MIPS = (1 << 12),
+};
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+ LoongArchCPU *cpu = LOONGARCH_CPU(cs);
+ abi_ulong hwcaps = 0;
+
+ hwcaps |= HWCAP_LOONGARCH_CRC32;
+
+ if (FIELD_EX32(cpu->env.cpucfg[1], CPUCFG1, UAL)) {
+ hwcaps |= HWCAP_LOONGARCH_UAL;
+ }
+
+ if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, FP)) {
+ hwcaps |= HWCAP_LOONGARCH_FPU;
+ }
+
+ if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LAM)) {
+ hwcaps |= HWCAP_LOONGARCH_LAM;
+ }
+
+ if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LSX)) {
+ hwcaps |= HWCAP_LOONGARCH_LSX;
+ }
+
+ if (FIELD_EX32(cpu->env.cpucfg[2], CPUCFG2, LASX)) {
+ hwcaps |= HWCAP_LOONGARCH_LASX;
+ }
+
+ return hwcaps;
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 11/46] linux-user: Move get_elf_hwcap to mips/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (9 preceding siblings ...)
2025-08-27 23:19 ` [PULL 10/46] linux-user: Move get_elf_hwcap to loongarch64/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 12/46] linux-user: Move get_elf_hwcap to sh4/elfload.c Richard Henderson
` (35 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Change the return type to abi_ulong, and pass in the cpu.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loader.h | 2 +-
linux-user/mips/target_elf.h | 2 ++
linux-user/mips64/target_elf.h | 2 ++
linux-user/elfload.c | 52 +---------------------------------
linux-user/mips/elfload.c | 50 ++++++++++++++++++++++++++++++++
5 files changed, 56 insertions(+), 52 deletions(-)
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 92b6d41145..04457737dd 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -103,7 +103,7 @@ const char *get_elf_cpu_model(uint32_t eflags);
#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_ARM) \
|| defined(TARGET_SPARC) || defined(TARGET_PPC) \
- || defined(TARGET_LOONGARCH64)
+ || defined(TARGET_LOONGARCH64) || defined(TARGET_MIPS)
abi_ulong get_elf_hwcap(CPUState *cs);
abi_ulong get_elf_hwcap2(CPUState *cs);
#endif
diff --git a/linux-user/mips/target_elf.h b/linux-user/mips/target_elf.h
index febf710c7a..877f8347d7 100644
--- a/linux-user/mips/target_elf.h
+++ b/linux-user/mips/target_elf.h
@@ -8,4 +8,6 @@
#ifndef MIPS_TARGET_ELF_H
#define MIPS_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+
#endif
diff --git a/linux-user/mips64/target_elf.h b/linux-user/mips64/target_elf.h
index 02e6d14840..c0347e5cb6 100644
--- a/linux-user/mips64/target_elf.h
+++ b/linux-user/mips64/target_elf.h
@@ -8,4 +8,6 @@
#ifndef MIPS64_TARGET_ELF_H
#define MIPS64_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 574b37a22c..dc3f502277 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -834,57 +834,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMIPSState *e
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-/* See arch/mips/include/uapi/asm/hwcap.h. */
-enum {
- HWCAP_MIPS_R6 = (1 << 0),
- HWCAP_MIPS_MSA = (1 << 1),
- HWCAP_MIPS_CRC32 = (1 << 2),
- HWCAP_MIPS_MIPS16 = (1 << 3),
- HWCAP_MIPS_MDMX = (1 << 4),
- HWCAP_MIPS_MIPS3D = (1 << 5),
- HWCAP_MIPS_SMARTMIPS = (1 << 6),
- HWCAP_MIPS_DSP = (1 << 7),
- HWCAP_MIPS_DSP2 = (1 << 8),
- HWCAP_MIPS_DSP3 = (1 << 9),
- HWCAP_MIPS_MIPS16E2 = (1 << 10),
- HWCAP_LOONGSON_MMI = (1 << 11),
- HWCAP_LOONGSON_EXT = (1 << 12),
- HWCAP_LOONGSON_EXT2 = (1 << 13),
- HWCAP_LOONGSON_CPUCFG = (1 << 14),
-};
-
-#define ELF_HWCAP get_elf_hwcap()
-
-#define GET_FEATURE_INSN(_flag, _hwcap) \
- do { if (cpu->env.insn_flags & (_flag)) { hwcaps |= _hwcap; } } while (0)
-
-#define GET_FEATURE_REG_SET(_reg, _mask, _hwcap) \
- do { if (cpu->env._reg & (_mask)) { hwcaps |= _hwcap; } } while (0)
-
-#define GET_FEATURE_REG_EQU(_reg, _start, _length, _val, _hwcap) \
- do { \
- if (extract32(cpu->env._reg, (_start), (_length)) == (_val)) { \
- hwcaps |= _hwcap; \
- } \
- } while (0)
-
-static uint32_t get_elf_hwcap(void)
-{
- MIPSCPU *cpu = MIPS_CPU(thread_cpu);
- uint32_t hwcaps = 0;
-
- GET_FEATURE_REG_EQU(CP0_Config0, CP0C0_AR, CP0C0_AR_LENGTH,
- 2, HWCAP_MIPS_R6);
- GET_FEATURE_REG_SET(CP0_Config3, 1 << CP0C3_MSAP, HWCAP_MIPS_MSA);
- GET_FEATURE_INSN(ASE_LMMI, HWCAP_LOONGSON_MMI);
- GET_FEATURE_INSN(ASE_LEXT, HWCAP_LOONGSON_EXT);
-
- return hwcaps;
-}
-
-#undef GET_FEATURE_REG_EQU
-#undef GET_FEATURE_REG_SET
-#undef GET_FEATURE_INSN
+#define ELF_HWCAP get_elf_hwcap(thread_cpu)
#endif /* TARGET_MIPS */
diff --git a/linux-user/mips/elfload.c b/linux-user/mips/elfload.c
index 04e3b76740..739f71c21b 100644
--- a/linux-user/mips/elfload.c
+++ b/linux-user/mips/elfload.c
@@ -42,3 +42,53 @@ const char *get_elf_cpu_model(uint32_t eflags)
return "24Kf";
#endif
}
+
+/* See arch/mips/include/uapi/asm/hwcap.h. */
+enum {
+ HWCAP_MIPS_R6 = (1 << 0),
+ HWCAP_MIPS_MSA = (1 << 1),
+ HWCAP_MIPS_CRC32 = (1 << 2),
+ HWCAP_MIPS_MIPS16 = (1 << 3),
+ HWCAP_MIPS_MDMX = (1 << 4),
+ HWCAP_MIPS_MIPS3D = (1 << 5),
+ HWCAP_MIPS_SMARTMIPS = (1 << 6),
+ HWCAP_MIPS_DSP = (1 << 7),
+ HWCAP_MIPS_DSP2 = (1 << 8),
+ HWCAP_MIPS_DSP3 = (1 << 9),
+ HWCAP_MIPS_MIPS16E2 = (1 << 10),
+ HWCAP_LOONGSON_MMI = (1 << 11),
+ HWCAP_LOONGSON_EXT = (1 << 12),
+ HWCAP_LOONGSON_EXT2 = (1 << 13),
+ HWCAP_LOONGSON_CPUCFG = (1 << 14),
+};
+
+#define GET_FEATURE_INSN(_flag, _hwcap) \
+ do { if (cpu->env.insn_flags & (_flag)) { hwcaps |= _hwcap; } } while (0)
+
+#define GET_FEATURE_REG_SET(_reg, _mask, _hwcap) \
+ do { if (cpu->env._reg & (_mask)) { hwcaps |= _hwcap; } } while (0)
+
+#define GET_FEATURE_REG_EQU(_reg, _start, _length, _val, _hwcap) \
+ do { \
+ if (extract32(cpu->env._reg, (_start), (_length)) == (_val)) { \
+ hwcaps |= _hwcap; \
+ } \
+ } while (0)
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+ abi_ulong hwcaps = 0;
+
+ GET_FEATURE_REG_EQU(CP0_Config0, CP0C0_AR, CP0C0_AR_LENGTH,
+ 2, HWCAP_MIPS_R6);
+ GET_FEATURE_REG_SET(CP0_Config3, 1 << CP0C3_MSAP, HWCAP_MIPS_MSA);
+ GET_FEATURE_INSN(ASE_LMMI, HWCAP_LOONGSON_MMI);
+ GET_FEATURE_INSN(ASE_LEXT, HWCAP_LOONGSON_EXT);
+
+ return hwcaps;
+}
+
+#undef GET_FEATURE_REG_EQU
+#undef GET_FEATURE_REG_SET
+#undef GET_FEATURE_INSN
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 12/46] linux-user: Move get_elf_hwcap to sh4/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (10 preceding siblings ...)
2025-08-27 23:19 ` [PULL 11/46] linux-user: Move get_elf_hwcap to mips/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 13/46] linux-user: Move hwcap functions to s390x/elfload.c Richard Henderson
` (34 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Change the return type to abi_ulong, and pass in the cpu.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loader.h | 3 ++-
linux-user/sh4/target_elf.h | 2 ++
linux-user/elfload.c | 29 +----------------------------
linux-user/sh4/elfload.c | 27 +++++++++++++++++++++++++++
4 files changed, 32 insertions(+), 29 deletions(-)
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 04457737dd..d8a9399807 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -103,7 +103,8 @@ const char *get_elf_cpu_model(uint32_t eflags);
#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_ARM) \
|| defined(TARGET_SPARC) || defined(TARGET_PPC) \
- || defined(TARGET_LOONGARCH64) || defined(TARGET_MIPS)
+ || defined(TARGET_LOONGARCH64) || defined(TARGET_MIPS) \
+ || defined(TARGET_SH4)
abi_ulong get_elf_hwcap(CPUState *cs);
abi_ulong get_elf_hwcap2(CPUState *cs);
#endif
diff --git a/linux-user/sh4/target_elf.h b/linux-user/sh4/target_elf.h
index d17011bd75..badd0f5371 100644
--- a/linux-user/sh4/target_elf.h
+++ b/linux-user/sh4/target_elf.h
@@ -8,4 +8,6 @@
#ifndef SH4_TARGET_ELF_H
#define SH4_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index dc3f502277..7e1c11c39f 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -963,34 +963,7 @@ static inline void elf_core_copy_regs(target_elf_gregset_t *regs,
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-enum {
- SH_CPU_HAS_FPU = 0x0001, /* Hardware FPU support */
- SH_CPU_HAS_P2_FLUSH_BUG = 0x0002, /* Need to flush the cache in P2 area */
- SH_CPU_HAS_MMU_PAGE_ASSOC = 0x0004, /* SH3: TLB way selection bit support */
- SH_CPU_HAS_DSP = 0x0008, /* SH-DSP: DSP support */
- SH_CPU_HAS_PERF_COUNTER = 0x0010, /* Hardware performance counters */
- SH_CPU_HAS_PTEA = 0x0020, /* PTEA register */
- SH_CPU_HAS_LLSC = 0x0040, /* movli.l/movco.l */
- SH_CPU_HAS_L2_CACHE = 0x0080, /* Secondary cache / URAM */
- SH_CPU_HAS_OP32 = 0x0100, /* 32-bit instruction support */
- SH_CPU_HAS_PTEAEX = 0x0200, /* PTE ASID Extension support */
-};
-
-#define ELF_HWCAP get_elf_hwcap()
-
-static uint32_t get_elf_hwcap(void)
-{
- SuperHCPU *cpu = SUPERH_CPU(thread_cpu);
- uint32_t hwcap = 0;
-
- hwcap |= SH_CPU_HAS_FPU;
-
- if (cpu->env.features & SH_FEATURE_SH4A) {
- hwcap |= SH_CPU_HAS_LLSC;
- }
-
- return hwcap;
-}
+#define ELF_HWCAP get_elf_hwcap(thread_cpu)
#endif
diff --git a/linux-user/sh4/elfload.c b/linux-user/sh4/elfload.c
index 546034ec07..99ad4f6334 100644
--- a/linux-user/sh4/elfload.c
+++ b/linux-user/sh4/elfload.c
@@ -9,3 +9,30 @@ const char *get_elf_cpu_model(uint32_t eflags)
{
return "sh7785";
}
+
+enum {
+ SH_CPU_HAS_FPU = 0x0001, /* Hardware FPU support */
+ SH_CPU_HAS_P2_FLUSH_BUG = 0x0002, /* Need to flush the cache in P2 area */
+ SH_CPU_HAS_MMU_PAGE_ASSOC = 0x0004, /* SH3: TLB way selection bit support */
+ SH_CPU_HAS_DSP = 0x0008, /* SH-DSP: DSP support */
+ SH_CPU_HAS_PERF_COUNTER = 0x0010, /* Hardware performance counters */
+ SH_CPU_HAS_PTEA = 0x0020, /* PTEA register */
+ SH_CPU_HAS_LLSC = 0x0040, /* movli.l/movco.l */
+ SH_CPU_HAS_L2_CACHE = 0x0080, /* Secondary cache / URAM */
+ SH_CPU_HAS_OP32 = 0x0100, /* 32-bit instruction support */
+ SH_CPU_HAS_PTEAEX = 0x0200, /* PTE ASID Extension support */
+};
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+ SuperHCPU *cpu = SUPERH_CPU(cs);
+ abi_ulong hwcap = 0;
+
+ hwcap |= SH_CPU_HAS_FPU;
+
+ if (cpu->env.features & SH_FEATURE_SH4A) {
+ hwcap |= SH_CPU_HAS_LLSC;
+ }
+
+ return hwcap;
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 13/46] linux-user: Move hwcap functions to s390x/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (11 preceding siblings ...)
2025-08-27 23:19 ` [PULL 12/46] linux-user: Move get_elf_hwcap to sh4/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 14/46] linux-user: Move get_elf_hwcap to riscv/elfload.c Richard Henderson
` (33 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
For get_elf_hwcap, change the return type to abi_ulong
and pass in the cpu.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loader.h | 5 +--
linux-user/s390x/target_elf.h | 2 ++
linux-user/s390x/target_proc.h | 2 +-
linux-user/elfload.c | 60 +---------------------------------
linux-user/s390x/elfload.c | 57 ++++++++++++++++++++++++++++++++
5 files changed, 62 insertions(+), 64 deletions(-)
diff --git a/linux-user/loader.h b/linux-user/loader.h
index d8a9399807..c14e69f551 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -104,13 +104,10 @@ const char *get_elf_cpu_model(uint32_t eflags);
#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_ARM) \
|| defined(TARGET_SPARC) || defined(TARGET_PPC) \
|| defined(TARGET_LOONGARCH64) || defined(TARGET_MIPS) \
- || defined(TARGET_SH4)
+ || defined(TARGET_SH4) || defined(TARGET_S390X)
abi_ulong get_elf_hwcap(CPUState *cs);
abi_ulong get_elf_hwcap2(CPUState *cs);
#endif
-#if defined(TARGET_S390X)
-uint32_t get_elf_hwcap(void);
-#endif
const char *elf_hwcap_str(uint32_t bit);
const char *elf_hwcap2_str(uint32_t bit);
diff --git a/linux-user/s390x/target_elf.h b/linux-user/s390x/target_elf.h
index e51b053339..cebace949a 100644
--- a/linux-user/s390x/target_elf.h
+++ b/linux-user/s390x/target_elf.h
@@ -8,4 +8,6 @@
#ifndef S390X_TARGET_ELF_H
#define S390X_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+
#endif
diff --git a/linux-user/s390x/target_proc.h b/linux-user/s390x/target_proc.h
index a4a4821ea5..60cc22d3b4 100644
--- a/linux-user/s390x/target_proc.h
+++ b/linux-user/s390x/target_proc.h
@@ -48,7 +48,7 @@ static void show_cpu_summary(CPUArchState *cpu_env, int fd)
{
S390CPUModel *model = env_archcpu(cpu_env)->model;
int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
- uint32_t elf_hwcap = get_elf_hwcap();
+ uint32_t elf_hwcap = get_elf_hwcap(env_cpu(cpu_env));
const char *hwcap_str;
int i;
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 7e1c11c39f..ba8593368d 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1039,65 +1039,7 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_S390
-#include "elf.h"
-
-#define ELF_HWCAP get_elf_hwcap()
-
-#define GET_FEATURE(_feat, _hwcap) \
- do { if (s390_has_feat(_feat)) { hwcap |= _hwcap; } } while (0)
-
-uint32_t get_elf_hwcap(void)
-{
- /*
- * Let's assume we always have esan3 and zarch.
- * 31-bit processes can use 64-bit registers (high gprs).
- */
- uint32_t hwcap = HWCAP_S390_ESAN3 | HWCAP_S390_ZARCH | HWCAP_S390_HIGH_GPRS;
-
- GET_FEATURE(S390_FEAT_STFLE, HWCAP_S390_STFLE);
- GET_FEATURE(S390_FEAT_MSA, HWCAP_S390_MSA);
- GET_FEATURE(S390_FEAT_LONG_DISPLACEMENT, HWCAP_S390_LDISP);
- GET_FEATURE(S390_FEAT_EXTENDED_IMMEDIATE, HWCAP_S390_EIMM);
- if (s390_has_feat(S390_FEAT_EXTENDED_TRANSLATION_3) &&
- s390_has_feat(S390_FEAT_ETF3_ENH)) {
- hwcap |= HWCAP_S390_ETF3EH;
- }
- GET_FEATURE(S390_FEAT_VECTOR, HWCAP_S390_VXRS);
- GET_FEATURE(S390_FEAT_VECTOR_ENH, HWCAP_S390_VXRS_EXT);
- GET_FEATURE(S390_FEAT_VECTOR_ENH2, HWCAP_S390_VXRS_EXT2);
-
- return hwcap;
-}
-
-const char *elf_hwcap_str(uint32_t bit)
-{
- static const char *hwcap_str[] = {
- [HWCAP_S390_NR_ESAN3] = "esan3",
- [HWCAP_S390_NR_ZARCH] = "zarch",
- [HWCAP_S390_NR_STFLE] = "stfle",
- [HWCAP_S390_NR_MSA] = "msa",
- [HWCAP_S390_NR_LDISP] = "ldisp",
- [HWCAP_S390_NR_EIMM] = "eimm",
- [HWCAP_S390_NR_DFP] = "dfp",
- [HWCAP_S390_NR_HPAGE] = "edat",
- [HWCAP_S390_NR_ETF3EH] = "etf3eh",
- [HWCAP_S390_NR_HIGH_GPRS] = "highgprs",
- [HWCAP_S390_NR_TE] = "te",
- [HWCAP_S390_NR_VXRS] = "vx",
- [HWCAP_S390_NR_VXRS_BCD] = "vxd",
- [HWCAP_S390_NR_VXRS_EXT] = "vxe",
- [HWCAP_S390_NR_GS] = "gs",
- [HWCAP_S390_NR_VXRS_EXT2] = "vxe2",
- [HWCAP_S390_NR_VXRS_PDE] = "vxp",
- [HWCAP_S390_NR_SORT] = "sort",
- [HWCAP_S390_NR_DFLT] = "dflt",
- [HWCAP_S390_NR_NNPA] = "nnpa",
- [HWCAP_S390_NR_PCI_MIO] = "pcimio",
- [HWCAP_S390_NR_SIE] = "sie",
- };
-
- return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
-}
+#define ELF_HWCAP get_elf_hwcap(thread_cpu)
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
diff --git a/linux-user/s390x/elfload.c b/linux-user/s390x/elfload.c
index 989953a247..79ceaba51d 100644
--- a/linux-user/s390x/elfload.c
+++ b/linux-user/s390x/elfload.c
@@ -3,9 +3,66 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
+#include "elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
{
return "qemu";
}
+
+#define GET_FEATURE(_feat, _hwcap) \
+ do { if (s390_has_feat(_feat)) { hwcap |= _hwcap; } } while (0)
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+ /*
+ * Let's assume we always have esan3 and zarch.
+ * 31-bit processes can use 64-bit registers (high gprs).
+ */
+ uint32_t hwcap = HWCAP_S390_ESAN3 | HWCAP_S390_ZARCH | HWCAP_S390_HIGH_GPRS;
+
+ GET_FEATURE(S390_FEAT_STFLE, HWCAP_S390_STFLE);
+ GET_FEATURE(S390_FEAT_MSA, HWCAP_S390_MSA);
+ GET_FEATURE(S390_FEAT_LONG_DISPLACEMENT, HWCAP_S390_LDISP);
+ GET_FEATURE(S390_FEAT_EXTENDED_IMMEDIATE, HWCAP_S390_EIMM);
+ if (s390_has_feat(S390_FEAT_EXTENDED_TRANSLATION_3) &&
+ s390_has_feat(S390_FEAT_ETF3_ENH)) {
+ hwcap |= HWCAP_S390_ETF3EH;
+ }
+ GET_FEATURE(S390_FEAT_VECTOR, HWCAP_S390_VXRS);
+ GET_FEATURE(S390_FEAT_VECTOR_ENH, HWCAP_S390_VXRS_EXT);
+ GET_FEATURE(S390_FEAT_VECTOR_ENH2, HWCAP_S390_VXRS_EXT2);
+
+ return hwcap;
+}
+
+const char *elf_hwcap_str(uint32_t bit)
+{
+ static const char *hwcap_str[] = {
+ [HWCAP_S390_NR_ESAN3] = "esan3",
+ [HWCAP_S390_NR_ZARCH] = "zarch",
+ [HWCAP_S390_NR_STFLE] = "stfle",
+ [HWCAP_S390_NR_MSA] = "msa",
+ [HWCAP_S390_NR_LDISP] = "ldisp",
+ [HWCAP_S390_NR_EIMM] = "eimm",
+ [HWCAP_S390_NR_DFP] = "dfp",
+ [HWCAP_S390_NR_HPAGE] = "edat",
+ [HWCAP_S390_NR_ETF3EH] = "etf3eh",
+ [HWCAP_S390_NR_HIGH_GPRS] = "highgprs",
+ [HWCAP_S390_NR_TE] = "te",
+ [HWCAP_S390_NR_VXRS] = "vx",
+ [HWCAP_S390_NR_VXRS_BCD] = "vxd",
+ [HWCAP_S390_NR_VXRS_EXT] = "vxe",
+ [HWCAP_S390_NR_GS] = "gs",
+ [HWCAP_S390_NR_VXRS_EXT2] = "vxe2",
+ [HWCAP_S390_NR_VXRS_PDE] = "vxp",
+ [HWCAP_S390_NR_SORT] = "sort",
+ [HWCAP_S390_NR_DFLT] = "dflt",
+ [HWCAP_S390_NR_NNPA] = "nnpa",
+ [HWCAP_S390_NR_PCI_MIO] = "pcimio",
+ [HWCAP_S390_NR_SIE] = "sie",
+ };
+
+ return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 14/46] linux-user: Move get_elf_hwcap to riscv/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (12 preceding siblings ...)
2025-08-27 23:19 ` [PULL 13/46] linux-user: Move hwcap functions to s390x/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 15/46] linux-user: Remove ELF_HWCAP Richard Henderson
` (32 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Change the return type to abi_ulong, and pass in the cpu.
As this is the last instance of get_elf_hwcap to be converted,
remove the ifdef around the declaration in loader.h.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loader.h | 5 -----
linux-user/riscv/target_elf.h | 2 ++
linux-user/elfload.c | 14 +-------------
linux-user/riscv/elfload.c | 12 ++++++++++++
4 files changed, 15 insertions(+), 18 deletions(-)
diff --git a/linux-user/loader.h b/linux-user/loader.h
index c14e69f551..729723cc06 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -101,13 +101,8 @@ extern unsigned long guest_stack_size;
/* Note that Elf32 and Elf64 use uint32_t for e_flags. */
const char *get_elf_cpu_model(uint32_t eflags);
-#if defined(TARGET_I386) || defined(TARGET_X86_64) || defined(TARGET_ARM) \
- || defined(TARGET_SPARC) || defined(TARGET_PPC) \
- || defined(TARGET_LOONGARCH64) || defined(TARGET_MIPS) \
- || defined(TARGET_SH4) || defined(TARGET_S390X)
abi_ulong get_elf_hwcap(CPUState *cs);
abi_ulong get_elf_hwcap2(CPUState *cs);
-#endif
const char *elf_hwcap_str(uint32_t bit);
const char *elf_hwcap2_str(uint32_t bit);
diff --git a/linux-user/riscv/target_elf.h b/linux-user/riscv/target_elf.h
index bfe86105d0..48d9af557b 100644
--- a/linux-user/riscv/target_elf.h
+++ b/linux-user/riscv/target_elf.h
@@ -8,4 +8,6 @@
#ifndef RISCV_TARGET_ELF_H
#define RISCV_TARGET_ELF_H
+#define HAVE_ELF_HWCAP 1
+
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ba8593368d..ce4055b0e9 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1099,19 +1099,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define VDSO_HEADER "vdso-64.c.inc"
#endif
-#define ELF_HWCAP get_elf_hwcap()
-
-static uint32_t get_elf_hwcap(void)
-{
-#define MISA_BIT(EXT) (1 << (EXT - 'A'))
- RISCVCPU *cpu = RISCV_CPU(thread_cpu);
- uint32_t mask = MISA_BIT('I') | MISA_BIT('M') | MISA_BIT('A')
- | MISA_BIT('F') | MISA_BIT('D') | MISA_BIT('C')
- | MISA_BIT('V');
-
- return cpu->env.misa_ext & mask;
-#undef MISA_BIT
-}
+#define ELF_HWCAP get_elf_hwcap(thread_cpu)
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
diff --git a/linux-user/riscv/elfload.c b/linux-user/riscv/elfload.c
index f92adb7308..2e7d622232 100644
--- a/linux-user/riscv/elfload.c
+++ b/linux-user/riscv/elfload.c
@@ -9,3 +9,15 @@ const char *get_elf_cpu_model(uint32_t eflags)
{
return "max";
}
+
+abi_ulong get_elf_hwcap(CPUState *cs)
+{
+#define MISA_BIT(EXT) (1 << (EXT - 'A'))
+ RISCVCPU *cpu = RISCV_CPU(cs);
+ uint32_t mask = MISA_BIT('I') | MISA_BIT('M') | MISA_BIT('A')
+ | MISA_BIT('F') | MISA_BIT('D') | MISA_BIT('C')
+ | MISA_BIT('V');
+
+ return cpu->env.misa_ext & mask;
+#undef MISA_BIT
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 15/46] linux-user: Remove ELF_HWCAP
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (13 preceding siblings ...)
2025-08-27 23:19 ` [PULL 14/46] linux-user: Move get_elf_hwcap to riscv/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 16/46] linux-user: Remove ELF_HWCAP2 Richard Henderson
` (31 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
All real definitions of ELF_HWCAP are now identical, and the stub
definitions are 0. Provide zero stub as a fallback definition.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 35 ++++++++++++-----------------------
1 file changed, 12 insertions(+), 23 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ce4055b0e9..88d439f348 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -28,6 +28,7 @@
#include "qemu/lockable.h"
#include "qapi/error.h"
#include "qemu/error-report.h"
+#include "target_elf.h"
#include "target_signal.h"
#include "tcg/debuginfo.h"
@@ -148,8 +149,6 @@ typedef abi_int target_pid_t;
#ifdef TARGET_I386
-#define ELF_HWCAP get_elf_hwcap(thread_cpu)
-
#ifdef TARGET_X86_64
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_X86_64
@@ -449,7 +448,6 @@ static bool init_guest_commpage(void)
return true;
}
-#define ELF_HWCAP get_elf_hwcap(thread_cpu)
#define ELF_HWCAP2 get_elf_hwcap2(thread_cpu)
#define ELF_PLATFORM get_elf_platform()
@@ -539,7 +537,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-#define ELF_HWCAP get_elf_hwcap(thread_cpu)
#define ELF_HWCAP2 get_elf_hwcap2(thread_cpu)
#if TARGET_BIG_ENDIAN
@@ -565,8 +562,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
# define ELF_ARCH EM_SPARCV9
#endif
-#define ELF_HWCAP get_elf_hwcap(thread_cpu)
-
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
{
@@ -598,7 +593,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_ARCH EM_PPC
-#define ELF_HWCAP get_elf_hwcap(thread_cpu)
#define ELF_HWCAP2 get_elf_hwcap2(thread_cpu)
/*
@@ -725,8 +719,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-#define ELF_HWCAP get_elf_hwcap(thread_cpu)
-
#define ELF_PLATFORM "loongarch"
#endif /* TARGET_LOONGARCH64 */
@@ -834,8 +826,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMIPSState *e
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-#define ELF_HWCAP get_elf_hwcap(thread_cpu)
-
#endif /* TARGET_MIPS */
#ifdef TARGET_MICROBLAZE
@@ -909,7 +899,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
(*regs)[32] = tswapreg(env->pc);
(*regs)[33] = tswapreg(cpu_get_sr(env));
}
-#define ELF_HWCAP 0
+
#define ELF_PLATFORM NULL
#endif /* TARGET_OPENRISC */
@@ -963,8 +953,6 @@ static inline void elf_core_copy_regs(target_elf_gregset_t *regs,
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-#define ELF_HWCAP get_elf_hwcap(thread_cpu)
-
#endif
#ifdef TARGET_M68K
@@ -1039,8 +1027,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_S390
-#define ELF_HWCAP get_elf_hwcap(thread_cpu)
-
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
regs->psw.addr = infop->entry;
@@ -1099,8 +1085,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define VDSO_HEADER "vdso-64.c.inc"
#endif
-#define ELF_HWCAP get_elf_hwcap(thread_cpu)
-
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
{
@@ -1268,10 +1252,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define elf_check_abi(x) (1)
#endif
-#ifndef ELF_HWCAP
-#define ELF_HWCAP 0
-#endif
-
#ifndef STACK_GROWS_DOWN
#define STACK_GROWS_DOWN 1
#endif
@@ -1291,6 +1271,15 @@ static inline void init_thread(struct target_pt_regs *regs,
#define EXSTACK_DEFAULT false
#endif
+/*
+ * Provide fallback definitions that the target may omit.
+ * One way or another, we'll get a link error if the setting of
+ * HAVE_* doesn't match the implementation.
+ */
+#ifndef HAVE_ELF_HWCAP
+abi_ulong get_elf_hwcap(CPUState *cs) { return 0; }
+#endif
+
#include "elf.h"
/* We must delay the following stanzas until after "elf.h". */
@@ -1868,7 +1857,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid());
NEW_AUX_ENT(AT_GID, (abi_ulong) getgid());
NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid());
- NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP);
+ NEW_AUX_ENT(AT_HWCAP, get_elf_hwcap(thread_cpu));
NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK));
NEW_AUX_ENT(AT_RANDOM, (abi_ulong) u_rand_bytes);
NEW_AUX_ENT(AT_SECURE, (abi_ulong) qemu_getauxval(AT_SECURE));
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 16/46] linux-user: Remove ELF_HWCAP2
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (14 preceding siblings ...)
2025-08-27 23:19 ` [PULL 15/46] linux-user: Remove ELF_HWCAP Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 17/46] linux-user: Move get_elf_platform to {i386, x86_64}/elfload.c Richard Henderson
` (30 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
All definitions of ELF_HWCAP2 are now identical. Provide a
not-reached stub as a fallback definition of get_elf_hwcap2.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 23 ++++++++++-------------
1 file changed, 10 insertions(+), 13 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 88d439f348..7a41917b49 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -448,8 +448,6 @@ static bool init_guest_commpage(void)
return true;
}
-#define ELF_HWCAP2 get_elf_hwcap2(thread_cpu)
-
#define ELF_PLATFORM get_elf_platform()
static const char *get_elf_platform(void)
@@ -537,8 +535,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-#define ELF_HWCAP2 get_elf_hwcap2(thread_cpu)
-
#if TARGET_BIG_ENDIAN
# define VDSO_HEADER "vdso-be.c.inc"
#else
@@ -593,8 +589,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_ARCH EM_PPC
-#define ELF_HWCAP2 get_elf_hwcap2(thread_cpu)
-
/*
* The requirements here are:
* - keep the final alignment of sp (sp & 0xf)
@@ -1279,6 +1273,10 @@ static inline void init_thread(struct target_pt_regs *regs,
#ifndef HAVE_ELF_HWCAP
abi_ulong get_elf_hwcap(CPUState *cs) { return 0; }
#endif
+#ifndef HAVE_ELF_HWCAP2
+abi_ulong get_elf_hwcap2(CPUState *cs) { g_assert_not_reached(); }
+#define HAVE_ELF_HWCAP2 0
+#endif
#include "elf.h"
@@ -1801,9 +1799,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
#ifdef DLINFO_ARCH_ITEMS
size += DLINFO_ARCH_ITEMS * 2;
#endif
-#ifdef ELF_HWCAP2
- size += 2;
-#endif
+ if (HAVE_ELF_HWCAP2) {
+ size += 2;
+ }
info->auxv_len = size * n;
size += envc + argc + 2;
@@ -1863,10 +1861,9 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
NEW_AUX_ENT(AT_SECURE, (abi_ulong) qemu_getauxval(AT_SECURE));
NEW_AUX_ENT(AT_EXECFN, info->file_string);
-#ifdef ELF_HWCAP2
- NEW_AUX_ENT(AT_HWCAP2, (abi_ulong) ELF_HWCAP2);
-#endif
-
+ if (HAVE_ELF_HWCAP2) {
+ NEW_AUX_ENT(AT_HWCAP2, get_elf_hwcap(thread_cpu));
+ }
if (u_base_platform) {
NEW_AUX_ENT(AT_BASE_PLATFORM, u_base_platform);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 17/46] linux-user: Move get_elf_platform to {i386, x86_64}/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (15 preceding siblings ...)
2025-08-27 23:19 ` [PULL 16/46] linux-user: Remove ELF_HWCAP2 Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 18/46] linux-user/i386: Return const data from get_elf_platform Richard Henderson
` (29 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Move get_elf_platform to i386/elfload.c; pass in CPUState.
Create a simple get_elf_platform for x86_64.
Introduce HAVE_ELF_PLATFORM.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/i386/target_elf.h | 1 +
linux-user/loader.h | 3 +++
linux-user/x86_64/target_elf.h | 1 +
linux-user/elfload.c | 18 ++----------------
linux-user/i386/elfload.c | 13 +++++++++++++
linux-user/x86_64/elfload.c | 5 +++++
6 files changed, 25 insertions(+), 16 deletions(-)
diff --git a/linux-user/i386/target_elf.h b/linux-user/i386/target_elf.h
index 802395af3a..44dde1ac4a 100644
--- a/linux-user/i386/target_elf.h
+++ b/linux-user/i386/target_elf.h
@@ -9,5 +9,6 @@
#define I386_TARGET_ELF_H
#define HAVE_ELF_HWCAP 1
+#define HAVE_ELF_PLATFORM 1
#endif
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 729723cc06..44bb4cbfd3 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -105,5 +105,8 @@ abi_ulong get_elf_hwcap(CPUState *cs);
abi_ulong get_elf_hwcap2(CPUState *cs);
const char *elf_hwcap_str(uint32_t bit);
const char *elf_hwcap2_str(uint32_t bit);
+#if defined(TARGET_I386)
+const char *get_elf_platform(CPUState *cs);
+#endif
#endif /* LINUX_USER_LOADER_H */
diff --git a/linux-user/x86_64/target_elf.h b/linux-user/x86_64/target_elf.h
index 03483bad57..498c3f7e4e 100644
--- a/linux-user/x86_64/target_elf.h
+++ b/linux-user/x86_64/target_elf.h
@@ -9,5 +9,6 @@
#define X86_64_TARGET_ELF_H
#define HAVE_ELF_HWCAP 1
+#define HAVE_ELF_PLATFORM 1
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 7a41917b49..e6e509c0a6 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -149,12 +149,12 @@ typedef abi_int target_pid_t;
#ifdef TARGET_I386
+#define ELF_PLATFORM get_elf_platform(thread_cpu)
+
#ifdef TARGET_X86_64
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_X86_64
-#define ELF_PLATFORM "x86_64"
-
static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
{
regs->rax = 0;
@@ -237,22 +237,8 @@ static bool init_guest_commpage(void)
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_386
-#define ELF_PLATFORM get_elf_platform()
#define EXSTACK_DEFAULT true
-static const char *get_elf_platform(void)
-{
- static char elf_platform[] = "i386";
- int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL);
- if (family > 6) {
- family = 6;
- }
- if (family >= 3) {
- elf_platform[1] = '0' + family;
- }
- return elf_platform;
-}
-
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
{
diff --git a/linux-user/i386/elfload.c b/linux-user/i386/elfload.c
index f99336e73c..1b759098ca 100644
--- a/linux-user/i386/elfload.c
+++ b/linux-user/i386/elfload.c
@@ -14,3 +14,16 @@ abi_ulong get_elf_hwcap(CPUState *cs)
{
return cpu_env(cs)->features[FEAT_1_EDX];
}
+
+const char *get_elf_platform(CPUState *cs)
+{
+ static char elf_platform[] = "i386";
+ int family = object_property_get_int(OBJECT(cs), "family", NULL);
+ if (family > 6) {
+ family = 6;
+ }
+ if (family >= 3) {
+ elf_platform[1] = '0' + family;
+ }
+ return elf_platform;
+}
diff --git a/linux-user/x86_64/elfload.c b/linux-user/x86_64/elfload.c
index f99336e73c..88541ea45e 100644
--- a/linux-user/x86_64/elfload.c
+++ b/linux-user/x86_64/elfload.c
@@ -14,3 +14,8 @@ abi_ulong get_elf_hwcap(CPUState *cs)
{
return cpu_env(cs)->features[FEAT_1_EDX];
}
+
+const char *get_elf_platform(CPUState *cs)
+{
+ return "x86_64";
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 18/46] linux-user/i386: Return const data from get_elf_platform
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (16 preceding siblings ...)
2025-08-27 23:19 ` [PULL 17/46] linux-user: Move get_elf_platform to {i386, x86_64}/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 19/46] linux-user: Move get_elf_platform to arm/elfload.c Richard Henderson
` (28 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Rather than modify a static buffer, index into an array of const data.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/i386/elfload.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/linux-user/i386/elfload.c b/linux-user/i386/elfload.c
index 1b759098ca..ef3a6c35d2 100644
--- a/linux-user/i386/elfload.c
+++ b/linux-user/i386/elfload.c
@@ -17,13 +17,9 @@ abi_ulong get_elf_hwcap(CPUState *cs)
const char *get_elf_platform(CPUState *cs)
{
- static char elf_platform[] = "i386";
+ static const char elf_platform[4][5] = { "i386", "i486", "i586", "i686" };
int family = object_property_get_int(OBJECT(cs), "family", NULL);
- if (family > 6) {
- family = 6;
- }
- if (family >= 3) {
- elf_platform[1] = '0' + family;
- }
- return elf_platform;
+
+ family = MAX(MIN(family, 6), 3);
+ return elf_platform[family - 3];
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 19/46] linux-user: Move get_elf_platform to arm/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (17 preceding siblings ...)
2025-08-27 23:19 ` [PULL 18/46] linux-user/i386: Return const data from get_elf_platform Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 20/46] linux-user/loongarch64: Create get_elf_platform Richard Henderson
` (27 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Move the aarch32 get_elf_platform to arm/elfload.c; pass in CPUState.
Create a simple version in aarch64/elfload.c, which we must do at the
same time because of the ifdef dependency between TARGET_AARCH64
and TARGET_ARM.
Since all versions of get_elf_platform now have the same
signature, remove the ifdef from the declaration in loader.h.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/target_elf.h | 1 +
linux-user/arm/target_elf.h | 1 +
linux-user/loader.h | 2 --
linux-user/aarch64/elfload.c | 5 +++++
linux-user/arm/elfload.c | 29 +++++++++++++++++++++++++
linux-user/elfload.c | 38 ++-------------------------------
6 files changed, 38 insertions(+), 38 deletions(-)
diff --git a/linux-user/aarch64/target_elf.h b/linux-user/aarch64/target_elf.h
index 77108f3cb0..dee79ce0c6 100644
--- a/linux-user/aarch64/target_elf.h
+++ b/linux-user/aarch64/target_elf.h
@@ -10,5 +10,6 @@
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_HWCAP2 1
+#define HAVE_ELF_PLATFORM 1
#endif
diff --git a/linux-user/arm/target_elf.h b/linux-user/arm/target_elf.h
index 90470bd87b..856ca41b16 100644
--- a/linux-user/arm/target_elf.h
+++ b/linux-user/arm/target_elf.h
@@ -10,5 +10,6 @@
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_HWCAP2 1
+#define HAVE_ELF_PLATFORM 1
#endif
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 44bb4cbfd3..440871466c 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -105,8 +105,6 @@ abi_ulong get_elf_hwcap(CPUState *cs);
abi_ulong get_elf_hwcap2(CPUState *cs);
const char *elf_hwcap_str(uint32_t bit);
const char *elf_hwcap2_str(uint32_t bit);
-#if defined(TARGET_I386)
const char *get_elf_platform(CPUState *cs);
-#endif
#endif /* LINUX_USER_LOADER_H */
diff --git a/linux-user/aarch64/elfload.c b/linux-user/aarch64/elfload.c
index 92c8ea62c6..1030cb8094 100644
--- a/linux-user/aarch64/elfload.c
+++ b/linux-user/aarch64/elfload.c
@@ -342,3 +342,8 @@ const char *elf_hwcap2_str(uint32_t bit)
return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
}
+
+const char *get_elf_platform(CPUState *cs)
+{
+ return TARGET_BIG_ENDIAN ? "aarch64_be" : "aarch64";
+}
diff --git a/linux-user/arm/elfload.c b/linux-user/arm/elfload.c
index c7561b005b..7de1f13f4b 100644
--- a/linux-user/arm/elfload.c
+++ b/linux-user/arm/elfload.c
@@ -170,3 +170,32 @@ const char *elf_hwcap2_str(uint32_t bit)
return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
}
+
+const char *get_elf_platform(CPUState *cs)
+{
+ CPUARMState *env = cpu_env(cs);
+
+#if TARGET_BIG_ENDIAN
+# define END "b"
+#else
+# define END "l"
+#endif
+
+ if (arm_feature(env, ARM_FEATURE_V8)) {
+ return "v8" END;
+ } else if (arm_feature(env, ARM_FEATURE_V7)) {
+ if (arm_feature(env, ARM_FEATURE_M)) {
+ return "v7m" END;
+ } else {
+ return "v7" END;
+ }
+ } else if (arm_feature(env, ARM_FEATURE_V6)) {
+ return "v6" END;
+ } else if (arm_feature(env, ARM_FEATURE_V5)) {
+ return "v5" END;
+ } else {
+ return "v4" END;
+ }
+
+#undef END
+}
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index e6e509c0a6..0e41737cf1 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -309,6 +309,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
#ifdef TARGET_ARM
+#define ELF_PLATFORM get_elf_platform(thread_cpu)
+
#ifndef TARGET_AARCH64
/* 32 bit ARM definitions */
@@ -434,37 +436,6 @@ static bool init_guest_commpage(void)
return true;
}
-#define ELF_PLATFORM get_elf_platform()
-
-static const char *get_elf_platform(void)
-{
- CPUARMState *env = cpu_env(thread_cpu);
-
-#if TARGET_BIG_ENDIAN
-# define END "b"
-#else
-# define END "l"
-#endif
-
- if (arm_feature(env, ARM_FEATURE_V8)) {
- return "v8" END;
- } else if (arm_feature(env, ARM_FEATURE_V7)) {
- if (arm_feature(env, ARM_FEATURE_M)) {
- return "v7m" END;
- } else {
- return "v7" END;
- }
- } else if (arm_feature(env, ARM_FEATURE_V6)) {
- return "v6" END;
- } else if (arm_feature(env, ARM_FEATURE_V5)) {
- return "v5" END;
- } else {
- return "v4" END;
- }
-
-#undef END
-}
-
#if TARGET_BIG_ENDIAN
#include "elf.h"
#include "vdso-be8.c.inc"
@@ -487,11 +458,6 @@ static const VdsoImageInfo *vdso_image_info(uint32_t elf_flags)
#define ELF_ARCH EM_AARCH64
#define ELF_CLASS ELFCLASS64
-#if TARGET_BIG_ENDIAN
-# define ELF_PLATFORM "aarch64_be"
-#else
-# define ELF_PLATFORM "aarch64"
-#endif
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 20/46] linux-user/loongarch64: Create get_elf_platform
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (18 preceding siblings ...)
2025-08-27 23:19 ` [PULL 19/46] linux-user: Move get_elf_platform to arm/elfload.c Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 21/46] linux-user/hppa: " Richard Henderson
` (26 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Move the string literal to a new function.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loongarch64/target_elf.h | 1 +
linux-user/elfload.c | 2 +-
linux-user/loongarch64/elfload.c | 5 +++++
3 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/linux-user/loongarch64/target_elf.h b/linux-user/loongarch64/target_elf.h
index 037740d36f..eb17927325 100644
--- a/linux-user/loongarch64/target_elf.h
+++ b/linux-user/loongarch64/target_elf.h
@@ -7,5 +7,6 @@
#define LOONGARCH_TARGET_ELF_H
#define HAVE_ELF_HWCAP 1
+#define HAVE_ELF_PLATFORM 1
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 0e41737cf1..9d61feae30 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -665,7 +665,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-#define ELF_PLATFORM "loongarch"
+#define ELF_PLATFORM get_elf_platform(thread_cpu)
#endif /* TARGET_LOONGARCH64 */
diff --git a/linux-user/loongarch64/elfload.c b/linux-user/loongarch64/elfload.c
index ee4a85b8d6..911352840f 100644
--- a/linux-user/loongarch64/elfload.c
+++ b/linux-user/loongarch64/elfload.c
@@ -56,3 +56,8 @@ abi_ulong get_elf_hwcap(CPUState *cs)
return hwcaps;
}
+
+const char *get_elf_platform(CPUState *cs)
+{
+ return "loongarch";
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 21/46] linux-user/hppa: Create get_elf_platform
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (19 preceding siblings ...)
2025-08-27 23:19 ` [PULL 20/46] linux-user/loongarch64: Create get_elf_platform Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:19 ` [PULL 22/46] linux-user: Remove ELF_PLATFORM Richard Henderson
` (25 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Move the string literal to a new function.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/hppa/target_elf.h | 2 ++
linux-user/elfload.c | 2 +-
linux-user/hppa/elfload.c | 5 +++++
3 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/linux-user/hppa/target_elf.h b/linux-user/hppa/target_elf.h
index 5826ca2cd2..85be00584d 100644
--- a/linux-user/hppa/target_elf.h
+++ b/linux-user/hppa/target_elf.h
@@ -8,4 +8,6 @@
#ifndef HPPA_TARGET_ELF_H
#define HPPA_TARGET_ELF_H
+#define HAVE_ELF_PLATFORM 1
+
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 9d61feae30..83cb6731ec 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -1046,7 +1046,7 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_PARISC
-#define ELF_PLATFORM "PARISC"
+#define ELF_PLATFORM get_elf_platform(thread_cpu)
#define STACK_GROWS_DOWN 0
#define STACK_ALIGNMENT 64
diff --git a/linux-user/hppa/elfload.c b/linux-user/hppa/elfload.c
index 2274fcbde4..9dd3fe092a 100644
--- a/linux-user/hppa/elfload.c
+++ b/linux-user/hppa/elfload.c
@@ -9,3 +9,8 @@ const char *get_elf_cpu_model(uint32_t eflags)
{
return "hppa";
}
+
+const char *get_elf_platform(CPUState *cs)
+{
+ return "PARISC";
+}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 22/46] linux-user: Remove ELF_PLATFORM
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (20 preceding siblings ...)
2025-08-27 23:19 ` [PULL 21/46] linux-user/hppa: " Richard Henderson
@ 2025-08-27 23:19 ` Richard Henderson
2025-08-27 23:20 ` [PULL 23/46] linux-user: Move get_elf_base_platform to mips/elfload.c Richard Henderson
` (24 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:19 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
All real definitions of ELF_PLATFORM are now identical, and the stub
definitions are NULL. Use HAVE_ELF_PLATFORM and provide a stub as a
fallback definition of get_elf_platform.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 83cb6731ec..d2d73b06fc 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -149,8 +149,6 @@ typedef abi_int target_pid_t;
#ifdef TARGET_I386
-#define ELF_PLATFORM get_elf_platform(thread_cpu)
-
#ifdef TARGET_X86_64
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_X86_64
@@ -309,8 +307,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
#ifdef TARGET_ARM
-#define ELF_PLATFORM get_elf_platform(thread_cpu)
-
#ifndef TARGET_AARCH64
/* 32 bit ARM definitions */
@@ -665,8 +661,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 4096
-#define ELF_PLATFORM get_elf_platform(thread_cpu)
-
#endif /* TARGET_LOONGARCH64 */
#ifdef TARGET_MIPS
@@ -846,8 +840,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
(*regs)[33] = tswapreg(cpu_get_sr(env));
}
-#define ELF_PLATFORM NULL
-
#endif /* TARGET_OPENRISC */
#ifdef TARGET_SH4
@@ -1046,7 +1038,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_PARISC
-#define ELF_PLATFORM get_elf_platform(thread_cpu)
#define STACK_GROWS_DOWN 0
#define STACK_ALIGNMENT 64
@@ -1182,10 +1173,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#define ELF_BASE_PLATFORM (NULL)
#endif
-#ifndef ELF_PLATFORM
-#define ELF_PLATFORM (NULL)
-#endif
-
#ifndef ELF_MACHINE
#define ELF_MACHINE ELF_ARCH
#endif
@@ -1229,6 +1216,9 @@ abi_ulong get_elf_hwcap(CPUState *cs) { return 0; }
abi_ulong get_elf_hwcap2(CPUState *cs) { g_assert_not_reached(); }
#define HAVE_ELF_HWCAP2 0
#endif
+#ifndef HAVE_ELF_PLATFORM
+const char *get_elf_platform(CPUState *cs) { return NULL; }
+#endif
#include "elf.h"
@@ -1699,7 +1689,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
}
u_platform = 0;
- k_platform = ELF_PLATFORM;
+ k_platform = get_elf_platform(thread_cpu);
if (k_platform) {
size_t len = strlen(k_platform) + 1;
if (STACK_GROWS_DOWN) {
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 23/46] linux-user: Move get_elf_base_platform to mips/elfload.c
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (21 preceding siblings ...)
2025-08-27 23:19 ` [PULL 22/46] linux-user: Remove ELF_PLATFORM Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 24/46] linux-user: Move target_cpu_copy_regs decl to qemu.h Richard Henderson
` (23 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Pass in CPUState; define HAVE_ELF_BASE_PLATFORM.
Since this was the only instance of ELF_BASE_PLATFORM, go ahead and
provide the stub definition for other platforms.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loader.h | 1 +
linux-user/mips/target_elf.h | 1 +
linux-user/mips64/target_elf.h | 1 +
linux-user/elfload.c | 40 ++++------------------------------
linux-user/mips/elfload.c | 30 +++++++++++++++++++++++++
5 files changed, 37 insertions(+), 36 deletions(-)
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 440871466c..42cba90dea 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -106,5 +106,6 @@ abi_ulong get_elf_hwcap2(CPUState *cs);
const char *elf_hwcap_str(uint32_t bit);
const char *elf_hwcap2_str(uint32_t bit);
const char *get_elf_platform(CPUState *cs);
+const char *get_elf_base_platform(CPUState *cs);
#endif /* LINUX_USER_LOADER_H */
diff --git a/linux-user/mips/target_elf.h b/linux-user/mips/target_elf.h
index 877f8347d7..08e699c085 100644
--- a/linux-user/mips/target_elf.h
+++ b/linux-user/mips/target_elf.h
@@ -9,5 +9,6 @@
#define MIPS_TARGET_ELF_H
#define HAVE_ELF_HWCAP 1
+#define HAVE_ELF_BASE_PLATFORM 1
#endif
diff --git a/linux-user/mips64/target_elf.h b/linux-user/mips64/target_elf.h
index c0347e5cb6..24bb7fcd3f 100644
--- a/linux-user/mips64/target_elf.h
+++ b/linux-user/mips64/target_elf.h
@@ -9,5 +9,6 @@
#define MIPS64_TARGET_ELF_H
#define HAVE_ELF_HWCAP 1
+#define HAVE_ELF_BASE_PLATFORM 1
#endif
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index d2d73b06fc..4facaa7e27 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -679,37 +679,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define elf_check_abi(x) (!((x) & EF_MIPS_ABI2))
#endif
-#define ELF_BASE_PLATFORM get_elf_base_platform()
-
-#define MATCH_PLATFORM_INSN(_flags, _base_platform) \
- do { if ((cpu->env.insn_flags & (_flags)) == _flags) \
- { return _base_platform; } } while (0)
-
-static const char *get_elf_base_platform(void)
-{
- MIPSCPU *cpu = MIPS_CPU(thread_cpu);
-
- /* 64 bit ISAs goes first */
- MATCH_PLATFORM_INSN(CPU_MIPS64R6, "mips64r6");
- MATCH_PLATFORM_INSN(CPU_MIPS64R5, "mips64r5");
- MATCH_PLATFORM_INSN(CPU_MIPS64R2, "mips64r2");
- MATCH_PLATFORM_INSN(CPU_MIPS64R1, "mips64");
- MATCH_PLATFORM_INSN(CPU_MIPS5, "mips5");
- MATCH_PLATFORM_INSN(CPU_MIPS4, "mips4");
- MATCH_PLATFORM_INSN(CPU_MIPS3, "mips3");
-
- /* 32 bit ISAs */
- MATCH_PLATFORM_INSN(CPU_MIPS32R6, "mips32r6");
- MATCH_PLATFORM_INSN(CPU_MIPS32R5, "mips32r5");
- MATCH_PLATFORM_INSN(CPU_MIPS32R2, "mips32r2");
- MATCH_PLATFORM_INSN(CPU_MIPS32R1, "mips32");
- MATCH_PLATFORM_INSN(CPU_MIPS2, "mips2");
-
- /* Fallback */
- return "mips";
-}
-#undef MATCH_PLATFORM_INSN
-
static inline void init_thread(struct target_pt_regs *regs,
struct image_info *infop)
{
@@ -1169,10 +1138,6 @@ static inline void init_thread(struct target_pt_regs *regs,
#endif /* TARGET_HEXAGON */
-#ifndef ELF_BASE_PLATFORM
-#define ELF_BASE_PLATFORM (NULL)
-#endif
-
#ifndef ELF_MACHINE
#define ELF_MACHINE ELF_ARCH
#endif
@@ -1219,6 +1184,9 @@ abi_ulong get_elf_hwcap2(CPUState *cs) { g_assert_not_reached(); }
#ifndef HAVE_ELF_PLATFORM
const char *get_elf_platform(CPUState *cs) { return NULL; }
#endif
+#ifndef HAVE_ELF_BASE_PLATFORM
+const char *get_elf_base_platform(CPUState *cs) { return NULL; }
+#endif
#include "elf.h"
@@ -1673,7 +1641,7 @@ static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc,
}
u_base_platform = 0;
- k_base_platform = ELF_BASE_PLATFORM;
+ k_base_platform = get_elf_base_platform(thread_cpu);
if (k_base_platform) {
size_t len = strlen(k_base_platform) + 1;
if (STACK_GROWS_DOWN) {
diff --git a/linux-user/mips/elfload.c b/linux-user/mips/elfload.c
index 739f71c21b..c353ccc1ad 100644
--- a/linux-user/mips/elfload.c
+++ b/linux-user/mips/elfload.c
@@ -92,3 +92,33 @@ abi_ulong get_elf_hwcap(CPUState *cs)
#undef GET_FEATURE_REG_EQU
#undef GET_FEATURE_REG_SET
#undef GET_FEATURE_INSN
+
+#define MATCH_PLATFORM_INSN(_flags, _base_platform) \
+ do { if ((cpu->env.insn_flags & (_flags)) == _flags) \
+ { return _base_platform; } } while (0)
+
+const char *get_elf_base_platform(CPUState *cs)
+{
+ MIPSCPU *cpu = MIPS_CPU(cs);
+
+ /* 64 bit ISAs goes first */
+ MATCH_PLATFORM_INSN(CPU_MIPS64R6, "mips64r6");
+ MATCH_PLATFORM_INSN(CPU_MIPS64R5, "mips64r5");
+ MATCH_PLATFORM_INSN(CPU_MIPS64R2, "mips64r2");
+ MATCH_PLATFORM_INSN(CPU_MIPS64R1, "mips64");
+ MATCH_PLATFORM_INSN(CPU_MIPS5, "mips5");
+ MATCH_PLATFORM_INSN(CPU_MIPS4, "mips4");
+ MATCH_PLATFORM_INSN(CPU_MIPS3, "mips3");
+
+ /* 32 bit ISAs */
+ MATCH_PLATFORM_INSN(CPU_MIPS32R6, "mips32r6");
+ MATCH_PLATFORM_INSN(CPU_MIPS32R5, "mips32r5");
+ MATCH_PLATFORM_INSN(CPU_MIPS32R2, "mips32r2");
+ MATCH_PLATFORM_INSN(CPU_MIPS32R1, "mips32");
+ MATCH_PLATFORM_INSN(CPU_MIPS2, "mips2");
+
+ /* Fallback */
+ return "mips";
+}
+
+#undef MATCH_PLATFORM_INSN
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 24/46] linux-user: Move target_cpu_copy_regs decl to qemu.h
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (22 preceding siblings ...)
2025-08-27 23:20 ` [PULL 23/46] linux-user: Move get_elf_base_platform to mips/elfload.c Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 25/46] linux-user: Create do_init_main_thread Richard Henderson
` (22 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
The function is not used by bsd-user, so placement
within include/user/cpu_loop.h is not ideal.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
include/user/cpu_loop.h | 4 ----
linux-user/qemu.h | 3 +++
2 files changed, 3 insertions(+), 4 deletions(-)
diff --git a/include/user/cpu_loop.h b/include/user/cpu_loop.h
index ad8a1d711f..346e37ede8 100644
--- a/include/user/cpu_loop.h
+++ b/include/user/cpu_loop.h
@@ -81,8 +81,4 @@ void target_exception_dump(CPUArchState *env, const char *fmt, int code);
#define EXCP_DUMP(env, fmt, code) \
target_exception_dump(env, fmt, code)
-typedef struct target_pt_regs target_pt_regs;
-
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs);
-
#endif
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 4d6fad28c6..0c3cfe93a1 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -359,4 +359,7 @@ void *lock_user_string(abi_ulong guest_addr);
/* Clone cpu state */
CPUArchState *cpu_copy(CPUArchState *env);
+typedef struct target_pt_regs target_pt_regs;
+void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs);
+
#endif /* QEMU_H */
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 25/46] linux-user: Create do_init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (23 preceding siblings ...)
2025-08-27 23:20 ` [PULL 24/46] linux-user: Move target_cpu_copy_regs decl to qemu.h Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 26/46] linux-user/i386: Create init_main_thread Richard Henderson
` (21 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Provide a unified function to initialize the main thread.
Keep target_pt_regs isolated to this function.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loader.h | 5 ++---
linux-user/elfload.c | 7 +++++--
linux-user/linuxload.c | 6 ++----
linux-user/main.c | 10 +++-------
4 files changed, 12 insertions(+), 16 deletions(-)
diff --git a/linux-user/loader.h b/linux-user/loader.h
index 42cba90dea..e0291cc3b0 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -82,12 +82,11 @@ struct linux_binprm {
int (*core_dump)(int, const CPUArchState *); /* coredump routine */
};
-void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
+void do_init_main_thread(CPUState *cs, struct image_info *infop);
abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
abi_ulong stringp, int push_ptr);
int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
- struct target_pt_regs *regs, struct image_info *infop,
- struct linux_binprm *);
+ struct image_info *infop, struct linux_binprm *);
uint32_t get_elf_eflags(int fd);
int load_elf_binary(struct linux_binprm *bprm, struct image_info *info);
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 4facaa7e27..6fce74f45a 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -3619,7 +3619,10 @@ static int elf_core_dump(int signr, const CPUArchState *env)
}
#endif /* USE_ELF_CORE_DUMP */
-void do_init_thread(struct target_pt_regs *regs, struct image_info *infop)
+void do_init_main_thread(CPUState *cs, struct image_info *infop)
{
- init_thread(regs, infop);
+ target_pt_regs regs = { };
+
+ init_thread(®s, infop);
+ target_cpu_copy_regs(cpu_env(cs), ®s);
}
diff --git a/linux-user/linuxload.c b/linux-user/linuxload.c
index 37f132be4a..85d700953e 100644
--- a/linux-user/linuxload.c
+++ b/linux-user/linuxload.c
@@ -139,8 +139,7 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
}
int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
- struct target_pt_regs *regs, struct image_info *infop,
- struct linux_binprm *bprm)
+ struct image_info *infop, struct linux_binprm *bprm)
{
int retval;
@@ -175,8 +174,7 @@ int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
return retval;
}
- /* Success. Initialize important registers. */
- do_init_thread(regs, infop);
+ /* Success. */
return 0;
}
diff --git a/linux-user/main.c b/linux-user/main.c
index ad1a29d198..e21842bde9 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -696,7 +696,6 @@ static int parse_args(int argc, char **argv)
int main(int argc, char **argv, char **envp)
{
- struct target_pt_regs regs1, *regs = ®s1;
struct image_info info1, *info = &info1;
struct linux_binprm bprm;
TaskState *ts;
@@ -762,9 +761,6 @@ int main(int argc, char **argv, char **envp)
trace_init_file();
qemu_plugin_load_list(&plugins, &error_fatal);
- /* Zero out regs */
- memset(regs, 0, sizeof(struct target_pt_regs));
-
/* Zero out image_info */
memset(info, 0, sizeof(struct image_info));
@@ -988,8 +984,8 @@ int main(int argc, char **argv, char **envp)
fd_trans_init();
- ret = loader_exec(execfd, exec_path, target_argv, target_environ, regs,
- info, &bprm);
+ ret = loader_exec(execfd, exec_path, target_argv, target_environ,
+ info, &bprm);
if (ret != 0) {
printf("Error while loading %s: %s\n", exec_path, strerror(-ret));
_exit(EXIT_FAILURE);
@@ -1041,7 +1037,7 @@ int main(int argc, char **argv, char **envp)
the real value of GUEST_BASE into account. */
tcg_prologue_init();
- target_cpu_copy_regs(env, regs);
+ do_init_main_thread(cpu, info);
if (gdbstub) {
gdbserver_start(gdbstub, &error_fatal);
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 26/46] linux-user/i386: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (24 preceding siblings ...)
2025-08-27 23:20 ` [PULL 25/46] linux-user: Create do_init_main_thread Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 27/46] linux-user/arm: " Richard Henderson
` (20 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Temporarily introduce HAVE_INIT_MAIN_THREAD during conversion.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/qemu.h | 1 +
linux-user/elfload.c | 29 +++++------------------
linux-user/i386/cpu_loop.c | 48 +++++++++++++++++---------------------
3 files changed, 29 insertions(+), 49 deletions(-)
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 0c3cfe93a1..8a9500d4f4 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -361,5 +361,6 @@ CPUArchState *cpu_copy(CPUArchState *env);
typedef struct target_pt_regs target_pt_regs;
void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs);
+void init_main_thread(CPUState *cs, struct image_info *info);
#endif /* QEMU_H */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 6fce74f45a..89f3972253 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -149,17 +149,12 @@ typedef abi_int target_pid_t;
#ifdef TARGET_I386
+#define HAVE_INIT_MAIN_THREAD
+
#ifdef TARGET_X86_64
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_X86_64
-static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
-{
- regs->rax = 0;
- regs->rsp = infop->start_stack;
- regs->rip = infop->entry;
-}
-
#define ELF_NREG 27
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -237,22 +232,6 @@ static bool init_guest_commpage(void)
#define EXSTACK_DEFAULT true
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- regs->esp = infop->start_stack;
- regs->eip = infop->entry;
-
- /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
- starts %edx contains a pointer to a function which might be
- registered using `atexit'. This provides a mean for the
- dynamic linker to call DT_FINI functions for shared libraries
- that have been loaded before the code runs.
-
- A value of 0 tells we have no such handler. */
- regs->edx = 0;
-}
-
#define ELF_NREG 17
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -3621,8 +3600,12 @@ static int elf_core_dump(int signr, const CPUArchState *env)
void do_init_main_thread(CPUState *cs, struct image_info *infop)
{
+#ifdef HAVE_INIT_MAIN_THREAD
+ init_main_thread(cs, infop);
+#else
target_pt_regs regs = { };
init_thread(®s, infop);
target_cpu_copy_regs(cpu_env(cs), ®s);
+#endif
}
diff --git a/linux-user/i386/cpu_loop.c b/linux-user/i386/cpu_loop.c
index d96d5553fa..7b2d8b03d8 100644
--- a/linux-user/i386/cpu_loop.c
+++ b/linux-user/i386/cpu_loop.c
@@ -331,11 +331,10 @@ static void target_cpu_free(void *obj)
g_free(obj);
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cpu, struct image_info *info)
{
- CPUState *cpu = env_cpu(env);
+ CPUArchState *env = cpu_env(cpu);
bool is64 = (env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM) != 0;
- int i;
OBJECT(cpu)->free = target_cpu_free;
env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
@@ -361,28 +360,25 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
/* flags setup : we activate the IRQs by default as in user mode */
env->eflags |= IF_MASK;
- /* linux register setup */
-#ifndef TARGET_ABI32
- env->regs[R_EAX] = regs->rax;
- env->regs[R_EBX] = regs->rbx;
- env->regs[R_ECX] = regs->rcx;
- env->regs[R_EDX] = regs->rdx;
- env->regs[R_ESI] = regs->rsi;
- env->regs[R_EDI] = regs->rdi;
- env->regs[R_EBP] = regs->rbp;
- env->regs[R_ESP] = regs->rsp;
- env->eip = regs->rip;
-#else
- env->regs[R_EAX] = regs->eax;
- env->regs[R_EBX] = regs->ebx;
- env->regs[R_ECX] = regs->ecx;
- env->regs[R_EDX] = regs->edx;
- env->regs[R_ESI] = regs->esi;
- env->regs[R_EDI] = regs->edi;
- env->regs[R_EBP] = regs->ebp;
- env->regs[R_ESP] = regs->esp;
- env->eip = regs->eip;
-#endif
+ /*
+ * Linux register setup.
+ *
+ * SVR4/i386 ABI (pages 3-31, 3-32) says that when the program
+ * starts %edx contains a pointer to a function which might be
+ * registered using `atexit'. This provides a mean for the
+ * dynamic linker to call DT_FINI functions for shared libraries
+ * that have been loaded before the code runs.
+ * A value of 0 tells we have no such handler.
+ *
+ * This applies to x86_64 as well as i386.
+ *
+ * That said, the kernel's ELF_PLAT_INIT simply zeros all of the general
+ * registers. Note that x86_cpu_reset_hold will set %edx to cpuid_version;
+ * clear all general registers defensively.
+ */
+ memset(env->regs, 0, sizeof(env->regs));
+ env->regs[R_ESP] = info->start_stack;
+ env->eip = info->entry;
/* linux interrupt setup */
#ifndef TARGET_ABI32
@@ -394,7 +390,7 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
PROT_READ|PROT_WRITE,
MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
idt_table = g2h_untagged(env->idt.base);
- for (i = 0; i < 20; i++) {
+ for (int i = 0; i < 20; i++) {
set_idt(i, 0, is64);
}
set_idt(3, 3, is64);
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 27/46] linux-user/arm: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (25 preceding siblings ...)
2025-08-27 23:20 ` [PULL 26/46] linux-user/i386: Create init_main_thread Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 28/46] linux-user/arm: Remove a.out startup remenents Richard Henderson
` (19 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/arm/cpu_loop.c | 51 ++++++++++++++++++++++++++++++++-------
linux-user/elfload.c | 41 +------------------------------
2 files changed, 43 insertions(+), 49 deletions(-)
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index 9d54422736..739e1607e3 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -480,17 +480,50 @@ void cpu_loop(CPUARMState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- CPUState *cpu = env_cpu(env);
- TaskState *ts = get_task_state(cpu);
- struct image_info *info = ts->info;
- int i;
+ CPUARMState *env = cpu_env(cs);
+ abi_ptr stack = info->start_stack;
+ abi_ptr entry = info->entry;
- cpsr_write(env, regs->uregs[16], CPSR_USER | CPSR_EXEC,
- CPSRWriteByInstr);
- for(i = 0; i < 16; i++) {
- env->regs[i] = regs->uregs[i];
+ cpsr_write(env, ARM_CPU_MODE_USR | (entry & 1 ? CPSR_T : 0),
+ CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
+
+ env->regs[15] = entry & 0xfffffffe;
+ env->regs[13] = stack;
+
+ /* FIXME - what to for failure of get_user()? */
+ get_user_ual(env->regs[2], stack + 8); /* envp */
+ get_user_ual(env->regs[1], stack + 4); /* envp */
+
+ /*
+ * Per the SVR4 ABI, r0 contains a pointer to a function to be
+ * registered with atexit. A value of 0 means we have no such handler.
+ */
+ env->regs[0] = 0;
+
+ /* For uClinux PIC binaries. */
+ /* XXX: Linux does this only on ARM with no MMU (do we care?) */
+ env->regs[10] = info->start_data;
+
+ /* Support ARM FDPIC. */
+ if (info_is_fdpic(info)) {
+ /*
+ * As described in the ABI document, r7 points to the loadmap info
+ * prepared by the kernel. If an interpreter is needed, r8 points
+ * to the interpreter loadmap and r9 points to the interpreter
+ * PT_DYNAMIC info. If no interpreter is needed, r8 is zero, and
+ * r9 points to the main program PT_DYNAMIC info.
+ */
+ env->regs[7] = info->loadmap_addr;
+ if (info->interpreter_loadmap_addr) {
+ /* Executable is dynamically loaded. */
+ env->regs[8] = info->interpreter_loadmap_addr;
+ env->regs[9] = info->interpreter_pt_dynamic_addr;
+ } else {
+ env->regs[8] = 0;
+ env->regs[9] = info->pt_dynamic_addr;
+ }
}
if (TARGET_BIG_ENDIAN) {
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 89f3972253..9586873954 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -293,46 +293,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
#define ELF_CLASS ELFCLASS32
#define EXSTACK_DEFAULT true
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- abi_long stack = infop->start_stack;
- memset(regs, 0, sizeof(*regs));
-
- regs->uregs[16] = ARM_CPU_MODE_USR;
- if (infop->entry & 1) {
- regs->uregs[16] |= CPSR_T;
- }
- regs->uregs[15] = infop->entry & 0xfffffffe;
- regs->uregs[13] = infop->start_stack;
- /* FIXME - what to for failure of get_user()? */
- get_user_ual(regs->uregs[2], stack + 8); /* envp */
- get_user_ual(regs->uregs[1], stack + 4); /* envp */
- /* XXX: it seems that r0 is zeroed after ! */
- regs->uregs[0] = 0;
- /* For uClinux PIC binaries. */
- /* XXX: Linux does this only on ARM with no MMU (do we care ?) */
- regs->uregs[10] = infop->start_data;
-
- /* Support ARM FDPIC. */
- if (info_is_fdpic(infop)) {
- /* As described in the ABI document, r7 points to the loadmap info
- * prepared by the kernel. If an interpreter is needed, r8 points
- * to the interpreter loadmap and r9 points to the interpreter
- * PT_DYNAMIC info. If no interpreter is needed, r8 is zero, and
- * r9 points to the main program PT_DYNAMIC info.
- */
- regs->uregs[7] = infop->loadmap_addr;
- if (infop->interpreter_loadmap_addr) {
- /* Executable is dynamically loaded. */
- regs->uregs[8] = infop->interpreter_loadmap_addr;
- regs->uregs[9] = infop->interpreter_pt_dynamic_addr;
- } else {
- regs->uregs[8] = 0;
- regs->uregs[9] = infop->pt_dynamic_addr;
- }
- }
-}
+#define HAVE_INIT_MAIN_THREAD
#define ELF_NREG 18
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 28/46] linux-user/arm: Remove a.out startup remenents
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (26 preceding siblings ...)
2025-08-27 23:20 ` [PULL 27/46] linux-user/arm: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 29/46] linux-user/aarch64: Create init_main_thread Richard Henderson
` (18 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
The setting of r1/r2 was removed in kernel commit acfdd4b1f7590d0
("ARM: 7791/1: a.out: remove partial a.out support"), and the
kernel commit message explains the history.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/arm/cpu_loop.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/linux-user/arm/cpu_loop.c b/linux-user/arm/cpu_loop.c
index 739e1607e3..9aeb9b0087 100644
--- a/linux-user/arm/cpu_loop.c
+++ b/linux-user/arm/cpu_loop.c
@@ -492,10 +492,6 @@ void init_main_thread(CPUState *cs, struct image_info *info)
env->regs[15] = entry & 0xfffffffe;
env->regs[13] = stack;
- /* FIXME - what to for failure of get_user()? */
- get_user_ual(env->regs[2], stack + 8); /* envp */
- get_user_ual(env->regs[1], stack + 4); /* envp */
-
/*
* Per the SVR4 ABI, r0 contains a pointer to a function to be
* registered with atexit. A value of 0 means we have no such handler.
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 29/46] linux-user/aarch64: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (27 preceding siblings ...)
2025-08-27 23:20 ` [PULL 28/46] linux-user/arm: Remove a.out startup remenents Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 30/46] linux-user/sparc: " Richard Henderson
` (17 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/aarch64/cpu_loop.c | 14 ++++++--------
linux-user/elfload.c | 10 +---------
2 files changed, 7 insertions(+), 17 deletions(-)
diff --git a/linux-user/aarch64/cpu_loop.c b/linux-user/aarch64/cpu_loop.c
index 030a630c93..4c4921152e 100644
--- a/linux-user/aarch64/cpu_loop.c
+++ b/linux-user/aarch64/cpu_loop.c
@@ -137,10 +137,10 @@ void cpu_loop(CPUARMState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
+ CPUARMState *env = cpu_env(cs);
ARMCPU *cpu = env_archcpu(env);
- int i;
if (!(arm_feature(env, ARM_FEATURE_AARCH64))) {
fprintf(stderr,
@@ -148,14 +148,12 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
exit(EXIT_FAILURE);
}
- for (i = 0; i < 31; i++) {
- env->xregs[i] = regs->regs[i];
- }
- env->pc = regs->pc;
- env->xregs[31] = regs->sp;
+ env->pc = info->entry & ~0x3ULL;
+ env->xregs[31] = info->start_stack;
+
#if TARGET_BIG_ENDIAN
env->cp15.sctlr_el[1] |= SCTLR_E0E;
- for (i = 1; i < 4; ++i) {
+ for (int i = 1; i < 4; ++i) {
env->cp15.sctlr_el[i] |= SCTLR_EE;
}
arm_rebuild_hflags(env);
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 9586873954..f93afbdcea 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -395,15 +395,7 @@ static const VdsoImageInfo *vdso_image_info(uint32_t elf_flags)
#define ELF_ARCH EM_AARCH64
#define ELF_CLASS ELFCLASS64
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- abi_long stack = infop->start_stack;
- memset(regs, 0, sizeof(*regs));
-
- regs->pc = infop->entry & ~0x3ULL;
- regs->sp = stack;
-}
+#define HAVE_INIT_MAIN_THREAD
#define ELF_NREG 34
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 30/46] linux-user/sparc: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (28 preceding siblings ...)
2025-08-27 23:20 ` [PULL 29/46] linux-user/aarch64: Create init_main_thread Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 31/46] linux-user/ppc: " Richard Henderson
` (16 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 12 ++----------
linux-user/sparc/cpu_loop.c | 16 +++++++---------
2 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index f93afbdcea..887a3a1cb2 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -438,16 +438,8 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
# define ELF_ARCH EM_SPARCV9
#endif
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- /* Note that target_cpu_copy_regs does not read psr/tstate. */
- regs->pc = infop->entry;
- regs->npc = regs->pc + 4;
- regs->y = 0;
- regs->u_regs[14] = (infop->start_stack - 16 * sizeof(abi_ulong)
- - TARGET_STACK_BIAS);
-}
+#define HAVE_INIT_MAIN_THREAD
+
#endif /* TARGET_SPARC */
#ifdef TARGET_PPC
diff --git a/linux-user/sparc/cpu_loop.c b/linux-user/sparc/cpu_loop.c
index 68f1e8ecd4..7d30cd1ff2 100644
--- a/linux-user/sparc/cpu_loop.c
+++ b/linux-user/sparc/cpu_loop.c
@@ -357,14 +357,12 @@ void cpu_loop (CPUSPARCState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- int i;
- env->pc = regs->pc;
- env->npc = regs->npc;
- env->y = regs->y;
- for(i = 0; i < 8; i++)
- env->gregs[i] = regs->u_regs[i];
- for(i = 0; i < 8; i++)
- env->regwptr[i] = regs->u_regs[i + 8];
+ CPUArchState *env = cpu_env(cs);
+
+ env->pc = info->entry;
+ env->npc = env->pc + 4;
+ env->regwptr[WREG_SP] = (info->start_stack - 16 * sizeof(abi_ulong)
+ - TARGET_STACK_BIAS);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 31/46] linux-user/ppc: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (29 preceding siblings ...)
2025-08-27 23:20 ` [PULL 30/46] linux-user/sparc: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 32/46] linux-user/loongarch64: " Richard Henderson
` (15 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 17 +----------------
linux-user/ppc/cpu_loop.c | 26 ++++++++++++++++++--------
2 files changed, 19 insertions(+), 24 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 887a3a1cb2..a30431c7a2 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -485,22 +485,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \
} while (0)
-static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
-{
- _regs->gpr[1] = infop->start_stack;
-#if defined(TARGET_PPC64)
- if (get_ppc64_abi(infop) < 2) {
- uint64_t val;
- get_user_u64(val, infop->entry + 8);
- _regs->gpr[2] = val + infop->load_bias;
- get_user_u64(val, infop->entry);
- infop->entry = val + infop->load_bias;
- } else {
- _regs->gpr[12] = infop->entry; /* r12 set to global entry address */
- }
-#endif
- _regs->nip = infop->entry;
-}
+#define HAVE_INIT_MAIN_THREAD
/* See linux kernel: arch/powerpc/include/asm/elf.h. */
#define ELF_NREG 48
diff --git a/linux-user/ppc/cpu_loop.c b/linux-user/ppc/cpu_loop.c
index 2a0efaffcd..22885ffd90 100644
--- a/linux-user/ppc/cpu_loop.c
+++ b/linux-user/ppc/cpu_loop.c
@@ -378,21 +378,31 @@ void cpu_loop(CPUPPCState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- int i;
+ CPUArchState *env = cpu_env(cs);
+ abi_ptr entry = info->entry;
+
+ env->gpr[1] = info->start_stack;
+
+#ifdef TARGET_PPC64
+ if (get_ppc64_abi(info) < 2) {
+ uint64_t val;
+ get_user_u64(val, entry + 8);
+ env->gpr[2] = val + info->load_bias;
+ get_user_u64(val, entry);
+ entry = val + info->load_bias;
+ } else {
+ env->gpr[12] = entry; /* r12 set to global entry address */
+ }
-#if defined(TARGET_PPC64)
int flag = (env->insns_flags2 & PPC2_BOOKE206) ? MSR_CM : MSR_SF;
#if defined(TARGET_ABI32)
ppc_store_msr(env, env->msr & ~((target_ulong)1 << flag));
#else
ppc_store_msr(env, env->msr | (target_ulong)1 << flag);
#endif
-#endif
+#endif /* TARGET_PPC64 */
- env->nip = regs->nip;
- for(i = 0; i < 32; i++) {
- env->gpr[i] = regs->gpr[i];
- }
+ env->nip = entry;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 32/46] linux-user/loongarch64: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (30 preceding siblings ...)
2025-08-27 23:20 ` [PULL 31/46] linux-user/ppc: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 33/46] linux-user/mips: " Richard Henderson
` (14 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Note that init_thread had set crmd in target_pt_regs, but
target_cpu_copy_regs did not copy to env. This turns out to be
ok because loongarch_cpu_reset_hold initializes CRMD properly.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 9 +--------
linux-user/loongarch64/cpu_loop.c | 11 ++++-------
2 files changed, 5 insertions(+), 15 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a30431c7a2..0feccfbe91 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -533,14 +533,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en
#define VDSO_HEADER "vdso.c.inc"
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- /*Set crmd PG,DA = 1,0 */
- regs->csr.crmd = 2 << 3;
- regs->csr.era = infop->entry;
- regs->regs[3] = infop->start_stack;
-}
+#define HAVE_INIT_MAIN_THREAD
/* See linux kernel: arch/loongarch/include/asm/elf.h */
#define ELF_NREG 45
diff --git a/linux-user/loongarch64/cpu_loop.c b/linux-user/loongarch64/cpu_loop.c
index ec8a06c88c..a0a4cbb7cc 100644
--- a/linux-user/loongarch64/cpu_loop.c
+++ b/linux-user/loongarch64/cpu_loop.c
@@ -120,13 +120,10 @@ void cpu_loop(CPULoongArchState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- int i;
-
- for (i = 0; i < 32; i++) {
- env->gpr[i] = regs->regs[i];
- }
- env->pc = regs->csr.era;
+ CPUArchState *env = cpu_env(cs);
+ env->pc = info->entry;
+ env->gpr[3] = info->start_stack;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 33/46] linux-user/mips: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (31 preceding siblings ...)
2025-08-27 23:20 ` [PULL 32/46] linux-user/loongarch64: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 34/46] linux-user/microblaze: " Richard Henderson
` (13 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Note that init_thread had set cp0_status in target_pt_regs, but
target_cpu_copy_regs did not copy to env. This turns out to be
ok because mips_cpu_reset_hold initializes CP0_Status properly.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 8 +-------
linux-user/mips/cpu_loop.c | 16 ++++++----------
2 files changed, 7 insertions(+), 17 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 0feccfbe91..ac96755b06 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -581,13 +581,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define elf_check_abi(x) (!((x) & EF_MIPS_ABI2))
#endif
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- regs->cp0_status = 2 << CP0St_KSU;
- regs->cp0_epc = infop->entry;
- regs->regs[29] = infop->start_stack;
-}
+#define HAVE_INIT_MAIN_THREAD
/* See linux kernel: arch/mips/include/asm/elf.h. */
#define ELF_NREG 45
diff --git a/linux-user/mips/cpu_loop.c b/linux-user/mips/cpu_loop.c
index 6405806eb0..e67b8a2e46 100644
--- a/linux-user/mips/cpu_loop.c
+++ b/linux-user/mips/cpu_loop.c
@@ -211,12 +211,9 @@ done_syscall:
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- CPUState *cpu = env_cpu(env);
- TaskState *ts = get_task_state(cpu);
- struct image_info *info = ts->info;
- int i;
+ CPUArchState *env = cpu_env(cs);
struct mode_req {
bool single;
@@ -245,12 +242,11 @@ void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
struct mode_req prog_req;
struct mode_req interp_req;
+ target_ulong entry = info->entry;
- for(i = 0; i < 32; i++) {
- env->active_tc.gpr[i] = regs->regs[i];
- }
- env->active_tc.PC = regs->cp0_epc & ~(target_ulong)1;
- if (regs->cp0_epc & 1) {
+ env->active_tc.gpr[29] = info->start_stack;
+ env->active_tc.PC = entry & ~(target_ulong)1;
+ if (entry & 1) {
env->hflags |= MIPS_HFLAG_M16;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 34/46] linux-user/microblaze: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (32 preceding siblings ...)
2025-08-27 23:20 ` [PULL 33/46] linux-user/mips: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 35/46] linux-user/openrisc: " Richard Henderson
` (12 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 8 +------
linux-user/microblaze/cpu_loop.c | 39 ++++----------------------------
2 files changed, 6 insertions(+), 41 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index ac96755b06..3f9ec49359 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -640,13 +640,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMIPSState *e
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_MICROBLAZE
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- regs->pc = infop->entry;
- regs->r1 = infop->start_stack;
-
-}
+#define HAVE_INIT_MAIN_THREAD
#define ELF_EXEC_PAGESIZE 4096
diff --git a/linux-user/microblaze/cpu_loop.c b/linux-user/microblaze/cpu_loop.c
index 87236c166f..d8277961c7 100644
--- a/linux-user/microblaze/cpu_loop.c
+++ b/linux-user/microblaze/cpu_loop.c
@@ -127,39 +127,10 @@ void cpu_loop(CPUMBState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- env->regs[0] = regs->r0;
- env->regs[1] = regs->r1;
- env->regs[2] = regs->r2;
- env->regs[3] = regs->r3;
- env->regs[4] = regs->r4;
- env->regs[5] = regs->r5;
- env->regs[6] = regs->r6;
- env->regs[7] = regs->r7;
- env->regs[8] = regs->r8;
- env->regs[9] = regs->r9;
- env->regs[10] = regs->r10;
- env->regs[11] = regs->r11;
- env->regs[12] = regs->r12;
- env->regs[13] = regs->r13;
- env->regs[14] = regs->r14;
- env->regs[15] = regs->r15;
- env->regs[16] = regs->r16;
- env->regs[17] = regs->r17;
- env->regs[18] = regs->r18;
- env->regs[19] = regs->r19;
- env->regs[20] = regs->r20;
- env->regs[21] = regs->r21;
- env->regs[22] = regs->r22;
- env->regs[23] = regs->r23;
- env->regs[24] = regs->r24;
- env->regs[25] = regs->r25;
- env->regs[26] = regs->r26;
- env->regs[27] = regs->r27;
- env->regs[28] = regs->r28;
- env->regs[29] = regs->r29;
- env->regs[30] = regs->r30;
- env->regs[31] = regs->r31;
- env->pc = regs->pc;
+ CPUArchState *env = cpu_env(cs);
+
+ env->pc = info->entry;
+ env->regs[1] = info->start_stack;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 35/46] linux-user/openrisc: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (33 preceding siblings ...)
2025-08-27 23:20 ` [PULL 34/46] linux-user/microblaze: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 36/46] linux-user/sh4: " Richard Henderson
` (11 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 7 +------
linux-user/openrisc/cpu_loop.c | 11 ++++-------
2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 3f9ec49359..03c9539774 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -673,12 +673,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMBState *env
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- regs->pc = infop->entry;
- regs->gpr[1] = infop->start_stack;
-}
+#define HAVE_INIT_MAIN_THREAD
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 8192
diff --git a/linux-user/openrisc/cpu_loop.c b/linux-user/openrisc/cpu_loop.c
index 306b4f8eb4..8c72347a99 100644
--- a/linux-user/openrisc/cpu_loop.c
+++ b/linux-user/openrisc/cpu_loop.c
@@ -83,13 +83,10 @@ void cpu_loop(CPUOpenRISCState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- int i;
+ CPUArchState *env = cpu_env(cs);
- for (i = 0; i < 32; i++) {
- cpu_set_gpr(env, i, regs->gpr[i]);
- }
- env->pc = regs->pc;
- cpu_set_sr(env, regs->sr);
+ env->pc = info->entry;
+ cpu_set_gpr(env, 1, info->start_stack);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 36/46] linux-user/sh4: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (34 preceding siblings ...)
2025-08-27 23:20 ` [PULL 35/46] linux-user/openrisc: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 37/46] linux-user/m68k: " Richard Henderson
` (10 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 8 +-------
linux-user/sh4/cpu_loop.c | 10 ++++------
2 files changed, 5 insertions(+), 13 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 03c9539774..8604308a31 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -701,13 +701,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_SH
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- /* Check other registers XXXXX */
- regs->pc = infop->entry;
- regs->regs[15] = infop->start_stack;
-}
+#define HAVE_INIT_MAIN_THREAD
/* See linux kernel: arch/sh/include/asm/elf.h. */
#define ELF_NREG 23
diff --git a/linux-user/sh4/cpu_loop.c b/linux-user/sh4/cpu_loop.c
index ee9eff3428..259ea1cc8b 100644
--- a/linux-user/sh4/cpu_loop.c
+++ b/linux-user/sh4/cpu_loop.c
@@ -81,12 +81,10 @@ void cpu_loop(CPUSH4State *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- int i;
+ CPUArchState *env = cpu_env(cs);
- for(i = 0; i < 16; i++) {
- env->gregs[i] = regs->regs[i];
- }
- env->pc = regs->pc;
+ env->pc = info->entry;
+ env->gregs[15] = info->start_stack;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 37/46] linux-user/m68k: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (35 preceding siblings ...)
2025-08-27 23:20 ` [PULL 36/46] linux-user/sh4: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 38/46] linux-user/alpha: " Richard Henderson
` (9 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 11 +----------
linux-user/m68k/cpu_loop.c | 25 ++++++-------------------
2 files changed, 7 insertions(+), 29 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 8604308a31..46150586af 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -746,16 +746,7 @@ static inline void elf_core_copy_regs(target_elf_gregset_t *regs,
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_68K
-/* ??? Does this need to do anything?
- #define ELF_PLAT_INIT(_r) */
-
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- regs->usp = infop->start_stack;
- regs->sr = 0;
- regs->pc = infop->entry;
-}
+#define HAVE_INIT_MAIN_THREAD
/* See linux kernel: arch/m68k/include/asm/elf.h. */
#define ELF_NREG 20
diff --git a/linux-user/m68k/cpu_loop.c b/linux-user/m68k/cpu_loop.c
index 23693f3358..aca0bf23dc 100644
--- a/linux-user/m68k/cpu_loop.c
+++ b/linux-user/m68k/cpu_loop.c
@@ -92,24 +92,11 @@ void cpu_loop(CPUM68KState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- env->pc = regs->pc;
- env->dregs[0] = regs->d0;
- env->dregs[1] = regs->d1;
- env->dregs[2] = regs->d2;
- env->dregs[3] = regs->d3;
- env->dregs[4] = regs->d4;
- env->dregs[5] = regs->d5;
- env->dregs[6] = regs->d6;
- env->dregs[7] = regs->d7;
- env->aregs[0] = regs->a0;
- env->aregs[1] = regs->a1;
- env->aregs[2] = regs->a2;
- env->aregs[3] = regs->a3;
- env->aregs[4] = regs->a4;
- env->aregs[5] = regs->a5;
- env->aregs[6] = regs->a6;
- env->aregs[7] = regs->usp;
- env->sr = regs->sr;
+ CPUArchState *env = cpu_env(cs);
+
+ env->pc = info->entry;
+ env->aregs[7] = info->start_stack;
+ env->sr = 0;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 38/46] linux-user/alpha: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (36 preceding siblings ...)
2025-08-27 23:20 ` [PULL 37/46] linux-user/m68k: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 39/46] linux-user/s390x: " Richard Henderson
` (8 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Note that init_thread had set ps in target_pt_regs, but
target_cpu_copy_regs did not copy to env. This turns out to be
ok because alpha_cpu_initfn initializes flags properly.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/alpha/cpu_loop.c | 11 ++++-------
linux-user/elfload.c | 8 +-------
2 files changed, 5 insertions(+), 14 deletions(-)
diff --git a/linux-user/alpha/cpu_loop.c b/linux-user/alpha/cpu_loop.c
index 80ad536c5f..728b64906d 100644
--- a/linux-user/alpha/cpu_loop.c
+++ b/linux-user/alpha/cpu_loop.c
@@ -173,13 +173,10 @@ void cpu_loop(CPUAlphaState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- int i;
+ CPUArchState *env = cpu_env(cs);
- for(i = 0; i < 28; i++) {
- env->ir[i] = ((abi_ulong *)regs)[i];
- }
- env->ir[IR_SP] = regs->usp;
- env->pc = regs->pc;
+ env->pc = info->entry;
+ env->ir[IR_SP] = info->start_stack;
}
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 46150586af..a7de852d4d 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -786,13 +786,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUM68KState *e
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_ALPHA
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- regs->pc = infop->entry;
- regs->ps = 8;
- regs->usp = infop->start_stack;
-}
+#define HAVE_INIT_MAIN_THREAD
#define ELF_EXEC_PAGESIZE 8192
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 39/46] linux-user/s390x: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (37 preceding siblings ...)
2025-08-27 23:20 ` [PULL 38/46] linux-user/alpha: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 40/46] linux-user/riscv: " Richard Henderson
` (7 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 9 +--------
linux-user/s390x/cpu_loop.c | 15 ++++++++-------
2 files changed, 9 insertions(+), 15 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index a7de852d4d..16aa09214e 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -798,14 +798,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUM68KState *e
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_S390
-static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop)
-{
- regs->psw.addr = infop->entry;
- regs->psw.mask = PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT | \
- PSW_MASK_MCHECK | PSW_MASK_PSTATE | PSW_MASK_64 | \
- PSW_MASK_32;
- regs->gprs[15] = infop->start_stack;
-}
+#define HAVE_INIT_MAIN_THREAD
/* See linux kernel: arch/s390/include/uapi/asm/ptrace.h (s390_regs). */
#define ELF_NREG 27
diff --git a/linux-user/s390x/cpu_loop.c b/linux-user/s390x/cpu_loop.c
index c9124444ed..49e44548f8 100644
--- a/linux-user/s390x/cpu_loop.c
+++ b/linux-user/s390x/cpu_loop.c
@@ -180,12 +180,13 @@ void cpu_loop(CPUS390XState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- int i;
- for (i = 0; i < 16; i++) {
- env->regs[i] = regs->gprs[i];
- }
- env->psw.mask = regs->psw.mask;
- env->psw.addr = regs->psw.addr;
+ CPUArchState *env = cpu_env(cs);
+
+ env->psw.addr = info->entry;
+ env->psw.mask = PSW_MASK_DAT | PSW_MASK_IO | PSW_MASK_EXT |
+ PSW_MASK_MCHECK | PSW_MASK_PSTATE | PSW_MASK_64 |
+ PSW_MASK_32;
+ env->regs[15] = info->start_stack;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 40/46] linux-user/riscv: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (38 preceding siblings ...)
2025-08-27 23:20 ` [PULL 39/46] linux-user/s390x: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 41/46] linux-user/hppa: " Richard Henderson
` (6 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 7 +------
linux-user/riscv/cpu_loop.c | 10 ++++------
2 files changed, 5 insertions(+), 12 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 16aa09214e..556f11d720 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -849,12 +849,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define VDSO_HEADER "vdso-64.c.inc"
#endif
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- regs->sepc = infop->entry;
- regs->sp = infop->start_stack;
-}
+#define HAVE_INIT_MAIN_THREAD
#define ELF_EXEC_PAGESIZE 4096
diff --git a/linux-user/riscv/cpu_loop.c b/linux-user/riscv/cpu_loop.c
index 2dd30c7b28..b316281532 100644
--- a/linux-user/riscv/cpu_loop.c
+++ b/linux-user/riscv/cpu_loop.c
@@ -94,14 +94,12 @@ void cpu_loop(CPURISCVState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- CPUState *cpu = env_cpu(env);
- TaskState *ts = get_task_state(cpu);
- struct image_info *info = ts->info;
+ CPUArchState *env = cpu_env(cs);
- env->pc = regs->sepc;
- env->gpr[xSP] = regs->sp;
+ env->pc = info->entry;
+ env->gpr[xSP] = info->start_stack;
env->elf_flags = info->elf_flags;
if ((env->misa_ext & RVE) && !(env->elf_flags & EF_RISCV_RVE)) {
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 41/46] linux-user/hppa: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (39 preceding siblings ...)
2025-08-27 23:20 ` [PULL 40/46] linux-user/riscv: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 42/46] linux-user/xtensa: " Richard Henderson
` (5 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 13 +------------
linux-user/hppa/cpu_loop.c | 18 +++++++++++-------
2 files changed, 12 insertions(+), 19 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 556f11d720..4876e4b0a8 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -864,18 +864,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define VDSO_HEADER "vdso.c.inc"
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- regs->iaoq[0] = infop->entry | PRIV_USER;
- regs->iaoq[1] = regs->iaoq[0] + 4;
- regs->gr[23] = 0;
- regs->gr[24] = infop->argv;
- regs->gr[25] = infop->argc;
- /* The top-of-stack contains a linkage buffer. */
- regs->gr[30] = infop->start_stack + 64;
- regs->gr[31] = infop->entry;
-}
+#define HAVE_INIT_MAIN_THREAD
#define LO_COMMPAGE 0
diff --git a/linux-user/hppa/cpu_loop.c b/linux-user/hppa/cpu_loop.c
index 9abaad5ef8..3af50653bb 100644
--- a/linux-user/hppa/cpu_loop.c
+++ b/linux-user/hppa/cpu_loop.c
@@ -196,12 +196,16 @@ void cpu_loop(CPUHPPAState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- int i;
- for (i = 1; i < 32; i++) {
- env->gr[i] = regs->gr[i];
- }
- env->iaoq_f = regs->iaoq[0];
- env->iaoq_b = regs->iaoq[1];
+ CPUArchState *env = cpu_env(cs);
+
+ env->iaoq_f = info->entry | PRIV_USER;
+ env->iaoq_b = env->iaoq_f + 4;
+ env->gr[23] = 0;
+ env->gr[24] = info->argv;
+ env->gr[25] = info->argc;
+ /* The top-of-stack contains a linkage buffer. */
+ env->gr[30] = info->start_stack + 64;
+ env->gr[31] = info->entry;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 42/46] linux-user/xtensa: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (40 preceding siblings ...)
2025-08-27 23:20 ` [PULL 41/46] linux-user/hppa: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 43/46] linux-user/hexagon: " Richard Henderson
` (4 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 18 +-----------------
linux-user/xtensa/cpu_loop.c | 22 ++++++++++++++++------
2 files changed, 17 insertions(+), 23 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 4876e4b0a8..447a9be11d 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -905,23 +905,7 @@ static bool init_guest_commpage(void)
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_XTENSA
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- regs->windowbase = 0;
- regs->windowstart = 1;
- regs->areg[1] = infop->start_stack;
- regs->pc = infop->entry;
- if (info_is_fdpic(infop)) {
- regs->areg[4] = infop->loadmap_addr;
- regs->areg[5] = infop->interpreter_loadmap_addr;
- if (infop->interpreter_loadmap_addr) {
- regs->areg[6] = infop->interpreter_pt_dynamic_addr;
- } else {
- regs->areg[6] = infop->pt_dynamic_addr;
- }
- }
-}
+#define HAVE_INIT_MAIN_THREAD
/* See linux kernel: arch/xtensa/include/asm/elf.h. */
#define ELF_NREG 128
diff --git a/linux-user/xtensa/cpu_loop.c b/linux-user/xtensa/cpu_loop.c
index c0fcf743e7..43a194fc4a 100644
--- a/linux-user/xtensa/cpu_loop.c
+++ b/linux-user/xtensa/cpu_loop.c
@@ -238,12 +238,22 @@ void cpu_loop(CPUXtensaState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- int i;
- for (i = 0; i < 16; ++i) {
- env->regs[i] = regs->areg[i];
+ CPUArchState *env = cpu_env(cs);
+
+ env->sregs[WINDOW_BASE] = 0;
+ env->sregs[WINDOW_START] = 1;
+ env->regs[1] = info->start_stack;
+ env->pc = info->entry;
+
+ if (info_is_fdpic(info)) {
+ env->regs[4] = info->loadmap_addr;
+ env->regs[5] = info->interpreter_loadmap_addr;
+ if (info->interpreter_loadmap_addr) {
+ env->regs[6] = info->interpreter_pt_dynamic_addr;
+ } else {
+ env->regs[6] = info->pt_dynamic_addr;
+ }
}
- env->sregs[WINDOW_START] = regs->windowstart;
- env->pc = regs->pc;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 43/46] linux-user/hexagon: Create init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (41 preceding siblings ...)
2025-08-27 23:20 ` [PULL 42/46] linux-user/xtensa: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 44/46] linux-user: Remove do_init_main_thread Richard Henderson
` (3 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
Merge init_thread and target_cpu_copy_regs.
There's no point going through a target_pt_regs intermediate.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/elfload.c | 7 +------
linux-user/hexagon/cpu_loop.c | 8 +++++---
2 files changed, 6 insertions(+), 9 deletions(-)
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 447a9be11d..4417c2d99a 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -954,12 +954,7 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_HEXAGON
-static inline void init_thread(struct target_pt_regs *regs,
- struct image_info *infop)
-{
- regs->sepc = infop->entry;
- regs->sp = infop->start_stack;
-}
+#define HAVE_INIT_MAIN_THREAD
#endif /* TARGET_HEXAGON */
diff --git a/linux-user/hexagon/cpu_loop.c b/linux-user/hexagon/cpu_loop.c
index e18a0183b5..25c97edcae 100644
--- a/linux-user/hexagon/cpu_loop.c
+++ b/linux-user/hexagon/cpu_loop.c
@@ -79,9 +79,11 @@ void cpu_loop(CPUHexagonState *env)
}
}
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs)
+void init_main_thread(CPUState *cs, struct image_info *info)
{
- env->gpr[HEX_REG_PC] = regs->sepc;
- env->gpr[HEX_REG_SP] = regs->sp;
+ CPUArchState *env = cpu_env(cs);
+
+ env->gpr[HEX_REG_PC] = info->entry;
+ env->gpr[HEX_REG_SP] = info->start_stack;
env->gpr[HEX_REG_USR] = 0x56000;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 44/46] linux-user: Remove do_init_main_thread
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (42 preceding siblings ...)
2025-08-27 23:20 ` [PULL 43/46] linux-user/hexagon: " Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 45/46] linux-user: Add strace for rseq Richard Henderson
` (2 subsequent siblings)
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Peter Maydell
All targets have been converted, so we can call init_main_thread
directly. Remove do_init_main_thread and HAVE_INIT_MAIN_THREAD.
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
---
linux-user/loader.h | 1 -
linux-user/qemu.h | 2 --
linux-user/elfload.c | 46 --------------------------------------------
linux-user/main.c | 2 +-
4 files changed, 1 insertion(+), 50 deletions(-)
diff --git a/linux-user/loader.h b/linux-user/loader.h
index e0291cc3b0..6482c7c90c 100644
--- a/linux-user/loader.h
+++ b/linux-user/loader.h
@@ -82,7 +82,6 @@ struct linux_binprm {
int (*core_dump)(int, const CPUArchState *); /* coredump routine */
};
-void do_init_main_thread(CPUState *cs, struct image_info *infop);
abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
abi_ulong stringp, int push_ptr);
int loader_exec(int fdexec, const char *filename, char **argv, char **envp,
diff --git a/linux-user/qemu.h b/linux-user/qemu.h
index 8a9500d4f4..e4dca0c20f 100644
--- a/linux-user/qemu.h
+++ b/linux-user/qemu.h
@@ -359,8 +359,6 @@ void *lock_user_string(abi_ulong guest_addr);
/* Clone cpu state */
CPUArchState *cpu_copy(CPUArchState *env);
-typedef struct target_pt_regs target_pt_regs;
-void target_cpu_copy_regs(CPUArchState *env, target_pt_regs *regs);
void init_main_thread(CPUState *cs, struct image_info *info);
#endif /* QEMU_H */
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 4417c2d99a..fce4c05674 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -149,8 +149,6 @@ typedef abi_int target_pid_t;
#ifdef TARGET_I386
-#define HAVE_INIT_MAIN_THREAD
-
#ifdef TARGET_X86_64
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_X86_64
@@ -293,8 +291,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUX86State *en
#define ELF_CLASS ELFCLASS32
#define EXSTACK_DEFAULT true
-#define HAVE_INIT_MAIN_THREAD
-
#define ELF_NREG 18
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -395,8 +391,6 @@ static const VdsoImageInfo *vdso_image_info(uint32_t elf_flags)
#define ELF_ARCH EM_AARCH64
#define ELF_CLASS ELFCLASS64
-#define HAVE_INIT_MAIN_THREAD
-
#define ELF_NREG 34
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -438,8 +432,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
# define ELF_ARCH EM_SPARCV9
#endif
-#define HAVE_INIT_MAIN_THREAD
-
#endif /* TARGET_SPARC */
#ifdef TARGET_PPC
@@ -485,8 +477,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \
} while (0)
-#define HAVE_INIT_MAIN_THREAD
-
/* See linux kernel: arch/powerpc/include/asm/elf.h. */
#define ELF_NREG 48
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -533,8 +523,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUPPCState *en
#define VDSO_HEADER "vdso.c.inc"
-#define HAVE_INIT_MAIN_THREAD
-
/* See linux kernel: arch/loongarch/include/asm/elf.h */
#define ELF_NREG 45
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -581,8 +569,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define elf_check_abi(x) (!((x) & EF_MIPS_ABI2))
#endif
-#define HAVE_INIT_MAIN_THREAD
-
/* See linux kernel: arch/mips/include/asm/elf.h. */
#define ELF_NREG 45
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -640,8 +626,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMIPSState *e
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_MICROBLAZE
-#define HAVE_INIT_MAIN_THREAD
-
#define ELF_EXEC_PAGESIZE 4096
#define USE_ELF_CORE_DUMP
@@ -673,8 +657,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUMBState *env
#define ELF_CLASS ELFCLASS32
#define ELF_DATA ELFDATA2MSB
-#define HAVE_INIT_MAIN_THREAD
-
#define USE_ELF_CORE_DUMP
#define ELF_EXEC_PAGESIZE 8192
@@ -701,8 +683,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_SH
-#define HAVE_INIT_MAIN_THREAD
-
/* See linux kernel: arch/sh/include/asm/elf.h. */
#define ELF_NREG 23
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -746,8 +726,6 @@ static inline void elf_core_copy_regs(target_elf_gregset_t *regs,
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_68K
-#define HAVE_INIT_MAIN_THREAD
-
/* See linux kernel: arch/m68k/include/asm/elf.h. */
#define ELF_NREG 20
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -786,8 +764,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUM68KState *e
#define ELF_CLASS ELFCLASS64
#define ELF_ARCH EM_ALPHA
-#define HAVE_INIT_MAIN_THREAD
-
#define ELF_EXEC_PAGESIZE 8192
#endif /* TARGET_ALPHA */
@@ -798,8 +774,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs, const CPUM68KState *e
#define ELF_DATA ELFDATA2MSB
#define ELF_ARCH EM_S390
-#define HAVE_INIT_MAIN_THREAD
-
/* See linux kernel: arch/s390/include/uapi/asm/ptrace.h (s390_regs). */
#define ELF_NREG 27
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -849,8 +823,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define VDSO_HEADER "vdso-64.c.inc"
#endif
-#define HAVE_INIT_MAIN_THREAD
-
#define ELF_EXEC_PAGESIZE 4096
#endif /* TARGET_RISCV */
@@ -864,8 +836,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define VDSO_HEADER "vdso.c.inc"
-#define HAVE_INIT_MAIN_THREAD
-
#define LO_COMMPAGE 0
static bool init_guest_commpage(void)
@@ -905,8 +875,6 @@ static bool init_guest_commpage(void)
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_XTENSA
-#define HAVE_INIT_MAIN_THREAD
-
/* See linux kernel: arch/xtensa/include/asm/elf.h. */
#define ELF_NREG 128
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
@@ -954,8 +922,6 @@ static void elf_core_copy_regs(target_elf_gregset_t *regs,
#define ELF_CLASS ELFCLASS32
#define ELF_ARCH EM_HEXAGON
-#define HAVE_INIT_MAIN_THREAD
-
#endif /* TARGET_HEXAGON */
#ifndef ELF_MACHINE
@@ -3438,15 +3404,3 @@ static int elf_core_dump(int signr, const CPUArchState *env)
return ret;
}
#endif /* USE_ELF_CORE_DUMP */
-
-void do_init_main_thread(CPUState *cs, struct image_info *infop)
-{
-#ifdef HAVE_INIT_MAIN_THREAD
- init_main_thread(cs, infop);
-#else
- target_pt_regs regs = { };
-
- init_thread(®s, infop);
- target_cpu_copy_regs(cpu_env(cs), ®s);
-#endif
-}
diff --git a/linux-user/main.c b/linux-user/main.c
index e21842bde9..6edeeecef3 100644
--- a/linux-user/main.c
+++ b/linux-user/main.c
@@ -1037,7 +1037,7 @@ int main(int argc, char **argv, char **envp)
the real value of GUEST_BASE into account. */
tcg_prologue_init();
- do_init_main_thread(cpu, info);
+ init_main_thread(cpu, info);
if (gdbstub) {
gdbserver_start(gdbstub, &error_fatal);
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 45/46] linux-user: Add strace for rseq
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (43 preceding siblings ...)
2025-08-27 23:20 ` [PULL 44/46] linux-user: Remove do_init_main_thread Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-27 23:20 ` [PULL 46/46] linux-user: do not print IP socket options by default Richard Henderson
2025-08-28 2:47 ` [PULL 00/46] linux-user patch queue Richard Henderson
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Joel Stanley
From: Joel Stanley <joel@jms.id.au>
build/qemu-riscv64 -cpu rv64,v=on -d strace build/tests/tcg/riscv64-linux-user/test-vstart-overflow
1118081 riscv_hwprobe(0xffffbc038200,1,0,0,0,0) = 0
1118081 brk(NULL) = 0x0000000000085000
1118081 brk(0x0000000000085b00) = 0x0000000000085b00
1118081 set_tid_address(0x850f0) = 1118081
1118081 set_robust_list(0x85100,24) = -1 errno=38 (Function not implemented)
1118081 rseq(0x857c0,32,0,0xf1401073) = -1 errno=38 (Function not implemented)
Signed-off-by: Joel Stanley <joel@jms.id.au>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250826060341.1118670-1-joel@jms.id.au>
---
linux-user/strace.list | 3 +++
1 file changed, 3 insertions(+)
diff --git a/linux-user/strace.list b/linux-user/strace.list
index ab818352a9..51b5ead969 100644
--- a/linux-user/strace.list
+++ b/linux-user/strace.list
@@ -1719,3 +1719,6 @@
#ifdef TARGET_NR_riscv_hwprobe
{ TARGET_NR_riscv_hwprobe, "riscv_hwprobe" , "%s(%p,%d,%d,%d,%d,%d)", NULL, NULL },
#endif
+#ifdef TARGET_NR_rseq
+{ TARGET_NR_rseq, "rseq" , "%s(%p,%u,%d,%#x)", NULL, NULL },
+#endif
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* [PULL 46/46] linux-user: do not print IP socket options by default
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (44 preceding siblings ...)
2025-08-27 23:20 ` [PULL 45/46] linux-user: Add strace for rseq Richard Henderson
@ 2025-08-27 23:20 ` Richard Henderson
2025-08-28 2:47 ` [PULL 00/46] linux-user patch queue Richard Henderson
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-27 23:20 UTC (permalink / raw)
To: qemu-devel; +Cc: Łukasz Stelmach
From: Łukasz Stelmach <l.stelmach@samsung.com>
IP protocols should not be printed unless the socket is an IPv4 or
IPv6 one. Current arrangement erroneously prints IPPROTO_IP for Unix
domain sockets.
Signed-off-by: Łukasz Stelmach <l.stelmach@samsung.com>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Message-ID: <20250827095412.2348821-1-l.stelmach@samsung.com>
---
linux-user/strace.c | 36 ++++++++++++++++++++----------------
1 file changed, 20 insertions(+), 16 deletions(-)
diff --git a/linux-user/strace.c b/linux-user/strace.c
index 3b744ccd4a..786354627a 100644
--- a/linux-user/strace.c
+++ b/linux-user/strace.c
@@ -586,23 +586,27 @@ print_socket_protocol(int domain, int type, int protocol)
return;
}
- switch (protocol) {
- case IPPROTO_IP:
- qemu_log("IPPROTO_IP");
- break;
- case IPPROTO_TCP:
- qemu_log("IPPROTO_TCP");
- break;
- case IPPROTO_UDP:
- qemu_log("IPPROTO_UDP");
- break;
- case IPPROTO_RAW:
- qemu_log("IPPROTO_RAW");
- break;
- default:
- qemu_log("%d", protocol);
- break;
+ if (domain == AF_INET || domain == AF_INET6) {
+ switch (protocol) {
+ case IPPROTO_IP:
+ qemu_log("IPPROTO_IP");
+ break;
+ case IPPROTO_TCP:
+ qemu_log("IPPROTO_TCP");
+ break;
+ case IPPROTO_UDP:
+ qemu_log("IPPROTO_UDP");
+ break;
+ case IPPROTO_RAW:
+ qemu_log("IPPROTO_RAW");
+ break;
+ default:
+ qemu_log("%d", protocol);
+ break;
+ }
+ return;
}
+ qemu_log("%d", protocol);
}
--
2.43.0
^ permalink raw reply related [flat|nested] 48+ messages in thread* Re: [PULL 00/46] linux-user patch queue
2025-08-27 23:19 [PULL 00/46] linux-user patch queue Richard Henderson
` (45 preceding siblings ...)
2025-08-27 23:20 ` [PULL 46/46] linux-user: do not print IP socket options by default Richard Henderson
@ 2025-08-28 2:47 ` Richard Henderson
46 siblings, 0 replies; 48+ messages in thread
From: Richard Henderson @ 2025-08-28 2:47 UTC (permalink / raw)
To: qemu-devel
On 8/28/25 09:19, Richard Henderson wrote:
> The following changes since commit 5fc03d4e28258fdf6a926a59c6b5e1edc23e6d5d:
>
> Merge tag 'pull-request-2025-08-27' ofhttps://gitlab.com/thuth/qemu into staging (2025-08-27 19:11:08 +1000)
>
> are available in the Git repository at:
>
> https://gitlab.com/rth7680/qemu.git tags/pull-lu-20250828
>
> for you to fetch changes up to a5fbf1c617c5b51082d317601e0d4cf5eea5c140:
>
> linux-user: do not print IP socket options by default (2025-08-28 07:33:34 +1000)
>
> ----------------------------------------------------------------
> linux-user: do not print IP socket options by default
> linux-user: Add strace for rseq
> linux-user: Move get_elf_cpu_model to target/elfload.c
> linux-user: Move get_elf_hwcap to target/elfload.c
> linux-user: Move get_elf_hwcap2 to target/elfload.c
> linux-user: Move get_elf_platform to target/elfload.c
> linux-user: Move get_elf_base_platform to target/elfload.c
> linux-user: Create init_main_thread in target/cpu_loop.c
> semihosting: Retrieve stack top from image_info
> semihosting: Initialize heap once per process
Applied, thanks. Please update https://wiki.qemu.org/ChangeLog/10.2 as appropriate.
r~
^ permalink raw reply [flat|nested] 48+ messages in thread