Revision 6049f4f8

b/Makefile.target
51 51
libobj-y += op_helper.o helper.o
52 52
libobj-$(CONFIG_NEED_MMU) += mmu.o
53 53
libobj-$(TARGET_ARM) += neon_helper.o iwmmxt_helper.o
54
libobj-$(TARGET_ALPHA) += alpha_palcode.o
55 54

  
56 55
# NOTE: the disassembler code is only needed for debugging
57 56
libobj-y += disas.o
......
312 311

  
313 312
obj-s390x-y = s390-virtio-bus.o s390-virtio.o
314 313

  
314
obj-alpha-y = alpha_palcode.o
315

  
315 316
main.o vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
316 317

  
317 318
vl.o: QEMU_CFLAGS+=$(SDL_CFLAGS)
b/hw/alpha_palcode.c
21 21
#include <stdlib.h>
22 22
#include <stdio.h>
23 23

  
24
#include "qemu.h"
25 24
#include "cpu.h"
26 25
#include "exec-all.h"
27 26

  
28
#if !defined (CONFIG_USER_ONLY)
29 27
/* Shared handlers */
30 28
static void pal_reset (CPUState *env);
31 29
/* Console handlers */
......
997 995
    uint64_t physical, page_size, end;
998 996
    int prot, zbits, ret;
999 997

  
1000
#if defined(CONFIG_USER_ONLY)
1001
        ret = 2;
1002
#else
1003
        ret = virtual_to_physical(env, &physical, &zbits, &prot,
1004
                                  address, mmu_idx, rw);
1005
#endif
998
    ret = virtual_to_physical(env, &physical, &zbits, &prot,
999
                              address, mmu_idx, rw);
1000

  
1006 1001
    switch (ret) {
1007 1002
    case 0:
1008 1003
        /* No fault */
......
1050 1045
    return ret;
1051 1046
}
1052 1047
#endif
1053

  
1054
#else /* !defined (CONFIG_USER_ONLY) */
1055
void pal_init (CPUState *env)
1056
{
1057
}
1058

  
1059
void call_pal (CPUState *env, int palcode)
1060
{
1061
    target_long ret;
1062

  
1063
    switch (palcode) {
1064
    case 0x80:
1065
        /* BPT */
1066
        qemu_log("BPT\n");
1067
        /* FIXME: Sends SIGTRAP, si_code=TRAP_BRKPT.  */
1068
        exit(1);
1069
    case 0x81:
1070
        /* BUGCHK */
1071
        qemu_log("BUGCHK\n");
1072
        /* FIXME: Sends SIGTRAP, si_code=SI_FAULT.  */
1073
        exit(1);
1074
    case 0x83:
1075
        /* CALLSYS */
1076
        qemu_log("CALLSYS n " TARGET_FMT_ld "\n", env->ir[0]);
1077
        ret = do_syscall(env, env->ir[IR_V0], env->ir[IR_A0], env->ir[IR_A1],
1078
                         env->ir[IR_A2], env->ir[IR_A3], env->ir[IR_A4],
1079
                         env->ir[IR_A5]);
1080
        if (ret >= 0) {
1081
            env->ir[IR_A3] = 0;
1082
            env->ir[IR_V0] = ret;
1083
        } else {
1084
            env->ir[IR_A3] = 1;
1085
            env->ir[IR_V0] = -ret;
1086
        }
1087
        break;
1088
    case 0x86:
1089
        /* IMB */
1090
        qemu_log("IMB\n");
1091
        /* ??? We can probably elide the code using page_unprotect that is
1092
           checking for self-modifying code.  Instead we could simply call
1093
           tb_flush here.  Until we work out the changes required to turn
1094
           off the extra write protection, this can be a no-op.  */
1095
        break;
1096
    case 0x9E:
1097
        /* RDUNIQUE */
1098
        qemu_log("RDUNIQUE: " TARGET_FMT_lx "\n", env->unique);
1099
        /* Handled in the translator for usermode.  */
1100
        abort();
1101
    case 0x9F:
1102
        /* WRUNIQUE */
1103
        qemu_log("WRUNIQUE: " TARGET_FMT_lx "\n", env->ir[IR_A0]);
1104
        /* Handled in the translator for usermode.  */
1105
        abort();
1106
    case 0xAA:
1107
        /* GENTRAP */
1108
        qemu_log("GENTRAP: " TARGET_FMT_lx "\n", env->ir[IR_A0]);
1109
        /* FIXME: This is supposed to send a signal:
1110
           SIGFPE:
1111
             GEN_INTOVF, GEN_INTDIV, GEN_FLTOVF, GEN_FLTDIV,
1112
             GEN_FLTUND, GEN_FLTINV, GEN_FLTINE, GEN_ROPRAND
1113
           SIGTRAP:
1114
             others
1115
           with various settings of si_code.  */
1116
        exit(1);
1117
    default:
1118
        qemu_log("%s: unhandled palcode %02x\n", __func__, palcode);
1119
        exit(1);
1120
    }
1121
}
1122
#endif
b/linux-user/alpha/target_signal.h
26 26
    return state->ir[IR_SP];
