Revision 67867308

b/Changelog
9 9
  - IRET and INT fixes in VM86 mode with IOPL=3
10 10
  - Port I/Os use TSS io map
11 11
  - Full task switching/task gate support
12
  - added verr, verw, arpl
12
  - added verr, verw, arpl, fcmovxx
13
  - PowerPC target support (Jocelyn Mayer)
13 14

  
14 15
version 0.5.0:
15 16
  
b/Makefile.target
146 146
LIBOBJS+=helper.o helper2.o
147 147
endif
148 148

  
149
ifeq ($(TARGET_ARCH), ppc)
150
LIBOBJS+=helper.o
151
endif
152

  
149 153
# NOTE: the disassembler code is only needed for debugging
150 154
LIBOBJS+=disas.o 
151 155
ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
b/configure
27 27
make="make"
28 28
strip="strip"
29 29
cpu=`uname -m`
30
target_list="i386-user i386 i386-softmmu arm-user sparc-user"
30
target_list="i386-user i386 i386-softmmu arm-user sparc-user ppc-user"
31 31
case "$cpu" in
32 32
  i386|i486|i586|i686|i86pc|BePC)
33 33
    cpu="i386"
......
322 322
target_cpu=`echo $target | cut -d '-' -f 1`
323 323
target_bigendian="no"
324 324
[ "$target_cpu" = "sparc" ] && target_bigendian=yes
325
[ "$target_cpu" = "ppc" ] && target_bigendian=yes
325 326
target_softmmu="no"
326 327
if expr $target : '.*-softmmu' > /dev/null ; then
327 328
  target_softmmu="yes"
......
358 359
  echo "TARGET_ARCH=sparc" >> $config_mak
359 360
  echo "#define TARGET_ARCH \"sparc\"" >> $config_h
360 361
  echo "#define TARGET_SPARC 1" >> $config_h
362
elif test "$target_cpu" = "ppc" ; then
363
  echo "TARGET_ARCH=ppc" >> $config_mak
364
  echo "#define TARGET_ARCH \"ppc\"" >> $config_h
365
  echo "#define TARGET_PPC 1" >> $config_h
361 366
else
362 367
  echo "Unsupported target CPU"
363 368
  exit 1
b/cpu-all.h
395 395
#define cpu_interrupt cpu_sparc_interrupt
396 396
#define cpu_signal_handler cpu_sparc_signal_handler
397 397

  
398
#elif defined(TARGET_PPC)
399

  
400
#define CPUState CPUPPCState
401
#define cpu_init cpu_ppc_init
402
#define cpu_exec cpu_ppc_exec
403
#define cpu_gen_code cpu_ppc_gen_code
404
#define cpu_interrupt cpu_ppc_interrupt
405
#define cpu_signal_handler cpu_ppc_signal_handler
406

  
398 407
#else
399 408

  
400 409
#error unsupported target CPU
b/cpu-exec.c
133 133
        env->cpsr = psr & ~0xf0000000;
134 134
    }
135 135
#elif defined(TARGET_SPARC)
136
#elif defined(TARGET_PPC)
136 137
#else
137 138
#error unsupported target CPU
138 139
#endif
......
228 229
                    env->cpsr &= ~0xf0000000;
229 230
#elif defined(TARGET_SPARC)
230 231
                    cpu_sparc_dump_state (env, logfile, 0);
232
#elif defined(TARGET_PPC)
233
                    cpu_ppc_dump_state(env, logfile, 0);
231 234
#else
232 235
#error unsupported target CPU 
233 236
#endif
......
246 249
                cs_base = 0;
247 250
                pc = (uint8_t *)env->regs[15];
248 251
#elif defined(TARGET_SPARC)
249
				flags = 0;
250
				cs_base = 0;
251
				if (env->npc) {
252
					env->pc = env->npc;
253
					env->npc = 0;
254
				}
255
				pc = (uint8_t *) env->pc;
252
                flags = 0;
253
                cs_base = 0;
254
                if (env->npc) {
255
                    env->pc = env->npc;
256
                    env->npc = 0;
257
                }
258
                pc = (uint8_t *) env->pc;
259
#elif defined(TARGET_PPC)
260
                flags = 0;
261
                cs_base = 0;
262
                pc = (uint8_t *)env->nip;
