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