27 27
}
28 28

  
29
/* From <asm/gentrap.h>.  */
30
#define TARGET_GEN_INTOVF      -1      /* integer overflow */
31
#define TARGET_GEN_INTDIV      -2      /* integer division by zero */
32
#define TARGET_GEN_FLTOVF      -3      /* fp overflow */
33
#define TARGET_GEN_FLTDIV      -4      /* fp division by zero */
34
#define TARGET_GEN_FLTUND      -5      /* fp underflow */
35
#define TARGET_GEN_FLTINV      -6      /* invalid fp operand */
36
#define TARGET_GEN_FLTINE      -7      /* inexact fp operand */
37
#define TARGET_GEN_DECOVF      -8      /* decimal overflow (for COBOL??) */
38
#define TARGET_GEN_DECDIV      -9      /* decimal division by zero */
39
#define TARGET_GEN_DECINV      -10     /* invalid decimal operand */
40
#define TARGET_GEN_ROPRAND     -11     /* reserved operand */
41
#define TARGET_GEN_ASSERTERR   -12     /* assertion error */
42
#define TARGET_GEN_NULPTRERR   -13     /* null pointer error */
43
#define TARGET_GEN_STKOVF      -14     /* stack overflow */
44
#define TARGET_GEN_STRLENERR   -15     /* string length error */
45
#define TARGET_GEN_SUBSTRERR   -16     /* substring error */
46
#define TARGET_GEN_RANGERR     -17     /* range error */
47
#define TARGET_GEN_SUBRNG      -18
48
#define TARGET_GEN_SUBRNG1     -19
49
#define TARGET_GEN_SUBRNG2     -20
50
#define TARGET_GEN_SUBRNG3     -21
51
#define TARGET_GEN_SUBRNG4     -22
52
#define TARGET_GEN_SUBRNG5     -23
53
#define TARGET_GEN_SUBRNG6     -24
54
#define TARGET_GEN_SUBRNG7     -25
55

  
29 56
#endif /* TARGET_SIGNAL_H */
b/linux-user/main.c
2351 2351
{
2352 2352
    int trapnr;
2353 2353
    target_siginfo_t info;
2354
    abi_long sysret;
2354 2355

  
2355 2356
    while (1) {
2356 2357
        trapnr = cpu_alpha_exec (env);
......
2365 2366
            exit(1);
2366 2367
            break;
2367 2368
        case EXCP_ARITH:
2368
            fprintf(stderr, "Arithmetic trap.\n");
2369
            exit(1);
2369
            info.si_signo = TARGET_SIGFPE;
2370
            info.si_errno = 0;
2371
            info.si_code = TARGET_FPE_FLTINV;
2372
            info._sifields._sigfault._addr = env->pc;
2373
            queue_signal(env, info.si_signo, &info);
2370 2374
            break;
2371 2375
        case EXCP_HW_INTERRUPT:
2372 2376
            fprintf(stderr, "External interrupt. Exit\n");
2373 2377
            exit(1);
2374 2378
            break;
2375 2379
        case EXCP_DFAULT:
2376
            fprintf(stderr, "MMU data fault\n");
2377
            exit(1);
2380
            info.si_signo = TARGET_SIGSEGV;
2381
            info.si_errno = 0;
2382
            info.si_code = 0;  /* ??? SEGV_MAPERR vs SEGV_ACCERR.  */
2383
            info._sifields._sigfault._addr = env->pc;
2384
            queue_signal(env, info.si_signo, &info);
2378 2385
            break;
2379 2386
        case EXCP_DTB_MISS_PAL:
2380 2387
            fprintf(stderr, "MMU data TLB miss in PALcode\n");
......
2393 2400
            exit(1);
2394 2401
            break;
2395 2402
        case EXCP_UNALIGN:
2396
            fprintf(stderr, "Unaligned access\n");
2397
            exit(1);
2403
            info.si_signo = TARGET_SIGBUS;
2404
            info.si_errno = 0;
2405
            info.si_code = TARGET_BUS_ADRALN;
2406
            info._sifields._sigfault._addr = env->pc;
2407
            queue_signal(env, info.si_signo, &info);
2398 2408
            break;
2399 2409
        case EXCP_OPCDEC:
2400
            fprintf(stderr, "Invalid instruction\n");
2401
            exit(1);
2410
        do_sigill:
2411
            info.si_signo = TARGET_SIGILL;
2412
            info.si_errno = 0;
2413
            info.si_code = TARGET_ILL_ILLOPC;
2414
            info._sifields._sigfault._addr = env->pc;
2415
            queue_signal(env, info.si_signo, &info);
2402 2416
            break;
2403 2417
        case EXCP_FEN:
2404
            fprintf(stderr, "Floating-point not allowed\n");
2405
            exit(1);
2418
            /* No-op.  Linux simply re-enables the FPU.  */
2406 2419
            break;
2407 2420
        case EXCP_CALL_PAL ... (EXCP_CALL_PALP - 1):
2408
            call_pal(env, (trapnr >> 6) | 0x80);
2421
            switch ((trapnr >> 6) | 0x80) {
2422
            case 0x80:
2423
                /* BPT */
2424
                info.si_signo = TARGET_SIGTRAP;
2425
                info.si_errno = 0;
2426
                info.si_code = TARGET_TRAP_BRKPT;
2427
                info._sifields._sigfault._addr = env->pc;
2428
                queue_signal(env, info.si_signo, &info);
2429
                break;
2430
            case 0x81:
2431
                /* BUGCHK */
2432
                info.si_signo = TARGET_SIGTRAP;
2433
                info.si_errno = 0;
2434
                info.si_code = 0;
2435
                info._sifields._sigfault._addr = env->pc;
2436
                queue_signal(env, info.si_signo, &info);
2437
                break;
2438
            case 0x83:
2439
                /* CALLSYS */
2440
                trapnr = env->ir[IR_V0];
2441
                sysret = do_syscall(env, trapnr,
2442
                                    env->ir[IR_A0], env->ir[IR_A1],
2443
                                    env->ir[IR_A2], env->ir[IR_A3],
2444
                                    env->ir[IR_A4], env->ir[IR_A5]);
2445
		if (trapnr != TARGET_NR_sigreturn
2446
                    && trapnr != TARGET_NR_rt_sigreturn) {
2447
                    env->ir[IR_V0] = (sysret < 0 ? -sysret : sysret);
2448
                    env->ir[IR_A3] = (sysret < 0);
2449
                }
2450
                break;
2451
            case 0x86:
2452
                /* IMB */
2453
                /* ??? We can probably elide the code using page_unprotect
2454
                   that is checking for self-modifying code.  Instead we
2455
                   could simply call tb_flush here.  Until we work out the
2456
                   changes required to turn off the extra write protection,
2457
                   this can be a no-op.  */
2458
                break;
2459
            case 0x9E:
2460
                /* RDUNIQUE */
2461
                /* Handled in the translator for usermode.  */
2462
                abort();
2463
            case 0x9F:
2464
                /* WRUNIQUE */
2465
                /* Handled in the translator for usermode.  */
2466
                abort();
2467
            case 0xAA:
2468
                /* GENTRAP */
2469
                info.si_signo = TARGET_SIGFPE;
2470
                switch (env->ir[IR_A0]) {
2471
                case TARGET_GEN_INTOVF:
2472
                    info.si_code = TARGET_FPE_INTOVF;
2473
                    break;
2474
                case TARGET_GEN_INTDIV:
2475
                    info.si_code = TARGET_FPE_INTDIV;
2476
                    break;
2477
                case TARGET_GEN_FLTOVF:
2478
                    info.si_code = TARGET_FPE_FLTOVF;
2479
                    break;
2480
                case TARGET_GEN_FLTUND:
2481
                    info.si_code = TARGET_FPE_FLTUND;
2482
                    break;
2483
                case TARGET_GEN_FLTINV:
2484
                    info.si_code = TARGET_FPE_FLTINV;
2485
                    break;
2486
                case TARGET_GEN_FLTINE:
2487
                    info.si_code = TARGET_FPE_FLTRES;
2488
                    break;
2489
                case TARGET_GEN_ROPRAND:
2490
                    info.si_code = 0;
2491
                    break;
2492
                default:
2493
                    info.si_signo = TARGET_SIGTRAP;
2494
                    info.si_code = 0;
2495
                    break;
2496
                }
2497
                info.si_errno = 0;
2498
                info._sifields._sigfault._addr = env->pc;
2499
                queue_signal(env, info.si_signo, &info);
2500
                break;
2501
            default:
2502
                goto do_sigill;
2503
            }
2409 2504
            break;
2410 2505
        case EXCP_CALL_PALP ... (EXCP_CALL_PALE - 1):
2411
            fprintf(stderr, "Privileged call to PALcode\n");
2412
            exit(1);
2413
            break;
2506
            goto do_sigill;
2414 2507
        case EXCP_DEBUG:
2415
            {
2416
                int sig;
2417

  
2418
                sig = gdb_handlesig (env, TARGET_SIGTRAP);
2419
                if (sig)
2420
                  {
2421
                    info.si_signo = sig;
2422
                    info.si_errno = 0;
2423
                    info.si_code = TARGET_TRAP_BRKPT;
2424
                    queue_signal(env, info.si_signo, &info);
2425
                  }
2508
            info.si_signo = gdb_handlesig (env, TARGET_SIGTRAP);
2509
            if (info.si_signo) {
2510
                info.si_errno = 0;
2511
                info.si_code = TARGET_TRAP_BRKPT;
2512
                queue_signal(env, info.si_signo, &info);
2426 2513
            }
2427 2514
            break;
2428 2515
        default:
b/linux-user/signal.c
4410 4410
    return 0;
4411 4411
}
4412 4412

  
4413
#elif defined(TARGET_ALPHA)
4414

  
4415
struct target_sigcontext {
4416
    abi_long sc_onstack;
4417
    abi_long sc_mask;
4418
    abi_long sc_pc;
4419
    abi_long sc_ps;
4420
    abi_long sc_regs[32];
4421
    abi_long sc_ownedfp;
4422
    abi_long sc_fpregs[32];
4423
    abi_ulong sc_fpcr;
4424
    abi_ulong sc_fp_control;
4425
    abi_ulong sc_reserved1;
4426
    abi_ulong sc_reserved2;
4427
    abi_ulong sc_ssize;
4428
    abi_ulong sc_sbase;
4429
    abi_ulong sc_traparg_a0;
4430
    abi_ulong sc_traparg_a1;
4431
    abi_ulong sc_traparg_a2;
4432
    abi_ulong sc_fp_trap_pc;
4433
    abi_ulong sc_fp_trigger_sum;
4434
    abi_ulong sc_fp_trigger_inst;
4435
};
4436

  
4437
struct target_ucontext {
4438
    abi_ulong uc_flags;
4439
    abi_ulong uc_link;
4440
    abi_ulong uc_osf_sigmask;
4441
    target_stack_t uc_stack;
4442
    struct target_sigcontext uc_mcontext;
4443
    target_sigset_t uc_sigmask;
4444
};
4445

  
4446
struct target_sigframe {
4447
    struct target_sigcontext sc;
4448
    unsigned int retcode[3];
4449
};
4450

  
4451
struct target_rt_sigframe {
4452
    target_siginfo_t info;
4453
    struct target_ucontext uc;
4454
    unsigned int retcode[3];
4455
};
4456

  
4457
#define INSN_MOV_R30_R16        0x47fe0410
4458
#define INSN_LDI_R0             0x201f0000
4459
#define INSN_CALLSYS            0x00000083
4460

  
4461
static int setup_sigcontext(struct target_sigcontext *sc, CPUState *env,
4462
                            abi_ulong frame_addr, target_sigset_t *set)
4463
{
4464
    int i, err = 0;
4465

  
4466
    err |= __put_user(on_sig_stack(frame_addr), &sc->sc_onstack);
4467
    err |= __put_user(set->sig[0], &sc->sc_mask);
4468
    err |= __put_user(env->pc, &sc->sc_pc);
4469
    err |= __put_user(8, &sc->sc_ps);
4470

  
4471
    for (i = 0; i < 31; ++i) {
4472
        err |= __put_user(env->ir[i], &sc->sc_regs[i]);
4473
    }
4474
    err |= __put_user(0, &sc->sc_regs[31]);
4475

  
4476
    for (i = 0; i < 31; ++i) {
4477
        err |= __put_user(env->fir[i], &sc->sc_fpregs[i]);
4478
    }
4479
    err |= __put_user(0, &sc->sc_fpregs[31]);
4480
    err |= __put_user(cpu_alpha_load_fpcr(env), &sc->sc_fpcr);
4481

  
4482
    err |= __put_user(0, &sc->sc_traparg_a0); /* FIXME */
4483
    err |= __put_user(0, &sc->sc_traparg_a1); /* FIXME */
4484
    err |= __put_user(0, &sc->sc_traparg_a2); /* FIXME */
4485

  
4486
    return err;
4487
}
4488

  
4489
static int restore_sigcontext(CPUState *env, struct target_sigcontext *sc)
4490
{
4491
    uint64_t fpcr;
4492
    int i, err = 0;
4493

  
4494
    err |= __get_user(env->pc, &sc->sc_pc);
4495

  
4496
    for (i = 0; i < 31; ++i) {
4497
        err |= __get_user(env->ir[i], &sc->sc_regs[i]);
4498
    }
4499
    for (i = 0; i < 31; ++i) {
4500
        err |= __get_user(env->fir[i], &sc->sc_fpregs[i]);
4501
    }
4502

  
4503
    err |= __get_user(fpcr, &sc->sc_fpcr);
4504
    cpu_alpha_store_fpcr(env, fpcr);
4505

  
4506
    return err;
4507
}
4508

  
4509
static inline abi_ulong get_sigframe(struct target_sigaction *sa,
4510
                                     CPUState *env, unsigned long framesize)
4511
{
4512
    abi_ulong sp = env->ir[IR_SP];
4513

  
4514
    /* This is the X/Open sanctioned signal stack switching.  */
4515
    if ((sa->sa_flags & TARGET_SA_ONSTACK) != 0 && !sas_ss_flags(sp)) {
4516
        sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
4517
    }
4518
    return (sp - framesize) & -32;
4519
}
4520

  
4521
static void setup_frame(int sig, struct target_sigaction *ka,
4522
                        target_sigset_t *set, CPUState *env)
4523
{
4524
    abi_ulong frame_addr, r26;
4525
    struct target_sigframe *frame;
4526
    int err = 0;
4527

  
4528
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
4529
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4530
        goto give_sigsegv;
4531
    }
4532

  
4533
    err |= setup_sigcontext(&frame->sc, env, frame_addr, set);
4534

  
4535
    if (ka->sa_restorer) {
4536
        r26 = ka->sa_restorer;
4537
    } else {
4538
        err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
4539
        err |= __put_user(INSN_LDI_R0 + TARGET_NR_sigreturn,
4540
                          &frame->retcode[1]);
4541
        err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
4542
        /* imb() */
4543
        r26 = frame_addr;
4544
    }
4545

  
4546
    unlock_user_struct(frame, frame_addr, 1);
4547

  
4548
    if (err) {
4549
    give_sigsegv:
4550
        if (sig == TARGET_SIGSEGV) {
4551
            ka->_sa_handler = TARGET_SIG_DFL;
4552
        }
4553
        force_sig(TARGET_SIGSEGV);
4554
    }
4555

  
4556
    env->ir[IR_RA] = r26;
4557
    env->ir[IR_PV] = env->pc = ka->_sa_handler;
4558
    env->ir[IR_A0] = sig;
4559
    env->ir[IR_A1] = 0;
4560
    env->ir[IR_A2] = frame_addr + offsetof(struct target_sigframe, sc);
4561
    env->ir[IR_SP] = frame_addr;
4562
}
4563

  
4564
static void setup_rt_frame(int sig, struct target_sigaction *ka,
4565
                           target_siginfo_t *info,
4566
			   target_sigset_t *set, CPUState *env)
4567
{
4568
    abi_ulong frame_addr, r26;
4569
    struct target_rt_sigframe *frame;
4570
    int i, err = 0;
4571

  
4572
    frame_addr = get_sigframe(ka, env, sizeof(*frame));
4573
    if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
4574
        goto give_sigsegv;
4575
    }
4576

  
4577
    err |= copy_siginfo_to_user(&frame->info, info);
4578

  
4579
    err |= __put_user(0, &frame->uc.uc_flags);
4580
    err |= __put_user(0, &frame->uc.uc_link);
4581
    err |= __put_user(set->sig[0], &frame->uc.uc_osf_sigmask);
4582
    err |= __put_user(target_sigaltstack_used.ss_sp,
4583
                      &frame->uc.uc_stack.ss_sp);
4584
    err |= __put_user(sas_ss_flags(env->ir[IR_SP]),
4585
                      &frame->uc.uc_stack.ss_flags);
4586
    err |= __put_user(target_sigaltstack_used.ss_size,
4587
                      &frame->uc.uc_stack.ss_size);
4588
    err |= setup_sigcontext(&frame->uc.uc_mcontext, env, frame_addr, set);
4589
    for (i = 0; i < TARGET_NSIG_WORDS; ++i) {
4590
        err |= __put_user(set->sig[i], &frame->uc.uc_sigmask.sig[i]);
4591
    }
4592

  
4593
    if (ka->sa_restorer) {
4594
        r26 = ka->sa_restorer;
4595
    } else {
4596
        err |= __put_user(INSN_MOV_R30_R16, &frame->retcode[0]);
4597
        err |= __put_user(INSN_LDI_R0 + TARGET_NR_rt_sigreturn,
4598
                          &frame->retcode[1]);
4599
        err |= __put_user(INSN_CALLSYS, &frame->retcode[2]);
4600
        /* imb(); */
4601
        r26 = frame_addr;
4602
    }
4603

  
4604
    if (err) {
4605
    give_sigsegv:
4606
       if (sig == TARGET_SIGSEGV) {
4607
            ka->_sa_handler = TARGET_SIG_DFL;
4608
        }
4609
        force_sig(TARGET_SIGSEGV);
4610
    }
4611

  
4612
    env->ir[IR_RA] = r26;
4613
    env->ir[IR_PV] = env->pc = ka->_sa_handler;
4614
    env->ir[IR_A0] = sig;
4615
    env->ir[IR_A1] = frame_addr + offsetof(struct target_rt_sigframe, info);
4616
    env->ir[IR_A2] = frame_addr + offsetof(struct target_rt_sigframe, uc);
4617
    env->ir[IR_SP] = frame_addr;
4618
}
4619

  
4620
long do_sigreturn(CPUState *env)
4621
{
4622
    struct target_sigcontext *sc;
4623
    abi_ulong sc_addr = env->ir[IR_A0];
4624
    target_sigset_t target_set;
4625
    sigset_t set;
4626

  
4627
    if (!lock_user_struct(VERIFY_READ, sc, sc_addr, 1)) {
4628
        goto badframe;
4629
    }
4630

  
4631
    target_sigemptyset(&target_set);
4632
    if (__get_user(target_set.sig[0], &sc->sc_mask)) {
4633
        goto badframe;
4634
    }
4635

  
4636
    target_to_host_sigset_internal(&set, &target_set);
4637
    sigprocmask(SIG_SETMASK, &set, NULL);
4638

  
4639
    if (restore_sigcontext(env, sc)) {
4640
        goto badframe;
4641
    }
4642
    unlock_user_struct(sc, sc_addr, 0);
4643
    return env->ir[IR_V0];
4644

  
4645
 badframe:
4646
    unlock_user_struct(sc, sc_addr, 0);
4647
    force_sig(TARGET_SIGSEGV);
4648
}
4649

  
4650
long do_rt_sigreturn(CPUState *env)
4651
{
4652
    abi_ulong frame_addr = env->ir[IR_A0];
4653
    struct target_rt_sigframe *frame;
4654
    sigset_t set;
4655

  
4656
    if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1)) {
4657
        goto badframe;
4658
    }
