This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
Re: PATCH: Fix ld for ELF/PPC
On Mon, Sep 30, 2002 at 11:00:26AM +0930, Alan Modra wrote:
> * 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.
Revised patch after thinking about it a little longer..
Also a testcase.
ld/ChangeLog
* 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.
ld/testcuite/ChangeLog
* ld-i386/reloc.s, ld-i386/reloc.d: New.
* ld-i386/i386.exp: Run new test.
Committing mainline, and branch in a few days if I don't forget.
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.80
diff -c -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 03:24:46 -0000
*************** output_rel_find ()
*** 1000,1019 ****
{
lang_statement_union_type *u;
lang_output_section_statement_type *lookup;
! 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)
{
! return lookup;
}
}
! return (lang_output_section_statement_type *) NULL;
}
/* Find the last output section before given output statement.
--- 1000,1038 ----
{
lang_statement_union_type *u;
lang_output_section_statement_type *lookup;
+ lang_output_section_statement_type *last = NULL;
+ lang_output_section_statement_type *last_rel = NULL;
+ lang_output_section_statement_type *last_rel_alloc = NULL;
! for (u = lang_output_section_statement.head; u; u = lookup->next)
{
lookup = &u->output_section_statement;
! if (strncmp (".rel", lookup->name, 4) == 0)
{
! /* Don't place after .rel.plt as doing so results in wrong
! dynamic tags. Also, place allocated reloc sections before
! non-allocated. */
! int rela = lookup->name[4] == 'a';
!
! if (strcmp (".plt", lookup->name + 4 + rela) == 0
! || (lookup->bfd_section != NULL
! && (lookup->bfd_section->flags & SEC_ALLOC) == 0))
! break;
! last_rel = lookup;
! if (lookup->bfd_section != NULL
! && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
! last_rel_alloc = lookup;
}
+ last = lookup;
}
!
! if (last_rel_alloc)
! return last_rel_alloc;
!
! if (last_rel)
! return last_rel;
!
! return last;
}
/* Find the last output section before given output statement.
*************** gld${EMULATION_NAME}_place_orphan (file,
*** 1138,1164 ****
&& HAVE_SECTION (hold_data, ".data"))
place = &hold_data;
else if (strncmp (secname, ".rel", 4) == 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;
! }
else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY
&& HAVE_SECTION (hold_rodata, ".rodata"))
place = &hold_rodata;
--- 1157,1166 ----
&& 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))
! place = &hold_rel;
else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY
&& HAVE_SECTION (hold_rodata, ".rodata"))
place = &hold_rodata;
Index: ld/testsuite/ld-i386/i386.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-i386/i386.exp,v
retrieving revision 1.3
diff -c -p -r1.3 i386.exp
*** ld/testsuite/ld-i386/i386.exp 27 Sep 2002 19:29:17 -0000 1.3
--- ld/testsuite/ld-i386/i386.exp 30 Sep 2002 03:24:46 -0000
*************** set i386tests {
*** 52,57 ****
--- 52,59 ----
"--32" {tlsnopic1.s tlsnopic2.s}
{{readelf -Ssrl tlsnopic.rd} {objdump -drj.text tlsnopic.dd}
{objdump -sj.got tlsnopic.sd}} "libtlsnopic.so"}
+ {"Reloc section order" "-shared -melf_i386" "--32" {reloc.s}
+ {{objdump -hw reloc.d}} "reloc.so"}
}
run_ld_link_tests $i386tests
Index: ld/testsuite/ld-i386/reloc.d
===================================================================
RCS file: ld/testsuite/ld-i386/reloc.d
diff -N ld/testsuite/ld-i386/reloc.d
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-i386/reloc.d 30 Sep 2002 03:24:46 -0000
***************
*** 0 ****
--- 1,18 ----
+ # Test that orphan reloc sections are placed before .rel.plt even when
+ # .rel.plt is the only reloc section.
+ #source: reloc.s
+ #as: --32
+ #ld: -shared -melf_i386
+ #objdump: -hw
+ #target: i?86-*-*
+
+ .*: +file format elf32-i386
+ #...
+ .*\.relplatypus.*
+ #...
+ .*\.rel\.plt.*
+ # x86 ld doesn't output non-alloc reloc sections to shared libs, so disable
+ # the following two lines for the time being.
+ # #...
+ # .*\.relechidna.*
+ #pass
Index: ld/testsuite/ld-i386/reloc.s
===================================================================
RCS file: ld/testsuite/ld-i386/reloc.s
diff -N ld/testsuite/ld-i386/reloc.s
*** /dev/null 1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-i386/reloc.s 30 Sep 2002 03:24:46 -0000
***************
*** 0 ****
--- 1,8 ----
+ .section echidna
+ .long .text
+
+ .section platypus,"ax"
+ .long .text
+
+ .text
+ jmp _start@plt
--
Alan Modra
IBM OzLabs - Linux Technology Centre