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]

mips64 linker accesses out-of-bounds array


The reloc count of a bfd is initialized to the size of the reloc
section divided by the size of each entry.  Later on,
mips_elf64_slurp_one_reloc_table() recomputes reloc_count as the
number of separate relocations, with up to 3 internal relocations per
external relocation.  We allocate enough memory for the 3 internal
relocations, but then, reloc_count grows, and then elfxx-mips.c ends
up using the cached relocation array (allocated before it grew) and
iterating over 3 times the grown relocation count, so it ends up
finding some, erhm, unexpected relocation types.

This patch arranges for us to create exactly three internal
relocations per external relocation, as we do elsewhere.  It fixes the
crash problem at hand, but I still see too many triple-NONE
relocations (that were already there before, FWIW), so some further
investigation is necessary to figure out where these unnecessary
relocations come from.

Meanwhile, ok to install?

Index: bfd/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* elf64-mips.c (mips_elf64_slurp_one_reloc_table): Generate
	exactly three internal relocs per external reloc.  Set reloc_count
	to the external reloc count.

Index: bfd/elf64-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-mips.c,v
retrieving revision 1.38
diff -u -p -r1.38 elf64-mips.c
--- bfd/elf64-mips.c 18 Sep 2002 17:28:37 -0000 1.38
+++ bfd/elf64-mips.c 6 Nov 2002 03:10:48 -0000
@@ -2073,7 +2073,7 @@ mips_elf64_slurp_one_reloc_table (abfd, 
 	  rela.r_addend = 0;
 	}
 
-      /* Each entry represents up to three actual relocations.  */
+      /* Each entry represents exactly three actual relocations.  */
 
       used_sym = false;
       used_ssym = false;
@@ -2096,27 +2096,6 @@ mips_elf64_slurp_one_reloc_table (abfd, 
 	      break;
 	    }
 
-	  if (type == R_MIPS_NONE)
-	    {
-	      /* There are no more relocations in this entry.  If this
-                 is the first entry, we need to generate a dummy
-                 relocation so that the generic linker knows that
-                 there has been a break in the sequence of relocations
-                 applying to a particular address.  */
-	      if (ir == 0)
-		{
-		  relent->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
-		  if ((abfd->flags & (EXEC_P | DYNAMIC)) == 0)
-		    relent->address = rela.r_offset;
-		  else
-		    relent->address = rela.r_offset - asect->vma;
-		  relent->addend = 0;
-		  relent->howto = &howto_table[(int) R_MIPS_NONE];
-		  ++relent;
-		}
-	      break;
-	    }
-
 	  /* Some types require symbols, whereas some do not.  */
 	  switch (type)
 	    {
@@ -2194,7 +2173,7 @@ mips_elf64_slurp_one_reloc_table (abfd, 
 	}
     }
 
-  asect->reloc_count += relent - relents;
+  asect->reloc_count += (relent - relents) / 3;
 
   if (allocated != NULL)
     free (allocated);
-- 
Alexandre Oliva   Enjoy Guarana', see http://www.ic.unicamp.br/~oliva/
Red Hat GCC Developer                 aoliva@{redhat.com, gcc.gnu.org}
CS PhD student at IC-Unicamp        oliva@{lsd.ic.unicamp.br, gnu.org}
Free Software Evangelist                Professional serial bug killer

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