4659
    target_to_host_sigset(&set, &frame->uc.uc_sigmask);
4660
    sigprocmask(SIG_SETMASK, &set, NULL);
4661

  
4662
    if (restore_sigcontext(env, &frame->uc.uc_mcontext)) {
4663
        goto badframe;
4664
    }
4665
    if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe,
4666
                                             uc.uc_stack),
4667
                       0, env->ir[IR_SP]) == -EFAULT) {
4668
        goto badframe;
4669
    }
4670

  
4671
    unlock_user_struct(frame, frame_addr, 0);
4672
    return env->ir[IR_V0];
4673

  
4674

  
4675
 badframe:
4676
    unlock_user_struct(frame, frame_addr, 0);
4677
    force_sig(TARGET_SIGSEGV);
4678
}
4679

  
4413 4680
#else
4414 4681

  
4415 4682
static void setup_frame(int sig, struct target_sigaction *ka,
b/linux-user/syscall.c
4775 4775
#ifdef TARGET_NR_sigaction
4776 4776
    case TARGET_NR_sigaction:
4777 4777
        {
4778
#if !defined(TARGET_MIPS)
4778
#if defined(TARGET_ALPHA)
4779
            struct target_sigaction act, oact, *pact = 0;
4779 4780
            struct target_old_sigaction *old_act;
4780
            struct target_sigaction act, oact, *pact;
4781 4781
            if (arg2) {
4782 4782
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4783 4783
                    goto efault;
4784 4784
                act._sa_handler = old_act->_sa_handler;
4785 4785
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4786 4786
                act.sa_flags = old_act->sa_flags;
4787
                act.sa_restorer = old_act->sa_restorer;
4787
                act.sa_restorer = 0;
4788 4788
                unlock_user_struct(old_act, arg2, 0);
4789 4789
                pact = &act;
4790
            } else {
4791
                pact = NULL;
4792 4790
            }
4793 4791
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4794 4792
            if (!is_error(ret) && arg3) {
......
4797 4795
                old_act->_sa_handler = oact._sa_handler;
4798 4796
                old_act->sa_mask = oact.sa_mask.sig[0];
4799 4797
                old_act->sa_flags = oact.sa_flags;
4800
                old_act->sa_restorer = oact.sa_restorer;
4801 4798
                unlock_user_struct(old_act, arg3, 1);
4802 4799
            }
4803
#else
4800
#elif defined(TARGET_MIPS)
4804 4801
	    struct target_sigaction act, oact, *pact, *old_act;
4805 4802

  
4806 4803
	    if (arg2) {
......
4828 4825
		old_act->sa_mask.sig[3] = 0;
4829 4826
		unlock_user_struct(old_act, arg3, 1);
4830 4827
	    }
4828
#else
4829
            struct target_old_sigaction *old_act;
4830
            struct target_sigaction act, oact, *pact;
4831
            if (arg2) {
4832
                if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1))
4833
                    goto efault;
4834
                act._sa_handler = old_act->_sa_handler;
4835
                target_siginitset(&act.sa_mask, old_act->sa_mask);
4836
                act.sa_flags = old_act->sa_flags;
4837
                act.sa_restorer = old_act->sa_restorer;
4838
                unlock_user_struct(old_act, arg2, 0);
4839
                pact = &act;
4840
            } else {
4841
                pact = NULL;
4842
            }
