OSDN Git Service

2010-12-07 François Dumont <francois.cppdevs@free.fr>
[pf3gnuchains/gcc-fork.git] / boehm-gc / dyn_load.c
index d82bad8..4bfa56c 100644 (file)
 #   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) && \
 #    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.  */
@@ -225,7 +228,7 @@ static ptr_t GC_first_common()
 
 # if defined(SUNOS4) || defined(SUNOS5DL)
 /* Add dynamic library data sections to the root set.          */
-# if !defined(PCR) && !defined(GC_SOLARIS_THREADS) && defined(THREADS)
+# if !defined(PCR) && !defined(GC_SOLARIS_PTHREADS) && defined(THREADS)
 #   ifndef SRC_M3
        --> fix mutual exclusion with dlopen
 #   endif  /* We assume M3 programs don't call dlopen for now */
@@ -400,6 +403,16 @@ GC_bool GC_register_main_static_data()
 /* It may still not be available in the library on the target system.   */
 /* Thus we also treat it as a weak symbol.                             */
 #define HAVE_DL_ITERATE_PHDR
+#pragma weak dl_iterate_phdr
+#endif
+
+# if (defined(FREEBSD) && __FreeBSD__ >= 7)
+/* On the FreeBSD system, any target system at major version 7 shall    */
+/* have dl_iterate_phdr; therefore, we need not make it weak as above.  */
+#define HAVE_DL_ITERATE_PHDR
+#endif
+
+#if defined(HAVE_DL_ITERATE_PHDR)
 
 static int GC_register_dynlib_callback(info, size, ptr)
      struct dl_phdr_info * info;
@@ -441,8 +454,6 @@ static int GC_register_dynlib_callback(info, size, ptr)
 
 /* Return TRUE if we succeed, FALSE if dl_iterate_phdr wasn't there. */
 
-#pragma weak dl_iterate_phdr
-
 GC_bool GC_register_dynamic_libraries_dl_iterate_phdr()
 {
   if (dl_iterate_phdr) {
@@ -709,7 +720,7 @@ void GC_register_dynamic_libraries()
 
 # endif /* USE_PROC || IRIX5 */
 
-# if defined(MSWIN32) || defined(MSWINCE)
+# if defined(MSWIN32) || defined(MSWINCE) || defined(CYGWIN32)
 
 # define WIN32_LEAN_AND_MEAN
 # define NOSERVICE
@@ -753,7 +764,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()
   {
@@ -860,8 +871,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()
   {
@@ -926,7 +941,7 @@ void GC_register_dynamic_libraries()
     GC_cond_add_roots(base, limit);
   }
 
-#endif /* MSWIN32 || MSWINCE */
+#endif /* MSWIN32 || MSWINCE || CYGWIN32 */
   
 #if defined(ALPHA) && defined(OSF1)
 
@@ -1142,69 +1157,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(struct mach_header *hdr) {
-    unsigned long i,c;
-    c = _dyld_image_count();
-    for(i=0;i<c;i++) if(_dyld_get_image_header(i) == hdr)
-        return _dyld_get_image_name(i);
-    return NULL;
+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;i<c;i++) 
+    if(_dyld_get_image_header(i) == hdr)
+      return _dyld_get_image_name(i);
+  return NULL;
 }
 #endif
-        
+
+
 /* This should never be called by a thread holding the lock */
-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",
-                start,end,sec->size,GC_dyld_name_for_hdr(hdr));
-#       endif
-        GC_add_roots((char*)start,(char*)end);
+static void 
+GC_dyld_image_add (const struct GC_MACH_HEADER *hdr, intptr_t slide)
+{
+  char secnam[16];
+  unsigned long start,end,i,j;
+  const struct GC_MACH_SECTION *sec;
+  const char *fmt;
+
+  if (GC_no_dls)
+    return;
+
+  for (i=0; i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]); i++)
+    {
+      sec = GC_GETSECTBYNAME (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_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(struct mach_header* hdr, unsigned long slide) {
-    unsigned long start,end,i;
-    const struct section *sec;
-    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("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);
+static void 
+GC_dyld_image_remove (const struct GC_MACH_HEADER *hdr, intptr_t slide)
+{
+  char secnam[16];
+  unsigned long start,end,i,j;
+  const struct GC_MACH_SECTION *sec;
+  const char *fmt;
+
+  for (i=0; i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]); i++)
+    {
+      sec = GC_GETSECTBYNAME (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_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. */
 }
@@ -1215,15 +1328,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
@@ -1236,27 +1352,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;