aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf32-bfin.c
diff options
context:
space:
mode:
authorBernd Schmidt <bernds@codesourcery.com>2008-03-26 13:04:23 +0000
committerBernd Schmidt <bernds@codesourcery.com>2008-03-26 13:04:23 +0000
commitc35e54f42419c844fb50cc537f4606ada454ecd6 (patch)
treed0a35ddef8684b7b3b39323d88ab67f8ad413e46 /bfd/elf32-bfin.c
parent53fcba31aee371e45fd8cb5401eee96e107cd4e9 (diff)
downloadgdb-c35e54f42419c844fb50cc537f4606ada454ecd6.zip
gdb-c35e54f42419c844fb50cc537f4606ada454ecd6.tar.gz
gdb-c35e54f42419c844fb50cc537f4606ada454ecd6.tar.bz2
* 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.
Diffstat (limited to 'bfd/elf32-bfin.c')
-rw-r--r--bfd/elf32-bfin.c130
1 files changed, 58 insertions, 72 deletions
diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c
index a5fe8a1..f83abd2 100644
--- a/bfd/elf32-bfin.c
+++ b/bfd/elf32-bfin.c
@@ -2070,6 +2070,60 @@ elf32_bfin_reloc_type_class (const Elf_Internal_Rela * rela)
}
}
+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
@@ -2737,43 +2791,9 @@ bfinfdpic_relocate_section (bfd * output_bfd,
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);
+ r = bfin_final_link_relocate (rel, howto, input_bfd, input_section,
+ contents, rel->r_offset,
+ relocation, rel->r_addend);
if (r != bfd_reloc_ok)
{
@@ -3039,43 +3059,9 @@ bfin_relocate_section (bfd * output_bfd,
}
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,
+ r = bfin_final_link_relocate (rel, howto, input_bfd, input_section,
contents, address,
relocation, rel->r_addend);