From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Ali Mohammad Pur <ali.mpfard@gmail.com>
Date: Mon, 27 Mar 2023 20:03:03 +1100
Subject: [PATCH] Teach os_dep and gcconfig.h about minerva

---
 include/private/gcconfig.h | 32 +++++++++++++++++++++++++++++---
 os_dep.c                   | 32 ++++++++++++++++++++++++--------
 2 files changed, 53 insertions(+), 11 deletions(-)

diff --git a/include/private/gcconfig.h b/include/private/gcconfig.h
index c1cf80fb1fb9fde95e14b0839a70d7ba421bf88f..b410f188f91960977a11695bf2a9da4639a32e94 100644
--- a/include/private/gcconfig.h
+++ b/include/private/gcconfig.h
@@ -344,6 +344,15 @@ EXTERN_C_BEGIN
 #   endif
 #   define mach_type_known
 # endif
+# if defined(__minerva__)
+#    define MINERVA
+#    define mach_type_known
+#    if defined(_X86_) || defined (__i386__)
+#        define I386
+#    elif defined(__x86_64__)
+#        define X86_64
+#    endif
+#endif
 # if (defined(__BEOS__) || defined(__HAIKU__)) && defined(_X86_)
 #    define I386
 #    define HAIKU
@@ -1068,6 +1077,23 @@ EXTERN_C_BEGIN
 #   endif
 # endif /* OPENBSD */
 
+#   ifdef MINERVA
+#     define OS_TYPE "MINERVA"
+      EXTERN_C_END
+#     include <unistd.h>
+      EXTERN_C_BEGIN
+#     define GETPAGESIZE() (unsigned)sysconf(_SC_PAGESIZE)
+      extern int etext[], _end[];
+#     define DATASTART ((ptr_t)((((word)(etext)) + 0xfff) & ~0xfff))
+#     define DATAEND ((ptr_t)(_end))
+#     define DYNAMIC_LOADING
+#     define MPROTECT_VDB
+#     define USE_MMAP_ANON
+#     ifndef USE_MMAP
+#       define USE_MMAP 1
+#     endif
+#   endif
+
 # ifdef SOLARIS
 #   define OS_TYPE "SOLARIS"
     extern int _etext[], _end[];
@@ -2757,7 +2783,7 @@ EXTERN_C_BEGIN
 #if defined(SVR4) || defined(LINUX) || defined(IRIX5) || defined(HPUX) \
     || defined(OPENBSD) || defined(NETBSD) || defined(FREEBSD) \
     || defined(DGUX) || defined(BSD) || defined(HAIKU) || defined(HURD) \
-    || defined(AIX) || defined(DARWIN) || defined(OSF1)
+    || defined(AIX) || defined(DARWIN) || defined(OSF1) || defined(MINERVA)
 # define UNIX_LIKE      /* Basic Unix-like system calls work.   */
 #endif
 
@@ -2807,7 +2833,7 @@ EXTERN_C_BEGIN
 
 #if defined(DARWIN) || defined(FREEBSD) || defined(HAIKU) \
     || defined(IRIX5) || defined(LINUX) || defined(NETBSD) \
-    || defined(OPENBSD) || defined(SOLARIS) \
+    || defined(OPENBSD) || defined(SOLARIS) || defined(MINERVA) \
     || ((defined(CYGWIN32) || defined(USE_MMAP) || defined(USE_MUNMAP)) \
         && !defined(USE_WINALLOC))
   /* Try both sbrk and mmap, in that order.     */
@@ -2943,7 +2969,7 @@ EXTERN_C_BEGIN
 
 #if ((defined(UNIX_LIKE) && (defined(DARWIN) || defined(HAIKU) \
                              || defined(HURD) || defined(OPENBSD) \
-                             || defined(ARM32) \
+                             || defined(ARM32) || defined(MINERVA) \
                              || defined(AVR32) || defined(MIPS) \
                              || defined(NIOS2) || defined(OR1K))) \
      || (defined(LINUX) && !defined(__gnu_linux__)) \
diff --git a/os_dep.c b/os_dep.c
index e90c7725011df1263ba7fcdadb839837a7e1b3d7..7e33a5daf11e8f3fc08c1e9dd9af17873f477729 100644
--- a/os_dep.c
+++ b/os_dep.c
@@ -858,6 +858,22 @@ GC_INNER size_t GC_page_size = 0;
 # define HAVE_GET_STACK_BASE
 #endif /* HAIKU */
 
