pm3-base, cvsup, etc. on -CURRENT [patch]

Don Lewis truckman at FreeBSD.org
Mon Jul 30 18:47:01 UTC 2007


The Modula 3 ports recently stopped working on -CURRENT because of a
change to the i386 machine-dependent kernel code removed a kludge that
the pm3 garbage collector was using to find the fault address when
accesses were made to protected pages.  The correct fix for this is to
convert the garbage collector to using sigaction() with the SA_SIGINFO
flag so that it can get the address in a supported fashion.  A further
problem is that the pm3-base port can't be built with GCC 4.2, which is
the base compiler in current.  The patch below addresses both of these
issues, though I cheated a bit in the bootstrap code by relying on the
fact that the fault address is also returned in an undocumented fourth
argument to old-style signal handlers, because this was an easier change
to make by hand.  In theory, the bootstrap assembly language code could
be regenerated from the .m3 source.

I've tested this on -CURRENT.  I've done some partial testing on
6.2-STABLE, but this port does most of its interesting work in the
install step, which is a problem for me because I don't happen to have
full access to a machine running -STABLE at the momemt.

I'd appreciate any feedback and testing of this patch that I can get.

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;



More information about the freebsd-ports mailing list