256 263
#else
257 264
#error unsupported CPU
258 265
#endif
......
376 383
#elif defined(TARGET_ARM)
377 384
    env->cpsr = compute_cpsr();
378 385
#elif defined(TARGET_SPARC)
386
#elif defined(TARGET_PPC)
379 387
#else
380 388
#error unsupported target CPU
381 389
#endif
......
513 521
{
514 522
	return 0;
515 523
}
524
#elif defined (TARGET_PPC)
525
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
526
                                    int is_write, sigset_t *old_set)
527
{
528
    TranslationBlock *tb;
529
    
530
#if 0
531
    if (cpu_single_env)
532
        env = cpu_single_env; /* XXX: find a correct solution for multithread */
533
#endif
534
#if defined(DEBUG_SIGNAL)
535
    printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", 
536
           pc, address, is_write, *(unsigned long *)old_set);
537
#endif
538
    /* XXX: locking issue */
539
    if (is_write && page_unprotect(address)) {
540
        return 1;
541
    }
542

  
543
    /* now we have a real cpu fault */
544
    tb = tb_find_pc(pc);
545
    if (tb) {
546
        /* the PC is inside the translated code. It means that we have
547
           a virtual CPU fault */
548
        cpu_restore_state(tb, env, pc);
549
    }
550
#if 0
551
    printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n", 
552
           env->eip, env->cr[2], env->error_code);
553
#endif
554
    /* we restore the process signal mask as the sigreturn should
555
       do it (XXX: use sigsetjmp) */
556
    sigprocmask(SIG_SETMASK, old_set, NULL);
557
    raise_exception_err(EXCP_PROGRAM, env->error_code);
558
    /* never comes here */
559
    return 1;
560
}
516 561
#else
517 562
#error unsupported target CPU
518 563
#endif
b/disas.c
171 171
	print_insn = print_insn_arm;
172 172
#elif defined(TARGET_SPARC)
173 173
	print_insn = print_insn_sparc;
174
#elif defined(TARGET_PPC)
175
	print_insn = print_insn_ppc;
174 176
#else
175 177
	fprintf(out, "Asm output not supported on this arch\n");
176 178
	return;
b/dyngen-exec.h
17 17
 * License along with this library; if not, write to the Free Software
18 18
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 19
 */
