| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133 | From 6a17eba5358549d0d6d195bb22b34cdbc068def2 Mon Sep 17 00:00:00 2001From: Volodymyr Arbatov <arbatov@cadence.com>Date: Mon, 6 May 2013 09:43:21 -0800Subject: [PATCH] Use signed data type for R_XTENSA_DIFF* relocation offsets.R_XTENSA_DIFF relocation offsets are in fact signed. Treat them as such.Add testcase that examines ld behaviour on R_XTENSA_DIFF relocationchanging sign during relaxation.2014-05-02  Volodymyr Arbatov  <arbatov@cadence.com>	    David Weatherford  <weath@cadence.com>	    Max Filippov  <jcmvbkbc@gmail.com>bfd/  * elf32-xtensa.c (relax_section): treat R_XTENSA_DIFF* relocations as  signed.gas/  * config/tc-xtensa.c (md_apply_fix): mark BFD_RELOC_XTENSA_DIFF*  fixups as signed.---Backported from: 1058c7532d0b012ac329219264ddad59049fb6e6Changes to Changelog files and tests are dropped. bfd/elf32-xtensa.c                       | 32 ++++++++++++----------- gas/config/tc-xtensa.c                   |  3 +++ 2 files changed, 20 insertions(+), 15 deletions(-)diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.cindex edb04b4..8818d67 100644--- a/bfd/elf32-xtensa.c+++ b/bfd/elf32-xtensa.c@@ -222,11 +222,11 @@ static reloc_howto_type elf_howto_table[] = 	 FALSE, 0, 0, FALSE),    /* Relocations for supporting difference of symbols.  */-  HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_bitfield,+  HOWTO (R_XTENSA_DIFF8, 0, 0, 8, FALSE, 0, complain_overflow_signed, 	 bfd_elf_xtensa_reloc, "R_XTENSA_DIFF8", FALSE, 0, 0xff, FALSE),-  HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_bitfield,+  HOWTO (R_XTENSA_DIFF16, 0, 1, 16, FALSE, 0, complain_overflow_signed, 	 bfd_elf_xtensa_reloc, "R_XTENSA_DIFF16", FALSE, 0, 0xffff, FALSE),-  HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_bitfield,+  HOWTO (R_XTENSA_DIFF32, 0, 2, 32, FALSE, 0, complain_overflow_signed, 	 bfd_elf_xtensa_reloc, "R_XTENSA_DIFF32", FALSE, 0, 0xffffffff, FALSE),    /* General immediate operand relocations.  */@@ -9013,7 +9013,8 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) 		  || r_type == R_XTENSA_DIFF16 		  || r_type == R_XTENSA_DIFF32) 		{-		  bfd_vma diff_value = 0, new_end_offset, diff_mask = 0;+		  bfd_signed_vma diff_value = 0;+		  bfd_vma new_end_offset, diff_mask = 0;  		  if (bfd_get_section_limit (abfd, sec) < old_source_offset) 		    {@@ -9027,15 +9028,15 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) 		    { 		    case R_XTENSA_DIFF8: 		      diff_value =-			bfd_get_8 (abfd, &contents[old_source_offset]);+			bfd_get_signed_8 (abfd, &contents[old_source_offset]); 		      break; 		    case R_XTENSA_DIFF16: 		      diff_value =-			bfd_get_16 (abfd, &contents[old_source_offset]);+			bfd_get_signed_16 (abfd, &contents[old_source_offset]); 		      break; 		    case R_XTENSA_DIFF32: 		      diff_value =-			bfd_get_32 (abfd, &contents[old_source_offset]);+			bfd_get_signed_32 (abfd, &contents[old_source_offset]); 		      break; 		    } @@ -9047,24 +9048,25 @@ relax_section (bfd *abfd, asection *sec, struct bfd_link_info *link_info) 		  switch (r_type) 		    { 		    case R_XTENSA_DIFF8:-		      diff_mask = 0xff;-		      bfd_put_8 (abfd, diff_value,+		      diff_mask = 0x7f;+		      bfd_put_signed_8 (abfd, diff_value, 				 &contents[old_source_offset]); 		      break; 		    case R_XTENSA_DIFF16:-		      diff_mask = 0xffff;-		      bfd_put_16 (abfd, diff_value,+		      diff_mask = 0x7fff;+		      bfd_put_signed_16 (abfd, diff_value, 				  &contents[old_source_offset]); 		      break; 		    case R_XTENSA_DIFF32:-		      diff_mask = 0xffffffff;-		      bfd_put_32 (abfd, diff_value,+		      diff_mask = 0x7fffffff;+		      bfd_put_signed_32 (abfd, diff_value, 				  &contents[old_source_offset]); 		      break; 		    } -		  /* Check for overflow.  */-		  if ((diff_value & ~diff_mask) != 0)+		  /* Check for overflow. Sign bits must be all zeroes or all ones */+		  if ((diff_value & ~diff_mask) != 0 &&+		      (diff_value & ~diff_mask) != (-1 & ~diff_mask)) 		    { 		      (*link_info->callbacks->reloc_dangerous) 			(link_info, _("overflow after relaxation"),diff --git a/gas/config/tc-xtensa.c b/gas/config/tc-xtensa.cindex 58ace38..7547c0a0 100644--- a/gas/config/tc-xtensa.c+++ b/gas/config/tc-xtensa.c@@ -5867,12 +5867,15 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg) 	    { 	    case BFD_RELOC_8: 	      fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF8;+	      fixP->fx_signed = 1; 	      break; 	    case BFD_RELOC_16: 	      fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF16;+	      fixP->fx_signed = 1; 	      break; 	    case BFD_RELOC_32: 	      fixP->fx_r_type = BFD_RELOC_XTENSA_DIFF32;+	      fixP->fx_signed = 1; 	      break; 	    default: 	      break;-- 1.8.1.4
 |