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:
commit
4791f22a5f
79 changed files with 1119 additions and 1441 deletions
|
|
@ -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")) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
------------------------------------
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
------------------------------------
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
14
linux-user/aarch64/target_ptrace.h
Normal file
14
linux-user/aarch64/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -8,4 +8,7 @@
|
|||
#ifndef ALPHA_TARGET_ELF_H
|
||||
#define ALPHA_TARGET_ELF_H
|
||||
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#define ELF_MACHINE EM_ALPHA
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
16
linux-user/arm/target_ptrace.h
Normal file
16
linux-user/arm/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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
|
|
@ -18,4 +18,7 @@
|
|||
#ifndef HEXAGON_TARGET_ELF_H
|
||||
#define HEXAGON_TARGET_ELF_H
|
||||
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_MACHINE EM_HEXAGON
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
32
linux-user/i386/target_ptrace.h
Normal file
32
linux-user/i386/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
15
linux-user/loongarch64/target_ptrace.h
Normal file
15
linux-user/loongarch64/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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"},
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
20
linux-user/microblaze/target_ptrace.h
Normal file
20
linux-user/microblaze/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
17
linux-user/mips/target_ptrace.h
Normal file
17
linux-user/mips/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
16
linux-user/mips64/target_ptrace.h
Normal file
16
linux-user/mips64/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
13
linux-user/openrisc/target_ptrace.h
Normal file
13
linux-user/openrisc/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
26
linux-user/ppc/target_ptrace.h
Normal file
26
linux-user/ppc/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
18
linux-user/s390x/target_ptrace.h
Normal file
18
linux-user/s390x/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
18
linux-user/sh4/target_ptrace.h
Normal file
18
linux-user/sh4/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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"
|
||||
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
24
linux-user/sparc/target_ptrace.h
Normal file
24
linux-user/sparc/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
40
linux-user/x86_64/target_ptrace.h
Normal file
40
linux-user/x86_64/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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. */
|
||||
|
|
|
|||
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
22
linux-user/xtensa/target_ptrace.h
Normal file
22
linux-user/xtensa/target_ptrace.h
Normal 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 */
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue