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]

Blackfin: Detect overflow on pcrel24 relocs


We need to handle pcrel24 relocs in a slightly special way due to how they are layed out. Currently, we don't do any error checking and silently allow overflows. I've committed this patch, which adds error checking and moves common code into a new function.


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: ChangeLog
===================================================================
RCS file: /cvs/src/src/bfd/ChangeLog,v
retrieving revision 1.4176
diff -c -p -r1.4176 ChangeLog
*** ChangeLog	25 Mar 2008 18:56:01 -0000	1.4176
--- ChangeLog	26 Mar 2008 13:03:26 -0000
***************
*** 1,3 ****
--- 1,9 ----
+ 2008-03-25  Bernd Schmidt  <bernd.schmidt@analog.com>
+ 
+ 	* elf32-bfin.c (bfin_final_link_relocate): New function, wrapper around
+ 	_bfd_final_link_relocate that also handles R_pcrel24 relocs.
+ 	(bfinfdpic_relocate_section, bfin_relocate_section): Use it.
+ 
  2008-03-25  Nathan Sidwell  <nathan@codesourcery.com>
  
  	* elf32-arm.c (elf32_arm_final_link_relocate): Skip dynamic relocs
Index: elf32-bfin.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-bfin.c,v
retrieving revision 1.29
diff -c -p -r1.29 elf32-bfin.c
*** elf32-bfin.c	12 Mar 2008 14:01:28 -0000	1.29
--- elf32-bfin.c	26 Mar 2008 13:03:27 -0000
*************** elf32_bfin_reloc_type_class (const Elf_I
*** 2070,2075 ****
--- 2070,2129 ----
      }
  }
  
+ static bfd_reloc_status_type
+ bfin_final_link_relocate (Elf_Internal_Rela *rel, reloc_howto_type *howto,
+ 			  bfd *input_bfd, asection *input_section,
+ 			  bfd_byte *contents, bfd_vma address,
+ 			  bfd_vma value, bfd_vma addend)
+ {
+   int r_type = ELF32_R_TYPE (rel->r_info);
+ 
+   if (r_type == R_pcrel24 || r_type == R_pcrel24_jump_l)
+     {
+       bfd_reloc_status_type r = bfd_reloc_ok;
+       bfd_vma x;
+ 
+       if (address > bfd_get_section_limit (input_bfd, input_section))
+ 	return bfd_reloc_outofrange;
+ 
+       value += addend;
+ 
+       /* Perform usual pc-relative correction.  */
+       value -= input_section->output_section->vma + input_section->output_offset;
+       value -= address;
+ 
+       /* We are getting reloc_entry->address 2 byte off from
+ 	 the start of instruction. Assuming absolute postion
+ 	 of the reloc data. But, following code had been written assuming
+ 	 reloc address is starting at begining of instruction.
+ 	 To compensate that I have increased the value of
+ 	 relocation by 1 (effectively 2) and used the addr -2 instead of addr.  */
+ 
+       value += 2;
+       address -= 2;
+ 
+       if ((value & 0xFF000000) != 0
+ 	  && (value & 0xFF000000) != 0xFF000000)
+ 	r = bfd_reloc_overflow;
+ 
+       value >>= 1;
+ 
+       x = bfd_get_16 (input_bfd, contents + address);
+       x = (x & 0xff00) | ((value >> 16) & 0xff);
+       bfd_put_16 (input_bfd, x, contents + address);
+ 
+       x = bfd_get_16 (input_bfd, contents + address + 2);
+       x = value & 0xFFFF;
+       bfd_put_16 (input_bfd, x, contents + address + 2);
+       return r;
+     }
+ 
+   return _bfd_final_link_relocate (howto, input_bfd, input_section, contents,
+ 				   rel->r_offset, value, addend);
+ 
+ }
+ 
+ 
  /* Relocate an Blackfin ELF section.
  
     The RELOCATE_SECTION function is called by the new ELF backend linker
*************** bfinfdpic_relocate_section (bfd * output
*** 2737,2779 ****
  	  break;
  	}
  
!       if (r_type == R_pcrel24
! 	  || r_type == R_pcrel24_jump_l)
! 	{
! 	  bfd_vma x;
! 	  bfd_vma address = rel->r_offset;
! 
! 	  relocation += rel->r_addend;
! 
! 	  /* Perform usual pc-relative correction.  */
! 	  relocation -= input_section->output_section->vma + input_section->output_offset;
! 	  relocation -= address;
! 
! 	  /* We are getting reloc_entry->address 2 byte off from
! 	     the start of instruction. Assuming absolute postion
! 	     of the reloc data. But, following code had been written assuming
! 	     reloc address is starting at begining of instruction.
! 	     To compensate that I have increased the value of
! 	     relocation by 1 (effectively 2) and used the addr -2 instead of addr.  */
! 
! 	  relocation += 2;
! 	  address -= 2;
! 
! 	  relocation >>= 1;
! 
! 	  x = bfd_get_16 (input_bfd, contents + address);
! 	  x = (x & 0xff00) | ((relocation >> 16) & 0xff);
! 	  bfd_put_16 (input_bfd, x, contents + address);
! 
! 	  x = bfd_get_16 (input_bfd, contents + address + 2);
! 	  x = relocation & 0xFFFF;
! 	  bfd_put_16 (input_bfd, x, contents + address + 2);
! 	  r = bfd_reloc_ok;
! 	}
!       else
! 	r = _bfd_final_link_relocate (howto, input_bfd, input_section,
! 				      contents, rel->r_offset,
! 				      relocation, rel->r_addend);
  
        if (r != bfd_reloc_ok)
  	{
--- 2791,2799 ----
  	  break;
  	}
  
