diff mbox

[boehm-gc] Use __rld_obj_head for IRIX GC_register_dynamic_libraries (PR libgcj/49451)

Message ID yddtybhg3dn.fsf@manam.CeBiTec.Uni-Bielefeld.DE
State New
Headers show

Commit Message

Rainer Orth June 22, 2011, 5:52 p.m. UTC
As reported in PR libgcj/49451, the FileHandleGcTest test fails on IRIX
since boehm-gc tries to open /proc/<pid> when the process is already out
of file descriptors.  Looking around, I've found a way for boehm-gc to
determine the list of shared libraries without using /proc, just as
Solaris and Tru64 UNIX do.

It uses __rld_obj_head, which provides the same info as _DYNAMIC on
Solaris, though in a slightly different way.  Fortunately, the current
Solaris code can be made to work on IRIX with very few changes.

The initial version allowed make check in boehm-gc to work without
problems, but failed when running any libjava test, which SEGVed in a
way that gdb couldn't catch ;-(  After some digging around, it turned
out that the addresses in the loaded shared objects may need an offset
added similar to the Solaris case, to take into account that the actual
virtual address and the quickstart one in the object don't match, if I
read the <obj_list.h> comment correctly.  The gdb sources provided an
important clue in gdb/solib-irix.c (fetch_lm_info).

The version below passes both make check on mips-sgi-irix6.5 for both
N32 and N64 multilibs, the previously failing FileHandleGcTest test now
passes as expected, and a couple of other libjava tests work, too.  A
full make check for libjava is currently running, ok for mainline if
that passes?

Please note that the O32 code is currently untested since support for
that ABI has been removed in GCC 4.6.  This is harmless for the in-tree
copy, but might be an issue upstream.  I'll probably give it a try on
the 4.5 branch.

Thanks.
	Rainer


