This is the mail archive of the java-patches@sourceware.cygnus.com mailing list for the Java project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

boehm-gc: data_start


Some of the problems I've had with boehm-gc on Alpha may be due to the
data_start hack in libgcjdata.c.  Regardless of linker options, the
data_start symbol does not appear to show up at the actual beginning of
the data segement... I am regularly seeing class variables prior to it.
(We could use GC_find_limit as an ugly fix.)

Since an actual data_start symbol is missing for some targets in glibc,
I once suggested a workaround based on /proc to find the data segment
boundaries.  It was never widely adopted, and Hans didn't use it in his
code.

Here's another attempt at a general fix for data_start.  It should work
on all Linux ELF targets.  It doesn't have some of the same problems as
the /proc solution (i.e. requiring I/O, failing if /proc is not
mounted).  This patch uses ELF program header information instead to
find the main data segment.  It is loosely based on code in dyn_load.c. 
It detects executables that are statically linked, falling back on the
.data symbol created by ld.  I've only tested on Alpha and ia32, but it
should work on all glibc targets at least.

I haven't shown this to Hans yet; I'm just posting it for feedback.  If
we can adopt it, we can also kill the libgcjdata hack in libjava.

2000-04-21  Jeff Sturm  <jsturm@sigma6.com>

	* gcconfig.h: Define SEARCH_FOR_DATA_START and DATASTART,
	  undefine LINUX_DATA_START for Alpha/Linux.
	* os_dep.c (GC_init_linux_data_start): use ELF program header
	  to resolve GC_data_start.
Index: gcconfig.h
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/gcconfig.h,v
retrieving revision 1.10
diff -u -r1.10 gcconfig.h
--- gcconfig.h	2000/04/19 10:09:57	1.10
+++ gcconfig.h	2000/04/22 03:43:57
@@ -1050,9 +1050,10 @@
 #       define CPP_WORDSZ 64
 #       define STACKBOTTOM ((ptr_t) 0x120000000)
 #       ifdef __ELF__
-#	  define LINUX_DATA_START
 #         define DYNAMIC_LOADING
 	  /* This doesn't work if the collector is in a dynamic library. */
+#	    define SEARCH_FOR_DATA_START
+#	    define DATASTART GC_data_start
 #       else
 #           define DATASTART ((ptr_t) 0x140000000)
 #       endif
Index: os_dep.c
===================================================================
RCS file: /cvs/java/libgcj/boehm-gc/os_dep.c,v
retrieving revision 1.10
diff -u -r1.10 os_dep.c
--- os_dep.c	2000/04/19 10:09:58	1.10
+++ os_dep.c	2000/04/22 03:43:57
@@ -144,20 +144,51 @@
 #endif
 
 #if defined(SEARCH_FOR_DATA_START)
-  /* The following doesn't work if the GC is in a dynamic library.	*/
   /* The I386 case can be handled without a search.  The Alpha case	*/
   /* used to be handled differently as well, but the rules changed	*/
   /* for recent Linux versions.  This seems to be the easiest way to	*/
   /* cover all versions.						*/
   ptr_t GC_data_start;
 
-  extern char * GC_copyright[];  /* Any data symbol would do. */
+#  include <elf.h>
+#  include <link.h>
 
-  void GC_init_linux_data_start()
-  {
-    extern ptr_t GC_find_limit();
+#  pragma weak _DYNAMIC
 
-    GC_data_start = GC_find_limit((ptr_t)GC_copyright, FALSE);
+  extern int this_data_start __asm__(".data");
+
+  void GC_init_linux_data_start() {
+	struct link_map *map = NULL;
+
+	if (_DYNAMIC) {
+	  ElfW(Dyn) *dp;
+
+	  for (dp = _DYNAMIC; dp->d_tag != DT_NULL; dp++) {
+		if (dp->d_tag == DT_DEBUG) {
+          map = ((struct r_debug *)(dp->d_un.d_ptr))->r_map;
+		  if (map) map = map->l_next;
+          break;
+		}
+      }
+    }
+
+	if (map) {
+	  struct link_map *loader = map->l_loader;
+
+	  if (loader) {
+		const ElfW(Phdr) *phdr = loader->l_phdr;
+		int i;
+
+		for (i = 0; i < loader->l_phnum; i++) {
+		  if (phdr[i].p_type == PT_LOAD && phdr[i].p_flags & PF_W) {
+			GC_data_start = (ptr_t)phdr[i].p_vaddr;
+		  }
+		}
+	  }
+	} else {
+	  /* static linking, use .data */
+	  GC_data_start = (ptr_t)&this_data_start;
+	}
   }
 #endif
 

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]