+#ifdef MINERVA
+# include <minerva.h>
+  GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *sb)
+  {
+    uintptr_t base;
+    size_t size;
+    if (get_stack_bounds(&base, &size) < 0) {
+      WARN("get_stack_bounds failed\n", 0);
+      return GC_UNIMPLEMENTED;
+    }
+    sb->mem_base = base + size;
+    return GC_SUCCESS;
+  }
+# define HAVE_GET_STACK_BASE
+#endif /* MINERVA */
+
 #ifdef OS2
   GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *sb)
   {
@@ -889,7 +905,7 @@ GC_INNER size_t GC_page_size = 0;
 
 #   if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) \
        || defined(HAIKU) || defined(HURD) || defined(FREEBSD) \
-       || defined(NETBSD)
+       || defined(NETBSD) || defined(MINERVA)
         static struct sigaction old_segv_act;
 #       if defined(_sigargs) /* !Irix6.x */ || defined(HPUX) \
            || defined(HURD) || defined(NETBSD) || defined(FREEBSD)
@@ -906,7 +922,7 @@ GC_INNER size_t GC_page_size = 0;
     {
 #       if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) \
            || defined(HAIKU) || defined(HURD) || defined(FREEBSD) \
-           || defined(NETBSD) || defined(OPENBSD)
+           || defined(NETBSD) || defined(OPENBSD) || defined(MINERVA)
           struct sigaction act;
 
           act.sa_handler = h;
@@ -973,7 +989,7 @@ GC_INNER size_t GC_page_size = 0;
     {
 #       if defined(SUNOS5SIGS) || defined(IRIX5) || defined(OSF1) \
            || defined(HAIKU) || defined(HURD) || defined(FREEBSD) \
-           || defined(NETBSD) || defined(OPENBSD)
+           || defined(NETBSD) || defined(OPENBSD) || defined(MINERVA)
           (void) sigaction(SIGSEGV, &old_segv_act, 0);
 #         if defined(IRIX5) && defined(_sigargs) /* Irix 5.x, not 6.x */ \
              || defined(HPUX) || defined(HURD) || defined(NETBSD) \
@@ -1271,7 +1287,7 @@ GC_INNER size_t GC_page_size = 0;
 # define GET_MAIN_STACKBASE_SPECIAL
 #elif !defined(AMIGA) && !defined(HAIKU) && !defined(OS2) \
       && !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) \
-      && !defined(GC_OPENBSD_THREADS) \
+      && !defined(GC_OPENBSD_THREADS) && !defined(MINERVA) \
       && (!defined(GC_SOLARIS_THREADS) || defined(_STRICT_STDC))
 
 # if (defined(HAVE_PTHREAD_ATTR_GET_NP) || defined(HAVE_PTHREAD_GETATTR_NP)) \
@@ -1375,7 +1391,7 @@ GC_INNER size_t GC_page_size = 0;
     return(result);
   }
 # define GET_MAIN_STACKBASE_SPECIAL
-#endif /* !AMIGA, !HAIKU, !OPENBSD, !OS2, !Windows */
+#endif /* !AMIGA, !HAIKU, !OPENBSD, !MINERVA, !OS2, !Windows */
 
 #if (defined(HAVE_PTHREAD_ATTR_GET_NP) || defined(HAVE_PTHREAD_GETATTR_NP)) \
     && defined(THREADS) && !defined(HAVE_GET_STACK_BASE)
@@ -2668,7 +2684,7 @@ static void block_unmap_inner(ptr_t start_addr, size_t len)
           ps3_free_mem(start_addr, len);
 #       elif defined(AIX) || defined(CYGWIN32) || defined(HAIKU) \
              || (defined(LINUX) && !defined(PREFER_MMAP_PROT_NONE)) \
-             || defined(HPUX)
+             || defined(HPUX) || defined(MINERVA)
           /* On AIX, mmap(PROT_NONE) fails with ENOMEM unless the       */
           /* environment variable XPG_SUS_ENV is set to ON.             */
           /* On Cygwin, calling mmap() with the new protection flags on */
@@ -3160,7 +3176,7 @@ GC_API GC_push_other_roots_proc GC_CALL GC_get_push_other_roots(void)
 # elif !defined(USE_WINALLOC)
 #   include <sys/mman.h>
 #   include <signal.h>
-#   if !defined(CYGWIN32) && !defined(HAIKU)
+#   if !defined(CYGWIN32) && !defined(HAIKU) && !defined(MINERVA)
 #     include <sys/syscall.h>
 #   endif
 
@@ -3275,7 +3291,7 @@ GC_API GC_push_other_roots_proc GC_CALL GC_get_push_other_roots(void)
 #     define CODE_OK (si -> si_code == 2 /* experimentally determined */)
 #   elif defined(IRIX5)
 #     define CODE_OK (si -> si_code == EACCES)
-#   elif defined(CYGWIN32) || defined(HAIKU) || defined(HURD)
+#   elif defined(CYGWIN32) || defined(HAIKU) || defined(HURD) || defined(MINERVA)
 #     define CODE_OK TRUE
 #   elif defined(LINUX)
 #     define CODE_OK TRUE
