This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[RFC] Default ld -r should not combine .init_array sections
- From: Jie Zhang <jie at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Fri, 26 Feb 2010 00:05:50 +0800
- Subject: [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)) }