Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 30 Jul 2007 11:24:07 -0700 (PDT)
From:      Don Lewis <truckman@FreeBSD.org>
To:        alfred@FreeBSD.org
Cc:        cvs-src@FreeBSD.org, src-committers@FreeBSD.org, cvs-all@FreeBSD.org, jhb@FreeBSD.org
Subject:   Re: cvs commit: src/sys/i386/i386 trap.c
Message-ID:  <200707301824.l6UIO7Qf092040@gw.catspoiler.org>
In-Reply-To: <20070730175334.GH92956@elvis.mu.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On 30 Jul, Alfred Perlstein wrote:
> * Don Lewis <truckman@FreeBSD.org> [070730 00:17] wrote:
>> 
>> After installing this patch, the bootstrap in the pm3-base port still
>> fails.  I installed pm3-base from the 6-STABLE package, and it isn't
>> able to compile any of the other ports.  I suspect the reason for the
>> latter is that it is new enough to use sendsig() and not osendsig().
>> This makes sense because osendsig is a COMPAT_43 function and the binary
>> is a lot newer than that.
>> 
>> To preserve the "kludge" ABI as much as possible, I think it would be
>> necessary to move the assignment to sc_err into the if-else block that
>> checks to see if the signal handler was installed with the SA_SIGIFNO
>> flag, and to make the same change in sendsig(), osendsig(), and
>> freebsd4_sendsig().  This will break the wine port unless it uses
>> SA_SIGINFO.
>> 
>> 
>> As an alternative, I've got a set of patches to pm3-base to get it
>> working on -CURRENT.  It wasn't too hard to fix the bootstrap to use the
>> "undocumented 4th arg" to the signal handler that is mentioned in
>> i386/include/sigframe.h.  The rest of the patches change the low-level
>> Module-3 code to use sigaction() with the SA_SIGINFO flag instead of
>> using a mixture of sigaction() (without SA_SIGINFO) and sigvec().
>> I'll post the patches for testing once I've had a chance to clean them
>> up some more.
> 
> This sounds really, really hackish.  I talked to Alan Cox about this
> over the weekend and he said, if I have this right, that supposedly
> a correct program actually does get the correct info on the stack
> as an argument to their signal callback.  m3 should be fixed.

We pass the address on the stack as an undocumented fourth argument to
old-style signals handlers, but the proper way to get the address is to
use SA_SIGINFO.

> Either that, or we can rev the syscalls and introduce an actual
> seperate field to the info that contains the fault address and
> tell m3 to use that.

Here's a patch to make m3 use SA_SIGINFO to get the address.  I
cheated and used the undocumented fourth argument method in the
bootstrap code because that was an easier change to make by hand to the
assembly language code.  In theory, it should be possible to regenerate
the assembly language code from the .m3 file so that it also uses
SA_SIGINFO.

I've tested this on -CURRENT, and attempted to test it on 6.2-STABLE. My
testing on the latter is hampered because the only 6.2-STABLE machine I
have access to at the moment is freefall, and this port is wierd because
it does all of its interesting work in the install step.

Index: Makefile
===================================================================
RCS file: /home/ncvs/ports/lang/pm3-base/Makefile,v
retrieving revision 1.20
diff -u -r1.20 Makefile
--- Makefile	6 Oct 2006 20:25:43 -0000	1.20
+++ Makefile	30 Jul 2007 17:44:40 -0000
@@ -49,6 +49,10 @@
 INST_TARGET=	freebsd-4
 BOOTSTRAP=	pm3-${PORTVERSION}-${TARGET}-boot.tar.bz2
 WORDSIZE=	32
+.if ${OSVERSION} >= 700042
+USE_GCC= 3.4
+GCC34_PATCH=${PATCHDIR}/GCC34-patch-${TARGET}
+.endif
 .elif ${ARCH} == "alpha"
 CFLAGS+=	-mieee
 TARGET=		FBSD_ALPHA
@@ -63,6 +67,7 @@
 .if ${EXTRA_PATCHES} == ${PATCHDIR}/${TARGET}-patch-*
 .undef EXTRA_PATCHES
 .endif
+EXTRA_PATCHES+= ${GCC34_PATCH}
 
 post-patch:
 	@${CP} ${WRKSRC}/libs/m3core/src/runtime/${TARGET}/RTHeapDepC.c \
