]> git.wh0rd.org Git - elf2flt.git/commitdiff
This patch adds elf2flt support for prioritised constructors and destructors,
authorDavid McCullough <davidm@snapgear.com>
Fri, 21 Jul 2006 13:11:04 +0000 (13:11 +0000)
committerDavid McCullough <davidm@snapgear.com>
Fri, 21 Jul 2006 13:11:04 +0000 (13:11 +0000)
but only when --enable-emit-relocs is in effect.

GCC puts prioritised constructors and destructors in special .ctor.N
and .dtor.N sections (where N encodes the priority).  The constructors
and destructors in these sections have a lower priority than those
in the default .ctor and .dtor sections.  However, we need to treat
the crtbegin.o's and crtend.o's sections specially; crtbegin.o's .[cd]tor
sections must come before all the other .[cd]tor* contents and crtend.o's
.[cd]tor sections must come after all other contents.

In --disable-emit-relocs links, it wasn't possible to treat crtbegin.o
and crtend.o specially.  ld-elf2flt would do:

                ld -r -o foo.elf2flt ...input objects...
                    |                               |
            ld -r -o foo.elf foo.elf2flt -T script  |
                                                    |
                                   ld -o foo.gdb foo.elf2flt -T script

so all the input .[cd]tor sections would already be lumped together by the
time the script was used.  This isn't a problem for --enable-emit-relocs as
it only links once.

The patch copies the [cd]tor support from the standard binutils linker
script.  The question is: should the new lines be used unconditionally,
or only when --enable-emit-relocs is in effect?

We could use the new lines for --disable-emit-relocs without breaking
programs that don't use prioritised [cd]tors.  However, it would be a user
interface regression for programs that _do_ use them.  At the moment,
if you try to use prioritised [cd]tors with --disable-emit-relocs,
you get a linker error like this:

   error: no memory region specified for loadable section `.ctors.60535'

With the new lines, the link would silently succeed, and you'd get a
runtime failure instead.  I've therefore guarded the lines with
"SINGLE_LINK:", a bit like the "W_RODAT" stuff that's already there.

Tested on Coldfire, with both --enable-emit-relocs and
--disable-emit-relocs.  It fixes the GCC ecos.exp tests.
Please install if OK.

Richard

Signed-off-by: Richard Sandiford <richard@codesourcery.com>
elf2flt.ld
ld-elf2flt.in

index 0c2e71d66c3c9e643cd224234d31df13a4a18fe6..cd4e652c305b12cefbb2602181c646f6d28e09cf 100644 (file)
@@ -91,12 +91,31 @@ R_RODAT             *(.gnu.linkonce.r*)
                . = ALIGN(4) ;
                __CTOR_LIST__ = .;
                LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
-               *(.ctors)
+SINGLE_LINK:   /* gcc uses crtbegin.o to find the start of
+SINGLE_LINK:      the constructors, so we make sure it is
+SINGLE_LINK:      first.  Because this is a wildcard, it
+SINGLE_LINK:      doesn't matter if the user does not
+SINGLE_LINK:      actually link against crtbegin.o; the
+SINGLE_LINK:      linker won't look for a file to match a
+SINGLE_LINK:      wildcard.  The wildcard also means that it
+SINGLE_LINK:      doesn't matter which directory crtbegin.o
+SINGLE_LINK:      is in.  */
+SINGLE_LINK:   KEEP (*crtbegin*.o(.ctors))
+SINGLE_LINK:   /* We don't want to include the .ctor section from
+SINGLE_LINK:      from the crtend.o file until after the sorted ctors.
+SINGLE_LINK:      The .ctor section from the crtend file contains the
+SINGLE_LINK:      end of ctors marker and it must be last */
+SINGLE_LINK:   KEEP (*(EXCLUDE_FILE (*crtend*.o ) .ctors))
+SINGLE_LINK:   KEEP (*(SORT(.ctors.*)))
+               KEEP (*(.ctors))
                LONG(0)
                __CTOR_END__ = .;
                __DTOR_LIST__ = .;
                LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
-               *(.dtors)
+SINGLE_LINK:   KEEP (*crtbegin*.o(.dtors))
+SINGLE_LINK:   KEEP (*(EXCLUDE_FILE (*crtend*.o ) .dtors))
+SINGLE_LINK:   KEEP (*(SORT(.dtors.*)))
+               KEEP (*(.dtors))
                LONG(0)
                __DTOR_END__ = .;
 
index 134ea4574b9e152b5ea722ad78b0964faa07548b..ff7a73410eda1373bd9e292413d47345ce933475 100644 (file)
@@ -127,6 +127,12 @@ then
                        esac
                        ARG1="$ARG1 -defsym $GOT_OFFSET=`expr ${SHARED_ID} '*' -4 - 4`"
                fi
+               if [ "@emit_relocs@" = "yes" ]
+               then
+                       SEDOP="$SEDOP -e s/^SINGLE_LINK://"
+               else
+                       SEDOP="$SEDOP -e /^SINGLE_LINK:/d"
+               fi
                
                # provide a default linker script, we usually need one
                [ -z "$LDSCRIPT" ] && LDSCRIPT="${LDSCRIPTPATH}/elf2flt.ld"