diff options
author | Paolo Molaro <lupus@oddwiz.org> | 2006-01-24 14:37:10 +0300 |
---|---|---|
committer | Paolo Molaro <lupus@oddwiz.org> | 2006-01-24 14:37:10 +0300 |
commit | d58dfa185af1d48fb93efdef1d046762f214f0a7 (patch) | |
tree | f851d10caf20d342811d58d624fcdcbd92fe4151 /libgc/dyn_load.c | |
parent | 3be1eb27881d243559d4ab0baf7b538334c7e1b3 (diff) |
Tue Jan 24 12:34:06 CET 2006 Paolo Molaro <lupus@ximian.com>
* *: update from upstream changes.
svn path=/trunk/mono/; revision=55979
Diffstat (limited to 'libgc/dyn_load.c')
-rw-r--r-- | libgc/dyn_load.c | 79 |
1 files changed, 48 insertions, 31 deletions
diff --git a/libgc/dyn_load.c b/libgc/dyn_load.c index 7111a874a7b..62d3815b0e2 100644 --- a/libgc/dyn_load.c +++ b/libgc/dyn_load.c @@ -96,7 +96,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 +114,7 @@ # define ElfW(type) Elf32_##type # else # define ElfW(type) Elf64_##type -# endif +# endif # endif # endif # endif @@ -493,7 +493,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 +501,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 +631,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 +754,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 +772,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 +881,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 +1141,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;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) { sec = getsectbynamefromheader( hdr,GC_dyld_sections[i].seg,GC_dyld_sections[i].sect); - 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", + 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 +1169,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() { |