This is the mail archive of the binutils@sourceware.org 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]

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."


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]