2011-06-17  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	PR libgcj/49451
	* include/private/gcconfig.h [IRIX5 && _MIPS_SZPTR == 64]
	(ELF_CLASS): Define.
	* dyn_load.c [IRIX5]: Include <elf.h>.
	Include <obj.h> for O32, <objlist.h> for N32, N64.
	[SUNOS5DL && USE_PROC_FOR_LIBRARIES] (obj_offset): Define.
	[SUNOS4 && USE_PROC_FOR_LIBRARIES] (obj_offset): Define.
	[IRIX5 && !USE_PROC_FOR_LIBRARIES] (struct link_map): Define.
	(__rld_obj_head): Declare.
	(l_next, l_addr, obj_offset): Define.
	(GC_FirstDLOpenedLinkMap): New function.
	[SUNOS4 || SUNOS5DL] (GC_register_dynamic_libraries): Also use on
	IRIX5.
	Use obj_offset.
	[IRIX5 || (USE_PROC_FOR_LIBRARIES && !LINUX]
	(GC_register_dynamic_libraries): Don't use /proc version on IRIX5.
diff mbox

Patch

diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c
--- a/boehm-gc/dyn_load.c
+++ b/boehm-gc/dyn_load.c
@@ -82,6 +82,15 @@ 
 #   define l_addr	lm_addr
 #   define l_name	lm_name
 #endif
+#ifdef IRIX5
+#   include <elf.h>
+#   if _MIPS_SIM == _MIPS_SIM_ABI32 /* O32 ABI */
+     /* Don't include <obj_list.h> here. */
+#     include <obj.h>
+#   else /* N32 or N64 ABIs */
+#     include <objlist.h>
+#   endif
+#endif
 
 #if defined(NETBSD)
 #   include <machine/elf_machdep.h>
@@ -139,6 +148,8 @@  GC_register_has_static_roots_callback
     Elf32_Dyn _DYNAMIC;
 #endif
 
+#define obj_offset(lm) ((unsigned long)(lm->l_addr))
+
 static struct link_map *
 GC_FirstDLOpenedLinkMap()
 {
@@ -192,6 +203,8 @@  GC_FirstDLOpenedLinkMap()
     struct link_dynamic _DYNAMIC;
 #endif
 
+#define obj_offset(lm) ((unsigned long)(lm->l_addr))
+
 static struct link_map *
 GC_FirstDLOpenedLinkMap()
 {
@@ -226,9 +239,59 @@  static ptr_t GC_first_common()
 
 #endif  /* SUNOS4 ... */
 
-# if defined(SUNOS4) || defined(SUNOS5DL)
+#if defined(IRIX5) && !defined(USE_PROC_FOR_LIBRARIES)
+
+/* Provide struct link map. */
+#  if _MIPS_SIM == _MIPS_SIM_ABI32 /* O32 ABI */
+/* Provide our own version of struct obj_list in <obj_list.h> with
+   correctly typed data member.  */
+struct obj_list {
+    struct obj *data;
+    struct obj_list *next;
+    struct obj_list *prev;
+} objList;
+
+struct link_map {
+    objList l_ol;
+};
+
+extern objList *__rld_obj_head;
+
+/* Map field names */
+#    define l_next	l_ol.next
+#    define l_addr	l_ol.data->o_pelfhdr	
+
+#    define obj_offset(lm) \
+	((unsigned long)(lm->l_ol.o_praw - (char *)lm->l_ol.o_base_address))
+#  else /* N32 or N64 ABIs */
+struct link_map {
+    ElfW(Obj_Info) l_oi;
+};
+
+extern ElfW(Obj_Info) *__rld_obj_head;
+
+/* Map field names */
+#    define l_next	l_oi.oi_next
+#    define l_addr	l_oi.oi_ehdr
+
+/* See gdb/solib-irix.c (fetch_lm_info).  */
+#    define obj_offset(lm) \
+	 ((unsigned long)(lm->l_oi.oi_ehdr - lm->l_oi.oi_orig_ehdr))
+#  endif
+
+static struct link_map *
+GC_FirstDLOpenedLinkMap()
+{
+    return (struct link_map *)__rld_obj_head;
+}
+
+#endif /* IRIX5 ... */
+
+# if defined(SUNOS4) || defined(SUNOS5DL) || defined(IRIX5)
 /* Add dynamic library data sections to the root set.		*/
-# if !defined(PCR) && !defined(GC_SOLARIS_PTHREADS) && defined(THREADS)
+# if !defined(PCR) \
+     && !defined(GC_SOLARIS_PTHREADS) && !defined(GC_IRIX_THREADS) \
+     && defined(THREADS)
 #   ifndef SRC_M3
 	--> fix mutual exclusion with dlopen
 #   endif  /* We assume M3 programs don't call dlopen for now */
@@ -241,7 +304,7 @@  void GC_register_dynamic_libraries()
   
 
   for (lm = GC_FirstDLOpenedLinkMap();
-       lm != (struct link_map *) 0;  lm = lm->l_next)
+       lm != (struct link_map *) 0;  lm = (struct link_map *) lm->l_next)
     {
 #     ifdef SUNOS4
 	struct exec *e;
@@ -252,7 +315,7 @@  void GC_register_dynamic_libraries()
 		    ((char *) (N_BSSADDR(*e) + e->a_bss + lm->lm_addr)),
 		    TRUE);
 #     endif
-#     ifdef SUNOS5DL
+#     if defined(SUNOS5DL) || defined(IRIX5)
 	ElfW(Ehdr) * e;
         ElfW(Phdr) * p;
         unsigned long offset;
@@ -261,7 +324,7 @@  void GC_register_dynamic_libraries()
         
 	e = (ElfW(Ehdr) *) lm->l_addr;
         p = ((ElfW(Phdr) *)(((char *)(e)) + e->e_phoff));
-        offset = ((unsigned long)(lm->l_addr));
+        offset = obj_offset(lm);
         for( i = 0; i < (int)(e->e_phnum); ((i++),(p++)) ) {
           switch( p->p_type ) {
             case PT_LOAD:
@@ -589,7 +652,7 @@  void GC_register_dynamic_libraries()
 
 #endif /* LINUX */
 
-#if defined(IRIX5) || (defined(USE_PROC_FOR_LIBRARIES) && !defined(LINUX))
+#if defined(USE_PROC_FOR_LIBRARIES) && !defined(LINUX)
 
 #include <sys/procfs.h>
 #include <sys/stat.h>
@@ -718,7 +781,7 @@  void GC_register_dynamic_libraries()
 	fd = -1;
 }
 
-# endif /* USE_PROC || IRIX5 */
+# endif /* USE_PROC */
 
 # if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
 
diff --git a/boehm-gc/include/private/gcconfig.h b/boehm-gc/include/private/gcconfig.h
--- a/boehm-gc/include/private/gcconfig.h
+++ b/boehm-gc/include/private/gcconfig.h
@@ -1445,6 +1445,9 @@ 
 #	  if CPP_WORDSZ != 64
 #	    define ALIGN_DOUBLE
 #	  endif
+#	  if _MIPS_SZPTR == 64
+#	    define ELF_CLASS ELFCLASS64
+#	  endif
 #	else
 #         define ALIGNMENT 4
 #	  define ALIGN_DOUBLE