This is the mail archive of the binutils@sources.redhat.com 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: [PATCH] Fix elfvsb tests on ppc64


On Tue, Jul 29, 2003 at 04:02:56PM +0200, Jakub Jelinek wrote:
> This seems to be enough to get the visibility tests to pass on ppc64
> (and does not introduce new failures on other arches).
> Committed as obvious.
> 
> 2003-07-29  Jakub Jelinek  <jakub@redhat.com>
> 
> 	* ld-elfvsb/elf-offset.ld: Add .rel.toc, .rela.toc and .toc
> 	sections.

Hmm, this isn't sufficient.  I find that running the testsuite natively
on powerpc64-linux requires that .rela.opd also be specified in the
script.  The real problem is that the test is run without -znocombreloc,
so orphan reloc sections get placed in .rela.dyn.  .rela.dyn isn't
specified in the script either, and thus is placed after any other
reloc sections.  However, ld.so assumes that .rela.dyn comes first in
this code from elf/do-rel.h

      ElfW(Word) nrelative = (map->l_info[RELCOUNT_IDX] == NULL
			      ? 0 : map->l_info[RELCOUNT_IDX]->d_un.d_val);
      const ElfW(Rel) *relative = r;
      r = r + MIN (nrelative, relsize / sizeof (ElfW(Rel)));

[snip]
	  for (; relative < r; ++relative)
	    DO_ELF_MACHINE_REL_RELATIVE (map, l_addr, relative);

Fixed by the following patch, which also tweaks output_rel_find to be
a little more robust in other situations.

	* emultempl/elf32.em (output_rel_find): Add "isdyn" param.  Put
	.rel.dyn before other reloc sections.  Don't stop looking for reloc
	sections on finding one that isn't allocated.  Match .rel even when
	placing .rela and vice versa, when setting last_rel and
	last_rel_alloc for the first time.  If no reloc sections in script,
	prefer allocated section over non-alloc.
	(gld${EMULATION_NAME}_place_orphan): Handle orphan .rel.dyn.

Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.101
diff -u -p -r1.101 elf32.em
--- ld/emultempl/elf32.em	27 Jun 2003 00:38:25 -0000	1.101
+++ ld/emultempl/elf32.em	4 Aug 2003 03:59:24 -0000
@@ -998,11 +998,12 @@ 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 (asection *sec)
+output_rel_find (asection *sec, int isdyn)
 {
   lang_statement_union_type *u;
   lang_output_section_statement_type *lookup;
   lang_output_section_statement_type *last = NULL;
+  lang_output_section_statement_type *last_alloc = NULL;
   lang_output_section_statement_type *last_rel = NULL;
   lang_output_section_statement_type *last_rel_alloc = NULL;
   int rela = sec->name[4] == 'a';
@@ -1012,22 +1013,30 @@ output_rel_find (asection *sec)
       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 lookrela = lookup->name[4] == 'a';
 
-	  if (strcmp (".plt", lookup->name + 4 + lookrela) == 0
-	      || (lookup->bfd_section != NULL
-		  && (lookup->bfd_section->flags & SEC_ALLOC) == 0))
+	  /* .rel.dyn must come before all other reloc sections, to suit
+	     GNU ld.so.  */
+	  if (isdyn)
+	    break;
+
+	  /* Don't place after .rel.plt as doing so results in wrong
+	     dynamic tags.  */
+	  if (strcmp (".plt", lookup->name + 4 + lookrela) == 0)
 	    break;
-	  last = lookup;
-	  if (rela == lookrela)
+
+	  if (rela == lookrela || last_rel == NULL)
 	    last_rel = lookup;
-	  if (lookup->bfd_section != NULL
+	  if ((rela == lookrela || last_rel_alloc == NULL)
+	      && lookup->bfd_section != NULL
 	      && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
 	    last_rel_alloc = lookup;
 	}
+
+      last = lookup;
+      if (lookup->bfd_section != NULL
+	  && (lookup->bfd_section->flags & SEC_ALLOC) != 0)
+	last_alloc = lookup;
     }
 
   if (last_rel_alloc)
@@ -1036,6 +1045,9 @@ output_rel_find (asection *sec)
   if (last_rel)
     return last_rel;
 
+  if (last_alloc)
+    return last_alloc;
+
   return last;
 }
 
@@ -1174,7 +1186,7 @@ gld${EMULATION_NAME}_place_orphan (lang_
   else if (strncmp (secname, ".rel", 4) == 0
 	   && (s->flags & SEC_LOAD) != 0
 	   && (hold_rel.os != NULL
-	       || (hold_rel.os = output_rel_find (s)) != NULL))
+	       || (hold_rel.os = output_rel_find (s, isdyn)) != NULL))
     place = &hold_rel;
   else if ((s->flags & (SEC_CODE | SEC_READONLY)) == SEC_READONLY
 	   && HAVE_SECTION (hold_rodata, ".rodata"))

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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