4843
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4844
            if (!is_error(ret) && arg3) {
4845
                if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0))
4846
                    goto efault;
4847
                old_act->_sa_handler = oact._sa_handler;
4848
                old_act->sa_mask = oact.sa_mask.sig[0];
4849
                old_act->sa_flags = oact.sa_flags;
4850
                old_act->sa_restorer = oact.sa_restorer;
4851
                unlock_user_struct(old_act, arg3, 1);
4852
            }
4831 4853
#endif
4832 4854
        }
4833 4855
        break;
4834 4856
#endif
4835 4857
    case TARGET_NR_rt_sigaction:
4836 4858
        {
4859
#if defined(TARGET_ALPHA)
4860
            struct target_sigaction act, oact, *pact = 0;
4861
            struct target_rt_sigaction *rt_act;
4862
            /* ??? arg4 == sizeof(sigset_t).  */
4863
            if (arg2) {
4864
                if (!lock_user_struct(VERIFY_READ, rt_act, arg2, 1))
4865
                    goto efault;
4866
                act._sa_handler = rt_act->_sa_handler;
4867
                act.sa_mask = rt_act->sa_mask;
4868
                act.sa_flags = rt_act->sa_flags;
4869
                act.sa_restorer = arg5;
4870
                unlock_user_struct(rt_act, arg2, 0);
4871
                pact = &act;
4872
            }
4873
            ret = get_errno(do_sigaction(arg1, pact, &oact));
4874
            if (!is_error(ret) && arg3) {
4875
                if (!lock_user_struct(VERIFY_WRITE, rt_act, arg3, 0))
4876
                    goto efault;
4877
                rt_act->_sa_handler = oact._sa_handler;
4878
                rt_act->sa_mask = oact.sa_mask;
4879
                rt_act->sa_flags = oact.sa_flags;
4880
                unlock_user_struct(rt_act, arg3, 1);
4881
            }
4882
#else
4837 4883
            struct target_sigaction *act;
4838 4884
            struct target_sigaction *oact;
4839 4885

  
......
4855 4901
                unlock_user_struct(act, arg2, 0);
4856 4902
            if (oact)
4857 4903
                unlock_user_struct(oact, arg3, 1);
4904
#endif
4858 4905
        }
