Mike, Attached is the requested qsort on destructors as well. After gcc branches for 4.8, I would imagine the first baby step towards full constructor/destructor priority support would be to remove...
/* The Apple assembler and linker do not support constructor priorities. */ #undef SUPPORTS_INIT_PRIORITY #define SUPPORTS_INIT_PRIORITY 0 from gcc/config/darwin.h and craft a way to suppress the emission of the (con//de)structor priority assembly which darwin's gas doesn't understand. That should be sufficient (with the qsorting by priority) to give us full constructor/destructor priority support within a module. Jack ps Bootstrap tested on x86_64-apple-darwin12 with no regressions in asan.exp. Will post full regression testresults tomorrow.
/gcc 2013-02-04 Alexander Potapenko <gli...@google.com> Jack Howarth <howa...@bromo.med.uc.edu> Jakub Jelinek <ja...@redhat.com> PR sanitizer/55617 * config/darwin.c (sort_dtor_records): Stabilized qsort on destructor priority by using original position. (finalize_dtors): New routine to sort destructors by priority before use in assemble_integer. (machopic_asm_out_destructor): Use finalize_dtors if needed. Index: gcc/config/darwin.c =================================================================== --- gcc/config/darwin.c (revision 195735) +++ gcc/config/darwin.c (working copy) @@ -89,7 +89,14 @@ typedef struct GTY(()) ctor_record { int position; /* original position */ } ctor_record; +typedef struct GTY(()) dtor_record { + rtx symbol; + int priority; /* destructor priority */ + int position; /* original position */ +} dtor_record; + static GTY(()) vec<ctor_record, va_gc> *ctors = NULL; +static GTY(()) vec<dtor_record, va_gc> *dtors = NULL; /* A flag to determine whether we are running c++ or obj-c++. This has to be settable from non-c-family contexts too (i.e. we can't use the c_dialect_ @@ -1724,6 +1731,17 @@ machopic_asm_out_constructor (rtx symbol fprintf (asm_out_file, ".reference .constructors_used\n"); } +void +machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED) +{ + dtor_record new_elt = {symbol, priority, vec_safe_length (dtors)}; + + vec_safe_push (dtors, new_elt); + + if (! MACHOPIC_INDIRECT) + fprintf (asm_out_file, ".reference .destructors_used\n"); +} + static int sort_ctor_records (const void * a, const void * b) { @@ -1740,6 +1758,22 @@ sort_ctor_records (const void * a, const return 0; } +static int +sort_dtor_records (const void * a, const void * b) +{ + const dtor_record *da = (const dtor_record *)a; + const dtor_record *db = (const dtor_record *)b; + if (da->priority > db->priority) + return 1; + if (da->priority < db->priority) + return -1; + if (da->position > db->position) + return 1; + if (da->position < db->position) + return -1; + return 0; +} + static void finalize_ctors() { @@ -1760,18 +1794,24 @@ finalize_ctors() } } -void -machopic_asm_out_destructor (rtx symbol, int priority ATTRIBUTE_UNUSED) +static void +finalize_dtors() { + unsigned int i; + dtor_record *elt; + if (MACHOPIC_INDIRECT) switch_to_section (darwin_sections[mod_term_section]); else switch_to_section (darwin_sections[destructor_section]); - assemble_align (POINTER_SIZE); - assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); - if (! MACHOPIC_INDIRECT) - fprintf (asm_out_file, ".reference .destructors_used\n"); + if (vec_safe_length (dtors) > 1) + dtors->qsort (sort_dtor_records); + FOR_EACH_VEC_SAFE_ELT (dtors, i, elt) + { + assemble_align (POINTER_SIZE); + assemble_integer (elt->symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); + } } void @@ -2805,6 +2845,8 @@ darwin_file_end (void) { if (!vec_safe_is_empty (ctors)) finalize_ctors(); + if (!vec_safe_is_empty (dtors)) + finalize_dtors(); machopic_finish (asm_out_file); if (strcmp (lang_hooks.name, "GNU C++") == 0) {