All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ulrich Hecht <uli@suse.de>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] Patches. Again.
Date: Tue, 22 Mar 2005 18:31:20 +0100	[thread overview]
Message-ID: <200503221831.20635.uli@suse.de> (raw)

[-- 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

                 reply	other threads:[~2005-03-22 17:50 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200503221831.20635.uli@suse.de \
    --to=uli@suse.de \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.