This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Blackfin: eh crash fix
- From: Bernd Schmidt <bernds_cb1 at t-online dot de>
- To: binutils at sources dot redhat dot com
- Date: Mon, 11 Feb 2008 23:25:07 +0100
- Subject: Blackfin: eh crash fix
I've committed the following patch, which fixes a problem with C++
exception handling in Blackfin FD-PIC binaries. The problem was that
.rofixup contained an invalid entry, generated by the linker when
encountering a reloc against a deleted part of .eh_frame. We already
have code in place to handle this for other relocs; the patch below
makes sure we don't create garbage in .rofixup for deleted byte4 relocs.
We use a placeholder value of -1 to communicate to the startup code
that a rofixup was deleted - unfortunately I can't see an easy way to
just omit it and shrink the section instead.
There's a corresponding patch in the uClibc startup code to ignore these
dummy -1 values; that one has been in the uClibc svn repository for a while.
Bernd
--
This footer brought to you by insane German lawmakers.
Analog Devices GmbH Wilhelm-Wagenfeld-Str. 6 80807 Muenchen
Sitz der Gesellschaft Muenchen, Registergericht Muenchen HRB 40368
Geschaeftsfuehrer Thomas Wessel, William A. Martin, Margaret Seif
Index: bfd/ChangeLog
===================================================================
RCS file: /cvs/src/src/bfd/ChangeLog,v
retrieving revision 1.4129
diff -c -p -r1.4129 ChangeLog
*** bfd/ChangeLog 11 Feb 2008 16:04:51 -0000 1.4129
--- bfd/ChangeLog 11 Feb 2008 22:24:17 -0000
***************
*** 5,10 ****
--- 5,13 ----
(elf32_bfin_merge_private_bfd_data): Simplify, and ensure object type
mismatches are detected.
+ * elf32-bfin.c (bfinfdpic_relocate_section): Take more care not to
+ emit invalid relocs or rofixup entries for deleted .eh_frame entries.
+
2008-02-11 Daniel Jacobowitz <dan@codesourcery.com>
* cache.c (cache_bread): Set bfd_error_file_truncated if EOF
Index: bfd/elf32-bfin.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-bfin.c,v
retrieving revision 1.27
diff -c -p -r1.27 elf32-bfin.c
*** bfd/elf32-bfin.c 11 Feb 2008 16:04:51 -0000 1.27
--- bfd/elf32-bfin.c 11 Feb 2008 22:24:17 -0000
*************** bfinfdpic_relocate_section (bfd * output
*** 2479,2484 ****
--- 2479,2487 ----
{
int dynindx;
bfd_vma addend = rel->r_addend;
+ bfd_vma offset;
+ offset = _bfd_elf_section_offset (output_bfd, info,
+ input_section, rel->r_offset);
/* If the symbol is dynamic but binds locally, use
section+offset. */
*************** bfinfdpic_relocate_section (bfd * output
*** 2535,2559 ****
}
if (!h || h->root.type != bfd_link_hash_undefweak)
{
! _bfinfdpic_add_rofixup (output_bfd,
! bfinfdpic_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_BFIN_FUNCDESC_VALUE)
! _bfinfdpic_add_rofixup
! (output_bfd,
! bfinfdpic_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);
}
}
}
--- 2538,2571 ----
}
if (!h || h->root.type != bfd_link_hash_undefweak)
{
! /* Only output a reloc for a not deleted entry. */
! if (offset >= (bfd_vma)-2)
! _bfinfdpic_add_rofixup (output_bfd,
! bfinfdpic_gotfixup_section
! (info), -1, picrel);
! else
! _bfinfdpic_add_rofixup (output_bfd,
! bfinfdpic_gotfixup_section
! (info),
! offset + input_section
! ->output_section->vma
! + input_section->output_offset,
! picrel);
!
if (r_type == R_BFIN_FUNCDESC_VALUE)
! {
! if (offset >= (bfd_vma)-2)
! _bfinfdpic_add_rofixup
! (output_bfd,
! bfinfdpic_gotfixup_section (info),
! -1, picrel);
! else
! _bfinfdpic_add_rofixup
! (output_bfd,
! bfinfdpic_gotfixup_section (info),
! offset + input_section->output_section->vma
! + input_section->output_offset + 4, picrel);
! }
}
}
}
*************** bfinfdpic_relocate_section (bfd * output
*** 2573,2587 ****
name, input_bfd, input_section, rel->r_offset);
return FALSE;
}
! _bfinfdpic_add_dyn_reloc (output_bfd,
! bfinfdpic_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);
}
else if (osec)
addend += osec->output_section->vma;
--- 2585,2603 ----
name, input_bfd, input_section, rel->r_offset);
return FALSE;
}
! /* Only output a reloc for a not deleted entry. */
! if (offset >= (bfd_vma)-2)
! _bfinfdpic_add_dyn_reloc (output_bfd,
! bfinfdpic_gotrel_section (info),
! 0, R_unused0, dynindx, addend, picrel);
! else
! _bfinfdpic_add_dyn_reloc (output_bfd,
! bfinfdpic_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;
*************** bfinfdpic_relocate_section (bfd * output
*** 2591,2597 ****
relocation = addend - rel->r_addend;
}
! if (r_type == R_BFIN_FUNCDESC_VALUE)
{
/* If we've omitted the dynamic relocation, just emit
the fixed addresses of the symbol and of the local
--- 2607,2613 ----
relocation = addend - rel->r_addend;
}
! if (r_type == R_BFIN_FUNCDESC_VALUE && offset < (bfd_vma)-2)
{
/* If we've omitted the dynamic relocation, just emit
the fixed addresses of the symbol and of the local