This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
fix frv eh_frame relaxation bug
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Tue, 08 May 2007 03:08:39 -0300
- Subject: fix frv eh_frame relaxation bug
elf-eh-frame.c removes CIEs that are redundant with previous CIEs, and
this requires the relocation for __gxx_personality_v0 to be dropped as
well.
However, the relocation code failed to take into account the
possibility of this kind of relaxation, and used the result of
_bfd_elf_section_offset() without testing whether it's -1, which
indicates that (re)location is to be dropped entirely because the
underlying construct was removed.
AFAICT we've already taken care of ensuring it would never be -2
(cross-segment relocations don't work), so this should be good enough.
I'm checking it in. Tested by building a functional libstdc++.so.6
(EH wouldn't work at all before the patch.)
Index: bfd/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* elf32-frv.c (elf32_frv_relocate_section): Discard dynamic relocs
for which _bfd_elf_section_offset returns -1.
Index: bfd/elf32-frv.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-frv.c,v
retrieving revision 1.52
diff -u -p -r1.52 elf32-frv.c
--- bfd/elf32-frv.c 26 Apr 2007 14:46:56 -0000 1.52
+++ bfd/elf32-frv.c 8 May 2007 06:05:17 -0000
@@ -3644,6 +3644,8 @@ elf32_frv_relocate_section (output_bfd,
input_section->output_section)
& (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
{
+ bfd_vma offset;
+
if (_frvfdpic_osec_readonly_p (output_bfd,
input_section
->output_section))
@@ -3654,22 +3656,27 @@ elf32_frv_relocate_section (output_bfd,
name, input_bfd, input_section, rel->r_offset);
return FALSE;
}
- _frvfdpic_add_rofixup (output_bfd,
- frvfdpic_gotfixup_section
- (info),
- _bfd_elf_section_offset
- (output_bfd, info,
- input_section, rel->r_offset)
- + input_section
- ->output_section->vma
- + input_section->output_offset,
- picrel);
+
+ offset = _bfd_elf_section_offset
+ (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (offset != (bfd_vma)-1)
+ _frvfdpic_add_rofixup (output_bfd,
+ frvfdpic_gotfixup_section
+ (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ picrel);
}
}
else if ((bfd_get_section_flags (output_bfd,
input_section->output_section)
& (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
{
+ bfd_vma offset;
+
if (_frvfdpic_osec_readonly_p (output_bfd,
input_section
->output_section))
@@ -3680,15 +3687,18 @@ elf32_frv_relocate_section (output_bfd,
name, input_bfd, input_section, rel->r_offset);
return FALSE;
}
- _frvfdpic_add_dyn_reloc (output_bfd,
- frvfdpic_gotrel_section (info),
- _bfd_elf_section_offset
- (output_bfd, info,
- input_section, rel->r_offset)
- + input_section
- ->output_section->vma
- + input_section->output_offset,
- r_type, dynindx, addend, picrel);
+
+ offset = _bfd_elf_section_offset
+ (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (offset != (bfd_vma)-1)
+ _frvfdpic_add_dyn_reloc (output_bfd,
+ frvfdpic_gotrel_section (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ r_type, dynindx, addend, picrel);
}
else
addend += frvfdpic_got_section (info)->output_section->vma;
@@ -3769,25 +3779,27 @@ elf32_frv_relocate_section (output_bfd,
}
if (!h || h->root.type != bfd_link_hash_undefweak)
{
- _frvfdpic_add_rofixup (output_bfd,
- frvfdpic_gotfixup_section
- (info),
- _bfd_elf_section_offset
- (output_bfd, info,
- input_section, rel->r_offset)
- + input_section
- ->output_section->vma
- + input_section->output_offset,
- picrel);
- if (r_type == R_FRV_FUNCDESC_VALUE)
- _frvfdpic_add_rofixup
- (output_bfd,
- frvfdpic_gotfixup_section (info),
- _bfd_elf_section_offset
- (output_bfd, info,
- input_section, rel->r_offset)
- + input_section->output_section->vma
- + input_section->output_offset + 4, picrel);
+ bfd_vma offset = _bfd_elf_section_offset
+ (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (offset != (bfd_vma)-1)
+ {
+ _frvfdpic_add_rofixup (output_bfd,
+ frvfdpic_gotfixup_section
+ (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ picrel);
+ if (r_type == R_FRV_FUNCDESC_VALUE)
+ _frvfdpic_add_rofixup
+ (output_bfd,
+ frvfdpic_gotfixup_section (info),
+ offset
+ + input_section->output_section->vma
+ + input_section->output_offset + 4, picrel);
+ }
}
}
}
@@ -3797,6 +3809,8 @@ elf32_frv_relocate_section (output_bfd,
input_section->output_section)
& (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
{
+ bfd_vma offset;
+
if (_frvfdpic_osec_readonly_p (output_bfd,
input_section
->output_section))
@@ -3807,15 +3821,18 @@ elf32_frv_relocate_section (output_bfd,
name, input_bfd, input_section, rel->r_offset);
return FALSE;
}
- _frvfdpic_add_dyn_reloc (output_bfd,
- frvfdpic_gotrel_section (info),
- _bfd_elf_section_offset
- (output_bfd, info,
- input_section, rel->r_offset)
- + input_section
- ->output_section->vma
- + input_section->output_offset,
- r_type, dynindx, addend, picrel);
+
+ offset = _bfd_elf_section_offset
+ (output_bfd, info,
+ input_section, rel->r_offset);
+
+ if (offset != (bfd_vma)-1)
+ _frvfdpic_add_dyn_reloc (output_bfd,
+ frvfdpic_gotrel_section (info),
+ offset + input_section
+ ->output_section->vma
+ + input_section->output_offset,
+ r_type, dynindx, addend, picrel);
}
else if (osec)
addend += osec->output_section->vma;
--
Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member http://www.fsfla.org/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}