From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1DDnWL-0002aN-Nz for qemu-devel@nongnu.org; Tue, 22 Mar 2005 12:50:26 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1DDnW4-0002SF-AJ for qemu-devel@nongnu.org; Tue, 22 Mar 2005 12:50:15 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1DDnW2-0002Px-A0 for qemu-devel@nongnu.org; Tue, 22 Mar 2005 12:50:06 -0500 Received: from [195.135.220.15] (helo=mx2.suse.de) by monty-python.gnu.org with esmtp (TLSv1:DES-CBC3-SHA:168) (Exim 4.34) id 1DDnDv-00009k-Lk for qemu-devel@nongnu.org; Tue, 22 Mar 2005 12:31:24 -0500 Received: from hermes.suse.de (hermes-ext.suse.de [195.135.221.8]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (No client certificate requested) by mx2.suse.de (Postfix) with ESMTP id 7C47B483 for ; Tue, 22 Mar 2005 18:31:21 +0100 (CET) From: Ulrich Hecht Date: Tue, 22 Mar 2005 18:31:20 +0100 MIME-Version: 1.0 Content-Type: Multipart/Mixed; boundary="Boundary-00=_oZFQCqhqjYOQH/z" Message-Id: <200503221831.20635.uli@suse.de> Subject: [Qemu-devel] Patches. Again. Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org --Boundary-00=_oZFQCqhqjYOQH/z Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Content-Disposition: inline Hi! Adapted to the latest softfloat changes and topped off with an evil hack that serves me well until someone implements the sigaltstack syscall properly. qemu-jobsignals.patch: SIGTSTP/SIGCONT handling qemu-arm-sigfpe.patch: signal FPA exceptions on ARM targets qemu-syscalls.patch: implements syscalls acct, uselib, syslog, ftruncate64, mincore, madvise, readahead, and clock_gettime qemu-sigaltstackhack.patch: dummy sigaltstack implementation, workaround in host signal handler to prevent endless segfault loops CU Uli --Boundary-00=_oZFQCqhqjYOQH/z Content-Type: text/x-diff; charset="us-ascii"; name="qemu-jobsignals.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qemu-jobsignals.patch" Index: linux-user/signal.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/signal.c,v retrieving revision 1.27 diff -u -r1.27 signal.c --- linux-user/signal.c 30 Jan 2005 22:59:18 -0000 1.27 +++ linux-user/signal.c 22 Mar 2005 12:42:30 -0000 @@ -348,10 +348,15 @@ k = &sigact_table[sig - 1]; handler = k->sa._sa_handler; if (handler == TARGET_SIG_DFL) { + if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || sig == TARGET_SIGTTOU) { + kill(getpid(),SIGSTOP); + return 0; + } else /* default handler : ignore some signal. The other are fatal */ if (sig != TARGET_SIGCHLD && sig != TARGET_SIGURG && - sig != TARGET_SIGWINCH) { + sig != TARGET_SIGWINCH && + sig != TARGET_SIGCONT) { force_sig(sig); } else { return 0; /* indicate ignored */ --Boundary-00=_oZFQCqhqjYOQH/z Content-Type: text/x-diff; charset="us-ascii"; name="qemu-arm-sigfpe.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qemu-arm-sigfpe.patch" Index: linux-user/main.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/main.c,v retrieving revision 1.62 diff -u -r1.62 main.c --- linux-user/main.c 13 Mar 2005 16:56:51 -0000 1.62 +++ linux-user/main.c 22 Mar 2005 12:42:30 -0000 @@ -325,18 +325,54 @@ { TaskState *ts = env->opaque; uint32_t opcode; + int rc; /* we handle the FPU emulation here, as Linux */ /* we get the opcode */ opcode = ldl_raw((uint8_t *)env->regs[15]); - if (EmulateAll(opcode, &ts->fpa, env->regs) == 0) { + if ((rc=EmulateAll(opcode, &ts->fpa, env->regs)) == 0) { /* illegal instruction */ info.si_signo = SIGILL; info.si_errno = 0; info.si_code = TARGET_ILL_ILLOPN; info._sifields._sigfault._addr = env->regs[15]; queue_signal(info.si_signo, &info); - } else { + } else if (rc < 0) { /* FP exception */ + int arm_fpe=0; + /* translate softfloat flags to FPSR flags */ + if(-rc & float_flag_invalid) arm_fpe |= BIT_IOC; + if(-rc & float_flag_divbyzero) arm_fpe |= BIT_DZC; + if(-rc & float_flag_overflow) arm_fpe |= BIT_OFC; + if(-rc & float_flag_underflow) arm_fpe |= BIT_UFC; + if(-rc & float_flag_inexact) arm_fpe |= BIT_IXC; + + FPSR fpsr = ts->fpa.fpsr; + //printf("fpsr 0x%x, arm_fpe 0x%x\n",fpsr,arm_fpe); + + if(fpsr & (arm_fpe << 16)) /* exception enabled? */ + { + info.si_signo = SIGFPE; + info.si_errno = 0; + /* ordered by priority, least first */ + if(arm_fpe & BIT_IXC) info.si_code = TARGET_FPE_FLTRES; + if(arm_fpe & BIT_UFC) info.si_code = TARGET_FPE_FLTUND; + if(arm_fpe & BIT_OFC) info.si_code = TARGET_FPE_FLTOVF; + if(arm_fpe & BIT_DZC) info.si_code = TARGET_FPE_FLTDIV; + if(arm_fpe & BIT_IOC) info.si_code = TARGET_FPE_FLTINV; + info._sifields._sigfault._addr = env->regs[15]; + queue_signal(info.si_signo, &info); + } + else + env->regs[15] += 4; + + /* accumulate unenabled exceptions */ + if((!(fpsr & BIT_IXE)) && (arm_fpe & BIT_IXC)) fpsr |= BIT_IXC; + if((!(fpsr & BIT_UFE)) && (arm_fpe & BIT_UFC)) fpsr |= BIT_UFC; + if((!(fpsr & BIT_OFE)) && (arm_fpe & BIT_OFC)) fpsr |= BIT_OFC; + if((!(fpsr & BIT_DZE)) && (arm_fpe & BIT_DZC)) fpsr |= BIT_DZC; + if((!(fpsr & BIT_IOE)) && (arm_fpe & BIT_IOC)) fpsr |= BIT_IOC; + ts->fpa.fpsr=fpsr; + } else { /* everything OK */ /* increment PC */ env->regs[15] += 4; } Index: target-arm/nwfpe/fpa11.c =================================================================== RCS file: /cvsroot/qemu/qemu/target-arm/nwfpe/fpa11.c,v retrieving revision 1.2 diff -u -r1.2 fpa11.c --- target-arm/nwfpe/fpa11.c 13 Mar 2005 16:55:58 -0000 1.2 +++ target-arm/nwfpe/fpa11.c 22 Mar 2005 12:42:30 -0000 @@ -161,6 +161,8 @@ fpa11->initflag = 1; } + set_float_exception_flags(0, &fpa11->fp_status); + if (TEST_OPCODE(opcode,MASK_CPRT)) { //fprintf(stderr,"emulating CPRT\n"); @@ -190,6 +192,11 @@ } // restore_flags(flags); + if(nRc == 1 && get_float_exception_flags(&fpa11->fp_status)) + { + //printf("fef 0x%x\n",float_exception_flags); + nRc=-get_float_exception_flags(&fpa11->fp_status); + } //printf("returning %d\n",nRc); return(nRc); --Boundary-00=_oZFQCqhqjYOQH/z Content-Type: text/x-diff; charset="us-ascii"; name="qemu-syscalls.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qemu-syscalls.patch" Index: Makefile.target =================================================================== RCS file: /cvsroot/qemu/qemu/Makefile.target,v retrieving revision 1.62 diff -u -r1.62 Makefile.target --- Makefile.target 13 Mar 2005 16:52:10 -0000 1.62 +++ Makefile.target 22 Mar 2005 12:42:29 -0000 @@ -209,8 +209,8 @@ ######################################################### -DEFINES+=-D_GNU_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -LIBS+=-lm +DEFINES+=-D_GNU_SOURCE -D_BSD_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +LIBS+=-lm -lrt ifndef CONFIG_USER_ONLY LIBS+=-lz endif Index: linux-user/syscall.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/syscall.c,v retrieving revision 1.58 diff -u -r1.58 syscall.c --- linux-user/syscall.c 1 Mar 2005 22:32:06 -0000 1.58 +++ linux-user/syscall.c 22 Mar 2005 12:42:30 -0000 @@ -207,6 +207,7 @@ #define __NR_sys_getdents __NR_getdents #define __NR_sys_getdents64 __NR_getdents64 #define __NR_sys_rt_sigqueueinfo __NR_rt_sigqueueinfo +#define __NR_sys_syslog __NR_syslog #if defined(__alpha__) || defined (__ia64__) || defined(__x86_64__) #define __NR__llseek __NR_lseek @@ -228,6 +229,7 @@ _syscall2(int,sys_statfs,const char *,path,struct kernel_statfs *,buf) _syscall2(int,sys_fstatfs,int,fd,struct kernel_statfs *,buf) _syscall3(int,sys_rt_sigqueueinfo,int,pid,int,sig,siginfo_t *,uinfo) +_syscall3(int,sys_syslog,int,type,char*,bufp,int,len) #ifdef __NR_exit_group _syscall1(int,exit_group,int,error_code) #endif @@ -241,6 +243,7 @@ extern int setresgid(gid_t, gid_t, gid_t); extern int getresgid(gid_t *, gid_t *, gid_t *); extern int setgroups(int, gid_t *); +extern int uselib(const char*); static inline long get_errno(long ret) { @@ -1830,7 +1833,9 @@ goto unimplemented; case TARGET_NR_acct: - goto unimplemented; + ret = get_errno(acct(path((const char*)arg1))); + break; + case TARGET_NR_umount2: ret = get_errno(umount2((const char *)arg1, arg2)); break; @@ -2142,7 +2147,9 @@ ret = get_errno(readlink(path((const char *)arg1), (char *)arg2, arg3)); break; case TARGET_NR_uselib: - goto unimplemented; + ret = get_errno(uselib(path((const char*)arg1))); + break; + case TARGET_NR_swapon: ret = get_errno(swapon((const char *)arg1, arg2)); break; @@ -2257,7 +2264,9 @@ ret = do_socketcall(arg1, (int32_t *)arg2); break; case TARGET_NR_syslog: - goto unimplemented; + ret = get_errno(sys_syslog((int)arg1, (char*)arg2, (int)arg3)); + break; + case TARGET_NR_setitimer: { struct target_itimerval *target_value = (void *)arg2; @@ -2758,7 +2768,8 @@ #endif #ifdef TARGET_NR_ftruncate64 case TARGET_NR_ftruncate64: - goto unimplemented; + ret = get_errno(ftruncate64((int)arg1, (off64_t)arg2)); + break; #endif #ifdef TARGET_NR_stat64 case TARGET_NR_stat64: @@ -3047,11 +3058,14 @@ goto unimplemented; #ifdef TARGET_NR_mincore case TARGET_NR_mincore: - goto unimplemented; + page_unprotect_range((void*)arg3, ((size_t)arg2 + TARGET_PAGE_SIZE - 1) / TARGET_PAGE_SIZE); + ret = get_errno(mincore((void*)arg1, (size_t)arg2, (unsigned char*)arg3)); + break; #endif #ifdef TARGET_NR_madvise case TARGET_NR_madvise: - goto unimplemented; + ret = get_errno(madvise((void*)arg1, (size_t)arg2, (int)arg3)); + break; #endif #if TARGET_LONG_BITS == 32 case TARGET_NR_fcntl64: @@ -3100,7 +3114,8 @@ ret = get_errno(gettid()); break; case TARGET_NR_readahead: - goto unimplemented; + ret = get_errno(readahead((int)arg1, (off64_t)arg2, (size_t)arg3)); + break; #ifdef TARGET_NR_setxattr case TARGET_NR_setxattr: case TARGET_NR_lsetxattr: @@ -3121,6 +3136,22 @@ case TARGET_NR_get_thread_area: goto unimplemented_nowarn; #endif +#ifdef TARGET_NR_clock_gettime + case TARGET_NR_clock_gettime: + { + struct target_timespec* ttp = (struct target_timespec*)arg2; + struct timespec htp; + if(ttp) { + htp.tv_sec = tswapl(ttp->tv_sec); + htp.tv_nsec = tswapl(ttp->tv_nsec); + ret = get_errno(clock_gettime((clockid_t)arg1, &htp)); + ttp->tv_sec = tswapl(htp.tv_sec); + ttp->tv_nsec = tswapl(htp.tv_nsec); + } else + ret = get_errno(clock_gettime((clockid_t)arg1, NULL)); + break; + } +#endif default: unimplemented: gemu_log("qemu: Unsupported syscall: %d\n", num); Index: linux-user/arm/syscall_nr.h =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/arm/syscall_nr.h,v retrieving revision 1.2 diff -u -r1.2 syscall_nr.h --- linux-user/arm/syscall_nr.h 6 Dec 2004 22:58:05 -0000 1.2 +++ linux-user/arm/syscall_nr.h 22 Mar 2005 12:42:30 -0000 @@ -259,4 +259,5 @@ /* 254 for set_thread_area */ /* 255 for get_thread_area */ /* 256 for set_tid_address */ +#define TARGET_NR_clock_gettime (263) #define TARGET_NR_utimes (269) --Boundary-00=_oZFQCqhqjYOQH/z Content-Type: text/x-diff; charset="us-ascii"; name="qemu-sigaltstackhack.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="qemu-sigaltstackhack.patch" Index: linux-user/signal.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/signal.c,v retrieving revision 1.27 diff -u -r1.27 signal.c --- linux-user/signal.c 30 Jan 2005 22:59:18 -0000 1.27 +++ linux-user/signal.c 22 Mar 2005 12:42:30 -0000 @@ -1019,6 +1026,14 @@ return err; } +void* hack_stack; + +void hack_handler(int signum) +{ + fprintf(stderr,"QEMU: stack overflow, aborting\n"); + exit(-SIGSEGV); +} + static inline void * get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize) { @@ -1031,6 +1046,19 @@ if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) sp = current->sas_ss_sp + current->sas_ss_size; #endif + + /* EVIL HACK TIME! + This is supposed to prevent endless segfault loops in case of stack + overflows that can occur as a result of the dummy sigaltstack() + syscall. */ + struct sigaction oldact; + struct sigaction act; + memset(&act,0,sizeof(struct sigaction)); + act.sa_handler=hack_handler; + sigaction(SIGSEGV,&act,&oldact); + hack_stack = *((void**)((sp-framesize)&~7)); + sigaction(SIGSEGV,&oldact,&act); + /* * ATPCS B01 mandates 8-byte alignment */ Index: linux-user/syscall.c =================================================================== RCS file: /cvsroot/qemu/qemu/linux-user/syscall.c,v retrieving revision 1.58 diff -u -r1.58 syscall.c --- linux-user/syscall.c 1 Mar 2005 22:32:06 -0000 1.58 +++ linux-user/syscall.c 22 Mar 2005 12:42:30 -0000 @@ -2725,7 +2734,8 @@ case TARGET_NR_capset: goto unimplemented; case TARGET_NR_sigaltstack: - goto unimplemented; + ret = 0; /* good enough for most purposes */ + break; case TARGET_NR_sendfile: goto unimplemented; #ifdef TARGET_NR_getpmsg --Boundary-00=_oZFQCqhqjYOQH/z--