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.