linux-user: Finish elfload.c split

linux-user: Drop deprecated -p option
 linux-user: Tidy print_socket_protocol
 hw/core: Dump cpu_reset in the reset.exit phase
 hw/core: Use qemu_log_trylock/unlock in cpu_common_reset_exit
 -----BEGIN PGP SIGNATURE-----
 
 iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmiyKFIdHHJpY2hhcmQu
 aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/LBggAgMBSVMz1BwkPvckY
 paakdAwuOqRE5yF2YxQAHALJa3aH18Vqk06ENqM9R5iyqvHBGnvrw8fshIBVZnDP
 eQDjNFwnCtSrXuSMdfr0r8jZc+y9R8foQKs9j+KL0ESOi+4VNhORfzFe/yrIEu0y
 XM5XhBjBH0kK9+S20uy5x3WXhRkfqq2CZiUt1izqTOwtbdzYENxdvDj8iDk48FwL
 fkrXUSnlBBsdsltQCsjbrUbWi1Wqj7skswRIzI8KXsj+psy0JJL2kHthaWzm8tTS
 KIXVaOtxtU7LQWhTaknmpcNIkHpnjmEw2ZijxYT29V8WnZtstihVoqqCLbCv6u+7
 JwwQhQ==
 =kHx+
 -----END PGP SIGNATURE-----

Merge tag 'pull-lu-20250830' of https://gitlab.com/rth7680/qemu into staging

linux-user: Finish elfload.c split
linux-user: Drop deprecated -p option
linux-user: Tidy print_socket_protocol
hw/core: Dump cpu_reset in the reset.exit phase
hw/core: Use qemu_log_trylock/unlock in cpu_common_reset_exit

# -----BEGIN PGP SIGNATURE-----
#
# iQFRBAABCgA7FiEEekgeeIaLTbaoWgXAZN846K9+IV8FAmiyKFIdHHJpY2hhcmQu
# aGVuZGVyc29uQGxpbmFyby5vcmcACgkQZN846K9+IV/LBggAgMBSVMz1BwkPvckY
# paakdAwuOqRE5yF2YxQAHALJa3aH18Vqk06ENqM9R5iyqvHBGnvrw8fshIBVZnDP
# eQDjNFwnCtSrXuSMdfr0r8jZc+y9R8foQKs9j+KL0ESOi+4VNhORfzFe/yrIEu0y
# XM5XhBjBH0kK9+S20uy5x3WXhRkfqq2CZiUt1izqTOwtbdzYENxdvDj8iDk48FwL
# fkrXUSnlBBsdsltQCsjbrUbWi1Wqj7skswRIzI8KXsj+psy0JJL2kHthaWzm8tTS
# KIXVaOtxtU7LQWhTaknmpcNIkHpnjmEw2ZijxYT29V8WnZtstihVoqqCLbCv6u+7
# JwwQhQ==
# =kHx+
# -----END PGP SIGNATURE-----
# gpg: Signature made Sat 30 Aug 2025 08:23:14 AM AEST
# gpg:                using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F
# gpg:                issuer "richard.henderson@linaro.org"
# gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [ultimate]

* tag 'pull-lu-20250830' of https://gitlab.com/rth7680/qemu: (91 commits)
  linux-user: Remove target_pt_regs from target_syscall.h
  linux-user/sparc: Create target_ptrace.h
  linux-user: Remove a.out declarations from elfload.c
  linux-user: Move arch_parse_elf_property to aarch64/elfload.c
  linux-user: Remove MAP_DENYWRITE from elfload.c
  linux-user: Remove ELIBBAD from elfload.c
  linux-user: Rename elf_check_arch
  linux-user: Standardize on ELF_MACHINE not ELF_ARCH
  linux-user: Move elf parameters to hexagon/target_elf.h
  linux-user: Move elf parameters to xtensa/target_elf.h
  linux-user: Move elf parameters to hppa/target_elf.h
  linux-user: Move elf parameters to riscv/target_elf.h
  linux-user: Move elf parameters to s390x/target_elf.h
  linux-user: Move elf parameters to alpha/target_elf.h
  linux-user: Move elf parameters to m68k/target_elf.h
  linux-user: Move elf parameters to sh4/target_elf.h
  linux-user: Move elf parameters to openrisc/target_elf.h
  linux-user: Move elf parameters to microblaze/target_elf.h
  linux-user: Move elf parameters to {mips,mips64}/target_elf.h
  linux-user: Move elf parameters to loongarch64/target_elf.h
  ...

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
This commit is contained in:
Richard Henderson 2025-08-30 08:24:48 +10:00
commit 4791f22a5f
79 changed files with 1119 additions and 1441 deletions

View file

@ -367,14 +367,6 @@ int main(int argc, char **argv)
}
} else if (!strcmp(r, "L")) {
interp_prefix = argv[optind++];
} else if (!strcmp(r, "p")) {
unsigned size, want = qemu_real_host_page_size();
r = argv[optind++];
if (qemu_strtoui(r, NULL, 10, &size) || size != want) {
warn_report("Deprecated page size option cannot "
"change host page size (%u)", want);
}
} else if (!strcmp(r, "g")) {
gdbstub = g_strdup(argv[optind++]);
} else if (!strcmp(r, "r")) {

View file

@ -81,16 +81,6 @@ kernel since 2001. None of the board types QEMU supports need
``param_struct`` support, so this option has been deprecated and will
be removed in a future QEMU version.
User-mode emulator command line arguments
-----------------------------------------
``-p`` (since 9.0)
''''''''''''''''''
The ``-p`` option pretends to control the host page size. However,
it is not possible to change the host page size, and using the
option only causes failures.
QEMU Machine Protocol (QMP) commands
------------------------------------

View file

@ -571,6 +571,14 @@ The ``-singlestep`` option has been given a name that better reflects
what it actually does. For both linux-user and bsd-user, use the
``-one-insn-per-tb`` option instead.
``-p`` (removed in 10.2)
''''''''''''''''''''''''
The ``-p`` option pretends to control the host page size. However,
it is not possible to change the host page size; we stopped trying
to do anything with the option except print a warning from 9.0,
and now the option is removed entirely.
QEMU Machine Protocol (QMP) commands
------------------------------------

View file

@ -262,9 +262,6 @@ Debug options:
Activate logging of the specified items (use '-d help' for a list of
log items)
``-p pagesize``
Act as if the host page size was 'pagesize' bytes
``-one-insn-per-tb``
Run the emulation with one guest instruction per translation block.
This slows down emulation a lot, but can be useful in some situations,

View file

@ -119,11 +119,6 @@ static void cpu_common_reset_hold(Object *obj, ResetType type)
{
CPUState *cpu = CPU(obj);
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
qemu_log("CPU Reset (CPU %d)\n", cpu->cpu_index);
log_cpu_state(cpu, cpu->cc->reset_dump_flags);
}
cpu->interrupt_request = 0;
cpu->halted = cpu->start_powered_off;
cpu->mem_io_pc = 0;
@ -137,6 +132,21 @@ static void cpu_common_reset_hold(Object *obj, ResetType type)
cpu_exec_reset_hold(cpu);
}
static void cpu_common_reset_exit(Object *obj, ResetType type)
{
if (qemu_loglevel_mask(CPU_LOG_RESET)) {
FILE *f = qemu_log_trylock();
if (f) {
CPUState *cpu = CPU(obj);
fprintf(f, "CPU Reset (CPU %d)\n", cpu->cpu_index);
cpu_dump_state(cpu, f, cpu->cc->reset_dump_flags);
qemu_log_unlock(f);
}
}
}
ObjectClass *cpu_class_by_name(const char *typename, const char *cpu_model)
{
ObjectClass *oc;
@ -380,6 +390,7 @@ static void cpu_common_class_init(ObjectClass *klass, const void *data)
dc->realize = cpu_common_realizefn;
dc->unrealize = cpu_common_unrealizefn;
rc->phases.hold = cpu_common_reset_hold;
rc->phases.exit = cpu_common_reset_exit;
cpu_class_init_props(dc);
/*
* Reason: CPUs still need special care by board code: wiring up

View file

@ -1,9 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu.h"
#include "loader.h"
#include "target/arm/cpu-features.h"
#include "target_elf.h"
#include "elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -347,3 +350,29 @@ const char *get_elf_platform(CPUState *cs)
{
return TARGET_BIG_ENDIAN ? "aarch64_be" : "aarch64";
}
bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
const uint32_t *data,
struct image_info *info,
Error **errp)
{
if (pr_type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) {
if (pr_datasz != sizeof(uint32_t)) {
error_setg(errp, "Ill-formed GNU_PROPERTY_AARCH64_FEATURE_1_AND");
return false;
}
/* We will extract GNU_PROPERTY_AARCH64_FEATURE_1_BTI later. */
info->note_flags = *data;
}
return true;
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUARMState *env)
{
for (int i = 0; i < 31; i++) {
r->pt.regs[i] = tswap64(env->xregs[i]);
}
r->pt.sp = tswap64(env->xregs[31]);
r->pt.pc = tswap64(env->pc);
r->pt.pstate = tswap64(pstate_read((CPUARMState *)env));
}

