for review: Linux-m68k port.

Tyson Dowd trd at cs.mu.OZ.AU
Tue Sep 29 19:30:53 AEST 1998


Hi,

This one has been waiting in the queue for a while.  
I think this addresses all the concerns of the previous review
(which was months ago).

It also contains improvements -- e.g. code for doing non-local
gotos.

I have no idea if this stuff works at all -- I will try to
get Roman to test it.

===================================================================


Estimated hours taken: 20

Port to Linux-m68k.  A lot of this work was done by Roman Hodek,
<Roman.Hodek at informatik.uni-erlangen.de>.

README.Linux-m68k:
	Mention that we have a port to the 68k.

configure.in:
	Add a test for two different sorts of signal handlers
	  void handler(int signum, struct sigcontext_struct context)
	and
	  void handler(int signum, int code, struct sigcontext_struct context)
	Set HAVE_SIGCONTEXT_STRUCT_NONBSD or HAVE_SIGCONTEXT_STRUCT_BSD 
	appropriately.

	Add support for shared libraries on the m68k as they should
	work.

	Make "working struct sigcontext" tests use MR_GET_FAULT_ADDR.

boehm_gc/config.h:
	Add some definitions for the m68k.

boehm_gc/os_dep.c:
	Get fault addresses using m68k specific code.

runtime/mercury_conf.h.in:
	Add new configuration definitions HAVE_SIGCONTEXT_STRUCT_BSD,
	and HAVE_SIGCONTEXT_STRUCT_BSD.

runtime/mercury_faultaddr.h:
	Add MR_GET_FAULT_ADDR.

runtime/mercury_goto.h:
	Add support for non-local gotos with Linux-68k.

runtime/mercury_memory_handlers.c:
	Handle 2 or 3 argument signal handlers.



