00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "gc_private.h"
00022 #ifdef DYNAMIC_LOADING
00023 #if !(defined(M68K) && defined(SUNOS)) && !defined(SPARC)
00024 --> We only know how to find data segments of dynamic libraries under SunOS 4.X
00025 #endif
00026
00027 #include <stdio.h>
00028 #if defined SUNOS5
00029 # include <sys/elf.h>
00030 # include <dlfcn.h>
00031 # include <link.h>
00032 #else
00033 # include <dlfcn.h>
00034 # include <link.h>
00035 # include <a.out.h>
00036
00037 # define l_next lm_next
00038 # define l_addr lm_addr
00039 # define l_name lm_name
00040 # endif
00041
00042
00043 #ifdef SUNOS5
00044
00045 static struct link_map *
00046 GC_FirstDLOpenedLinkMap()
00047 {
00048 extern Elf32_Dyn _DYNAMIC;
00049 Elf32_Dyn *dp;
00050 struct r_debug *r;
00051 static struct link_map * cachedResult = 0;
00052
00053 if( &_DYNAMIC == 0) {
00054 return(0);
00055 }
00056 if( cachedResult == 0 ) {
00057 int tag;
00058 for( dp = ((Elf32_Dyn *)(&_DYNAMIC)); (tag = dp->d_tag) != 0; dp++ ) {
00059 if( tag == DT_DEBUG ) {
00060 struct link_map *lm
00061 = ((struct r_debug *)(dp->d_un.d_ptr))->r_map;
00062 if( lm != 0 ) cachedResult = lm->l_next;
00063 break;
00064 }
00065 }
00066 }
00067 return cachedResult;
00068 }
00069
00070 # endif
00071
00072 # ifdef SUNOS4
00073
00074 static struct link_map *
00075 GC_FirstDLOpenedLinkMap()
00076 {
00077 extern struct link_dynamic _DYNAMIC;
00078
00079 if( &_DYNAMIC == 0) {
00080 return(0);
00081 }
00082 return(_DYNAMIC.ld_un.ld_1->ld_loaded);
00083 }
00084
00085
00086 # endif
00087
00088
00089 # if !defined(PCR) && defined(THREADS)
00090 --> fix mutual exclusion with dlopen
00091 # endif
00092 void GC_register_dynamic_libraries()
00093 {
00094 struct link_map *lm = GC_FirstDLOpenedLinkMap();
00095
00096
00097 for (lm = GC_FirstDLOpenedLinkMap();
00098 lm != (struct link_map *) 0; lm = lm->l_next)
00099 {
00100 # ifdef SUNOS4
00101 struct exec *e;
00102
00103 e = (struct exec *) lm->lm_addr;
00104 GC_add_roots_inner(
00105 ((char *) (N_DATOFF(*e) + lm->lm_addr)),
00106 ((char *) (N_BSSADDR(*e) + e->a_bss + lm->lm_addr)));
00107 # endif
00108 # ifdef SUNOS5
00109 Elf32_Ehdr * e;
00110 Elf32_Phdr * p;
00111 unsigned long offset;
00112 char * start;
00113 register int i;
00114
00115 e = (Elf32_Ehdr *) lm->l_addr;
00116 p = ((Elf32_Phdr *)(((char *)(e)) + e->e_phoff));
00117 offset = ((unsigned long)(lm->l_addr));
00118 for( i = 0; i < e->e_phnum; ((i++),(p++)) ) {
00119 switch( p->p_type ) {
00120 case PT_LOAD:
00121 {
00122 if( !(p->p_flags & PF_W) ) break;
00123 start = ((char *)(p->p_vaddr)) + offset;
00124 GC_add_roots_inner(
00125 start,
00126 start + p->p_memsz
00127 );
00128 }
00129 break;
00130 default:
00131 break;
00132 }
00133 }
00134 # endif
00135 }
00136 }
00137
00138 #else
00139 void GC_register_dynamic_libraries(){}
00140
00141 int GC_no_dynamic_loading;
00142 #endif