View file

@ -8,8 +8,29 @@
#ifndef AARCH64_TARGET_ELF_H
#define AARCH64_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_MACHINE EM_AARCH64
#define ELF_CLASS ELFCLASS64
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_HWCAP2 1
#define HAVE_ELF_PLATFORM 1
#define HAVE_ELF_CORE_DUMP 1
#define HAVE_ELF_GNU_PROPERTY 1
/*
* See linux kernel: arch/arm64/include/asm/elf.h, where
* elf_gregset_t is mapped to struct user_pt_regs via sizeof.
*/
typedef struct target_elf_gregset_t {
struct target_user_pt_regs pt;
} target_elf_gregset_t;
#if TARGET_BIG_ENDIAN
# define VDSO_HEADER "vdso-be.c.inc"
#else
# define VDSO_HEADER "vdso-le.c.inc"
#endif
#endif

View file

@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef AARCH64_TARGET_PTRACE_H
#define AARCH64_TARGET_PTRACE_H
/* See arch/arm64/include/uapi/asm/ptrace.h. */
struct target_user_pt_regs {
uint64_t regs[31];
uint64_t sp;
uint64_t pc;
uint64_t pstate;
};
#endif /* AARCH64_TARGET_PTRACE_H */

View file

@ -1,13 +1,6 @@
#ifndef AARCH64_TARGET_SYSCALL_H
#define AARCH64_TARGET_SYSCALL_H
struct target_pt_regs {
uint64_t regs[31];
uint64_t sp;
uint64_t pc;
uint64_t pstate;
};
#if TARGET_BIG_ENDIAN
#define UNAME_MACHINE "aarch64_be"
#else

View file

@ -8,4 +8,7 @@
#ifndef ALPHA_TARGET_ELF_H
#define ALPHA_TARGET_ELF_H
#define ELF_CLASS ELFCLASS64
#define ELF_MACHINE EM_ALPHA
#endif

View file

@ -1,46 +1,6 @@
#ifndef ALPHA_TARGET_SYSCALL_H
#define ALPHA_TARGET_SYSCALL_H
/* default linux values for the selectors */
#define __USER_DS (1)
struct target_pt_regs {
abi_ulong r0;
abi_ulong r1;
abi_ulong r2;
abi_ulong r3;
abi_ulong r4;
abi_ulong r5;
abi_ulong r6;
abi_ulong r7;
abi_ulong r8;
abi_ulong r19;
abi_ulong r20;
abi_ulong r21;
abi_ulong r22;
abi_ulong r23;
abi_ulong r24;
abi_ulong r25;
abi_ulong r26;
abi_ulong r27;
abi_ulong r28;
abi_ulong hae;
/* JRP - These are the values provided to a0-a2 by PALcode */
abi_ulong trap_a0;
abi_ulong trap_a1;
abi_ulong trap_a2;
/* These are saved by PAL-code: */
abi_ulong ps;
abi_ulong pc;
abi_ulong gp;
abi_ulong r16;
abi_ulong r17;
abi_ulong r18;
/* Those is needed by qemu to temporary store the user stack pointer */
abi_ulong usp;
abi_ulong unique;
};
#define UNAME_MACHINE "alpha"
#define UNAME_MINIMUM_RELEASE "2.6.32"

View file

@ -3,7 +3,11 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "user-internals.h"
#include "target_elf.h"
#include "target/arm/cpu-features.h"
#include "target_elf.h"
#include "elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -199,3 +203,75 @@ const char *get_elf_platform(CPUState *cs)
#undef END
}
bool init_guest_commpage(void)
{
ARMCPU *cpu = ARM_CPU(thread_cpu);
int host_page_size = qemu_real_host_page_size();
abi_ptr commpage;
void *want;
void *addr;
/*
* M-profile allocates maximum of 2GB address space, so can never
* allocate the commpage. Skip it.
*/
if (arm_feature(&cpu->env, ARM_FEATURE_M)) {
return true;
}
commpage = HI_COMMPAGE & -host_page_size;
want = g2h_untagged(commpage);
addr = mmap(want, host_page_size, PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE |
(commpage < reserved_va ? MAP_FIXED : MAP_FIXED_NOREPLACE),
-1, 0);
if (addr == MAP_FAILED) {
perror("Allocating guest commpage");
exit(EXIT_FAILURE);
}
if (addr != want) {
return false;
}
/* Set kernel helper versions; rest of page is 0. */
__put_user(5, (uint32_t *)g2h_untagged(0xffff0ffcu));
if (mprotect(addr, host_page_size, PROT_READ)) {
perror("Protecting guest commpage");
exit(EXIT_FAILURE);
}
page_set_flags(commpage, commpage | (host_page_size - 1),
PAGE_READ | PAGE_EXEC | PAGE_VALID);
return true;
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUARMState *env)
{
for (int i = 0; i < 16; ++i) {
r->pt.regs[i] = tswapal(env->regs[i]);
}
r->pt.cpsr = tswapal(cpsr_read((CPUARMState *)env));
r->pt.orig_r0 = tswapal(env->regs[0]); /* FIXME */
}
#if TARGET_BIG_ENDIAN
# include "vdso-be8.c.inc"
# include "vdso-be32.c.inc"
#else
# include "vdso-le.c.inc"
#endif
const VdsoImageInfo *get_vdso_image_info(uint32_t elf_flags)
{
#if TARGET_BIG_ENDIAN
return (EF_ARM_EABI_VERSION(elf_flags) >= EF_ARM_EABI_VER4
&& (elf_flags & EF_ARM_BE8)
? &vdso_be8_image_info
: &vdso_be32_image_info);
#else
return &vdso_image_info;
#endif
}

View file

@ -8,8 +8,26 @@
#ifndef ARM_TARGET_ELF_H
#define ARM_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_MACHINE EM_ARM
#define ELF_CLASS ELFCLASS32
#define EXSTACK_DEFAULT true
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_HWCAP2 1
#define HAVE_ELF_PLATFORM 1
#define HAVE_ELF_CORE_DUMP 1
#define HAVE_VDSO_IMAGE_INFO 1
#define HI_COMMPAGE ((intptr_t)0xffff0f00u)
/*
* See linux kernel: arch/arm/include/asm/elf.h, where
* elf_gregset_t is mapped to struct pt_regs via sizeof.
*/
typedef struct target_elf_gregset_t {
struct target_pt_regs pt;
} target_elf_gregset_t;
#endif

View file

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef ARM_TARGET_PTRACE_H
#define ARM_TARGET_PTRACE_H
/*
* See arch/arm/include/uapi/asm/ptrace.h.
* Instead of an array and ARM_xx defines, use proper fields.
*/
struct target_pt_regs {
abi_ulong regs[16];
abi_ulong cpsr;
abi_ulong orig_r0;
};
#endif /* ARM_TARGET_PTRACE_H */

View file

@ -1,14 +1,6 @@
#ifndef ARM_TARGET_SYSCALL_H
#define ARM_TARGET_SYSCALL_H
/* this struct defines the way the registers are stored on the
stack during a system call. */
/* uregs[0..15] are r0 to r15; uregs[16] is CPSR; uregs[17] is ORIG_r0 */
struct target_pt_regs {
abi_long uregs[18];
};
#define ARM_SYSCALL_BASE 0x900000
#define ARM_THUMB_SYSCALL 0

File diff suppressed because it is too large Load diff

View file

@ -18,4 +18,7 @@
#ifndef HEXAGON_TARGET_ELF_H
#define HEXAGON_TARGET_ELF_H
#define ELF_CLASS ELFCLASS32
#define ELF_MACHINE EM_HEXAGON
#endif

View file

@ -18,11 +18,6 @@
#ifndef HEXAGON_TARGET_SYSCALL_H
#define HEXAGON_TARGET_SYSCALL_H
struct target_pt_regs {
abi_long sepc;
abi_long sp;
};
#define UNAME_MACHINE "hexagon"
#define UNAME_MINIMUM_RELEASE "4.15.0"

View file

@ -3,6 +3,7 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -14,3 +15,33 @@ const char *get_elf_platform(CPUState *cs)
{
return "PARISC";
}
bool init_guest_commpage(void)
{
/* If reserved_va, then we have already mapped 0 page on the host. */
if (!reserved_va) {
void *want, *addr;
want = g2h_untagged(LO_COMMPAGE);
addr = mmap(want, TARGET_PAGE_SIZE, PROT_NONE,
MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED_NOREPLACE, -1, 0);
if (addr == MAP_FAILED) {
perror("Allocating guest commpage");
exit(EXIT_FAILURE);
}
if (addr != want) {
return false;
}
}
/*
* On Linux, page zero is normally marked execute only + gateway.
* Normal read or write is supposed to fail (thus PROT_NONE above),
* but specific offsets have kernel code mapped to raise permissions
* and implement syscalls. Here, simply mark the page executable.
* Special case the entry points during translation (see do_page_zero).
*/
page_set_flags(LO_COMMPAGE, LO_COMMPAGE | ~TARGET_PAGE_MASK,
PAGE_EXEC | PAGE_VALID);
return true;
}

