From 52ec91b476b116824f1e91bca628137e486a2e44 Mon Sep 17 00:00:00 2001
From: tromey <tromey@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Mon, 21 Jun 1999 15:39:02 +0000
Subject: [PATCH] 	Alpha patch from Jeff Sturm: 	* os_dep.c
 (GC_init_linuxalpha): New function. 	* misc.c: Initialize for alpha linux. 
 * gc_priv.h (GC_test_and_set): Define for alpha. 	* config.h: Don't
 assume __data_start on alpha.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@27670 138bc75d-0d04-0410-961f-82ee72b054a4
---
 boehm-gc/ChangeLog |  6 ++++
 boehm-gc/config.h  |  4 +--
 boehm-gc/gc_priv.h | 24 +++++++++++++-
 boehm-gc/misc.c    |  3 ++
 boehm-gc/os_dep.c  | 78 +++++++++++++++++++++++++++++++++++++++++++++-
 5 files changed, 111 insertions(+), 4 deletions(-)

diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index 279a2f38f3f0..af461baff29b 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,5 +1,11 @@
 1999-06-21  Tom Tromey  <tromey@cygnus.com>
 
+	Alpha patch from Jeff Sturm:
+	* os_dep.c (GC_init_linuxalpha): New function.
+	* misc.c: Initialize for alpha linux.
+	* gc_priv.h (GC_test_and_set): Define for alpha.
+	* config.h: Don't assume __data_start on alpha.
+
 	* Makefile.in: Rebuilt.
 	* Makefile.am (libgcjgc_la_LDFLAGS): Use -version-info, not
 	-release.
diff --git a/boehm-gc/config.h b/boehm-gc/config.h
index 6aaf5032c788..89110a6b8247 100644
--- a/boehm-gc/config.h
+++ b/boehm-gc/config.h
@@ -844,8 +844,8 @@
 #       define CPP_WORDSZ 64
 #       define STACKBOTTOM ((ptr_t) 0x120000000)
 #       ifdef __ELF__
-            extern int __data_start;
-#           define DATASTART &__data_start
+#           define DATASTART GC_data_start
+#           define USE_PROC
 #           define DYNAMIC_LOADING
 #       else
 #           define DATASTART ((ptr_t) 0x140000000)
diff --git a/boehm-gc/gc_priv.h b/boehm-gc/gc_priv.h
index 888e46e1e607..cc8b1476ddc2 100644
--- a/boehm-gc/gc_priv.h
+++ b/boehm-gc/gc_priv.h
@@ -442,10 +442,32 @@ void GC_print_callers (/* struct callinfo info[NFRAMES] */);
 		: "0"(1), "m"(*(addr)));
 	  return oldval;
        }
+       inline static void GC_clear(volatile unsigned int *addr) {
+          *(addr) = 0;
+       }
+#    elif defined(__alpha__)
+       inline static int GC_test_and_set(volatile unsigned int *addr) {
+        long oldval, temp;
+
+        __asm__ __volatile__(
+              "1:\tldl_l %0,%3\n"
+              "\tbne %0,2f\n"
+              "\tor $31,1,%1\n"
+              "\tstl_c %1,%2\n"
+              "\tbeq %1,1b\n"
+              "2:\tmb\n"
+              : "=&r"(oldval), "=&r"(temp), "=m"(*(addr))
+              : "m"(*(addr))
+              : "memory");
+        return (int)oldval;
+       }
+       inline static void GC_clear(volatile unsigned int *addr) {
+          __asm__ __volatile__("mb": : :"memory");
+          *(addr) = 0;
+       }
 #    else
        -- > Need implementation of GC_test_and_set()
 #    endif
-#    define GC_clear(addr) (*(addr) = 0)
 
      extern volatile unsigned int GC_allocate_lock;
 	/* This is not a mutex because mutexes that obey the (optional)     */
diff --git a/boehm-gc/misc.c b/boehm-gc/misc.c
index 72c87b0802c0..70f583f982d5 100644
--- a/boehm-gc/misc.c
+++ b/boehm-gc/misc.c
@@ -436,6 +436,9 @@ void GC_init_inner()
 #   if defined(LINUX) && defined(POWERPC)
 	GC_init_linuxppc();
 #   endif
