From: Mark Shinwell Date: Wed, 30 Aug 2006 17:39:17 +0000 (+0000) Subject: bfd/ X-Git-Tag: binutils-csl-sourcerygxx-4_1-18~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=506135d82adb6f020a68339210248bbe1d0fd86d;p=thirdparty%2Fbinutils-gdb.git 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. --- 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 + + 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 * 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;