This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFC] Default ld -r should not combine .init_array sections


We found this issue on arm-none-eabi target. The default ld -r combines .init_array.* sections. Such that priority information recorded in section name will be lost. When the object file from the output of "ld -r" is linked into the final executable, the static constructors will do initialization in wrong order.

For example:

$ cat a.cpp
#include <stdio.h>

class A
{
public:
  A() {
    printf ("A\n");
  }
};

A a __attribute__ ((init_priority (1000)));

$ cat b.cpp
#include <stdio.h>

class B
{
public:
  B() {
    printf ("B\n");
  }
};

B b __attribute__ ((init_priority (2000)));

int main ()
{
  return 0;
}

#include <stdio.h>

class C
{
public:
  C() {
    printf ("C\n");
  }
};

C c __attribute__ ((init_priority (3000)));

$ arm-none-eabi-g++ -o m a.cpp b.cpp c.cpp
$ arm-none-eabi-run m
A
B
C

But

$ arm-none-eabi-g++ -c a.cpp b.cpp c.cpp
$ arm-none-eabi-ld -r -o ac.o a.o c.o
$ arm-none-eabi-g++ -o m ac.o b.o
$ arm-none-eabi-run m
B
A
C

With the attach patch, we can get the expected result. This patch also do the same thing for .fini_array sections. Any comments?


Thanks, Jie
Index: scripttempl/elf.sc
===================================================================
RCS file: /cvs/src/src/ld/scripttempl/elf.sc,v
retrieving revision 1.98
diff -u -p -r1.98 elf.sc
--- scripttempl/elf.sc	9 Dec 2009 01:26:03 -0000	1.98
+++ scripttempl/elf.sc	25 Feb 2010 15:09:23 -0000
@@ -216,6 +216,20 @@ test "${LARGE_SECTIONS}" = "yes" && LARG
     *(.ldata${RELOCATING+ .ldata.* .gnu.linkonce.l.*})
     ${RELOCATING+. = ALIGN(. != 0 ? ${ALIGNMENT} : 1);}
   }"
+INIT_ARRAY=".init_array   ${RELOCATING-0} :
+  {
+     ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__init_array_start = .);}}
+     KEEP (*(SORT(.init_array.*)))
+     KEEP (*(.init_array))
+     ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__init_array_end = .);}}
+  }"
+FINI_ARRAY=".fini_array   ${RELOCATING-0} :
+  {
+    ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_start = .);}}
+    KEEP (*(.fini_array))
+    KEEP (*(SORT(.fini_array.*)))
+    ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_end = .);}}
+  }"
 CTOR=".ctors        ${CONSTRUCTING-0} : 
   {
     ${CONSTRUCTING+${CTOR_START}}
@@ -455,20 +469,8 @@ cat <<EOF
     KEEP (*(.preinit_array))
     ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__preinit_array_end = .);}}
   }
-  .init_array   ${RELOCATING-0} :
-  {
-     ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__init_array_start = .);}}
-     KEEP (*(SORT(.init_array.*)))
-     KEEP (*(.init_array))
-     ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__init_array_end = .);}}
-  }
-  .fini_array   ${RELOCATING-0} :
-  {
-    ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_start = .);}}
-    KEEP (*(.fini_array))
-    KEEP (*(SORT(.fini_array.*)))
-    ${RELOCATING+${CREATE_SHLIB-PROVIDE_HIDDEN (${USER_LABEL_PREFIX}__fini_array_end = .);}}
-  }
+  ${RELOCATING+${INIT_ARRAY}}
+  ${RELOCATING+${FINI_ARRAY}}
   ${SMALL_DATA_CTOR-${RELOCATING+${CTOR}}}
   ${SMALL_DATA_DTOR-${RELOCATING+${DTOR}}}
   .jcr          ${RELOCATING-0} : { KEEP (*(.jcr)) }

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]