20
#if !defined(__DYNGEN_EXEC_H__)
21
#define __DYNGEN_EXEC_H__
22

  
20 23
typedef unsigned char uint8_t;
21 24
typedef unsigned short uint16_t;
22 25
typedef unsigned int uint32_t;
......
27 30
typedef signed int int32_t;
28 31
typedef signed long long int64_t;
29 32

  
33
#define INT8_MIN		(-128)
34
#define INT16_MIN		(-32767-1)
35
#define INT32_MIN		(-2147483647-1)
36
#define INT64_MIN		(-(int64_t)(9223372036854775807)-1)
37
#define INT8_MAX		(127)
38
#define INT16_MAX		(32767)
39
#define INT32_MAX		(2147483647)
40
#define INT64_MAX		((int64_t)(9223372036854775807))
41
#define UINT8_MAX		(255)
42
#define UINT16_MAX		(65535)
43
#define UINT32_MAX		(4294967295U)
44
#define UINT64_MAX		((uint64_t)(18446744073709551615))
45

  
30 46
#define bswap32(x) \
31 47
({ \
32 48
	uint32_t __x = (x); \
......
191 207
#ifdef __mc68000
192 208
#define EXIT_TB() asm volatile ("rts")
193 209
#endif
210

  
211
#endif /* !defined(__DYNGEN_EXEC_H__) */
b/linux-user/elfload.c
104 104

  
105 105
#endif
106 106

  
107
#ifdef TARGET_PPC
108

  
109
#define ELF_START_MMAP 0x80000000
110

  
111
#define elf_check_arch(x) ( (x) == EM_PPC )
112

  
113
#define ELF_CLASS	ELFCLASS32
114
#ifdef TARGET_WORDS_BIGENDIAN
115
#define ELF_DATA	ELFDATA2MSB
116
#else
117
#define ELF_DATA	ELFDATA2LSB
118
#endif
119
#define ELF_ARCH	EM_PPC
120

  
121
/* Note that isn't exactly what regular kernel does
122
 * but this is what the ABI wants and is needed to allow
123
 * execution of PPC BSD programs.
124
 */
125
#define ELF_PLAT_INIT(_r)                                  \
126
do {                                                       \
127
   unsigned long *pos = (unsigned long *)bprm->p, tmp = 1; \
128
    _r->gpr[3] = bprm->argc;                               \
129
    _r->gpr[4] = (unsigned long)++pos;                     \
130
    for (; tmp != 0; pos++)                                \
131
        tmp = *pos;                                        \
132
     _r->gpr[5] = (unsigned long)pos;                      \
133
} while (0)
134

  
135
static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
136
{
137
    _regs->msr = 1 << MSR_PR; /* Set user mode */
138
    _regs->gpr[1] = infop->start_stack;
139
    _regs->nip = infop->entry;
140
}
141

  
142
#define USE_ELF_CORE_DUMP
143
#define ELF_EXEC_PAGESIZE	4096
144

  
145
#endif
146

  
107 147
#include "elf.h"
108 148

  
109 149
/*
b/linux-user/main.c
324 324

  
325 325
#endif
326 326

  
327
#ifdef TARGET_PPC
328

  
329
void cpu_loop(CPUPPCState *env)
330
{
331
    int trapnr;
332
    target_siginfo_t info;
333
    
334
    for(;;) {
335
        trapnr = cpu_ppc_exec(env);
336
        switch(trapnr) {
337
        case EXCP_NONE:
338
        case EXCP_INTERRUPT:
339
        case EXCP_MTMSR: /* mtmsr instruction:               */
340
        case EXCP_BRANCH: /* branch instruction               */
341
            /* Single step mode */
342
            break;
343
#if 0
344
        case EXCP_RESET: /* System reset                     */
345
            fprintf(stderr, "RESET asked... Stop emulation\n");
346
            cpu_ppc_dump_state(env, stderr, 0);
347
            abort();
348
#endif
349
        case EXCP_MACHINE_CHECK: /* Machine check exception          */
350
            fprintf(stderr, "Machine check exeption... "
351
                    "See you in kernel code !\n");
352
            cpu_ppc_dump_state(env, stderr, 0);
353
            abort();
354
        case EXCP_DSI:  /* Impossible memory access         */
355
            fprintf(stderr, "Invalid memory access\n");
356
            info.si_signo = SIGSEGV;
357
            info.si_errno = 0;
358
            info.si_code = TARGET_ILL_ILLOPN;
359
            info._sifields._sigfault._addr = env->nip;
360
            queue_signal(info.si_signo, &info);
361
            break;
362
        case EXCP_ISI: /* Impossible instruction fetch     */
363
            fprintf(stderr, "Invalid instruction fetch\n");
364
            info.si_signo = SIGBUS;
365
            info.si_errno = 0;
366
            info.si_code = TARGET_ILL_ILLOPN;
367
            info._sifields._sigfault._addr = env->nip;
368
            queue_signal(info.si_signo, &info);
369
            break;
370
        case EXCP_EXTERNAL: /* External interruption            */
371
            fprintf(stderr, "External access exeption\n");
372
            cpu_ppc_dump_state(env, stderr, 0);
373
            abort();
374
        case EXCP_ALIGN: /* Alignment exception              */
375
            fprintf(stderr, "Alignment exception\n");
376
            cpu_ppc_dump_state(env, stderr, 0);
377
            abort();
378
        case EXCP_PROGRAM: /* Program exception                */
379
            fprintf(stderr, "Program exception\n");
380
            cpu_ppc_dump_state(env, stderr, 0);
381
            abort();
382
            break;
383
        /* Trap */
384
        case EXCP_TRAP: /* Trap                             */
385
        case EXCP_TRACE: /* Trace exception (optional)       */
386
            info.si_signo = SIGTRAP;
387
            info.si_errno = 0;
388
            info.si_code = TARGET_ILL_ILLOPN;
389
            info._sifields._sigfault._addr = env->nip;
390
            queue_signal(info.si_signo, &info);
391
            break;
392
        /* Invalid instruction */
393
        case EXCP_INVAL:
394
            info.si_signo = SIGILL;
395
            info.si_errno = 0;
396
            info.si_code = TARGET_ILL_ILLOPN;
397
            info._sifields._sigfault._addr = env->nip;
398
            queue_signal(info.si_signo, &info);
399
            break;
400
        /* Privileged instruction */
401
        case EXCP_PRIV: /* Privileged instruction           */
402
            info.si_signo = SIGILL;
403
            info.si_errno = 0;
404
            info.si_code = TARGET_ILL_ILLOPN;
405
            info._sifields._sigfault._addr = env->nip;
406
            queue_signal(info.si_signo, &info);
407
            break;
408
        case EXCP_NO_FP: /* No floating point                */
409
        case EXCP_DECR: /* Decrementer exception            */
410
        case EXCP_RESA: /* Implementation specific          */
411
        case EXCP_RESB: /* Implementation specific          */
412
        case EXCP_FP_ASSIST: /* Floating-point assist (optional) */
413
            fprintf(stderr, "Misc expt...\n");
414
            cpu_ppc_dump_state(env, stderr, 0);
415
            abort();
416

  
417
        case EXCP_SYSCALL:
418
        {
419
            uint32_t ret;
420
            /* system call */
421
            /* WARNING:
422
             * PPC ABI uses overflow flag in cr0 to signal an error
423
             * in syscalls.
424
             */
425
            env->crf[0] &= ~0x1;
426
            ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
427
                             env->gpr[5], env->gpr[6], env->gpr[7],
428
                             env->gpr[8]);
429
            if (ret > (uint32_t)(-515)) {
430
                env->crf[0] |= 0x1;
431
                ret = -ret;
432
            }
433
            env->gpr[3] = ret;
434
            break;
435
        }
436
        default:
437
//        error:
438
            fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", 
439
                    trapnr);
