Commit 678673089d1ba7cd0f2960a2815a0d5bb8a72fa3
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
Showing
11 changed files
with
495 additions
and
125 deletions
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 | ... | ... |
disas.c
... | ... | @@ -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 */ | ... | ... |