summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Brook <paul@codesourcery.com>2006-05-03 14:30:23 +0000
committerPaul Brook <paul@codesourcery.com>2006-05-03 14:30:23 +0000
commit94766e1ae6b53f465da1f3b50b82fd7120f93a74 (patch)
treef35e576d110ac06879e41d89ac4fded5fd6c8fe7
parent55ac68787dcc14a394da069e659166657295dde7 (diff)
downloadgdb-94766e1ae6b53f465da1f3b50b82fd7120f93a74.tar.gz
2006-05-03 Paul Brook <paul@codesourcery.com>
* bfd/elf32-arm.c (elf32_arm_reloc_map): Add MOVW and MOVT relocs. (elf32_arm_final_link_relocate): Handle MOVW and MOVT relocs. (elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto. * bfd/reloc.c: Ditto. * bfd/bfd-in2.h: Regenerate. * bfd/libbfd.h: Regenerate. * bfd/libcoff.h: Regenerate. * gas/config/tc-arm.c (parse_half): New function. (operand_parse_code): Remove OP_Iffff. Add OP_HALF. (parse_operands): Ditto. (do_mov16): Reject invalid relocations. (do_t_mov16): Ditto. Use Thumb reloc numbers. (insns): Replace Iffff with HALF. (md_apply_fix): Add MOVW and MOVT relocs. (tc_gen_reloc): Ditto. * gas/doc/c-arm.texi: Document relocation operators * ld/testsuite/ld-arm/arm-elf.exp: Add arm-movwt. * ld/testsuite/ld-arm/arm-movwt.d: New test. * ld/testsuite/ld-arm/arm-movwt.s: New test. * ld/testsuite/ld-arm/arm.ld: Add .far.
-rw-r--r--ChangeLog.csl23
-rw-r--r--bfd/bfd-in2.h10
-rw-r--r--bfd/elf32-arm.c101
-rw-r--r--bfd/libbfd.h8
-rw-r--r--bfd/reloc.c18
5 files changed, 154 insertions, 6 deletions
diff --git a/ChangeLog.csl b/ChangeLog.csl
index eaf8ce15984..dc69626d4b4 100644
--- a/ChangeLog.csl
+++ b/ChangeLog.csl
@@ -1,3 +1,26 @@
+2006-05-03 Paul Brook <paul@codesourcery.com>
+
+ * bfd/elf32-arm.c (elf32_arm_reloc_map): Add MOVW and MOVT relocs.
+ (elf32_arm_final_link_relocate): Handle MOVW and MOVT relocs.
+ (elf32_arm_gc_sweep_hook, elf32_arm_check_relocs): Ditto.
+ * bfd/reloc.c: Ditto.
+ * bfd/bfd-in2.h: Regenerate.
+ * bfd/libbfd.h: Regenerate.
+ * bfd/libcoff.h: Regenerate.
+ * gas/config/tc-arm.c (parse_half): New function.
+ (operand_parse_code): Remove OP_Iffff. Add OP_HALF.
+ (parse_operands): Ditto.
+ (do_mov16): Reject invalid relocations.
+ (do_t_mov16): Ditto. Use Thumb reloc numbers.
+ (insns): Replace Iffff with HALF.
+ (md_apply_fix): Add MOVW and MOVT relocs.
+ (tc_gen_reloc): Ditto.
+ * gas/doc/c-arm.texi: Document relocation operators
+ * ld/testsuite/ld-arm/arm-elf.exp: Add arm-movwt.
+ * ld/testsuite/ld-arm/arm-movwt.d: New test.
+ * ld/testsuite/ld-arm/arm-movwt.s: New test.
+ * ld/testsuite/ld-arm/arm.ld: Add .far.
+
2006-05-02 Joseph Myers <joseph@codesourcery.com>
* gas/config/tc-arm.c (do_iwmmxt_wldstbh): Don't multiply offset
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 4a777ed825c..de564e20385 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -2893,6 +2893,16 @@ pc-relative or some form of GOT-indirect relocation. */
/* 31-bit PC relative address. */
BFD_RELOC_ARM_PREL31,
+/* Low and High halfword relocations for MOVW and MOVT instructions. */
+ BFD_RELOC_ARM_MOVW,
+ BFD_RELOC_ARM_MOVT,
+ BFD_RELOC_ARM_MOVW_PCREL,
+ BFD_RELOC_ARM_MOVT_PCREL,
+ BFD_RELOC_ARM_THUMB_MOVW,
+ BFD_RELOC_ARM_THUMB_MOVT,
+ BFD_RELOC_ARM_THUMB_MOVW_PCREL,
+ BFD_RELOC_ARM_THUMB_MOVT_PCREL,
+
/* Relocations for setting up GOTs and PLTs for shared libraries. */
BFD_RELOC_ARM_JUMP_SLOT,
BFD_RELOC_ARM_GLOB_DAT,
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index f64f5d6feee..b3500017865 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -1366,6 +1366,14 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
{BFD_RELOC_ARM_TLS_LE32, R_ARM_TLS_LE32},
{BFD_RELOC_VTABLE_INHERIT, R_ARM_GNU_VTINHERIT},
{BFD_RELOC_VTABLE_ENTRY, R_ARM_GNU_VTENTRY},
+ {BFD_RELOC_ARM_MOVW, R_ARM_MOVW_ABS_NC},
+ {BFD_RELOC_ARM_MOVT, R_ARM_MOVT_ABS},
+ {BFD_RELOC_ARM_MOVW_PCREL, R_ARM_MOVW_PREL_NC},
+ {BFD_RELOC_ARM_MOVT_PCREL, R_ARM_MOVT_PREL},
+ {BFD_RELOC_ARM_THUMB_MOVW, R_ARM_THM_MOVW_ABS_NC},
+ {BFD_RELOC_ARM_THUMB_MOVT, R_ARM_THM_MOVT_ABS},
+ {BFD_RELOC_ARM_THUMB_MOVW_PCREL, R_ARM_THM_MOVW_PREL_NC},
+ {BFD_RELOC_ARM_THUMB_MOVT_PCREL, R_ARM_THM_MOVT_PREL},
};
static reloc_howto_type *
@@ -4080,6 +4088,76 @@ elf32_arm_final_link_relocate (reloc_howto_type * howto,
}
return bfd_reloc_ok;
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_MOVT_ABS:
+ case R_ARM_MOVW_PREL_NC:
+ case R_ARM_MOVT_PREL:
+ {
+ bfd_vma insn = bfd_get_32 (input_bfd, hit_data);
+
+ if (globals->use_rel)
+ {
+ 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)
+ value >>= 16;
+
+ insn &= 0xfff0f000;
+ insn |= value & 0xfff;
+ insn |= (value & 0xf000) << 4;
+ bfd_put_32 (input_bfd, insn, hit_data);
+ }
+ return bfd_reloc_ok;
+
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ case R_ARM_THM_MOVW_PREL_NC:
+ case R_ARM_THM_MOVT_PREL:
+ {
+ bfd_vma insn;
+
+ insn = bfd_get_16 (input_bfd, hit_data) << 16;
+ insn |= bfd_get_16 (input_bfd, hit_data + 2);
+
+ if (globals->use_rel)
+ {
+ addend = ((insn >> 4) & 0xf000)
+ | ((insn >> 15) & 0x0800)
+ | ((insn >> 4) & 0x0700)
+ | (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)
+ value >>= 16;
+
+ insn &= 0xfbf08f00;
+ insn |= (value & 0xf000) << 4;
+ insn |= (value & 0x0800) << 15;
+ insn |= (value & 0x0700) << 4;
+ insn |= (value & 0x00ff);
+
+ bfd_put_16 (input_bfd, insn >> 16, hit_data);
+ bfd_put_16 (input_bfd, insn & 0xffff, hit_data + 2);
+ }
+ return bfd_reloc_ok;
+
default:
return bfd_reloc_notsupported;
}
@@ -5651,6 +5729,14 @@ elf32_arm_gc_sweep_hook (bfd * abfd,
case R_ARM_JUMP24:
case R_ARM_PREL31:
case R_ARM_THM_CALL:
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_MOVT_ABS:
+ case R_ARM_MOVW_PREL_NC:
+ case R_ARM_MOVT_PREL:
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ case R_ARM_THM_MOVW_PREL_NC:
+ case R_ARM_THM_MOVT_PREL:
/* Should the interworking branches be here also? */
if (h != NULL)
@@ -5861,6 +5947,14 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
case R_ARM_JUMP24:
case R_ARM_PREL31:
case R_ARM_THM_CALL:
+ case R_ARM_MOVW_ABS_NC:
+ case R_ARM_MOVT_ABS:
+ case R_ARM_MOVW_PREL_NC:
+ case R_ARM_MOVT_PREL:
+ case R_ARM_THM_MOVW_ABS_NC:
+ case R_ARM_THM_MOVT_ABS:
+ case R_ARM_THM_MOVW_PREL_NC:
+ case R_ARM_THM_MOVT_PREL:
/* Should the interworking branches be listed here? */
if (h != NULL)
{
@@ -5877,12 +5971,7 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info,
refers to is in a different object. We can't tell for
sure yet, because something later might force the
symbol local. */
- if (r_type == R_ARM_PC24
- || r_type == R_ARM_CALL
- || r_type == R_ARM_JUMP24
- || r_type == R_ARM_PREL31
- || r_type == R_ARM_PLT32
- || r_type == R_ARM_THM_CALL)
+ if (r_type != R_ARM_ABS32 && r_type != R_ARM_REL32)
h->needs_plt = 1;
/* If we create a PLT entry, this relocation will reference
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 6d48036f823..7e61f364d09 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1198,6 +1198,14 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_ARM_SBREL32",
"BFD_RELOC_ARM_TARGET2",
"BFD_RELOC_ARM_PREL31",
+ "BFD_RELOC_ARM_MOVW",
+ "BFD_RELOC_ARM_MOVT",
+ "BFD_RELOC_ARM_MOVW_PCREL",
+ "BFD_RELOC_ARM_MOVT_PCREL",
+ "BFD_RELOC_ARM_THUMB_MOVW",
+ "BFD_RELOC_ARM_THUMB_MOVT",
+ "BFD_RELOC_ARM_THUMB_MOVW_PCREL",
+ "BFD_RELOC_ARM_THUMB_MOVT_PCREL",
"BFD_RELOC_ARM_JUMP_SLOT",
"BFD_RELOC_ARM_GLOB_DAT",
"BFD_RELOC_ARM_GOT32",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 31314e7246f..e7f9aed7656 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2683,6 +2683,24 @@ ENUM
BFD_RELOC_ARM_PREL31
ENUMDOC
31-bit PC relative address.
+ENUM
+ BFD_RELOC_ARM_MOVW
+ENUMX
+ BFD_RELOC_ARM_MOVT
+ENUMX
+ BFD_RELOC_ARM_MOVW_PCREL
+ENUMX
+ BFD_RELOC_ARM_MOVT_PCREL
+ENUMX
+ BFD_RELOC_ARM_THUMB_MOVW
+ENUMX
+ BFD_RELOC_ARM_THUMB_MOVT
+ENUMX
+ BFD_RELOC_ARM_THUMB_MOVW_PCREL
+ENUMX
+ BFD_RELOC_ARM_THUMB_MOVT_PCREL
+ENUMDOC
+ Low and High halfword relocations for MOVW and MOVT instructions.
ENUM
BFD_RELOC_ARM_JUMP_SLOT