!       r = bfin_final_link_relocate (rel, howto, input_bfd, input_section,
! 				    contents, rel->r_offset,
! 				    relocation, rel->r_addend);
  
        if (r != bfd_reloc_ok)
  	{
*************** bfin_relocate_section (bfd * output_bfd,
*** 3039,3081 ****
  	  }
  	  goto do_default;
  
- 	case R_pcrel24:
- 	case R_pcrel24_jump_l:
- 	  {
- 	    bfd_vma x;
- 
- 	    relocation += rel->r_addend;
- 
- 	    /* Perform usual pc-relative correction.  */
- 	    relocation -= input_section->output_section->vma + input_section->output_offset;
- 	    relocation -= address;
- 
- 	    /* We are getting reloc_entry->address 2 byte off from
- 	       the start of instruction. Assuming absolute postion
- 	       of the reloc data. But, following code had been written assuming
- 	       reloc address is starting at begining of instruction.
- 	       To compensate that I have increased the value of
- 	       relocation by 1 (effectively 2) and used the addr -2 instead of addr.  */
- 
- 	    relocation += 2;
- 	    address -= 2;
- 
- 	    relocation >>= 1;
- 
- 	    x = bfd_get_16 (input_bfd, contents + address);
- 	    x = (x & 0xff00) | ((relocation >> 16) & 0xff);
- 	    bfd_put_16 (input_bfd, x, contents + address);
- 
- 	    x = bfd_get_16 (input_bfd, contents + address + 2);
- 	    x = relocation & 0xFFFF;
- 	    bfd_put_16 (input_bfd, x, contents + address + 2);
- 	    r = bfd_reloc_ok;
- 	  }
- 	  break;
- 
  	default:
  	do_default:
! 	  r = _bfd_final_link_relocate (howto, input_bfd, input_section,
  					contents, address,
  					relocation, rel->r_addend);
  
--- 3059,3067 ----
  	  }
  	  goto do_default;
  
  	default:
  	do_default:
! 	  r = bfin_final_link_relocate (rel, howto, input_bfd, input_section,
  					contents, address,
  					relocation, rel->r_addend);
  

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