+#   if defined(LINUX) && defined(ALPHA)
+      GC_init_linuxalpha();
+#   endif
 #   ifdef SOLARIS_THREADS
 	GC_thr_init();
 	/* We need dirty bits in order to find live stack sections.	*/
diff --git a/boehm-gc/os_dep.c b/boehm-gc/os_dep.c
index f05e94d14c91..29cf8ff99ecd 100644
--- a/boehm-gc/os_dep.c
+++ b/boehm-gc/os_dep.c
@@ -68,7 +68,7 @@
 #   define NEED_FIND_LIMIT
 # endif
 
-# if defined(LINUX) && defined(POWERPC)
+# if defined(LINUX) && (defined(POWERPC) || defined(ALPHA))
 #   define NEED_FIND_LIMIT
 # endif
 
@@ -148,6 +148,82 @@
   }
 #endif
 
+#if defined(LINUX) && defined(ALPHA)
+  ptr_t GC_data_start;
+
+  void GC_init_linuxalpha()
+  {
+# ifdef USE_PROC
+    FILE *fp = fopen("/proc/self/maps", "r");
+
+    if (fp) {
+      extern void *_etext;
+      ptr_t stacktop = 0, stackbottom = 0;
+      ptr_t textstart = 0, textend = 0;
+      ptr_t datastart = 0, dataend = 0;
+      ptr_t bssstart = 0, bssend = 0;
+
+      while (!feof(fp)) {
+        ptr_t start, end, offset;
+        unsigned short major, minor;
+        char r, w, x, p;
+        unsigned int inode;
+
+        int n = fscanf(fp, "%lx-%lx %c%c%c%c %lx %hx:%hx %d",
+          &start, &end, &r, &w, &x, &p, &offset, &major, &minor, &inode);
+        if (n < 10) break;
+
+        /*
+         * If local variable lies within segment, it is stack.
+         * Else if segment lies below _end and is executable,
+         * it is text.  Otherwise, if segment start lies between
+         * _etext and _end and segment is writable and is mapped
+         * to the executable image it is data, otherwise bss.
+         */
+         if (start < (ptr_t)&fp && end > (ptr_t)&fp && w == 'w') {
+           stacktop = start;
+           stackbottom = end;
+         } else if (start < (ptr_t)&_end && w == '-' && x == 'x') {
+           textstart = start;
+           textend = end;
+         } else if (start >= (ptr_t)&_etext &&
+                      start < (ptr_t)&_end && w == 'w') {
+           if (inode > 0) {
+             datastart = start;
+             dataend = end;
+           } else {
+             bssstart = start;
+             bssend = end;
+           }
+         }
+
+         //printf("%016lx-%016lx %c%c%c%c %016lx %02hx:%02hx %d\n",
+         //      start, end, r, w, x, p, offset, major, minor, inode);
+
+         while (fgetc(fp) != '\n') ;
+       }
+       fclose(fp);
+
+       //fprintf(stderr, "text:  %lx-%lx\n", textstart, textend);
+       //fprintf(stderr, "data:  %lx-%lx\n", datastart, dataend);
+       //fprintf(stderr, "bss:   %lx-%lx\n", bssstart, bssend);
+       //fprintf(stderr, "stack: %lx-%lx\n", stacktop, stackbottom);
+
+       GC_data_start = datastart;
+     } else {
+# endif
+       extern ptr_t GC_find_limit();
+       extern int _edata;
+       /* This may need to be environ, without the underscore, for */
+       /* some versions.  */
+       GC_data_start = GC_find_limit((ptr_t)&_edata, FALSE);
+# ifdef USE_PROC
+     }
+# endif
+     //fprintf(stderr, "GC_data_start = %p\n", GC_data_start);
+  }
+#endif
+
 # ifdef ECOS
 
 # ifndef ECOS_GC_MEMORY_SIZE
-- 
GitLab