Alpha has never set AT_HWCAP in linux-user emulation, so getauxval(AT_HWCAP) always returned 0 regardless of the emulated CPU model. The Linux kernel computes ELF_HWCAP as ~amask(-1), i.e. the set of ISA extension bits that the amask instruction reports as supported (cleared in its output). env->amask stores exactly those bits with the same layout (BWX=0x1, FIX=0x2, CIX=0x4, MVI=0x100, TRAP=0x200, PREFETCH=0x1000), so returning it directly from get_elf_hwcap matches the kernel convention. Add HAVE_ELF_HWCAP to target_elf.h and implement get_elf_hwcap() in elfload.c to expose the emulated CPU's capability mask to user-space programs via the auxiliary vector. Without this fix, programs using getauxval(AT_HWCAP) to detect BWX/FIX/CIX (such as glibc's memcpy or JIT compilers targeting Alpha) incorrectly concluded that no extensions were available even when emulating ev56+. Signed-off-by: Matt Turner <mattst88@gmail.com> Cc: qemu-stable@nongnu.org Reviewed-by: Helge Deller <deller@gmx.de> Signed-off-by: Helge Deller <deller@gmx.de>
35 lines
842 B
C
35 lines
842 B
C
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
|
|
|
#include "qemu/osdep.h"
|
|
#include "qemu.h"
|
|
#include "loader.h"
|
|
#include "target_elf.h"
|
|
|
|
|
|
abi_ulong get_elf_hwcap(CPUState *cs)
|
|
{
|
|
/*
|
|
* The Linux kernel computes ELF_HWCAP as ~amask(-1), which clears a bit
|
|
* for each supported ISA extension. env->amask stores exactly those bits
|
|
* set for the extensions supported by the emulated CPU model, matching
|
|
* the kernel's convention: bit set in AT_HWCAP ↔ extension present.
|
|
*/
|
|
return cpu_env(cs)->amask;
|
|
}
|
|
|
|
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUAlphaState *env)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < 31; i++) {
|
|
r->regs[i] = tswap64(env->ir[i]);
|
|
}
|
|
r->pc = tswap64(env->pc);
|
|
r->unique = tswap64(env->unique);
|
|
}
|
|
|
|
const char *get_elf_cpu_model(uint32_t eflags)
|
|
{
|
|
return "ev67";
|
|
}
|