This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
mips n32 bfd will corrupt relocation addends
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: 08 Jan 2003 19:37:50 -0200
- Subject: mips n32 bfd will corrupt relocation addends
- Organization: GCC Team, Red Hat
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