440
            cpu_ppc_dump_state(env, stderr, 0);
441
            abort();
442
        }
443
        process_pending_signals(env);
444
    }
445
}
446
#endif
447

  
327 448
void usage(void)
328 449
{
329 450
    printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
......
517 638
#elif defined(TARGET_SPARC)
518 639
	env->pc = regs->u_regs[0];
519 640
	env->regwptr[6] = regs->u_regs[1]-0x40;
641
#elif defined(TARGET_PPC)
642
    {
643
        int i;
644
        for (i = 0; i < 32; i++)
645
            env->msr[i] = (regs->msr >> i) & 1;
646
        env->nip = regs->nip;
647
        for(i = 0; i < 32; i++) {
648
            env->gpr[i] = regs->gpr[i];
649
        }
650
    }
520 651
#else
521 652
#error unsupported target CPU
522 653
#endif
b/linux-user/syscall.c
65 65

  
66 66
//#define DEBUG
67 67

  
68
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
69
/* 16 bit uid wrappers emulation */
70
#define USE_UID16
71
#endif
72

  
68 73
//#include <linux/msdos_fs.h>
69 74
#define	VFAT_IOCTL_READDIR_BOTH		_IOR('r', 1, struct dirent [2])
70 75
#define	VFAT_IOCTL_READDIR_SHORT	_IOR('r', 2, struct dirent [2])
......
1264 1269
        new_env->regs[13] = newsp;
1265 1270
        new_env->regs[0] = 0;
1266 1271
#elif defined(TARGET_SPARC)
1267
		printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
1272
        printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
1273
#elif defined(TARGET_PPC)
1274
        if (!newsp)
1275
            newsp = env->gpr[1];
1276
        new_env->gpr[1] = newsp;
1277
        { 
1278
            int i;
1279
            for (i = 7; i < 32; i++)
1280
                new_env->gpr[i] = 0;
1281
        }
1268 1282
#else
1269 1283
#error unsupported target CPU
1270 1284
#endif
......
1325 1339
    return ret;
1326 1340
}
1327 1341

  
1342
#ifdef USE_UID16
1328 1343

  
1329
#define high2lowuid(x) (x)
1330
#define high2lowgid(x) (x)
1331
#define low2highuid(x) (x)
1332
#define low2highgid(x) (x)
1344
static inline int high2lowuid(int uid)
1345
{
1346
    if (uid > 65535)
1347
        return 65534;
1348
    else
1349
        return uid;
1350
}
1351

  
1352
static inline int high2lowgid(int gid)
1353
{
1354
    if (gid > 65535)
1355
        return 65534;
1356
    else
1357
        return gid;
1358
}
1359

  
1360
static inline int low2highuid(int uid)
1361
{
1362
    if ((int16_t)uid == -1)
1363
        return -1;
1364
    else
1365
        return uid;
1366
}
1367

  
1368
static inline int low2highgid(int gid)
1369
{
1370
    if ((int16_t)gid == -1)
1371
        return -1;
1372
    else
1373
        return gid;
1374
}
1375

  
1376
#endif /* USE_UID16 */
1333 1377

  
1334 1378
void syscall_init(void)
1335 1379
{
......
1472 1516
    case TARGET_NR_chmod:
1473 1517
        ret = get_errno(chmod((const char *)arg1, arg2));
1474 1518
        break;
1475
    case TARGET_NR_lchown:
1476
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
1477
        break;
1478 1519
#ifdef TARGET_NR_break
1479 1520
    case TARGET_NR_break:
1480 1521
        goto unimplemented;
......
1495 1536
    case TARGET_NR_umount:
1496 1537
        ret = get_errno(umount((const char *)arg1));
1497 1538
        break;
1498
    case TARGET_NR_setuid:
1499
        ret = get_errno(setuid(low2highuid(arg1)));
1500
        break;
1501
    case TARGET_NR_getuid:
1502
        ret = get_errno(getuid());
1503
        break;
1504 1539
    case TARGET_NR_stime:
1505 1540
        {
1506 1541
            int *time_ptr = (int *)arg1;
......
1596 1631
    case TARGET_NR_prof:
1597 1632
        goto unimplemented;
1598 1633
#endif
1599
    case TARGET_NR_setgid:
1600
        ret = get_errno(setgid(low2highgid(arg1)));
1601
        break;
1602
    case TARGET_NR_getgid:
1603
        ret = get_errno(getgid());
1604
        break;
1605 1634
    case TARGET_NR_signal:
1606 1635
        goto unimplemented;
1607
    case TARGET_NR_geteuid:
1608
        ret = get_errno(geteuid());
1609
        break;
1610
    case TARGET_NR_getegid:
1611
        ret = get_errno(getegid());
1612
        break;
1636

  
1613 1637
    case TARGET_NR_acct:
1614 1638
        goto unimplemented;
1615 1639
    case TARGET_NR_umount2:
......
1844 1868
        /* NOTE: ret is eax, so not transcoding must be done */
1845 1869
        ret = do_rt_sigreturn(cpu_env);
1846 1870
        break;
1847
    case TARGET_NR_setreuid:
1848
        ret = get_errno(setreuid(arg1, arg2));
1849
        break;
1850
    case TARGET_NR_setregid:
1851
        ret = get_errno(setregid(arg1, arg2));
1852
        break;
1853 1871
    case TARGET_NR_sethostname:
1854 1872
        ret = get_errno(sethostname((const char *)arg1, arg2));
1855 1873
        break;
......
1906 1924
            ret = get_errno(settimeofday(&tv, NULL));
1907 1925
        }
1908 1926
        break;
1909
    case TARGET_NR_getgroups:
1910
        {
1911
            int gidsetsize = arg1;
1912
            uint16_t *target_grouplist = (void *)arg2;
1913
            gid_t *grouplist;
1914
            int i;
1915

  
1916
            grouplist = alloca(gidsetsize * sizeof(gid_t));
1917
            ret = get_errno(getgroups(gidsetsize, grouplist));
1918
            if (!is_error(ret)) {
1919
                for(i = 0;i < gidsetsize; i++)
1920
                    target_grouplist[i] = tswap16(grouplist[i]);
1921
            }
1922
        }
1923
        break;
1924
    case TARGET_NR_setgroups:
1925
        {
1926
            int gidsetsize = arg1;
1927
            uint16_t *target_grouplist = (void *)arg2;
1928
            gid_t *grouplist;
1929
            int i;
1930

  
1931
            grouplist = alloca(gidsetsize * sizeof(gid_t));
1932
            for(i = 0;i < gidsetsize; i++)
1933
                grouplist[i] = tswap16(target_grouplist[i]);
1934
            ret = get_errno(setgroups(gidsetsize, grouplist));
1935
        }
1936
        break;
1937 1927
    case TARGET_NR_select:
1938 1928
        {
1939 1929
            struct target_sel_arg_struct *sel = (void *)arg1;
......
2026 2016
    case TARGET_NR_fchmod:
2027 2017
        ret = get_errno(fchmod(arg1, arg2));
2028 2018
        break;
2029
    case TARGET_NR_fchown:
2030
        ret = get_errno(fchown(arg1, arg2, arg3));
2031
        break;
2032 2019
    case TARGET_NR_getpriority:
2033 2020
        ret = get_errno(getpriority(arg1, arg2));
2034 2021
        break;
......
2121 2108
                struct target_stat *target_st = (void *)arg2;
2122 2109
                target_st->st_dev = tswap16(st.st_dev);
2123 2110
                target_st->st_ino = tswapl(st.st_ino);
2111
#if defined(TARGET_PPC)
2112
                target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
2113
                target_st->st_uid = tswap32(st.st_uid);
2114
                target_st->st_gid = tswap32(st.st_gid);
2115
#else
2124 2116
                target_st->st_mode = tswap16(st.st_mode);
2125
                target_st->st_nlink = tswap16(st.st_nlink);
2126 2117
                target_st->st_uid = tswap16(st.st_uid);
2127 2118
                target_st->st_gid = tswap16(st.st_gid);
2119
#endif
2120
                target_st->st_nlink = tswap16(st.st_nlink);
2128 2121
                target_st->st_rdev = tswap16(st.st_rdev);
2129 2122
                target_st->st_size = tswapl(st.st_size);
2130 2123
                target_st->st_blksize = tswapl(st.st_blksize);
......
2230 2223
        break;
2231 2224
    case TARGET_NR_afs_syscall:
2232 2225
        goto unimplemented;
2233
    case TARGET_NR_setfsuid:
2234
        ret = get_errno(setfsuid(arg1));
2235
        break;
2236
    case TARGET_NR_setfsgid:
2237
        ret = get_errno(setfsgid(arg1));
2238
        break;
2239 2226
    case TARGET_NR__llseek:
2240 2227
        {
2241 2228
            int64_t res;
......
2465 2452
            }
2466 2453
        }
2467 2454
        break;
2468
#ifdef TARGET_NR_setresuid
2469
    case TARGET_NR_setresuid:
2470
        ret = get_errno(setresuid(low2highuid(arg1), 
2471
                                  low2highuid(arg2), 
2472
                                  low2highuid(arg3)));
2473
        break;
2474
#endif
2475
#ifdef TARGET_NR_getresuid
2476
    case TARGET_NR_getresuid:
2477
        {
2478
            int ruid, euid, suid;
2479
            ret = get_errno(getresuid(&ruid, &euid, &suid));
2480
            if (!is_error(ret)) {
2481
                *(uint16_t *)arg1 = tswap16(high2lowuid(ruid));
2482
                *(uint16_t *)arg2 = tswap16(high2lowuid(euid));
2483
                *(uint16_t *)arg3 = tswap16(high2lowuid(suid));
2484
            }
2485
        }
2486
        break;
2487
#endif
2488
#ifdef TARGET_NR_getresgid
2489
    case TARGET_NR_setresgid:
2490
        ret = get_errno(setresgid(low2highgid(arg1), 
2491
                                  low2highgid(arg2), 
2492
                                  low2highgid(arg3)));
2493
        break;
2494
#endif
2495
#ifdef TARGET_NR_getresgid
2496
    case TARGET_NR_getresgid:
2497
        {
2498
            int rgid, egid, sgid;
2499
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
2500
            if (!is_error(ret)) {
2501
                *(uint16_t *)arg1 = high2lowgid(tswap16(rgid));
2502
                *(uint16_t *)arg2 = high2lowgid(tswap16(egid));
2503
                *(uint16_t *)arg3 = high2lowgid(tswap16(sgid));
2504
            }
2505
        }
2506
        break;
2507
#endif
2508 2455
    case TARGET_NR_query_module:
2509 2456
        goto unimplemented;
2510 2457
    case TARGET_NR_nfsservctl:
2511 2458
        goto unimplemented;
2512 2459
    case TARGET_NR_prctl:
2513 2460
        goto unimplemented;
2461
#ifdef TARGET_NR_pread
2514 2462
    case TARGET_NR_pread:
2515 2463
        page_unprotect_range((void *)arg2, arg3);
2516 2464
        ret = get_errno(pread(arg1, (void *)arg2, arg3, arg4));
......
2518 2466
    case TARGET_NR_pwrite:
2519 2467
        ret = get_errno(pwrite(arg1, (void *)arg2, arg3, arg4));
2520 2468
        break;
2521
    case TARGET_NR_chown:
2522
        ret = get_errno(chown((const char *)arg1, arg2, arg3));
2523
        break;
2469
#endif
2524 2470
    case TARGET_NR_getcwd:
2525 2471
        ret = get_errno(sys_getcwd1((char *)arg1, arg2));
2526 2472
        break;
......
2594 2540
        }
