linux-user pull request 20210517
- alpha sigaction fixes/cleanups - s390x sigaction fixes/cleanup - sparc sigaction fixes/cleanup - s390x core dumping support - core dump fix (app name) - arm fpa11 fix and cleanup - strace fixes (unshare(), llseek()) - fix copy_file_range() - use GDateTime - Remove dead code -----BEGIN PGP SIGNATURE----- iQJGBAABCAAwFiEEzS913cjjpNwuT1Fz8ww4vT8vvjwFAmCjUSASHGxhdXJlbnRA dml2aWVyLmV1AAoJEPMMOL0/L748kUEP/ifogPJjzjOdbe24UeNkhzDFI1NBl0HI SBYuw6IPW/FGKUQJStCLmzgR/jYemcbF6rgZ4oACQjAQ/jD/jmGGhKKMTy+Vbydb Z7ebc3eRS+5kilT/gs5apYmDoAh462ucZDGHMIezTwvDzaxFZtheqWE7tbDRKAYq SH0ySOVcxj7NKR+TsD4RklI/iUZxOUgT7s9Cax6o2yAzxlhrXYzjlPTafuAVh8X8 GLN8r02X9bLUfRf0WPCSjQMOx3UufnECWSux0KtJpzCDCBmlDd3xJYoah/GXvjcB G+Xa/b8KZol7BHjE2DrblHoEk0NbJfV8NyxajIWWKyl7c2q6QJ7ozV9Z1c71nLaq cBWu9Uup6nBiP1Bf58M/2E5uyHSu46peLTrYBy5+W2xnHICwSMEXositefnBJP4H DEw3K2txC/FribP+jzDFbSr08efwkPnqakpGeGnKkCXqN104qBI0PBADnF+qPUA2 nvEIDb45lWjo//d9MW6GoYAKwDXdPORu1UTCVgjZ3W55sXfK4vNPC6dxvnVnjaCI wgTyK0iJ2pzFwgpceNyISw7HF5l5FYchlmoDfkgLeNEowwL5bZfAtxq04Cgl114/ bdfJUJ9mRKKyOfR7y/qn8+uPlv/0iZJ5JLuBFysDlL5pSiOQK07BmxsLi03qRQst ce8uJvohtMIX =JkjD -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/vivier2/tags/linux-user-for-6.1-pull-request' into staging linux-user pull request 20210517 - alpha sigaction fixes/cleanups - s390x sigaction fixes/cleanup - sparc sigaction fixes/cleanup - s390x core dumping support - core dump fix (app name) - arm fpa11 fix and cleanup - strace fixes (unshare(), llseek()) - fix copy_file_range() - use GDateTime - Remove dead code # gpg: Signature made Tue 18 May 2021 06:31:12 BST # gpg: using RSA key CD2F75DDC8E3A4DC2E4F5173F30C38BD3F2FBE3C # gpg: issuer "laurent@vivier.eu" # gpg: Good signature from "Laurent Vivier <lvivier@redhat.com>" [full] # gpg: aka "Laurent Vivier <laurent@vivier.eu>" [full] # gpg: aka "Laurent Vivier (Red Hat) <lvivier@redhat.com>" [full] # Primary key fingerprint: CD2F 75DD C8E3 A4DC 2E4F 5173 F30C 38BD 3F2F BE3C * remotes/vivier2/tags/linux-user-for-6.1-pull-request: (59 commits) linux-user/elfload: add s390x core dumping support linux-user/elfload: fix filling psinfo->pr_psargs linux-user: Tidy TARGET_NR_rt_sigaction linux-user/alpha: Share code for TARGET_NR_sigaction linux-user/alpha: Define TARGET_ARCH_HAS_KA_RESTORER linux-user: Honor TARGET_ARCH_HAS_SA_RESTORER in do_syscall linux-user: Pass ka_restorer to do_sigaction linux-user/alpha: Rename the sigaction restorer field linux-user/alpha: Fix rt sigframe return linux-user: use GDateTime for formatting timestamp for core file linux-user: Fix erroneous conversion in copy_file_range linux-user: Add copy_file_range to strace.list linux-user/s390x: Handle vector regs in signal stack linux-user/s390x: Clean up signal.c linux-user/s390x: Add build asserts for sigset sizes linux-user/s390x: Fix frame_addr corruption in setup_frame linux-user/s390x: Add stub sigframe argument for last_break linux-user/s390x: Set psw.mask properly for the signal handler linux-user/s390x: Clean up single-use gotos in signal.c linux-user/s390x: Tidy save_sigregs ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
c313e52e64
default-configs/targets
linux-user
aarch64
alpha
arm
elfload.chexagon
hppa
i386
m68k
main.cmeson.buildmicroblaze
mips
nios2
openrisc
ppc
qemu.hriscv
s390x
sh4
signal-common.hsignal.csparc
sparc64
cpu_loop.cmeson.buildsignal.csockbits.hsyscall.tblsyscallhdr.shtarget_cpu.htarget_elf.htarget_fcntl.htarget_signal.htarget_structs.htarget_syscall.htermbits.h
strace.cstrace.listsyscall.csyscall_defs.hxtensa
tests/tcg/sparc64
@ -1,5 +1,6 @@
|
||||
TARGET_ARCH=sparc64
|
||||
TARGET_BASE_ARCH=sparc
|
||||
TARGET_ABI_DIR=sparc
|
||||
TARGET_SYSTBL_ABI=common,64
|
||||
TARGET_SYSTBL=syscall.tbl
|
||||
TARGET_ALIGNED_ONLY=y
|
||||
|
@ -561,11 +561,7 @@ long do_rt_sigreturn(CPUARMState *env)
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
if (do_sigaltstack(frame_addr +
|
||||
offsetof(struct target_rt_sigframe, uc.tuc_stack),
|
||||
0, get_sp_from_cpustate(env)) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
target_restore_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
@ -138,8 +138,8 @@ void setup_frame(int sig, struct target_sigaction *ka,
|
||||
|
||||
setup_sigcontext(&frame->sc, env, frame_addr, set);
|
||||
|
||||
if (ka->sa_restorer) {
|
||||
r26 = ka->sa_restorer;
|
||||
if (ka->ka_restorer) {
|
||||
r26 = ka->ka_restorer;
|
||||
} else {
|
||||
__put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
|
||||
__put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
|
||||
@ -192,15 +192,15 @@ void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]);
|
||||
}
|
||||
|
||||
if (ka->sa_restorer) {
|
||||
r26 = ka->sa_restorer;
|
||||
if (ka->ka_restorer) {
|
||||
r26 = ka->ka_restorer;
|
||||
} else {
|
||||
__put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
|
||||
__put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
|
||||
&frame->retcode[1]);
|
||||
__put_user(INSN_CALLSYS, &frame->retcode[2]);
|
||||
/* imb(); */
|
||||
r26 = frame_addr + offsetof(struct target_sigframe, retcode);
|
||||
r26 = frame_addr + offsetof(struct target_rt_sigframe, retcode);
|
||||
}
|
||||
|
||||
if (err) {
|
||||
@ -257,11 +257,7 @@ long do_rt_sigreturn(CPUAlphaState *env)
|
||||
set_sigmask(&set);
|
||||
|
||||
restore_sigcontext(env, &frame->uc.tuc_mcontext);
|
||||
if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
|
||||
uc.tuc_stack),
|
||||
0, env->ir[IR_SP]) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
target_restore_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
@ -92,6 +92,7 @@ typedef struct target_sigaltstack {
|
||||
#define TARGET_GEN_SUBRNG7 -25
|
||||
|
||||
#define TARGET_ARCH_HAS_SETUP_FRAME
|
||||
#define TARGET_ARCH_HAS_KA_RESTORER
|
||||
|
||||
/* bit-flags */
|
||||
#define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */
|
||||
|
@ -224,6 +224,64 @@ static bool insn_is_linux_bkpt(uint32_t opcode, bool is_thumb)
|
||||
}
|
||||
}
|
||||
|
||||
static bool emulate_arm_fpa11(CPUARMState *env, uint32_t opcode)
|
||||
{
|
||||
TaskState *ts = env_cpu(env)->opaque;
|
||||
int rc = EmulateAll(opcode, &ts->fpa, env);
|
||||
int raise, enabled;
|
||||
|
||||
if (rc == 0) {
|
||||
/* Illegal instruction */
|
||||
return false;
|
||||
}
|
||||
if (rc > 0) {
|
||||
/* Everything ok. */
|
||||
env->regs[15] += 4;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* FP exception */
|
||||
rc = -rc;
|
||||
raise = 0;
|
||||
|
||||
/* Translate softfloat flags to FPSR flags */
|
||||
if (rc & float_flag_invalid) {
|
||||
raise |= BIT_IOC;
|
||||
}
|
||||
if (rc & float_flag_divbyzero) {
|
||||
raise |= BIT_DZC;
|
||||
}
|
||||
if (rc & float_flag_overflow) {
|
||||
raise |= BIT_OFC;
|
||||
}
|
||||
if (rc & float_flag_underflow) {
|
||||
raise |= BIT_UFC;
|
||||
}
|
||||
if (rc & float_flag_inexact) {
|
||||
raise |= BIT_IXC;
|
||||
}
|
||||
|
||||
/* Accumulate unenabled exceptions */
|
||||
enabled = ts->fpa.fpsr >> 16;
|
||||
ts->fpa.fpsr |= raise & ~enabled;
|
||||
|
||||
if (raise & enabled) {
|
||||
target_siginfo_t info = { };
|
||||
|
||||
/*
|
||||
* The kernel's nwfpe emulator does not pass a real si_code.
|
||||
* It merely uses send_sig(SIGFPE, current, 1).
|
||||
*/
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_code = TARGET_SI_KERNEL;
|
||||
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
} else {
|
||||
env->regs[15] += 4;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void cpu_loop(CPUARMState *env)
|
||||
{
|
||||
CPUState *cs = env_cpu(env);
|
||||
@ -244,9 +302,7 @@ void cpu_loop(CPUARMState *env)
|
||||
case EXCP_NOCP:
|
||||
case EXCP_INVSTATE:
|
||||
{
|
||||
TaskState *ts = cs->opaque;
|
||||
uint32_t opcode;
|
||||
int rc;
|
||||
|
||||
/* we handle the FPU emulation here, as Linux */
|
||||
/* we get the opcode */
|
||||
@ -263,64 +319,15 @@ void cpu_loop(CPUARMState *env)
|
||||
goto excp_debug;
|
||||
}
|
||||
|
||||
rc = EmulateAll(opcode, &ts->fpa, env);
|
||||
if (rc == 0) { /* illegal instruction */
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->regs[15];
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
} else if (rc < 0) { /* FP exception */
|
||||
int arm_fpe=0;
|
||||
|
||||
/* translate softfloat flags to FPSR flags */
|
||||
if (-rc & float_flag_invalid)
|
||||
arm_fpe |= BIT_IOC;
|
||||
if (-rc & float_flag_divbyzero)
|
||||
arm_fpe |= BIT_DZC;
|
||||
if (-rc & float_flag_overflow)
|
||||
arm_fpe |= BIT_OFC;
|
||||
if (-rc & float_flag_underflow)
|
||||
arm_fpe |= BIT_UFC;
|
||||
if (-rc & float_flag_inexact)
|
||||
arm_fpe |= BIT_IXC;
|
||||
|
||||
FPSR fpsr = ts->fpa.fpsr;
|
||||
//printf("fpsr 0x%x, arm_fpe 0x%x\n",fpsr,arm_fpe);
|
||||
|
||||
if (fpsr & (arm_fpe << 16)) { /* exception enabled? */
|
||||
info.si_signo = TARGET_SIGFPE;
|
||||
info.si_errno = 0;
|
||||
|
||||
/* ordered by priority, least first */
|
||||
if (arm_fpe & BIT_IXC) info.si_code = TARGET_FPE_FLTRES;
|
||||
if (arm_fpe & BIT_UFC) info.si_code = TARGET_FPE_FLTUND;
|
||||
if (arm_fpe & BIT_OFC) info.si_code = TARGET_FPE_FLTOVF;
|
||||
if (arm_fpe & BIT_DZC) info.si_code = TARGET_FPE_FLTDIV;
|
||||
if (arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV;
|
||||
|
||||
info._sifields._sigfault._addr = env->regs[15];
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
} else {
|
||||
env->regs[15] += 4;
|
||||
}
|
||||
|
||||
/* accumulate unenabled exceptions */
|
||||
if ((!(fpsr & BIT_IXE)) && (arm_fpe & BIT_IXC))
|
||||
fpsr |= BIT_IXC;
|
||||
if ((!(fpsr & BIT_UFE)) && (arm_fpe & BIT_UFC))
|
||||
fpsr |= BIT_UFC;
|
||||
if ((!(fpsr & BIT_OFE)) && (arm_fpe & BIT_OFC))
|
||||
fpsr |= BIT_OFC;
|
||||
if ((!(fpsr & BIT_DZE)) && (arm_fpe & BIT_DZC))
|
||||
fpsr |= BIT_DZC;
|
||||
if ((!(fpsr & BIT_IOE)) && (arm_fpe & BIT_IOC))
|
||||
fpsr |= BIT_IOC;
|
||||
ts->fpa.fpsr=fpsr;
|
||||
} else { /* everything OK */
|
||||
/* increment PC */
|
||||
env->regs[15] += 4;
|
||||
if (!env->thumb && emulate_arm_fpa11(env, opcode)) {
|
||||
break;
|
||||
}
|
||||
|
||||
info.si_signo = TARGET_SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->regs[15];
|
||||
queue_signal(env, info.si_signo, QEMU_SI_FAULT, &info);
|
||||
}
|
||||
break;
|
||||
case EXCP_SWI:
|
||||
|
@ -685,11 +685,7 @@ static int do_sigframe_return_v2(CPUARMState *env,
|
||||
}
|
||||
}
|
||||
|
||||
if (do_sigaltstack(context_addr
|
||||
+ offsetof(struct target_ucontext_v2, tuc_stack),
|
||||
0, get_sp_from_cpustate(env)) == -EFAULT) {
|
||||
return 1;
|
||||
}
|
||||
target_restore_altstack(&uc->tuc_stack, env);
|
||||
|
||||
#if 0
|
||||
/* Send SIGTRAP if we're single-stepping */
|
||||
@ -773,8 +769,7 @@ static long do_rt_sigreturn_v1(CPUARMState *env)
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)
|
||||
goto badframe;
|
||||
target_restore_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
#if 0
|
||||
/* Send SIGTRAP if we're single-stepping */
|
||||
|
@ -676,48 +676,25 @@ static uint32_t get_elf_hwcap2(void)
|
||||
|
||||
#define ELF_CLASS ELFCLASS64
|
||||
#define ELF_ARCH EM_SPARCV9
|
||||
|
||||
#define STACK_BIAS 2047
|
||||
|
||||
static inline void init_thread(struct target_pt_regs *regs,
|
||||
struct image_info *infop)
|
||||
{
|
||||
#ifndef TARGET_ABI32
|
||||
regs->tstate = 0;
|
||||
#endif
|
||||
regs->pc = infop->entry;
|
||||
regs->npc = regs->pc + 4;
|
||||
regs->y = 0;
|
||||
#ifdef TARGET_ABI32
|
||||
regs->u_regs[14] = infop->start_stack - 16 * 4;
|
||||
#else
|
||||
if (personality(infop->personality) == PER_LINUX32)
|
||||
regs->u_regs[14] = infop->start_stack - 16 * 4;
|
||||
else
|
||||
regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS;
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
#define ELF_START_MMAP 0x80000000
|
||||
#define ELF_HWCAP (HWCAP_SPARC_FLUSH | HWCAP_SPARC_STBAR | HWCAP_SPARC_SWAP \
|
||||
| HWCAP_SPARC_MULDIV)
|
||||
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#define ELF_ARCH EM_SPARC
|
||||
#endif /* TARGET_SPARC64 */
|
||||
|
||||
static inline void init_thread(struct target_pt_regs *regs,
|
||||
struct image_info *infop)
|
||||
{
|
||||
regs->psr = 0;
|
||||
/* Note that target_cpu_copy_regs does not read psr/tstate. */
|
||||
regs->pc = infop->entry;
|
||||
regs->npc = regs->pc + 4;
|
||||
regs->y = 0;
|
||||
regs->u_regs[14] = infop->start_stack - 16 * 4;
|
||||
regs->u_regs[14] = (infop->start_stack - 16 * sizeof(abi_ulong)
|
||||
- TARGET_STACK_BIAS);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
#endif /* TARGET_SPARC */
|
||||
|
||||
#ifdef TARGET_PPC
|
||||
|
||||
@ -1398,6 +1375,39 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
|
||||
regs->gprs[15] = infop->start_stack;
|
||||
}
|
||||
|
||||
/* See linux kernel: arch/s390/include/uapi/asm/ptrace.h (s390_regs). */
|
||||
#define ELF_NREG 27
|
||||
typedef target_elf_greg_t target_elf_gregset_t[ELF_NREG];
|
||||
|
||||
enum {
|
||||
TARGET_REG_PSWM = 0,
|
||||
TARGET_REG_PSWA = 1,
|
||||
TARGET_REG_GPRS = 2,
|
||||
TARGET_REG_ARS = 18,
|
||||
TARGET_REG_ORIG_R2 = 26,
|
||||
};
|
||||
|
||||
static void elf_core_copy_regs(target_elf_gregset_t *regs,
|
||||
const CPUS390XState *env)
|
||||
{
|
||||
int i;
|
||||
uint32_t *aregs;
|
||||
|
||||
(*regs)[TARGET_REG_PSWM] = tswapreg(env->psw.mask);
|
||||
(*regs)[TARGET_REG_PSWA] = tswapreg(env->psw.addr);
|
||||
for (i = 0; i < 16; i++) {
|
||||
(*regs)[TARGET_REG_GPRS + i] = tswapreg(env->regs[i]);
|
||||
}
|
||||
aregs = (uint32_t *)&((*regs)[TARGET_REG_ARS]);
|
||||
for (i = 0; i < 16; i++) {
|
||||
aregs[i] = tswap32(env->aregs[i]);
|
||||
}
|
||||
(*regs)[TARGET_REG_ORIG_R2] = 0;
|
||||
}
|
||||
|
||||
#define USE_ELF_CORE_DUMP
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
#endif /* TARGET_S390X */
|
||||
|
||||
#ifdef TARGET_RISCV
|
||||
@ -3399,7 +3409,6 @@ static size_t note_size(const struct memelfnote *);
|
||||
static void free_note_info(struct elf_note_info *);
|
||||
static int fill_note_info(struct elf_note_info *, long, const CPUArchState *);
|
||||
static void fill_thread_info(struct elf_note_info *, const CPUArchState *);
|
||||
static int core_dump_filename(const TaskState *, char *, size_t);
|
||||
|
||||
static int dump_write(int, const void *, size_t);
|
||||
static int write_note(struct memelfnote *, int);
|
||||
@ -3642,11 +3651,12 @@ static int fill_psinfo(struct target_elf_prpsinfo *psinfo, const TaskState *ts)
|
||||
|
||||
(void) memset(psinfo, 0, sizeof (*psinfo));
|
||||
|
||||
len = ts->info->arg_end - ts->info->arg_start;
|
||||
len = ts->info->env_strings - ts->info->arg_strings;
|
||||
if (len >= ELF_PRARGSZ)
|
||||
len = ELF_PRARGSZ - 1;
|
||||
if (copy_from_user(&psinfo->pr_psargs, ts->info->arg_start, len))
|
||||
if (copy_from_user(&psinfo->pr_psargs, ts->info->arg_strings, len)) {
|
||||
return -EFAULT;
|
||||
}
|
||||
for (i = 0; i < len; i++)
|
||||
if (psinfo->pr_psargs[i] == 0)
|
||||
psinfo->pr_psargs[i] = ' ';
|
||||
@ -3698,32 +3708,16 @@ static void fill_auxv_note(struct memelfnote *note, const TaskState *ts)
|
||||
* for the name:
|
||||
* qemu_<basename-of-target-binary>_<date>-<time>_<pid>.core
|
||||
*
|
||||
* Returns 0 in case of success, -1 otherwise (errno is set).
|
||||
* Returns the filename
|
||||
*/
|
||||
static int core_dump_filename(const TaskState *ts, char *buf,
|
||||
size_t bufsize)
|
||||
static char *core_dump_filename(const TaskState *ts)
|
||||
{
|
||||
char timestamp[64];
|
||||
char *base_filename = NULL;
|
||||
struct timeval tv;
|
||||
struct tm tm;
|
||||
g_autoptr(GDateTime) now = g_date_time_new_now_local();
|
||||
g_autofree char *nowstr = g_date_time_format(now, "%Y%m%d-%H%M%S");
|
||||
g_autofree char *base_filename = g_path_get_basename(ts->bprm->filename);
|
||||
|
||||
assert(bufsize >= PATH_MAX);
|
||||
|
||||
if (gettimeofday(&tv, NULL) < 0) {
|
||||
(void) fprintf(stderr, "unable to get current timestamp: %s",
|
||||
strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
base_filename = g_path_get_basename(ts->bprm->filename);
|
||||
(void) strftime(timestamp, sizeof (timestamp), "%Y%m%d-%H%M%S",
|
||||
localtime_r(&tv.tv_sec, &tm));
|
||||
(void) snprintf(buf, bufsize, "qemu_%s_%s_%d.core",
|
||||
base_filename, timestamp, (int)getpid());
|
||||
g_free(base_filename);
|
||||
|
||||
return (0);
|
||||
return g_strdup_printf("qemu_%s_%s_%d.core",
|
||||
base_filename, nowstr, (int)getpid());
|
||||
}
|
||||
|
||||
static int dump_write(int fd, const void *ptr, size_t size)
|
||||
@ -3951,7 +3945,7 @@ static int elf_core_dump(int signr, const CPUArchState *env)
|
||||
const CPUState *cpu = env_cpu((CPUArchState *)env);
|
||||
const TaskState *ts = (const TaskState *)cpu->opaque;
|
||||
struct vm_area_struct *vma = NULL;
|
||||
char corefile[PATH_MAX];
|
||||
g_autofree char *corefile = NULL;
|
||||
struct elf_note_info info;
|
||||
struct elfhdr elf;
|
||||
struct elf_phdr phdr;
|
||||
@ -3968,8 +3962,7 @@ static int elf_core_dump(int signr, const CPUArchState *env)
|
||||
if (dumpsize.rlim_cur == 0)
|
||||
return 0;
|
||||
|
||||
if (core_dump_filename(ts, corefile, sizeof (corefile)) < 0)
|
||||
return (-errno);
|
||||
corefile = core_dump_filename(ts);
|
||||
|
||||
if ((fd = open(corefile, O_WRONLY | O_CREAT,
|
||||
S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)) < 0)
|
||||
|
@ -260,11 +260,7 @@ long do_rt_sigreturn(CPUHexagonState *env)
|
||||
}
|
||||
|
||||
restore_ucontext(env, &frame->uc);
|
||||
|
||||
if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
|
||||
uc.uc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
target_restore_altstack(&frame->uc.uc_stack, env);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
@ -187,13 +187,7 @@ long do_rt_sigreturn(CPUArchState *env)
|
||||
set_sigmask(&set);
|
||||
|
||||
restore_sigcontext(env, &frame->uc.tuc_mcontext);
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
|
||||
if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
|
||||
uc.tuc_stack),
|
||||
0, env->gr[30]) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
target_restore_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
@ -581,10 +581,7 @@ long do_rt_sigreturn(CPUX86State *env)
|
||||
goto badframe;
|
||||
}
|
||||
|
||||
if (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe, uc.tuc_stack), 0,
|
||||
get_sp_from_cpustate(env)) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
target_restore_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
@ -400,10 +400,7 @@ long do_rt_sigreturn(CPUM68KState *env)
|
||||
if (target_rt_restore_ucontext(env, &frame->uc))
|
||||
goto badframe;
|
||||
|
||||
if (do_sigaltstack(frame_addr +
|
||||
offsetof(struct target_rt_sigframe, uc.tuc_stack),
|
||||
0, get_sp_from_cpustate(env)) == -EFAULT)
|
||||
goto badframe;
|
||||
target_restore_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
@ -205,7 +205,6 @@ CPUArchState *cpu_copy(CPUArchState *env)
|
||||
CPUState *new_cpu = cpu_create(cpu_type);
|
||||
CPUArchState *new_env = new_cpu->env_ptr;
|
||||
CPUBreakpoint *bp;
|
||||
CPUWatchpoint *wp;
|
||||
|
||||
/* Reset non arch specific state */
|
||||
cpu_reset(new_cpu);
|
||||
@ -217,13 +216,9 @@ CPUArchState *cpu_copy(CPUArchState *env)
|
||||
Note: Once we support ptrace with hw-debug register access, make sure
|
||||
BP_CPU break/watchpoints are handled correctly on clone. */
|
||||
QTAILQ_INIT(&new_cpu->breakpoints);
|
||||
QTAILQ_INIT(&new_cpu->watchpoints);
|
||||
QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
|
||||
cpu_breakpoint_insert(new_cpu, bp->pc, bp->flags, NULL);
|
||||
}
|
||||
QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
|
||||
cpu_watchpoint_insert(new_cpu, wp->vaddr, wp->len, wp->flags, NULL);
|
||||
}
|
||||
|
||||
return new_env;
|
||||
}
|
||||
|
@ -32,7 +32,6 @@ subdir('mips')
|
||||
subdir('ppc')
|
||||
subdir('s390x')
|
||||
subdir('sh4')
|
||||
subdir('sparc64')
|
||||
subdir('sparc')
|
||||
subdir('x86_64')
|
||||
subdir('xtensa')
|
||||
|
@ -209,11 +209,7 @@ long do_rt_sigreturn(CPUMBState *env)
|
||||
|
||||
restore_sigcontext(&frame->uc.tuc_mcontext, env);
|
||||
|
||||
if (do_sigaltstack(frame_addr +
|
||||
offsetof(struct target_rt_sigframe, uc.tuc_stack),
|
||||
0, get_sp_from_cpustate(env)) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
target_restore_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
@ -368,11 +368,7 @@ long do_rt_sigreturn(CPUMIPSState *env)
|
||||
set_sigmask(&blocked);
|
||||
|
||||
restore_sigcontext(env, &frame->rs_uc.tuc_mcontext);
|
||||
|
||||
if (do_sigaltstack(frame_addr +
|
||||
offsetof(struct target_rt_sigframe, rs_uc.tuc_stack),
|
||||
0, get_sp_from_cpustate(env)) == -EFAULT)
|
||||
goto badframe;
|
||||
target_restore_altstack(&frame->rs_uc.tuc_stack, env);
|
||||
|
||||
env->active_tc.PC = env->CP0_EPC;
|
||||
mips_set_hflags_isa_mode_from_pc(env);
|
||||
|
@ -82,9 +82,7 @@ static int rt_restore_ucontext(CPUNios2State *env, struct target_ucontext *uc,
|
||||
int *pr2)
|
||||
{
|
||||
int temp;
|
||||
abi_ulong off, frame_addr = env->regs[R_SP];
|
||||
unsigned long *gregs = uc->tuc_mcontext.gregs;
|
||||
int err;
|
||||
|
||||
/* Always make any pending restarted system calls return -EINTR */
|
||||
/* current->restart_block.fn = do_no_restart_syscall; */
|
||||
@ -130,11 +128,7 @@ static int rt_restore_ucontext(CPUNios2State *env, struct target_ucontext *uc,
|
||||
__get_user(env->regs[R_RA], &gregs[23]);
|
||||
__get_user(env->regs[R_SP], &gregs[28]);
|
||||
|
||||
off = offsetof(struct target_rt_sigframe, uc.tuc_stack);
|
||||
err = do_sigaltstack(frame_addr + off, 0, get_sp_from_cpustate(env));
|
||||
if (err == -EFAULT) {
|
||||
return 1;
|
||||
}
|
||||
target_restore_altstack(&uc->tuc_stack, env);
|
||||
|
||||
*pr2 = env->regs[2];
|
||||
return 0;
|
||||
|
@ -158,10 +158,7 @@ long do_rt_sigreturn(CPUOpenRISCState *env)
|
||||
set_sigmask(&set);
|
||||
|
||||
restore_sigcontext(env, &frame->uc.tuc_mcontext);
|
||||
if (do_sigaltstack(frame_addr + offsetof(target_rt_sigframe, uc.tuc_stack),
|
||||
0, frame_addr) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
target_restore_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return cpu_get_gpr(env, 11);
|
||||
|
@ -655,9 +655,7 @@ long do_rt_sigreturn(CPUPPCState *env)
|
||||
if (do_setcontext(&rt_sf->uc, env, 1))
|
||||
goto sigsegv;
|
||||
|
||||
do_sigaltstack(rt_sf_addr
|
||||
+ offsetof(struct target_rt_sigframe, uc.tuc_stack),
|
||||
0, env->gpr[1]);
|
||||
target_restore_altstack(&rt_sf->uc.tuc_stack, env);
|
||||
|
||||
unlock_user_struct(rt_sf, rt_sf_addr, 1);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
@ -432,7 +432,8 @@ int target_to_host_signal(int sig);
|
||||
int host_to_target_signal(int sig);
|
||||
long do_sigreturn(CPUArchState *env);
|
||||
long do_rt_sigreturn(CPUArchState *env);
|
||||
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp);
|
||||
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr,
|
||||
CPUArchState *env);
|
||||
int do_sigprocmask(int how, const sigset_t *set, sigset_t *oldset);
|
||||
abi_long do_swapcontext(CPUArchState *env, abi_ulong uold_ctx,
|
||||
abi_ulong unew_ctx, abi_long ctx_size);
|
||||
|
@ -192,11 +192,7 @@ long do_rt_sigreturn(CPURISCVState *env)
|
||||
}
|
||||
|
||||
restore_ucontext(env, &frame->uc);
|
||||
|
||||
if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
|
||||
uc.uc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
target_restore_altstack(&frame->uc.uc_stack, env);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
@ -25,25 +25,24 @@
|
||||
#define __NUM_FPRS 16
|
||||
#define __NUM_ACRS 16
|
||||
|
||||
#define S390_SYSCALL_SIZE 2
|
||||
#define __SIGNAL_FRAMESIZE 160 /* FIXME: 31-bit mode -> 96 */
|
||||
|
||||
#define _SIGCONTEXT_NSIG 64
|
||||
#define _SIGCONTEXT_NSIG_BPW 64 /* FIXME: 31-bit mode -> 32 */
|
||||
#define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW)
|
||||
#define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS)
|
||||
#define PSW_ADDR_AMODE 0x0000000000000000UL /* 0x80000000UL for 31-bit */
|
||||
#define S390_SYSCALL_OPCODE ((uint16_t)0x0a00)
|
||||
|
||||
typedef struct {
|
||||
target_psw_t psw;
|
||||
target_ulong gprs[__NUM_GPRS];
|
||||
unsigned int acrs[__NUM_ACRS];
|
||||
abi_ulong gprs[__NUM_GPRS];
|
||||
abi_uint acrs[__NUM_ACRS];
|
||||
} target_s390_regs_common;
|
||||
|
||||
typedef struct {
|
||||
unsigned int fpc;
|
||||
double fprs[__NUM_FPRS];
|
||||
uint32_t fpc;
|
||||
uint32_t pad;
|
||||
uint64_t fprs[__NUM_FPRS];
|
||||
} target_s390_fp_regs;
|
||||
|
||||
typedef struct {
|
||||
@ -51,30 +50,41 @@ typedef struct {
|
||||
target_s390_fp_regs fpregs;
|
||||
} target_sigregs;
|
||||
|
||||
struct target_sigcontext {
|
||||
target_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
|
||||
target_sigregs *sregs;
|
||||
};
|
||||
typedef struct {
|
||||
uint64_t vxrs_low[16];
|
||||
uint64_t vxrs_high[16][2];
|
||||
uint8_t reserved[128];
|
||||
} target_sigregs_ext;
|
||||
|
||||
typedef struct {
|
||||
abi_ulong oldmask[_SIGCONTEXT_NSIG_WORDS];
|
||||
abi_ulong sregs;
|
||||
} target_sigcontext;
|
||||
|
||||
typedef struct {
|
||||
uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
|
||||
struct target_sigcontext sc;
|
||||
target_sigcontext sc;
|
||||
target_sigregs sregs;
|
||||
int signo;
|
||||
uint8_t retcode[S390_SYSCALL_SIZE];
|
||||
target_sigregs_ext sregs_ext;
|
||||
uint16_t retcode;
|
||||
} sigframe;
|
||||
|
||||
#define TARGET_UC_VXRS 2
|
||||
|
||||
struct target_ucontext {
|
||||
target_ulong tuc_flags;
|
||||
struct target_ucontext *tuc_link;
|
||||
abi_ulong tuc_flags;
|
||||
abi_ulong tuc_link;
|
||||
target_stack_t tuc_stack;
|
||||
target_sigregs tuc_mcontext;
|
||||
target_sigset_t tuc_sigmask; /* mask last for extensibility */
|
||||
target_sigset_t tuc_sigmask;
|
||||
uint8_t reserved[128 - sizeof(target_sigset_t)];
|
||||
target_sigregs_ext tuc_mcontext_ext;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t callee_used_stack[__SIGNAL_FRAMESIZE];
|
||||
uint8_t retcode[S390_SYSCALL_SIZE];
|
||||
uint16_t retcode;
|
||||
struct target_siginfo info;
|
||||
struct target_ucontext uc;
|
||||
} rt_sigframe;
|
||||
@ -105,151 +115,191 @@ get_sigframe(struct target_sigaction *ka, CPUS390XState *env, size_t frame_size)
|
||||
static void save_sigregs(CPUS390XState *env, target_sigregs *sregs)
|
||||
{
|
||||
int i;
|
||||
//save_access_regs(current->thread.acrs); FIXME
|
||||
|
||||
/* Copy a 'clean' PSW mask to the user to avoid leaking
|
||||
information about whether PER is currently on. */
|
||||
/*
|
||||
* Copy a 'clean' PSW mask to the user to avoid leaking
|
||||
* information about whether PER is currently on.
|
||||
*/
|
||||
__put_user(env->psw.mask, &sregs->regs.psw.mask);
|
||||
__put_user(env->psw.addr, &sregs->regs.psw.addr);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
__put_user(env->regs[i], &sregs->regs.gprs[i]);
|
||||
}
|
||||
for (i = 0; i < 16; i++) {
|
||||
__put_user(env->aregs[i], &sregs->regs.acrs[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to store the fp registers to current->thread.fp_regs
|
||||
* to merge them with the emulated registers.
|
||||
*/
|
||||
//save_fp_regs(¤t->thread.fp_regs); FIXME
|
||||
for (i = 0; i < 16; i++) {
|
||||
__put_user(*get_freg(env, i), &sregs->fpregs.fprs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void save_sigregs_ext(CPUS390XState *env, target_sigregs_ext *ext)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* if (MACHINE_HAS_VX) ...
|
||||
* That said, we always allocate the stack storage and the
|
||||
* space is always available in env.
|
||||
*/
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__put_user(env->vregs[i][1], &ext->vxrs_low[i]);
|
||||
}
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__put_user(env->vregs[i + 16][0], &ext->vxrs_high[i][0]);
|
||||
__put_user(env->vregs[i + 16][1], &ext->vxrs_high[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
void setup_frame(int sig, struct target_sigaction *ka,
|
||||
target_sigset_t *set, CPUS390XState *env)
|
||||
{
|
||||
sigframe *frame;
|
||||
abi_ulong frame_addr;
|
||||
abi_ulong restorer;
|
||||
|
||||
frame_addr = get_sigframe(ka, env, sizeof(*frame));
|
||||
trace_user_setup_frame(env, frame_addr);
|
||||
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
|
||||
goto give_sigsegv;
|
||||
}
|
||||
|
||||
__put_user(set->sig[0], &frame->sc.oldmask[0]);
|
||||
|
||||
save_sigregs(env, &frame->sregs);
|
||||
|
||||
__put_user((abi_ulong)(unsigned long)&frame->sregs,
|
||||
(abi_ulong *)&frame->sc.sregs);
|
||||
|
||||
/* Set up to return from userspace. If provided, use a stub
|
||||
already in userspace. */
|
||||
if (ka->sa_flags & TARGET_SA_RESTORER) {
|
||||
env->regs[14] = (unsigned long)
|
||||
ka->sa_restorer | PSW_ADDR_AMODE;
|
||||
} else {
|
||||
env->regs[14] = (frame_addr + offsetof(sigframe, retcode))
|
||||
| PSW_ADDR_AMODE;
|
||||
__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
|
||||
(uint16_t *)(frame->retcode));
|
||||
force_sigsegv(sig);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set up backchain. */
|
||||
__put_user(env->regs[15], (abi_ulong *) frame);
|
||||
|
||||
/* Create struct sigcontext on the signal stack. */
|
||||
/* Make sure that we're initializing all of oldmask. */
|
||||
QEMU_BUILD_BUG_ON(ARRAY_SIZE(frame->sc.oldmask) != 1);
|
||||
__put_user(set->sig[0], &frame->sc.oldmask[0]);
|
||||
__put_user(frame_addr + offsetof(sigframe, sregs), &frame->sc.sregs);
|
||||
|
||||
/* Create _sigregs on the signal stack */
|
||||
save_sigregs(env, &frame->sregs);
|
||||
|
||||
/*
|
||||
* ??? The kernel uses regs->gprs[2] here, which is not yet the signo.
|
||||
* Moreover the comment talks about allowing backtrace, which is really
|
||||
* done by the r15 copy above.
|
||||
*/
|
||||
__put_user(sig, &frame->signo);
|
||||
|
||||
/* Create sigregs_ext on the signal stack. */
|
||||
save_sigregs_ext(env, &frame->sregs_ext);
|
||||
|
||||
/*
|
||||
* Set up to return from userspace.
|
||||
* If provided, use a stub already in userspace.
|
||||
*/
|
||||
if (ka->sa_flags & TARGET_SA_RESTORER) {
|
||||
restorer = ka->sa_restorer;
|
||||
} else {
|
||||
restorer = frame_addr + offsetof(sigframe, retcode);
|
||||
__put_user(S390_SYSCALL_OPCODE | TARGET_NR_sigreturn,
|
||||
&frame->retcode);
|
||||
}
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
env->regs[14] = restorer;
|
||||
env->regs[15] = frame_addr;
|
||||
env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
|
||||
/* Force default amode and default user address space control. */
|
||||
env->psw.mask = PSW_MASK_64 | PSW_MASK_32 | PSW_ASC_PRIMARY
|
||||
| (env->psw.mask & ~PSW_MASK_ASC);
|
||||
env->psw.addr = ka->_sa_handler;
|
||||
|
||||
env->regs[2] = sig; //map_signal(sig);
|
||||
env->regs[3] = frame_addr += offsetof(typeof(*frame), sc);
|
||||
env->regs[2] = sig;
|
||||
env->regs[3] = frame_addr + offsetof(typeof(*frame), sc);
|
||||
|
||||
/* We forgot to include these in the sigcontext.
|
||||
To avoid breaking binary compatibility, they are passed as args. */
|
||||
env->regs[4] = 0; // FIXME: no clue... current->thread.trap_no;
|
||||
env->regs[5] = 0; // FIXME: no clue... current->thread.prot_addr;
|
||||
/*
|
||||
* We forgot to include these in the sigcontext.
|
||||
* To avoid breaking binary compatibility, they are passed as args.
|
||||
*/
|
||||
env->regs[4] = 0; /* FIXME: regs->int_code & 127 */
|
||||
env->regs[5] = 0; /* FIXME: regs->int_parm_long */
|
||||
env->regs[6] = 0; /* FIXME: current->thread.last_break */
|
||||
|
||||
/* Place signal number on stack to allow backtrace from handler. */
|
||||
__put_user(env->regs[2], &frame->signo);
|
||||
unlock_user_struct(frame, frame_addr, 1);
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
force_sigsegv(sig);
|
||||
}
|
||||
|
||||
void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
target_siginfo_t *info,
|
||||
target_sigset_t *set, CPUS390XState *env)
|
||||
{
|
||||
int i;
|
||||
rt_sigframe *frame;
|
||||
abi_ulong frame_addr;
|
||||
abi_ulong restorer;
|
||||
abi_ulong uc_flags;
|
||||
|
||||
frame_addr = get_sigframe(ka, env, sizeof *frame);
|
||||
trace_user_setup_rt_frame(env, frame_addr);
|
||||
if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
|
||||
goto give_sigsegv;
|
||||
}
|
||||
|
||||
tswap_siginfo(&frame->info, info);
|
||||
|
||||
/* Create the ucontext. */
|
||||
__put_user(0, &frame->uc.tuc_flags);
|
||||
__put_user((abi_ulong)0, (abi_ulong *)&frame->uc.tuc_link);
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
save_sigregs(env, &frame->uc.tuc_mcontext);
|
||||
for (i = 0; i < TARGET_NSIG_WORDS; i++) {
|
||||
__put_user((abi_ulong)set->sig[i],
|
||||
(abi_ulong *)&frame->uc.tuc_sigmask.sig[i]);
|
||||
}
|
||||
|
||||
/* Set up to return from userspace. If provided, use a stub
|
||||
already in userspace. */
|
||||
if (ka->sa_flags & TARGET_SA_RESTORER) {
|
||||
env->regs[14] = ka->sa_restorer | PSW_ADDR_AMODE;
|
||||
} else {
|
||||
env->regs[14] = (frame_addr + offsetof(typeof(*frame), retcode))
|
||||
| PSW_ADDR_AMODE;
|
||||
__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
|
||||
(uint16_t *)(frame->retcode));
|
||||
force_sigsegv(sig);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set up backchain. */
|
||||
__put_user(env->regs[15], (abi_ulong *) frame);
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
env->regs[15] = frame_addr;
|
||||
env->psw.addr = (target_ulong) ka->_sa_handler | PSW_ADDR_AMODE;
|
||||
/*
|
||||
* Set up to return from userspace.
|
||||
* If provided, use a stub already in userspace.
|
||||
*/
|
||||
if (ka->sa_flags & TARGET_SA_RESTORER) {
|
||||
restorer = ka->sa_restorer;
|
||||
} else {
|
||||
restorer = frame_addr + offsetof(typeof(*frame), retcode);
|
||||
__put_user(S390_SYSCALL_OPCODE | TARGET_NR_rt_sigreturn,
|
||||
&frame->retcode);
|
||||
}
|
||||
|
||||
env->regs[2] = sig; //map_signal(sig);
|
||||
/* Create siginfo on the signal stack. */
|
||||
tswap_siginfo(&frame->info, info);
|
||||
|
||||
/* Create ucontext on the signal stack. */
|
||||
uc_flags = 0;
|
||||
if (s390_has_feat(S390_FEAT_VECTOR)) {
|
||||
uc_flags |= TARGET_UC_VXRS;
|
||||
}
|
||||
__put_user(uc_flags, &frame->uc.tuc_flags);
|
||||
__put_user(0, &frame->uc.tuc_link);
|
||||
target_save_altstack(&frame->uc.tuc_stack, env);
|
||||
save_sigregs(env, &frame->uc.tuc_mcontext);
|
||||
save_sigregs_ext(env, &frame->uc.tuc_mcontext_ext);
|
||||
tswap_sigset(&frame->uc.tuc_sigmask, set);
|
||||
|
||||
/* Set up registers for signal handler */
|
||||
env->regs[14] = restorer;
|
||||
env->regs[15] = frame_addr;
|
||||
/* Force default amode and default user address space control. */
|
||||
env->psw.mask = PSW_MASK_64 | PSW_MASK_32 | PSW_ASC_PRIMARY
|
||||
| (env->psw.mask & ~PSW_MASK_ASC);
|
||||
env->psw.addr = ka->_sa_handler;
|
||||
|
||||
env->regs[2] = sig;
|
||||
env->regs[3] = frame_addr + offsetof(typeof(*frame), info);
|
||||
env->regs[4] = frame_addr + offsetof(typeof(*frame), uc);
|
||||
return;
|
||||
|
||||
give_sigsegv:
|
||||
force_sigsegv(sig);
|
||||
env->regs[5] = 0; /* FIXME: current->thread.last_break */
|
||||
}
|
||||
|
||||
static int
|
||||
restore_sigregs(CPUS390XState *env, target_sigregs *sc)
|
||||
static void restore_sigregs(CPUS390XState *env, target_sigregs *sc)
|
||||
{
|
||||
int err = 0;
|
||||
target_ulong prev_addr;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
__get_user(env->regs[i], &sc->regs.gprs[i]);
|
||||
}
|
||||
|
||||
prev_addr = env->psw.addr;
|
||||
__get_user(env->psw.mask, &sc->regs.psw.mask);
|
||||
trace_user_s390x_restore_sigregs(env, (unsigned long long)sc->regs.psw.addr,
|
||||
(unsigned long long)env->psw.addr);
|
||||
__get_user(env->psw.addr, &sc->regs.psw.addr);
|
||||
/* FIXME: 31-bit -> | PSW_ADDR_AMODE */
|
||||
trace_user_s390x_restore_sigregs(env, env->psw.addr, prev_addr);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
__get_user(env->aregs[i], &sc->regs.acrs[i]);
|
||||
@ -257,8 +307,24 @@ restore_sigregs(CPUS390XState *env, target_sigregs *sc)
|
||||
for (i = 0; i < 16; i++) {
|
||||
__get_user(*get_freg(env, i), &sc->fpregs.fprs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return err;
|
||||
static void restore_sigregs_ext(CPUS390XState *env, target_sigregs_ext *ext)
|
||||
{
|
||||
int i;
|
||||
|
||||
/*
|
||||
* if (MACHINE_HAS_VX) ...
|
||||
* That said, we always allocate the stack storage and the
|
||||
* space is always available in env.
|
||||
*/
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__get_user(env->vregs[i][1], &ext->vxrs_low[i]);
|
||||
}
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__get_user(env->vregs[i + 16][0], &ext->vxrs_high[i][0]);
|
||||
__get_user(env->vregs[i + 16][1], &ext->vxrs_high[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
long do_sigreturn(CPUS390XState *env)
|
||||
@ -270,23 +336,22 @@ long do_sigreturn(CPUS390XState *env)
|
||||
|
||||
trace_user_do_sigreturn(env, frame_addr);
|
||||
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
|
||||
goto badframe;
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
/* Make sure that we're initializing all of target_set. */
|
||||
QEMU_BUILD_BUG_ON(ARRAY_SIZE(target_set.sig) != 1);
|
||||
__get_user(target_set.sig[0], &frame->sc.oldmask[0]);
|
||||
|
||||
target_to_host_sigset_internal(&set, &target_set);
|
||||
set_sigmask(&set); /* ~_BLOCKABLE? */
|
||||
|
||||
if (restore_sigregs(env, &frame->sregs)) {
|
||||
goto badframe;
|
||||
}
|
||||
restore_sigregs(env, &frame->sregs);
|
||||
restore_sigregs_ext(env, &frame->sregs_ext);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
||||
badframe:
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUS390XState *env)
|
||||
@ -297,25 +362,18 @@ long do_rt_sigreturn(CPUS390XState *env)
|
||||
|
||||
trace_user_do_rt_sigreturn(env, frame_addr);
|
||||
if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
|
||||
goto badframe;
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
target_to_host_sigset(&set, &frame->uc.tuc_sigmask);
|
||||
|
||||
set_sigmask(&set); /* ~_BLOCKABLE? */
|
||||
|
||||
if (restore_sigregs(env, &frame->uc.tuc_mcontext)) {
|
||||
goto badframe;
|
||||
}
|
||||
restore_sigregs(env, &frame->uc.tuc_mcontext);
|
||||
restore_sigregs_ext(env, &frame->uc.tuc_mcontext_ext);
|
||||
|
||||
if (do_sigaltstack(frame_addr + offsetof(rt_sigframe, uc.tuc_stack), 0,
|
||||
get_sp_from_cpustate(env)) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
target_restore_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
@ -323,12 +323,7 @@ long do_rt_sigreturn(CPUSH4State *regs)
|
||||
set_sigmask(&blocked);
|
||||
|
||||
restore_sigcontext(regs, &frame->uc.tuc_mcontext);
|
||||
|
||||
if (do_sigaltstack(frame_addr +
|
||||
offsetof(struct target_rt_sigframe, uc.tuc_stack),
|
||||
0, get_sp_from_cpustate(regs)) == -EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
target_restore_altstack(&frame->uc.tuc_stack, regs);
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
@ -24,6 +24,7 @@ int on_sig_stack(unsigned long sp);
|
||||
int sas_ss_flags(unsigned long sp);
|
||||
abi_ulong target_sigsp(abi_ulong sp, struct target_sigaction *ka);
|
||||
void target_save_altstack(target_stack_t *uss, CPUArchState *env);
|
||||
abi_long target_restore_altstack(target_stack_t *uss, CPUArchState *env);
|
||||
|
||||
static inline void target_sigemptyset(target_sigset_t *set)
|
||||
{
|
||||
|
@ -297,6 +297,50 @@ void target_save_altstack(target_stack_t *uss, CPUArchState *env)
|
||||
__put_user(ts->sigaltstack_used.ss_size, &uss->ss_size);
|
||||
}
|
||||
|
||||
abi_long target_restore_altstack(target_stack_t *uss, CPUArchState *env)
|
||||
{
|
||||
TaskState *ts = (TaskState *)thread_cpu->opaque;
|
||||
size_t minstacksize = TARGET_MINSIGSTKSZ;
|
||||
target_stack_t ss;
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
/* ELF V2 for PPC64 has a 4K minimum stack size for signal handlers */
|
||||
struct image_info *image = ts->info;
|
||||
if (get_ppc64_abi(image) > 1) {
|
||||
minstacksize = 4096;
|
||||
}
|
||||
#endif
|
||||
|
||||
__get_user(ss.ss_sp, &uss->ss_sp);
|
||||
__get_user(ss.ss_size, &uss->ss_size);
|
||||
__get_user(ss.ss_flags, &uss->ss_flags);
|
||||
|
||||
if (on_sig_stack(get_sp_from_cpustate(env))) {
|
||||
return -TARGET_EPERM;
|
||||
}
|
||||
|
||||
switch (ss.ss_flags) {
|
||||
default:
|
||||
return -TARGET_EINVAL;
|
||||
|
||||
case TARGET_SS_DISABLE:
|
||||
ss.ss_size = 0;
|
||||
ss.ss_sp = 0;
|
||||
break;
|
||||
|
||||
case TARGET_SS_ONSTACK:
|
||||
case 0:
|
||||
if (ss.ss_size < minstacksize) {
|
||||
return -TARGET_ENOMEM;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
ts->sigaltstack_used.ss_sp = ss.ss_sp;
|
||||
ts->sigaltstack_used.ss_size = ss.ss_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* siginfo conversion */
|
||||
|
||||
static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
|
||||
@ -756,81 +800,49 @@ static void host_signal_handler(int host_signum, siginfo_t *info,
|
||||
|
||||
/* do_sigaltstack() returns target values and errnos. */
|
||||
/* compare linux/kernel/signal.c:do_sigaltstack() */
|
||||
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp)
|
||||
abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr,
|
||||
CPUArchState *env)
|
||||
{
|
||||
int ret;
|
||||
struct target_sigaltstack oss;
|
||||
TaskState *ts = (TaskState *)thread_cpu->opaque;
|
||||
target_stack_t oss, *uoss = NULL;
|
||||
abi_long ret = -TARGET_EFAULT;
|
||||
|
||||
/* XXX: test errors */
|
||||
if(uoss_addr)
|
||||
{
|
||||
__put_user(ts->sigaltstack_used.ss_sp, &oss.ss_sp);
|
||||
__put_user(ts->sigaltstack_used.ss_size, &oss.ss_size);
|
||||
__put_user(sas_ss_flags(sp), &oss.ss_flags);
|
||||
if (uoss_addr) {
|
||||
/* Verify writability now, but do not alter user memory yet. */
|
||||
if (!lock_user_struct(VERIFY_WRITE, uoss, uoss_addr, 0)) {
|
||||
goto out;
|
||||
}
|
||||
target_save_altstack(&oss, env);
|
||||
}
|
||||
|
||||
if(uss_addr)
|
||||
{
|
||||
struct target_sigaltstack *uss;
|
||||
struct target_sigaltstack ss;
|
||||
size_t minstacksize = TARGET_MINSIGSTKSZ;
|
||||
if (uss_addr) {
|
||||
target_stack_t *uss;
|
||||
|
||||
#if defined(TARGET_PPC64)
|
||||
/* ELF V2 for PPC64 has a 4K minimum stack size for signal handlers */
|
||||
struct image_info *image = ((TaskState *)thread_cpu->opaque)->info;
|
||||
if (get_ppc64_abi(image) > 1) {
|
||||
minstacksize = 4096;
|
||||
}
|
||||
#endif
|
||||
|
||||
ret = -TARGET_EFAULT;
|
||||
if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1)) {
|
||||
goto out;
|
||||
}
|
||||
__get_user(ss.ss_sp, &uss->ss_sp);
|
||||
__get_user(ss.ss_size, &uss->ss_size);
|
||||
__get_user(ss.ss_flags, &uss->ss_flags);
|
||||
unlock_user_struct(uss, uss_addr, 0);
|
||||
|
||||
ret = -TARGET_EPERM;
|
||||
if (on_sig_stack(sp))
|
||||
ret = target_restore_altstack(uss, env);
|
||||
if (ret) {
|
||||
goto out;
|
||||
|
||||
ret = -TARGET_EINVAL;
|
||||
if (ss.ss_flags != TARGET_SS_DISABLE
|
||||
&& ss.ss_flags != TARGET_SS_ONSTACK
|
||||
&& ss.ss_flags != 0)
|
||||
goto out;
|
||||
|
||||
if (ss.ss_flags == TARGET_SS_DISABLE) {
|
||||
ss.ss_size = 0;
|
||||
ss.ss_sp = 0;
|
||||
} else {
|
||||
ret = -TARGET_ENOMEM;
|
||||
if (ss.ss_size < minstacksize) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
ts->sigaltstack_used.ss_sp = ss.ss_sp;
|
||||
ts->sigaltstack_used.ss_size = ss.ss_size;
|
||||
}
|
||||
|
||||
if (uoss_addr) {
|
||||
ret = -TARGET_EFAULT;
|
||||
if (copy_to_user(uoss_addr, &oss, sizeof(oss)))
|
||||
goto out;
|
||||
memcpy(uoss, &oss, sizeof(oss));
|
||||
unlock_user_struct(uoss, uoss_addr, 1);
|
||||
uoss = NULL;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
|
||||
out:
|
||||
if (uoss) {
|
||||
unlock_user_struct(uoss, uoss_addr, 0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* do_sigaction() return target values and host errnos */
|
||||
int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
struct target_sigaction *oact)
|
||||
struct target_sigaction *oact, abi_ulong ka_restorer)
|
||||
{
|
||||
struct target_sigaction *k;
|
||||
struct sigaction act1;
|
||||
@ -863,6 +875,9 @@ int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
__get_user(k->sa_flags, &act->sa_flags);
|
||||
#ifdef TARGET_ARCH_HAS_SA_RESTORER
|
||||
__get_user(k->sa_restorer, &act->sa_restorer);
|
||||
#endif
|
||||
#ifdef TARGET_ARCH_HAS_KA_RESTORER
|
||||
k->ka_restorer = ka_restorer;
|
||||
#endif
|
||||
/* To be swapped in target_to_host_sigset. */
|
||||
k->sa_mask = act->sa_mask;
|
||||
|
@ -21,107 +21,96 @@
|
||||
#include "signal-common.h"
|
||||
#include "linux-user/trace.h"
|
||||
|
||||
#define __SUNOS_MAXWIN 31
|
||||
|
||||
/* This is what SunOS does, so shall I. */
|
||||
struct target_sigcontext {
|
||||
abi_ulong sigc_onstack; /* state to restore */
|
||||
|
||||
abi_ulong sigc_mask; /* sigmask to restore */
|
||||
abi_ulong sigc_sp; /* stack pointer */
|
||||
abi_ulong sigc_pc; /* program counter */
|
||||
abi_ulong sigc_npc; /* next program counter */
|
||||
abi_ulong sigc_psr; /* for condition codes etc */
|
||||
abi_ulong sigc_g1; /* User uses these two registers */
|
||||
abi_ulong sigc_o0; /* within the trampoline code. */
|
||||
|
||||
/* Now comes information regarding the users window set
|
||||
* at the time of the signal.
|
||||
*/
|
||||
abi_ulong sigc_oswins; /* outstanding windows */
|
||||
|
||||
/* stack ptrs for each regwin buf */
|
||||
char *sigc_spbuf[__SUNOS_MAXWIN];
|
||||
|
||||
/* Windows to restore after signal */
|
||||
struct {
|
||||
abi_ulong locals[8];
|
||||
abi_ulong ins[8];
|
||||
} sigc_wbuf[__SUNOS_MAXWIN];
|
||||
};
|
||||
/* A Sparc stack frame */
|
||||
struct sparc_stackf {
|
||||
/* A Sparc register window */
|
||||
struct target_reg_window {
|
||||
abi_ulong locals[8];
|
||||
abi_ulong ins[8];
|
||||
/* It's simpler to treat fp and callers_pc as elements of ins[]
|
||||
* since we never need to access them ourselves.
|
||||
*/
|
||||
char *structptr;
|
||||
abi_ulong xargs[6];
|
||||
abi_ulong xxargs[1];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
struct {
|
||||
abi_ulong psr;
|
||||
abi_ulong pc;
|
||||
abi_ulong npc;
|
||||
abi_ulong y;
|
||||
abi_ulong u_regs[16]; /* globals and ins */
|
||||
} si_regs;
|
||||
int si_mask;
|
||||
} __siginfo_t;
|
||||
/* A Sparc stack frame. */
|
||||
struct target_stackf {
|
||||
/*
|
||||
* Since qemu does not reference fp or callers_pc directly,
|
||||
* it's simpler to treat fp and callers_pc as elements of ins[],
|
||||
* and then bundle locals[] and ins[] into reg_window.
|
||||
*/
|
||||
struct target_reg_window win;
|
||||
/*
|
||||
* Similarly, bundle structptr and xxargs into xargs[].
|
||||
* This portion of the struct is part of the function call abi,
|
||||
* and belongs to the callee for spilling argument registers.
|
||||
*/
|
||||
abi_ulong xargs[8];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
abi_ulong si_float_regs[32];
|
||||
unsigned long si_fsr;
|
||||
unsigned long si_fpqdepth;
|
||||
struct target_siginfo_fpu {
|
||||
#ifdef TARGET_SPARC64
|
||||
uint64_t si_double_regs[32];
|
||||
uint64_t si_fsr;
|
||||
uint64_t si_gsr;
|
||||
uint64_t si_fprs;
|
||||
#else
|
||||
/* It is more convenient for qemu to move doubles, not singles. */
|
||||
uint64_t si_double_regs[16];
|
||||
uint32_t si_fsr;
|
||||
uint32_t si_fpqdepth;
|
||||
struct {
|
||||
unsigned long *insn_addr;
|
||||
unsigned long insn;
|
||||
uint32_t insn_addr;
|
||||
uint32_t insn;
|
||||
} si_fpqueue [16];
|
||||
} qemu_siginfo_fpu_t;
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef TARGET_ARCH_HAS_SETUP_FRAME
|
||||
struct target_signal_frame {
|
||||
struct sparc_stackf ss;
|
||||
__siginfo_t info;
|
||||
abi_ulong fpu_save;
|
||||
uint32_t insns[2] QEMU_ALIGNED(8);
|
||||
abi_ulong extramask[TARGET_NSIG_WORDS - 1];
|
||||
abi_ulong extra_size; /* Should be 0 */
|
||||
qemu_siginfo_fpu_t fpu_state;
|
||||
struct target_stackf ss;
|
||||
struct target_pt_regs regs;
|
||||
uint32_t si_mask;
|
||||
abi_ulong fpu_save;
|
||||
uint32_t insns[2] QEMU_ALIGNED(8);
|
||||
abi_ulong extramask[TARGET_NSIG_WORDS - 1];
|
||||
abi_ulong extra_size; /* Should be 0 */
|
||||
abi_ulong rwin_save;
|
||||
};
|
||||
#endif
|
||||
|
||||
struct target_rt_signal_frame {
|
||||
struct sparc_stackf ss;
|
||||
siginfo_t info;
|
||||
abi_ulong regs[20];
|
||||
sigset_t mask;
|
||||
abi_ulong fpu_save;
|
||||
uint32_t insns[2];
|
||||
stack_t stack;
|
||||
unsigned int extra_size; /* Should be 0 */
|
||||
qemu_siginfo_fpu_t fpu_state;
|
||||
struct target_stackf ss;
|
||||
target_siginfo_t info;
|
||||
struct target_pt_regs regs;
|
||||
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
|
||||
abi_ulong fpu_save;
|
||||
target_stack_t stack;
|
||||
target_sigset_t mask;
|
||||
#else
|
||||
target_sigset_t mask;
|
||||
abi_ulong fpu_save;
|
||||
uint32_t insns[2];
|
||||
target_stack_t stack;
|
||||
abi_ulong extra_size; /* Should be 0 */
|
||||
#endif
|
||||
abi_ulong rwin_save;
|
||||
};
|
||||
|
||||
static inline abi_ulong get_sigframe(struct target_sigaction *sa,
|
||||
CPUSPARCState *env,
|
||||
unsigned long framesize)
|
||||
static abi_ulong get_sigframe(struct target_sigaction *sa,
|
||||
CPUSPARCState *env,
|
||||
size_t framesize)
|
||||
{
|
||||
abi_ulong sp = get_sp_from_cpustate(env);
|
||||
|
||||
/*
|
||||
* If we are on the alternate signal stack and would overflow it, don't.
|
||||
* Return an always-bogus address instead so we will die with SIGSEGV.
|
||||
*/
|
||||
*/
|
||||
if (on_sig_stack(sp) && !likely(on_sig_stack(sp - framesize))) {
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* This is the X/Open sanctioned signal stack switching. */
|
||||
sp = target_sigsp(sp, sa) - framesize;
|
||||
|
||||
/* Always align the stack frame. This handles two cases. First,
|
||||
/*
|
||||
* Always align the stack frame. This handles two cases. First,
|
||||
* sigaltstack need not be mindful of platform specific stack
|
||||
* alignment. Second, if we took this signal because the stack
|
||||
* is not aligned properly, we'd like to take the signal cleanly
|
||||
@ -132,175 +121,310 @@ static inline abi_ulong get_sigframe(struct target_sigaction *sa,
|
||||
return sp;
|
||||
}
|
||||
|
||||
static int
|
||||
setup___siginfo(__siginfo_t *si, CPUSPARCState *env, abi_ulong mask)
|
||||
static void save_pt_regs(struct target_pt_regs *regs, CPUSPARCState *env)
|
||||
{
|
||||
int err = 0, i;
|
||||
int i;
|
||||
|
||||
__put_user(env->psr, &si->si_regs.psr);
|
||||
__put_user(env->pc, &si->si_regs.pc);
|
||||
__put_user(env->npc, &si->si_regs.npc);
|
||||
__put_user(env->y, &si->si_regs.y);
|
||||
for (i=0; i < 8; i++) {
|
||||
__put_user(env->gregs[i], &si->si_regs.u_regs[i]);
|
||||
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
|
||||
__put_user(sparc64_tstate(env), ®s->tstate);
|
||||
/* TODO: magic should contain PT_REG_MAGIC + %tt. */
|
||||
__put_user(0, ®s->magic);
|
||||
#else
|
||||
__put_user(cpu_get_psr(env), ®s->psr);
|
||||
#endif
|
||||
|
||||
__put_user(env->pc, ®s->pc);
|
||||
__put_user(env->npc, ®s->npc);
|
||||
__put_user(env->y, ®s->y);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
__put_user(env->gregs[i], ®s->u_regs[i]);
|
||||
}
|
||||
for (i=0; i < 8; i++) {
|
||||
__put_user(env->regwptr[WREG_O0 + i], &si->si_regs.u_regs[i + 8]);
|
||||
for (i = 0; i < 8; i++) {
|
||||
__put_user(env->regwptr[WREG_O0 + i], ®s->u_regs[i + 8]);
|
||||
}
|
||||
__put_user(mask, &si->si_mask);
|
||||
return err;
|
||||
}
|
||||
|
||||
#define NF_ALIGNEDSZ (((sizeof(struct target_signal_frame) + 7) & (~7)))
|
||||
static void restore_pt_regs(struct target_pt_regs *regs, CPUSPARCState *env)
|
||||
{
|
||||
int i;
|
||||
|
||||
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
|
||||
/* User can only change condition codes and %asi in %tstate. */
|
||||
uint64_t tstate;
|
||||
__get_user(tstate, ®s->tstate);
|
||||
cpu_put_ccr(env, tstate >> 32);
|
||||
env->asi = extract64(tstate, 24, 8);
|
||||
#else
|
||||
/*
|
||||
* User can only change condition codes and FPU enabling in %psr.
|
||||
* But don't bother with FPU enabling, since a real kernel would
|
||||
* just re-enable the FPU upon the next fpu trap.
|
||||
*/
|
||||
uint32_t psr;
|
||||
__get_user(psr, ®s->psr);
|
||||
env->psr = (psr & PSR_ICC) | (env->psr & ~PSR_ICC);
|
||||
#endif
|
||||
|
||||
/* Note that pc and npc are handled in the caller. */
|
||||
|
||||
__get_user(env->y, ®s->y);
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
__get_user(env->gregs[i], ®s->u_regs[i]);
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
__get_user(env->regwptr[WREG_O0 + i], ®s->u_regs[i + 8]);
|
||||
}
|
||||
}
|
||||
|
||||
static void save_reg_win(struct target_reg_window *win, CPUSPARCState *env)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
__put_user(env->regwptr[i + WREG_L0], &win->locals[i]);
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
__put_user(env->regwptr[i + WREG_I0], &win->ins[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void save_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
for (i = 0; i < 32; ++i) {
|
||||
__put_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
|
||||
}
|
||||
__put_user(env->fsr, &fpu->si_fsr);
|
||||
__put_user(env->gsr, &fpu->si_gsr);
|
||||
__put_user(env->fprs, &fpu->si_fprs);
|
||||
#else
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__put_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
|
||||
}
|
||||
__put_user(env->fsr, &fpu->si_fsr);
|
||||
__put_user(0, &fpu->si_fpqdepth);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void restore_fpu(struct target_siginfo_fpu *fpu, CPUSPARCState *env)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef TARGET_SPARC64
|
||||
uint64_t fprs;
|
||||
__get_user(fprs, &fpu->si_fprs);
|
||||
|
||||
/* In case the user mucks about with FPRS, restore as directed. */
|
||||
if (fprs & FPRS_DL) {
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__get_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
|
||||
}
|
||||
}
|
||||
if (fprs & FPRS_DU) {
|
||||
for (i = 16; i < 32; ++i) {
|
||||
__get_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
|
||||
}
|
||||
}
|
||||
__get_user(env->fsr, &fpu->si_fsr);
|
||||
__get_user(env->gsr, &fpu->si_gsr);
|
||||
env->fprs |= fprs;
|
||||
#else
|
||||
for (i = 0; i < 16; ++i) {
|
||||
__get_user(env->fpr[i].ll, &fpu->si_double_regs[i]);
|
||||
}
|
||||
__get_user(env->fsr, &fpu->si_fsr);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef TARGET_ARCH_HAS_SETUP_FRAME
|
||||
void setup_frame(int sig, struct target_sigaction *ka,
|
||||
target_sigset_t *set, CPUSPARCState *env)
|
||||
{
|
||||
abi_ulong sf_addr;
|
||||
struct target_signal_frame *sf;
|
||||
int sigframe_size, err, i;
|
||||
size_t sf_size = sizeof(*sf) + sizeof(struct target_siginfo_fpu);
|
||||
int i;
|
||||
|
||||
/* 1. Make sure everything is clean */
|
||||
//synchronize_user_stack();
|
||||
|
||||
sigframe_size = NF_ALIGNEDSZ;
|
||||
sf_addr = get_sigframe(ka, env, sigframe_size);
|
||||
sf_addr = get_sigframe(ka, env, sf_size);
|
||||
trace_user_setup_frame(env, sf_addr);
|
||||
|
||||
sf = lock_user(VERIFY_WRITE, sf_addr,
|
||||
sizeof(struct target_signal_frame), 0);
|
||||
sf = lock_user(VERIFY_WRITE, sf_addr, sf_size, 0);
|
||||
if (!sf) {
|
||||
goto sigsegv;
|
||||
force_sigsegv(sig);
|
||||
return;
|
||||
}
|
||||
#if 0
|
||||
if (invalid_frame_pointer(sf, sigframe_size))
|
||||
goto sigill_and_return;
|
||||
#endif
|
||||
|
||||
/* 2. Save the current process state */
|
||||
err = setup___siginfo(&sf->info, env, set->sig[0]);
|
||||
save_pt_regs(&sf->regs, env);
|
||||
__put_user(0, &sf->extra_size);
|
||||
|
||||
//save_fpu_state(regs, &sf->fpu_state);
|
||||
//__put_user(&sf->fpu_state, &sf->fpu_save);
|
||||
save_fpu((struct target_siginfo_fpu *)(sf + 1), env);
|
||||
__put_user(sf_addr + sizeof(*sf), &sf->fpu_save);
|
||||
|
||||
__put_user(set->sig[0], &sf->info.si_mask);
|
||||
__put_user(0, &sf->rwin_save); /* TODO: save_rwin_state */
|
||||
|
||||
__put_user(set->sig[0], &sf->si_mask);
|
||||
for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {
|
||||
__put_user(set->sig[i + 1], &sf->extramask[i]);
|
||||
}
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
__put_user(env->regwptr[i + WREG_L0], &sf->ss.locals[i]);
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
__put_user(env->regwptr[i + WREG_I0], &sf->ss.ins[i]);
|
||||
}
|
||||
if (err)
|
||||
goto sigsegv;
|
||||
save_reg_win(&sf->ss.win, env);
|
||||
|
||||
/* 3. signal handler back-trampoline and parameters */
|
||||
env->regwptr[WREG_SP] = sf_addr;
|
||||
env->regwptr[WREG_O0] = sig;
|
||||
env->regwptr[WREG_O1] = sf_addr +
|
||||
offsetof(struct target_signal_frame, info);
|
||||
offsetof(struct target_signal_frame, regs);
|
||||
env->regwptr[WREG_O2] = sf_addr +
|
||||
offsetof(struct target_signal_frame, info);
|
||||
offsetof(struct target_signal_frame, regs);
|
||||
|
||||
/* 4. signal handler */
|
||||
env->pc = ka->_sa_handler;
|
||||
env->npc = (env->pc + 4);
|
||||
env->npc = env->pc + 4;
|
||||
|
||||
/* 5. return to kernel instructions */
|
||||
if (ka->ka_restorer) {
|
||||
env->regwptr[WREG_O7] = ka->ka_restorer;
|
||||
} else {
|
||||
uint32_t val32;
|
||||
|
||||
env->regwptr[WREG_O7] = sf_addr +
|
||||
offsetof(struct target_signal_frame, insns) - 2 * 4;
|
||||
|
||||
/* mov __NR_sigreturn, %g1 */
|
||||
val32 = 0x821020d8;
|
||||
__put_user(val32, &sf->insns[0]);
|
||||
|
||||
__put_user(0x821020d8u, &sf->insns[0]);
|
||||
/* t 0x10 */
|
||||
val32 = 0x91d02010;
|
||||
__put_user(val32, &sf->insns[1]);
|
||||
__put_user(0x91d02010u, &sf->insns[1]);
|
||||
}
|
||||
unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
|
||||
return;
|
||||
#if 0
|
||||
sigill_and_return:
|
||||
force_sig(TARGET_SIGILL);
|
||||
#endif
|
||||
sigsegv:
|
||||
unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
|
||||
force_sigsegv(sig);
|
||||
unlock_user(sf, sf_addr, sf_size);
|
||||
}
|
||||
#endif /* TARGET_ARCH_HAS_SETUP_FRAME */
|
||||
|
||||
void setup_rt_frame(int sig, struct target_sigaction *ka,
|
||||
target_siginfo_t *info,
|
||||
target_sigset_t *set, CPUSPARCState *env)
|
||||
{
|
||||
qemu_log_mask(LOG_UNIMP, "setup_rt_frame: not implemented\n");
|
||||
abi_ulong sf_addr;
|
||||
struct target_rt_signal_frame *sf;
|
||||
size_t sf_size = sizeof(*sf) + sizeof(struct target_siginfo_fpu);
|
||||
|
||||
sf_addr = get_sigframe(ka, env, sf_size);
|
||||
trace_user_setup_rt_frame(env, sf_addr);
|
||||
|
||||
sf = lock_user(VERIFY_WRITE, sf_addr, sf_size, 0);
|
||||
if (!sf) {
|
||||
force_sigsegv(sig);
|
||||
return;
|
||||
}
|
||||
|
||||
/* 2. Save the current process state */
|
||||
save_reg_win(&sf->ss.win, env);
|
||||
save_pt_regs(&sf->regs, env);
|
||||
|
||||
save_fpu((struct target_siginfo_fpu *)(sf + 1), env);
|
||||
__put_user(sf_addr + sizeof(*sf), &sf->fpu_save);
|
||||
|
||||
__put_user(0, &sf->rwin_save); /* TODO: save_rwin_state */
|
||||
|
||||
tswap_siginfo(&sf->info, info);
|
||||
tswap_sigset(&sf->mask, set);
|
||||
target_save_altstack(&sf->stack, env);
|
||||
|
||||
#ifdef TARGET_ABI32
|
||||
__put_user(0, &sf->extra_size);
|
||||
#endif
|
||||
|
||||
/* 3. signal handler back-trampoline and parameters */
|
||||
env->regwptr[WREG_SP] = sf_addr - TARGET_STACK_BIAS;
|
||||
env->regwptr[WREG_O0] = sig;
|
||||
env->regwptr[WREG_O1] =
|
||||
sf_addr + offsetof(struct target_rt_signal_frame, info);
|
||||
#ifdef TARGET_ABI32
|
||||
env->regwptr[WREG_O2] =
|
||||
sf_addr + offsetof(struct target_rt_signal_frame, regs);
|
||||
#else
|
||||
env->regwptr[WREG_O2] = env->regwptr[WREG_O1];
|
||||
#endif
|
||||
|
||||
/* 4. signal handler */
|
||||
env->pc = ka->_sa_handler;
|
||||
env->npc = env->pc + 4;
|
||||
|
||||
/* 5. return to kernel instructions */
|
||||
#ifdef TARGET_ABI32
|
||||
if (ka->ka_restorer) {
|
||||
env->regwptr[WREG_O7] = ka->ka_restorer;
|
||||
} else {
|
||||
env->regwptr[WREG_O7] =
|
||||
sf_addr + offsetof(struct target_rt_signal_frame, insns) - 2 * 4;
|
||||
|
||||
/* mov __NR_rt_sigreturn, %g1 */
|
||||
__put_user(0x82102065u, &sf->insns[0]);
|
||||
/* t 0x10 */
|
||||
__put_user(0x91d02010u, &sf->insns[1]);
|
||||
}
|
||||
#else
|
||||
env->regwptr[WREG_O7] = ka->ka_restorer;
|
||||
#endif
|
||||
|
||||
unlock_user(sf, sf_addr, sf_size);
|
||||
}
|
||||
|
||||
long do_sigreturn(CPUSPARCState *env)
|
||||
{
|
||||
#ifdef TARGET_ARCH_HAS_SETUP_FRAME
|
||||
abi_ulong sf_addr;
|
||||
struct target_signal_frame *sf;
|
||||
abi_ulong up_psr, pc, npc;
|
||||
struct target_signal_frame *sf = NULL;
|
||||
abi_ulong pc, npc, ptr;
|
||||
target_sigset_t set;
|
||||
sigset_t host_set;
|
||||
int i;
|
||||
|
||||
sf_addr = env->regwptr[WREG_SP];
|
||||
trace_user_do_sigreturn(env, sf_addr);
|
||||
if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
|
||||
|
||||
/* 1. Make sure we are not getting garbage from the user */
|
||||
if ((sf_addr & 15) || !lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
|
||||
goto segv_and_exit;
|
||||
}
|
||||
|
||||
/* 1. Make sure we are not getting garbage from the user */
|
||||
|
||||
if (sf_addr & 3)
|
||||
/* Make sure stack pointer is aligned. */
|
||||
__get_user(ptr, &sf->regs.u_regs[14]);
|
||||
if (ptr & 7) {
|
||||
goto segv_and_exit;
|
||||
}
|
||||
|
||||
__get_user(pc, &sf->info.si_regs.pc);
|
||||
__get_user(npc, &sf->info.si_regs.npc);
|
||||
|
||||
/* Make sure instruction pointers are aligned. */
|
||||
__get_user(pc, &sf->regs.pc);
|
||||
__get_user(npc, &sf->regs.npc);
|
||||
if ((pc | npc) & 3) {
|
||||
goto segv_and_exit;
|
||||
}
|
||||
|
||||
/* 2. Restore the state */
|
||||
__get_user(up_psr, &sf->info.si_regs.psr);
|
||||
|
||||
/* User can only change condition codes and FPU enabling in %psr. */
|
||||
env->psr = (up_psr & (PSR_ICC /* | PSR_EF */))
|
||||
| (env->psr & ~(PSR_ICC /* | PSR_EF */));
|
||||
|
||||
restore_pt_regs(&sf->regs, env);
|
||||
env->pc = pc;
|
||||
env->npc = npc;
|
||||
__get_user(env->y, &sf->info.si_regs.y);
|
||||
for (i=0; i < 8; i++) {
|
||||
__get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]);
|
||||
}
|
||||
for (i=0; i < 8; i++) {
|
||||
__get_user(env->regwptr[i + WREG_O0], &sf->info.si_regs.u_regs[i + 8]);
|
||||
|
||||
__get_user(ptr, &sf->fpu_save);
|
||||
if (ptr) {
|
||||
struct target_siginfo_fpu *fpu;
|
||||
if ((ptr & 3) || !lock_user_struct(VERIFY_READ, fpu, ptr, 1)) {
|
||||
goto segv_and_exit;
|
||||
}
|
||||
restore_fpu(fpu, env);
|
||||
unlock_user_struct(fpu, ptr, 0);
|
||||
}
|
||||
|
||||
/* FIXME: implement FPU save/restore:
|
||||
* __get_user(fpu_save, &sf->fpu_save);
|
||||
* if (fpu_save) {
|
||||
* if (restore_fpu_state(env, fpu_save)) {
|
||||
* goto segv_and_exit;
|
||||
* }
|
||||
* }
|
||||
*/
|
||||
__get_user(ptr, &sf->rwin_save);
|
||||
if (ptr) {
|
||||
goto segv_and_exit; /* TODO: restore_rwin */
|
||||
}
|
||||
|
||||
/* This is pretty much atomic, no amount locking would prevent
|
||||
* the races which exist anyways.
|
||||
*/
|
||||
__get_user(set.sig[0], &sf->info.si_mask);
|
||||
for(i = 1; i < TARGET_NSIG_WORDS; i++) {
|
||||
__get_user(set.sig[0], &sf->si_mask);
|
||||
for (i = 1; i < TARGET_NSIG_WORDS; i++) {
|
||||
__get_user(set.sig[i], &sf->extramask[i - 1]);
|
||||
}
|
||||
|
||||
@ -310,17 +434,74 @@ long do_sigreturn(CPUSPARCState *env)
|
||||
unlock_user_struct(sf, sf_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
||||
segv_and_exit:
|
||||
segv_and_exit:
|
||||
unlock_user_struct(sf, sf_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
#else
|
||||
return -TARGET_ENOSYS;
|
||||
#endif
|
||||
}
|
||||
|
||||
long do_rt_sigreturn(CPUSPARCState *env)
|
||||
{
|
||||
trace_user_do_rt_sigreturn(env, 0);
|
||||
qemu_log_mask(LOG_UNIMP, "do_rt_sigreturn: not implemented\n");
|
||||
return -TARGET_ENOSYS;
|
||||
abi_ulong sf_addr, tpc, tnpc, ptr;
|
||||
struct target_rt_signal_frame *sf = NULL;
|
||||
sigset_t set;
|
||||
|
||||
sf_addr = get_sp_from_cpustate(env);
|
||||
trace_user_do_rt_sigreturn(env, sf_addr);
|
||||
|
||||
/* 1. Make sure we are not getting garbage from the user */
|
||||
if ((sf_addr & 15) || !lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) {
|
||||
goto segv_and_exit;
|
||||
}
|
||||
|
||||
/* Validate SP alignment. */
|
||||
__get_user(ptr, &sf->regs.u_regs[8 + WREG_SP]);
|
||||
if ((ptr + TARGET_STACK_BIAS) & 7) {
|
||||
goto segv_and_exit;
|
||||
}
|
||||
|
||||
/* Validate PC and NPC alignment. */
|
||||
__get_user(tpc, &sf->regs.pc);
|
||||
__get_user(tnpc, &sf->regs.npc);
|
||||
if ((tpc | tnpc) & 3) {
|
||||
goto segv_and_exit;
|
||||
}
|
||||
|
||||
/* 2. Restore the state */
|
||||
restore_pt_regs(&sf->regs, env);
|
||||
|
||||
__get_user(ptr, &sf->fpu_save);
|
||||
if (ptr) {
|
||||
struct target_siginfo_fpu *fpu;
|
||||
if ((ptr & 7) || !lock_user_struct(VERIFY_READ, fpu, ptr, 1)) {
|
||||
goto segv_and_exit;
|
||||
}
|
||||
restore_fpu(fpu, env);
|
||||
unlock_user_struct(fpu, ptr, 0);
|
||||
}
|
||||
|
||||
__get_user(ptr, &sf->rwin_save);
|
||||
if (ptr) {
|
||||
goto segv_and_exit; /* TODO: restore_rwin_state */
|
||||
}
|
||||
|
||||
target_restore_altstack(&sf->stack, env);
|
||||
target_to_host_sigset(&set, &sf->mask);
|
||||
set_sigmask(&set);
|
||||
|
||||
env->pc = tpc;
|
||||
env->npc = tnpc;
|
||||
|
||||
unlock_user_struct(sf, sf_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
||||
segv_and_exit:
|
||||
unlock_user_struct(sf, sf_addr, 0);
|
||||
force_sig(TARGET_SIGSEGV);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
}
|
||||
|
||||
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
|
||||
@ -388,14 +569,6 @@ struct target_ucontext {
|
||||
target_mcontext_t tuc_mcontext;
|
||||
};
|
||||
|
||||
/* A V9 register window */
|
||||
struct target_reg_window {
|
||||
abi_ulong locals[8];
|
||||
abi_ulong ins[8];
|
||||
};
|
||||
|
||||
#define TARGET_STACK_BIAS 2047
|
||||
|
||||
/* {set, get}context() needed for 64-bit SparcLinux userland. */
|
||||
void sparc64_set_context(CPUSPARCState *env)
|
||||
{
|
||||
|
@ -20,6 +20,12 @@
|
||||
#ifndef SPARC_TARGET_CPU_H
|
||||
#define SPARC_TARGET_CPU_H
|
||||
|
||||
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
|
||||
# define TARGET_STACK_BIAS 2047
|
||||
#else
|
||||
# define TARGET_STACK_BIAS 0
|
||||
#endif
|
||||
|
||||
static inline void cpu_clone_regs_child(CPUSPARCState *env, target_ulong newsp,
|
||||
unsigned flags)
|
||||
{
|
||||
@ -40,6 +46,7 @@ static inline void cpu_clone_regs_child(CPUSPARCState *env, target_ulong newsp,
|
||||
#endif
|
||||
/* ??? The kernel appears to copy one stack frame to the new stack. */
|
||||
/* ??? The kernel force aligns the new stack. */
|
||||
/* Userspace provides a biased stack pointer value. */
|
||||
env->regwptr[WREG_SP] = newsp;
|
||||
}
|
||||
|
||||
@ -77,7 +84,7 @@ static inline void cpu_set_tls(CPUSPARCState *env, target_ulong newtls)
|
||||
|
||||
static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
|
||||
{
|
||||
return state->regwptr[WREG_SP];
|
||||
return state->regwptr[WREG_SP] + TARGET_STACK_BIAS;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -67,7 +67,9 @@ typedef struct target_sigaltstack {
|
||||
#define TARGET_MINSIGSTKSZ 4096
|
||||
#define TARGET_SIGSTKSZ 16384
|
||||
|
||||
#ifdef TARGET_ABI32
|
||||
#define TARGET_ARCH_HAS_SETUP_FRAME
|
||||
#endif
|
||||
|
||||
/* bit-flags */
|
||||
#define TARGET_SS_AUTODISARM (1U << 31) /* disable sas during sighandling */
|
||||
|
@ -26,13 +26,10 @@ struct target_ipc_perm {
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ushort __pad1;
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad2;
|
||||
#else
|
||||
abi_ushort mode;
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __pad0;
|
||||
#endif
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
uint64_t __unused1;
|
||||
uint64_t __unused2;
|
||||
@ -40,22 +37,17 @@ struct target_ipc_perm {
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_uint __pad1;
|
||||
#endif
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_uint __pad2;
|
||||
#endif
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_uint __pad3;
|
||||
#endif
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_cpid; /* pid of creator */
|
||||
abi_ulong shm_lpid; /* pid of last shmop */
|
||||
abi_long shm_nattch; /* number of current attaches */
|
||||
/*
|
||||
* Note that sparc32 splits these into hi/lo parts.
|
||||
* For simplicity in qemu, always use a 64-bit type.
|
||||
*/
|
||||
int64_t shm_atime; /* last attach time */
|
||||
int64_t shm_dtime; /* last detach time */
|
||||
int64_t shm_ctime; /* last change time */
|
||||
abi_ulong shm_segsz; /* size of segment in bytes */
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
@ -3,18 +3,34 @@
|
||||
|
||||
#include "target_errno.h"
|
||||
|
||||
#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
|
||||
struct target_pt_regs {
|
||||
abi_ulong psr;
|
||||
abi_ulong pc;
|
||||
abi_ulong npc;
|
||||
abi_ulong y;
|
||||
abi_ulong u_regs[16];
|
||||
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
|
||||
|
||||
#define UNAME_MACHINE "sparc"
|
||||
#ifdef TARGET_SPARC64
|
||||
# define UNAME_MACHINE "sparc64"
|
||||
#else
|
||||
# define UNAME_MACHINE "sparc"
|
||||
#endif
|
||||
#define UNAME_MINIMUM_RELEASE "2.6.32"
|
||||
|
||||
/* SPARC kernels don't define this in their Kconfig, but they have the
|
||||
/*
|
||||
* SPARC kernels don't define this in their Kconfig, but they have the
|
||||
* same ABI as if they did, implemented by sparc-specific code which fishes
|
||||
* directly in the u_regs() struct for half the parameters in sparc_do_fork()
|
||||
* and copy_thread().
|
||||
@ -25,20 +41,24 @@ struct target_pt_regs {
|
||||
#define TARGET_MCL_FUTURE 0x4000
|
||||
#define TARGET_MCL_ONFAULT 0x8000
|
||||
|
||||
/* For SPARC SHMLBA is determined at runtime in the kernel, and
|
||||
* libc has to runtime-detect it using the hwcaps (see glibc
|
||||
* sysdeps/unix/sysv/linux/sparc/getshmlba; we follow the same
|
||||
* logic here, though we know we're not the sparc v9 64-bit case).
|
||||
/*
|
||||
* For SPARC SHMLBA is determined at runtime in the kernel, and
|
||||
* libc has to runtime-detect it using the hwcaps.
|
||||
* See glibc sysdeps/unix/sysv/linux/sparc/getshmlba.
|
||||
*/
|
||||
#define TARGET_FORCE_SHMLBA
|
||||
|
||||
static inline abi_ulong target_shmlba(CPUSPARCState *env)
|
||||
{
|
||||
#ifdef TARGET_SPARC64
|
||||
return MAX(TARGET_PAGE_SIZE, 16 * 1024);
|
||||
#else
|
||||
if (!(env->def.features & CPU_FEATURE_FLUSH)) {
|
||||
return 64 * 1024;
|
||||
} else {
|
||||
return 256 * 1024;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* SPARC_TARGET_SYSCALL_H */
|
||||
|
@ -1,20 +0,0 @@
|
||||
/*
|
||||
* qemu user cpu loop
|
||||
*
|
||||
* Copyright (c) 2003-2008 Fabrice Bellard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "../sparc/cpu_loop.c"
|
@ -1,5 +0,0 @@
|
||||
syscall_nr_generators += {
|
||||
'sparc64': generator(sh,
|
||||
arguments: [ meson.current_source_dir() / 'syscallhdr.sh', '@INPUT@', '@OUTPUT@', '@EXTRA_ARGS@' ],
|
||||
output: '@BASENAME@_nr.h')
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
/*
|
||||
* Emulation of Linux signals
|
||||
*
|
||||
* Copyright (c) 2003 Fabrice Bellard
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "../sparc/signal.c"
|
@ -1 +0,0 @@
|
||||
#include "../sparc/sockbits.h"
|
@ -1,487 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note
|
||||
#
|
||||
# system call numbers and entry vectors for sparc
|
||||
#
|
||||
# The format is:
|
||||
# <number> <abi> <name> <entry point> <compat entry point>
|
||||
#
|
||||
# The <abi> can be common, 64, or 32 for this file.
|
||||
#
|
||||
0 common restart_syscall sys_restart_syscall
|
||||
1 32 exit sys_exit sparc_exit
|
||||
1 64 exit sparc_exit
|
||||
2 common fork sys_fork
|
||||
3 common read sys_read
|
||||
4 common write sys_write
|
||||
5 common open sys_open compat_sys_open
|
||||
6 common close sys_close
|
||||
7 common wait4 sys_wait4 compat_sys_wait4
|
||||
8 common creat sys_creat
|
||||
9 common link sys_link
|
||||
10 common unlink sys_unlink
|
||||
11 32 execv sunos_execv
|
||||
11 64 execv sys_nis_syscall
|
||||
12 common chdir sys_chdir
|
||||
13 32 chown sys_chown16
|
||||
13 64 chown sys_chown
|
||||
14 common mknod sys_mknod
|
||||
15 common chmod sys_chmod
|
||||
16 32 lchown sys_lchown16
|
||||
16 64 lchown sys_lchown
|
||||
17 common brk sys_brk
|
||||
18 common perfctr sys_nis_syscall
|
||||
19 common lseek sys_lseek compat_sys_lseek
|
||||
20 common getpid sys_getpid
|
||||
21 common capget sys_capget
|
||||
22 common capset sys_capset
|
||||
23 32 setuid sys_setuid16
|
||||
23 64 setuid sys_setuid
|
||||
24 32 getuid sys_getuid16
|
||||
24 64 getuid sys_getuid
|
||||
25 common vmsplice sys_vmsplice compat_sys_vmsplice
|
||||
26 common ptrace sys_ptrace compat_sys_ptrace
|
||||
27 common alarm sys_alarm
|
||||
28 common sigaltstack sys_sigaltstack compat_sys_sigaltstack
|
||||
29 32 pause sys_pause
|
||||
29 64 pause sys_nis_syscall
|
||||
30 32 utime sys_utime32
|
||||
30 64 utime sys_utime
|
||||
31 32 lchown32 sys_lchown
|
||||
32 32 fchown32 sys_fchown
|
||||
33 common access sys_access
|
||||
34 common nice sys_nice
|
||||
35 32 chown32 sys_chown
|
||||
36 common sync sys_sync
|
||||
37 common kill sys_kill
|
||||
38 common stat sys_newstat compat_sys_newstat
|
||||
39 32 sendfile sys_sendfile compat_sys_sendfile
|
||||
39 64 sendfile sys_sendfile64
|
||||
40 common lstat sys_newlstat compat_sys_newlstat
|
||||
41 common dup sys_dup
|
||||
42 common pipe sys_sparc_pipe
|
||||
43 common times sys_times compat_sys_times
|
||||
44 32 getuid32 sys_getuid
|
||||
45 common umount2 sys_umount
|
||||
46 32 setgid sys_setgid16
|
||||
46 64 setgid sys_setgid
|
||||
47 32 getgid sys_getgid16
|
||||
47 64 getgid sys_getgid
|
||||
48 common signal sys_signal
|
||||
49 32 geteuid sys_geteuid16
|
||||
49 64 geteuid sys_geteuid
|
||||
50 32 getegid sys_getegid16
|
||||
50 64 getegid sys_getegid
|
||||
51 common acct sys_acct
|
||||
52 64 memory_ordering sys_memory_ordering
|
||||
53 32 getgid32 sys_getgid
|
||||
54 common ioctl sys_ioctl compat_sys_ioctl
|
||||
55 common reboot sys_reboot
|
||||
56 32 mmap2 sys_mmap2 sys32_mmap2
|
||||
57 common symlink sys_symlink
|
||||
58 common readlink sys_readlink
|
||||
59 32 execve sys_execve sys32_execve
|
||||
59 64 execve sys64_execve
|
||||
60 common umask sys_umask
|
||||
61 common chroot sys_chroot
|
||||
62 common fstat sys_newfstat compat_sys_newfstat
|
||||
63 common fstat64 sys_fstat64 compat_sys_fstat64
|
||||
64 common getpagesize sys_getpagesize
|
||||
65 common msync sys_msync
|
||||
66 common vfork sys_vfork
|
||||
67 common pread64 sys_pread64 compat_sys_pread64
|
||||
68 common pwrite64 sys_pwrite64 compat_sys_pwrite64
|
||||
69 32 geteuid32 sys_geteuid
|
||||
70 32 getegid32 sys_getegid
|
||||
71 common mmap sys_mmap
|
||||
72 32 setreuid32 sys_setreuid
|
||||
73 32 munmap sys_munmap
|
||||
73 64 munmap sys_64_munmap
|
||||
74 common mprotect sys_mprotect
|
||||
75 common madvise sys_madvise
|
||||
76 common vhangup sys_vhangup
|
||||
77 32 truncate64 sys_truncate64 compat_sys_truncate64
|
||||
78 common mincore sys_mincore
|
||||
79 32 getgroups sys_getgroups16
|
||||
79 64 getgroups sys_getgroups
|
||||
80 32 setgroups sys_setgroups16
|
||||
80 64 setgroups sys_setgroups
|
||||
81 common getpgrp sys_getpgrp
|
||||
82 32 setgroups32 sys_setgroups
|
||||
83 common setitimer sys_setitimer compat_sys_setitimer
|
||||
84 32 ftruncate64 sys_ftruncate64 compat_sys_ftruncate64
|
||||
85 common swapon sys_swapon
|
||||
86 common getitimer sys_getitimer compat_sys_getitimer
|
||||
87 32 setuid32 sys_setuid
|
||||
88 common sethostname sys_sethostname
|
||||
89 32 setgid32 sys_setgid
|
||||
90 common dup2 sys_dup2
|
||||
91 32 setfsuid32 sys_setfsuid
|
||||
92 common fcntl sys_fcntl compat_sys_fcntl
|
||||
93 common select sys_select
|
||||
94 32 setfsgid32 sys_setfsgid
|
||||
95 common fsync sys_fsync
|
||||
96 common setpriority sys_setpriority
|
||||
97 common socket sys_socket
|
||||
98 common connect sys_connect
|
||||
99 common accept sys_accept
|
||||
100 common getpriority sys_getpriority
|
||||
101 common rt_sigreturn sys_rt_sigreturn sys32_rt_sigreturn
|
||||
102 common rt_sigaction sys_rt_sigaction compat_sys_rt_sigaction
|
||||
103 common rt_sigprocmask sys_rt_sigprocmask compat_sys_rt_sigprocmask
|
||||
104 common rt_sigpending sys_rt_sigpending compat_sys_rt_sigpending
|
||||
105 32 rt_sigtimedwait sys_rt_sigtimedwait_time32 compat_sys_rt_sigtimedwait_time32
|
||||
105 64 rt_sigtimedwait sys_rt_sigtimedwait
|
||||
106 common rt_sigqueueinfo sys_rt_sigqueueinfo compat_sys_rt_sigqueueinfo
|
||||
107 common rt_sigsuspend sys_rt_sigsuspend compat_sys_rt_sigsuspend
|
||||
108 32 setresuid32 sys_setresuid
|
||||
108 64 setresuid sys_setresuid
|
||||
109 32 getresuid32 sys_getresuid
|
||||
109 64 getresuid sys_getresuid
|
||||
110 32 setresgid32 sys_setresgid
|
||||
110 64 setresgid sys_setresgid
|
||||
111 32 getresgid32 sys_getresgid
|
||||
111 64 getresgid sys_getresgid
|
||||
112 32 setregid32 sys_setregid
|
||||
113 common recvmsg sys_recvmsg compat_sys_recvmsg
|
||||
114 common sendmsg sys_sendmsg compat_sys_sendmsg
|
||||
115 32 getgroups32 sys_getgroups
|
||||
116 common gettimeofday sys_gettimeofday compat_sys_gettimeofday
|
||||
117 common getrusage sys_getrusage compat_sys_getrusage
|
||||
118 common getsockopt sys_getsockopt sys_getsockopt
|
||||
119 common getcwd sys_getcwd
|
||||
120 common readv sys_readv compat_sys_readv
|
||||
121 common writev sys_writev compat_sys_writev
|
||||
122 common settimeofday sys_settimeofday compat_sys_settimeofday
|
||||
123 32 fchown sys_fchown16
|
||||
123 64 fchown sys_fchown
|
||||
124 common fchmod sys_fchmod
|
||||
125 common recvfrom sys_recvfrom
|
||||
126 32 setreuid sys_setreuid16
|
||||
126 64 setreuid sys_setreuid
|
||||
127 32 setregid sys_setregid16
|
||||
127 64 setregid sys_setregid
|
||||
128 common rename sys_rename
|
||||
129 common truncate sys_truncate compat_sys_truncate
|
||||
130 common ftruncate sys_ftruncate compat_sys_ftruncate
|
||||
131 common flock sys_flock
|
||||
132 common lstat64 sys_lstat64 compat_sys_lstat64
|
||||
133 common sendto sys_sendto
|
||||
134 common shutdown sys_shutdown
|
||||
135 common socketpair sys_socketpair
|
||||
136 common mkdir sys_mkdir
|
||||
137 common rmdir sys_rmdir
|
||||
138 32 utimes sys_utimes_time32
|
||||
138 64 utimes sys_utimes
|
||||
139 common stat64 sys_stat64 compat_sys_stat64
|
||||
140 common sendfile64 sys_sendfile64
|
||||
141 common getpeername sys_getpeername
|
||||
142 32 futex sys_futex_time32
|
||||
142 64 futex sys_futex
|
||||
143 common gettid sys_gettid
|
||||
144 common getrlimit sys_getrlimit compat_sys_getrlimit
|
||||
145 common setrlimit sys_setrlimit compat_sys_setrlimit
|
||||
146 common pivot_root sys_pivot_root
|
||||
147 common prctl sys_prctl
|
||||
148 common pciconfig_read sys_pciconfig_read
|
||||
149 common pciconfig_write sys_pciconfig_write
|
||||
150 common getsockname sys_getsockname
|
||||
151 common inotify_init sys_inotify_init
|
||||
152 common inotify_add_watch sys_inotify_add_watch
|
||||
153 common poll sys_poll
|
||||
154 common getdents64 sys_getdents64
|
||||
155 32 fcntl64 sys_fcntl64 compat_sys_fcntl64
|
||||
156 common inotify_rm_watch sys_inotify_rm_watch
|
||||
157 common statfs sys_statfs compat_sys_statfs
|
||||
158 common fstatfs sys_fstatfs compat_sys_fstatfs
|
||||
159 common umount sys_oldumount
|
||||
160 common sched_set_affinity sys_sched_setaffinity compat_sys_sched_setaffinity
|
||||
161 common sched_get_affinity sys_sched_getaffinity compat_sys_sched_getaffinity
|
||||
162 common getdomainname sys_getdomainname
|
||||
163 common setdomainname sys_setdomainname
|
||||
164 64 utrap_install sys_utrap_install
|
||||
165 common quotactl sys_quotactl
|
||||
166 common set_tid_address sys_set_tid_address
|
||||
167 common mount sys_mount compat_sys_mount
|
||||
168 common ustat sys_ustat compat_sys_ustat
|
||||
169 common setxattr sys_setxattr
|
||||
170 common lsetxattr sys_lsetxattr
|
||||
171 common fsetxattr sys_fsetxattr
|
||||
172 common getxattr sys_getxattr
|
||||
173 common lgetxattr sys_lgetxattr
|
||||
174 common getdents sys_getdents compat_sys_getdents
|
||||
175 common setsid sys_setsid
|
||||
176 common fchdir sys_fchdir
|
||||
177 common fgetxattr sys_fgetxattr
|
||||
178 common listxattr sys_listxattr
|
||||
179 common llistxattr sys_llistxattr
|
||||
180 common flistxattr sys_flistxattr
|
||||
181 common removexattr sys_removexattr
|
||||
182 common lremovexattr sys_lremovexattr
|
||||
183 32 sigpending sys_sigpending compat_sys_sigpending
|
||||
183 64 sigpending sys_nis_syscall
|
||||
184 common query_module sys_ni_syscall
|
||||
185 common setpgid sys_setpgid
|
||||
186 common fremovexattr sys_fremovexattr
|
||||
187 common tkill sys_tkill
|
||||
188 32 exit_group sys_exit_group sparc_exit_group
|
||||
188 64 exit_group sparc_exit_group
|
||||
189 common uname sys_newuname
|
||||
190 common init_module sys_init_module
|
||||
191 32 personality sys_personality sys_sparc64_personality
|
||||
191 64 personality sys_sparc64_personality
|
||||
192 32 remap_file_pages sys_sparc_remap_file_pages sys_remap_file_pages
|
||||
192 64 remap_file_pages sys_remap_file_pages
|
||||
193 common epoll_create sys_epoll_create
|
||||
194 common epoll_ctl sys_epoll_ctl
|
||||
195 common epoll_wait sys_epoll_wait
|
||||
196 common ioprio_set sys_ioprio_set
|
||||
197 common getppid sys_getppid
|
||||
198 32 sigaction sys_sparc_sigaction compat_sys_sparc_sigaction
|
||||
198 64 sigaction sys_nis_syscall
|
||||
199 common sgetmask sys_sgetmask
|
||||
200 common ssetmask sys_ssetmask
|
||||
201 32 sigsuspend sys_sigsuspend
|
||||
201 64 sigsuspend sys_nis_syscall
|
||||
202 common oldlstat sys_newlstat compat_sys_newlstat
|
||||
203 common uselib sys_uselib
|
||||
204 32 readdir sys_old_readdir compat_sys_old_readdir
|
||||
204 64 readdir sys_nis_syscall
|
||||
205 common readahead sys_readahead compat_sys_readahead
|
||||
206 common socketcall sys_socketcall sys32_socketcall
|
||||
207 common syslog sys_syslog
|
||||
208 common lookup_dcookie sys_lookup_dcookie compat_sys_lookup_dcookie
|
||||
209 common fadvise64 sys_fadvise64 compat_sys_fadvise64
|
||||
210 common fadvise64_64 sys_fadvise64_64 compat_sys_fadvise64_64
|
||||
211 common tgkill sys_tgkill
|
||||
212 common waitpid sys_waitpid
|
||||
213 common swapoff sys_swapoff
|
||||
214 common sysinfo sys_sysinfo compat_sys_sysinfo
|
||||
215 32 ipc sys_ipc compat_sys_ipc
|
||||
215 64 ipc sys_sparc_ipc
|
||||
216 32 sigreturn sys_sigreturn sys32_sigreturn
|
||||
216 64 sigreturn sys_nis_syscall
|
||||
217 common clone sys_clone
|
||||
218 common ioprio_get sys_ioprio_get
|
||||
219 32 adjtimex sys_adjtimex_time32
|
||||
219 64 adjtimex sys_sparc_adjtimex
|
||||
220 32 sigprocmask sys_sigprocmask compat_sys_sigprocmask
|
||||
220 64 sigprocmask sys_nis_syscall
|
||||
221 common create_module sys_ni_syscall
|
||||
222 common delete_module sys_delete_module
|
||||
223 common get_kernel_syms sys_ni_syscall
|
||||
224 common getpgid sys_getpgid
|
||||
225 common bdflush sys_bdflush
|
||||
226 common sysfs sys_sysfs
|
||||
227 common afs_syscall sys_nis_syscall
|
||||
228 common setfsuid sys_setfsuid16
|
||||
229 common setfsgid sys_setfsgid16
|
||||
230 common _newselect sys_select compat_sys_select
|
||||
231 32 time sys_time32
|
||||
232 common splice sys_splice
|
||||
233 32 stime sys_stime32
|
||||
233 64 stime sys_stime
|
||||
234 common statfs64 sys_statfs64 compat_sys_statfs64
|
||||
235 common fstatfs64 sys_fstatfs64 compat_sys_fstatfs64
|
||||
236 common _llseek sys_llseek
|
||||
237 common mlock sys_mlock
|
||||
238 common munlock sys_munlock
|
||||
239 common mlockall sys_mlockall
|
||||
240 common munlockall sys_munlockall
|
||||
241 common sched_setparam sys_sched_setparam
|
||||
242 common sched_getparam sys_sched_getparam
|
||||
243 common sched_setscheduler sys_sched_setscheduler
|
||||
244 common sched_getscheduler sys_sched_getscheduler
|
||||
245 common sched_yield sys_sched_yield
|
||||
246 common sched_get_priority_max sys_sched_get_priority_max
|
||||
247 common sched_get_priority_min sys_sched_get_priority_min
|
||||
248 32 sched_rr_get_interval sys_sched_rr_get_interval_time32
|
||||
248 64 sched_rr_get_interval sys_sched_rr_get_interval
|
||||
249 32 nanosleep sys_nanosleep_time32
|
||||
249 64 nanosleep sys_nanosleep
|
||||
250 32 mremap sys_mremap
|
||||
250 64 mremap sys_64_mremap
|
||||
251 common _sysctl sys_ni_syscall
|
||||
252 common getsid sys_getsid
|
||||
253 common fdatasync sys_fdatasync
|
||||
254 32 nfsservctl sys_ni_syscall sys_nis_syscall
|
||||
254 64 nfsservctl sys_nis_syscall
|
||||
255 common sync_file_range sys_sync_file_range compat_sys_sync_file_range
|
||||
256 32 clock_settime sys_clock_settime32
|
||||
256 64 clock_settime sys_clock_settime
|
||||
257 32 clock_gettime sys_clock_gettime32
|
||||
257 64 clock_gettime sys_clock_gettime
|
||||
258 32 clock_getres sys_clock_getres_time32
|
||||
258 64 clock_getres sys_clock_getres
|
||||
259 32 clock_nanosleep sys_clock_nanosleep_time32
|
||||
259 64 clock_nanosleep sys_clock_nanosleep
|
||||
260 common sched_getaffinity sys_sched_getaffinity compat_sys_sched_getaffinity
|
||||
261 common sched_setaffinity sys_sched_setaffinity compat_sys_sched_setaffinity
|
||||
262 32 timer_settime sys_timer_settime32
|
||||
262 64 timer_settime sys_timer_settime
|
||||
263 32 timer_gettime sys_timer_gettime32
|
||||
263 64 timer_gettime sys_timer_gettime
|
||||
264 common timer_getoverrun sys_timer_getoverrun
|
||||
265 common timer_delete sys_timer_delete
|
||||
266 common timer_create sys_timer_create compat_sys_timer_create
|
||||
# 267 was vserver
|
||||
267 common vserver sys_nis_syscall
|
||||
268 common io_setup sys_io_setup compat_sys_io_setup
|
||||
269 common io_destroy sys_io_destroy
|
||||
270 common io_submit sys_io_submit compat_sys_io_submit
|
||||
271 common io_cancel sys_io_cancel
|
||||
272 32 io_getevents sys_io_getevents_time32
|
||||
272 64 io_getevents sys_io_getevents
|
||||
273 common mq_open sys_mq_open compat_sys_mq_open
|
||||
274 common mq_unlink sys_mq_unlink
|
||||
275 32 mq_timedsend sys_mq_timedsend_time32
|
||||
275 64 mq_timedsend sys_mq_timedsend
|
||||
276 32 mq_timedreceive sys_mq_timedreceive_time32
|
||||
276 64 mq_timedreceive sys_mq_timedreceive
|
||||
277 common mq_notify sys_mq_notify compat_sys_mq_notify
|
||||
278 common mq_getsetattr sys_mq_getsetattr compat_sys_mq_getsetattr
|
||||
279 common waitid sys_waitid compat_sys_waitid
|
||||
280 common tee sys_tee
|
||||
281 common add_key sys_add_key
|
||||
282 common request_key sys_request_key
|
||||
283 common keyctl sys_keyctl compat_sys_keyctl
|
||||
284 common openat sys_openat compat_sys_openat
|
||||
285 common mkdirat sys_mkdirat
|
||||
286 common mknodat sys_mknodat
|
||||
287 common fchownat sys_fchownat
|
||||
288 32 futimesat sys_futimesat_time32
|
||||
288 64 futimesat sys_futimesat
|
||||
289 common fstatat64 sys_fstatat64 compat_sys_fstatat64
|
||||
290 common unlinkat sys_unlinkat
|
||||
291 common renameat sys_renameat
|
||||
292 common linkat sys_linkat
|
||||
293 common symlinkat sys_symlinkat
|
||||
294 common readlinkat sys_readlinkat
|
||||
295 common fchmodat sys_fchmodat
|
||||
296 common faccessat sys_faccessat
|
||||
297 32 pselect6 sys_pselect6_time32 compat_sys_pselect6_time32
|
||||
297 64 pselect6 sys_pselect6
|
||||
298 32 ppoll sys_ppoll_time32 compat_sys_ppoll_time32
|
||||
298 64 ppoll sys_ppoll
|
||||
299 common unshare sys_unshare
|
||||
300 common set_robust_list sys_set_robust_list compat_sys_set_robust_list
|
||||
301 common get_robust_list sys_get_robust_list compat_sys_get_robust_list
|
||||
302 common migrate_pages sys_migrate_pages compat_sys_migrate_pages
|
||||
303 common mbind sys_mbind compat_sys_mbind
|
||||
304 common get_mempolicy sys_get_mempolicy compat_sys_get_mempolicy
|
||||
305 common set_mempolicy sys_set_mempolicy compat_sys_set_mempolicy
|
||||
306 common kexec_load sys_kexec_load compat_sys_kexec_load
|
||||
307 common move_pages sys_move_pages compat_sys_move_pages
|
||||
308 common getcpu sys_getcpu
|
||||
309 common epoll_pwait sys_epoll_pwait compat_sys_epoll_pwait
|
||||
310 32 utimensat sys_utimensat_time32
|
||||
310 64 utimensat sys_utimensat
|
||||
311 common signalfd sys_signalfd compat_sys_signalfd
|
||||
312 common timerfd_create sys_timerfd_create
|
||||
313 common eventfd sys_eventfd
|
||||
314 common fallocate sys_fallocate compat_sys_fallocate
|
||||
315 32 timerfd_settime sys_timerfd_settime32
|
||||
315 64 timerfd_settime sys_timerfd_settime
|
||||
316 32 timerfd_gettime sys_timerfd_gettime32
|
||||
316 64 timerfd_gettime sys_timerfd_gettime
|
||||
317 common signalfd4 sys_signalfd4 compat_sys_signalfd4
|
||||
318 common eventfd2 sys_eventfd2
|
||||
319 common epoll_create1 sys_epoll_create1
|
||||
320 common dup3 sys_dup3
|
||||
321 common pipe2 sys_pipe2
|
||||
322 common inotify_init1 sys_inotify_init1
|
||||
323 common accept4 sys_accept4
|
||||
324 common preadv sys_preadv compat_sys_preadv
|
||||
325 common pwritev sys_pwritev compat_sys_pwritev
|
||||
326 common rt_tgsigqueueinfo sys_rt_tgsigqueueinfo compat_sys_rt_tgsigqueueinfo
|
||||
327 common perf_event_open sys_perf_event_open
|
||||
328 32 recvmmsg sys_recvmmsg_time32 compat_sys_recvmmsg_time32
|
||||
328 64 recvmmsg sys_recvmmsg
|
||||
329 common fanotify_init sys_fanotify_init
|
||||
330 common fanotify_mark sys_fanotify_mark compat_sys_fanotify_mark
|
||||
331 common prlimit64 sys_prlimit64
|
||||
332 common name_to_handle_at sys_name_to_handle_at
|
||||
333 common open_by_handle_at sys_open_by_handle_at compat_sys_open_by_handle_at
|
||||
334 32 clock_adjtime sys_clock_adjtime32
|
||||
334 64 clock_adjtime sys_sparc_clock_adjtime
|
||||
335 common syncfs sys_syncfs
|
||||
336 common sendmmsg sys_sendmmsg compat_sys_sendmmsg
|
||||
337 common setns sys_setns
|
||||
338 common process_vm_readv sys_process_vm_readv compat_sys_process_vm_readv
|
||||
339 common process_vm_writev sys_process_vm_writev compat_sys_process_vm_writev
|
||||
340 32 kern_features sys_ni_syscall sys_kern_features
|
||||
340 64 kern_features sys_kern_features
|
||||
341 common kcmp sys_kcmp
|
||||
342 common finit_module sys_finit_module
|
||||
343 common sched_setattr sys_sched_setattr
|
||||
344 common sched_getattr sys_sched_getattr
|
||||
345 common renameat2 sys_renameat2
|
||||
346 common seccomp sys_seccomp
|
||||
347 common getrandom sys_getrandom
|
||||
348 common memfd_create sys_memfd_create
|
||||
349 common bpf sys_bpf
|
||||
350 32 execveat sys_execveat sys32_execveat
|
||||
350 64 execveat sys64_execveat
|
||||
351 common membarrier sys_membarrier
|
||||
352 common userfaultfd sys_userfaultfd
|
||||
353 common bind sys_bind
|
||||
354 common listen sys_listen
|
||||
355 common setsockopt sys_setsockopt sys_setsockopt
|
||||
356 common mlock2 sys_mlock2
|
||||
357 common copy_file_range sys_copy_file_range
|
||||
358 common preadv2 sys_preadv2 compat_sys_preadv2
|
||||
359 common pwritev2 sys_pwritev2 compat_sys_pwritev2
|
||||
360 common statx sys_statx
|
||||
361 32 io_pgetevents sys_io_pgetevents_time32 compat_sys_io_pgetevents
|
||||
361 64 io_pgetevents sys_io_pgetevents
|
||||
362 common pkey_mprotect sys_pkey_mprotect
|
||||
363 common pkey_alloc sys_pkey_alloc
|
||||
364 common pkey_free sys_pkey_free
|
||||
365 common rseq sys_rseq
|
||||
# room for arch specific syscalls
|
||||
392 64 semtimedop sys_semtimedop
|
||||
393 common semget sys_semget
|
||||
394 common semctl sys_semctl compat_sys_semctl
|
||||
395 common shmget sys_shmget
|
||||
396 common shmctl sys_shmctl compat_sys_shmctl
|
||||
397 common shmat sys_shmat compat_sys_shmat
|
||||
398 common shmdt sys_shmdt
|
||||
399 common msgget sys_msgget
|
||||
400 common msgsnd sys_msgsnd compat_sys_msgsnd
|
||||
401 common msgrcv sys_msgrcv compat_sys_msgrcv
|
||||
402 common msgctl sys_msgctl compat_sys_msgctl
|
||||
403 32 clock_gettime64 sys_clock_gettime sys_clock_gettime
|
||||
404 32 clock_settime64 sys_clock_settime sys_clock_settime
|
||||
405 32 clock_adjtime64 sys_clock_adjtime sys_clock_adjtime
|
||||
406 32 clock_getres_time64 sys_clock_getres sys_clock_getres
|
||||
407 32 clock_nanosleep_time64 sys_clock_nanosleep sys_clock_nanosleep
|
||||
408 32 timer_gettime64 sys_timer_gettime sys_timer_gettime
|
||||
409 32 timer_settime64 sys_timer_settime sys_timer_settime
|
||||
410 32 timerfd_gettime64 sys_timerfd_gettime sys_timerfd_gettime
|
||||
411 32 timerfd_settime64 sys_timerfd_settime sys_timerfd_settime
|
||||
412 32 utimensat_time64 sys_utimensat sys_utimensat
|
||||
413 32 pselect6_time64 sys_pselect6 compat_sys_pselect6_time64
|
||||
414 32 ppoll_time64 sys_ppoll compat_sys_ppoll_time64
|
||||
416 32 io_pgetevents_time64 sys_io_pgetevents sys_io_pgetevents
|
||||
417 32 recvmmsg_time64 sys_recvmmsg compat_sys_recvmmsg_time64
|
||||
418 32 mq_timedsend_time64 sys_mq_timedsend sys_mq_timedsend
|
||||
419 32 mq_timedreceive_time64 sys_mq_timedreceive sys_mq_timedreceive
|
||||
420 32 semtimedop_time64 sys_semtimedop sys_semtimedop
|
||||
421 32 rt_sigtimedwait_time64 sys_rt_sigtimedwait compat_sys_rt_sigtimedwait_time64
|
||||
422 32 futex_time64 sys_futex sys_futex
|
||||
423 32 sched_rr_get_interval_time64 sys_sched_rr_get_interval sys_sched_rr_get_interval
|
||||
424 common pidfd_send_signal sys_pidfd_send_signal
|
||||
425 common io_uring_setup sys_io_uring_setup
|
||||
426 common io_uring_enter sys_io_uring_enter
|
||||
427 common io_uring_register sys_io_uring_register
|
||||
428 common open_tree sys_open_tree
|
||||
429 common move_mount sys_move_mount
|
||||
430 common fsopen sys_fsopen
|
||||
431 common fsconfig sys_fsconfig
|
||||
432 common fsmount sys_fsmount
|
||||
433 common fspick sys_fspick
|
||||
434 common pidfd_open sys_pidfd_open
|
||||
# 435 reserved for clone3
|
||||
436 common close_range sys_close_range
|
||||
437 common openat2 sys_openat2
|
||||
438 common pidfd_getfd sys_pidfd_getfd
|
||||
439 common faccessat2 sys_faccessat2
|
@ -1,32 +0,0 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
in="$1"
|
||||
out="$2"
|
||||
my_abis=`echo "($3)" | tr ',' '|'`
|
||||
prefix="$4"
|
||||
offset="$5"
|
||||
|
||||
fileguard=LINUX_USER_SPARC64_`basename "$out" | sed \
|
||||
-e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' \
|
||||
-e 's/[^A-Z0-9_]/_/g' -e 's/__/_/g'`
|
||||
grep -E "^[0-9A-Fa-fXx]+[[:space:]]+${my_abis}" "$in" | sort -n | (
|
||||
printf "#ifndef %s\n" "${fileguard}"
|
||||
printf "#define %s\n" "${fileguard}"
|
||||
printf "\n"
|
||||
|
||||
nxt=0
|
||||
while read nr abi name entry compat ; do
|
||||
if [ -z "$offset" ]; then
|
||||
printf "#define TARGET_NR_%s%s\t%s\n" \
|
||||
"${prefix}" "${name}" "${nr}"
|
||||
else
|
||||
printf "#define TARGET_NR_%s%s\t(%s + %s)\n" \
|
||||
"${prefix}" "${name}" "${offset}" "${nr}"
|
||||
fi
|
||||
nxt=$((nr+1))
|
||||
done
|
||||
|
||||
printf "\n"
|
||||
printf "#endif /* %s */" "${fileguard}"
|
||||
) > "$out"
|
@ -1 +0,0 @@
|
||||
#include "../sparc/target_cpu.h"
|
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation, or (at your option) any
|
||||
* later version. See the COPYING file in the top-level directory.
|
||||
*/
|
||||
|
||||
#ifndef SPARC64_TARGET_ELF_H
|
||||
#define SPARC64_TARGET_ELF_H
|
||||
static inline const char *cpu_get_model(uint32_t eflags)
|
||||
{
|
||||
return "TI UltraSparc II";
|
||||
}
|
||||
#endif
|
@ -1 +0,0 @@
|
||||
#include "../sparc/target_fcntl.h"
|
@ -1 +0,0 @@
|
||||
#include "../sparc/target_signal.h"
|
@ -1,58 +0,0 @@
|
||||
/*
|
||||
* SPARC64 specific structures for linux-user
|
||||
*
|
||||
* Copyright (c) 2013 Fabrice Bellard
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#ifndef SPARC64_TARGET_STRUCTS_H
|
||||
#define SPARC64_TARGET_STRUCTS_H
|
||||
|
||||
struct target_ipc_perm {
|
||||
abi_int __key; /* Key. */
|
||||
abi_uint uid; /* Owner's user ID. */
|
||||
abi_uint gid; /* Owner's group ID. */
|
||||
abi_uint cuid; /* Creator's user ID. */
|
||||
abi_uint cgid; /* Creator's group ID. */
|
||||
abi_ushort mode; /* Read/write permission. */
|
||||
abi_ushort __pad1;
|
||||
abi_ushort __seq; /* Sequence number. */
|
||||
abi_ushort __pad2;
|
||||
abi_ulong __unused1;
|
||||
abi_ulong __unused2;
|
||||
};
|
||||
|
||||
struct target_shmid_ds {
|
||||
struct target_ipc_perm shm_perm; /* operation permission struct */
|
||||
abi_long shm_segsz; /* size of segment in bytes */
|
||||
abi_ulong shm_atime; /* time of last shmat() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused1;
|
||||
#endif
|
||||
abi_ulong shm_dtime; /* time of last shmdt() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused2;
|
||||
#endif
|
||||
abi_ulong shm_ctime; /* time of last change by shmctl() */
|
||||
#if TARGET_ABI_BITS == 32
|
||||
abi_ulong __unused3;
|
||||
#endif
|
||||
abi_int shm_cpid; /* pid of creator */
|
||||
abi_int shm_lpid; /* pid of last shmop */
|
||||
abi_ulong shm_nattch; /* number of current attaches */
|
||||
abi_ulong __unused4;
|
||||
abi_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,35 +0,0 @@
|
||||
#ifndef SPARC64_TARGET_SYSCALL_H
|
||||
#define SPARC64_TARGET_SYSCALL_H
|
||||
|
||||
#include "../sparc/target_errno.h"
|
||||
|
||||
struct target_pt_regs {
|
||||
abi_ulong u_regs[16];
|
||||
abi_ulong tstate;
|
||||
abi_ulong pc;
|
||||
abi_ulong npc;
|
||||
abi_ulong y;
|
||||
abi_ulong fprs;
|
||||
};
|
||||
|
||||
#define UNAME_MACHINE "sparc64"
|
||||
#define UNAME_MINIMUM_RELEASE "2.6.32"
|
||||
|
||||
/* SPARC kernels don't define this in their Kconfig, but they have the
|
||||
* same ABI as if they did, implemented by sparc-specific code which fishes
|
||||
* directly in the u_regs() struct for half the parameters in sparc_do_fork()
|
||||
* and copy_thread().
|
||||
*/
|
||||
#define TARGET_CLONE_BACKWARDS
|
||||
#define TARGET_MINSIGSTKSZ 4096
|
||||
#define TARGET_MCL_CURRENT 0x2000
|
||||
#define TARGET_MCL_FUTURE 0x4000
|
||||
#define TARGET_MCL_ONFAULT 0x8000
|
||||
|
||||
#define TARGET_FORCE_SHMLBA
|
||||
|
||||
static inline abi_ulong target_shmlba(CPUSPARCState *env)
|
||||
{
|
||||
return MAX(TARGET_PAGE_SIZE, 16 * 1024);
|
||||
}
|
||||
#endif /* SPARC64_TARGET_SYSCALL_H */
|
@ -1,291 +0,0 @@
|
||||
/* from asm/termbits.h */
|
||||
|
||||
#ifndef LINUX_USER_SPARC64_TERMBITS_H
|
||||
#define LINUX_USER_SPARC64_TERMBITS_H
|
||||
|
||||
#define TARGET_NCCS 19
|
||||
|
||||
typedef unsigned char target_cc_t; /* cc_t */
|
||||
typedef unsigned int target_speed_t; /* speed_t */
|
||||
typedef unsigned int target_tcflag_t; /* tcflag_t */
|
||||
|
||||
struct target_termios {
|
||||
target_tcflag_t c_iflag; /* input mode flags */
|
||||
target_tcflag_t c_oflag; /* output mode flags */
|
||||
target_tcflag_t c_cflag; /* control mode flags */
|
||||
target_tcflag_t c_lflag; /* local mode flags */
|
||||
target_cc_t c_line; /* line discipline */
|
||||
target_cc_t c_cc[TARGET_NCCS]; /* control characters */
|
||||
};
|
||||
|
||||
|
||||
/* c_cc characters */
|
||||
#define TARGET_VINTR 0
|
||||
#define TARGET_VQUIT 1
|
||||
#define TARGET_VERASE 2
|
||||
#define TARGET_VKILL 3
|
||||
#define TARGET_VEOF 4
|
||||
#define TARGET_VEOL 5
|
||||
#define TARGET_VEOL2 6
|
||||
#define TARGET_VSWTC 7
|
||||
#define TARGET_VSTART 8
|
||||
#define TARGET_VSTOP 9
|
||||
|
||||
#define TARGET_VSUSP 10
|
||||
#define TARGET_VDSUSP 11 /* SunOS POSIX nicety I do believe... */
|
||||
#define TARGET_VREPRINT 12
|
||||
#define TARGET_VDISCARD 13
|
||||
#define TARGET_VWERASE 14
|
||||
#define TARGET_VLNEXT 15
|
||||
|
||||
/* Kernel keeps vmin/vtime separated, user apps assume vmin/vtime is
|
||||
* shared with eof/eol
|
||||
*/
|
||||
#define TARGET_VMIN TARGET_VEOF
|
||||
#define TARGET_VTIME TARGET_VEOL
|
||||
|
||||
/* c_iflag bits */
|
||||
#define TARGET_IGNBRK 0x00000001
|
||||
#define TARGET_BRKINT 0x00000002
|
||||
#define TARGET_IGNPAR 0x00000004
|
||||
#define TARGET_PARMRK 0x00000008
|
||||
#define TARGET_INPCK 0x00000010
|
||||
#define TARGET_ISTRIP 0x00000020
|
||||
#define TARGET_INLCR 0x00000040
|
||||
#define TARGET_IGNCR 0x00000080
|
||||
#define TARGET_ICRNL 0x00000100
|
||||
#define TARGET_IUCLC 0x00000200
|
||||
#define TARGET_IXON 0x00000400
|
||||
#define TARGET_IXANY 0x00000800
|
||||
#define TARGET_IXOFF 0x00001000
|
||||
#define TARGET_IMAXBEL 0x00002000
|
||||
#define TARGET_IUTF8 0x00004000
|
||||
|
||||
/* c_oflag bits */
|
||||
#define TARGET_OPOST 0x00000001
|
||||
#define TARGET_OLCUC 0x00000002
|
||||
#define TARGET_ONLCR 0x00000004
|
||||
#define TARGET_OCRNL 0x00000008
|
||||
#define TARGET_ONOCR 0x00000010
|
||||
#define TARGET_ONLRET 0x00000020
|
||||
#define TARGET_OFILL 0x00000040
|
||||
#define TARGET_OFDEL 0x00000080
|
||||
#define TARGET_NLDLY 0x00000100
|
||||
#define TARGET_NL0 0x00000000
|
||||
#define TARGET_NL1 0x00000100
|
||||
#define TARGET_CRDLY 0x00000600
|
||||
#define TARGET_CR0 0x00000000
|
||||
#define TARGET_CR1 0x00000200
|
||||
#define TARGET_CR2 0x00000400
|
||||
#define TARGET_CR3 0x00000600
|
||||
#define TARGET_TABDLY 0x00001800
|
||||
#define TARGET_TAB0 0x00000000
|
||||
#define TARGET_TAB1 0x00000800
|
||||
#define TARGET_TAB2 0x00001000
|
||||
#define TARGET_TAB3 0x00001800
|
||||
#define TARGET_XTABS 0x00001800
|
||||
#define TARGET_BSDLY 0x00002000
|
||||
#define TARGET_BS0 0x00000000
|
||||
#define TARGET_BS1 0x00002000
|
||||
#define TARGET_VTDLY 0x00004000
|
||||
#define TARGET_VT0 0x00000000
|
||||
#define TARGET_VT1 0x00004000
|
||||
#define TARGET_FFDLY 0x00008000
|
||||
#define TARGET_FF0 0x00000000
|
||||
#define TARGET_FF1 0x00008000
|
||||
#define TARGET_PAGEOUT 0x00010000 /* SUNOS specific */
|
||||
#define TARGET_WRAP 0x00020000 /* SUNOS specific */
|
||||
|
||||
/* c_cflag bit meaning */
|
||||
#define TARGET_CBAUD 0x0000100f
|
||||
#define TARGET_B0 0x00000000 /* hang up */
|
||||
#define TARGET_B50 0x00000001
|
||||
#define TARGET_B75 0x00000002
|
||||
#define TARGET_B110 0x00000003
|
||||
#define TARGET_B134 0x00000004
|
||||
#define TARGET_B150 0x00000005
|
||||
#define TARGET_B200 0x00000006
|
||||
#define TARGET_B300 0x00000007
|
||||
#define TARGET_B600 0x00000008
|
||||
#define TARGET_B1200 0x00000009
|
||||
#define TARGET_B1800 0x0000000a
|
||||
#define TARGET_B2400 0x0000000b
|
||||
#define TARGET_B4800 0x0000000c
|
||||
#define TARGET_B9600 0x0000000d
|
||||
#define TARGET_B19200 0x0000000e
|
||||
#define TARGET_B38400 0x0000000f
|
||||
#define TARGET_EXTA B19200
|
||||
#define TARGET_EXTB B38400
|
||||
#define TARGET_CSIZE 0x00000030
|
||||
#define TARGET_CS5 0x00000000
|
||||
#define TARGET_CS6 0x00000010
|
||||
#define TARGET_CS7 0x00000020
|
||||
#define TARGET_CS8 0x00000030
|
||||
#define TARGET_CSTOPB 0x00000040
|
||||
#define TARGET_CREAD 0x00000080
|
||||
#define TARGET_PARENB 0x00000100
|
||||
#define TARGET_PARODD 0x00000200
|
||||
#define TARGET_HUPCL 0x00000400
|
||||
#define TARGET_CLOCAL 0x00000800
|
||||
#define TARGET_CBAUDEX 0x00001000
|
||||
/* We'll never see these speeds with the Zilogs, but for completeness... */
|
||||
#define TARGET_B57600 0x00001001
|
||||
#define TARGET_B115200 0x00001002
|
||||
#define TARGET_B230400 0x00001003
|
||||
#define TARGET_B460800 0x00001004
|
||||
/* This is what we can do with the Zilogs. */
|
||||
#define TARGET_B76800 0x00001005
|
||||
/* This is what we can do with the SAB82532. */
|
||||
#define TARGET_B153600 0x00001006
|
||||
#define TARGET_B307200 0x00001007
|
||||
#define TARGET_B614400 0x00001008
|
||||
#define TARGET_B921600 0x00001009
|
||||
/* And these are the rest... */
|
||||
#define TARGET_B500000 0x0000100a
|
||||
#define TARGET_B576000 0x0000100b
|
||||
#define TARGET_B1000000 0x0000100c
|
||||
#define TARGET_B1152000 0x0000100d
|
||||
#define TARGET_B1500000 0x0000100e
|
||||
#define TARGET_B2000000 0x0000100f
|
||||
/* These have totally bogus values and nobody uses them
|
||||
so far. Later on we'd have to use say 0x10000x and
|
||||
adjust CBAUD constant and drivers accordingly.
|
||||
#define B2500000 0x00001010
|
||||
#define B3000000 0x00001011
|
||||
#define B3500000 0x00001012
|
||||
#define B4000000 0x00001013 */
|
||||
#define TARGET_CIBAUD 0x100f0000 /* input baud rate (not used) */
|
||||
#define TARGET_CMSPAR 0x40000000 /* mark or space (stick) parity */
|
||||
#define TARGET_CRTSCTS 0x80000000 /* flow control */
|
||||
|
||||
/* c_lflag bits */
|
||||
#define TARGET_ISIG 0x00000001
|
||||
#define TARGET_ICANON 0x00000002
|
||||
#define TARGET_XCASE 0x00000004
|
||||
#define TARGET_ECHO 0x00000008
|
||||
#define TARGET_ECHOE 0x00000010
|
||||
#define TARGET_ECHOK 0x00000020
|
||||
#define TARGET_ECHONL 0x00000040
|
||||
#define TARGET_NOFLSH 0x00000080
|
||||
#define TARGET_TOSTOP 0x00000100
|
||||
#define TARGET_ECHOCTL 0x00000200
|
||||
#define TARGET_ECHOPRT 0x00000400
|
||||
#define TARGET_ECHOKE 0x00000800
|
||||
#define TARGET_DEFECHO 0x00001000 /* SUNOS thing, what is it? */
|
||||
#define TARGET_FLUSHO 0x00002000
|
||||
#define TARGET_PENDIN 0x00004000
|
||||
#define TARGET_IEXTEN 0x00008000
|
||||
#define TARGET_EXTPROC 0x00010000
|
||||
|
||||
/* ioctls */
|
||||
|
||||
/* Big T */
|
||||
#define TARGET_TCGETA TARGET_IOR('T', 1, struct target_termio)
|
||||
#define TARGET_TCSETA TARGET_IOW('T', 2, struct target_termio)
|
||||
#define TARGET_TCSETAW TARGET_IOW('T', 3, struct target_termio)
|
||||
#define TARGET_TCSETAF TARGET_IOW('T', 4, struct target_termio)
|
||||
#define TARGET_TCSBRK TARGET_IO('T', 5)
|
||||
#define TARGET_TCXONC TARGET_IO('T', 6)
|
||||
#define TARGET_TCFLSH TARGET_IO('T', 7)
|
||||
#define TARGET_TCGETS TARGET_IOR('T', 8, struct target_termios)
|
||||
#define TARGET_TCSETS TARGET_IOW('T', 9, struct target_termios)
|
||||
#define TARGET_TCSETSW TARGET_IOW('T', 10, struct target_termios)
|
||||
#define TARGET_TCSETSF TARGET_IOW('T', 11, struct target_termios)
|
||||
|
||||
/* Note that all the ioctls that are not available in Linux have a
|
||||
* double underscore on the front to: a) avoid some programs to
|
||||
* thing we support some ioctls under Linux (autoconfiguration stuff)
|
||||
*/
|
||||
/* Little t */
|
||||
#define TARGET_TIOCGETD TARGET_IOR('t', 0, int)
|
||||
#define TARGET_TIOCSETD TARGET_IOW('t', 1, int)
|
||||
//#define __TIOCHPCL _IO('t', 2) /* SunOS Specific */
|
||||
//#define __TIOCMODG _IOR('t', 3, int) /* SunOS Specific */
|
||||
//#define __TIOCMODS _IOW('t', 4, int) /* SunOS Specific */
|
||||
//#define __TIOCGETP _IOR('t', 8, struct sgttyb) /* SunOS Specific */
|
||||
//#define __TIOCSETP _IOW('t', 9, struct sgttyb) /* SunOS Specific */
|
||||
//#define __TIOCSETN _IOW('t', 10, struct sgttyb) /* SunOS Specific */
|
||||
#define TARGET_TIOCEXCL TARGET_IO('t', 13)
|
||||
#define TARGET_TIOCNXCL TARGET_IO('t', 14)
|
||||
//#define __TIOCFLUSH _IOW('t', 16, int) /* SunOS Specific */
|
||||
//#define __TIOCSETC _IOW('t', 17, struct tchars) /* SunOS Specific */
|
||||
//#define __TIOCGETC _IOR('t', 18, struct tchars) /* SunOS Specific */
|
||||
//#define __TIOCTCNTL _IOW('t', 32, int) /* SunOS Specific */
|
||||
//#define __TIOCSIGNAL _IOW('t', 33, int) /* SunOS Specific */
|
||||
//#define __TIOCSETX _IOW('t', 34, int) /* SunOS Specific */
|
||||
//#define __TIOCGETX _IOR('t', 35, int) /* SunOS Specific */
|
||||
#define TARGET_TIOCCONS TARGET_IO('t', 36)
|
||||
//#define __TIOCSSIZE _IOW('t', 37, struct sunos_ttysize) /* SunOS Specific */
|
||||
//#define __TIOCGSIZE _IOR('t', 38, struct sunos_ttysize) /* SunOS Specific */
|
||||
#define TARGET_TIOCGSOFTCAR TARGET_IOR('t', 100, int)
|
||||
#define TARGET_TIOCSSOFTCAR TARGET_IOW('t', 101, int)
|
||||
//#define __TIOCUCNTL _IOW('t', 102, int) /* SunOS Specific */
|
||||
#define TARGET_TIOCSWINSZ TARGET_IOW('t', 103, struct winsize)
|
||||
#define TARGET_TIOCGWINSZ TARGET_IOR('t', 104, struct winsize)
|
||||
//#define __TIOCREMOTE _IOW('t', 105, int) /* SunOS Specific */
|
||||
#define TARGET_TIOCMGET TARGET_IOR('t', 106, int)
|
||||
#define TARGET_TIOCMBIC TARGET_IOW('t', 107, int)
|
||||
#define TARGET_TIOCMBIS TARGET_IOW('t', 108, int)
|
||||
#define TARGET_TIOCMSET TARGET_IOW('t', 109, int)
|
||||
#define TARGET_TIOCSTART TARGET_IO('t', 110)
|
||||
#define TARGET_TIOCSTOP TARGET_IO('t', 111)
|
||||
#define TARGET_TIOCPKT TARGET_IOW('t', 112, int)
|
||||
#define TARGET_TIOCNOTTY TARGET_IO('t', 113)
|
||||
#define TARGET_TIOCSTI TARGET_IOW('t', 114, char)
|
||||
#define TARGET_TIOCOUTQ TARGET_IOR('t', 115, int)
|
||||
//#define __TIOCGLTC _IOR('t', 116, struct ltchars) /* SunOS Specific */
|
||||
//#define __TIOCSLTC _IOW('t', 117, struct ltchars) /* SunOS Specific */
|
||||
/* 118 is the non-posix setpgrp tty ioctl */
|
||||
/* 119 is the non-posix getpgrp tty ioctl */
|
||||
//#define __TIOCCDTR TARGET_IO('t', 120) /* SunOS Specific */
|
||||
//#define __TIOCSDTR TARGET_IO('t', 121) /* SunOS Specific */
|
||||
#define TARGET_TIOCCBRK TARGET_IO('t', 122)
|
||||
#define TARGET_TIOCSBRK TARGET_IO('t', 123)
|
||||
//#define __TIOCLGET TARGET_IOW('t', 124, int) /* SunOS Specific */
|
||||
//#define __TIOCLSET TARGET_IOW('t', 125, int) /* SunOS Specific */
|
||||
//#define __TIOCLBIC TARGET_IOW('t', 126, int) /* SunOS Specific */
|
||||
//#define __TIOCLBIS TARGET_IOW('t', 127, int) /* SunOS Specific */
|
||||
//#define __TIOCISPACE TARGET_IOR('t', 128, int) /* SunOS Specific */
|
||||
//#define __TIOCISIZE TARGET_IOR('t', 129, int) /* SunOS Specific */
|
||||
#define TARGET_TIOCSPGRP TARGET_IOW('t', 130, int)
|
||||
#define TARGET_TIOCGPGRP TARGET_IOR('t', 131, int)
|
||||
#define TARGET_TIOCSCTTY TARGET_IO('t', 132)
|
||||
#define TARGET_TIOCGSID TARGET_IOR('t', 133, int)
|
||||
/* Get minor device of a pty master's FD -- Solaris equiv is ISPTM */
|
||||
#define TARGET_TIOCGPTN TARGET_IOR('t', 134, unsigned int) /* Get Pty Number */
|
||||
#define TARGET_TIOCSPTLCK TARGET_IOW('t', 135, int) /* Lock/unlock PTY */
|
||||
#define TARGET_TIOCGPTPEER TARGET_IO('t', 137) /* Safely open the slave */
|
||||
|
||||
/* Little f */
|
||||
#define TARGET_FIOCLEX TARGET_IO('f', 1)
|
||||
#define TARGET_FIONCLEX TARGET_IO('f', 2)
|
||||
#define TARGET_FIOASYNC TARGET_IOW('f', 125, int)
|
||||
#define TARGET_FIONBIO TARGET_IOW('f', 126, int)
|
||||
#define TARGET_FIONREAD TARGET_IOR('f', 127, int)
|
||||
#define TARGET_TIOCINQ TARGET_FIONREAD
|
||||
|
||||
/* SCARY Rutgers local SunOS kernel hackery, perhaps I will support it
|
||||
* someday. This is completely bogus, I know...
|
||||
*/
|
||||
//#define __TCGETSTAT TARGET_IO('T', 200) /* Rutgers specific */
|
||||
//#define __TCSETSTAT TARGET_IO('T', 201) /* Rutgers specific */
|
||||
|
||||
/* Linux specific, no SunOS equivalent. */
|
||||
#define TARGET_TIOCLINUX 0x541C
|
||||
#define TARGET_TIOCGSERIAL 0x541E
|
||||
#define TARGET_TIOCSSERIAL 0x541F
|
||||
#define TARGET_TCSBRKP 0x5425
|
||||
#define TARGET_TIOCTTYGSTRUCT 0x5426
|
||||
#define TARGET_TIOCSERCONFIG 0x5453
|
||||
#define TARGET_TIOCSERGWILD 0x5454
|
||||
#define TARGET_TIOCSERSWILD 0x5455
|
||||
#define TARGET_TIOCGLCKTRMIOS 0x5456
|
||||
#define TARGET_TIOCSLCKTRMIOS 0x5457
|
||||
#define TARGET_TIOCSERGSTRUCT 0x5458 /* For debugging only */
|
||||
#define TARGET_TIOCSERGETLSR 0x5459 /* Get line status register */
|
||||
#define TARGET_TIOCSERGETMULTI 0x545A /* Get multiport config */
|
||||
#define TARGET_TIOCSERSETMULTI 0x545B /* Set multiport config */
|
||||
#define TARGET_TIOCMIWAIT 0x545C /* Wait input */
|
||||
#define TARGET_TIOCGICOUNT 0x545D /* Read serial port inline interrupt counts */
|
||||
|
||||
#endif
|
@ -1109,6 +1109,12 @@ UNUSED static struct flags clone_flags[] = {
|
||||
#if defined(CLONE_NEWNET)
|
||||
FLAG_GENERIC(CLONE_NEWNET),
|
||||
#endif
|
||||
#if defined(CLONE_NEWCGROUP)
|
||||
FLAG_GENERIC(CLONE_NEWCGROUP),
|
||||
#endif
|
||||
#if defined(CLONE_NEWTIME)
|
||||
FLAG_GENERIC(CLONE_NEWTIME),
|
||||
#endif
|
||||
#if defined(CLONE_IO)
|
||||
FLAG_GENERIC(CLONE_IO),
|
||||
#endif
|
||||
@ -2335,7 +2341,7 @@ print_linkat(void *cpu_env, const struct syscallname *name,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR__llseek
|
||||
#if defined(TARGET_NR__llseek) || defined(TARGET_NR_llseek)
|
||||
static void
|
||||
print__llseek(void *cpu_env, const struct syscallname *name,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
@ -2355,6 +2361,7 @@ print__llseek(void *cpu_env, const struct syscallname *name,
|
||||
qemu_log("%s", whence);
|
||||
print_syscall_epilogue(name);
|
||||
}
|
||||
#define print_llseek print__llseek
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR_lseek
|
||||
@ -3467,6 +3474,18 @@ print_unlinkat(void *cpu_env, const struct syscallname *name,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR_unshare
|
||||
static void
|
||||
print_unshare(void *cpu_env, const struct syscallname *name,
|
||||
abi_long arg0, abi_long arg1, abi_long arg2,
|
||||
abi_long arg3, abi_long arg4, abi_long arg5)
|
||||
{
|
||||
print_syscall_prologue(name);
|
||||
print_flags(clone_flags, arg0, 1);
|
||||
print_syscall_epilogue(name);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_NR_utime
|
||||
static void
|
||||
print_utime(void *cpu_env, const struct syscallname *name,
|
||||
|
@ -511,6 +511,9 @@
|
||||
#ifdef TARGET_NR__llseek
|
||||
{ TARGET_NR__llseek, "_llseek" , NULL, print__llseek, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_llseek
|
||||
{ TARGET_NR_llseek, "llseek" , NULL, print_llseek, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_lock
|
||||
{ TARGET_NR_lock, "lock" , NULL, NULL, NULL },
|
||||
#endif
|
||||
@ -1573,7 +1576,7 @@
|
||||
{ TARGET_NR_unlinkat, "unlinkat" , NULL, print_unlinkat, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_unshare
|
||||
{ TARGET_NR_unshare, "unshare" , NULL, NULL, NULL },
|
||||
{ TARGET_NR_unshare, "unshare" , NULL, print_unshare, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_userfaultfd
|
||||
{ TARGET_NR_userfaultfd, "userfaultfd" , NULL, NULL, NULL },
|
||||
@ -1665,3 +1668,6 @@
|
||||
#ifdef TARGET_NR_statx
|
||||
{ TARGET_NR_statx, "statx", NULL, print_statx, NULL },
|
||||
#endif
|
||||
#ifdef TARGET_NR_copy_file_range
|
||||
{ TARGET_NR_copy_file_range, "copy_file_range", "%s(%d,%p,%d,%p,"TARGET_ABI_FMT_lu",%u)", NULL, NULL },
|
||||
#endif
|
||||
|
@ -8980,29 +8980,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
#ifdef TARGET_NR_sigaction
|
||||
case TARGET_NR_sigaction:
|
||||
{
|
||||
#if defined(TARGET_ALPHA)
|
||||
struct target_sigaction act, oact, *pact = 0;
|
||||
struct target_old_sigaction *old_act;
|
||||
if (arg2) {
|
||||
if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
|
||||
return -TARGET_EFAULT;
|
||||
act._sa_handler = old_act->_sa_handler;
|
||||
target_siginitset(&act.sa_mask, old_act->sa_mask);
|
||||
act.sa_flags = old_act->sa_flags;
|
||||
act.sa_restorer = 0;
|
||||
unlock_user_struct(old_act, arg2, 0);
|
||||
pact = &act;
|
||||
}
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact));
|
||||
if (!is_error(ret) && arg3) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
|
||||
return -TARGET_EFAULT;
|
||||
old_act->_sa_handler = oact._sa_handler;
|
||||
old_act->sa_mask = oact.sa_mask.sig[0];
|
||||
old_act->sa_flags = oact.sa_flags;
|
||||
unlock_user_struct(old_act, arg3, 1);
|
||||
}
|
||||
#elif defined(TARGET_MIPS)
|
||||
#if defined(TARGET_MIPS)
|
||||
struct target_sigaction act, oact, *pact, *old_act;
|
||||
|
||||
if (arg2) {
|
||||
@ -9017,7 +8995,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
pact = NULL;
|
||||
}
|
||||
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact));
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact, 0));
|
||||
|
||||
if (!is_error(ret) && arg3) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
|
||||
@ -9039,23 +9017,24 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
act._sa_handler = old_act->_sa_handler;
|
||||
target_siginitset(&act.sa_mask, old_act->sa_mask);
|
||||
act.sa_flags = old_act->sa_flags;
|
||||
#ifdef TARGET_ARCH_HAS_SA_RESTORER
|
||||
act.sa_restorer = old_act->sa_restorer;
|
||||
#ifdef TARGET_ARCH_HAS_KA_RESTORER
|
||||
act.ka_restorer = 0;
|
||||
#endif
|
||||
unlock_user_struct(old_act, arg2, 0);
|
||||
pact = &act;
|
||||
} else {
|
||||
pact = NULL;
|
||||
}
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact));
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact, 0));
|
||||
if (!is_error(ret) && arg3) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
|
||||
return -TARGET_EFAULT;
|
||||
old_act->_sa_handler = oact._sa_handler;
|
||||
old_act->sa_mask = oact.sa_mask.sig[0];
|
||||
old_act->sa_flags = oact.sa_flags;
|
||||
#ifdef TARGET_ARCH_HAS_SA_RESTORER
|
||||
old_act->sa_restorer = oact.sa_restorer;
|
||||
#endif
|
||||
unlock_user_struct(old_act, arg3, 1);
|
||||
}
|
||||
#endif
|
||||
@ -9064,77 +9043,43 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
#endif
|
||||
case TARGET_NR_rt_sigaction:
|
||||
{
|
||||
#if defined(TARGET_ALPHA)
|
||||
/* For Alpha and SPARC this is a 5 argument syscall, with
|
||||
/*
|
||||
* For Alpha and SPARC this is a 5 argument syscall, with
|
||||
* a 'restorer' parameter which must be copied into the
|
||||
* sa_restorer field of the sigaction struct.
|
||||
* For Alpha that 'restorer' is arg5; for SPARC it is arg4,
|
||||
* and arg5 is the sigsetsize.
|
||||
* Alpha also has a separate rt_sigaction struct that it uses
|
||||
* here; SPARC uses the usual sigaction struct.
|
||||
*/
|
||||
struct target_rt_sigaction *rt_act;
|
||||
struct target_sigaction act, oact, *pact = 0;
|
||||
|
||||
if (arg4 != sizeof(target_sigset_t)) {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
if (arg2) {
|
||||
if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
|
||||
return -TARGET_EFAULT;
|
||||
act._sa_handler = rt_act->_sa_handler;
|
||||
act.sa_mask = rt_act->sa_mask;
|
||||
act.sa_flags = rt_act->sa_flags;
|
||||
act.sa_restorer = arg5;
|
||||
unlock_user_struct(rt_act, arg2, 0);
|
||||
pact = &act;
|
||||
}
|
||||
ret = get_errno(do_sigaction(arg1, pact, &oact));
|
||||
if (!is_error(ret) && arg3) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
|
||||
return -TARGET_EFAULT;
|
||||
rt_act->_sa_handler = oact._sa_handler;
|
||||
rt_act->sa_mask = oact.sa_mask;
|
||||
rt_act->sa_flags = oact.sa_flags;
|
||||
unlock_user_struct(rt_act, arg3, 1);
|
||||
}
|
||||
#else
|
||||
#ifdef TARGET_SPARC
|
||||
#if defined(TARGET_ALPHA)
|
||||
target_ulong sigsetsize = arg4;
|
||||
target_ulong restorer = arg5;
|
||||
#elif defined(TARGET_SPARC)
|
||||
target_ulong restorer = arg4;
|
||||
target_ulong sigsetsize = arg5;
|
||||
#else
|
||||
target_ulong sigsetsize = arg4;
|
||||
target_ulong restorer = 0;
|
||||
#endif
|
||||
struct target_sigaction *act;
|
||||
struct target_sigaction *oact;
|
||||
struct target_sigaction *act = NULL;
|
||||
struct target_sigaction *oact = NULL;
|
||||
|
||||
if (sigsetsize != sizeof(target_sigset_t)) {
|
||||
return -TARGET_EINVAL;
|
||||
}
|
||||
if (arg2) {
|
||||
if (!lock_user_struct(VERIFY_READ, act, arg2, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
#ifdef TARGET_ARCH_HAS_KA_RESTORER
|
||||
act->ka_restorer = restorer;
|
||||
#endif
|
||||
} else {
|
||||
act = NULL;
|
||||
if (arg2 && !lock_user_struct(VERIFY_READ, act, arg2, 1)) {
|
||||
return -TARGET_EFAULT;
|
||||
}
|
||||
if (arg3) {
|
||||
if (!lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
|
||||
ret = -TARGET_EFAULT;
|
||||
goto rt_sigaction_fail;
|
||||
if (arg3 && !lock_user_struct(VERIFY_WRITE, oact, arg3, 0)) {
|
||||
ret = -TARGET_EFAULT;
|
||||
} else {
|
||||
ret = get_errno(do_sigaction(arg1, act, oact, restorer));
|
||||
if (oact) {
|
||||
unlock_user_struct(oact, arg3, 1);
|
||||
}
|
||||
} else
|
||||
oact = NULL;
|
||||
ret = get_errno(do_sigaction(arg1, act, oact));
|
||||
rt_sigaction_fail:
|
||||
if (act)
|
||||
}
|
||||
if (act) {
|
||||
unlock_user_struct(act, arg2, 0);
|
||||
if (oact)
|
||||
unlock_user_struct(oact, arg3, 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
#ifdef TARGET_NR_sgetmask /* not on alpha */
|
||||
@ -11195,8 +11140,7 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
return ret;
|
||||
}
|
||||
case TARGET_NR_sigaltstack:
|
||||
return do_sigaltstack(arg1, arg2,
|
||||
get_sp_from_cpustate((CPUArchState *)cpu_env));
|
||||
return do_sigaltstack(arg1, arg2, cpu_env);
|
||||
|
||||
#ifdef CONFIG_SENDFILE
|
||||
#ifdef TARGET_NR_sendfile
|
||||
@ -13245,8 +13189,9 @@ static abi_long do_syscall1(void *cpu_env, int num, abi_long arg1,
|
||||
}
|
||||
poutoff = &outoff;
|
||||
}
|
||||
/* Do not sign-extend the count parameter. */
|
||||
ret = get_errno(safe_copy_file_range(arg1, pinoff, arg3, poutoff,
|
||||
arg5, arg6));
|
||||
(abi_ulong)arg5, arg6));
|
||||
if (!is_error(ret) && ret > 0) {
|
||||
if (arg2) {
|
||||
if (put_user_u64(inoff, arg2)) {
|
||||
|
@ -492,7 +492,7 @@ void target_to_host_old_sigset(sigset_t *sigset,
|
||||
const abi_ulong *old_sigset);
|
||||
struct target_sigaction;
|
||||
int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
struct target_sigaction *oact);
|
||||
struct target_sigaction *oact, abi_ulong ka_restorer);
|
||||
|
||||
#include "target_signal.h"
|
||||
|
||||
@ -501,27 +501,12 @@ int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
#endif
|
||||
|
||||
#if defined(TARGET_ALPHA)
|
||||
struct target_old_sigaction {
|
||||
abi_ulong _sa_handler;
|
||||
abi_ulong sa_mask;
|
||||
int32_t sa_flags;
|
||||
};
|
||||
typedef int32_t target_old_sa_flags;
|
||||
#else
|
||||
typedef abi_ulong target_old_sa_flags;
|
||||
#endif
|
||||
|
||||
struct target_rt_sigaction {
|
||||
abi_ulong _sa_handler;
|
||||
abi_ulong sa_flags;
|
||||
target_sigset_t sa_mask;
|
||||
};
|
||||
|
||||
/* This is the struct used inside the kernel. The ka_restorer
|
||||
field comes from the 5th argument to sys_rt_sigaction. */
|
||||
struct target_sigaction {
|
||||
abi_ulong _sa_handler;
|
||||
abi_ulong sa_flags;
|
||||
target_sigset_t sa_mask;
|
||||
abi_ulong sa_restorer;
|
||||
};
|
||||
#elif defined(TARGET_MIPS)
|
||||
#if defined(TARGET_MIPS)
|
||||
struct target_sigaction {
|
||||
uint32_t sa_flags;
|
||||
#if defined(TARGET_ABI_MIPSN32)
|
||||
@ -539,7 +524,7 @@ struct target_sigaction {
|
||||
struct target_old_sigaction {
|
||||
abi_ulong _sa_handler;
|
||||
abi_ulong sa_mask;
|
||||
abi_ulong sa_flags;
|
||||
target_old_sa_flags sa_flags;
|
||||
#ifdef TARGET_ARCH_HAS_SA_RESTORER
|
||||
abi_ulong sa_restorer;
|
||||
#endif
|
||||
|
@ -253,12 +253,8 @@ long do_rt_sigreturn(CPUXtensaState *env)
|
||||
set_sigmask(&set);
|
||||
|
||||
restore_sigcontext(env, frame);
|
||||
target_restore_altstack(&frame->uc.tuc_stack, env);
|
||||
|
||||
if (do_sigaltstack(frame_addr +
|
||||
offsetof(struct target_rt_sigframe, uc.tuc_stack),
|
||||
0, get_sp_from_cpustate(env)) == -TARGET_EFAULT) {
|
||||
goto badframe;
|
||||
}
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return -TARGET_QEMU_ESIGRETURN;
|
||||
|
||||
|
@ -1,11 +1,6 @@
|
||||
# -*- Mode: makefile -*-
|
||||
#
|
||||
# sparc specific tweaks and masking out broken tests
|
||||
|
||||
# different from the other hangs:
|
||||
# tests/tcg/multiarch/linux-test.c:264: Value too large for defined data type (ret=-1, errno=92/Value too large for defined data type)
|
||||
run-linux-test: linux-test
|
||||
$(call skip-test, $<, "BROKEN")
|
||||
# sparc specific tweaks
|
||||
|
||||
# On Sparc64 Linux support 8k pages
|
||||
EXTRA_RUNS+=run-test-mmap-8192
|
||||
|
Loading…
x
Reference in New Issue
Block a user