View file

@ -8,6 +8,14 @@
#ifndef HPPA_TARGET_ELF_H
#define HPPA_TARGET_ELF_H
#define ELF_CLASS ELFCLASS32
#define ELF_MACHINE EM_PARISC
#define HAVE_ELF_PLATFORM 1
#define LO_COMMPAGE 0
#define STACK_GROWS_DOWN 0
#define STACK_ALIGNMENT 64
#define VDSO_HEADER "vdso.c.inc"
#endif

View file

@ -1,24 +1,6 @@
#ifndef HPPA_TARGET_SYSCALL_H
#define HPPA_TARGET_SYSCALL_H
struct target_pt_regs {
target_ulong gr[32];
uint64_t fr[32];
target_ulong sr[8];
target_ulong iasq[2];
target_ulong iaoq[2];
target_ulong cr27;
target_ulong __pad0;
target_ulong orig_r28;
target_ulong ksp;
target_ulong kpc;
target_ulong sar;
target_ulong iir;
target_ulong isr;
target_ulong ior;
target_ulong ipsw;
};
#define UNAME_MACHINE "parisc"
#define UNAME_MINIMUM_RELEASE "2.6.32"
#define TARGET_CLONE_BACKWARDS

View file

@ -3,6 +3,7 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -23,3 +24,24 @@ const char *get_elf_platform(CPUState *cs)
family = MAX(MIN(family, 6), 3);
return elf_platform[family - 3];
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUX86State *env)
{
r->pt.bx = tswapal(env->regs[R_EBX]);
r->pt.cx = tswapal(env->regs[R_ECX]);
r->pt.dx = tswapal(env->regs[R_EDX]);
r->pt.si = tswapal(env->regs[R_ESI]);
r->pt.di = tswapal(env->regs[R_EDI]);
r->pt.bp = tswapal(env->regs[R_EBP]);
r->pt.ax = tswapal(env->regs[R_EAX]);
r->pt.ds = tswapal(env->segs[R_DS].selector & 0xffff);
r->pt.es = tswapal(env->segs[R_ES].selector & 0xffff);
r->pt.fs = tswapal(env->segs[R_FS].selector & 0xffff);
r->pt.gs = tswapal(env->segs[R_GS].selector & 0xffff);
r->pt.orig_ax = tswapal(get_task_state(env_cpu_const(env))->orig_ax);
r->pt.ip = tswapal(env->eip);
r->pt.cs = tswapal(env->segs[R_CS].selector & 0xffff);
r->pt.flags = tswapal(env->eflags);
r->pt.sp = tswapal(env->regs[R_ESP]);
r->pt.ss = tswapal(env->segs[R_SS].selector & 0xffff);
}

View file

@ -8,7 +8,40 @@
#ifndef I386_TARGET_ELF_H
#define I386_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_CLASS ELFCLASS32
#define ELF_MACHINE EM_386
#define EXSTACK_DEFAULT true
#define VDSO_HEADER "vdso.c.inc"
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_PLATFORM 1
#define HAVE_ELF_CORE_DUMP 1
/*
* See linux kernel: arch/x86/include/asm/elf.h, where elf_gregset_t
* is mapped to struct user_regs_struct via sizeof.
*/
typedef struct target_elf_gregset_t {
struct target_user_regs_struct pt;
} target_elf_gregset_t;
/*
* This is used to ensure we don't load something for the wrong architecture.
*/
#define elf_check_machine(x) ((x) == EM_386 || (x) == EM_486)
/*
* i386 is the only target which supplies AT_SYSINFO for the vdso.
* All others only supply AT_SYSINFO_EHDR.
*/
#define DLINFO_ARCH_ITEMS (vdso_info != NULL)
#define ARCH_DLINFO \
do { \
if (vdso_info) { \
NEW_AUX_ENT(AT_SYSINFO, vdso_info->entry); \
} \
} while (0)
#endif

View file

@ -0,0 +1,32 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef I386_TARGET_PTRACE_H
#define I386_TARGET_PTRACE_H
/*
* Note that arch/x86/include/uapi/asm/ptrace.h (struct pt_regs) and
* arch/x86/include/asm/user_32.h (struct user_regs_struct) have the
* same layout, though the exact types differ (int vs long vs unsigned).
* Define user_regs_struct because that's what's actually used.
*/
struct target_user_regs_struct {
abi_ulong bx;
abi_ulong cx;
abi_ulong dx;
abi_ulong si;
abi_ulong di;
abi_ulong bp;
abi_ulong ax;
abi_ulong ds;
abi_ulong es;
abi_ulong fs;
abi_ulong gs;
abi_ulong orig_ax;
abi_ulong ip;
abi_ulong cs;
abi_ulong flags;
abi_ulong sp;
abi_ulong ss;
};
#endif /* I386_TARGET_PTRACE_H */

View file

@ -5,24 +5,6 @@
#define __USER_CS (0x23)
#define __USER_DS (0x2B)
struct target_pt_regs {
long ebx;
long ecx;
long edx;
long esi;
long edi;
long ebp;
long eax;
int xds;
int xes;
long orig_eax;
long eip;
int xcs;
long eflags;
long esp;
int xss;
};
/* ioctls */
#define TARGET_LDT_ENTRIES 8192

View file

@ -105,5 +105,26 @@ 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);
bool init_guest_commpage(void);
struct target_elf_gregset_t;
void elf_core_copy_regs(struct target_elf_gregset_t *, const CPUArchState *);
typedef struct {
const uint8_t *image;
const uint32_t *relocs;
unsigned image_size;
unsigned reloc_count;
unsigned sigreturn_ofs;
unsigned rt_sigreturn_ofs;
} VdsoImageInfo;
/* Note that both Elf32_Word and Elf64_Word are uint32_t. */
const VdsoImageInfo *get_vdso_image_info(uint32_t elf_flags);
bool arch_parse_elf_property(uint32_t pr_type, uint32_t pr_datasz,
const uint32_t *data,
struct image_info *info,
Error **errp);
#endif /* LINUX_USER_LOADER_H */

View file

@ -3,6 +3,7 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -61,3 +62,17 @@ const char *get_elf_platform(CPUState *cs)
{
return "loongarch";
}
#define tswapreg(ptr) tswapal(ptr)
void elf_core_copy_regs(target_elf_gregset_t *r, const CPULoongArchState *env)
{
r->pt.regs[0] = 0;
for (int i = 1; i < ARRAY_SIZE(env->gpr); i++) {
r->pt.regs[i] = tswapreg(env->gpr[i]);
}
r->pt.csr_era = tswapreg(env->pc);
r->pt.csr_badv = tswapreg(env->CSR_BADV);
}

View file

@ -6,7 +6,20 @@
#ifndef LOONGARCH_TARGET_ELF_H
#define LOONGARCH_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_CLASS ELFCLASS64
#define ELF_MACHINE EM_LOONGARCH
#define EXSTACK_DEFAULT true
#define VDSO_HEADER "vdso.c.inc"
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_PLATFORM 1
#define HAVE_ELF_CORE_DUMP 1
/* See linux kernel: arch/loongarch/include/asm/elf.h */
typedef struct target_elf_gregset_t {
struct target_user_pt_regs pt;
} target_elf_gregset_t;
#endif

View file

@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef LOONGARCH64_TARGET_PTRACE_H
#define LOONGARCH64_TARGET_PTRACE_H
/* See arch/loongarch/include/uapi/asm/ptrace.h. */
struct target_user_pt_regs {
abi_ulong regs[32];
abi_ulong orig_a0;
abi_ulong csr_era;
abi_ulong csr_badv;
abi_ulong reserved[10];
};
#endif /* LOONGARCH64_TARGET_PTRACE_H */

View file

@ -8,29 +8,6 @@
#include "qemu/units.h"
/*
* this struct defines the way the registers are stored on the
* stack during a system call.
*/
struct target_pt_regs {
/* Saved main processor registers. */
target_ulong regs[32];
/* Saved special registers. */
struct {
target_ulong era;
target_ulong badv;
target_ulong crmd;
target_ulong prmd;
target_ulong euen;
target_ulong ecfg;
target_ulong estat;
} csr;
target_ulong orig_a0;
target_ulong __last[0];
};
#define UNAME_MACHINE "loongarch64"
#define UNAME_MINIMUM_RELEASE "5.19.0"

View file

@ -4,6 +4,7 @@
#include "qemu.h"
#include "loader.h"
#include "elf.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -16,3 +17,27 @@ const char *get_elf_cpu_model(uint32_t eflags)
/* Coldfire */
return "any";
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUM68KState *env)
{
r->d1 = tswapal(env->dregs[1]);
r->d2 = tswapal(env->dregs[2]);
r->d3 = tswapal(env->dregs[3]);
r->d4 = tswapal(env->dregs[4]);
r->d5 = tswapal(env->dregs[5]);
r->d6 = tswapal(env->dregs[6]);
r->d7 = tswapal(env->dregs[7]);
r->a0 = tswapal(env->aregs[0]);
r->a1 = tswapal(env->aregs[1]);
r->a2 = tswapal(env->aregs[2]);
r->a3 = tswapal(env->aregs[3]);
r->a4 = tswapal(env->aregs[4]);
r->a5 = tswapal(env->aregs[5]);
r->a6 = tswapal(env->aregs[6]);
r->d0 = tswapal(env->dregs[0]);
r->usp = tswapal(env->aregs[7]);
r->orig_d0 = tswapal(env->dregs[0]); /* FIXME */
r->sr = tswapal(env->sr);
r->pc = tswapal(env->pc);
/* FIXME: regs->format | regs->vector */
}

