summaryrefslogtreecommitdiff
path: root/boehm-gc
diff options
context:
space:
mode:
Diffstat (limited to 'boehm-gc')
-rw-r--r--boehm-gc/ChangeLog17
-rw-r--r--boehm-gc/dyn_load.c215
2 files changed, 174 insertions, 58 deletions
diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index cb05810ac59..8a1abca8ba8 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,3 +1,20 @@
+2010-11-29 Iain Sandoe <iains@gcc.gnu.org>
+ Mike Stump <mrs@gcc.gnu.org>
+
+ PR target/26427
+ PR target/33120
+ PR testsuite/35710
+ * dyn_load.c (GC_register_dynamic_libraries/DARWIN): Add new writable
+ data section names.
+ (GC_dyld_name_for_hdr): Adjust layout.
+ (GC_dyld_image_add): Adjust layout, add new Darwin sections, adjust
+ debug to name the sections.
+ (GC_dyld_image_remove): Adjust layout, remove new Darwin sections,
+ adjust debug to name the sections.
+ (GC_register_dynamic_libraries): Adjust layout.
+ (GC_init_dyld): Likewise.
+ (GC_register_main_static_data): Likewise.
+
2010-10-29 Paolo Bonzini <bonzini@gnu.org>
* configure: Regenerate.
diff --git a/boehm-gc/dyn_load.c b/boehm-gc/dyn_load.c
index 2133f465ef9..4bfa56cac2c 100644
--- a/boehm-gc/dyn_load.c
+++ b/boehm-gc/dyn_load.c
@@ -1157,72 +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(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;
+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(const struct GC_MACH_HEADER *hdr, intptr_t slide)
+static void
+GC_dyld_image_add (const struct GC_MACH_HEADER *hdr, intptr_t slide)
{
- unsigned long start,end,i;
- const struct GC_MACH_SECTION *sec;
- if (GC_no_dls) return;
- for(i=0;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
+ 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_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;i<sizeof(GC_dyld_sections)/sizeof(GC_dyld_sections[0]);i++) {
+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_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. */
}
@@ -1233,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
@@ -1254,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;