Index: files/GCC34-patch-FreeBSD4
===================================================================
RCS file: files/GCC34-patch-FreeBSD4
diff -N files/GCC34-patch-FreeBSD4
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/GCC34-patch-FreeBSD4	27 Jul 2007 20:47:31 -0000
@@ -0,0 +1,19 @@
+--- m3config/src/FreeBSD4.orig	2000-05-31 10:55:01.000000000 -0700
++++ m3config/src/FreeBSD4	2007-07-27 13:46:14.000000000 -0700
+@@ -18,12 +18,12 @@
+ 
+ ASM = ["as", "-o"]
+ BOPT_FLAG = "-O"
+-CC = ["cc","-c"]
+-GNU_CC = "cc"
++CC = ["gcc34","-c"]
++GNU_CC = "gcc34"
+ GNU_CFLAGS = []
+-LINK = ["cc"]
++LINK = ["gcc34"]
+ MAKELIB = [ "ar", "cru" ]
+-MAKESHLIB = ["cc","-shared"]
++MAKESHLIB = ["gcc34","-shared"]
+ OPT_FLAG = "-O"
+ RANLIB = ["ranlib"]
+ RPATH_FLAG = "-R"
Index: files/patch-RTHeapDep.m3
===================================================================
RCS file: files/patch-RTHeapDep.m3
diff -N files/patch-RTHeapDep.m3
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/patch-RTHeapDep.m3	28 Jul 2007 01:37:47 -0000
@@ -0,0 +1,116 @@
+--- libs/m3core/src/runtime/FreeBSD4/RTHeapDep.m3.orig	2000-05-31 10:54:33.000000000 -0700
++++ libs/m3core/src/runtime/FreeBSD4/RTHeapDep.m3	2007-07-27 18:37:41.000000000 -0700
+@@ -50,36 +50,41 @@
+ 
+     (* establish SIGSEGV handler; remember previous handler *)
+     VAR
+-      vec := Usignal.struct_sigvec{
+-               sv_handler := Fault, sv_mask :=
+-               Word.LeftShift(1, Usignal.SIGVTALRM - 1), sv_flags := 0};
+-      ovec: Usignal.struct_sigvec;
+-      ret := Usignal.sigvec(Usignal.SIGSEGV, vec, ovec);
+-      vecb := Usignal.struct_sigvec{
+-               sv_handler := Fault, sv_mask :=
+-               Word.LeftShift(1, Usignal.SIGVTALRM - 1), sv_flags := 0};
+-      ovecb: Usignal.struct_sigvec;
+-      retb := Usignal.sigvec(Usignal.SIGBUS, vecb, ovecb);
++      vec, ovec, vecb, ovecb : Usignal.struct_sigaction;
++      ret, retb : Ctypes.int;
+     BEGIN
++      vec.sa_flags  := Word.Or(Usignal.SA_RESTART, Usignal.SA_SIGINFO);
++      vecb.sa_flags  := Word.Or(Usignal.SA_RESTART, Usignal.SA_SIGINFO);
++      vec.sa_handler := Fault;
++      vecb.sa_handler := Fault;
++      EVAL Usignal.sigemptyset(vec.sa_mask);
++      EVAL Usignal.sigemptyset(vecb.sa_mask);
++      (* block the "SIGVTALRM" signal when signal handlers are called *)
++      EVAL Usignal.sigaddset(vec.sa_mask, Usignal.SIGVTALRM);
++      EVAL Usignal.sigaddset(vecb.sa_mask, Usignal.SIGVTALRM);
++      ret := Usignal.sigaction(Usignal.SIGSEGV, ADR(vec), ADR(ovec));
++      retb := Usignal.sigaction(Usignal.SIGSEGV, ADR(vecb), ADR(ovecb));
+       <* ASSERT ret = 0 *>
+       <* ASSERT retb = 0 *>
+-      defaultSIGSEGV := ovec.sv_handler;
+-      defaultSIGBUS := ovecb.sv_handler;
++      defaultSIGSEGV := ovec.sa_handler;
++      defaultSIGBUS := ovecb.sa_handler;
+     END;
+ 
+     (* establish signal handler for all other signals that dump core, if no
+        handler exists *)
+     PROCEDURE OverrideDefault (sig: Ctypes.int) =
+       VAR
+-        vec := Usignal.struct_sigvec{
+-                 sv_handler := Core, sv_mask :=
+-                 Word.LeftShift(1, Usignal.SIGVTALRM - 1), sv_flags := 0};
+-        ovec: Usignal.struct_sigvec;
+-        ret                         := Usignal.sigvec(sig, vec, ovec);
++        vec, ovec : Usignal.struct_sigaction;
++        ret : Ctypes.int;
+       BEGIN
++        vec.sa_flags := Usignal.SA_SIGINFO;
++        vec.sa_handler := Core;
++        EVAL Usignal.sigemptyset(vec.sa_mask);
++        EVAL Usignal.sigaddset(vec.sa_mask, Usignal.SIGVTALRM);
++        ret := Usignal.sigaction(sig, ADR(vec), ADR(ovec));
+         <* ASSERT ret = 0 *>
+-        IF ovec.sv_handler # Usignal.SIG_DFL THEN
+-          ret := Usignal.sigvec(sig, ovec, vec);
++        IF ovec.sa_handler # Usignal.SIG_DFL THEN
++          ret := Usignal.sigaction(sig, ADR(ovec), ADR(vec));
+           <* ASSERT ret = 0 *>
+         END;
+       END OverrideDefault;
+@@ -99,10 +104,10 @@
+    action. *)
+ 
+ PROCEDURE Fault (sig : Ctypes.int;
+-                 code: Ctypes.int;
+-                 scp : UNTRACED REF Usignal.struct_sigcontext) =
++                 info: UNTRACED REF Usignal.struct_siginfo;
++                 uap : UNTRACED REF Usignal.struct_ucontext) =
+   VAR
+-    sf_addr := LOOPHOLE(scp.sc_err, ADDRESS);
++    sf_addr := info.si_addr;
+ 
+   BEGIN
+     IF RTHeapRep.Fault(sf_addr) THEN
+@@ -110,9 +115,9 @@
+     END;
+     IF defaultSIGSEGV = Usignal.SIG_IGN THEN RETURN; END;
+     IF defaultSIGSEGV = Usignal.SIG_DFL THEN
+-      Core(sig, code, scp);
++      Core(sig, info, uap);
+     ELSE
+-      defaultSIGSEGV(sig, code, scp);
++      defaultSIGSEGV(sig, info, uap);
+     END;
+   END Fault;
+ 
+@@ -124,18 +129,20 @@
+ VAR dumped_core := FALSE;
+ 
+ PROCEDURE Core (             sig : Ctypes.int;
+-                <* UNUSED *> code: Ctypes.int;
+-                <* UNUSED *> scp : UNTRACED REF Usignal.struct_sigcontext) =
++                <* UNUSED *> info: UNTRACED REF Usignal.struct_siginfo;
++                <* UNUSED *> uap : UNTRACED REF Usignal.struct_ucontext) =
+   VAR
+-    ovec: Usignal.struct_sigvec;
+-    vec := Usignal.struct_sigvec{sv_handler := Usignal.SIG_DFL,
+-                                 sv_mask := 0, sv_flags := 0};
++    ovec: Usignal.struct_sigaction;
++    vec : Usignal.struct_sigaction;
+   BEGIN
+     INC(RT0u.inCritical);
+     IF NOT dumped_core THEN
+       dumped_core := TRUE;
+       EVAL RTHeapRep.Crash();      (* clean up the heap *)
+-      EVAL Usignal.sigvec(sig, vec, ovec); (* establish default action *)
++      vec.sa_handler := Usignal.SIG_DFL;
++      EVAL Usignal.sigemptyset(vec.sa_mask);
++      vec.sa_flags := 0;
++      EVAL Usignal.sigaction(sig, ADR(vec), ADR(ovec)); (* establish default action *)
+       EVAL Usignal.sigsetmask(0);
+       (** EVAL Usignal.kill(Uprocess.getpid(), sig); (* dump core *) **)
+       Cstdlib.abort (); (* dump core *)
Index: files/patch-RTHeapDep.ms
===================================================================
RCS file: files/patch-RTHeapDep.ms
diff -N files/patch-RTHeapDep.ms
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/patch-RTHeapDep.ms	27 Jul 2007 20:44:44 -0000
@@ -0,0 +1,12 @@
+--- boot-FreeBSD4/m3core/FreeBSD4/RTHeapDep.ms.orig	2000-09-05 14:50:31.000000000 -0700
++++ boot-FreeBSD4/m3core/FreeBSD4/RTHeapDep.ms	2007-07-27 13:42:37.000000000 -0700
+@@ -232,8 +232,7 @@
+ 	pushl %ebx
+ 	movl 8(%ebp),%edi
+ 	movl 12(%ebp),%esi
+-	movl 16(%ebp),%ebx
+-	movl 72(%ebx),%eax
++	movl 20(%ebp),%eax
+ 	pushl %eax
+ 	movl MI_RTHeapRep+556,%eax
+ 	call *%eax
Index: files/patch-RTSignal.m3
===================================================================
RCS file: files/patch-RTSignal.m3
diff -N files/patch-RTSignal.m3
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/patch-RTSignal.m3	30 Jul 2007 07:39:16 -0000
@@ -0,0 +1,64 @@
+--- libs/m3core/src/runtime/FreeBSD4/RTSignal.m3.orig	2000-05-31 10:54:33.000000000 -0700
++++ libs/m3core/src/runtime/FreeBSD4/RTSignal.m3	2007-07-27 18:55:32.000000000 -0700
+@@ -10,9 +10,6 @@
+ IMPORT RTMisc, RTProcess, Usignal, Uprocess;
+ FROM Ctypes IMPORT int;
+ 
+-TYPE
+-  SigInfo = UNTRACED REF Usignal.struct_sigcontext;
+-
+ VAR
+   DefaultHandler   : Usignal.SignalHandler;
+   IgnoreSignal     : Usignal.SignalHandler;
+@@ -61,7 +58,9 @@
+     EVAL Usignal.sigaction (sig, ADR(initial_handlers[id]), NIL);
+   END RestoreHandler;
+ 
+-PROCEDURE Shutdown (sig: int; <*UNUSED*> code: int; <*UNUSED*> scp: SigInfo) =
++PROCEDURE Shutdown (sig : int;
++                    <*UNUSED*> info: UNTRACED REF Usignal.struct_siginfo;
++                    <*UNUSED*> uap : UNTRACED REF Usignal.struct_ucontext) =
+   VAR new, old: Usignal.struct_sigaction;
+   BEGIN
+     new.sa_handler := DefaultHandler;
+@@ -71,28 +70,34 @@
+     EVAL Usignal.kill (Uprocess.getpid (), sig);  (* and resend the signal *)
+   END Shutdown;
+ 
+-PROCEDURE Interrupt (sig: int;  code: int;  scp: SigInfo) =
++PROCEDURE Interrupt (sig : int;
++                     info: UNTRACED REF Usignal.struct_siginfo;
++                     uap : UNTRACED REF Usignal.struct_ucontext) =
+   VAR h := RTProcess.OnInterrupt (NIL);
+   BEGIN
+     IF (h = NIL) THEN
+-      Shutdown (sig, code, scp);
++      Shutdown (sig, info, uap);
+     ELSE
+       EVAL RTProcess.OnInterrupt (h); (* reinstall the handler *)
+       h ();
+     END;
+   END Interrupt;
+ 
+-PROCEDURE Quit (<*UNUSED*> sig, code: int; scp: SigInfo) =
++PROCEDURE Quit (<*UNUSED*> sig : int;
++                <*UNUSED*> info: UNTRACED REF Usignal.struct_siginfo;
++                uap : UNTRACED REF Usignal.struct_ucontext) =
+   VAR pc := 0;
+   BEGIN
+-    IF (scp # NIL) THEN pc := scp.sc_eip END;
++    IF (uap # NIL) THEN pc := uap.uc_mcontext.mc_eip END;
+     RTMisc.FatalErrorPC (pc, "aborted");
+   END Quit;
+ 
+-PROCEDURE SegV (<*UNUSED*> sig, code: int; scp: SigInfo) =
++PROCEDURE SegV (<*UNUSED*> sig : int;
++                <*UNUSED*> info: UNTRACED REF Usignal.struct_siginfo;
++                uap : UNTRACED REF Usignal.struct_ucontext) =
+   VAR pc := 0;
+   BEGIN
+-    IF (scp # NIL) THEN pc := scp.sc_eip END;
++    IF (uap # NIL) THEN pc := uap.uc_mcontext.mc_eip END;
+     RTMisc.FatalErrorPC (pc,
+       "Segmentation violation - possible attempt to dereference NIL");
+   END SegV;
Index: files/patch-Usignal.i3
===================================================================
RCS file: files/patch-Usignal.i3
diff -N files/patch-Usignal.i3
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ files/patch-Usignal.i3	30 Jul 2007 07:32:05 -0000
@@ -0,0 +1,104 @@
+--- libs/m3core/src/unix/freebsd-4/Usignal.i3.orig	2000-05-31 10:54:53.000000000 -0700
++++ libs/m3core/src/unix/freebsd-4/Usignal.i3	2007-07-30 00:31:02.000000000 -0700
+@@ -8,7 +8,8 @@
+ 
+ INTERFACE Usignal;
+ 
+-FROM Ctypes IMPORT int, unsigned_int;
++FROM Ctypes IMPORT int, unsigned_int, char, void_star;
++FROM Utypes IMPORT pid_t, uid_t, size_t;
+ 
+ (*** <signal.h> ***)
+ 
+@@ -62,8 +63,9 @@
+ 
+ (* Signal vector "template" used in sigaction call. *)
+ TYPE
+-  SignalHandler = PROCEDURE (sig, code: int;
+-                             scp: UNTRACED REF struct_sigcontext);
++  SignalHandler = PROCEDURE (sig: int;
++                             info: UNTRACED REF struct_siginfo;
++                             uap: UNTRACED REF struct_ucontext);
+ 
+   sigset_t = ARRAY [0..3] OF unsigned_int;
+   sigset_t_star = UNTRACED REF sigset_t;
+@@ -108,6 +110,8 @@
+   SA_RESETHAND   = 16_0004;   (* reset to SIG_DFL when taking signal *)
+   SA_NOCLDSTOP   = 16_0008;   (* do not generate SIGCHLD on child stop *)
+   SA_NODEFER     = 16_0010;   (* don't mask the signal we're delivering *)
++  SA_NOCLDWAIT   = 16_0020;   (* don't keep zombies around *)
++  SA_SIGINFO     = 16_0040;   (* signal handler with SA_SIGINFO args *)
+ 
+ TYPE
+   struct_sigstack = RECORD 
+@@ -148,6 +152,70 @@
+     sc_ss: int;
+   END;
+ 
++TYPE
++  struct_mcontext = RECORD
++    mc_onstack: int;   (* sigstack state to restore *)
++    mc_gs: int;
++    mc_fs: int;
++    mc_es: int;
++    mc_ds: int;
++    mc_edi: int;
++    mc_esi: int;
++    mc_ebp: int;       (* frame pointer *)
++    mc_isp: int;
++    mc_ebx: int;
++    mc_edx: int;
++    mc_ecx: int;
++    mc_eax: int;
++    mc_trapno: int;
++    mc_err: int;
++    mc_eip: int;       (* program counter *)
++    mc_cs: int;
++    mc_efl: int;
++    mc_esp: int;       (* stack pinter *)
++    mc_ss: int;
++
++    mc_len: int;
++    mc_fpformat: int;
++    mc_ownedfp: int;
++    mc_spare1: int;
++    mc_fpstate: ARRAY [0..127] OF int;
++    mc_spare2:  ARRAY [0..7] OF int;
++  END;
++
++TYPE
++  struct_stack = RECORD
++    ss_sp:   UNTRACED REF char;
++    ss_size: size_t;
++    ss_flags: int;
++  END;
++
++TYPE
++  struct_ucontext = RECORD
++    us_sigmask: sigset_t; (* signal mask to restore *)
++    uc_mcontext: struct_mcontext;
++    uc_link: UNTRACED REF struct_ucontext;
++    uc_stack: struct_stack;
++    uc_flags: int;
++    uc_spare: ARRAY [0..3] OF int;
++  END;
++
++TYPE
++  struct_siginfo = RECORD
++    si_signo:  int;
++    si_errno:  int;
++    si_code:   int;
++    si_pid:    pid_t;
++    si_uid:    uid_t;
++    si_status: int;
++    si_addr:   void_star;
++    sival_int: int;
++    (* XXX - various union members below *)
++    si_reason_trapno_timerid: int;
++    si_reason_overrun:        int;
++    si_spare2: ARRAY [1..6] OF int;
++  END;
++
+ (* Do not modifiy these variables *)
+ VAR (*CONST*)
+   BADSIG, SIG_ERR, SIG_DFL, SIG_IGN, SIG_HOLD: SignalHandler;




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200707301824.l6UIO7Qf092040>