View file

@ -8,4 +8,31 @@
#ifndef M68K_TARGET_ELF_H
#define M68K_TARGET_ELF_H
#define ELF_CLASS ELFCLASS32
#define ELF_MACHINE EM_68K
#define HAVE_ELF_CORE_DUMP 1
/*
* See linux kernel: arch/m68k/include/asm/elf.h, where
* elf_gregset_t is mapped to struct user_regs_struct via sizeof.
*
* Note that user_regs_struct has
* short stkadj, sr;
* ...
* short fmtvec, __fill;
* but ELF_CORE_COPY_REGS writes to unsigned longs.
* Therefore adjust the sr and fmtvec fields to match.
*/
typedef struct target_elf_gregset_t {
abi_ulong d1, d2, d3, d4, d5, d6, d7;
abi_ulong a0, a1, a2, a3, a4, a5, a6;
abi_ulong d0;
abi_ulong usp;
abi_ulong orig_d0;
abi_ulong sr;
abi_ulong pc;
abi_ulong fmtvec;
} target_elf_gregset_t;
#endif

View file

@ -1,22 +1,6 @@
#ifndef M68K_TARGET_SYSCALL_H
#define M68K_TARGET_SYSCALL_H
/* this struct defines the way the registers are stored on the
stack during a system call. */
struct target_pt_regs {
abi_long d1, d2, d3, d4, d5, d6, d7;
abi_long a0, a1, a2, a3, a4, a5, a6;
abi_ulong d0;
abi_ulong usp;
abi_ulong orig_d0;
int16_t stkadj;
uint16_t sr;
abi_ulong pc;
uint16_t fntvex;
uint16_t __fill;
};
#define UNAME_MACHINE "m68k"
#define UNAME_MINIMUM_RELEASE "2.6.32"

View file

