OSDN Git Service

2006-05-11 Paul Brook <paul@codesourcery.com>
authorPaul Brook <paul@codesourcery.com>
Thu, 11 May 2006 15:17:34 +0000 (15:17 +0000)
committerPaul Brook <paul@codesourcery.com>
Thu, 11 May 2006 15:17:34 +0000 (15:17 +0000)
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.
* reloc.c: Ditto.
* bfd-in2.h: Regenerate.
* libbfd.h: Regenerate.
* 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.
* doc/c-arm.texi: Document relocation operators
ld/testsuite/
* ld-arm/arm-elf.exp: Add arm-movwt.
* ld-arm/arm-movwt.d: New test.
* ld-arm/arm-movwt.s: New test.
* ld-arm/arm.ld: Add .far.

bfd/ChangeLog
bfd/bfd-in2.h
bfd/elf32-arm.c
bfd/libbfd.h
bfd/reloc.c

index a95fd4f..9f9ba30 100644 (file)
@@ -1,3 +1,13 @@
+2006-05-11  Paul Brook  <paul@codesourcery.com>
+
+       * 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.
+       * reloc.c: Ditto.
+       * bfd-in2.h: Regenerate.
+       * libbfd.h: Regenerate.
+       * libcoff.h: Regenerate.
+
 2006-05-11  Mike Bland  <mbland@google.com>
 
        * elf.c (_bfd_elf_init_private_section_data): Don't change
index 94118cc..5ba74d2 100644 (file)
@@ -2897,6 +2897,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,
index 3b4152a..e0a5abe 100644 (file)
@@ -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
index 6cbef48..34b0f4f 100644 (file)
@@ -1208,6 +1208,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",
index f1d09a5..6adc7fb 100644 (file)
@@ -2701,6 +2701,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