This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Blackfin: Detect overflow on pcrel24 relocs
- From: Bernd Schmidt <bernds_cb1 at t-online dot de>
- To: binutils at sources dot redhat dot com
- Date: Wed, 26 Mar 2008 14:05:43 +0100
- Subject: 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);