@ -340,16 +340,6 @@ static void handle_arg_ld_prefix(const char *arg)
interp_prefix = strdup(arg);
}
static void handle_arg_pagesize(const char *arg)
{
unsigned size, want = qemu_real_host_page_size();
if (qemu_strtoui(arg, NULL, 10, &size) || size != want) {
warn_report("Deprecated page size option cannot "
"change host page size (%u)", want);
}
}
static void handle_arg_seed(const char *arg)
{
seed_optarg = arg;
@ -522,8 +512,6 @@ static const struct qemu_argument arg_table[] = {
"range[,...]","filter logging based on address range"},
{"D", "QEMU_LOG_FILENAME", true, handle_arg_log_filename,
"logfile", "write logs to 'logfile' (default stderr)"},
{"p", "QEMU_PAGESIZE", true, handle_arg_pagesize,
"pagesize", "deprecated change to host page size"},
{"one-insn-per-tb",
"QEMU_ONE_INSN_PER_TB", false, handle_arg_one_insn_per_tb,
"", "run with one guest instruction per emulated TB"},

View file

@ -3,9 +3,22 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
{
return "any";
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUMBState *env)
{
for (int i = 0; i < 32; i++) {
r->pt.r[i] = tswapal(env->regs[i]);
}
r->pt.pc = tswapal(env->pc);
r->pt.msr = tswapal(mb_cpu_read_msr(env));
r->pt.ear = tswapal(env->ear);
r->pt.esr = tswapal(env->esr);
}

View file

@ -21,6 +21,7 @@
#include "user-internals.h"
#include "signal-common.h"
#include "linux-user/trace.h"
#include "target_ptrace.h"
struct target_sigcontext {
struct target_pt_regs regs; /* needs to be first */
@ -50,75 +51,17 @@ struct target_rt_sigframe {
static void setup_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
{
__put_user(env->regs[0], &sc->regs.r0);
__put_user(env->regs[1], &sc->regs.r1);
__put_user(env->regs[2], &sc->regs.r2);
__put_user(env->regs[3], &sc->regs.r3);
__put_user(env->regs[4], &sc->regs.r4);
__put_user(env->regs[5], &sc->regs.r5);
__put_user(env->regs[6], &sc->regs.r6);
__put_user(env->regs[7], &sc->regs.r7);
__put_user(env->regs[8], &sc->regs.r8);
__put_user(env->regs[9], &sc->regs.r9);
__put_user(env->regs[10], &sc->regs.r10);
__put_user(env->regs[11], &sc->regs.r11);
__put_user(env->regs[12], &sc->regs.r12);
__put_user(env->regs[13], &sc->regs.r13);
__put_user(env->regs[14], &sc->regs.r14);
__put_user(env->regs[15], &sc->regs.r15);
__put_user(env->regs[16], &sc->regs.r16);
__put_user(env->regs[17], &sc->regs.r17);
__put_user(env->regs[18], &sc->regs.r18);
__put_user(env->regs[19], &sc->regs.r19);
__put_user(env->regs[20], &sc->regs.r20);
__put_user(env->regs[21], &sc->regs.r21);
__put_user(env->regs[22], &sc->regs.r22);
__put_user(env->regs[23], &sc->regs.r23);
__put_user(env->regs[24], &sc->regs.r24);
__put_user(env->regs[25], &sc->regs.r25);
__put_user(env->regs[26], &sc->regs.r26);
__put_user(env->regs[27], &sc->regs.r27);
__put_user(env->regs[28], &sc->regs.r28);
__put_user(env->regs[29], &sc->regs.r29);
__put_user(env->regs[30], &sc->regs.r30);
__put_user(env->regs[31], &sc->regs.r31);
for (int i = 0; i < 32; ++i) {
__put_user(env->regs[i], &sc->regs.r[i]);
}
__put_user(env->pc, &sc->regs.pc);
}
static void restore_sigcontext(struct target_sigcontext *sc, CPUMBState *env)
{
__get_user(env->regs[0], &sc->regs.r0);
__get_user(env->regs[1], &sc->regs.r1);
__get_user(env->regs[2], &sc->regs.r2);
__get_user(env->regs[3], &sc->regs.r3);
__get_user(env->regs[4], &sc->regs.r4);
__get_user(env->regs[5], &sc->regs.r5);
__get_user(env->regs[6], &sc->regs.r6);
__get_user(env->regs[7], &sc->regs.r7);
__get_user(env->regs[8], &sc->regs.r8);
__get_user(env->regs[9], &sc->regs.r9);
__get_user(env->regs[10], &sc->regs.r10);
__get_user(env->regs[11], &sc->regs.r11);
__get_user(env->regs[12], &sc->regs.r12);
__get_user(env->regs[13], &sc->regs.r13);
__get_user(env->regs[14], &sc->regs.r14);
__get_user(env->regs[15], &sc->regs.r15);
__get_user(env->regs[16], &sc->regs.r16);
__get_user(env->regs[17], &sc->regs.r17);
__get_user(env->regs[18], &sc->regs.r18);
__get_user(env->regs[19], &sc->regs.r19);
__get_user(env->regs[20], &sc->regs.r20);
__get_user(env->regs[21], &sc->regs.r21);
__get_user(env->regs[22], &sc->regs.r22);
__get_user(env->regs[23], &sc->regs.r23);
__get_user(env->regs[24], &sc->regs.r24);
__get_user(env->regs[25], &sc->regs.r25);
__get_user(env->regs[26], &sc->regs.r26);
__get_user(env->regs[27], &sc->regs.r27);
__get_user(env->regs[28], &sc->regs.r28);
__get_user(env->regs[29], &sc->regs.r29);
__get_user(env->regs[30], &sc->regs.r30);
__get_user(env->regs[31], &sc->regs.r31);
for (int i = 0; i < 32; ++i) {
__get_user(env->regs[i], &sc->regs.r[i]);
}
__get_user(env->pc, &sc->regs.pc);
}

View file

@ -8,4 +8,21 @@
#ifndef MICROBLAZE_TARGET_ELF_H
#define MICROBLAZE_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_CLASS ELFCLASS32
#define ELF_MACHINE EM_MICROBLAZE
#define elf_check_machine(x) ((x) == EM_MICROBLAZE || (x) == EM_MICROBLAZE_OLD)
#define HAVE_ELF_CORE_DUMP 1
/*
* See linux kernel: arch/microblaze/include/asm/elf.h, where
* elf_gregset_t is mapped to struct pt_regs via sizeof.
*/
typedef struct target_elf_gregset_t {
struct target_pt_regs pt;
} target_elf_gregset_t;
#endif

View file

@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef MICROBLAZE_TARGET_PTRACE_H
#define MICROBLAZE_TARGET_PTRACE_H
/* We use microblaze_reg_t to keep things similar to the kernel sources. */
typedef uint32_t microblaze_reg_t;
struct target_pt_regs {
/* Note the kernel enumerates all 32 registers. */
microblaze_reg_t r[32];
microblaze_reg_t pc;
microblaze_reg_t msr;
microblaze_reg_t ear;
microblaze_reg_t esr;
microblaze_reg_t fsr;
uint32_t kernel_mode;
};
#endif /* MICROBLAZE_TARGET_PTRACE_H */

View file

@ -4,50 +4,6 @@
#define UNAME_MACHINE "microblaze"
#define UNAME_MINIMUM_RELEASE "2.6.32"
/* We use microblaze_reg_t to keep things similar to the kernel sources. */
typedef uint32_t microblaze_reg_t;
struct target_pt_regs {
microblaze_reg_t r0;
microblaze_reg_t r1;
microblaze_reg_t r2;
microblaze_reg_t r3;
microblaze_reg_t r4;
microblaze_reg_t r5;
microblaze_reg_t r6;
microblaze_reg_t r7;
microblaze_reg_t r8;
microblaze_reg_t r9;
microblaze_reg_t r10;
microblaze_reg_t r11;
microblaze_reg_t r12;
microblaze_reg_t r13;
microblaze_reg_t r14;
microblaze_reg_t r15;
microblaze_reg_t r16;
microblaze_reg_t r17;
microblaze_reg_t r18;
microblaze_reg_t r19;
microblaze_reg_t r20;
microblaze_reg_t r21;
microblaze_reg_t r22;
microblaze_reg_t r23;
microblaze_reg_t r24;
microblaze_reg_t r25;
microblaze_reg_t r26;
microblaze_reg_t r27;
microblaze_reg_t r28;
microblaze_reg_t r29;
microblaze_reg_t r30;
microblaze_reg_t r31;
microblaze_reg_t pc;
microblaze_reg_t msr;
microblaze_reg_t ear;
microblaze_reg_t esr;
microblaze_reg_t fsr;
uint32_t kernel_mode;
};
#define TARGET_CLONE_BACKWARDS
#define TARGET_MCL_CURRENT 1
#define TARGET_MCL_FUTURE 2

View file

@ -4,6 +4,7 @@
#include "qemu.h"
#include "loader.h"
#include "elf.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -122,3 +123,20 @@ const char *get_elf_base_platform(CPUState *cs)
}
#undef MATCH_PLATFORM_INSN
/* See linux kernel: arch/mips/kernel/process.c:elf_dump_regs. */
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUMIPSState *env)
{
for (int i = 1; i < ARRAY_SIZE(env->active_tc.gpr); i++) {
r->pt.regs[i] = tswapl(env->active_tc.gpr[i]);
}
r->pt.regs[26] = 0;
r->pt.regs[27] = 0;
r->pt.lo = tswapl(env->active_tc.LO[0]);
r->pt.hi = tswapl(env->active_tc.HI[0]);
r->pt.cp0_epc = tswapl(env->active_tc.PC);
r->pt.cp0_badvaddr = tswapl(env->CP0_BadVAddr);
r->pt.cp0_status = tswapl(env->CP0_Status);
r->pt.cp0_cause = tswapl(env->CP0_Cause);
}

View file

@ -8,7 +8,22 @@
#ifndef MIPS_TARGET_ELF_H
#define MIPS_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_CLASS ELFCLASS32
#define ELF_MACHINE EM_MIPS
#define EXSTACK_DEFAULT true
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_BASE_PLATFORM 1
#define HAVE_ELF_CORE_DUMP 1
/* See linux kernel: arch/mips/include/asm/elf.h. */
typedef struct target_elf_gregset_t {
union {
abi_ulong reserved[45];
struct target_pt_regs pt;
};
} target_elf_gregset_t;
#endif

View file

@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef MIPS_TARGET_PTRACE_H
#define MIPS_TARGET_PTRACE_H
struct target_pt_regs {
abi_ulong pad0[6];
abi_ulong regs[32];
abi_ulong lo;
abi_ulong hi;
abi_ulong cp0_epc;
abi_ulong cp0_badvaddr;
abi_ulong cp0_status;
abi_ulong cp0_cause;
};
#endif /* MIPS_TARGET_PTRACE_H */

View file

@ -1,25 +1,6 @@
#ifndef MIPS_TARGET_SYSCALL_H
#define MIPS_TARGET_SYSCALL_H
/* this struct defines the way the registers are stored on the
stack during a system call. */
struct target_pt_regs {
/* Pad bytes for argument save space on the stack. */
abi_ulong pad0[6];
/* Saved main processor registers. */
abi_ulong regs[32];
/* Saved special registers. */
abi_ulong cp0_status;
abi_ulong lo;
abi_ulong hi;
abi_ulong cp0_badvaddr;
abi_ulong cp0_cause;
abi_ulong cp0_epc;
};
#define UNAME_MACHINE "mips"
#define UNAME_MINIMUM_RELEASE "2.6.32"

View file

@ -8,7 +8,28 @@
#ifndef MIPS64_TARGET_ELF_H
#define MIPS64_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_CLASS ELFCLASS64
#define ELF_MACHINE EM_MIPS
#define EXSTACK_DEFAULT true
#ifdef TARGET_ABI_MIPSN32
#define elf_check_abi(x) ((x) & EF_MIPS_ABI2)
#else
#define elf_check_abi(x) (!((x) & EF_MIPS_ABI2))
#endif
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_BASE_PLATFORM 1
#define HAVE_ELF_CORE_DUMP 1
/* See linux kernel: arch/mips/include/asm/elf.h. */
typedef struct target_elf_gregset_t {
union {
target_ulong reserved[45];
struct target_pt_regs pt;
};
} target_elf_gregset_t;
#endif

View file

@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef MIPS64_TARGET_PTRACE_H
#define MIPS64_TARGET_PTRACE_H
struct target_pt_regs {
target_ulong regs[32];
target_ulong lo;
target_ulong hi;
target_ulong cp0_epc;
target_ulong cp0_badvaddr;
target_ulong cp0_status;
target_ulong cp0_cause;
};
#endif /* MIPS64_TARGET_PTRACE_H */

View file

@ -1,22 +1,6 @@
#ifndef MIPS64_TARGET_SYSCALL_H
#define MIPS64_TARGET_SYSCALL_H
/* this struct defines the way the registers are stored on the
stack during a system call. */
struct target_pt_regs {
/* Saved main processor registers. */
target_ulong regs[32];
/* Saved special registers. */
target_ulong cp0_status;
target_ulong lo;
target_ulong hi;
target_ulong cp0_badvaddr;
target_ulong cp0_cause;
target_ulong cp0_epc;
};
#define UNAME_MACHINE "mips64"
#define UNAME_MINIMUM_RELEASE "2.6.32"

View file

@ -3,9 +3,19 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
{
return "any";
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUOpenRISCState *env)
{
for (int i = 0; i < 32; i++) {
r->pt.gpr[i] = tswapal(cpu_get_gpr(env, i));
}
r->pt.pc = tswapal(env->pc);
r->pt.sr = tswapal(cpu_get_sr(env));
}

View file

@ -21,9 +21,10 @@
#include "user-internals.h"
#include "signal-common.h"
#include "linux-user/trace.h"
#include "target_ptrace.h"
typedef struct target_sigcontext {
struct target_pt_regs regs;
struct target_user_regs_struct regs;
abi_ulong oldmask;
} target_sigcontext;

View file

@ -8,4 +8,19 @@
#ifndef OPENRISC_TARGET_ELF_H
#define OPENRISC_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_MACHINE EM_OPENRISC
#define ELF_CLASS ELFCLASS32
#define HAVE_ELF_CORE_DUMP 1
/*
* See linux kernel: arch/openrisc/include/uapi/asm/elf.h, where
* elf_gregset_t is mapped to struct user_regs_struct via sizeof.
*/
typedef struct target_elf_gregset_t {
struct target_user_regs_struct pt;
} target_elf_gregset_t;
#endif

View file

@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef OPENRISC_TARGET_PTRACE_H
#define OPENRISC_TARGET_PTRACE_H
/* See arch/openrisc/include/uapi/asm/ptrace.h. */
struct target_user_regs_struct {
abi_ulong gpr[32];
abi_ulong pc;
abi_ulong sr;
};
#endif /* OPENRISC_TARGET_PTRACE_H */

View file

@ -1,17 +1,6 @@
#ifndef OPENRISC_TARGET_SYSCALL_H
#define OPENRISC_TARGET_SYSCALL_H
/* Note that in linux/arch/openrisc/include/uapi/asm/ptrace.h,
* this is called user_regs_struct. Given that this is what
* is used within struct sigcontext we need this definition.
* However, elfload.c wants this name.
*/
struct target_pt_regs {
abi_ulong gpr[32];
abi_ulong pc;
abi_ulong sr;
};
#define UNAME_MACHINE "openrisc"
#define UNAME_MINIMUM_RELEASE "2.6.32"

View file

@ -3,6 +3,7 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -129,3 +130,17 @@ abi_ulong get_elf_hwcap2(CPUState *cs)
return features;
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUPPCState *env)
{
for (int i = 0; i < ARRAY_SIZE(env->gpr); i++) {
r->pt.gpr[i] = tswapal(env->gpr[i]);
}
r->pt.nip = tswapal(env->nip);
r->pt.msr = tswapal(env->msr);
r->pt.ctr = tswapal(env->ctr);
r->pt.link = tswapal(env->lr);
r->pt.xer = tswapal(cpu_read_xer(env));
r->pt.ccr = tswapal(ppc_get_cr(env));
}

