mirror of https://github.com/xemu-project/xemu.git
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
This commit is contained in:
parent
28b6751f30
commit
678673089d
|
@ -9,7 +9,8 @@ version 0.5.1:
|
|||
- IRET and INT fixes in VM86 mode with IOPL=3
|
||||
- Port I/Os use TSS io map
|
||||
- Full task switching/task gate support
|
||||
- added verr, verw, arpl
|
||||
- added verr, verw, arpl, fcmovxx
|
||||
- PowerPC target support (Jocelyn Mayer)
|
||||
|
||||
version 0.5.0:
|
||||
|
||||
|
|
|
@ -146,6 +146,10 @@ ifeq ($(TARGET_ARCH), i386)
|
|||
LIBOBJS+=helper.o helper2.o
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_ARCH), ppc)
|
||||
LIBOBJS+=helper.o
|
||||
endif
|
||||
|
||||
# NOTE: the disassembler code is only needed for debugging
|
||||
LIBOBJS+=disas.o
|
||||
ifeq ($(findstring i386, $(TARGET_ARCH) $(ARCH)),i386)
|
||||
|
|
|
@ -27,7 +27,7 @@ ar="ar"
|
|||
make="make"
|
||||
strip="strip"
|
||||
cpu=`uname -m`
|
||||
target_list="i386-user i386 i386-softmmu arm-user sparc-user"
|
||||
target_list="i386-user i386 i386-softmmu arm-user sparc-user ppc-user"
|
||||
case "$cpu" in
|
||||
i386|i486|i586|i686|i86pc|BePC)
|
||||
cpu="i386"
|
||||
|
@ -322,6 +322,7 @@ config_h=$target_dir/config.h
|
|||
target_cpu=`echo $target | cut -d '-' -f 1`
|
||||
target_bigendian="no"
|
||||
[ "$target_cpu" = "sparc" ] && target_bigendian=yes
|
||||
[ "$target_cpu" = "ppc" ] && target_bigendian=yes
|
||||
target_softmmu="no"
|
||||
if expr $target : '.*-softmmu' > /dev/null ; then
|
||||
target_softmmu="yes"
|
||||
|
@ -358,6 +359,10 @@ elif test "$target_cpu" = "sparc" ; then
|
|||
echo "TARGET_ARCH=sparc" >> $config_mak
|
||||
echo "#define TARGET_ARCH \"sparc\"" >> $config_h
|
||||
echo "#define TARGET_SPARC 1" >> $config_h
|
||||
elif test "$target_cpu" = "ppc" ; then
|
||||
echo "TARGET_ARCH=ppc" >> $config_mak
|
||||
echo "#define TARGET_ARCH \"ppc\"" >> $config_h
|
||||
echo "#define TARGET_PPC 1" >> $config_h
|
||||
else
|
||||
echo "Unsupported target CPU"
|
||||
exit 1
|
||||
|
|
|
@ -395,6 +395,15 @@ void page_unprotect_range(uint8_t *data, unsigned long data_size);
|
|||
#define cpu_interrupt cpu_sparc_interrupt
|
||||
#define cpu_signal_handler cpu_sparc_signal_handler
|
||||
|
||||
#elif defined(TARGET_PPC)
|
||||
|
||||
#define CPUState CPUPPCState
|
||||
#define cpu_init cpu_ppc_init
|
||||
#define cpu_exec cpu_ppc_exec
|
||||
#define cpu_gen_code cpu_ppc_gen_code
|
||||
#define cpu_interrupt cpu_ppc_interrupt
|
||||
#define cpu_signal_handler cpu_ppc_signal_handler
|
||||
|
||||
#else
|
||||
|
||||
#error unsupported target CPU
|
||||
|
|
59
cpu-exec.c
59
cpu-exec.c
|
@ -133,6 +133,7 @@ int cpu_exec(CPUState *env1)
|
|||
env->cpsr = psr & ~0xf0000000;
|
||||
}
|
||||
#elif defined(TARGET_SPARC)
|
||||
#elif defined(TARGET_PPC)
|
||||
#else
|
||||
#error unsupported target CPU
|
||||
#endif
|
||||
|
@ -228,6 +229,8 @@ int cpu_exec(CPUState *env1)
|
|||
env->cpsr &= ~0xf0000000;
|
||||
#elif defined(TARGET_SPARC)
|
||||
cpu_sparc_dump_state (env, logfile, 0);
|
||||
#elif defined(TARGET_PPC)
|
||||
cpu_ppc_dump_state(env, logfile, 0);
|
||||
#else
|
||||
#error unsupported target CPU
|
||||
#endif
|
||||
|
@ -246,13 +249,17 @@ int cpu_exec(CPUState *env1)
|
|||
cs_base = 0;
|
||||
pc = (uint8_t *)env->regs[15];
|
||||
#elif defined(TARGET_SPARC)
|
||||
flags = 0;
|
||||
cs_base = 0;
|
||||
if (env->npc) {
|
||||
env->pc = env->npc;
|
||||
env->npc = 0;
|
||||
}
|
||||
pc = (uint8_t *) env->pc;
|
||||
flags = 0;
|
||||
cs_base = 0;
|
||||
if (env->npc) {
|
||||
env->pc = env->npc;
|
||||
env->npc = 0;
|
||||
}
|
||||
pc = (uint8_t *) env->pc;
|
||||
#elif defined(TARGET_PPC)
|
||||
flags = 0;
|
||||
cs_base = 0;
|
||||
pc = (uint8_t *)env->nip;
|
||||
#else
|
||||
#error unsupported CPU
|
||||
#endif
|
||||
|
@ -376,6 +383,7 @@ int cpu_exec(CPUState *env1)
|
|||
#elif defined(TARGET_ARM)
|
||||
env->cpsr = compute_cpsr();
|
||||
#elif defined(TARGET_SPARC)
|
||||
#elif defined(TARGET_PPC)
|
||||
#else
|
||||
#error unsupported target CPU
|
||||
#endif
|
||||
|
@ -513,6 +521,43 @@ static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
#elif defined (TARGET_PPC)
|
||||
static inline int handle_cpu_signal(unsigned long pc, unsigned long address,
|
||||
int is_write, sigset_t *old_set)
|
||||
{
|
||||
TranslationBlock *tb;
|
||||
|
||||
#if 0
|
||||
if (cpu_single_env)
|
||||
env = cpu_single_env; /* XXX: find a correct solution for multithread */
|
||||
#endif
|
||||
#if defined(DEBUG_SIGNAL)
|
||||
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx w=%d oldset=0x%08lx\n",
|
||||
pc, address, is_write, *(unsigned long *)old_set);
|
||||
#endif
|
||||
/* XXX: locking issue */
|
||||
if (is_write && page_unprotect(address)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* now we have a real cpu fault */
|
||||
tb = tb_find_pc(pc);
|
||||
if (tb) {
|
||||
/* the PC is inside the translated code. It means that we have
|
||||
a virtual CPU fault */
|
||||
cpu_restore_state(tb, env, pc);
|
||||
}
|
||||
#if 0
|
||||
printf("PF exception: EIP=0x%08x CR2=0x%08x error=0x%x\n",
|
||||
env->eip, env->cr[2], env->error_code);
|
||||
#endif
|
||||
/* we restore the process signal mask as the sigreturn should
|
||||
do it (XXX: use sigsetjmp) */
|
||||
sigprocmask(SIG_SETMASK, old_set, NULL);
|
||||
raise_exception_err(EXCP_PROGRAM, env->error_code);
|
||||
/* never comes here */
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
#error unsupported target CPU
|
||||
#endif
|
||||
|
|
2
disas.c
2
disas.c
|
@ -171,6 +171,8 @@ void disas(FILE *out, void *code, unsigned long size, int is_host, int flags)
|
|||
print_insn = print_insn_arm;
|
||||
#elif defined(TARGET_SPARC)
|
||||
print_insn = print_insn_sparc;
|
||||
#elif defined(TARGET_PPC)
|
||||
print_insn = print_insn_ppc;
|
||||
#else
|
||||
fprintf(out, "Asm output not supported on this arch\n");
|
||||
return;
|
||||
|
|
|
@ -17,6 +17,9 @@
|
|||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#if !defined(__DYNGEN_EXEC_H__)
|
||||
#define __DYNGEN_EXEC_H__
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
typedef unsigned short uint16_t;
|
||||
typedef unsigned int uint32_t;
|
||||
|
@ -27,6 +30,19 @@ typedef signed short int16_t;
|
|||
typedef signed int int32_t;
|
||||
typedef signed long long int64_t;
|
||||
|
||||
#define INT8_MIN (-128)
|
||||
#define INT16_MIN (-32767-1)
|
||||
#define INT32_MIN (-2147483647-1)
|
||||
#define INT64_MIN (-(int64_t)(9223372036854775807)-1)
|
||||
#define INT8_MAX (127)
|
||||
#define INT16_MAX (32767)
|
||||
#define INT32_MAX (2147483647)
|
||||
#define INT64_MAX ((int64_t)(9223372036854775807))
|
||||
#define UINT8_MAX (255)
|
||||
#define UINT16_MAX (65535)
|
||||
#define UINT32_MAX (4294967295U)
|
||||
#define UINT64_MAX ((uint64_t)(18446744073709551615))
|
||||
|
||||
#define bswap32(x) \
|
||||
({ \
|
||||
uint32_t __x = (x); \
|
||||
|
@ -191,3 +207,5 @@ extern int __op_jmp0, __op_jmp1, __op_jmp2, __op_jmp3;
|
|||
#ifdef __mc68000
|
||||
#define EXIT_TB() asm volatile ("rts")
|
||||
#endif
|
||||
|
||||
#endif /* !defined(__DYNGEN_EXEC_H__) */
|
||||
|
|
|
@ -104,6 +104,46 @@ static inline void init_thread(struct target_pt_regs *regs, struct image_info *i
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_PPC
|
||||
|
||||
#define ELF_START_MMAP 0x80000000
|
||||
|
||||
#define elf_check_arch(x) ( (x) == EM_PPC )
|
||||
|
||||
#define ELF_CLASS ELFCLASS32
|
||||
#ifdef TARGET_WORDS_BIGENDIAN
|
||||
#define ELF_DATA ELFDATA2MSB
|
||||
#else
|
||||
#define ELF_DATA ELFDATA2LSB
|
||||
#endif
|
||||
#define ELF_ARCH EM_PPC
|
||||
|
||||
/* Note that isn't exactly what regular kernel does
|
||||
* but this is what the ABI wants and is needed to allow
|
||||
* execution of PPC BSD programs.
|
||||
*/
|
||||
#define ELF_PLAT_INIT(_r) \
|
||||
do { \
|
||||
unsigned long *pos = (unsigned long *)bprm->p, tmp = 1; \
|
||||
_r->gpr[3] = bprm->argc; \
|
||||
_r->gpr[4] = (unsigned long)++pos; \
|
||||
for (; tmp != 0; pos++) \
|
||||
tmp = *pos; \
|
||||
_r->gpr[5] = (unsigned long)pos; \
|
||||
} while (0)
|
||||
|
||||
static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop)
|
||||
{
|
||||
_regs->msr = 1 << MSR_PR; /* Set user mode */
|
||||
_regs->gpr[1] = infop->start_stack;
|
||||
_regs->nip = infop->entry;
|
||||
}
|
||||
|
||||
#define USE_ELF_CORE_DUMP
|
||||
#define ELF_EXEC_PAGESIZE 4096
|
||||
|
||||
#endif
|
||||
|
||||
#include "elf.h"
|
||||
|
||||
/*
|
||||
|
|
|
@ -324,6 +324,127 @@ void cpu_loop (CPUSPARCState *env)
|
|||
|
||||
#endif
|
||||
|
||||
#ifdef TARGET_PPC
|
||||
|
||||
void cpu_loop(CPUPPCState *env)
|
||||
{
|
||||
int trapnr;
|
||||
target_siginfo_t info;
|
||||
|
||||
for(;;) {
|
||||
trapnr = cpu_ppc_exec(env);
|
||||
switch(trapnr) {
|
||||
case EXCP_NONE:
|
||||
case EXCP_INTERRUPT:
|
||||
case EXCP_MTMSR: /* mtmsr instruction: */
|
||||
case EXCP_BRANCH: /* branch instruction */
|
||||
/* Single step mode */
|
||||
break;
|
||||
#if 0
|
||||
case EXCP_RESET: /* System reset */
|
||||
fprintf(stderr, "RESET asked... Stop emulation\n");
|
||||
cpu_ppc_dump_state(env, stderr, 0);
|
||||
abort();
|
||||
#endif
|
||||
case EXCP_MACHINE_CHECK: /* Machine check exception */
|
||||
fprintf(stderr, "Machine check exeption... "
|
||||
"See you in kernel code !\n");
|
||||
cpu_ppc_dump_state(env, stderr, 0);
|
||||
abort();
|
||||
case EXCP_DSI: /* Impossible memory access */
|
||||
fprintf(stderr, "Invalid memory access\n");
|
||||
info.si_signo = SIGSEGV;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(info.si_signo, &info);
|
||||
break;
|
||||
case EXCP_ISI: /* Impossible instruction fetch */
|
||||
fprintf(stderr, "Invalid instruction fetch\n");
|
||||
info.si_signo = SIGBUS;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(info.si_signo, &info);
|
||||
break;
|
||||
case EXCP_EXTERNAL: /* External interruption */
|
||||
fprintf(stderr, "External access exeption\n");
|
||||
cpu_ppc_dump_state(env, stderr, 0);
|
||||
abort();
|
||||
case EXCP_ALIGN: /* Alignment exception */
|
||||
fprintf(stderr, "Alignment exception\n");
|
||||
cpu_ppc_dump_state(env, stderr, 0);
|
||||
abort();
|
||||
case EXCP_PROGRAM: /* Program exception */
|
||||
fprintf(stderr, "Program exception\n");
|
||||
cpu_ppc_dump_state(env, stderr, 0);
|
||||
abort();
|
||||
break;
|
||||
/* Trap */
|
||||
case EXCP_TRAP: /* Trap */
|
||||
case EXCP_TRACE: /* Trace exception (optional) */
|
||||
info.si_signo = SIGTRAP;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(info.si_signo, &info);
|
||||
break;
|
||||
/* Invalid instruction */
|
||||
case EXCP_INVAL:
|
||||
info.si_signo = SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(info.si_signo, &info);
|
||||
break;
|
||||
/* Privileged instruction */
|
||||
case EXCP_PRIV: /* Privileged instruction */
|
||||
info.si_signo = SIGILL;
|
||||
info.si_errno = 0;
|
||||
info.si_code = TARGET_ILL_ILLOPN;
|
||||
info._sifields._sigfault._addr = env->nip;
|
||||
queue_signal(info.si_signo, &info);
|
||||
break;
|
||||
case EXCP_NO_FP: /* No floating point */
|
||||
case EXCP_DECR: /* Decrementer exception */
|
||||
case EXCP_RESA: /* Implementation specific */
|
||||
case EXCP_RESB: /* Implementation specific */
|
||||
case EXCP_FP_ASSIST: /* Floating-point assist (optional) */
|
||||
fprintf(stderr, "Misc expt...\n");
|
||||
cpu_ppc_dump_state(env, stderr, 0);
|
||||
abort();
|
||||
|
||||
case EXCP_SYSCALL:
|
||||
{
|
||||
uint32_t ret;
|
||||
/* system call */
|
||||
/* WARNING:
|
||||
* PPC ABI uses overflow flag in cr0 to signal an error
|
||||
* in syscalls.
|
||||
*/
|
||||
env->crf[0] &= ~0x1;
|
||||
ret = do_syscall(env, env->gpr[0], env->gpr[3], env->gpr[4],
|
||||
env->gpr[5], env->gpr[6], env->gpr[7],
|
||||
env->gpr[8]);
|
||||
if (ret > (uint32_t)(-515)) {
|
||||
env->crf[0] |= 0x1;
|
||||
ret = -ret;
|
||||
}
|
||||
env->gpr[3] = ret;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// error:
|
||||
fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n",
|
||||
trapnr);
|
||||
cpu_ppc_dump_state(env, stderr, 0);
|
||||
abort();
|
||||
}
|
||||
process_pending_signals(env);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void usage(void)
|
||||
{
|
||||
printf("qemu-" TARGET_ARCH " version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
|
||||
|
@ -517,6 +638,16 @@ int main(int argc, char **argv)
|
|||
#elif defined(TARGET_SPARC)
|
||||
env->pc = regs->u_regs[0];
|
||||
env->regwptr[6] = regs->u_regs[1]-0x40;
|
||||
#elif defined(TARGET_PPC)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 32; i++)
|
||||
env->msr[i] = (regs->msr >> i) & 1;
|
||||
env->nip = regs->nip;
|
||||
for(i = 0; i < 32; i++) {
|
||||
env->gpr[i] = regs->gpr[i];
|
||||
}
|
||||
}
|
||||
#else
|
||||
#error unsupported target CPU
|
||||
#endif
|
||||
|
|
|
@ -65,6 +65,11 @@
|
|||
|
||||
//#define DEBUG
|
||||
|
||||
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
|
||||
/* 16 bit uid wrappers emulation */
|
||||
#define USE_UID16
|
||||
#endif
|
||||
|
||||
//#include <linux/msdos_fs.h>
|
||||
#define VFAT_IOCTL_READDIR_BOTH _IOR('r', 1, struct dirent [2])
|
||||
#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)
|
|||
new_env->regs[13] = newsp;
|
||||
new_env->regs[0] = 0;
|
||||
#elif defined(TARGET_SPARC)
|
||||
printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
|
||||
printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
|
||||
#elif defined(TARGET_PPC)
|
||||
if (!newsp)
|
||||
newsp = env->gpr[1];
|
||||
new_env->gpr[1] = newsp;
|
||||
{
|
||||
int i;
|
||||
for (i = 7; i < 32; i++)
|
||||
new_env->gpr[i] = 0;
|
||||
}
|
||||
#else
|
||||
#error unsupported target CPU
|
||||
#endif
|
||||
|
@ -1325,11 +1339,41 @@ static long do_fcntl(int fd, int cmd, unsigned long arg)
|
|||
return ret;
|
||||
}
|
||||
|
||||
#ifdef USE_UID16
|
||||
|
||||
#define high2lowuid(x) (x)
|
||||
#define high2lowgid(x) (x)
|
||||
#define low2highuid(x) (x)
|
||||
#define low2highgid(x) (x)
|
||||
static inline int high2lowuid(int uid)
|
||||
{
|
||||
if (uid > 65535)
|
||||
return 65534;
|
||||
else
|
||||
return uid;
|
||||
}
|
||||
|
||||
static inline int high2lowgid(int gid)
|
||||
{
|
||||
if (gid > 65535)
|
||||
return 65534;
|
||||
else
|
||||
return gid;
|
||||
}
|
||||
|
||||
static inline int low2highuid(int uid)
|
||||
{
|
||||
if ((int16_t)uid == -1)
|
||||
return -1;
|
||||
else
|
||||
return uid;
|
||||
}
|
||||
|
||||
static inline int low2highgid(int gid)
|
||||
{
|
||||
if ((int16_t)gid == -1)
|
||||
return -1;
|
||||
else
|
||||
return gid;
|
||||
}
|
||||
|
||||
#endif /* USE_UID16 */
|
||||
|
||||
void syscall_init(void)
|
||||
{
|
||||
|
@ -1472,9 +1516,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
|||
case TARGET_NR_chmod:
|
||||
ret = get_errno(chmod((const char *)arg1, arg2));
|
||||
break;
|
||||
case TARGET_NR_lchown:
|
||||
ret = get_errno(chown((const char *)arg1, arg2, arg3));
|
||||
break;
|
||||
#ifdef TARGET_NR_break
|
||||
case TARGET_NR_break:
|
||||
goto unimplemented;
|
||||
|
@ -1495,12 +1536,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
|||
case TARGET_NR_umount:
|
||||
ret = get_errno(umount((const char *)arg1));
|
||||
break;
|
||||
case TARGET_NR_setuid:
|
||||
ret = get_errno(setuid(low2highuid(arg1)));
|
||||
break;
|
||||
case TARGET_NR_getuid:
|
||||
ret = get_errno(getuid());
|
||||
break;
|
||||
case TARGET_NR_stime:
|
||||
{
|
||||
int *time_ptr = (int *)arg1;
|
||||
|
@ -1596,20 +1631,9 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
|||
case TARGET_NR_prof:
|
||||
goto unimplemented;
|
||||
#endif
|
||||
case TARGET_NR_setgid:
|
||||
ret = get_errno(setgid(low2highgid(arg1)));
|
||||
break;
|
||||
case TARGET_NR_getgid:
|
||||
ret = get_errno(getgid());
|
||||
break;
|
||||
case TARGET_NR_signal:
|
||||
goto unimplemented;
|
||||
case TARGET_NR_geteuid:
|
||||
ret = get_errno(geteuid());
|
||||
break;
|
||||
case TARGET_NR_getegid:
|
||||
ret = get_errno(getegid());
|
||||
break;
|
||||
|
||||
case TARGET_NR_acct:
|
||||
goto unimplemented;
|
||||
case TARGET_NR_umount2:
|
||||
|
@ -1844,12 +1868,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
|||
/* NOTE: ret is eax, so not transcoding must be done */
|
||||
ret = do_rt_sigreturn(cpu_env);
|
||||
break;
|
||||
case TARGET_NR_setreuid:
|
||||
ret = get_errno(setreuid(arg1, arg2));
|
||||
break;
|
||||
case TARGET_NR_setregid:
|
||||
ret = get_errno(setregid(arg1, arg2));
|
||||
break;
|
||||
case TARGET_NR_sethostname:
|
||||
ret = get_errno(sethostname((const char *)arg1, arg2));
|
||||
break;
|
||||
|
@ -1906,34 +1924,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
|||
ret = get_errno(settimeofday(&tv, NULL));
|
||||
}
|
||||
break;
|
||||
case TARGET_NR_getgroups:
|
||||
{
|
||||
int gidsetsize = arg1;
|
||||
uint16_t *target_grouplist = (void *)arg2;
|
||||
gid_t *grouplist;
|
||||
int i;
|
||||
|
||||
grouplist = alloca(gidsetsize * sizeof(gid_t));
|
||||
ret = get_errno(getgroups(gidsetsize, grouplist));
|
||||
if (!is_error(ret)) {
|
||||
for(i = 0;i < gidsetsize; i++)
|
||||
target_grouplist[i] = tswap16(grouplist[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TARGET_NR_setgroups:
|
||||
{
|
||||
int gidsetsize = arg1;
|
||||
uint16_t *target_grouplist = (void *)arg2;
|
||||
gid_t *grouplist;
|
||||
int i;
|
||||
|
||||
grouplist = alloca(gidsetsize * sizeof(gid_t));
|
||||
for(i = 0;i < gidsetsize; i++)
|
||||
grouplist[i] = tswap16(target_grouplist[i]);
|
||||
ret = get_errno(setgroups(gidsetsize, grouplist));
|
||||
}
|
||||
break;
|
||||
case TARGET_NR_select:
|
||||
{
|
||||
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,
|
|||
case TARGET_NR_fchmod:
|
||||
ret = get_errno(fchmod(arg1, arg2));
|
||||
break;
|
||||
case TARGET_NR_fchown:
|
||||
ret = get_errno(fchown(arg1, arg2, arg3));
|
||||
break;
|
||||
case TARGET_NR_getpriority:
|
||||
ret = get_errno(getpriority(arg1, arg2));
|
||||
break;
|
||||
|
@ -2121,10 +2108,16 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
|||
struct target_stat *target_st = (void *)arg2;
|
||||
target_st->st_dev = tswap16(st.st_dev);
|
||||
target_st->st_ino = tswapl(st.st_ino);
|
||||
#if defined(TARGET_PPC)
|
||||
target_st->st_mode = tswapl(st.st_mode); /* XXX: check this */
|
||||
target_st->st_uid = tswap32(st.st_uid);
|
||||
target_st->st_gid = tswap32(st.st_gid);
|
||||
#else
|
||||
target_st->st_mode = tswap16(st.st_mode);
|
||||
target_st->st_nlink = tswap16(st.st_nlink);
|
||||
target_st->st_uid = tswap16(st.st_uid);
|
||||
target_st->st_gid = tswap16(st.st_gid);
|
||||
#endif
|
||||
target_st->st_nlink = tswap16(st.st_nlink);
|
||||
target_st->st_rdev = tswap16(st.st_rdev);
|
||||
target_st->st_size = tswapl(st.st_size);
|
||||
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,
|
|||
break;
|
||||
case TARGET_NR_afs_syscall:
|
||||
goto unimplemented;
|
||||
case TARGET_NR_setfsuid:
|
||||
ret = get_errno(setfsuid(arg1));
|
||||
break;
|
||||
case TARGET_NR_setfsgid:
|
||||
ret = get_errno(setfsgid(arg1));
|
||||
break;
|
||||
case TARGET_NR__llseek:
|
||||
{
|
||||
int64_t res;
|
||||
|
@ -2465,52 +2452,13 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
|||
}
|
||||
}
|
||||
break;
|
||||
#ifdef TARGET_NR_setresuid
|
||||
case TARGET_NR_setresuid:
|
||||
ret = get_errno(setresuid(low2highuid(arg1),
|
||||
low2highuid(arg2),
|
||||
low2highuid(arg3)));
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_getresuid
|
||||
case TARGET_NR_getresuid:
|
||||
{
|
||||
int ruid, euid, suid;
|
||||
ret = get_errno(getresuid(&ruid, &euid, &suid));
|
||||
if (!is_error(ret)) {
|
||||
*(uint16_t *)arg1 = tswap16(high2lowuid(ruid));
|
||||
*(uint16_t *)arg2 = tswap16(high2lowuid(euid));
|
||||
*(uint16_t *)arg3 = tswap16(high2lowuid(suid));
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_getresgid
|
||||
case TARGET_NR_setresgid:
|
||||
ret = get_errno(setresgid(low2highgid(arg1),
|
||||
low2highgid(arg2),
|
||||
low2highgid(arg3)));
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_getresgid
|
||||
case TARGET_NR_getresgid:
|
||||
{
|
||||
int rgid, egid, sgid;
|
||||
ret = get_errno(getresgid(&rgid, &egid, &sgid));
|
||||
if (!is_error(ret)) {
|
||||
*(uint16_t *)arg1 = high2lowgid(tswap16(rgid));
|
||||
*(uint16_t *)arg2 = high2lowgid(tswap16(egid));
|
||||
*(uint16_t *)arg3 = high2lowgid(tswap16(sgid));
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case TARGET_NR_query_module:
|
||||
goto unimplemented;
|
||||
case TARGET_NR_nfsservctl:
|
||||
goto unimplemented;
|
||||
case TARGET_NR_prctl:
|
||||
goto unimplemented;
|
||||
#ifdef TARGET_NR_pread
|
||||
case TARGET_NR_pread:
|
||||
page_unprotect_range((void *)arg2, arg3);
|
||||
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,
|
|||
case TARGET_NR_pwrite:
|
||||
ret = get_errno(pwrite(arg1, (void *)arg2, arg3, arg4));
|
||||
break;
|
||||
case TARGET_NR_chown:
|
||||
ret = get_errno(chown((const char *)arg1, arg2, arg3));
|
||||
break;
|
||||
#endif
|
||||
case TARGET_NR_getcwd:
|
||||
ret = get_errno(sys_getcwd1((char *)arg1, arg2));
|
||||
break;
|
||||
|
@ -2594,6 +2540,116 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
|||
}
|
||||
break;
|
||||
|
||||
#ifdef USE_UID16
|
||||
case TARGET_NR_lchown:
|
||||
ret = get_errno(lchown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
|
||||
break;
|
||||
case TARGET_NR_getuid:
|
||||
ret = get_errno(high2lowuid(getuid()));
|
||||
break;
|
||||
case TARGET_NR_getgid:
|
||||
ret = get_errno(high2lowgid(getgid()));
|
||||
break;
|
||||
case TARGET_NR_geteuid:
|
||||
ret = get_errno(high2lowuid(geteuid()));
|
||||
break;
|
||||
case TARGET_NR_getegid:
|
||||
ret = get_errno(high2lowgid(getegid()));
|
||||
break;
|
||||
case TARGET_NR_setreuid:
|
||||
ret = get_errno(setreuid(low2highuid(arg1), low2highuid(arg2)));
|
||||
break;
|
||||
case TARGET_NR_setregid:
|
||||
ret = get_errno(setregid(low2highgid(arg1), low2highgid(arg2)));
|
||||
break;
|
||||
case TARGET_NR_getgroups:
|
||||
{
|
||||
int gidsetsize = arg1;
|
||||
uint16_t *target_grouplist = (void *)arg2;
|
||||
gid_t *grouplist;
|
||||
int i;
|
||||
|
||||
grouplist = alloca(gidsetsize * sizeof(gid_t));
|
||||
ret = get_errno(getgroups(gidsetsize, grouplist));
|
||||
if (!is_error(ret)) {
|
||||
for(i = 0;i < gidsetsize; i++)
|
||||
target_grouplist[i] = tswap16(grouplist[i]);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TARGET_NR_setgroups:
|
||||
{
|
||||
int gidsetsize = arg1;
|
||||
uint16_t *target_grouplist = (void *)arg2;
|
||||
gid_t *grouplist;
|
||||
int i;
|
||||
|
||||
grouplist = alloca(gidsetsize * sizeof(gid_t));
|
||||
for(i = 0;i < gidsetsize; i++)
|
||||
grouplist[i] = tswap16(target_grouplist[i]);
|
||||
ret = get_errno(setgroups(gidsetsize, grouplist));
|
||||
}
|
||||
break;
|
||||
case TARGET_NR_fchown:
|
||||
ret = get_errno(fchown(arg1, low2highuid(arg2), low2highgid(arg3)));
|
||||
break;
|
||||
#ifdef TARGET_NR_setresuid
|
||||
case TARGET_NR_setresuid:
|
||||
ret = get_errno(setresuid(low2highuid(arg1),
|
||||
low2highuid(arg2),
|
||||
low2highuid(arg3)));
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_getresuid
|
||||
case TARGET_NR_getresuid:
|
||||
{
|
||||
int ruid, euid, suid;
|
||||
ret = get_errno(getresuid(&ruid, &euid, &suid));
|
||||
if (!is_error(ret)) {
|
||||
*(uint16_t *)arg1 = tswap16(high2lowuid(ruid));
|
||||
*(uint16_t *)arg2 = tswap16(high2lowuid(euid));
|
||||
*(uint16_t *)arg3 = tswap16(high2lowuid(suid));
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_getresgid
|
||||
case TARGET_NR_setresgid:
|
||||
ret = get_errno(setresgid(low2highgid(arg1),
|
||||
low2highgid(arg2),
|
||||
low2highgid(arg3)));
|
||||
break;
|
||||
#endif
|
||||
#ifdef TARGET_NR_getresgid
|
||||
case TARGET_NR_getresgid:
|
||||
{
|
||||
int rgid, egid, sgid;
|
||||
ret = get_errno(getresgid(&rgid, &egid, &sgid));
|
||||
if (!is_error(ret)) {
|
||||
*(uint16_t *)arg1 = tswap16(high2lowgid(rgid));
|
||||
*(uint16_t *)arg2 = tswap16(high2lowgid(egid));
|
||||
*(uint16_t *)arg3 = tswap16(high2lowgid(sgid));
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case TARGET_NR_chown:
|
||||
ret = get_errno(chown((const char *)arg1, low2highuid(arg2), low2highgid(arg3)));
|
||||
break;
|
||||
case TARGET_NR_setuid:
|
||||
ret = get_errno(setuid(low2highuid(arg1)));
|
||||
break;
|
||||
case TARGET_NR_setgid:
|
||||
ret = get_errno(setgid(low2highgid(arg1)));
|
||||
break;
|
||||
case TARGET_NR_setfsuid:
|
||||
ret = get_errno(setfsuid(arg1));
|
||||
break;
|
||||
case TARGET_NR_setfsgid:
|
||||
ret = get_errno(setfsgid(arg1));
|
||||
break;
|
||||
#endif /* USE_UID16 */
|
||||
|
||||
case TARGET_NR_lchown32:
|
||||
ret = get_errno(lchown((const char *)arg1, arg2, arg3));
|
||||
break;
|
||||
|
@ -2665,6 +2721,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3,
|
|||
case TARGET_NR_setfsgid32:
|
||||
ret = get_errno(setfsgid(arg1));
|
||||
break;
|
||||
|
||||
case TARGET_NR_pivot_root:
|
||||
goto unimplemented;
|
||||
case TARGET_NR_mincore:
|
||||
|
|
|
@ -279,7 +279,7 @@ struct target_sigaction;
|
|||
int do_sigaction(int sig, const struct target_sigaction *act,
|
||||
struct target_sigaction *oact);
|
||||
|
||||
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
|
||||
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC)
|
||||
|
||||
#define TARGET_SA_NOCLDSTOP 0x00000001
|
||||
#define TARGET_SA_NOCLDWAIT 0x00000002 /* not supported yet */
|
||||
|
@ -664,7 +664,7 @@ struct target_pollfd {
|
|||
#define TARGET_HDIO_SET_PIO_MODE 0x0327 /* reconfig interface to new speed */
|
||||
|
||||
|
||||
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
|
||||
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC)
|
||||
|
||||
/* 0x54 is just a magic number to make these relatively unique ('T') */
|
||||
|
||||
|
@ -891,6 +891,9 @@ struct target_termios {
|
|||
#define TARGET_MAP_LOCKED 0x2000 /* pages are locked */
|
||||
#define TARGET_MAP_NORESERVE 0x4000 /* don't check for reservations */
|
||||
|
||||
#endif /* defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC) || defined(TARGET_PPC) */
|
||||
|
||||
#if defined(TARGET_I386) || defined(TARGET_ARM) || defined(TARGET_SPARC)
|
||||
struct target_stat {
|
||||
unsigned short st_dev;
|
||||
unsigned short __pad1;
|
||||
|
@ -951,7 +954,62 @@ struct target_stat64 {
|
|||
unsigned long long st_ino;
|
||||
} __attribute__((packed));
|
||||
|
||||
#endif /* defined(TARGET_I386) || defined(TARGET_ARM) */
|
||||
#elif defined(TARGET_PPC)
|
||||
|
||||
struct target_stat {
|
||||
unsigned short st_dev;
|
||||
target_ulong st_ino;
|
||||
unsigned int st_mode;
|
||||
unsigned short st_nlink;
|
||||
unsigned int st_uid;
|
||||
unsigned int st_gid;
|
||||
unsigned short st_rdev;
|
||||
target_ulong st_size;
|
||||
target_ulong st_blksize;
|
||||
target_ulong st_blocks;
|
||||
target_ulong target_st_atime;
|
||||
target_ulong __unused1;
|
||||
target_ulong target_st_mtime;
|
||||
target_ulong __unused2;
|
||||
target_ulong target_st_ctime;
|
||||
target_ulong __unused3;
|
||||
target_ulong __unused4;
|
||||
target_ulong __unused5;
|
||||
};
|
||||
|
||||
struct target_stat64 {
|
||||
unsigned long long st_dev;
|
||||
|
||||
unsigned long long st_ino;
|
||||
|
||||
unsigned int st_mode;
|
||||
unsigned int st_nlink;
|
||||
|
||||
unsigned int st_uid;
|
||||
unsigned int st_gid;
|
||||
|
||||
unsigned long long st_rdev;
|
||||
unsigned short int __pad2;
|
||||
|
||||
long long st_size;
|
||||
target_ulong st_blksize;
|
||||
|
||||
long long st_blocks; /* Number 512-byte blocks allocated. */
|
||||
|
||||
target_ulong target_st_atime;
|
||||
target_ulong target_st_atime_nsec;
|
||||
|
||||
target_ulong target_st_mtime;
|
||||
target_ulong target_st_mtime_nsec;
|
||||
|
||||
target_ulong target_st_ctime;
|
||||
target_ulong target_st_ctime_nsec;
|
||||
|
||||
target_ulong __unused4;
|
||||
target_ulong __unused5;
|
||||
};
|
||||
|
||||
#endif /* defined(TARGET_PPC) */
|
||||
|
||||
#define TARGET_F_DUPFD 0 /* dup */
|
||||
#define TARGET_F_GETFD 1 /* get close_on_exec */
|
||||
|
|
Loading…
Reference in New Issue