? p Index: main.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v retrieving revision 1.59 diff -u -p -r1.59 main.c --- main.c 7 Feb 2005 23:12:27 -0000 1.59 +++ main.c 11 Feb 2005 00:25:05 -0000 @@ -62,40 +62,51 @@ void gemu_log(const char *fmt, ...) va_list ap; va_start(ap, fmt); + { + FILE * f; + f = fopen ("/mountrequests", "a"); + if (f) + { + vfprintf (f, fmt, ap); + fclose (f); + } + else vfprintf(stderr, fmt, ap); + } +// vgemu_log(fmt, ap); va_end(ap); } void cpu_outb(CPUState *env, int addr, int val) { - fprintf(stderr, "outb: port=0x%04x, data=%02x\n", addr, val); + gemu_log("outb: port=0x%04x, data=%02x\n", addr, val); } void cpu_outw(CPUState *env, int addr, int val) { - fprintf(stderr, "outw: port=0x%04x, data=%04x\n", addr, val); + gemu_log("outw: port=0x%04x, data=%04x\n", addr, val); } void cpu_outl(CPUState *env, int addr, int val) { - fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val); + gemu_log("outl: port=0x%04x, data=%08x\n", addr, val); } int cpu_inb(CPUState *env, int addr) { - fprintf(stderr, "inb: port=0x%04x\n", addr); + gemu_log("inb: port=0x%04x\n", addr); return 0; } int cpu_inw(CPUState *env, int addr) { - fprintf(stderr, "inw: port=0x%04x\n", addr); + gemu_log("inw: port=0x%04x\n", addr); return 0; } int cpu_inl(CPUState *env, int addr) { - fprintf(stderr, "inl: port=0x%04x\n", addr); + gemu_log("inl: port=0x%04x\n", addr); return 0; } @@ -609,12 +620,12 @@ void cpu_loop(CPUPPCState *env) break; case EXCP_RESET: /* Should not happen ! */ - fprintf(stderr, "RESET asked... Stop emulation\n"); + gemu_log("RESET asked... Stop emulation\n"); if (loglevel) fprintf(logfile, "RESET asked... Stop emulation\n"); abort(); case EXCP_MACHINE_CHECK: - fprintf(stderr, "Machine check exeption... Stop emulation\n"); + gemu_log("Machine check exeption... Stop emulation\n"); if (loglevel) fprintf(logfile, "RESET asked... Stop emulation\n"); info.si_signo = TARGET_SIGBUS; @@ -623,7 +634,7 @@ void cpu_loop(CPUPPCState *env) info._sifields._sigfault._addr = env->nip - 4; queue_signal(info.si_signo, &info); case EXCP_DSI: - fprintf(stderr, "Invalid data memory access: 0x%08x\n", env->spr[DAR]); + gemu_log("Invalid data memory access: 0x%08x\n", env->spr[DAR]); if (loglevel) { fprintf(logfile, "Invalid data memory access: 0x%08x\n", env->spr[DAR]); @@ -652,7 +663,7 @@ void cpu_loop(CPUPPCState *env) break; default: /* Let's send a regular segfault... */ - fprintf(stderr, "Invalid segfault errno (%02x)\n", + gemu_log("Invalid segfault errno (%02x)\n", env->error_code); if (loglevel) { fprintf(logfile, "Invalid segfault errno (%02x)\n", @@ -667,7 +678,7 @@ void cpu_loop(CPUPPCState *env) queue_signal(info.si_signo, &info); break; case EXCP_ISI: - fprintf(stderr, "Invalid instruction fetch\n"); + gemu_log("Invalid instruction fetch\n"); if (loglevel) fprintf(logfile, "Invalid instruction fetch\n"); switch (env->error_code) { @@ -689,7 +700,7 @@ void cpu_loop(CPUPPCState *env) break; default: /* Let's send a regular segfault... */ - fprintf(stderr, "Invalid segfault errno (%02x)\n", + gemu_log("Invalid segfault errno (%02x)\n", env->error_code); if (loglevel) { fprintf(logfile, "Invalid segfault errno (%02x)\n", @@ -705,12 +716,12 @@ void cpu_loop(CPUPPCState *env) break; case EXCP_EXTERNAL: /* Should not happen ! */ - fprintf(stderr, "External interruption... Stop emulation\n"); + gemu_log("External interruption... Stop emulation\n"); if (loglevel) fprintf(logfile, "External interruption... Stop emulation\n"); abort(); case EXCP_ALIGN: - fprintf(stderr, "Invalid unaligned memory access\n"); + gemu_log("Invalid unaligned memory access\n"); if (loglevel) fprintf(logfile, "Invalid unaligned memory access\n"); info.si_signo = TARGET_SIGBUS; @@ -722,7 +733,7 @@ void cpu_loop(CPUPPCState *env) case EXCP_PROGRAM: switch (env->error_code & ~0xF) { case EXCP_FP: - fprintf(stderr, "Program exception\n"); + gemu_log("Program exception\n"); if (loglevel) fprintf(logfile, "Program exception\n"); /* Set FX */ @@ -760,7 +771,7 @@ void cpu_loop(CPUPPCState *env) info.si_code = TARGET_FPE_FLTSUB; break; default: - fprintf(stderr, "Unknown floating point exception " + gemu_log("Unknown floating point exception " "(%02x)\n", env->error_code); if (loglevel) { fprintf(logfile, "Unknown floating point exception " @@ -769,7 +780,7 @@ void cpu_loop(CPUPPCState *env) } break; case EXCP_INVAL: - fprintf(stderr, "Invalid instruction\n"); + gemu_log("Invalid instruction\n"); if (loglevel) fprintf(logfile, "Invalid instruction\n"); info.si_signo = TARGET_SIGILL; @@ -788,7 +799,7 @@ void cpu_loop(CPUPPCState *env) info.si_code = TARGET_ILL_COPROC; break; default: - fprintf(stderr, "Unknown invalid operation (%02x)\n", + gemu_log("Unknown invalid operation (%02x)\n", env->error_code & 0xF); if (loglevel) { fprintf(logfile, "Unknown invalid operation (%02x)\n", @@ -799,7 +810,7 @@ void cpu_loop(CPUPPCState *env) } break; case EXCP_PRIV: - fprintf(stderr, "Privilege violation\n"); + gemu_log("Privilege violation\n"); if (loglevel) fprintf(logfile, "Privilege violation\n"); info.si_signo = TARGET_SIGILL; @@ -812,20 +823,20 @@ void cpu_loop(CPUPPCState *env) info.si_code = TARGET_ILL_PRVREG; break; default: - fprintf(stderr, "Unknown privilege violation (%02x)\n", + gemu_log("Unknown privilege violation (%02x)\n", env->error_code & 0xF); info.si_code = TARGET_ILL_PRVOPC; break; } break; case EXCP_TRAP: - fprintf(stderr, "Tried to call a TRAP\n"); + gemu_log("Tried to call a TRAP\n"); if (loglevel) fprintf(logfile, "Tried to call a TRAP\n"); abort(); default: /* Should not happen ! */ - fprintf(stderr, "Unknown program exception (%02x)\n", + gemu_log("Unknown program exception (%02x)\n", env->error_code); if (loglevel) { fprintf(logfile, "Unknwon program exception (%02x)\n", @@ -837,7 +848,7 @@ void cpu_loop(CPUPPCState *env) queue_signal(info.si_signo, &info); break; case EXCP_NO_FP: - fprintf(stderr, "No floating point allowed\n"); + gemu_log("No floating point allowed\n"); if (loglevel) fprintf(logfile, "No floating point allowed\n"); info.si_signo = TARGET_SIGILL; @@ -848,19 +859,19 @@ void cpu_loop(CPUPPCState *env) break; case EXCP_DECR: /* Should not happen ! */ - fprintf(stderr, "Decrementer exception\n"); + gemu_log("Decrementer exception\n"); if (loglevel) fprintf(logfile, "Decrementer exception\n"); abort(); case EXCP_RESA: /* Implementation specific */ /* Should not happen ! */ - fprintf(stderr, "RESA exception should never happen !\n"); + gemu_log("RESA exception should never happen !\n"); if (loglevel) fprintf(logfile, "RESA exception should never happen !\n"); abort(); case EXCP_RESB: /* Implementation specific */ /* Should not happen ! */ - fprintf(stderr, "RESB exception should never happen !\n"); + gemu_log("RESB exception should never happen !\n"); if (loglevel) fprintf(logfile, "RESB exception should never happen !\n"); abort(); @@ -869,14 +880,14 @@ void cpu_loop(CPUPPCState *env) break; case EXCP_FP_ASSIST: /* Should not happen ! */ - fprintf(stderr, "Floating point assist exception\n"); + gemu_log("Floating point assist exception\n"); if (loglevel) fprintf(logfile, "Floating point assist exception\n"); abort(); case EXCP_MTMSR: /* We reloaded the msr, just go on */ if (msr_pr == 0) { - fprintf(stderr, "Tried to go into supervisor mode !\n"); + gemu_log("Tried to go into supervisor mode !\n"); if (loglevel) fprintf(logfile, "Tried to go into supervisor mode !\n"); abort(); @@ -887,7 +898,7 @@ void cpu_loop(CPUPPCState *env) break; case EXCP_RFI: /* Should not occur: we always are in user mode */ - fprintf(stderr, "Return from interrupt ?\n"); + gemu_log("Return from interrupt ?\n"); if (loglevel) fprintf(logfile, "Return from interrupt ?\n"); abort(); @@ -1000,7 +1011,7 @@ int main(int argc, char **argv) qemu_host_page_size = atoi(argv[optind++]); if (qemu_host_page_size == 0 || (qemu_host_page_size & (qemu_host_page_size - 1)) != 0) { - fprintf(stderr, "page size must be a power of two\n"); + gemu_log("page size must be a power of two\n"); exit(1); } } else Index: signal.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/signal.c,v retrieving revision 1.27 diff -u -p -r1.27 signal.c --- signal.c 30 Jan 2005 22:59:18 -0000 1.27 +++ signal.c 11 Feb 2005 00:25:05 -0000 @@ -342,7 +342,7 @@ int queue_signal(int sig, target_siginfo target_ulong handler; #if defined(DEBUG_SIGNAL) - fprintf(stderr, "queue_signal: sig=%d\n", + gemu_log("queue_signal: sig=%d\n", sig); #endif k = &sigact_table[sig - 1]; @@ -413,7 +413,7 @@ static void host_signal_handler(int host if (sig < 1 || sig > TARGET_NSIG) return; #if defined(DEBUG_SIGNAL) - fprintf(stderr, "qemu: got signal %d\n", sig); + gemu_log("qemu: got signal %d\n", sig); #endif host_to_target_siginfo_noswap(&tinfo, info); if (queue_signal(sig, &tinfo) == 1) { @@ -433,7 +433,7 @@ int do_sigaction(int sig, const struct t return -EINVAL; k = &sigact_table[sig - 1]; #if defined(DEBUG_SIGNAL) - fprintf(stderr, "sigaction sig=%d act=0x%08x, oact=0x%08x\n", + gemu_log("sigaction sig=%d act=0x%08x, oact=0x%08x\n", sig, (int)act, (int)oact); #endif if (oact) { @@ -846,7 +846,7 @@ long do_sigreturn(CPUX86State *env) int eax, i; #if defined(DEBUG_SIGNAL) - fprintf(stderr, "do_sigreturn\n"); + gemu_log("do_sigreturn\n"); #endif /* set blocked signals */ if (__get_user(target_set.sig[0], &frame->sc.oldmask)) @@ -1625,25 +1625,25 @@ long do_rt_sigreturn(CPUState *env) static void setup_frame(int sig, struct emulated_sigaction *ka, target_sigset_t *set, CPUState *env) { - fprintf(stderr, "setup_frame: not implemented\n"); + gemu_log("setup_frame: not implemented\n"); } static void setup_rt_frame(int sig, struct emulated_sigaction *ka, target_siginfo_t *info, target_sigset_t *set, CPUState *env) { - fprintf(stderr, "setup_rt_frame: not implemented\n"); + gemu_log("setup_rt_frame: not implemented\n"); } long do_sigreturn(CPUState *env) { - fprintf(stderr, "do_sigreturn: not implemented\n"); + gemu_log("do_sigreturn: not implemented\n"); return -ENOSYS; } long do_rt_sigreturn(CPUState *env) { - fprintf(stderr, "do_rt_sigreturn: not implemented\n"); + gemu_log("do_rt_sigreturn: not implemented\n"); return -ENOSYS; } @@ -1673,7 +1673,7 @@ void process_pending_signals(void *cpu_e handle_signal: #ifdef DEBUG_SIGNAL - fprintf(stderr, "qemu: process signal %d\n", sig); + gemu_log("qemu: process signal %d\n", sig); #endif /* dequeue signal */ q = k->first; Index: syscall.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/syscall.c,v retrieving revision 1.57 diff -u -p -r1.57 syscall.c --- syscall.c 31 Jan 2005 20:45:13 -0000 1.57 +++ syscall.c 11 Feb 2005 00:25:06 -0000 @@ -1509,6 +1509,50 @@ static long do_fcntl(int fd, int cmd, un return ret; } +static long do_nfs_mount(const char *source, const char *target, + const char *fstype, unsigned long mountflags, + const void *data) +{ + const struct target_nfs_mount_data *tdata; + struct target_nfs_mount_data hdata; + + tdata = (const struct target_nfs_mount_data *)data; + hdata.version = tswap32(tdata->version); + /* If the user provides a later verson, ignore it and hope for the + best. */ + if (hdata.version > TARGET_NFS_MOUNT_VERSION) + hdata.version = TARGET_NFS_MOUNT_VERSION; + hdata.fd = tswap32(tdata->fd); + memcpy(&hdata.old_root, &tdata->old_root, sizeof(hdata.old_root)); + hdata.flags = tswap32(tdata->flags); + hdata.rsize = tswap32(tdata->rsize); + hdata.wsize = tswap32(tdata->wsize); + hdata.timeo = tswap32(tdata->timeo); + hdata.retrans = tswap32(tdata->retrans); + hdata.acregmin = tswap32(tdata->acregmin); + hdata.acregmax = tswap32(tdata->acregmax); + hdata.acdirmin = tswap32(tdata->acdirmin); + hdata.acdirmax = tswap32(tdata->acdirmax); + hdata.addr.sin_family = tswap16(tdata->addr.sin_family); + hdata.addr.sin_port = tswap16(tdata->addr.sin_port); + hdata.addr.sin_addr.s_addr = tswap32(tdata->addr.sin_addr.s_addr); + //memcpy (&hdata.addr, &tdata->addr, sizeof(hdata.addr)); + memcpy (hdata.hostname, tdata->hostname, 256); + if (hdata.version >= 2) + hdata.namlen = tswap32(tdata->namlen); + if (hdata.version >= 3) + hdata.bsize = tswap32(tdata->bsize); + if (hdata.version >= 4) { + hdata.root.size = tswap16(hdata.root.size); + memcpy(&hdata.root.data, &tdata->root.data, sizeof(hdata.root.data)); + } + if (hdata.version >= 5) + hdata.pseudoflavor = tswap32(tdata->pseudoflavor); + if (hdata.version >= 6) + memcpy (hdata.context, tdata->context, TARGET_NFS_MAX_CONTEXT_LEN + 1); + return get_errno(mount(source, target, fstype, mountflags, data)); +} + #ifdef USE_UID16 static inline int high2lowuid(int uid) @@ -1705,8 +1749,30 @@ long do_syscall(void *cpu_env, int num, ret = get_errno(getpid()); break; case TARGET_NR_mount: - /* need to look at the data field */ - goto unimplemented; + { + const char *source = (const char *)arg1; + const char *target = (const char *)arg2; + const char *fstype = (const char *)arg3; + unsigned long mountflags = arg4; + const void *data = (const void *)arg5; + + fstype = (const char *)arg3; + if (strcmp (fstype, "nfs") == 0) { + ret = do_nfs_mount(source, target, fstype, mountflags, data); + } else if (strcmp (fstype, "ncpfs") == 0 + || strcmp (fstype, "smbfs") == 0) { + /* These filesystems take binary arguments which we don't + know how to translate. */ + ret = -ENODEV; + } else { + /* Assume all other filesystem options are a character string, + so we can pass the data argument unmodified. */ + ret = get_errno(mount(source, target, fstype, mountflags, + data)); + } + + } + break; case TARGET_NR_umount: ret = get_errno(umount((const char *)arg1)); break; Index: syscall_defs.h =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/syscall_defs.h,v retrieving revision 1.22 diff -u -p -r1.22 syscall_defs.h --- syscall_defs.h 30 Sep 2004 22:04:13 -0000 1.22 +++ syscall_defs.h 11 Feb 2005 00:25:06 -0000 @@ -1246,3 +1246,40 @@ struct target_sysinfo { unsigned int mem_unit; /* Memory unit size in bytes */ char _f[20-2*sizeof(target_long)-sizeof(int)]; /* Padding: libc5 uses this.. */ }; + +/* NFS mount options structure. Taken from 2.6.10 kernel headers. */ +#define TARGET_NFS_MOUNT_VERSION 6 +#define TARGET_NFS_MAX_CONTEXT_LEN 256 +struct target_nfs_mount_data { + int version; /* 1 */ + int fd; /* 1 */ + struct { + unsigned char data[32]; + } old_root; /* 1 */ + int flags; /* 1 */ + int rsize; /* 1 */ + int wsize; /* 1 */ + int timeo; /* 1 */ + int retrans; /* 1 */ + int acregmin; /* 1 */ + int acregmax; /* 1 */ + int acdirmin; /* 1 */ + int acdirmax; /* 1 */ + struct { + int16_t sin_family; + uint16_t sin_port; + struct { + uint32_t s_addr; + }sin_addr; + char pad[8]; + } addr; /* 1 */ + char hostname[256]; /* 1 */ + int namlen; /* 2 */ + unsigned int bsize; /* 3 */ + struct { + uint16_t size; + unsigned char data[32]; + } root; /* 4 */ + int pseudoflavor; /* 5 */ + char context[TARGET_NFS_MAX_CONTEXT_LEN + 1]; /* 6 */ +};