This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Fix .eh_frame optimisation in linker
- From: Andreas Schwab <schwab at suse dot de>
- To: binutils at sourceware dot org
- Date: Sun, 24 Aug 2008 23:43:08 +0200
- Subject: Fix .eh_frame optimisation in linker
This fixes the .eh_frame optimisation in the linker: subtracting two
unsigned int values and then adding that to a bfd_vma value results in a
wrong value when bfd_vma is wider than int and the difference is
negative.
This fixes the massive testsuite regressions in mainline GCC on ppc64,
where all exception related tests crash. This was triggered by the
recent change to use CFI insns in the assembler output.
Tested on ppc64-linux and checked in as obvious.
Andreas.
2008-08-24 Andreas Schwab <schwab@suse.de>
* elf-eh-frame.c (_bfd_elf_write_section_eh_frame): Do proper
extension when calculating difference of offsets.
--- bfd/elf-eh-frame.c.~1.71.~ 2008-08-08 21:32:05.000000000 +0200
+++ bfd/elf-eh-frame.c 2008-08-24 23:07:22.000000000 +0200
@@ -1445,7 +1445,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
val = read_value (abfd, buf, per_width,
get_DW_EH_PE_signed (per_encoding));
- val += ent->offset - ent->new_offset;
+ val += (bfd_vma) ent->offset - ent->new_offset;
val -= extra_string + extra_data;
write_value (abfd, buf, val, per_width);
action &= ~4;
@@ -1504,7 +1504,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
}
break;
case DW_EH_PE_pcrel:
- value += ent->offset - ent->new_offset;
+ value += (bfd_vma) ent->offset - ent->new_offset;
address += (sec->output_section->vma
+ sec->output_offset
+ ent->offset + 8);
@@ -1538,7 +1538,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
if (value)
{
if ((ent->lsda_encoding & 0xf0) == DW_EH_PE_pcrel)
- value += ent->offset - ent->new_offset;
+ value += (bfd_vma) ent->offset - ent->new_offset;
else if (cie->u.cie.make_lsda_relative)
value -= (sec->output_section->vma
+ sec->output_offset
@@ -1577,7 +1577,7 @@ _bfd_elf_write_section_eh_frame (bfd *ab
continue;
if ((ent->fde_encoding & 0xf0) == DW_EH_PE_pcrel)
- value += ent->offset + 8 - new_offset;
+ value += (bfd_vma) ent->offset + 8 - new_offset;
if (ent->make_relative)
value -= (sec->output_section->vma
+ sec->output_offset
--
Andreas Schwab, SuSE Labs, schwab@suse.de
SuSE Linux Products GmbH, Maxfeldstraße 5, 90409 Nürnberg, Germany
PGP key fingerprint = 58CA 54C7 6D53 942B 1756 01D3 44D5 214B 8276 4ED5
"And now for something completely different."