4859 4906
        break;
4860 4907
#ifdef TARGET_NR_sgetmask /* not on alpha */
b/linux-user/syscall_defs.h
472 472

  
473 473
#endif
474 474

  
475
#if defined(TARGET_MIPS)
475
#if defined(TARGET_ALPHA)
476
struct target_old_sigaction {
477
    abi_ulong _sa_handler;
478
    abi_ulong sa_mask;
479
    abi_ulong sa_flags;
480
};
481

  
482
struct target_rt_sigaction {
483
    abi_ulong _sa_handler;
484
    abi_ulong sa_flags;
485
    target_sigset_t sa_mask;
486
};
476 487

  
488
/* This is the struct used inside the kernel.  The ka_restorer
489
   field comes from the 5th argument to sys_rt_sigaction.  */
490
struct target_sigaction {
491
    abi_ulong _sa_handler;
492
    abi_ulong sa_flags;
493
    target_sigset_t sa_mask;
494
    abi_ulong sa_restorer;
495
};
496
#elif defined(TARGET_MIPS)
477 497
struct target_sigaction {
478 498
	uint32_t	sa_flags;
479 499
#if defined(TARGET_ABI_MIPSN32)
......
483 503
#endif
484 504
	target_sigset_t	sa_mask;
485 505
};
486

  
487 506
#else
488 507
struct target_old_sigaction {
489 508
        abi_ulong _sa_handler;
b/target-alpha/cpu.h
511 511
void cpu_alpha_store_fpcr (CPUState *env, uint64_t val);
512 512
int cpu_alpha_mfpr (CPUState *env, int iprn, uint64_t *valp);
513 513
int cpu_alpha_mtpr (CPUState *env, int iprn, uint64_t val, uint64_t *oldvalp);
514
void pal_init (CPUState *env);
515 514
#if !defined (CONFIG_USER_ONLY)
515
void pal_init (CPUState *env);
516 516
void call_pal (CPUState *env);
517
#else
518
void call_pal (CPUState *env, int palcode);
519 517
#endif
520 518

  
521 519
static inline void cpu_pc_from_tb(CPUState *env, TranslationBlock *tb)
b/target-alpha/translate.c
3094 3094
    env->ps |= 1 << 3;
3095 3095
    cpu_alpha_store_fpcr(env, (FPCR_INVD | FPCR_DZED | FPCR_OVFD
3096 3096
                               | FPCR_UNFD | FPCR_INED | FPCR_DNOD));
3097
#endif
3097
#else
3098 3098
    pal_init(env);
3099
#endif
3099 3100

  
3100 3101
    /* Initialize IPR */
3101 3102
#if defined (CONFIG_USER_ONLY)

Also available in: Unified diff