qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] Patches. Again.
@ 2005-03-22 17:31 Ulrich Hecht
  0 siblings, 0 replies; only message in thread
From: Ulrich Hecht @ 2005-03-22 17:31 UTC (permalink / raw)
  To: qemu-devel

[-- Attachment #1: Type: text/plain, Size: 531 bytes --]

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

[-- Attachment #2: qemu-jobsignals.patch --]
[-- Type: text/x-diff, Size: 952 bytes --]

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 */

[-- Attachment #3: qemu-arm-sigfpe.patch --]
[-- Type: text/x-diff, Size: 4080 bytes --]

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);

[-- Attachment #4: qemu-syscalls.patch --]
[-- Type: text/x-diff, Size: 5240 bytes --]

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)

[-- Attachment #5: qemu-sigaltstackhack.patch --]
[-- Type: text/x-diff, Size: 1877 bytes --]

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

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2005-03-22 17:50 UTC | newest]

Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-03-22 17:31 [Qemu-devel] Patches. Again Ulrich Hecht

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).