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