View file

@ -8,7 +8,63 @@
#ifndef PPC_TARGET_ELF_H
#define PPC_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_MACHINE PPC_ELF_MACHINE
#ifdef TARGET_PPC64
# define ELF_CLASS ELFCLASS64
#else
# define ELF_CLASS ELFCLASS32
# define EXSTACK_DEFAULT true
#endif
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_HWCAP2 1
#define HAVE_ELF_CORE_DUMP 1
/*
* The size of 48 words is set in arch/powerpc/include/uapi/asm/elf.h.
* However PPC_ELF_CORE_COPY_REGS in arch/powerpc/include/asm/elf.h
* open-codes a memcpy from struct pt_regs, then zeros the rest.
*/
typedef struct target_elf_gregset_t {
union {
struct target_pt_regs pt;
abi_ulong reserved[48];
};
} target_elf_gregset_t;
#ifndef TARGET_PPC64
# define VDSO_HEADER "vdso-32.c.inc"
#elif TARGET_BIG_ENDIAN
# define VDSO_HEADER "vdso-64.c.inc"
#else
# define VDSO_HEADER "vdso-64le.c.inc"
#endif
/*
* The requirements here are:
* - keep the final alignment of sp (sp & 0xf)
* - make sure the 32-bit value at the first 16 byte aligned position of
* AUXV is greater than 16 for glibc compatibility.
* AT_IGNOREPPC is used for that.
* - for compatibility with glibc ARCH_DLINFO must always be defined on PPC,
* even if DLINFO_ARCH_ITEMS goes to zero or is undefined.
*/
#define DLINFO_ARCH_ITEMS 5
#define ARCH_DLINFO \
do { \
PowerPCCPU *cpu = POWERPC_CPU(thread_cpu); \
/* \
* Handle glibc compatibility: these magic entries must \
* be at the lowest addresses in the final auxv. \
*/ \
NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \
NEW_AUX_ENT(AT_DCACHEBSIZE, cpu->env.dcache_line_size); \
NEW_AUX_ENT(AT_ICACHEBSIZE, cpu->env.icache_line_size); \
NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \
} while (0)
#endif

View file

@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef PPC_TARGET_PTRACE_H
#define PPC_TARGET_PTRACE_H
struct target_pt_regs {
abi_ulong gpr[32];
abi_ulong nip;
abi_ulong msr;
abi_ulong orig_gpr3; /* Used for restarting system calls */
abi_ulong ctr;
abi_ulong link;
abi_ulong xer;
abi_ulong ccr;
#if defined(TARGET_PPC64)
abi_ulong softe;
#else
abi_ulong mq; /* 601 only (not used at present) */
#endif
abi_ulong trap; /* Reason for being here */
abi_ulong dar; /* Fault registers */
abi_ulong dsisr;
abi_ulong result; /* Result of a system call */
};
#endif /* PPC_TARGET_PTRACE_H */

View file

@ -20,34 +20,6 @@
#ifndef PPC_TARGET_SYSCALL_H
#define PPC_TARGET_SYSCALL_H
/* XXX: ABSOLUTELY BUGGY:
* for now, this is quite just a cut-and-paste from i386 target...
*/
/* default linux values for the selectors */
#define __USER_DS (1)
struct target_pt_regs {
abi_ulong gpr[32];
abi_ulong nip;
abi_ulong msr;
abi_ulong orig_gpr3; /* Used for restarting system calls */
abi_ulong ctr;
abi_ulong link;
abi_ulong xer;
abi_ulong ccr;
#if defined(TARGET_PPC64)
abi_ulong softe;
#else
abi_ulong mq; /* 601 only (not used at present) */
#endif
/* Used on APUS to hold IPL value. */
abi_ulong trap; /* Reason for being here */
abi_ulong dar; /* Fault registers */
abi_ulong dsisr;
abi_ulong result; /* Result of a system call */
};
/* ioctls */
struct target_revectored_struct {
abi_ulong __map[8]; /* 256 bits */

View file

@ -8,6 +8,16 @@
#ifndef RISCV_TARGET_ELF_H
#define RISCV_TARGET_ELF_H
#define ELF_MACHINE EM_RISCV
#ifdef TARGET_RISCV32
#define ELF_CLASS ELFCLASS32
#define VDSO_HEADER "vdso-32.c.inc"
#else
#define ELF_CLASS ELFCLASS64
#define VDSO_HEADER "vdso-64.c.inc"
#endif
#define HAVE_ELF_HWCAP 1
#endif

View file

@ -8,41 +8,6 @@
#ifndef LINUX_USER_RISCV_TARGET_SYSCALL_H
#define LINUX_USER_RISCV_TARGET_SYSCALL_H
struct target_pt_regs {
abi_long sepc;
abi_long ra;
abi_long sp;
abi_long gp;
abi_long tp;
abi_long t0;
abi_long t1;
abi_long t2;
abi_long s0;
abi_long s1;
abi_long a0;
abi_long a1;
abi_long a2;
abi_long a3;
abi_long a4;
abi_long a5;
abi_long a6;
abi_long a7;
abi_long s2;
abi_long s3;
abi_long s4;
abi_long s5;
abi_long s6;
abi_long s7;
abi_long s8;
abi_long s9;
abi_long s10;
abi_long s11;
abi_long t3;
abi_long t4;
abi_long t5;
abi_long t6;
};
#ifdef TARGET_RISCV32
#define UNAME_MACHINE "riscv32"
#define UNAME_MINIMUM_RELEASE "5.4.0"

View file

@ -4,6 +4,7 @@
#include "qemu.h"
#include "loader.h"
#include "elf.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -66,3 +67,16 @@ const char *elf_hwcap_str(uint32_t bit)
return bit < ARRAY_SIZE(hwcap_str) ? hwcap_str[bit] : NULL;
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUS390XState *env)
{
r->pt.psw.mask = tswapal(env->psw.mask);
r->pt.psw.addr = tswapal(env->psw.addr);
for (int i = 0; i < 16; i++) {
r->pt.gprs[i] = tswapal(env->regs[i]);
}
for (int i = 0; i < 16; i++) {
r->pt.acrs[i] = tswap32(env->aregs[i]);
}
r->pt.orig_gpr2 = 0;
}

View file

@ -22,6 +22,7 @@
#include "signal-common.h"
#include "linux-user/trace.h"
#include "vdso-asmoffset.h"
#include "target_ptrace.h"
#define __NUM_GPRS 16
#define __NUM_FPRS 16

View file

@ -8,6 +8,21 @@
#ifndef S390X_TARGET_ELF_H
#define S390X_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_CLASS ELFCLASS64
#define ELF_MACHINE EM_S390
#define VDSO_HEADER "vdso.c.inc"
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_CORE_DUMP 1
/*
* See linux kernel: arch/s390/include/asm/elf.h, where
* elf_gregset_t is typedef'd to struct s390_regs.
*/
typedef struct target_elf_gregset_t {
struct target_s390_regs pt;
} target_elf_gregset_t;
#endif

View file

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef S390X_TARGET_PTRACE_H
#define S390X_TARGET_PTRACE_H
typedef struct {
abi_ulong mask;
abi_ulong addr;
} target_psw_t;
struct target_s390_regs {
target_psw_t psw;
abi_ulong gprs[16];
abi_uint acrs[16];
abi_ulong orig_gpr2;
};
#endif /* S390X_TARGET_PTRACE_H */

View file

@ -1,28 +1,6 @@
#ifndef S390X_TARGET_SYSCALL_H
#define S390X_TARGET_SYSCALL_H
/* this typedef defines how a Program Status Word looks like */
typedef struct {
abi_ulong mask;
abi_ulong addr;
} __attribute__ ((aligned(8))) target_psw_t;
/*
* The pt_regs struct defines the way the registers are stored on
* the stack during a system call.
*/
#define TARGET_NUM_GPRS 16
struct target_pt_regs {
abi_ulong args[1];
target_psw_t psw;
abi_ulong gprs[TARGET_NUM_GPRS];
abi_ulong orig_gpr2;
unsigned short ilen;
unsigned short trap;
};
#define UNAME_MACHINE "s390x"
#define UNAME_MINIMUM_RELEASE "2.6.32"

View file

@ -3,6 +3,7 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -36,3 +37,17 @@ abi_ulong get_elf_hwcap(CPUState *cs)
return hwcap;
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUSH4State *env)
{
for (int i = 0; i < 16; i++) {
r->pt.regs[i] = tswapal(env->gregs[i]);
}
r->pt.pc = tswapal(env->pc);
r->pt.pr = tswapal(env->pr);
r->pt.sr = tswapal(env->sr);
r->pt.gbr = tswapal(env->gbr);
r->pt.mach = tswapal(env->mach);
r->pt.macl = tswapal(env->macl);
}

