diff options
author | Mark Shinwell <shinwell@codesourcery.com> | 2006-08-30 17:39:17 +0000 |
---|---|---|
committer | Mark Shinwell <shinwell@codesourcery.com> | 2006-08-30 17:39:17 +0000 |
commit | 81ecfae8c39bf0d348aefafff51395a26fb49fc5 (patch) | |
tree | b43ebca2ffea8419c047c4b7a0978a2acd1fb3fc | |
parent | 082397387ad1b0faf7099e9d05db6d3b61b54007 (diff) | |
download | gdb-81ecfae8c39bf0d348aefafff51395a26fb49fc5.tar.gz |
bfd/
* elf32-arm.c (elf32_arm_final_link_relocate): Add support for
R_ARM_MOVW_BREL_NC, R_ARM_MOVW_BREL, R_ARM_MOVT_BREL,
R_ARM_THM_MOVW_BREL_NC, R_ARM_THM_MOVW_BREL and
R_ARM_THM_MOVT_BREL relocations.
-rw-r--r-- | ChangeLog.csl | 8 | ||||
-rw-r--r-- | bfd/elf32-arm.c | 39 |
2 files changed, 41 insertions, 6 deletions
diff --git a/ChangeLog.csl b/ChangeLog.csl index 095990713eb..613242f3990 100644 --- a/ChangeLog.csl +++ b/ChangeLog.csl @@ -1,3 +1,11 @@ +2006-08-30 Mark Shinwell <shinwell@codesourcery.com> + + bfd/ + * elf32-arm.c (elf32_arm_final_link_relocate): Add support for + R_ARM_MOVW_BREL_NC, R_ARM_MOVW_BREL, R_ARM_MOVT_BREL, + R_ARM_THM_MOVW_BREL_NC, R_ARM_THM_MOVW_BREL and + R_ARM_THM_MOVT_BREL relocations. + 2006-08-29 Nathan Sidwell <nathan@codesourcery.com> * ldlang.c (walk_wild): Allow * to glob '/' in wildcarded match. diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 9ae60fd88a1..5d45b6d3c83 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -4732,6 +4732,13 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, case R_ARM_MOVT_ABS: case R_ARM_MOVW_PREL_NC: case R_ARM_MOVT_PREL: + /* Until we properly support segment-base-relative addressing then + we assume the segment base to be zero, as for the group relocations. + Thus R_ARM_MOVW_BREL_NC has the same semantics as R_ARM_MOVW_ABS_NC + and R_ARM_MOVT_BREL has the same semantics as R_ARM_MOVT_ABS. */ + case R_ARM_MOVW_BREL_NC: + case R_ARM_MOVW_BREL: + case R_ARM_MOVT_BREL: { bfd_vma insn = bfd_get_32 (input_bfd, hit_data); @@ -4740,15 +4747,21 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, addend = ((insn >> 4) & 0xf000) | (insn & 0xfff); signed_addend = (addend ^ 0x10000) - 0x10000; } + value += signed_addend; - if (sym_flags == STT_ARM_TFUNC) - value |= 1; if (r_type == R_ARM_MOVW_PREL_NC || r_type == R_ARM_MOVT_PREL) value -= (input_section->output_section->vma + input_section->output_offset + rel->r_offset); - if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL) + if (r_type == R_ARM_MOVW_BREL && value >= 0x10000) + return bfd_reloc_overflow; + + if (sym_flags == STT_ARM_TFUNC) + value |= 1; + + if (r_type == R_ARM_MOVT_ABS || r_type == R_ARM_MOVT_PREL + || r_type == R_ARM_MOVT_BREL) value >>= 16; insn &= 0xfff0f000; @@ -4762,6 +4775,14 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, case R_ARM_THM_MOVT_ABS: case R_ARM_THM_MOVW_PREL_NC: case R_ARM_THM_MOVT_PREL: + /* Until we properly support segment-base-relative addressing then + we assume the segment base to be zero, as for the above relocations. + Thus R_ARM_THM_MOVW_BREL_NC has the same semantics as + R_ARM_THM_MOVW_ABS_NC and R_ARM_THM_MOVT_BREL has the same semantics + as R_ARM_THM_MOVT_ABS. */ + case R_ARM_THM_MOVW_BREL_NC: + case R_ARM_THM_MOVW_BREL: + case R_ARM_THM_MOVT_BREL: { bfd_vma insn; @@ -4776,15 +4797,21 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto, | (insn & 0x00ff); signed_addend = (addend ^ 0x10000) - 0x10000; } + value += signed_addend; - if (sym_flags == STT_ARM_TFUNC) - value |= 1; if (r_type == R_ARM_THM_MOVW_PREL_NC || r_type == R_ARM_THM_MOVT_PREL) value -= (input_section->output_section->vma + input_section->output_offset + rel->r_offset); - if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL) + if (r_type == R_ARM_THM_MOVW_BREL && value >= 0x10000) + return bfd_reloc_overflow; + + if (sym_flags == STT_ARM_TFUNC) + value |= 1; + + if (r_type == R_ARM_THM_MOVT_ABS || r_type == R_ARM_THM_MOVT_PREL + || r_type == R_ARM_THM_MOVT_BREL) value >>= 16; insn &= 0xfbf08f00; |