Index: README.Linux-m68k
===================================================================
RCS file: README.Linux-m68k
diff -N README.Linux-m68k
--- /dev/null	Wed May 28 10:49:58 1997
+++ README.Linux-m68k	Tue Sep 29 18:30:30 1998
@@ -0,0 +1,9 @@
+
+Mercury has been ported to Linux/m68k thanks to Roman Hodek
+<Roman.Hodek at informatik.uni-erlangen.de>.
+
+The port is relatively untested -- if you have an m68k machine
+running Linux and run Mercury successfully please let us know.
+
+
+
Index: configure.in
===================================================================
RCS file: /home/mercury1/repository/mercury/configure.in,v
retrieving revision 1.133
diff -u -r1.133 configure.in
--- configure.in	1998/07/01 06:07:58	1.133
+++ configure.in	1998/09/29 08:51:59
@@ -376,8 +376,8 @@
 # check the basics of sigcontext_struct
 #
 AC_MSG_CHECKING(for working \`sigcontext_struct')
-AC_CACHE_VAL(mercury_cv_sigcontext_struct,
-mercury_cv_sigcontext_struct=no
+AC_CACHE_VAL(mercury_cv_sigcontext_struct_nonbsd,
+mercury_cv_sigcontext_struct_nonbsd=no
 AC_TRY_RUN([
 /* see runtime/memory.c for documentation of this code */
 
@@ -391,6 +391,8 @@
 #include <asm/sigcontext.h>
 #endif
 
+#include "mercury_faultaddr.h"
+
 #include <stdio.h>
 
 extern void handler(int signum, struct sigcontext_struct info);
@@ -407,13 +409,79 @@
 }
 
 void handler(int signum, struct sigcontext_struct context) {
-	if (signum == SIGSEGV && (int *) context.cr2 == FAULT_ADDRESS) {
+	int *addr;
+	addr = (int *) MR_GET_FAULT_ADDR(context);
+	if (signum == SIGSEGV && addr == FAULT_ADDRESS) {
 		exit(0);
 	} else {
 		exit(1);
 	}
-}], [mercury_cv_sigcontext_struct=yes], [true], [true]))
-AC_MSG_RESULT($mercury_cv_sigcontext_struct)
+}], [mercury_cv_sigcontext_struct_nonbsd=yes], [true], [true]))
+AC_MSG_RESULT($mercury_cv_sigcontext_struct_nonbsd)
+
+if test $mercury_cv_sigcontext_struct_nonbsd = no; then
+	#
+	# check for a BSD style sigcontext_struct
+	#
+	AC_MSG_CHECKING(for BSD-ish \`sigcontext_struct')
+	AC_CACHE_VAL(mercury_cv_sigcontext_struct_bsd,
+	mercury_cv_sigcontext_struct_bsd=no
+
+	/* see runtime/mercury_memory.c for documentation of this code */
+
+	AC_TRY_RUN([
+
+	#define sigcontext_struct sigcontext
+
+	#define __KERNEL__
+	#include <signal.h>
+	#undef __KERNEL__
+
+	#ifdef HAVE_ASM_SIGCONTEXT
+	#include <asm/sigcontext.h>
+	#endif
+
+	#include "mercury_faultaddr.h"
+
+	#include <stdio.h>
+
+	extern void handler(int signum, int code, struct
+		sigcontext_struct info);
+
+	#define FAULT_ADDRESS ((int *)112)
+
+	int main() {
+		signal(SIGSEGV, (void (*)(int))handler);
+
+		/* provoke a SIGSEGV */
+		(*FAULT_ADDRESS)++;
+
+		exit(1);
+	}
+
+	void handler(int signum, int code, struct sigcontext_struct context) {
+		int *addr;
+		addr = (int *) MR_GET_FAULT_ADDR(context);
+		if (signum == SIGSEGV && addr == FAULT_ADDRESS) {
+			exit(0);
+		} else {
+			exit(1);
+		}
+	}], [mercury_cv_sigcontext_struct_bsd=yes], [true], [true]))
+else
+	mercury_cv_sigcontext_struct_bsd=no
+fi
+
+if test $mercury_cv_sigcontext_struct_nonbsd = yes; then
+	mercury_cv_sigcontext_struct=yes
+	AC_DEFINE(HAVE_SIGCONTEXT_STRUCT_NONBSD)
+fi
+
+if test $mercury_cv_sigcontext_struct_bsd = yes; then
+	mercury_cv_sigcontext_struct=yes
+	AC_DEFINE(HAVE_SIGCONTEXT_STRUCT_BSD)
+fi
+
 if test $mercury_cv_sigcontext_struct = yes; then
 	AC_DEFINE(HAVE_SIGCONTEXT_STRUCT)
 	AC_DEFINE(HAVE_SIGINFO)
@@ -437,9 +505,16 @@
 	#include <asm/sigcontext.h>
 	#endif
 
+	#include "mercury_faultaddr.h"
+
 	#include <stdio.h>
 
-	extern void handler(int signum, struct sigcontext_struct info);
+	#if HAVE_SIGCONTEXT_STRUCT_BSD
+	extern void handler(int signum, int code, 
+			struct sigcontext_struct context);
+	#else
+	extern void handler(int signum, struct sigcontext_struct context);
+	#endif
 
 	#define FAULT_ADDRESS ((int *)112)
 
@@ -452,11 +527,16 @@
 		exit(1);
 	}
 
-	void handler(int signum, struct sigcontext_struct info) {
-		if (signum == SIGSEGV &&
-			(int *) info.cr2 == FAULT_ADDRESS &&
-			(long) info.eip != 0)
-		{
+	#if HAVE_SIGCONTEXT_STRUCT_BSD
+	void handler(int signum, int code, struct sigcontext_struct context) {
+	#else
+	void handler(int signum, struct sigcontext_struct context) {
+	#endif
+		int *addr;
+		long pc;
+		addr = (int *) MR_GET_FAULT_ADDR(context);
+		pc = (long) context.eip;
+		if (signum == SIGSEGV && addr == FAULT_ADDRESS && pc != 0) {
 			exit(0);
 		} else {
 			exit(1);
@@ -1516,6 +1596,10 @@
 
 case "$host" in
 	i?86-*-linux|i?86-*-linux-gnu)
+		AC_MSG_RESULT(yes)
+		EXT_FOR_SHARED_LIB=so
+		;;
+	m68*-linux|m68*-linux-gnu)
 		AC_MSG_RESULT(yes)
 		EXT_FOR_SHARED_LIB=so
 		;;
Index: boehm_gc/config.h
===================================================================
RCS file: /home/mercury1/repository/mercury/boehm_gc/config.h,v
retrieving revision 1.14
diff -u -r1.14 config.h
--- config.h	1998/08/31 23:05:08	1.14
+++ config.h	1998/09/29 07:19:05
@@ -118,21 +118,24 @@
 #   define HP_PA
 #   define mach_type_known
 # endif
-# if defined(linux) && defined(i386)
-#    define I386
+# if defined(linux) || defined(__linux__)
 #    define LINUX
+# endif
+# if defined(LINUX) && defined(i386)
+#    define I386
 #    define mach_type_known
 # endif
-# if defined(linux) && defined(powerpc)
+# if defined(LINUX) && defined(powerpc)
 #    define POWERPC
-#    define LINUX
 #    define mach_type_known
 # endif
+# if defined(LINUX) && defined(__mc68000__)
+#    define M68K
+#    define mach_type_known
+# endif
 # if defined(__alpha) || defined(__alpha__)
 #   define ALPHA
-#   if defined(linux) || defined(__linux__)
-#     define LINUX
-#   else
+#   if !defined(LINUX)
 #     define OSF1	/* a.k.a Digital Unix */
 #   endif
 #   define mach_type_known
@@ -370,6 +373,29 @@
 #	define HEURISTIC2
 	extern char etext;
 #	define DATASTART ((ptr_t)(&etext))
+#   endif
+#   ifdef LINUX
+#      define OS_TYPE "LINUX"
+#      define STACKBOTTOM ((ptr_t)0xf0000000)
+#      define MPROTECT_VDB
+#       ifdef __ELF__
+#            define DYNAMIC_LOADING
+             extern char **__environ;
+#            define DATASTART ((ptr_t)(&__environ))
+                             /* hideous kludge: __environ is the first */
+                             /* word in crt0.o, and delimits the start */
+                             /* of the data segment, no matter which   */
+                             /* ld options were passed through.        */
+                             /* We could use _etext instead, but that  */
+                             /* would include .rodata, which may       */
+                             /* contain large read-only data tables    */
+                             /* that we'd rather not scan.             */
+             extern int _end;
+#            define DATAEND (&_end)
+#       else
+             extern int etext;
+#            define DATASTART ((ptr_t)((((word) (&etext)) + 0xfff) & ~0xfff))
+#       endif
 #   endif
 #   ifdef SUNOS4
 #	define OS_TYPE "SUNOS4"
Index: boehm_gc/os_dep.c
===================================================================
RCS file: /home/mercury1/repository/mercury/boehm_gc/os_dep.c,v
retrieving revision 1.19
diff -u -r1.19 os_dep.c
--- os_dep.c	1998/08/31 23:05:22	1.19
+++ os_dep.c	1998/09/29 07:09:05
@@ -1453,7 +1453,12 @@
 # endif
 # if defined(LINUX)
 #   if (LINUX_VERSION_CODE >= 0x20100)
-      void GC_write_fault_handler(int sig, struct sigcontext sc)
+#     if defined(M68K)
+	void GC_write_fault_handler(int sig, int code,
+			struct sigcontext_struct sc)
+#     else
+        void GC_write_fault_handler(int sig, struct sigcontext sc)
+#     endif
 #   else
       void GC_write_fault_handler(int sig, struct sigcontext_struct sc)
 #   endif
@@ -1489,6 +1494,30 @@
 #   ifdef LINUX
 #     ifdef I386
 	char * addr = (char *) (sc.cr2);
+#     elif defined(M68K)
+        char * addr = NULL;
+
+	struct sigcontext *scp = (struct sigcontext *)(&sc);
+
+	int format = (scp->sc_formatvec >> 12) & 0xf;
+	unsigned long *framedata = (unsigned long *)(scp + 1); 
+	unsigned long ea;
+
+	if (format == 0xa || format == 0xb) {
+		/* 68020/030 */
+		ea = framedata[2];
+	} else if (format == 7) {
+		/* 68040 */
+		ea = framedata[3];
+	} else if (format == 4) {
+		/* 68060 */
+		ea = framedata[0];
+		if (framedata[1] & 0x08000000) {
+			/* correct addr on misaligned access */
+			ea = (ea+4095)&(~4095);
+		}
+	}	
+	addr = (char *)ea;
 #     else
         char * addr = /* As of 1.3.90 there seemed to be no way to do this. */;
 #     endif
Index: runtime/mercury_conf.h.in
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf.h.in,v
retrieving revision 1.6
diff -u -r1.6 mercury_conf.h.in
--- mercury_conf.h.in	1998/06/09 02:07:47	1.6
+++ mercury_conf.h.in	1998/09/29 08:27:52
@@ -125,10 +125,20 @@
 **	HAVE_SIGCONTEXT_STRUCT	defined iff normal signal handlers are given
 **				sigcontext_struct arguments that we can use to
 **				figure out the fault address for SIGSEGVs.
+**	HAVE_SIGCONTEXT_STRUCT_BSD
+**				defined iff signal handlers have three
+**				parameters, the third being the
+**				sigcontext struct.
+**	HAVE_SIGCONTEXT_STRUCT_NONBSD
+**				defined iff signal handlers have two
+**				parameters, the second being the
+**				sigcontext struct. 
 */
 #undef	HAVE_SIGINFO
 #undef	HAVE_SIGINFO_T
 #undef	HAVE_SIGCONTEXT_STRUCT
+#undef	HAVE_SIGCONTEXT_STRUCT_BSD
+#undef	HAVE_SIGCONTEXT_STRUCT_NONBSD
 
 /*
 ** For debugging purposes, if we get a fatal signal, we print out the
Index: runtime/mercury_faultaddr.h
===================================================================
RCS file: mercury_faultaddr.h
diff -N mercury_faultaddr.h
--- /dev/null	Wed May 28 10:49:58 1997
+++ mercury_faultaddr.h	Tue Sep 29 18:03:17 1998
@@ -0,0 +1,58 @@
+/*
+** Copyright (C) 1998 The University of Melbourne.
+** This file may only be copied under the terms of the GNU Library General
+** Public License - see the file COPYING.LIB in the Mercury distribution.
+*/
+
+/*
+** mercury_faultaddr.h:  
+** 	Macros for determining the fault address of a signal.
+** 	This is usually non-portable, so architecture specific versions
+** 	are given here, so a single macro can be used elsewhere in the
+** 	system (in particular, this code is necessary both in the
+** 	runtime and in the configuration scripts).
+*/
+
+#ifndef	MERCURY_FAULT_ADDR_H
+#define	MERCURY_FAULT_ADDR_H
+
+
+#if defined(__i386__)
+
+  #define MR_GET_FAULT_ADDR(sc) \
+	((void *)(((struct sigcontext_struct)(sc)).cr2))
+
+#elif defined(__mc68000__)
+
+  #define MR_GET_FAULT_ADDR(sc)					\
+	({ 								\
+		struct sigcontext *scp = (struct sigcontext *)(&sc);	\
+		int format = (scp->sc_formatvec >> 12) & 0xf;		\
+		unsigned long *framedata = (unsigned long *)(scp + 1);	\
+		unsigned long ea; 					\
+		if (format == 0xa || format == 0xb)			\
+			/* 68020/030 */ 				\
+			ea = framedata[2];				\
+		else if (format == 7)					\
+			/* 68040 */					\
+			ea = framedata[3];				\
+		else if (format == 4) {					\
+			/* 68060 */					\
+			ea = framedata[0];				\
+			if (framedata[1] & 0x08000000)			\
+				/* correct addr on misaligned access */	\
+				ea = (ea+4095)&(~4095);			\
+			}						\
+			(void *)ea;					\
+	})
+#else
+
+/* 
+** This space deliberately left blank.
+** 
+** We will get a compile error if it is used but not defined.
+*/
+
+#endif
+
+#endif /* not MERCURY_FAULT_ADDR_H */
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_goto.h,v
retrieving revision 1.14
diff -u -r1.14 mercury_goto.h
--- mercury_goto.h	1998/09/04 11:26:10	1.14
+++ mercury_goto.h	1998/09/29 08:45:11
@@ -111,10 +111,12 @@
   #define ASM_FALLTHROUGH(label) \
   	goto skip(label);
 
-#elif defined(__i386__)
+#elif defined(__i386__) || defined(__mc68000__)
 
   /*
   ** The following hack works around a stack leak on the i386.
+  ** (and apparently the 68000 too).
+  **
   ** The problem is that gcc pushes function parameters onto
   ** the stack when calling C functions such as GC_malloc(),
   ** and only restores the stack pointer in the epilogue.
@@ -178,7 +180,9 @@
     ** setjmp()/longjmp() will do that for us automatically,
     ** precisely because it is a callee-save register.
     */
-    #define INLINE_ASM_FIXUP_REGS     				\
+    #if defined(__i386__)
+
+      #define INLINE_ASM_FIXUP_REGS     			\
     	"	call 0f\n"     					\
     	"0:\n"       						\
     	"	popl %%ebx\n"     				\
@@ -192,6 +196,17 @@
 		/* tell gcc we clobber ebx and memory */	\
     		: : : "%ebx", "memory"
 #endif
+    #elif defined(__mc68000__)
+
+	/*
+	**  This piece of magic thanks to Roman Hodek
+	**  <Roman.Hodek at informatik.uni-erlangen.de>
+	*/ 
+
+      #define INLINE_ASM_FIXUP_REGS \
+        "       lea (%%pc,_GLOBAL_OFFSET_TABLE_ at GOTPC),%%a5\n" : : : "memory"
+
+    #endif
 
     /*
     ** It is safe to fall through into INLINE_ASM_FIXUP_REGS,
Index: runtime/mercury_memory_handlers.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_memory_handlers.c,v
retrieving revision 1.8
diff -u -r1.8 mercury_memory_handlers.c
--- mercury_memory_handlers.c	1998/09/29 05:11:00	1.8
+++ mercury_memory_handlers.c	1998/09/29 08:26:03
@@ -68,12 +68,18 @@
 #include "mercury_trace_base.h"
 #include "mercury_memory_zones.h"
 #include "mercury_memory_handlers.h"
+#include "mercury_faultaddr.h"
 
 /*---------------------------------------------------------------------------*/
 
 #ifdef HAVE_SIGINFO
   #if defined(HAVE_SIGCONTEXT_STRUCT)
-    static	void	complex_sighandler(int, struct sigcontext_struct);
+    #if defined(HAVE_SIGCONTEXT_STRUCT_BSD)
+      static	void	complex_sighandler_bsd(int, int, 
+		      struct sigcontext_struct);
+    #else
+      static	void	complex_sighandler(int, struct sigcontext_struct);
+    #endif
   #elif defined(HAVE_SIGINFO_T)
     static	void	complex_bushandler(int, siginfo_t *, void *);
     static	void	complex_segvhandler(int, siginfo_t *, void *);
@@ -87,8 +93,13 @@
 
 #ifdef HAVE_SIGINFO
   #if defined(HAVE_SIGCONTEXT_STRUCT)
-    #define     bus_handler	complex_sighandler
-    #define     segv_handler	complex_sighandler
+    #if defined(HAVE_SIGCONTEXT_STRUCT_BSD)
+      #define     bus_handler	complex_sighandler_bsd
+      #define     segv_handler	complex_sighandler_bsd
+    #else
+      #define     bus_handler	complex_sighandler
+      #define     segv_handler	complex_sighandler
+    #endif
   #elif defined(HAVE_SIGINFO_T)
     #define     bus_handler	complex_bushandler
     #define     segv_handler	complex_segvhandler
@@ -306,11 +317,15 @@
 }
 
 #if defined(HAVE_SIGCONTEXT_STRUCT)
-
-static void
-complex_sighandler(int sig, struct sigcontext_struct sigcontext)
+  #if defined(HAVE_SIGCONTEXT_STRUCT_BSD)
+    static void
+    complex_sighandler(int sig, int code, struct sigcontext_struct sigcontext)
+  #else
+    static void
+    complex_sighandler(int sig, struct sigcontext_struct sigcontext)
+  #endif
 {
-	void *address = (void *) sigcontext.cr2;
+	void *address = (void *) MR_GET_FAULT_ADDR(sigcontext);
   #ifdef PC_ACCESS
 	void *pc_at_signal = (void *) sigcontext.PC_ACCESS;
   #endif


-- 
       Tyson Dowd           # There isn't any reason why Linux can't be
                            # implemented as an enterprise computing solution.
     trd at cs.mu.oz.au        # Find out what you've been missing while you've
http://www.cs.mu.oz.au/~trd # been rebooting Windows NT. -- InfoWorld, 1998.



More information about the developers mailing list