View file

@ -8,6 +8,20 @@
#ifndef SH4_TARGET_ELF_H
#define SH4_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_CLASS ELFCLASS32
#define ELF_MACHINE EM_SH
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_CORE_DUMP 1
/*
* See linux kernel: arch/sh/include/asm/elf.h, where
* elf_gregset_t is mapped to struct pt_regs via sizeof.
*/
typedef struct target_elf_gregset_t {
struct target_pt_regs pt;
} target_elf_gregset_t;
#endif

View file

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef SH4_TARGET_PTRACE_H
#define SH4_TARGET_PTRACE_H
/* See arch/sh/include/uapi/asm/ptrace_32.h. */
struct target_pt_regs {
abi_ulong regs[16];
abi_ulong pc;
abi_ulong pr;
abi_ulong sr;
abi_ulong gbr;
abi_ulong mach;
abi_ulong macl;
abi_long tra;
};
#endif /* SH4_TARGET_PTRACE_H */

View file

@ -1,17 +1,6 @@
#ifndef SH4_TARGET_SYSCALL_H
#define SH4_TARGET_SYSCALL_H
struct target_pt_regs {
unsigned long regs[16];
unsigned long pc;
unsigned long pr;
unsigned long sr;
unsigned long gbr;
unsigned long mach;
unsigned long macl;
long tra;
};
#define UNAME_MACHINE "sh4"
#define UNAME_MINIMUM_RELEASE "2.6.32"

View file

