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]

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


On 02/26/2010 12:30 AM, H.J. Lu wrote:
On Thu, Feb 25, 2010 at 8:05 AM, Jie Zhang<jie@codesourcery.com> wrote:
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?



Please include a generic testcase.


Here is a new version with testcase and ChangeLog entry.


Jie
	* scripttempl/elf.sc: Don't combine .init_array.* or
	.fini_array.* when do relocatable linking.

	testsuite/
	* ld-cdtest/cdtest2.exp: New test.
	* ld-cdtest/cdtest2.cc: New test.

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	26 Feb 2010 08:30:08 -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: testsuite/ld-cdtest/cdtest2.cc
===================================================================
RCS file: testsuite/ld-cdtest/cdtest2.cc
diff -N testsuite/ld-cdtest/cdtest2.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/ld-cdtest/cdtest2.cc	26 Feb 2010 08:30:08 -0000
@@ -0,0 +1,7 @@
+class A
+{
+public:
+  A() {}
+};
+
+A a __attribute__ ((init_priority (1000)));
Index: testsuite/ld-cdtest/cdtest2.exp
===================================================================
RCS file: testsuite/ld-cdtest/cdtest2.exp
diff -N testsuite/ld-cdtest/cdtest2.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/ld-cdtest/cdtest2.exp	26 Feb 2010 08:30:08 -0000
@@ -0,0 +1,55 @@
+# Test the constructor priority with relocatable linking
+#
+# Copyright 2010   Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+
+set testname "constructor priority with relocatable linking"
+
+if {! [is_elf_format] } {
+    unsupported $testname
+    return
+}
+
+if {! [ld_compile "$CXX $CXXFLAGS" $srcdir/$subdir/cdtest2.cc tmpdir/cdtest2.o] } {
+    unresolved $testname
+    return
+}
+
+send_log "$READELF --section-headers tmpdir/cdtest2.o\n"
+set exec_output [run_host_cmd "$READELF" "--section-headers tmpdir/cdtest2.o"]
+
+if {! [regexp ".init_array.01000" $exec_output] } {
+    unsupported $testname
+    return
+}
+
+if ![ld_relocate $ld tmpdir/cdtest2r.o tmpdir/cdtest2.o] {
+    fail $testname
+} else {
+    send_log "$READELF --section-headers tmpdir/cdtest2r.o\n"
+    set exec_output [run_host_cmd "$READELF" "--section-headers tmpdir/cdtest2r.o"]
+
+    if {! [regexp ".init_array.01000" $exec_output] } {
+	fail $testname
+	return
+    }
+
+    pass $testname
+    return 1
+}

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