Revision 67867308
b/Changelog | ||
---|---|---|
9 | 9 |
- IRET and INT fixes in VM86 mode with IOPL=3 |
10 | 10 |
- Port I/Os use TSS io map |
11 | 11 |
- Full task switching/task gate support |
12 |
- added verr, verw, arpl |
|
12 |
- added verr, verw, arpl, fcmovxx |
|
13 |
- PowerPC target support (Jocelyn Mayer) |
|
13 | 14 |
|
14 | 15 |
version 0.5.0: |
15 | 16 |
|
b/Makefile.target | ||
---|---|---|
146 | 146 |
LIBOBJS+=helper.o helper2.o |
147 | 147 |
endif |
148 | 148 |
|
149 |
ifeq ($(TARGET_ARCH), ppc) |
|
150 |
LIBOBJS+=helper.o |
|
151 |
endif |
|
152 |
|
|
149 | 153 |
# NOTE: the disassembler code is only needed for debugging |
150 | 154 |
LIBOBJS+=disas.o |
151 | 155 |
ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386) |
b/configure | ||
---|---|---|
27 | 27 |
make="make" |
28 | 28 |
strip="strip" |
29 | 29 |
cpu=`uname -m` |
30 |
target_list="i386-user i386 i386-softmmu arm-user sparc-user" |
|
30 |
target_list="i386-user i386 i386-softmmu arm-user sparc-user ppc-user"
|
|
31 | 31 |
case "$cpu" in |
32 | 32 |
i386|i486|i586|i686|i86pc|BePC) |
33 | 33 |
cpu="i386" |
... | ... | |
322 | 322 |
target_cpu=`echo $target | cut -d '-' -f 1` |
323 | 323 |
target_bigendian="no" |
324 | 324 |
[ "$target_cpu" = "sparc" ] && target_bigendian=yes |
325 |
[ "$target_cpu" = "ppc" ] && target_bigendian=yes |
|
325 | 326 |
target_softmmu="no" |
326 | 327 |
if expr $target : '.*-softmmu' > /dev/null ; then |
327 | 328 |
target_softmmu="yes" |
... | ... | |
358 | 359 |
echo "TARGET_ARCH=sparc" >> $config_mak |
359 | 360 |
echo "#define TARGET_ARCH \"sparc\"" >> $config_h |
360 | 361 |
echo "#define TARGET_SPARC 1" >> $config_h |
362 |
elif test "$target_cpu" = "ppc" ; then |
|
363 |
echo "TARGET_ARCH=ppc" >> $config_mak |
|
364 |
echo "#define TARGET_ARCH \"ppc\"" >> $config_h |
|
365 |
echo "#define TARGET_PPC 1" >> $config_h |
|
361 | 366 |
else |
362 | 367 |
echo "Unsupported target CPU" |
363 | 368 |
exit 1 |
b/cpu-all.h | ||
---|---|---|
395 | 395 |
#define cpu_interrupt cpu_sparc_interrupt |
396 | 396 |
#define cpu_signal_handler cpu_sparc_signal_handler |
397 | 397 |
|
398 |
#elif defined(TARGET_PPC) |
|
399 |
|
|
400 |
#define CPUState CPUPPCState |
|
401 |
#define cpu_init cpu_ppc_init |
|
402 |
#define cpu_exec cpu_ppc_exec |
|
403 |
#define cpu_gen_code cpu_ppc_gen_code |
|
404 |
#define cpu_interrupt cpu_ppc_interrupt |
|
405 |
#define cpu_signal_handler cpu_ppc_signal_handler |
|
406 |
|
|
398 | 407 |
#else |
399 | 408 |
|
400 | 409 |
#error unsupported target CPU |
b/cpu-exec.c | ||
---|---|---|
133 | 133 |
env->cpsr = psr & ~0xf0000000; |
134 | 134 |
} |
135 | 135 |
#elif defined(TARGET_SPARC) |
136 |
#elif defined(TARGET_PPC) |
|
136 | 137 |
#else |
137 | 138 |
#error unsupported target CPU |
138 | 139 |
#endif |
... | ... | |
228 | 229 |
env->cpsr &= ~0xf0000000; |
229 | 230 |
#elif defined(TARGET_SPARC) |
230 | 231 |
cpu_sparc_dump_state (env, logfile, 0); |
232 |
#elif defined(TARGET_PPC) |
|
233 |
cpu_ppc_dump_state(env, logfile, 0); |
|
231 | 234 |
#else |
232 | 235 |
#error unsupported target CPU |
233 | 236 |
#endif |
... | ... | |
246 | 249 |
cs_base = 0; |
247 | 250 |
pc = (uint8_t *)env->regs[15]; |
248 | 251 |
#elif defined(TARGET_SPARC) |
249 |
flags = 0; |
|
250 |
cs_base = 0; |
|
251 |
if (env->npc) { |
|
252 |
env->pc = env->npc; |
|
253 |
env->npc = 0; |
|
254 |
} |
|
255 |
pc = (uint8_t *) env->pc; |
|
252 |
flags = 0; |
|
253 |
cs_base = 0; |
|
254 |
if (env->npc) { |
|
255 |
env->pc = env->npc; |
|
256 |
env->npc = 0; |
|
257 |
} |
|
258 |
pc = (uint8_t *) env->pc; |
|
259 |
#elif defined(TARGET_PPC) |
|
260 |
flags = 0; |
|
261 |
cs_base = 0; |
|
262 |
pc = (uint8_t *)env->nip; |
|
256 | 263 |
#else |
257 | 264 |
#error unsupported CPU |
258 | 265 |
#endif |
... | ... | |
376 | 383 |
#elif defined(TARGET_ARM) |
377 | 384 |
env->cpsr = compute_cpsr(); |
378 | 385 |
#elif defined(TARGET_SPARC) |
386 |
#elif defined(TARGET_PPC) |
|
379 | 387 |
#else |
380 | 388 |
#error unsupported target CPU |
381 | 389 |
#endif |
... | ... | |
513 | 521 |
{ |
514 | 522 |
return 0; |
515 | 523 |
} |
524 |
#elif defined (TARGET_PPC) |
|
525 |
static inline int handle_cpu_signal(unsigned long pc, unsigned long address, |
|
526 |
int is_write, sigset_t *old_set) |
|
527 |
{ |
|
528 |
TranslationBlock *tb; |
|
529 |
|
|
530 |
#if 0 |
|
531 |
if (cpu_single_env) |
|
532 |
env = cpu_single_env; /* XXX: find a correct solution for multithread */ |
|
533 |
#endif |
|
534 |
#if defined(DEBUG_SIGNAL) |
|
535 |
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n", |
|
536 |
pc, address, is_write, *(unsigned long *)old_set); |
|
537 |
#endif |
|
538 |
/* XXX: locking issue */ |
|
539 |
if (is_write && page_unprotect(address)) { |
|
540 |
return 1; |
|
541 |
} |
|
542 |
|
|
543 |
/* now we have a real cpu fault */ |
|
544 |
tb = tb_find_pc(pc); |
|
545 |
if (tb) { |
|
546 |
/* the PC is inside the translated code. It means that we have |
|
547 |
a virtual CPU fault */ |
|
548 |
cpu_restore_state(tb, env, pc); |
|
549 |
} |
|
550 |
#if 0 |
|
551 |
printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n", |
|
552 |
env->eip, env->cr[2], env->error_code); |
|
553 |
#endif |
|
554 |
/* we restore the process signal mask as the sigreturn should |
|
555 |
do it (XXX: use sigsetjmp) */ |
|
556 |
sigprocmask(SIG_SETMASK, old_set, NULL); |
|
557 |
raise_exception_err(EXCP_PROGRAM, env->error_code); |
|
558 |
/* never comes here */ |
|
559 |
return 1; |
|
560 |
} |
|
516 | 561 |
#else |
517 | 562 |
#error unsupported target CPU |
518 | 563 |
#endif |
b/disas.c | ||
---|---|---|
171 | 171 |
print_insn = print_insn_arm; |
172 | 172 |
#elif defined(TARGET_SPARC) |
173 | 173 |
print_insn = print_insn_sparc; |
174 |
#elif defined(TARGET_PPC) |
|
175 |
print_insn = print_insn_ppc; |
|
174 | 176 |
#else |
175 | 177 |
fprintf(out, "Asm output not supported on this arch\n"); |
176 | 178 |
return; |
b/dyngen-exec.h | ||
---|---|---|
17 | 17 |
* License along with this library; if not, write to the Free Software |
18 | 18 |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
19 | 19 |
*/ |
20 |
#if !defined(__DYNGEN_EXEC_H__) |
|
21 |
#define __DYNGEN_EXEC_H__ |
|
22 |
|
|
20 | 23 |
typedef unsigned char uint8_t; |
21 | 24 |
typedef unsigned short uint16_t; |
22 | 25 |
typedef unsigned int uint32_t; |
... | ... | |
27 | 30 |
typedef signed int int32_t; |
28 | 31 |
typedef signed long long int64_t; |
29 | 32 |
|
33 |
#define INT8_MIN (-128) |
|
34 |
#define INT16_MIN (-32767-1) |
|
35 |
#define INT32_MIN (-2147483647-1) |
|
36 |
#define INT64_MIN (-(int64_t)(9223372036854775807)-1) |
|
37 |
#define INT8_MAX (127) |
|
38 |
#define INT16_MAX (32767) |
|
39 |
#define INT32_MAX (2147483647) |
|
40 |
#define INT64_MAX ((int64_t)(9223372036854775807)) |
|
41 |
#define UINT8_MAX (255) |
|
42 |
#define UINT16_MAX (65535) |
|
43 |
#define UINT32_MAX (4294967295U) |
|
44 |
#define UINT64_MAX ((uint64_t)(18446744073709551615)) |
|
45 |
|
|
30 | 46 |
#define bswap32(x) \ |
31 | 47 |
({ \ |
32 | 48 |
uint32_t __x = (x); \ |
... | ... | |
191 | 207 |
#ifdef __mc68000 |
192 | 208 |
#define EXIT_TB() asm volatile ("rts") |
193 | 209 |
#endif |
210 |
|
|
211 |
#endif /* !defined(__DYNGEN_EXEC_H__) */ |
b/linux-user/elfload.c | ||
---|---|---|
104 | 104 |
|
105 | 105 |
#endif |
106 | 106 |
|
107 |
#ifdef TARGET_PPC |
|
108 |
|
|
109 |
#define ELF_START_MMAP 0x80000000 |
|
110 |
|
|
111 |
#define elf_check_arch(x) ( (x) == EM_PPC ) |
|
112 |
|
|
113 |
#define ELF_CLASS ELFCLASS32 |
|
114 |
#ifdef TARGET_WORDS_BIGENDIAN |
|
115 |
#define ELF_DATA ELFDATA2MSB |
|
116 |
#else |
|
117 |
#define ELF_DATA ELFDATA2LSB |
|
118 |
#endif |
|
119 |
#define ELF_ARCH EM_PPC |
|
120 |
|
|
121 |
/* Note that isn't exactly what regular kernel does |
|
122 |
* but this is what the ABI wants and is needed to allow |
|
123 |
* execution of PPC BSD programs. |
|
124 |
*/ |
|
125 |
#define ELF_PLAT_INIT(_r) \ |
|
126 |
do { \ |
|
127 |
unsigned long *pos = (unsigned long *)bprm->p, tmp = 1; \ |
|
128 |
_r->gpr[3] = bprm->argc; \ |
|
129 |
_r->gpr[4] = (unsigned long)++pos; \ |
|
130 |
for (; tmp != 0; pos++) \ |
|
131 |
tmp = *pos; \ |
|
132 |
_r->gpr[5] = (unsigned long)pos; \ |
|
133 |
} while (0) |
|
134 |
|
|
135 |
static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop) |
|
136 |
{ |
|
137 |
_regs->msr = 1 << MSR_PR; /* Set user mode */ |
|
138 |
_regs->gpr[1] = infop->start_stack; |
|
139 |
_regs->nip = infop->entry; |
|
140 |
} |
|
141 |
|
|
142 |
#define USE_ELF_CORE_DUMP |
|
143 |
#define ELF_EXEC_PAGESIZE 4096 |
|
144 |
|
|
145 |
#endif |
|
146 |
|
|
107 | 147 |
#include "elf.h" |
108 | 148 |
|
109 | 149 |
/* |
b/linux-user/main.c | ||
---|---|---|
324 | 324 |
|
325 | 325 |
#endif |
326 | 326 |
|
327 |
#ifdef TARGET_PPC |
|
328 |
|
|
329 |
void cpu_loop(CPUPPCState *env) |
|
330 |
{ |
|
331 |
int trapnr; |
|
332 |
target_siginfo_t info; |
|
333 |
|
|
334 |
for(;;) { |
|
335 |
trapnr = cpu_ppc_exec(env); |
|
336 |
switch(trapnr) { |
|
337 |
case EXCP_NONE: |
|
338 |
case EXCP_INTERRUPT: |
|
339 |
case EXCP_MTMSR: /* mtmsr instruction: */ |
|
340 |
case EXCP_BRANCH: /* branch instruction */ |
|
341 |
/* Single step mode */ |
|
342 |
break; |
|
343 |
#if 0 |
|
344 |
case EXCP_RESET: /* System reset */ |
|
345 |
fprintf(stderr, "RESET asked... Stop emulation\n"); |
|
346 |
cpu_ppc_dump_state(env, stderr, 0); |
|
347 |
abort(); |
|
348 |
#endif |
|
349 |
case EXCP_MACHINE_CHECK: /* Machine check exception */ |
|
350 |
fprintf(stderr, "Machine check exeption... " |
|
351 |
"See you in kernel code !\n"); |
|
352 |
cpu_ppc_dump_state(env, stderr, 0); |
|
353 |
abort(); |
|
354 |
case EXCP_DSI: /* Impossible memory access */ |
|
355 |
fprintf(stderr, "Invalid memory access\n"); |
|
356 |
info.si_signo = SIGSEGV; |
|
357 |
info.si_errno = 0; |
|
358 |
info.si_code = TARGET_ILL_ILLOPN; |
|
359 |
info._sifields._sigfault._addr = env->nip; |
|
360 |
queue_signal(info.si_signo, &info); |
|
361 |
break; |
|
362 |
case EXCP_ISI: /* Impossible instruction fetch */ |
|
363 |
fprintf(stderr, "Invalid instruction fetch\n"); |
|
364 |
info.si_signo = SIGBUS; |
|
365 |
info.si_errno = 0; |
|
366 |
info.si_code = TARGET_ILL_ILLOPN; |
|
367 |
info._sifields._sigfault._addr = env->nip; |
|
368 |
queue_signal(info.si_signo, &info); |
|
369 |
break; |
|
370 |
case EXCP_EXTERNAL: /* External interruption */ |
|
371 |
fprintf(stderr, "External access exeption\n"); |
|
372 |
cpu_ppc_dump_state(env, stderr, 0); |
|
373 |
abort(); |
|
374 |
case EXCP_ALIGN: /* Alignment exception */ |
|
375 |
fprintf(stderr, "Alignment exception\n"); |
|
376 |
cpu_ppc_dump_state(env, stderr, 0); |
|
377 |
abort(); |
|
378 |
case EXCP_PROGRAM: /* Program exception */ |
|
379 |
fprintf(stderr, "Program exception\n"); |
|
380 |
cpu_ppc_dump_state(env, stderr, 0); |
|
381 |
abort(); |
|
382 |
break; |
|
383 |
/* Trap */ |
|
384 |
case EXCP_TRAP: /* Trap */ |
|
385 |
case EXCP_TRACE: /* Trace exception (optional) */ |
|
386 |
info.si_signo = SIGTRAP; |
|
387 |
info.si_errno = 0; |
|
388 |
info.si_code = TARGET_ILL_ILLOPN; |
|
389 |
info._sifields._sigfault._addr = env->nip; |
|
390 |
queue_signal(info.si_signo, &info); |
|
391 |
break; |
|
392 |
/* Invalid instruction */ |
|
393 |
case EXCP_INVAL: |
|
394 |
info.si_signo = SIGILL; |
|
395 |
info.si_errno = 0; |
|
396 |
info.si_code = TARGET_ILL_ILLOPN; |
|
397 |
info._sifields._sigfault._addr = env->nip; |
|
398 |
queue_signal(info.si_signo, &info); |
|
399 |
break; |
|
400 |
/* Privileged instruction */ |
|
401 |
case EXCP_PRIV: /* Privileged instruction */ |
|
402 |
info.si_signo = SIGILL; |
|
403 |
info.si_errno = 0; |
|
404 |
info.si_code = TARGET_ILL_ILLOPN; |
|
405 |
info._sifields._sigfault._addr = env->nip; |
|
406 |
queue_signal(info.si_signo, &info); |
|
407 |
break; |
|
408 |
case EXCP_NO_FP: /* No floating point */ |
|
409 |
case EXCP_DECR: /* Decrementer exception */ |
|
410 |
case EXCP_RESA: /* Implementation specific */ |
|
411 |
case EXCP_RESB: /* Implementation specific */ |
|
412 |
case EXCP_FP_ASSIST: /* Floating-point assist (optional) */ |
|
413 |
fprintf(stderr, "Misc expt...\n"); |
|
414 |
cpu_ppc_dump_state(env, stderr, 0); |
|
415 |
abort(); |
|
416 |
|
|
417 |
case EXCP_SYSCALL: |
|
418 |
{ |
|
419 |
uint32_t ret; |
|
420 |
/* system call */ |
|
421 |
/* WARNING: |
|
422 |
* PPC ABI uses overflow flag in cr0 to signal an error |
|
423 |
* in syscalls. |
|
424 |
*/ |
|
425 |
env->crf[0] &= ~0x1; |
|
426 |
ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4], |
|
427 |
env->gpr[5], env->gpr[6], env->gpr[7], |
|
428 |
env->gpr[8]); |
|
429 |
if (ret > (uint32_t)(-515)) { |
|
430 |
env->crf[0] |= 0x1; |
|
431 |
ret = -ret; |
|
432 |
} |
|
433 |
env->gpr[3] = ret; |
|
434 |
break; |
|
435 |
} |
|
436 |
default: |
|
437 |
// error: |
|
438 |
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", |
|
439 |
trapnr); |
|
440 |
cpu_ppc_dump_state(env, stderr, 0); |
|
441 |
abort(); |
|
442 |
} |
|
443 |
process_pending_signals(env); |
|
444 |
} |
|
445 |
} |
|
446 |
#endif |
|
447 |
|
|
327 | 448 |
void usage(void) |
328 | 449 |
{ |
329 | 450 |
printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n" |
... | ... | |
517 | 638 |
#elif defined(TARGET_SPARC) |
518 | 639 |
env->pc = regs->u_regs[0]; |
519 | 640 |
env->regwptr[6] = regs->u_regs[1]-0x40; |
641 |
#elif defined(TARGET_PPC) |
|
642 |
{ |
|
643 |
int i; |
|
644 |
for (i = 0; i < 32; i++) |
|
645 |
env->msr[i] = (regs->msr >> i) & 1; |
|
646 |
env->nip = regs->nip; |
|
647 |
for(i = 0; i < 32; i++) { |
|
648 |
env->gpr[i] = regs->gpr[i]; |
|
649 |
} |
|
650 |
} |
|
520 | 651 |
#else |
521 | 652 |
#error unsupported target CPU |
522 | 653 |
#endif |
b/linux-user/syscall.c | ||
---|---|---|
65 | 65 |
|
66 | 66 |
//#define DEBUG |
67 | 67 |
|
68 |
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) |
|
69 |
/* 16 bit uid wrappers emulation */ |
|
70 |
#define USE_UID16 |
|
71 |
#endif |
|
72 |
|
|
68 | 73 |
//#include <linux/msdos_fs.h> |
69 | 74 |
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2]) |
70 | 75 |
#define VFAT_IOCTL_READDIR_SHORT _IOR('r', 2, struct dirent [2]) |
... | ... | |
1264 | 1269 |
new_env->regs[13] = newsp; |
1265 | 1270 |
new_env->regs[0] = 0; |
1266 | 1271 |
#elif defined(TARGET_SPARC) |
1267 |
printf ("HELPME: %s:%d\n", __FILE__, __LINE__); |
|
1272 |
printf ("HELPME: %s:%d\n", __FILE__, __LINE__); |
|
1273 |
#elif defined(TARGET_PPC) |
|
1274 |
if (!newsp) |
|
1275 |
newsp = env->gpr[1]; |
|
1276 |
new_env->gpr[1] = newsp; |
|
1277 |
{ |
|
1278 |
int i; |
|
1279 |
for (i = 7; i < 32; i++) |
|
1280 |
new_env->gpr[i] = 0; |
|
1281 |
} |
|
1268 | 1282 |
#else |
1269 | 1283 |
#error unsupported target CPU |
1270 | 1284 |
#endif |
... | ... | |
1325 | 1339 |
return ret; |
1326 | 1340 |
} |
1327 | 1341 |
|
1342 |
#ifdef USE_UID16 |
|
1328 | 1343 |
|
1329 |
#define high2lowuid(x) (x) |
|
1330 |
#define high2lowgid(x) (x) |
|
1331 |
#define low2highuid(x) (x) |
|
1332 |
#define low2highgid(x) (x) |
|
1344 |
static inline int high2lowuid(int uid) |
|
1345 |
{ |
|
1346 |
if (uid > 65535) |
|
1347 |
return 65534; |
|
1348 |
else |
|
1349 |
return uid; |
|
1350 |
} |
|
1351 |
|
|
1352 |
static inline int high2lowgid(int gid) |
|
1353 |
{ |
|
1354 |
if (gid > 65535) |
|
1355 |
return 65534; |
|
1356 |
else |
|
1357 |
return gid; |
|
1358 |
} |
|
1359 |
|
|
1360 |
static inline int low2highuid(int uid) |
|
1361 |
{ |
|
1362 |
if ((int16_t)uid == -1) |
|
1363 |
return -1; |
|
1364 |
else |
|
1365 |
return uid; |
|
1366 |
} |
|
1367 |
|
|
1368 |
static inline int low2highgid(int gid) |
|
1369 |
{ |
|
1370 |
if ((int16_t)gid == -1) |
|
1371 |
return -1; |
|
1372 |
else |
|
1373 |
return gid; |
|
1374 |
} |
|
1375 |
|
|
1376 |
#endif /* USE_UID16 */ |
|
1333 | 1377 |
|
1334 | 1378 |
void syscall_init(void) |
1335 | 1379 |
{ |
... | ... | |
1472 | 1516 |
case TARGET_NR_chmod: |
1473 | 1517 |
ret = get_errno(chmod((const char *)arg1, arg2)); |
1474 | 1518 |
break; |
1475 |
case TARGET_NR_lchown: |
|
1476 |
ret = get_errno(chown((const char *)arg1, arg2, arg3)); |
|
1477 |
break; |
|
1478 | 1519 |
#ifdef TARGET_NR_break |
1479 | 1520 |
case TARGET_NR_break: |
1480 | 1521 |
goto unimplemented; |
... | ... | |
1495 | 1536 |
case TARGET_NR_umount: |
1496 | 1537 |
ret = get_errno(umount((const char *)arg1)); |
1497 | 1538 |
break; |
1498 |
case TARGET_NR_setuid: |
|
1499 |
ret = get_errno(setuid(low2highuid(arg1))); |
|
1500 |
break; |
|
1501 |
case TARGET_NR_getuid: |
|
1502 |
ret = get_errno(getuid()); |
|
1503 |
break; |
|
1504 | 1539 |
case TARGET_NR_stime: |
1505 | 1540 |
{ |
1506 | 1541 |
int *time_ptr = (int *)arg1; |
... | ... | |
1596 | 1631 |
case TARGET_NR_prof: |
1597 | 1632 |
goto unimplemented; |
1598 | 1633 |
#endif |
1599 |
case TARGET_NR_setgid: |
|
1600 |
ret = get_errno(setgid(low2highgid(arg1))); |
|
1601 |
break; |
|
1602 |
case TARGET_NR_getgid: |
|
1603 |
ret = get_errno(getgid()); |
|
1604 |
break; |
|
1605 | 1634 |
case TARGET_NR_signal: |
1606 | 1635 |
goto unimplemented; |
1607 |
case TARGET_NR_geteuid: |
|
1608 |
ret = get_errno(geteuid()); |
|
1609 |
break; |
|
1610 |
case TARGET_NR_getegid: |
|
1611 |
ret = get_errno(getegid()); |
|
1612 |
break; |
|
1636 |
|
|
1613 | 1637 |
case TARGET_NR_acct: |
1614 | 1638 |
goto unimplemented; |
1615 | 1639 |
case TARGET_NR_umount2: |
... | ... | |
1844 | 1868 |
/* NOTE: ret is eax, so not transcoding must be done */ |
1845 | 1869 |
ret = do_rt_sigreturn(cpu_env); |
1846 | 1870 |
break; |
1847 |
case TARGET_NR_setreuid: |
|
1848 |
ret = get_errno(setreuid(arg1, arg2)); |
|
1849 |
break; |
|
1850 |
case TARGET_NR_setregid: |
|
1851 |
ret = get_errno(setregid(arg1, arg2)); |
|
1852 |
break; |
|
1853 | 1871 |
case TARGET_NR_sethostname: |
1854 | 1872 |
ret = get_errno(sethostname((const char *)arg1, arg2)); |
1855 | 1873 |
break; |
... | ... | |
1906 | 1924 |
ret = get_errno(settimeofday(&tv, NULL)); |
1907 | 1925 |
} |
1908 | 1926 |
break; |
1909 |
case TARGET_NR_getgroups: |
|
1910 |
{ |
|
1911 |
int gidsetsize = arg1; |
|
1912 |
uint16_t *target_grouplist = (void *)arg2; |
|
1913 |
gid_t *grouplist; |
|
1914 |
int i; |
|
1915 |
|
|
1916 |
grouplist = alloca(gidsetsize * sizeof(gid_t)); |
|
1917 |
ret = get_errno(getgroups(gidsetsize, grouplist)); |
|
1918 |
if (!is_error(ret)) { |
|
1919 |
for(i = 0;i < gidsetsize; i++) |
|
1920 |
target_grouplist[i] = tswap16(grouplist[i]); |
|
1921 |
} |
|
1922 |
} |
|
1923 |
break; |
|
1924 |
case TARGET_NR_setgroups: |
|
1925 |
{ |
|
1926 |
int gidsetsize = arg1; |
|
1927 |
uint16_t *target_grouplist = (void *)arg2; |
|
1928 |
gid_t *grouplist; |
|
1929 |
int i; |
|
1930 |
|
|
1931 |
grouplist = alloca(gidsetsize * sizeof(gid_t)); |
|
1932 |
for(i = 0;i < gidsetsize; i++) |
|
1933 |
grouplist[i] = tswap16(target_grouplist[i]); |
|
1934 |
ret = get_errno(setgroups(gidsetsize, grouplist)); |
|
1935 |
} |
|
1936 |
break; |
|
1937 | 1927 |
case TARGET_NR_select: |
1938 | 1928 |
{ |
1939 | 1929 |
struct target_sel_arg_struct *sel = (void *)arg1; |
... | ... | |
2026 | 2016 |
case TARGET_NR_fchmod: |
2027 | 2017 |
ret = get_errno(fchmod(arg1, arg2)); |
2028 | 2018 |
break; |
2029 |
case TARGET_NR_fchown: |
|
2030 |
ret = get_errno(fchown(arg1, arg2, arg3)); |
|
2031 |
break; |
|
2032 | 2019 |
case TARGET_NR_getpriority: |
2033 | 2020 |
ret = get_errno(getpriority(arg1, arg2)); |
2034 | 2021 |
break; |
... | ... | |
2121 | 2108 |
struct target_stat *target_st = (void *)arg2; |
2122 | 2109 |
target_st->st_dev = tswap16(st.st_dev); |
2123 | 2110 |
target_st->st_ino = tswapl(st.st_ino); |
2111 |
#if defined(TARGET_PPC) |
|
2112 |
target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */ |
|
2113 |
target_st->st_uid = tswap32(st.st_uid); |
|
2114 |
target_st->st_gid = tswap32(st.st_gid); |
|
2115 |
#else |
|
2124 | 2116 |
target_st->st_mode = tswap16(st.st_mode); |
2125 |
target_st->st_nlink = tswap16(st.st_nlink); |
|
2126 | 2117 |
target_st->st_uid = tswap16(st.st_uid); |
2127 | 2118 |
target_st->st_gid = tswap16(st.st_gid); |
2119 |
#endif |
|
2120 |
target_st->st_nlink = tswap16(st.st_nlink); |
|
2128 | 2121 |
target_st->st_rdev = tswap16(st.st_rdev); |
2129 | 2122 |
target_st->st_size = tswapl(st.st_size); |
2130 | 2123 |
target_st->st_blksize = tswapl(st.st_blksize); |
... | ... | |
2230 | 2223 |
break; |
2231 | 2224 |
case TARGET_NR_afs_syscall: |
2232 | 2225 |
goto unimplemented; |
2233 |
case TARGET_NR_setfsuid: |
|
2234 |
ret = get_errno(setfsuid(arg1)); |
|
2235 |
break; |
|
2236 |
case TARGET_NR_setfsgid: |
|
2237 |
ret = get_errno(setfsgid(arg1)); |
|
2238 |
break; |
|
2239 | 2226 |
case TARGET_NR__llseek: |
2240 | 2227 |
{ |
2241 | 2228 |
int64_t res; |
... | ... | |
2465 | 2452 |
} |
2466 | 2453 |
} |
2467 | 2454 |
break; |
2468 |
#ifdef TARGET_NR_setresuid |
|
2469 |
case TARGET_NR_setresuid: |
|
2470 |
ret = get_errno(setresuid(low2highuid(arg1), |
|
2471 |
low2highuid(arg2), |
|
2472 |
low2highuid(arg3))); |
|
2473 |
break; |
|
2474 |
#endif |
|
2475 |
#ifdef TARGET_NR_getresuid |
|
2476 |
case TARGET_NR_getresuid: |
|
2477 |
{ |
|
2478 |
int ruid, euid, suid; |
|
2479 |
ret = get_errno(getresuid(&ruid, &euid, &suid)); |
|
2480 |
if (!is_error(ret)) { |
|
2481 |
*(uint16_t *)arg1 = tswap16(high2lowuid(ruid)); |
|
2482 |
*(uint16_t *)arg2 = tswap16(high2lowuid(euid)); |
|
2483 |
*(uint16_t *)arg3 = tswap16(high2lowuid(suid)); |
|
2484 |
} |
|
2485 |
} |
|
2486 |
break; |
|
2487 |
#endif |
|
2488 |
#ifdef TARGET_NR_getresgid |
|
2489 |
case TARGET_NR_setresgid: |
|
2490 |
ret = get_errno(setresgid(low2highgid(arg1), |
|
2491 |
low2highgid(arg2), |
|
2492 |
low2highgid(arg3))); |
|
2493 |
break; |
|
2494 |
#endif |
|
2495 |
#ifdef TARGET_NR_getresgid |
|
2496 |
case TARGET_NR_getresgid: |
|
2497 |
{ |
|
2498 |
int rgid, egid, sgid; |
|
2499 |
ret = get_errno(getresgid(&rgid, &egid, &sgid)); |
|
2500 |
if (!is_error(ret)) { |
|
2501 |
*(uint16_t *)arg1 = high2lowgid(tswap16(rgid)); |
|
2502 |
*(uint16_t *)arg2 = high2lowgid(tswap16(egid)); |
|
2503 |
*(uint16_t *)arg3 = high2lowgid(tswap16(sgid)); |
|
2504 |
} |
|
2505 |
} |
|
2506 |
break; |
|
2507 |
#endif |
|
2508 | 2455 |
case TARGET_NR_query_module: |
2509 | 2456 |
goto unimplemented; |
2510 | 2457 |
case TARGET_NR_nfsservctl: |
2511 | 2458 |
goto unimplemented; |
2512 | 2459 |
case TARGET_NR_prctl: |
2513 | 2460 |
goto unimplemented; |
2461 |
#ifdef TARGET_NR_pread |
|
2514 | 2462 |
case TARGET_NR_pread: |
2515 | 2463 |
page_unprotect_range((void *)arg2, arg3); |
2516 | 2464 |
ret = get_errno(pread(arg1, (void *)arg2, arg3, arg4)); |
... | ... | |
2518 | 2466 |
case TARGET_NR_pwrite: |
2519 | 2467 |
ret = get_errno(pwrite(arg1, (void *)arg2, arg3, arg4)); |
2520 | 2468 |
break; |
2521 |
case TARGET_NR_chown: |
|
2522 |
ret = get_errno(chown((const char *)arg1, arg2, arg3)); |
|
2523 |
break; |
|
2469 |
#endif |
|
2524 | 2470 |
case TARGET_NR_getcwd: |
2525 | 2471 |
ret = get_errno(sys_getcwd1((char *)arg1, arg2)); |
2526 | 2472 |
break; |
... | ... | |
2594 | 2540 |
} |
2595 | 2541 |
break; |
2596 | 2542 |
|
2543 |
#ifdef USE_UID16 |
|
2544 |
case TARGET_NR_lchown: |
|
2545 |
ret = get_errno(lchown((const char *)arg1, low2highuid(arg2), low2highgid(arg3))); |
|
2546 |
break; |
|
2547 |
case TARGET_NR_getuid: |
|
2548 |
ret = get_errno(high2lowuid(getuid())); |
|
2549 |
break; |
|
2550 |
case TARGET_NR_getgid: |
|
2551 |
ret = get_errno(high2lowgid(getgid())); |
|
2552 |
break; |
|
2553 |
case TARGET_NR_geteuid: |
|
2554 |
ret = get_errno(high2lowuid(geteuid())); |
|
2555 |
break; |
|
2556 |
case TARGET_NR_getegid: |
|
2557 |
ret = get_errno(high2lowgid(getegid())); |
|
2558 |
break; |
|
2559 |
case TARGET_NR_setreuid: |
|
2560 |
ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2))); |
|
2561 |
break; |
|
2562 |
case TARGET_NR_setregid: |
|
2563 |
ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2))); |
|
2564 |
break; |
|
2565 |
case TARGET_NR_getgroups: |
|
2566 |
{ |
|
2567 |
int gidsetsize = arg1; |
|
2568 |
uint16_t *target_grouplist = (void *)arg2; |
|
2569 |
gid_t *grouplist; |
|
2570 |
int i; |
|
2571 |
|
|
2572 |
grouplist = alloca(gidsetsize * sizeof(gid_t)); |
|
2573 |
ret = get_errno(getgroups(gidsetsize, grouplist)); |
|
2574 |
if (!is_error(ret)) { |
|
2575 |
for(i = 0;i < gidsetsize; i++) |
|
2576 |
target_grouplist[i] = tswap16(grouplist[i]); |
|
2577 |
} |
|
2578 |
} |
|
2579 |
break; |
|
2580 |
case TARGET_NR_setgroups: |
|
2581 |
{ |
|
2582 |
int gidsetsize = arg1; |
|
2583 |
uint16_t *target_grouplist = (void *)arg2; |
|
2584 |
gid_t *grouplist; |
|
2585 |
int i; |
|
2586 |
|
|
2587 |
grouplist = alloca(gidsetsize * sizeof(gid_t)); |
|
2588 |
for(i = 0;i < gidsetsize; i++) |
|
2589 |
grouplist[i] = tswap16(target_grouplist[i]); |
|
2590 |
ret = get_errno(setgroups(gidsetsize, grouplist)); |
|
2591 |
} |
|
2592 |
break; |
|
2593 |
case TARGET_NR_fchown: |
|
2594 |
ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3))); |
|
2595 |
break; |
|
2596 |
#ifdef TARGET_NR_setresuid |
|
2597 |
case TARGET_NR_setresuid: |
|
2598 |
ret = get_errno(setresuid(low2highuid(arg1), |
|
2599 |
low2highuid(arg2), |
|
2600 |
low2highuid(arg3))); |
|
2601 |
break; |
|
2602 |
#endif |
|
2603 |
#ifdef TARGET_NR_getresuid |
|
2604 |
case TARGET_NR_getresuid: |
|
2605 |
{ |
|
2606 |
int ruid, euid, suid; |
|
2607 |
ret = get_errno(getresuid(&ruid, &euid, &suid)); |
|
2608 |
if (!is_error(ret)) { |
|
2609 |
*(uint16_t *)arg1 = tswap16(high2lowuid(ruid)); |
|
2610 |
*(uint16_t *)arg2 = tswap16(high2lowuid(euid)); |
|
2611 |
*(uint16_t *)arg3 = tswap16(high2lowuid(suid)); |
|
2612 |
} |
|
2613 |
} |
|
2614 |
break; |
|
2615 |
#endif |
|
2616 |
#ifdef TARGET_NR_getresgid |
|
2617 |
case TARGET_NR_setresgid: |
|
2618 |
ret = get_errno(setresgid(low2highgid(arg1), |
|
2619 |
low2highgid(arg2), |
|
2620 |
low2highgid(arg3))); |
|
2621 |
break; |
|
2622 |
#endif |
|
2623 |
#ifdef TARGET_NR_getresgid |
|
2624 |
case TARGET_NR_getresgid: |
|
2625 |
{ |
|
2626 |
int rgid, egid, sgid; |
|
2627 |
ret = get_errno(getresgid(&rgid, &egid, &sgid)); |
|
2628 |
if (!is_error(ret)) { |
|
2629 |
*(uint16_t *)arg1 = tswap16(high2lowgid(rgid)); |
|
2630 |
*(uint16_t *)arg2 = tswap16(high2lowgid(egid)); |
|
2631 |
*(uint16_t *)arg3 = tswap16(high2lowgid(sgid)); |
|
2632 |
} |
|
2633 |
} |
|
2634 |
break; |
|
2635 |
#endif |
|
2636 |
case TARGET_NR_chown: |
|
2637 |
ret = get_errno(chown((const char *)arg1, low2highuid(arg2), low2highgid(arg3))); |
|
2638 |
break; |
|
2639 |
case TARGET_NR_setuid: |
|
2640 |
ret = get_errno(setuid(low2highuid(arg1))); |
|
2641 |
break; |
|
2642 |
case TARGET_NR_setgid: |
|
2643 |
ret = get_errno(setgid(low2highgid(arg1))); |
|
2644 |
break; |
|
2645 |
case TARGET_NR_setfsuid: |
|
2646 |
ret = get_errno(setfsuid(arg1)); |
|
2647 |
break; |
|
2648 |
case TARGET_NR_setfsgid: |
|
2649 |
ret = get_errno(setfsgid(arg1)); |
|
2650 |
break; |
|
2651 |
#endif /* USE_UID16 */ |
|
2652 |
|
|
2597 | 2653 |
case TARGET_NR_lchown32: |
2598 | 2654 |
ret = get_errno(lchown((const char *)arg1, arg2, arg3)); |
2599 | 2655 |
break; |
... | ... | |
2665 | 2721 |
case TARGET_NR_setfsgid32: |
2666 | 2722 |
ret = get_errno(setfsgid(arg1)); |
2667 | 2723 |
break; |
2724 |
|
|
2668 | 2725 |
case TARGET_NR_pivot_root: |
2669 | 2726 |
goto unimplemented; |
2670 | 2727 |
case TARGET_NR_mincore: |
b/linux-user/syscall_defs.h | ||
---|---|---|
279 | 279 |
int do_sigaction(int sig, const struct target_sigaction *act, |
280 | 280 |
struct target_sigaction *oact); |
281 | 281 |
|
282 |
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) |
|
282 |
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC)
|
|
283 | 283 |
|
284 | 284 |
#define TARGET_SA_NOCLDSTOP 0x00000001 |
285 | 285 |
#define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */ |
... | ... | |
664 | 664 |
#define TARGET_HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */ |
665 | 665 |
|
666 | 666 |
|
667 |
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) |
|
667 |
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC)
|
|
668 | 668 |
|
669 | 669 |
/* 0x54 is just a magic number to make these relatively unique ('T') */ |
670 | 670 |
|
... | ... | |
891 | 891 |
#define TARGET_MAP_LOCKED 0x2000 /* pages are locked */ |
892 | 892 |
#define TARGET_MAP_NORESERVE 0x4000 /* don't check for reservations */ |
893 | 893 |
|
894 |
#endif /* defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) */ |
|
895 |
|
|
896 |
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) |
|
894 | 897 |
struct target_stat { |
895 | 898 |
unsigned short st_dev; |
896 | 899 |
unsigned short __pad1; |
... | ... | |
951 | 954 |
unsigned long long st_ino; |
952 | 955 |
} __attribute__((packed)); |
953 | 956 |
|
954 |
#endif /* defined(TARGET_I386) || defined(TARGET_ARM) */ |
|
957 |
#elif defined(TARGET_PPC) |
|
958 |
|
|
959 |
struct target_stat { |
|
960 |
unsigned short st_dev; |
|
961 |
target_ulong st_ino; |
|
962 |
unsigned int st_mode; |
|
963 |
unsigned short st_nlink; |
|
964 |
unsigned int st_uid; |
|
965 |
unsigned int st_gid; |
|
966 |
unsigned short st_rdev; |
|
967 |
target_ulong st_size; |
|
968 |
target_ulong st_blksize; |
|
969 |
target_ulong st_blocks; |
|
970 |
target_ulong target_st_atime; |
|
971 |
target_ulong __unused1; |
|
972 |
target_ulong target_st_mtime; |
|
973 |
target_ulong __unused2; |
|
974 |
target_ulong target_st_ctime; |
|
975 |
target_ulong __unused3; |
|
976 |
target_ulong __unused4; |
|
977 |
target_ulong __unused5; |
|
978 |
}; |
|
979 |
|
|
980 |
struct target_stat64 { |
|
981 |
unsigned long long st_dev; |
|
982 |
|
|
983 |
unsigned long long st_ino; |
|
984 |
|
|
985 |
unsigned int st_mode; |
|
986 |
unsigned int st_nlink; |
|
987 |
|
|
988 |
unsigned int st_uid; |
|
989 |
unsigned int st_gid; |
|
990 |
|
|
991 |
unsigned long long st_rdev; |
|
992 |
unsigned short int __pad2; |
|
993 |
|
|
994 |
long long st_size; |
|
995 |
target_ulong st_blksize; |
|
996 |
|
|
997 |
long long st_blocks; /* Number 512-byte blocks allocated. */ |
|
998 |
|
|
999 |
target_ulong target_st_atime; |
|
1000 |
target_ulong target_st_atime_nsec; |
|
1001 |
|
|
1002 |
target_ulong target_st_mtime; |
|
1003 |
target_ulong target_st_mtime_nsec; |
|
1004 |
|
|
1005 |
target_ulong target_st_ctime; |
|
1006 |
target_ulong target_st_ctime_nsec; |
|
1007 |
|
|
1008 |
target_ulong __unused4; |
|
1009 |
target_ulong __unused5; |
|
1010 |
}; |
|
1011 |
|
|
1012 |
#endif /* defined(TARGET_PPC) */ |
|
955 | 1013 |
|
956 | 1014 |
#define TARGET_F_DUPFD 0 /* dup */ |
957 | 1015 |
#define TARGET_F_GETFD 1 /* get close_on_exec */ |
Also available in: Unified diff