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:
Peter Maydell 2021-05-18 16:17:22 +01:00
commit c313e52e64
48 changed files with 856 additions and 1667 deletions

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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:

View file

@ -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 */

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -32,7 +32,6 @@ subdir('mips')
subdir('ppc')
subdir('s390x')
subdir('sh4')
subdir('sparc64')
subdir('sparc')
subdir('x86_64')
subdir('xtensa')

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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(&current->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;
}

View file

@ -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;

View file

@ -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)
{

View file

@ -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;

View file

@ -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), &regs->tstate);
/* TODO: magic should contain PT_REG_MAGIC + %tt. */
__put_user(0, &regs->magic);
#else
__put_user(cpu_get_psr(env), &regs->psr);
#endif
__put_user(env->pc, &regs->pc);
__put_user(env->npc, &regs->npc);
__put_user(env->y, &regs->y);
for (i = 0; i < 8; i++) {
__put_user(env->gregs[i], &regs->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], &regs->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, &regs->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, &regs->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, &regs->y);
for (i = 0; i < 8; i++) {
__get_user(env->gregs[i], &regs->u_regs[i]);
}
for (i = 0; i < 8; i++) {
__get_user(env->regwptr[WREG_O0 + i], &regs->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)
{

View file

@ -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

View file

@ -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 */

View file

@ -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;
};

View file

@ -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 */

View file

@ -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"

View file

@ -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')
}

View file

@ -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"

View file

@ -1 +0,0 @@
#include "../sparc/sockbits.h"

View file

@ -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

View file

@ -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"

View file

@ -1 +0,0 @@
#include "../sparc/target_cpu.h"

View file

@ -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

View file

@ -1 +0,0 @@
#include "../sparc/target_fcntl.h"

View file

@ -1 +0,0 @@
#include "../sparc/target_signal.h"

View file

@ -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

View file

@ -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 */

View file

@ -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

View file

@ -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,

View file

@ -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

View file

@ -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)) {

View file

@ -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

View file

@ -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;

View file

@ -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