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]

mips n32 bfd will corrupt relocation addends


The trick to carry addends over to combined relocations fails when two
consecutive relocations happen to have the same offset into different
sections.  Hard to trigger, but with very disruptive results when it
does.  Here's a patch that gets it to take the section into account
when deciding whether two relocations are combined.

While at that, I noticed that we had references to reloc_entry in the
macro that took entry as an argument.  Oops.  Also fixed.

Ok to install?

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

	* elfn32-mips.c (prev_reloc_section): New.
	(GET_RELOC_ADDEND): Use it.  Parenthesize macro arguments.
	(SET_RELOC_ADDEND): Parenthesize macro argument.

Index: bfd/elfn32-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfn32-mips.c,v
retrieving revision 1.4
diff -u -p -r1.4 elfn32-mips.c
--- bfd/elfn32-mips.c 30 Nov 2002 08:39:39 -0000 1.4
+++ bfd/elfn32-mips.c 8 Jan 2003 21:31:58 -0000
@@ -1,6 +1,6 @@
 /* MIPS-specific support for 32-bit ELF
-   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002
-   Free Software Foundation, Inc.
+   Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+   2003  Free Software Foundation, Inc.
 
    Most of the information added by Ian Lance Taylor, Cygnus Support,
    <ian@cygnus.com>.
@@ -96,6 +96,7 @@ static irix_compat_t elf_n32_mips_irix_c
 extern const bfd_target bfd_elf32_nbigmips_vec;
 extern const bfd_target bfd_elf32_nlittlemips_vec;
 
+static bfd_vma prev_reloc_section = NULL;
 static bfd_vma prev_reloc_address = -1;
 static bfd_vma prev_reloc_addend = 0;
 
@@ -1207,29 +1208,31 @@ static reloc_howto_type elf_mips_gnu_vte
 {									\
   /* If we're relocating, and this is an external symbol, we don't	\
      want to change anything.  */					\
-    if (obfd != (bfd *) NULL						\
-	&& (sym->flags & BSF_SECTION_SYM) == 0				\
-	&& (! entry->howto->partial_inplace				\
-	    || entry->addend == 0))					\
+    if ((obfd) != (bfd *) NULL						\
+	&& ((sym)->flags & BSF_SECTION_SYM) == 0			\
+	&& (! (entry)->howto->partial_inplace				\
+	    || (entry)->addend == 0))					\
       {									\
-        entry->address += sec->output_offset;				\
+        (entry)->address += (sec)->output_offset;			\
         return bfd_reloc_ok;						\
       }									\
 									\
     /* The addend of combined relocs is remembered and left for		\
        subsequent relocs.  */						\
-    if (prev_reloc_address != reloc_entry->address)			\
+    if (prev_reloc_address != (entry)->address				\
+	|| prev_reloc_section != (sec))					\
       {									\
-        prev_reloc_address = reloc_entry->address;			\
-        prev_reloc_addend = reloc_entry->addend;			\
+	prev_reloc_section = (sec);					\
+        prev_reloc_address = (entry)->address;				\
+        prev_reloc_addend = (entry)->addend;				\
       }									\
     else								\
-      reloc_entry->addend = prev_reloc_addend;				\
+      (entry)->addend = prev_reloc_addend;				\
 }
 
 #define SET_RELOC_ADDEND(entry)						\
 {									\
-  prev_reloc_addend = entry->addend;					\
+  prev_reloc_addend = (entry)->addend;					\
 }
 
 static bfd_reloc_status_type
-- 
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]