Commit 678673089d1ba7cd0f2960a2815a0d5bb8a72fa3

Authored by bellard
1 parent 28b6751f

PowerPC target support (Jocelyn Mayer) - added better support for uid16


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@474 c046a42c-6fe2-441c-8c8c-71466251a162
Changelog
... ... @@ -9,7 +9,8 @@ version 0.5.1:
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  
... ...
Makefile.target
... ... @@ -146,6 +146,10 @@ ifeq ($(TARGET_ARCH), i386)
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)
... ...
configure
... ... @@ -27,7 +27,7 @@ ar="ar"
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,6 +322,7 @@ config_h=$target_dir/config.h
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,6 +359,10 @@ elif test "$target_cpu" = "sparc" ; then
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
... ...
cpu-all.h
... ... @@ -395,6 +395,15 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size);
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
... ...
cpu-exec.c
... ... @@ -133,6 +133,7 @@ int cpu_exec(CPUState *env1)
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,6 +229,8 @@ int cpu_exec(CPUState *env1)
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,13 +249,17 @@ int cpu_exec(CPUState *env1)
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,6 +383,7 @@ int cpu_exec(CPUState *env1)
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,6 +521,43 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
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
... ...
... ... @@ -171,6 +171,8 @@ void disas(FILE *out, void *code, unsigned long size, int is_host, int flags)
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;
... ...
dyngen-exec.h
... ... @@ -17,6 +17,9 @@
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,6 +30,19 @@ typedef signed short int16_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,3 +207,5 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
191 207 #ifdef __mc68000
192 208 #define EXIT_TB() asm volatile ("rts")
193 209 #endif
  210 +
  211 +#endif /* !defined(__DYNGEN_EXEC_H__) */
... ...
linux-user/elfload.c
... ... @@ -104,6 +104,46 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
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 /*
... ...
linux-user/main.c
... ... @@ -324,6 +324,127 @@ void cpu_loop (CPUSPARCState *env)
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,6 +638,16 @@ int main(int argc, char **argv)
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
... ...
linux-user/syscall.c
... ... @@ -65,6 +65,11 @@
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,7 +1269,16 @@ int do_fork(CPUState *env, unsigned int flags, unsigned long newsp)
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,11 +1339,41 @@ static long do_fcntl(int fd, int cmd, unsigned long arg)
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,9 +1516,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,12 +1536,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,20 +1631,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,12 +1868,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,34 +1924,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,9 +2016,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,10 +2108,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,12 +2223,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,52 +2452,13 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,9 +2466,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,6 +2540,116 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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,6 +2721,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
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:
... ...
linux-user/syscall_defs.h
... ... @@ -279,7 +279,7 @@ struct target_sigaction;
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,7 +664,7 @@ struct target_pollfd {
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,6 +891,9 @@ struct target_termios {
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,7 +954,62 @@ struct target_stat64 {
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 */
... ...