From: Mark Shinwell Date: Wed, 18 Oct 2006 15:34:50 +0000 (+0000) Subject: * elf32-arm.c (elf32_arm_final_link_relocate): Add support for X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=92f5d02b57f259eb32c3b3499898af0d6814fead;p=binutils-gdb.git * 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/bfd/ChangeLog b/bfd/ChangeLog index db2662f7b29..961e65e04c9 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,10 @@ +2006-10-17 Mark Shinwell + + * 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-10-17 Mark Shinwell * elf32-arm.c (elf32_arm_howto_table_1): Change offset for diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index c2e51c1976d..f9f668fa633 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -4832,6 +4832,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); @@ -4840,15 +4847,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; @@ -4862,6 +4875,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; @@ -4876,15 +4897,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;