C:/Users/Dennis/src/lang/russell.orig/src/gc/dynamic_load.c

Go to the documentation of this file.
00001 /*
00002  * Copyright (c) 1991-1993 by Xerox Corporation.  All rights reserved.
00003  *
00004  * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED
00005  * OR IMPLIED.  ANY USE IS AT YOUR OWN RISK.
00006  *
00007  * Permission is hereby granted to copy this garbage collector for any purpose,
00008  * provided the above notices are retained on all copies.
00009  * Author: Bill Janssen
00010  * Modified by: Hans Boehm
00011  */
00012 
00013 /*
00014  * This is incredibly OS specific code for tracking down data sections in
00015  * dynamic libraries.  There appears to be no way of doing this quickly
00016  * without groveling through undocumented data structures.  We would argue
00017  * that this is a bug in the design of the dlopen interface.  THIS CODE
00018  * MAY BREAK IN FUTURE OS RELEASES.  If this matters to you, don't hesitate
00019  * to let your vendor know ...
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   /* struct link_map field overrides */
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; /* might be NIL */
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 /* Add dynamic library data sections to the root set.           */
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

Generated on Fri Jan 25 10:39:45 2008 for russell by  doxygen 1.5.4