diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-03-22 15:23:14 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-03-22 15:23:14 +0000 |
commit | dab2ed991a49678fbd4d45ff1b328340a77057df (patch) | |
tree | 0c587c5ef62faa0c3bf9b39a7ce9281c0a63e2b2 /linux-user | |
parent | e591824733ec698d92d1f09c2ffb9b86b799d6da (diff) | |
download | qemu-dab2ed991a49678fbd4d45ff1b328340a77057df.zip qemu-dab2ed991a49678fbd4d45ff1b328340a77057df.tar.gz qemu-dab2ed991a49678fbd4d45ff1b328340a77057df.tar.bz2 |
better 16 bit code support
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@38 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/main.c | 8 | ||||
-rw-r--r-- | linux-user/syscall.c | 37 | ||||
-rw-r--r-- | linux-user/syscall_defs.h | 16 |
3 files changed, 48 insertions, 13 deletions
diff --git a/linux-user/main.c b/linux-user/main.c index 45e81b2..3222629 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -179,7 +179,7 @@ int main(int argc, char **argv) env->regs[R_EDI] = regs->edi; env->regs[R_EBP] = regs->ebp; env->regs[R_ESP] = regs->esp; - env->pc = regs->eip; + env->eip = regs->eip; /* linux segment setup */ env->gdt.base = (void *)gdt_table; @@ -198,12 +198,12 @@ int main(int argc, char **argv) uint8_t *pc; err = cpu_x86_exec(env); + pc = env->seg_cache[R_CS].base + env->eip; switch(err) { case EXCP0D_GPF: - pc = (uint8_t *)env->pc; if (pc[0] == 0xcd && pc[1] == 0x80) { /* syscall */ - env->pc += 2; + env->eip += 2; env->regs[R_EAX] = do_syscall(env, env->regs[R_EAX], env->regs[R_EBX], @@ -219,7 +219,7 @@ int main(int argc, char **argv) default: trap_error: fprintf(stderr, "0x%08lx: Unknown exception %d, aborting\n", - (long)env->pc, err); + (long)pc, err); abort(); } } diff --git a/linux-user/syscall.c b/linux-user/syscall.c index c0bee47..afdf189 100644 --- a/linux-user/syscall.c +++ b/linux-user/syscall.c @@ -53,6 +53,7 @@ #include <linux/cdrom.h> #include <linux/hdreg.h> #include <linux/soundcard.h> +#include <linux/dirent.h> #include "gemu.h" @@ -63,13 +64,6 @@ #define PAGE_MASK ~(PAGE_SIZE - 1) #endif -struct dirent { - long d_ino; - long d_off; - unsigned short d_reclen; - char d_name[256]; /* We must not include limits.h! */ -}; - //#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]) @@ -86,6 +80,7 @@ struct dirent { #define __NR_sys_statfs __NR_statfs #define __NR_sys_fstatfs __NR_fstatfs #define __NR_sys_getdents __NR_getdents +#define __NR_sys_getdents64 __NR_getdents64 #ifdef __NR_gettid _syscall0(int, gettid) @@ -97,6 +92,7 @@ static int gettid(void) { _syscall1(int,sys_uname,struct new_utsname *,buf) _syscall2(int,sys_getcwd1,char *,buf,size_t,size) _syscall3(int, sys_getdents, uint, fd, struct dirent *, dirp, uint, count); +_syscall3(int, sys_getdents64, uint, fd, struct dirent64 *, dirp, uint, count); _syscall5(int, _llseek, uint, fd, ulong, hi, ulong, lo, loff_t *, res, uint, wh); _syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf) @@ -1005,7 +1001,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, ret = get_errno(setsid()); break; case TARGET_NR_sigaction: -#if 0 +#if 1 { ret = 0; } @@ -1336,6 +1332,7 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, { struct dirent *dirp = (void *)arg2; long count = arg3; + ret = get_errno(sys_getdents(arg1, dirp, count)); if (!is_error(ret)) { struct dirent *de; @@ -1355,6 +1352,29 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, } } break; + case TARGET_NR_getdents64: + { + struct dirent64 *dirp = (void *)arg2; + long count = arg3; + ret = get_errno(sys_getdents64(arg1, dirp, count)); + if (!is_error(ret)) { + struct dirent64 *de; + int len = ret; + int reclen; + de = dirp; + while (len > 0) { + reclen = tswap16(de->d_reclen); + if (reclen > len) + break; + de->d_reclen = reclen; + tswap64s(&de->d_ino); + tswap64s(&de->d_off); + de = (struct dirent64 *)((char *)de + reclen); + len -= reclen; + } + } + } + break; case TARGET_NR__newselect: ret = do_select(arg1, (void *)arg2, (void *)arg3, (void *)arg4, (void *)arg5); @@ -1519,7 +1539,6 @@ long do_syscall(void *cpu_env, int num, long arg1, long arg2, long arg3, case TARGET_NR_pivot_root: case TARGET_NR_mincore: case TARGET_NR_madvise: - case TARGET_NR_getdents64: goto unimplemented; #if TARGET_LONG_BITS == 32 case TARGET_NR_fcntl64: diff --git a/linux-user/syscall_defs.h b/linux-user/syscall_defs.h index dc44272..8b2d6bd 100644 --- a/linux-user/syscall_defs.h +++ b/linux-user/syscall_defs.h @@ -75,6 +75,22 @@ struct kernel_statfs { int f_spare[6]; }; +struct target_dirent { + target_long d_ino; + target_long d_off; + unsigned short d_reclen; + char d_name[256]; /* We must not include limits.h! */ +}; + +struct target_dirent64 { + uint64_t d_ino; + int64_t d_off; + unsigned short d_reclen; + unsigned char d_type; + char d_name[256]; +}; + + /* mostly generic signal stuff */ #define TARGET_SIG_DFL ((target_long)0) /* default signal handling */ #define TARGET_SIG_IGN ((target_long)1) /* ignore signal */ |