X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=boehm-gc%2Fdyn_load.c;h=f1e3e8ec74fdb41b8174dd2d66c2638ba1725f6e;hb=240f22d347213edc0d738cd9fb43ea13065a2789;hp=200abde7810b4d74d82db42cab53693ff0fde49a;hpb=1602764e229df36b9eec13b6bb88ed2a27f29fb0;p=pf3gnuchains%2Fgcc-fork.git diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c index 200abde7810..f1e3e8ec74f 100644 --- a/boehm-gc/dyn_load.c +++ b/boehm-gc/dyn_load.c @@ -49,10 +49,13 @@ # undef GC_must_restore_redefined_dlopen # endif -#if (defined(DYNAMIC_LOADING) || defined(MSWIN32) || defined(MSWINCE)) \ +#if (defined(DYNAMIC_LOADING) \ + || defined(MSWIN32) \ + || defined(MSWINCE) \ + || defined(CYGWIN32)) \ && !defined(PCR) #if !defined(SUNOS4) && !defined(SUNOS5DL) && !defined(IRIX5) && \ - !defined(MSWIN32) && !defined(MSWINCE) && \ + !defined(MSWIN32) && !defined(MSWINCE) && !defined(CYGWIN32) && \ !(defined(ALPHA) && defined(OSF1)) && \ !defined(HPUX) && !(defined(LINUX) && defined(__ELF__)) && \ !defined(RS6000) && !defined(SCO_ELF) && !defined(DGUX) && \ @@ -79,6 +82,15 @@ # define l_addr lm_addr # define l_name lm_name #endif +#ifdef IRIX5 +# include +# if _MIPS_SIM == _MIPS_SIM_ABI32 /* O32 ABI */ + /* Don't include here. */ +# include +# else /* N32 or N64 ABIs */ +# include +# endif +#endif #if defined(NETBSD) # include @@ -119,7 +131,7 @@ # endif # endif -/* An user-supplied routine that is called to dtermine if a DSO must +/* An user-supplied routine that is called to determine if a DSO must be scanned by the gc. */ static int (*GC_has_static_roots)(const char *, void *, size_t); /* Register the routine. */ @@ -136,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() { @@ -189,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() { @@ -223,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 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 */ @@ -238,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; @@ -249,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; @@ -258,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: @@ -586,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 #include @@ -715,9 +781,9 @@ void GC_register_dynamic_libraries() fd = -1; } -# endif /* USE_PROC || IRIX5 */ +# endif /* USE_PROC */ -# if defined(MSWIN32) || defined(MSWINCE) +# if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32) # define WIN32_LEAN_AND_MEAN # define NOSERVICE @@ -761,7 +827,7 @@ void GC_register_dynamic_libraries() } # endif -# ifdef MSWINCE +# if defined(MSWINCE) || defined(CYGWIN32) /* Do we need to separately register the main static data segment? */ GC_bool GC_register_main_static_data() { @@ -868,8 +934,12 @@ void GC_register_dynamic_libraries() } # endif /* DEBUG_VIRTUALQUERY */ - extern GC_bool GC_wnt; /* Is Windows NT derivative. */ - /* Defined and set in os_dep.c. */ +# ifdef CYGWIN32 +# define GC_wnt (TRUE) +# else + extern GC_bool GC_wnt; /* Is Windows NT derivative. */ + /* Defined and set in os_dep.c. */ +# endif void GC_register_dynamic_libraries() { @@ -934,7 +1004,7 @@ void GC_register_dynamic_libraries() GC_cond_add_roots(base, limit); } -#endif /* MSWIN32 || MSWINCE */ +#endif /* MSWIN32 || MSWINCE || CYGWIN32 */ #if defined(ALPHA) && defined(OSF1) @@ -1150,72 +1220,167 @@ void GC_register_dynamic_libraries() /*#define DARWIN_DEBUG*/ +/* Writeable sections generally available on Darwin. */ const static struct { const char *seg; const char *sect; } GC_dyld_sections[] = { { SEG_DATA, SECT_DATA }, + /* Used by FSF GCC, but not by OSX system tools, so far. */ + { SEG_DATA, "__static_data" }, { SEG_DATA, SECT_BSS }, - { SEG_DATA, SECT_COMMON } + { SEG_DATA, SECT_COMMON }, + /* FSF GCC - zero-sized object sections for targets supporting section + anchors. */ + { SEG_DATA, "__zobj_data" }, + { SEG_DATA, "__zobj_bss" } }; - + +/* Additional writeable sections: + + GCC on Darwin constucts aligned sections "on demand", where the alignment + size is embedded in the section name. Furthermore, there are distintions + between sections containing private vs. public symbols. + + It also constructs sections specifically for zero-sized objects, when the + target supports section anchors. */ +const char * GC_dyld_add_sect_fmts[] = +{ + "__bss%u", + "__pu_bss%u", + "__zo_bss%u", + "__zo_pu_bss%u", + NULL +} ; + +/* Currently, mach-o will allow up to a max of 2^15 alignment in an + object file. */ +#define L2_MAX_OFILE_ALIGNMENT 15 + + #ifdef DARWIN_DEBUG -static const char *GC_dyld_name_for_hdr(const struct GC_MACH_HEADER *hdr) { - unsigned long i,c; - c = _dyld_image_count(); - for(i=0;isize == 0) continue; - start = slide + sec->addr; - end = start + sec->size; -# ifdef DARWIN_DEBUG - GC_printf4("Adding section at %p-%p (%lu bytes) from image %s\n", - start,end,sec->size,GC_dyld_name_for_hdr(hdr)); -# endif - GC_add_roots((char*)start,(char*)end); + if(sec == NULL || sec->size == 0) + continue; + + start = slide + sec->addr; + end = start + sec->size; + +# ifdef DARWIN_DEBUG + GC_printf5("Adding section __DATA,%s at %p-%p (%lu bytes) from image %s\n", + GC_dyld_sections[i].sect, start,end,sec->size,GC_dyld_name_for_hdr(hdr)); +# endif + GC_add_roots((char*)start,(char*)end); } -# ifdef DARWIN_DEBUG - GC_print_static_roots(); -# endif + + /* Sections constructed on demand. */ + j=0; + while ((fmt = GC_dyld_add_sect_fmts[j]) != NULL) + { + /* Add our manufactured aligned BSS sections. */ + for (i=0; i<=L2_MAX_OFILE_ALIGNMENT; i++) + { + snprintf (secnam, 16, fmt, (unsigned)i); + sec = GC_GETSECTBYNAME (hdr, SEG_DATA, secnam); + if (sec == NULL || sec->size == 0) + continue; + start = slide + sec->addr; + end = start + sec->size; +# ifdef DARWIN_DEBUG + GC_printf5("Adding section __DATA,%s at %p-%p (%lu bytes) from image %s\n", + secnam, start,end,sec->size,GC_dyld_name_for_hdr(hdr)); +# endif + GC_add_roots((char*)start,(char*)end); + } + j++; + } +# ifdef DARWIN_DEBUG + GC_print_static_roots(); +# endif } /* This should never be called by a thread holding the lock */ -static void GC_dyld_image_remove(const struct GC_MACH_HEADER *hdr, - intptr_t slide) { - unsigned long start,end,i; - const struct GC_MACH_SECTION *sec; - for(i=0;isize == 0) continue; - start = slide + sec->addr; - end = start + sec->size; -# ifdef DARWIN_DEBUG - GC_printf4("Removing section at %p-%p (%lu bytes) from image %s\n", - start,end,sec->size,GC_dyld_name_for_hdr(hdr)); -# endif - GC_remove_roots((char*)start,(char*)end); + if(sec == NULL || sec->size == 0) + continue; + + start = slide + sec->addr; + end = start + sec->size; +# ifdef DARWIN_DEBUG + GC_printf5("Removing section __DATA,%s at %p-%p (%lu bytes) from image %s\n", + GC_dyld_sections[i].sect, start,end,sec->size,GC_dyld_name_for_hdr(hdr)); +# endif + GC_remove_roots((char*)start,(char*)end); } -# ifdef DARWIN_DEBUG - GC_print_static_roots(); -# endif + + /* Remove our on-demand sections. */ + j=0; + while ((fmt = GC_dyld_add_sect_fmts[j]) != NULL) + { + for (i=0; i<=L2_MAX_OFILE_ALIGNMENT; i++) + { + snprintf (secnam, 16, fmt, (unsigned)i); + sec = GC_GETSECTBYNAME (hdr, SEG_DATA, secnam); + if (sec == NULL || sec->size == 0) + continue; + start = slide + sec->addr; + end = start + sec->size; +# ifdef DARWIN_DEBUG + GC_printf5("Removing section __DATA,%s at %p-%p (%lu bytes) from image %s\n", + secnam, start,end,sec->size,GC_dyld_name_for_hdr(hdr)); +# endif + GC_remove_roots((char*)start,(char*)end); + } + j++; + } + +# ifdef DARWIN_DEBUG + GC_print_static_roots(); +# endif } -void GC_register_dynamic_libraries() { +void +GC_register_dynamic_libraries() +{ /* Currently does nothing. The callbacks are setup by GC_init_dyld() The dyld library takes it from there. */ } @@ -1226,15 +1391,18 @@ void GC_register_dynamic_libraries() { This should be called BEFORE any thread in created and WITHOUT the allocation lock held. */ -void GC_init_dyld() { +void +GC_init_dyld() +{ static GC_bool initialized = FALSE; char *bind_fully_env = NULL; - if(initialized) return; + if(initialized) + return; -# ifdef DARWIN_DEBUG +# ifdef DARWIN_DEBUG GC_printf0("Registering dyld callbacks...\n"); -# endif +# endif /* Apple's Documentation: When you call _dyld_register_func_for_add_image, the dynamic linker runtime @@ -1247,27 +1415,28 @@ void GC_init_dyld() { linked in the future */ - _dyld_register_func_for_add_image(GC_dyld_image_add); - _dyld_register_func_for_remove_image(GC_dyld_image_remove); + _dyld_register_func_for_add_image(GC_dyld_image_add); + _dyld_register_func_for_remove_image(GC_dyld_image_remove); - /* Set this early to avoid reentrancy issues. */ - initialized = TRUE; + /* Set this early to avoid reentrancy issues. */ + initialized = TRUE; - bind_fully_env = getenv("DYLD_BIND_AT_LAUNCH"); + bind_fully_env = getenv("DYLD_BIND_AT_LAUNCH"); - if (bind_fully_env == NULL) { -# ifdef DARWIN_DEBUG + if (bind_fully_env == NULL) + { +# ifdef DARWIN_DEBUG GC_printf0("Forcing full bind of GC code...\n"); -# endif +# endif - if(!_dyld_bind_fully_image_containing_address((unsigned long*)GC_malloc)) - GC_abort("_dyld_bind_fully_image_containing_address failed"); + if (!_dyld_bind_fully_image_containing_address((unsigned long*)GC_malloc)) + GC_abort("_dyld_bind_fully_image_containing_address failed"); } - } #define HAVE_REGISTER_MAIN_STATIC_DATA -GC_bool GC_register_main_static_data() +GC_bool +GC_register_main_static_data (void) { /* Already done through dyld callbacks */ return FALSE;