X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=libgc%2Fdyn_load.c;h=a6e33163dfdf2cb9bf09fcf1d7067d199949ba8b;hb=972273ea96373d10bb098d4f9888ffa6ed49adaf;hp=7111a874a7bb5d330952050c1b3d4cae4ecfdd61;hpb=ff228e1c801bda9666b6edab3ee962e05edcf480;p=mono.git diff --git a/libgc/dyn_load.c b/libgc/dyn_load.c index 7111a874a7b..a6e33163dfd 100644 --- a/libgc/dyn_load.c +++ b/libgc/dyn_load.c @@ -66,6 +66,11 @@ #include #ifdef SUNOS5DL +/* Avoid #error "large files are not supported by libelf" errors */ +#if defined(_ILP32) && (_FILE_OFFSET_BITS != 32) +#undef _FILE_OFFSET_BITS +#define _FILE_OFFSET_BITS 32 +#endif # include # include # include @@ -96,7 +101,7 @@ /* Newer versions of GNU/Linux define this macro. We * define it similarly for any ELF systems that don't. */ # ifndef ElfW -# ifdef FREEBSD +# if defined(FREEBSD) # if __ELF_WORD_SIZE == 32 # define ElfW(type) Elf32_##type # else @@ -114,7 +119,7 @@ # define ElfW(type) Elf32_##type # else # define ElfW(type) Elf64_##type -# endif +# endif # endif # endif # endif @@ -493,7 +498,6 @@ static struct link_map * GC_FirstDLOpenedLinkMap() { ElfW(Dyn) *dp; - struct r_debug *r; static struct link_map *cachedResult = 0; if( _DYNAMIC == 0) { @@ -502,6 +506,12 @@ GC_FirstDLOpenedLinkMap() if( cachedResult == 0 ) { int tag; for( dp = _DYNAMIC; (tag = dp->d_tag) != 0; dp++ ) { + /* FIXME: The DT_DEBUG header is not mandated by the */ + /* ELF spec. This code appears to be dependent on */ + /* idiosynchracies of older GNU tool chains. If this code */ + /* fails for you, the real problem is probably that it is */ + /* being used at all. You should be getting the */ + /* dl_iterate_phdr version. */ if( tag == DT_DEBUG ) { struct link_map *lm = ((struct r_debug *)(dp->d_un.d_ptr))->r_map; @@ -626,7 +636,8 @@ void GC_register_dynamic_libraries() } for (i = 0; i < needed_sz; i++) { flags = addr_map[i].pr_mflags; - if ((flags & (MA_BREAK | MA_STACK | MA_PHYS)) != 0) goto irrelevant; + if ((flags & (MA_BREAK | MA_STACK | MA_PHYS + | MA_FETCHOP | MA_NOTCACHED)) != 0) goto irrelevant; if ((flags & (MA_READ | MA_WRITE)) != (MA_READ | MA_WRITE)) goto irrelevant; /* The latter test is empirically useless in very old Irix */ @@ -748,6 +759,10 @@ void GC_register_dynamic_libraries() # define HAVE_REGISTER_MAIN_STATIC_DATA + /* The frame buffer testing code is dead in this version. */ + /* We leave it here temporarily in case the switch to just */ + /* testing for MEM_IMAGE sections causes un expected */ + /* problems. */ GC_bool GC_warn_fb = TRUE; /* Warn about traced likely */ /* graphics memory. */ GC_bool GC_disallow_ignore_fb = FALSE; @@ -762,25 +777,27 @@ void GC_register_dynamic_libraries() /* Should [start, start+len) be treated as a frame buffer */ /* and ignored? */ - /* Unfortunately, we currently have no real way to tell */ - /* automatically, and rely largely on user input. */ - /* FIXME: If we had more data on this phenomenon (e.g. */ - /* is start aligned to a MB multiple?) we should be able to */ - /* do better. */ + /* Unfortunately, we currently are not quite sure how to tell */ + /* this automatically, and rely largely on user input. */ + /* We expect that any mapping with type MEM_MAPPED (which */ + /* apparently excludes library data sections) can be safely */ + /* ignored. But we're too chicken to do that in this */ + /* version. */ /* Based on a very limited sample, it appears that: */ - /* - Frame buffer mappings appear as mappings of length */ - /* 2**n MB - 192K. (We guess the 192K can vary a bit.) */ - /* - Have a stating address at best 64K aligned. */ - /* I'd love more information about the mapping, since I */ - /* can't reproduce the problem. */ - static GC_bool is_frame_buffer(ptr_t start, size_t len) + /* - Frame buffer mappings appear as mappings of large */ + /* length, usually a bit less than a power of two. */ + /* - The definition of "a bit less" in the above cannot */ + /* be made more precise. */ + /* - Have a starting address at best 64K aligned. */ + /* - Have type == MEM_MAPPED. */ + static GC_bool is_frame_buffer(ptr_t start, size_t len, DWORD tp) { static GC_bool initialized = FALSE; # define MB (1024*1024) # define DEFAULT_FB_MB 15 # define MIN_FB_MB 3 - if (GC_disallow_ignore_fb) return FALSE; + if (GC_disallow_ignore_fb || tp != MEM_MAPPED) return FALSE; if (!initialized) { char * ignore_fb_string = GETENV("GC_IGNORE_FB"); @@ -869,7 +886,11 @@ void GC_register_dynamic_libraries() && (protect == PAGE_EXECUTE_READWRITE || protect == PAGE_READWRITE) && !GC_is_heap_base(buf.AllocationBase) - && !is_frame_buffer(p, buf.RegionSize)) { + /* This used to check for + * !is_frame_buffer(p, buf.RegionSize, buf.Type) + * instead of just checking for MEM_IMAGE. + * If something breaks, change it back. */ + && buf.Type == MEM_IMAGE) { # ifdef DEBUG_VIRTUALQUERY GC_dump_meminfo(&buf); # endif @@ -1125,21 +1146,22 @@ static const char *GC_dyld_name_for_hdr(struct mach_header *hdr) { static void GC_dyld_image_add(struct mach_header* hdr, unsigned long slide) { unsigned long start,end,i; const struct section *sec; + if (GC_no_dls) return; 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", + if(sec == NULL || sec->size == 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 +# endif GC_add_roots((char*)start,(char*)end); - } -# ifdef DARWIN_DEBUG - GC_print_static_roots(); -# endif + } +# ifdef DARWIN_DEBUG + GC_print_static_roots(); +# endif } /* This should never be called by a thread holding the lock */ @@ -1152,15 +1174,15 @@ static void GC_dyld_image_remove(struct mach_header* hdr, unsigned long slide) { if(sec == NULL || sec->size == 0) continue; start = slide + sec->addr; end = start + sec->size; -# ifdef DARWIN_DEBUG +# 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); } -# ifdef DARWIN_DEBUG - GC_print_static_roots(); -# endif +# ifdef DARWIN_DEBUG + GC_print_static_roots(); +# endif } void GC_register_dynamic_libraries() {