@ -21,6 +21,8 @@
#include "user-internals.h"
#include "signal-common.h"
#include "linux-user/trace.h"
#include "target_ptrace.h"
/* A Sparc register window */
struct target_reg_window {

View file

@ -8,6 +8,17 @@
#ifndef SPARC_TARGET_ELF_H
#define SPARC_TARGET_ELF_H
#ifndef TARGET_SPARC64
# define ELF_CLASS ELFCLASS32
# define ELF_MACHINE EM_SPARC
#elif defined(TARGET_ABI32)
# define ELF_CLASS ELFCLASS32
# define elf_check_machine(x) ((x) == EM_SPARC32PLUS || (x) == EM_SPARC)
#else
# define ELF_CLASS ELFCLASS64
# define ELF_MACHINE EM_SPARCV9
#endif
#define HAVE_ELF_HWCAP 1
#endif

View file

@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef SPARC_TARGET_PTRACE_H
#define SPARC_TARGET_PTRACE_H
/* See arch/sparc/include/uapi/asm/ptrace.h. */
struct target_pt_regs {
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
abi_ulong u_regs[16];
abi_ulong tstate;
abi_ulong pc;
abi_ulong npc;
uint32_t y;
uint32_t magic;
#else
abi_ulong psr;
abi_ulong pc;
abi_ulong npc;
abi_ulong y;
abi_ulong u_regs[16];
#endif
};
#endif /* SPARC_TARGET_PTRACE_H */

View file

@ -1,25 +1,6 @@
#ifndef SPARC_TARGET_SYSCALL_H
#define SPARC_TARGET_SYSCALL_H
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
struct target_pt_regs {
abi_ulong u_regs[16];
abi_ulong tstate;
abi_ulong pc;
abi_ulong npc;
uint32_t y;
uint32_t magic;
};
#else
struct target_pt_regs {
abi_ulong psr;
abi_ulong pc;
abi_ulong npc;
abi_ulong y;
abi_ulong u_regs[16];
};
#endif
#ifdef TARGET_SPARC64
# define UNAME_MACHINE "sparc64"
#else

View file

@ -499,116 +499,118 @@ print_socket_type(int type)
static void
print_socket_protocol(int domain, int type, int protocol)
{
if (domain == AF_PACKET ||
(domain == AF_INET && type == TARGET_SOCK_PACKET)) {
switch (protocol) {
case 0x0003:
qemu_log("ETH_P_ALL");
break;
default:
qemu_log("%d", protocol);
}
return;
}
const char *name = NULL;
if (domain == PF_NETLINK) {
switch (domain) {
case AF_PACKET:
switch (protocol) {
case 3:
name = "ETH_P_ALL";
break;
}
break;
case PF_NETLINK:
switch (protocol) {
case NETLINK_ROUTE:
qemu_log("NETLINK_ROUTE");
name = "NETLINK_ROUTE";
break;
case NETLINK_UNUSED:
qemu_log("NETLINK_UNUSED");
name = "NETLINK_UNUSED";
break;
case NETLINK_USERSOCK:
qemu_log("NETLINK_USERSOCK");
name = "NETLINK_USERSOCK";
break;
case NETLINK_FIREWALL:
qemu_log("NETLINK_FIREWALL");
name = "NETLINK_FIREWALL";
break;
case NETLINK_SOCK_DIAG:
qemu_log("NETLINK_SOCK_DIAG");
name = "NETLINK_SOCK_DIAG";
break;
case NETLINK_NFLOG:
qemu_log("NETLINK_NFLOG");
name = "NETLINK_NFLOG";
break;
case NETLINK_XFRM:
qemu_log("NETLINK_XFRM");
name = "NETLINK_XFRM";
break;
case NETLINK_SELINUX:
qemu_log("NETLINK_SELINUX");
name = "NETLINK_SELINUX";
break;
case NETLINK_ISCSI:
qemu_log("NETLINK_ISCSI");
name = "NETLINK_ISCSI";
break;
case NETLINK_AUDIT:
qemu_log("NETLINK_AUDIT");
name = "NETLINK_AUDIT";
break;
case NETLINK_FIB_LOOKUP:
qemu_log("NETLINK_FIB_LOOKUP");
name = "NETLINK_FIB_LOOKUP";
break;
case NETLINK_CONNECTOR:
qemu_log("NETLINK_CONNECTOR");
name = "NETLINK_CONNECTOR";
break;
case NETLINK_NETFILTER:
qemu_log("NETLINK_NETFILTER");
name = "NETLINK_NETFILTER";
break;
case NETLINK_IP6_FW:
qemu_log("NETLINK_IP6_FW");
name = "NETLINK_IP6_FW";
break;
case NETLINK_DNRTMSG:
qemu_log("NETLINK_DNRTMSG");
name = "NETLINK_DNRTMSG";
break;
case NETLINK_KOBJECT_UEVENT:
qemu_log("NETLINK_KOBJECT_UEVENT");
name = "NETLINK_KOBJECT_UEVENT";
break;
case NETLINK_GENERIC:
qemu_log("NETLINK_GENERIC");
name = "NETLINK_GENERIC";
break;
case NETLINK_SCSITRANSPORT:
qemu_log("NETLINK_SCSITRANSPORT");
name = "NETLINK_SCSITRANSPORT";
break;
case NETLINK_ECRYPTFS:
qemu_log("NETLINK_ECRYPTFS");
name = "NETLINK_ECRYPTFS";
break;
case NETLINK_RDMA:
qemu_log("NETLINK_RDMA");
name = "NETLINK_RDMA";
break;
case NETLINK_CRYPTO:
qemu_log("NETLINK_CRYPTO");
name = "NETLINK_CRYPTO";
break;
case NETLINK_SMC:
qemu_log("NETLINK_SMC");
break;
default:
qemu_log("%d", protocol);
name = "NETLINK_SMC";
break;
}
return;
}
break;
if (domain == AF_INET || domain == AF_INET6) {
case AF_INET:
case AF_INET6:
switch (protocol) {
case 3:
if (domain == AF_INET && type == TARGET_SOCK_PACKET) {
name = "ETH_P_ALL";
}
break;
case IPPROTO_IP:
qemu_log("IPPROTO_IP");
name = "IPPROTO_IP";
break;
case IPPROTO_TCP:
qemu_log("IPPROTO_TCP");
name = "IPPROTO_TCP";
break;
case IPPROTO_UDP:
qemu_log("IPPROTO_UDP");
name = "IPPROTO_UDP";
break;
case IPPROTO_RAW:
qemu_log("IPPROTO_RAW");
break;
default:
qemu_log("%d", protocol);
name = "IPPROTO_RAW";
break;
}
return;
break;
}
qemu_log("%d", protocol);
}
if (name) {
qemu_log("%s", name);
} else {
qemu_log("%d", protocol);
}
}
#ifdef TARGET_NR__newselect
static void

View file

@ -1,8 +1,10 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#include "qemu/osdep.h"
#include "qemu/error-report.h"
#include "qemu.h"
#include "loader.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
@ -19,3 +21,53 @@ const char *get_elf_platform(CPUState *cs)
{
return "x86_64";
}
bool init_guest_commpage(void)
{
/*
* The vsyscall page is at a high negative address aka kernel space,
* which means that we cannot actually allocate it with target_mmap.
* We still should be able to use page_set_flags, unless the user
* has specified -R reserved_va, which would trigger an assert().
*/
if (reserved_va != 0 &&
TARGET_VSYSCALL_PAGE + TARGET_PAGE_SIZE - 1 > reserved_va) {
error_report("Cannot allocate vsyscall page");
exit(EXIT_FAILURE);
}
page_set_flags(TARGET_VSYSCALL_PAGE,
TARGET_VSYSCALL_PAGE | ~TARGET_PAGE_MASK,
PAGE_EXEC | PAGE_VALID);
return true;
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUX86State *env)
{
r->pt.r15 = tswapal(env->regs[15]);
r->pt.r14 = tswapal(env->regs[14]);
r->pt.r13 = tswapal(env->regs[13]);
r->pt.r12 = tswapal(env->regs[12]);
r->pt.bp = tswapal(env->regs[R_EBP]);
r->pt.bx = tswapal(env->regs[R_EBX]);
r->pt.r11 = tswapal(env->regs[11]);
r->pt.r10 = tswapal(env->regs[10]);
r->pt.r9 = tswapal(env->regs[9]);
r->pt.r8 = tswapal(env->regs[8]);
r->pt.ax = tswapal(env->regs[R_EAX]);
r->pt.cx = tswapal(env->regs[R_ECX]);
r->pt.dx = tswapal(env->regs[R_EDX]);
r->pt.si = tswapal(env->regs[R_ESI]);
r->pt.di = tswapal(env->regs[R_EDI]);
r->pt.orig_ax = tswapal(get_task_state(env_cpu_const(env))->orig_ax);
r->pt.ip = tswapal(env->eip);
r->pt.cs = tswapal(env->segs[R_CS].selector & 0xffff);
r->pt.flags = tswapal(env->eflags);
r->pt.sp = tswapal(env->regs[R_ESP]);
r->pt.ss = tswapal(env->segs[R_SS].selector & 0xffff);
r->pt.fs_base = tswapal(env->segs[R_FS].base);
r->pt.gs_base = tswapal(env->segs[R_GS].base);
r->pt.ds = tswapal(env->segs[R_DS].selector & 0xffff);
r->pt.es = tswapal(env->segs[R_ES].selector & 0xffff);
r->pt.fs = tswapal(env->segs[R_FS].selector & 0xffff);
r->pt.gs = tswapal(env->segs[R_GS].selector & 0xffff);
}

View file

@ -8,7 +8,23 @@
#ifndef X86_64_TARGET_ELF_H
#define X86_64_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_CLASS ELFCLASS64
#define ELF_MACHINE EM_X86_64
#define VDSO_HEADER "vdso.c.inc"
#define HAVE_ELF_HWCAP 1
#define HAVE_ELF_PLATFORM 1
#define HAVE_ELF_CORE_DUMP 1
#define HAVE_GUEST_COMMPAGE 1
/*
* See linux kernel: arch/x86/include/asm/elf.h, where
* elf_gregset_t is mapped to struct user_regs_struct via sizeof.
*/
typedef struct target_elf_gregset_t {
struct target_user_regs_struct pt;
} target_elf_gregset_t;
#endif

View file

@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef X86_64_TARGET_PTRACE_H
#define X86_64_TARGET_PTRACE_H
/*
* The struct pt_regs in arch/x86/include/uapi/asm/ptrace.h has missing
* register values and is not used. See arch/x86/include/asm/user_64.h.
*/
struct target_user_regs_struct {
abi_ulong r15;
abi_ulong r14;
abi_ulong r13;
abi_ulong r12;
abi_ulong bp;
abi_ulong bx;
abi_ulong r11;
abi_ulong r10;
abi_ulong r9;
abi_ulong r8;
abi_ulong ax;
abi_ulong cx;
abi_ulong dx;
abi_ulong si;
abi_ulong di;
abi_ulong orig_ax;
abi_ulong ip;
abi_ulong cs;
abi_ulong flags;
abi_ulong sp;
abi_ulong ss;
abi_ulong fs_base;
abi_ulong gs_base;
abi_ulong ds;
abi_ulong es;
abi_ulong fs;
abi_ulong gs;
};
#endif /* X86_64_TARGET_PTRACE_H */

View file

@ -4,34 +4,6 @@
#define __USER_CS (0x33)
#define __USER_DS (0x2B)
struct target_pt_regs {
abi_ulong r15;
abi_ulong r14;
abi_ulong r13;
abi_ulong r12;
abi_ulong rbp;
abi_ulong rbx;
/* arguments: non interrupts/non tracing syscalls only save up to here */
abi_ulong r11;
abi_ulong r10;
abi_ulong r9;
abi_ulong r8;
abi_ulong rax;
abi_ulong rcx;
abi_ulong rdx;
abi_ulong rsi;
abi_ulong rdi;
abi_ulong orig_rax;
/* end of arguments */
/* cpu exception frame or undefined */
abi_ulong rip;
abi_ulong cs;
abi_ulong eflags;
abi_ulong rsp;
abi_ulong ss;
/* top of stack page */
};
/* Maximum number of LDT entries supported. */
#define TARGET_LDT_ENTRIES 8192
/* The size of each LDT entry. */

View file

@ -3,9 +3,29 @@
#include "qemu/osdep.h"
#include "qemu.h"
#include "loader.h"
#include "target_elf.h"
const char *get_elf_cpu_model(uint32_t eflags)
{
return XTENSA_DEFAULT_CPU_MODEL;
}
void elf_core_copy_regs(target_elf_gregset_t *r, const CPUXtensaState *env)
{
r->pt.pc = tswap32(env->pc);
r->pt.ps = tswap32(env->sregs[PS] & ~PS_EXCM);
r->pt.lbeg = tswap32(env->sregs[LBEG]);
r->pt.lend = tswap32(env->sregs[LEND]);
r->pt.lcount = tswap32(env->sregs[LCOUNT]);
r->pt.sar = tswap32(env->sregs[SAR]);
r->pt.windowstart = tswap32(env->sregs[WINDOW_START]);
r->pt.windowbase = tswap32(env->sregs[WINDOW_BASE]);
r->pt.threadptr = tswap32(env->uregs[THREADPTR]);
xtensa_sync_phys_from_window((CPUXtensaState *)env);
for (unsigned i = 0; i < env->config->nareg; ++i) {
r->pt.a[i] = tswap32(env->phys_regs[i]);
}
}

View file

@ -8,4 +8,19 @@
#ifndef XTENSA_TARGET_ELF_H
#define XTENSA_TARGET_ELF_H
#include "target_ptrace.h"
#define ELF_CLASS ELFCLASS32
#define ELF_MACHINE EM_XTENSA
#define HAVE_ELF_CORE_DUMP 1
/*
* See linux kernel: arch/xtensa/include/asm/elf.h, where elf_gregset_t
* is mapped to struct user_pt_regs via typedef and sizeof.
*/
typedef struct target_elf_gregset_t {
struct target_user_pt_regs pt;
} target_elf_gregset_t;
#endif

View file

@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef XTENSA_TARGET_PTRACE_H
#define XTENSA_TARGET_PTRACE_H
/* See arch/xtensa/include/uapi/asm/ptrace.h. */
struct target_user_pt_regs {
uint32_t pc;
uint32_t ps;
uint32_t lbeg;
uint32_t lend;
uint32_t lcount;
uint32_t sar;
uint32_t windowstart;
uint32_t windowbase;
uint32_t threadptr;
uint32_t syscall;
uint32_t reserved[6 + 48];
uint32_t a[64];
};
#endif /* XTENSA_TARGET_PTRACE_H */

View file

@ -8,41 +8,6 @@
#define MMAP_SHIFT TARGET_PAGE_BITS
typedef uint32_t xtensa_reg_t;
typedef struct {
} xtregs_opt_t; /* TODO */
struct target_pt_regs {
xtensa_reg_t pc; /* 4 */
xtensa_reg_t ps; /* 8 */
xtensa_reg_t depc; /* 12 */
xtensa_reg_t exccause; /* 16 */
xtensa_reg_t excvaddr; /* 20 */
xtensa_reg_t debugcause; /* 24 */
xtensa_reg_t wmask; /* 28 */
xtensa_reg_t lbeg; /* 32 */
xtensa_reg_t lend; /* 36 */
xtensa_reg_t lcount; /* 40 */
xtensa_reg_t sar; /* 44 */
xtensa_reg_t windowbase; /* 48 */
xtensa_reg_t windowstart; /* 52 */
xtensa_reg_t syscall; /* 56 */
xtensa_reg_t icountlevel; /* 60 */
xtensa_reg_t scompare1; /* 64 */
xtensa_reg_t threadptr; /* 68 */
/* Additional configurable registers that are used by the compiler. */
xtregs_opt_t xtregs_opt;
/* Make sure the areg field is 16 bytes aligned. */
int align[0] __attribute__ ((aligned(16)));
/* current register frame.
* Note: The ESF for kernel exceptions ends after 16 registers!
*/
xtensa_reg_t areg[16];
};
#define TARGET_MCL_CURRENT 1
#define TARGET_MCL_FUTURE 2
#define TARGET_MCL_ONFAULT 4