This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: [PATCH] Support for R_ARM_MOVW_BREL_NC et al.
- From: Mark Shinwell <shinwell at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Tue, 17 Oct 2006 17:01:56 +0100
- Subject: Re: [PATCH] Support for R_ARM_MOVW_BREL_NC et al.
- References: <4534FD7B.7080809@codesourcery.com>
Mark Shinwell wrote:
This patch provides support for the ARM relocations listed below.
Tested on arm-none-linux-gnueabi. OK?
Sorry, I failed to use the correct diff format. Try again...
--
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.95
diff -U3 -p -r1.95 elf32-arm.c
--- bfd/elf32-arm.c 17 Oct 2006 15:46:21 -0000 1.95
+++ bfd/elf32-arm.c 17 Oct 2006 16:01:00 -0000
@@ -4832,6 +4832,13 @@ elf32_arm_final_link_relocate (reloc_how
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_how
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_how
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_how
| (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;