2595 2541
        break;
2596 2542

  
2543
#ifdef USE_UID16
2544
    case TARGET_NR_lchown:
2545
        ret = get_errno(lchown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
2546
        break;
2547
    case TARGET_NR_getuid:
2548
        ret = get_errno(high2lowuid(getuid()));
2549
        break;
2550
    case TARGET_NR_getgid:
2551
        ret = get_errno(high2lowgid(getgid()));
2552
        break;
2553
    case TARGET_NR_geteuid:
2554
        ret = get_errno(high2lowuid(geteuid()));
2555
        break;
2556
    case TARGET_NR_getegid:
2557
        ret = get_errno(high2lowgid(getegid()));
2558
        break;
2559
    case TARGET_NR_setreuid:
2560
        ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
2561
        break;
2562
    case TARGET_NR_setregid:
2563
        ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
2564
        break;
2565
    case TARGET_NR_getgroups:
2566
        {
2567
            int gidsetsize = arg1;
2568
            uint16_t *target_grouplist = (void *)arg2;
2569
            gid_t *grouplist;
2570
            int i;
2571

  
2572
            grouplist = alloca(gidsetsize * sizeof(gid_t));
2573
            ret = get_errno(getgroups(gidsetsize, grouplist));
2574
            if (!is_error(ret)) {
2575
                for(i = 0;i < gidsetsize; i++)
2576
                    target_grouplist[i] = tswap16(grouplist[i]);
2577
            }
2578
        }
2579
        break;
2580
    case TARGET_NR_setgroups:
2581
        {
2582
            int gidsetsize = arg1;
2583
            uint16_t *target_grouplist = (void *)arg2;
2584
            gid_t *grouplist;
2585
            int i;
2586

  
2587
            grouplist = alloca(gidsetsize * sizeof(gid_t));
2588
            for(i = 0;i < gidsetsize; i++)
2589
                grouplist[i] = tswap16(target_grouplist[i]);
2590
            ret = get_errno(setgroups(gidsetsize, grouplist));
2591
        }
2592
        break;
2593
    case TARGET_NR_fchown:
2594
        ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
2595
        break;
2596
#ifdef TARGET_NR_setresuid
2597
    case TARGET_NR_setresuid:
2598
        ret = get_errno(setresuid(low2highuid(arg1), 
2599
                                  low2highuid(arg2), 
2600
                                  low2highuid(arg3)));
2601
        break;
2602
#endif
2603
#ifdef TARGET_NR_getresuid
2604
    case TARGET_NR_getresuid:
2605
        {
2606
            int ruid, euid, suid;
2607
            ret = get_errno(getresuid(&ruid, &euid, &suid));
2608
            if (!is_error(ret)) {
2609
                *(uint16_t *)arg1 = tswap16(high2lowuid(ruid));
2610
                *(uint16_t *)arg2 = tswap16(high2lowuid(euid));
2611
                *(uint16_t *)arg3 = tswap16(high2lowuid(suid));
2612
            }
2613
        }
2614
        break;
2615
#endif
2616
#ifdef TARGET_NR_getresgid
2617
    case TARGET_NR_setresgid:
2618
        ret = get_errno(setresgid(low2highgid(arg1), 
2619
                                  low2highgid(arg2), 
2620
                                  low2highgid(arg3)));
2621
        break;
2622
#endif
2623
#ifdef TARGET_NR_getresgid
2624
    case TARGET_NR_getresgid:
2625
        {
2626
            int rgid, egid, sgid;
2627
            ret = get_errno(getresgid(&rgid, &egid, &sgid));
2628
            if (!is_error(ret)) {
2629
                *(uint16_t *)arg1 = tswap16(high2lowgid(rgid));
2630
                *(uint16_t *)arg2 = tswap16(high2lowgid(egid));
2631
                *(uint16_t *)arg3 = tswap16(high2lowgid(sgid));
2632
            }
2633
        }
2634
        break;
2635
#endif
2636
    case TARGET_NR_chown:
2637
        ret = get_errno(chown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
2638
        break;
2639
    case TARGET_NR_setuid:
2640
        ret = get_errno(setuid(low2highuid(arg1)));
2641
        break;
2642
    case TARGET_NR_setgid:
2643
        ret = get_errno(setgid(low2highgid(arg1)));
2644
        break;
2645
    case TARGET_NR_setfsuid:
2646
        ret = get_errno(setfsuid(arg1));
2647
        break;
2648
    case TARGET_NR_setfsgid:
2649
        ret = get_errno(setfsgid(arg1));
2650
        break;
2651
#endif /* USE_UID16 */
2652

  
2597 2653
    case TARGET_NR_lchown32:
2598 2654
        ret = get_errno(lchown((const char *)arg1, arg2, arg3));
2599 2655
        break;
......
2665 2721
    case TARGET_NR_setfsgid32:
2666 2722
        ret = get_errno(setfsgid(arg1));
2667 2723
        break;
2724

  
2668 2725
    case TARGET_NR_pivot_root:
2669 2726
        goto unimplemented;
2670 2727
    case TARGET_NR_mincore:
b/linux-user/syscall_defs.h
279 279
int do_sigaction(int sig, const struct target_sigaction *act,
280 280
                 struct target_sigaction *oact);
281 281

  
282
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
282
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC)
283 283

  
284 284
#define TARGET_SA_NOCLDSTOP	0x00000001
285 285
#define TARGET_SA_NOCLDWAIT	0x00000002 /* not supported yet */
......
664 664
#define TARGET_HDIO_SET_PIO_MODE      0x0327  /* reconfig interface to new speed */
665 665

  
666 666

  
667
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
667
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC)
668 668

  
669 669
/* 0x54 is just a magic number to make these relatively unique ('T') */
670 670

  
......
891 891
#define TARGET_MAP_LOCKED	0x2000		/* pages are locked */
892 892
#define TARGET_MAP_NORESERVE	0x4000		/* don't check for reservations */
893 893

  
894
#endif /* defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) */
895

  
896
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
894 897
struct target_stat {
895 898
	unsigned short st_dev;
896 899
	unsigned short __pad1;
......
951 954
	unsigned long long	st_ino;
952 955
} __attribute__((packed));
953 956

  
954
#endif /* defined(TARGET_I386) || defined(TARGET_ARM) */
957
#elif defined(TARGET_PPC)
958

  
959
struct target_stat {
960
	unsigned short st_dev;
961
	target_ulong st_ino;
962
	unsigned int st_mode;
963
	unsigned short st_nlink;
964
	unsigned int st_uid;
965
	unsigned int st_gid;
966
	unsigned short st_rdev;
967
	target_ulong  st_size;
968
	target_ulong  st_blksize;
969
	target_ulong  st_blocks;
970
	target_ulong  target_st_atime;
971
	target_ulong  __unused1;
972
	target_ulong  target_st_mtime;
973
	target_ulong  __unused2;
974
	target_ulong  target_st_ctime;
975
	target_ulong  __unused3;
976
	target_ulong  __unused4;
977
	target_ulong  __unused5;
978
};
979

  
980
struct target_stat64 {
981
	unsigned long long st_dev;
982

  
983
        unsigned long long st_ino;
984

  
985
	unsigned int	st_mode;
986
	unsigned int	st_nlink;
987

  
988
	unsigned int st_uid;
989
	unsigned int st_gid;
990

  
991
	unsigned long long	st_rdev;
992
	unsigned short int __pad2;
993

  
994
	long long	st_size;
995
	target_ulong	st_blksize;
996

  
997
	long long	st_blocks;	/* Number 512-byte blocks allocated. */
998

  
999
	target_ulong	target_st_atime;
1000
        target_ulong    target_st_atime_nsec;
1001

  
1002
	target_ulong	target_st_mtime;
1003
        target_ulong    target_st_mtime_nsec;
1004

  
1005
	target_ulong	target_st_ctime;
1006
        target_ulong    target_st_ctime_nsec;
1007

  
1008
        target_ulong    __unused4;
1009
        target_ulong    __unused5;
1010
};
1011

  
1012
#endif /* defined(TARGET_PPC) */
955 1013

  
956 1014
#define TARGET_F_DUPFD         0       /* dup */
957 1015
#define TARGET_F_GETFD         1       /* get close_on_exec */

Also available in: Unified diff