This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] PREL_11_0 and PC12 Thumb-2 relocations
- From: Mark Shinwell <shinwell at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Thu, 31 Aug 2006 16:06:04 +0100
- Subject: [PATCH] PREL_11_0 and PC12 Thumb-2 relocations
Here is bfd support for the ARM Thumb-2 PREL_11_0 and PC12 relocs.
At this stage gas support is not provided, but that is a QoI issue
rather than an EABI-compliance issue.
Since gas support is lacking, this patch has been tested manually.
Anyone who is interested can see the details of that testing below.
OK?
Mark
--
2006-08-31 Mark Shinwell <shinwell@codesourcery.com>
bfd/
* elf32-arm.c (elf32_arm_howto_table_1): Adjust entries for
R_ARM_THM_ALU_PREL_11_0 and R_ARM_THM_PC12 relocations.
(elf32_arm_final_link_relocate): Handle R_ARM_THM_ALU_PREL_11_0
and R_ARM_THM_PC12 relocations.
--
Testing of PREL_11_0
--------------------
I've tested this by using a hex editor to construct an object that dumps
thus:
test.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <_start>:
0: f60f 0000 addw r0, pc, #2048
0: R_ARM_THM_ALU_PREL_11_0 f
4: f6af 0000 subw r0, pc, #2048
4: R_ARM_THM_ALU_PREL_11_0 f
8: f60f 0000 addw r0, pc, #2048
8: R_ARM_THM_ALU_PREL_11_0 g
c: f6af 0000 subw r0, pc, #2048
c: R_ARM_THM_ALU_PREL_11_0 g
Disassembly of section .after:
00000000 <f>:
0: f240 0000 movw r0, #0 ; 0x0
Disassembly of section .before:
00000000 <g>:
0: f240 0000 movw r0, #0 ; 0x0
Then we link this with:
-Ttext 0x8000 --section-start .after=0x87fc --section-start .before=0x7900
and the resulting executable is as follows:
test: file format elf32-littlearm
Disassembly of section .text:
00008000 <_start>:
8000: f60f 70fc addw r0, pc, #4092 ; 0xffc
8004: f2af 0008 subw r0, pc, #8 ; 0x8
8008: f20f 00f8 addw r0, pc, #248 ; 0xf8
800c: f6af 700c subw r0, pc, #3852 ; 0xf0c
Disassembly of section .after:
000087fc <f>:
87fc: f240 0000 movw r0, #0 ; 0x0
Disassembly of section .before:
00007900 <g>:
7900: f240 0000 movw r0, #0 ; 0x0
Setting --section-start .after=0x8800 yields an overflow as expected.
Testing of PC12
---------------
Again a hex editor was used, this time to construct the following:
test-ldr.o: file format elf32-littlearm
Disassembly of section .text:
00000000 <_start>:
0: f8df 0800 ldr.w r0, [pc, #2048]
0: R_ARM_THM_PC12 f
4: f85f 0800 ldr.w r0, [pc, #-2048]
4: R_ARM_THM_PC12 f
8: f8df 0800 ldr.w r0, [pc, #2048]
8: R_ARM_THM_PC12 g
c: f85f 0800 ldr.w r0, [pc, #-2048]
c: R_ARM_THM_PC12 g
Disassembly of section .after:
00000000 <f>:
0: f240 0000 movw r0, #0 ; 0x0
Disassembly of section .before:
00000000 <g>:
0: f240 0000 movw r0, #0 ; 0x0
Linking this as above we end up with:
test-ldr: file format elf32-littlearm
Disassembly of section .text:
00008000 <_start>:
8000: f8df 0ffc ldr.w r0, [pc, #4092]
8004: f85f 0008 ldr.w r0, [pc, #-8]
8008: f8df 00f8 ldr.w r0, [pc, #248]
800c: f85f 0f0c ldr.w r0, [pc, #-3852]
Disassembly of section .after:
000087fc <f>:
87fc: f240 0000 movw r0, #0 ; 0x0
Disassembly of section .before:
00007900 <g>:
7900: f240 0000 movw r0, #0 ; 0x0
Again, placing .after at 0x8800 yields an overflow.
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.70.2.12
diff -U3 -p -r1.70.2.12 elf32-arm.c
--- bfd/elf32-arm.c 30 Aug 2006 17:39:17 -0000 1.70.2.12
+++ bfd/elf32-arm.c 31 Aug 2006 11:15:13 -0000
@@ -834,12 +834,12 @@ static reloc_howto_type elf32_arm_howto_
13, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
- complain_overflow_signed,/* complain_on_overflow */
+ complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_ARM_THM_ALU_PREL_11_0",/* name */
FALSE, /* partial_inplace */
- 0x040070ff, /* src_mask */
- 0x040070ff, /* dst_mask */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
TRUE), /* pcrel_offset */
HOWTO (R_ARM_THM_PC12, /* type */
@@ -848,12 +848,12 @@ static reloc_howto_type elf32_arm_howto_
13, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
- complain_overflow_signed,/* complain_on_overflow */
+ complain_overflow_dont,/* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_ARM_THM_PC12", /* name */
FALSE, /* partial_inplace */
- 0x040070ff, /* src_mask */
- 0x040070ff, /* dst_mask */
+ 0x0fffffff, /* src_mask */
+ 0x0fffffff, /* dst_mask */
TRUE), /* pcrel_offset */
HOWTO (R_ARM_ABS32_NOI, /* type */
@@ -3958,6 +3958,81 @@ elf32_arm_final_link_relocate (reloc_how
bfd_put_16 (input_bfd, value, hit_data);
return bfd_reloc_ok;
+ case R_ARM_THM_ALU_PREL_11_0:
+ /* Corresponds to: addw.w reg, pc, #offset (and similarly for subw). */
+ {
+ bfd_vma insn;
+ bfd_signed_vma relocation;
+
+ insn = (bfd_get_16 (input_bfd, hit_data) << 16)
+ | bfd_get_16 (input_bfd, hit_data + 2);
+
+ if (globals->use_rel)
+ {
+ signed_addend = (insn & 0xff) | ((insn & 0x7000) >> 4)
+ | ((insn & (1 << 26)) >> 15);
+ if (insn & 0xf00000)
+ signed_addend = -signed_addend;
+ }
+
+ relocation = value + signed_addend;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ value = abs (relocation);
+
+ if (value >= 0x1000)
+ return bfd_reloc_overflow;
+
+ insn = (insn & 0xfb0f8f00) | (value & 0xff)
+ | ((value & 0x700) << 4)
+ | ((value & 0x800) << 15);
+ if (relocation < 0)
+ insn |= 0xa00000;
+
+ bfd_put_16 (input_bfd, insn >> 16, hit_data);
+ bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
+
+ return bfd_reloc_ok;
+ }
+
+ case R_ARM_THM_PC12:
+ /* Corresponds to: ldr.w reg, [pc, #offset]. */
+ {
+ bfd_vma insn;
+ bfd_signed_vma relocation;
+
+ insn = (bfd_get_16 (input_bfd, hit_data) << 16)
+ | bfd_get_16 (input_bfd, hit_data + 2);
+
+ if (globals->use_rel)
+ {
+ signed_addend = insn & 0xfff;
+ if (!(insn & (1 << 23)))
+ signed_addend = -signed_addend;
+ }
+
+ relocation = value + signed_addend;
+ relocation -= (input_section->output_section->vma
+ + input_section->output_offset
+ + rel->r_offset);
+
+ value = abs (relocation);
+
+ if (value >= 0x1000)
+ return bfd_reloc_overflow;
+
+ insn = (insn & 0xff7ff000) | value;
+ if (relocation >= 0)
+ insn |= (1 << 23);
+
+ bfd_put_16 (input_bfd, insn >> 16, hit_data);
+ bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
+
+ return bfd_reloc_ok;
+ }
+
case R_ARM_THM_XPC22:
case R_ARM_THM_CALL:
/* Thumb BL (branch long instruction). */