linker script ignoring init_priority attribute
Posted: Mon Jan 25, 2010 11:03 am
I've recently changed my code over to use gcc's init_priority attribute so I can explicitly specify the order of initialization of C++ objects across translation units. The changes worked fine on Win32 and Linux, but with devkitARM r27, the attribute was being ignored.
I dug a bit into the specs and linker script being used by devkitARM, and compared them with the embedded linker script used by my gcc version on Linux, and found that the devkitARM linker script was not sorting the init_array and fini_array lists. After patching the linker script by adding the two SORT() lines, devkitARM properly called (and destroyed) my C++ objects in the correct order.
Here's a unified diff for gba_cart.ld:
It seems all of the .ld scripts (GBA, DS, GP32) are missing this sorting, so I guess I'm the first person to use the init_priority attribute.
Hope this helps. Let me know if you need any futher information or testing.
I dug a bit into the specs and linker script being used by devkitARM, and compared them with the embedded linker script used by my gcc version on Linux, and found that the devkitARM linker script was not sorting the init_array and fini_array lists. After patching the linker script by adding the two SORT() lines, devkitARM properly called (and destroyed) my C++ objects in the correct order.
Here's a unified diff for gba_cart.ld:
Code: Select all
--- gba_cart.ld.orig Sat Nov 21 13:03:07 2009
+++ gba_cart.ld Mon Jan 25 18:26:38 2010
@@ -196,13 +196,21 @@
__init_lma = __preinit_lma + SIZEOF(.preinit_array);
PROVIDE (__init_array_start = .);
- .init_array : AT (__init_lma) { KEEP (*(.init_array)) } >iwram
+ .init_array : AT (__init_lma)
+ {
+ KEEP (*(SORT(.init_array.*)))
+ KEEP (*(.init_array))
+ } >iwram
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
__fini_lma = __init_lma + SIZEOF(.init_array);
- .fini_array : AT (__fini_lma) { KEEP (*(.fini_array)) } >iwram
+ .fini_array : AT (__fini_lma)
+ {
+ KEEP (*(.fini_array))
+ KEEP (*(SORT(.fini_array.*)))
+ } >iwram
PROVIDE (__fini_array_end = .);
__jcr_lma = __fini_lma + SIZEOF(.fini_array);
Hope this helps. Let me know if you need any futher information or testing.