diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cc67ff91508..bfb857d102a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2013-02-04 Alexander Potapenko + Jack Howarth + Jakub Jelinek + + PR sanitizer/55617 + * config/darwin.c (sort_ctor_records): Stabilized qsort + on constructor priority by using original position. + (finalize_ctors): New routine to sort constructors by + priority before use in assemble_integer. + (machopic_asm_out_constructor): Use finalize_ctors if needed. + 2013-02-04 Jakub Jelinek PR libstdc++/54314 diff --git a/gcc/config/darwin.c b/gcc/config/darwin.c index 0c791390609..f1bf24aa91d 100644 --- a/gcc/config/darwin.c +++ b/gcc/config/darwin.c @@ -83,6 +83,14 @@ along with GCC; see the file COPYING3. If not see kernel) the stubs might still be required, and this will be set true. */ int darwin_emit_branch_islands = false; +typedef struct GTY(()) ctor_record { + rtx symbol; + int priority; /* constructor priority */ + int position; /* original position */ +} ctor_record; + +static GTY(()) vec *ctors = 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_ functions). */ @@ -1708,15 +1716,48 @@ machopic_select_rtx_section (enum machine_mode mode, rtx x, void machopic_asm_out_constructor (rtx symbol, int priority ATTRIBUTE_UNUSED) { + ctor_record new_elt = {symbol, priority, vec_safe_length (ctors)}; + + vec_safe_push (ctors, new_elt); + + if (! MACHOPIC_INDIRECT) + fprintf (asm_out_file, ".reference .constructors_used\n"); +} + +static int +sort_ctor_records (const void * a, const void * b) +{ + const ctor_record *ca = (const ctor_record *)a; + const ctor_record *cb = (const ctor_record *)b; + if (ca->priority > cb->priority) + return 1; + if (ca->priority < cb->priority) + return -1; + if (ca->position > cb->position) + return 1; + if (ca->position < cb->position) + return -1; + return 0; +} + +static void +finalize_ctors() +{ + unsigned int i; + ctor_record *elt; + if (MACHOPIC_INDIRECT) switch_to_section (darwin_sections[mod_init_section]); else switch_to_section (darwin_sections[constructor_section]); - assemble_align (POINTER_SIZE); - assemble_integer (symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); - if (! MACHOPIC_INDIRECT) - fprintf (asm_out_file, ".reference .constructors_used\n"); + if (vec_safe_length (ctors) > 1) + ctors->qsort (sort_ctor_records); + FOR_EACH_VEC_SAFE_ELT (ctors, i, elt) + { + assemble_align (POINTER_SIZE); + assemble_integer (elt->symbol, POINTER_SIZE / BITS_PER_UNIT, POINTER_SIZE, 1); + } } void @@ -2762,6 +2803,8 @@ darwin_file_start (void) void darwin_file_end (void) { + if (!vec_safe_is_empty (ctors)) + finalize_ctors(); machopic_finish (asm_out_file); if (strcmp (lang_hooks.name, "GNU C++") == 0) {