# HG changeset patch # User jlarmour # Date 1412349201 0 # Node ID 68c8985fd5f0d9091d649b3e945120ffe732a0f0 # Parent a1df75458e136955a3270e0108bb2d9a93d2e3c2 * src/synth.ld src/synth_entry.c: Look for static constructors in the .init_array section as well as .ctors (needed for gcc 4.7 and later) diff --git a/packages/hal/synth/arch/current/ChangeLog b/packages/hal/synth/arch/current/ChangeLog --- a/packages/hal/synth/arch/current/ChangeLog +++ b/packages/hal/synth/arch/current/ChangeLog @@ -1,3 +1,9 @@ +2014-10-01 Ross Younger + + * src/synth.ld src/synth_entry.c: Look for static constructors in + the .init_array section as well as .ctors (needed for gcc 4.7 and + later) + 2011-08-13 Sergei Gavrikov * cdl/hal_synth.cdl (CYGPKG_HAL_SYNTH_TESTS): Fix a typo in make rule. diff --git a/packages/hal/synth/arch/current/src/synth.ld b/packages/hal/synth/arch/current/src/synth.ld --- a/packages/hal/synth/arch/current/src/synth.ld +++ b/packages/hal/synth/arch/current/src/synth.ld @@ -197,6 +197,9 @@ GROUP(libtarget.a libgcc.a) KEEP(*(SORT(.ctors*))) __CTOR_END__ = ABSOLUTE(.); \ __DTOR_LIST__ = ABSOLUTE(.); \ KEEP(*(SORT(.dtors*))) __DTOR_END__ = ABSOLUTE(.); \ + /* In gcc 4.7, constructors moved from .ctors to .init_array . */ \ + . = ALIGN(8); __init_array_start__ = ABSOLUTE(.); \ + KEEP(*(SORT(.init_array*))) __init_array_end__ = ABSOLUTE(.); \ . = ALIGN(32); \ KEEP(*( SORT (.ecos.table.*))); \ _GOT2_START_ = ABSOLUTE(.); *(.got2) _GOT2_END_ = ABSOLUTE(.); \ diff --git a/packages/hal/synth/arch/current/src/synth_entry.c b/packages/hal/synth/arch/current/src/synth_entry.c --- a/packages/hal/synth/arch/current/src/synth_entry.c +++ b/packages/hal/synth/arch/current/src/synth_entry.c @@ -68,10 +68,27 @@ cyg_bool cyg_hal_stop_constructors; typedef void (*pfunc) (void); extern pfunc __CTOR_LIST__[]; extern pfunc __CTOR_END__[]; +extern pfunc __init_array_start__[]; +extern pfunc __init_array_end__[]; void cyg_hal_invoke_constructors (void) { + /* Note: We appear to be running the constructors twice here, but + * this is not actually the case. + * gcc 4.7 changed the way static constructors are linked: + * - Prior to gcc 4.7, they appeared in the .ctors section of the + * ELF * image. + * - Since gcc 4.7, they moved to .init_array and in the reverse + * order. + * + * For us to look for both (both here and in synth.ld) is harmless, + * because the constructors are only linked once, and we are not + * too worried about squeezing every last byte of code size out of + * the synth target. + * + * - wry, 2014-10-01 + */ #ifdef CYGSEM_HAL_STOP_CONSTRUCTORS_ON_FLAG static pfunc *p = &__CTOR_END__[-1]; @@ -83,11 +100,20 @@ cyg_hal_invoke_constructors (void) break; } } + for (p = &__init_array_start__[0]; p != (__init_array_end__); p++) { + (*p) (); + if (cyg_hal_stop_constructors) { + p++; + break; + } + } #else pfunc *p; for (p = &__CTOR_END__[-1]; p >= __CTOR_LIST__; p--) (*p) (); + for (p = &__init_array_start__[0]; p != (__init_array_end__); p++) + (*p) (); #endif }