summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Shinwell <shinwell@codesourcery.com>2006-08-31 14:59:52 +0000
committerMark Shinwell <shinwell@codesourcery.com>2006-08-31 14:59:52 +0000
commit9267ff4c32bf787ed7514aca35d6918adca37267 (patch)
tree894610d59b4eda0e4bc1ca958093793580468932
parent597046f541639c4a85f9283caa9cd9f22bcf3c38 (diff)
downloadgdb-9267ff4c32bf787ed7514aca35d6918adca37267.tar.gz
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.
-rw-r--r--ChangeLog.csl8
-rw-r--r--bfd/elf32-arm.c87
2 files changed, 89 insertions, 6 deletions
diff --git a/ChangeLog.csl b/ChangeLog.csl
index b1623d013ad..d9ba0c6f7f9 100644
--- a/ChangeLog.csl
+++ b/ChangeLog.csl
@@ -1,3 +1,11 @@
+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.
+
2006-08-31 Joseph Myers <joseph@codesourcery.com>
ld/testsuite/
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 5d45b6d3c83..9c80e74ff84 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -834,12 +834,12 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
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_table_1[] =
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_howto_type * howto,
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). */