This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: PATCH: Fix ld for ELF/PPC
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: "H. J. Lu" <hjl at lucon dot org>
- Cc: Jack Howarth <howarth at bromo dot msbb dot uc dot edu>, binutils at sources dot redhat dot com
- Date: Mon, 30 Sep 2002 11:00:26 +0930
- Subject: Re: PATCH: Fix ld for ELF/PPC
- References: <200209291441.KAA01834@bromo.msbb.uc.edu> <20020929170140.A25376@lucon.org>
On Sun, Sep 29, 2002 at 05:01:40PM -0700, H. J. Lu wrote:
> * ld/emulparams/elf32ppclinux.sh (OTHER_GOT_RELOC_SECTIONS): New.
The elf32ppc.sh change is OK, but this one is hardly necessary since
elf32ppclinux.sh sources elf32ppc.sh.
Also, I'm about to commit a more comprehensive fix.
* emultempl/elf32.em (output_rel_find): Always place orphan loadable
reloc sections just before .rel.plt/.rela.plt.
(gld${EMULATION_NAME}_place_orphan <.rel>): Remove combreloc code.
Only put loadable reloc sections in hold_rel.
Jack, would you mind checking that this works on your testcase without
HJ's changes?
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.80
diff -u -p -r1.80 elf32.em
--- ld/emultempl/elf32.em 20 Jul 2002 13:41:11 -0000 1.80
+++ ld/emultempl/elf32.em 30 Sep 2002 01:14:53 -0000
@@ -75,7 +75,7 @@ static void gld${EMULATION_NAME}_before_
static boolean gld${EMULATION_NAME}_open_dynamic_archive
PARAMS ((const char *, search_dirs_type *, lang_input_statement_type *));
static lang_output_section_statement_type *output_rel_find
- PARAMS ((void));
+ PARAMS ((asection *));
static asection *output_prev_sec_find
PARAMS ((lang_output_section_statement_type *));
static boolean gld${EMULATION_NAME}_place_orphan
@@ -996,21 +996,27 @@ cat >>e${EMULATION_NAME}.c <<EOF
/* A variant of lang_output_section_find. Used by place_orphan. */
static lang_output_section_statement_type *
-output_rel_find ()
+output_rel_find (s)
+ asection *s;
{
lang_statement_union_type *u;
lang_output_section_statement_type *lookup;
+ lang_output_section_statement_type *last_rel = NULL;
+ int is_rela = strncmp (s->name, ".rela", 5) == 0;
for (u = lang_output_section_statement.head;
u != (lang_statement_union_type *) NULL;
u = lookup->next)
{
lookup = &u->output_section_statement;
- if (strncmp (".rel", lookup->name, 4) == 0
- && lookup->bfd_section != NULL
- && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
+ if (strncmp (".rela", lookup->name, is_rela + 4) == 0
+ && lookup->name[is_rela + 4] == '.')
{
- return lookup;
+ /* Don't place after .rela.plt as doing so results in wrong
+ dynamic tags. */
+ if (strcmp ("plt", lookup->name + is_rela + 5) == 0)
+ return last_rel;
+ last_rel = lookup;
}
}
return (lang_output_section_statement_type *) NULL;
@@ -1138,27 +1144,10 @@ gld${EMULATION_NAME}_place_orphan (file,
&& HAVE_SECTION (hold_data, ".data"))
place = &hold_data;
else if (strncmp (secname, ".rel", 4) == 0
+ && (s->flags & SEC_LOAD) != 0
&& (hold_rel.os != NULL
- || (hold_rel.os = output_rel_find ()) != NULL))
- {
- if (! link_info.relocateable && link_info.combreloc)
- {
- if (strncmp (secname, ".rela", 5) == 0)
- os = lang_output_section_find (".rela.dyn");
- else
- os = lang_output_section_find (".rel.dyn");
-
- if (os != NULL
- && os->bfd_section != NULL
- && ((s->flags ^ os->bfd_section->flags)
- & (SEC_LOAD | SEC_ALLOC)) == 0)
- {
- lang_add_section (&os->children, s, os, file);
- return true;
- }
- }
- place = &hold_rel;
- }
+ || (hold_rel.os = output_rel_find (s)) != NULL))
+ place = &hold_rel;
else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY
&& HAVE_SECTION (hold_rodata, ".rodata"))
place = &hold_rodata;
--
Alan Modra
IBM OzLabs - Linux Technology Centre