Page 1 of 1

linker script ignoring init_priority attribute

Posted: Mon Jan 25, 2010 11:03 am
by bpoint
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:

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);
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.

Re: linker script ignoring init_priority attribute

Posted: Wed Feb 10, 2010 8:39 pm
by bpoint
I'm also including a unified diff for ds_arm9.ld, as it's slightly different from the GBA linker script:

Code: Select all

--- ds_arm9.ld.orig     Thu Feb 11 04:02:34 2010
+++ ds_arm9.ld  Thu Feb 11 04:03:11 2010
@@ -80,10 +80,18 @@
   .preinit_array     : { KEEP (*(.preinit_array)) } >ewram = 0xff
   PROVIDE (__preinit_array_end = .);
   PROVIDE (__init_array_start = .);
-  .init_array     : { KEEP (*(.init_array)) } >ewram = 0xff
+  .init_array     :
+  {
+       KEEP (*(SORT(.init_array.*)))
+       KEEP (*(.init_array))
+  } >ewram = 0xff
   PROVIDE (__init_array_end = .);
   PROVIDE (__fini_array_start = .);
-  .fini_array     : { KEEP (*(.fini_array)) } >ewram = 0xff
+  .fini_array     :
+  {
+       KEEP (*(.fini_array))
+       KEEP (*(SORT(.fini_array.*)))
+  } >ewram = 0xff
   PROVIDE (__fini_array_end = .);

        .ctors :
Any chance these patches could make it into r28? :)

Re: linker script ignoring init_priority attribute

Posted: Thu Feb 11, 2010 3:39 pm
by ritz
I have no idea what you're talking about, but you can submit the patch directly to the devkitPro project: http://sourceforge.net/tracker/?func=ad ... tid=668553

Re: linker script ignoring init_priority attribute

Posted: Fri Feb 12, 2010 3:17 am
by WinterMute
Yeah, the patch tracker is best really but thanks for pointing this out. I committed the changes to svn this afternoon, will be in R28

Re: linker script ignoring init_priority attribute

Posted: Fri Feb 12, 2010 6:58 am
by bpoint
Thanks! I'll use the patch tracker for future patches.