[ARM] Add support for thumb1 pcrop relocations.
authorMickael Guene <mickael.guene@st.com>
Wed, 16 Dec 2015 09:09:05 +0000 (10:09 +0100)
committerChristophe Lyon <christophe.lyon@linaro.org>
Wed, 16 Dec 2015 09:19:51 +0000 (10:19 +0100)
To support thumb1 execute-only code we need to support four new
relocations (R_ARM_THM_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G1_NC,
R_ARM_THM_ALU_ABS_G2_NC and  R_ARM_THM_ALU_ABS_G3_NC).
These relocations allow the static linker to finalize construction
of symbol address.
Typical sequence of code to get address of the symbol foo is then
the following :
movs r3, #:upper8_15:#foo
lsls r3, #8
adds r3, #:upper0_7:#foo
lsls r3, #8
adds r3, #:lower8_15:#foo
lsls r3, #8
adds r3, #:lower0_7:#foo
This will give following sequence of text and relocations after
assembly :
   4: 2300       movs r3, #0
4: R_ARM_THM_ALU_ABS_G3_NC foo
   6: 021b       lsls r3, r3, #8
   8: 3300       adds r3, #0
8: R_ARM_THM_ALU_ABS_G2_NC foo
   a: 021b       lsls r3, r3, #8
   c: 3300       adds r3, #0
c: R_ARM_THM_ALU_ABS_G1_NC foo
   e: 021b       lsls r3, r3, #8
  10: 3300       adds r3, #0
10: R_ARM_THM_ALU_ABS_G0_NC foo

16 files changed:
bfd/bfd-in2.h
bfd/elf32-arm.c
bfd/libbfd.h
bfd/reloc.c
gas/config/tc-arm.c
gas/doc/c-arm.texi
gas/testsuite/gas/arm/adds-thumb1-reloc-local.d [new file with mode: 0644]
gas/testsuite/gas/arm/adds-thumb1-reloc-local.s [new file with mode: 0644]
gas/testsuite/gas/arm/movs-thumb1-reloc-local.d [new file with mode: 0644]
gas/testsuite/gas/arm/movs-thumb1-reloc-local.s [new file with mode: 0644]
include/elf/arm.h
ld/testsuite/ld-arm/arm-elf.exp
ld/testsuite/ld-arm/thumb1-adds.d [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-adds.s [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-movs.d [new file with mode: 0644]
ld/testsuite/ld-arm/thumb1-movs.s [new file with mode: 0644]

index 606d11b73c783ae54728e7f9f2fd90c00f7617b7..39eb19a8edf2e063b9c0f438f8fd22406cad30b1 100644 (file)
@@ -3516,6 +3516,12 @@ pc-relative or some form of GOT-indirect relocation.  */
 /* ARM support for STT_GNU_IFUNC.  */
   BFD_RELOC_ARM_IRELATIVE,
 
+/* Thumb1 relocations to support execute-only code.  */
+  BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,
+  BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,
+  BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,
+  BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,
+
 /* These relocs are only used within the ARM assembler.  They are not
 (at present) written to any object files.  */
   BFD_RELOC_ARM_IMMEDIATE,
index 49dfc5338e45fd1df518cc8781e918444dc1831e..49d6469fc3c1bcd2e99a5d80e923ba56ef08eb2b 100644 (file)
@@ -1689,6 +1689,60 @@ static reloc_howto_type elf32_arm_howto_table_1[] =
         0x00000000,            /* src_mask */
         0x00000000,            /* dst_mask */
         FALSE),                /* pcrel_offset */
+  EMPTY_HOWTO (130),
+  EMPTY_HOWTO (131),
+  HOWTO (R_ARM_THM_ALU_ABS_G0_NC,/* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_bitfield,/* complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_ARM_THM_ALU_ABS_G0_NC",/* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x00000000,            /* src_mask.  */
+        0x00000000,            /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+  HOWTO (R_ARM_THM_ALU_ABS_G1_NC,/* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_bitfield,/* complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_ARM_THM_ALU_ABS_G1_NC",/* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x00000000,            /* src_mask.  */
+        0x00000000,            /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+  HOWTO (R_ARM_THM_ALU_ABS_G2_NC,/* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_bitfield,/* complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_ARM_THM_ALU_ABS_G2_NC",/* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x00000000,            /* src_mask.  */
+        0x00000000,            /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
+  HOWTO (R_ARM_THM_ALU_ABS_G3_NC,/* type.  */
+        0,                     /* rightshift.  */
+        1,                     /* size (0 = byte, 1 = short, 2 = long).  */
+        16,                    /* bitsize.  */
+        FALSE,                 /* pc_relative.  */
+        0,                     /* bitpos.  */
+        complain_overflow_bitfield,/* complain_on_overflow.  */
+        bfd_elf_generic_reloc, /* special_function.  */
+        "R_ARM_THM_ALU_ABS_G3_NC",/* name.  */
+        FALSE,                 /* partial_inplace.  */
+        0x00000000,            /* src_mask.  */
+        0x00000000,            /* dst_mask.  */
+        FALSE),                /* pcrel_offset.  */
 };
 
 /* 160 onwards: */
@@ -1889,7 +1943,11 @@ static const struct elf32_arm_reloc_map elf32_arm_reloc_map[] =
     {BFD_RELOC_ARM_LDC_SB_G0, R_ARM_LDC_SB_G0},
     {BFD_RELOC_ARM_LDC_SB_G1, R_ARM_LDC_SB_G1},
     {BFD_RELOC_ARM_LDC_SB_G2, R_ARM_LDC_SB_G2},
-    {BFD_RELOC_ARM_V4BX,            R_ARM_V4BX}
+    {BFD_RELOC_ARM_V4BX,            R_ARM_V4BX},
+    {BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC, R_ARM_THM_ALU_ABS_G3_NC},
+    {BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC, R_ARM_THM_ALU_ABS_G2_NC},
+    {BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC, R_ARM_THM_ALU_ABS_G1_NC},
+    {BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC, R_ARM_THM_ALU_ABS_G0_NC}
   };
 
 static reloc_howto_type *
@@ -11023,6 +11081,33 @@ elf32_arm_final_link_relocate (reloc_howto_type *           howto,
       }
       return bfd_reloc_ok;
 
+    case R_ARM_THM_ALU_ABS_G0_NC:
+    case R_ARM_THM_ALU_ABS_G1_NC:
+    case R_ARM_THM_ALU_ABS_G2_NC:
+    case R_ARM_THM_ALU_ABS_G3_NC:
+       {
+           const int shift_array[4] = {0, 8, 16, 24};
+           bfd_vma insn = bfd_get_16 (input_bfd, hit_data);
+           bfd_vma addr = value;
+           int shift = shift_array[r_type - R_ARM_THM_ALU_ABS_G0_NC];
+
+           /* Compute address.  */
+           if (globals->use_rel)
+               signed_addend = insn & 0xff;
+           addr += signed_addend;
+           if (branch_type == ST_BRANCH_TO_THUMB)
+               addr |= 1;
+           /* Clean imm8 insn.  */
+           insn &= 0xff00;
+           /* And update with correct part of address.  */
+           insn |= (addr >> shift) & 0xff;
+           /* Update insn.  */
+           bfd_put_16 (input_bfd, insn, hit_data);
+       }
+
+       *unresolved_reloc_p = FALSE;
+       return bfd_reloc_ok;
+
     default:
       return bfd_reloc_notsupported;
     }
index 1c93c91c656e34f3b46172d8e50c85a0bc4e5b3c..8765bee2dc6619e68fb8ed3e3dfde48705b1545a 100644 (file)
@@ -1545,6 +1545,10 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_ARM_LDC_SB_G2",
   "BFD_RELOC_ARM_V4BX",
   "BFD_RELOC_ARM_IRELATIVE",
+  "BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC",
+  "BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC",
+  "BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC",
+  "BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC",
   "BFD_RELOC_ARM_IMMEDIATE",
   "BFD_RELOC_ARM_ADRL_IMMEDIATE",
   "BFD_RELOC_ARM_T32_IMMEDIATE",
index 593e7c71011a6c9fbbac61c3928d4a649f9feffe..869503c49c8b5f7b382c41ab60cb653ade82b1a5 100644 (file)
@@ -3271,6 +3271,17 @@ ENUM
 ENUMDOC
   ARM support for STT_GNU_IFUNC.
 
+ENUM
+  BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+ENUMX
+  BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC
+ENUMX
+  BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC
+ENUMX
+  BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC
+ENUMDOC
+  Thumb1 relocations to support execute-only code.
+
 ENUM
   BFD_RELOC_ARM_IMMEDIATE
 ENUMX
index 8ea1e8d8386bc90da6d33e0bd5718b8d6ea54be6..6f3f93328cf0a4d37fbd8851fb7ea1d1e3a62a0c 100644 (file)
@@ -5273,7 +5273,28 @@ static struct group_reloc_table_entry group_reloc_table[] =
       BFD_RELOC_ARM_ALU_SB_G2,         /* ALU */
       BFD_RELOC_ARM_LDR_SB_G2,         /* LDR */
       BFD_RELOC_ARM_LDRS_SB_G2,                /* LDRS */
-      BFD_RELOC_ARM_LDC_SB_G2 }        };      /* LDC */
+      BFD_RELOC_ARM_LDC_SB_G2 },       /* LDC */
+    /* Absolute thumb alu relocations.  */
+    { "lower0_7",
+      BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC,/* ALU.  */
+      0,                               /* LDR.  */
+      0,                               /* LDRS.  */
+      0 },                             /* LDC.  */
+    { "lower8_15",
+      BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC,/* ALU.  */
+      0,                               /* LDR.  */
+      0,                               /* LDRS.  */
+      0 },                             /* LDC.  */
+    { "upper0_7",
+      BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC,/* ALU.  */
+      0,                               /* LDR.  */
+      0,                               /* LDRS.  */
+      0 },                             /* LDC.  */
+    { "upper8_15",
+      BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC,/* ALU.  */
+      0,                               /* LDR.  */
+      0,                               /* LDRS.  */
+      0 } };                           /* LDC.  */
 
 /* Given the address of a pointer pointing to the textual name of a group
    relocation as may appear in assembler source, attempt to find its details
@@ -10394,7 +10415,9 @@ do_t_add_sub (void)
                {
                  inst.instruction = THUMB_OP16(opcode);
                  inst.instruction |= (Rd << 4) | Rs;
-                 inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
+                 if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+                     || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
+                   inst.reloc.type = BFD_RELOC_ARM_THUMB_ADD;
                  if (inst.size_req != 2)
                    inst.relax = opcode;
                }
@@ -11745,9 +11768,13 @@ do_t_mov_cmp (void)
              inst.instruction = THUMB_OP16 (opcode);
              inst.instruction |= Rn << 8;
              if (inst.size_req == 2)
-               inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
+               {
+                 if (inst.reloc.type < BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+                     || inst.reloc.type > BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
+                   inst.reloc.type = BFD_RELOC_ARM_THUMB_IMM;
+               }
              else
-               inst.relax = opcode;
+                 inst.relax = opcode;
            }
          else
            {
@@ -18608,7 +18635,7 @@ static const struct asm_opcode insns[] =
   CL("cmnp",   170f000,           2, (RR, SH),      cmp),
 
  tCE("mov",    1a00000, _mov,     2, (RR, SH),      mov,  t_mov_cmp),
- tC3("movs",   1b00000, _movs,    2, (RR, SH),      mov,  t_mov_cmp),
+ tC3("movs",   1b00000, _movs,    2, (RR, SHG),     mov,  t_mov_cmp),
  tCE("mvn",    1e00000, _mvn,     2, (RR, SH),      mov,  t_mvn_tst),
  tC3("mvns",   1f00000, _mvns,    2, (RR, SH),      mov,  t_mvn_tst),
 
@@ -23242,6 +23269,68 @@ md_apply_fix (fixS *   fixP,
        }
       return;
 
+   case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
+   case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
+   case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
+   case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
+      gas_assert (!fixP->fx_done);
+      {
+       bfd_vma insn;
+       bfd_boolean is_mov;
+       bfd_vma encoded_addend = value;
+
+       /* Check that addend can be encoded in instruction.  */
+       if (!seg->use_rela_p && (value < 0 || value > 255))
+         as_bad_where (fixP->fx_file, fixP->fx_line,
+                       _("the offset 0x%08lX is not representable"),
+                       (unsigned long) encoded_addend);
+
+       /* Extract the instruction.  */
+       insn = md_chars_to_number (buf, THUMB_SIZE);
+       is_mov = (insn & 0xf800) == 0x2000;
+
+       /* Encode insn.  */
+       if (is_mov)
+         {
+           if (!seg->use_rela_p)
+             insn |= encoded_addend;
+         }
+       else
+         {
+           int rd, rs;
+
+           /* Extract the instruction.  */
+            /* Encoding is the following
+               0x8000  SUB
+               0x00F0  Rd
+               0x000F  Rs
+            */
+            /* The following conditions must be true :
+               - ADD
+               - Rd == Rs
+               - Rd <= 7
+            */
+           rd = (insn >> 4) & 0xf;
+           rs = insn & 0xf;
+           if ((insn & 0x8000) || (rd != rs) || rd > 7)
+             as_bad_where (fixP->fx_file, fixP->fx_line,
+                       _("Unable to process relocation for thumb opcode: %lx"),
+                       (unsigned long) insn);
+
+           /* Encode as ADD immediate8 thumb 1 code.  */
+           insn = 0x3000 | (rd << 8);
+
+           /* Place the encoded addend into the first 8 bits of the
+              instruction.  */
+           if (!seg->use_rela_p)
+             insn |= encoded_addend;
+         }
+
+       /* Update the instruction.  */
+       md_number_to_chars (buf, insn, THUMB_SIZE);
+      }
+      break;
+
    case BFD_RELOC_ARM_ALU_PC_G0_NC:
    case BFD_RELOC_ARM_ALU_PC_G0:
    case BFD_RELOC_ARM_ALU_PC_G1_NC:
@@ -23579,6 +23668,10 @@ tc_gen_reloc (asection *section, fixS *fixp)
     case BFD_RELOC_ARM_LDC_SB_G1:
     case BFD_RELOC_ARM_LDC_SB_G2:
     case BFD_RELOC_ARM_V4BX:
+    case BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC:
+    case BFD_RELOC_ARM_THUMB_ALU_ABS_G1_NC:
+    case BFD_RELOC_ARM_THUMB_ALU_ABS_G2_NC:
+    case BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC:
       code = fixp->fx_r_type;
       break;
 
@@ -23881,6 +23974,12 @@ arm_fix_adjustable (fixS * fixP)
       || fixP->fx_r_type == BFD_RELOC_ARM_THUMB_MOVT_PCREL)
     return FALSE;
 
+  /* BFD_RELOC_ARM_THUMB_ALU_ABS_Gx_NC relocations have VERY limited
+     offsets, so keep these symbols.  */
+  if (fixP->fx_r_type >= BFD_RELOC_ARM_THUMB_ALU_ABS_G0_NC
+      && fixP->fx_r_type <= BFD_RELOC_ARM_THUMB_ALU_ABS_G3_NC)
+    return FALSE;
+
   return TRUE;
 }
 #endif /* defined (OBJ_ELF) || defined (OBJ_COFF) */
index ee26e6dc0a11f35b23550ae52e318785257b5cfc..091fc93738c4eada2c6587f6708e32175bf08709 100644 (file)
@@ -537,6 +537,22 @@ respectively.  For example to load the 32-bit address of foo into r0:
         MOVT r0, #:upper16:foo
 @end smallexample
 
+Relocations @samp{R_ARM_THM_ALU_ABS_G0_NC}, @samp{R_ARM_THM_ALU_ABS_G1_NC},
+@samp{R_ARM_THM_ALU_ABS_G2_NC} and @samp{R_ARM_THM_ALU_ABS_G3_NC} can be
+generated by prefixing the value with @samp{#:lower0_7:#},
+@samp{#:lower8_15:#}, @samp{#:upper0_7:#} and @samp{#:upper8_15:#}
+respectively.  For example to load the 32-bit address of foo into r0:
+
+@smallexample
+        MOVS r0, #:upper8_15:#foo
+        LSLS r0, r0, #8
+        ADDS r0, #:upper0_7:#foo
+        LSLS r0, r0, #8
+        ADDS r0, #:lower8_15:#foo
+        LSLS r0, r0, #8
+        ADDS r0, #:lower0_7:#foo
+@end smallexample
+
 @node ARM-Neon-Alignment
 @subsection NEON Alignment Specifiers
 
diff --git a/gas/testsuite/gas/arm/adds-thumb1-reloc-local.d b/gas/testsuite/gas/arm/adds-thumb1-reloc-local.d
new file mode 100644 (file)
index 0000000..190f0ab
--- /dev/null
@@ -0,0 +1,16 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+#name: ADDS relocations against local symbols for armv6s-m
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> 3000        adds    r0, #0
+                       0: R_ARM_THM_ALU_ABS_G3_NC      bar
+0[0-9a-f]+ <[^>]+> 3000        adds    r0, #0
+                       2: R_ARM_THM_ALU_ABS_G2_NC      bar
+0[0-9a-f]+ <[^>]+> 3000        adds    r0, #0
+                       4: R_ARM_THM_ALU_ABS_G1_NC      bar
+0[0-9a-f]+ <[^>]+> 3000        adds    r0, #0
+                       6: R_ARM_THM_ALU_ABS_G0_NC      bar
+#...
diff --git a/gas/testsuite/gas/arm/adds-thumb1-reloc-local.s b/gas/testsuite/gas/arm/adds-thumb1-reloc-local.s
new file mode 100644 (file)
index 0000000..4e1ebcc
--- /dev/null
@@ -0,0 +1,13 @@
+.arch armv6s-m
+.text
+.syntax unified
+.thumb
+foo:
+adds r0, #:upper8_15:#bar
+adds r0, #:upper0_7:#bar
+adds r0, #:lower8_15:#bar
+adds r0, #:lower0_7:#bar
+
+.space 0x10000
+
+bar:
diff --git a/gas/testsuite/gas/arm/movs-thumb1-reloc-local.d b/gas/testsuite/gas/arm/movs-thumb1-reloc-local.d
new file mode 100644 (file)
index 0000000..3febca3
--- /dev/null
@@ -0,0 +1,16 @@
+#objdump: -dr --prefix-addresses --show-raw-insn
+#skip: *-*-*coff *-*-pe *-*-wince *-*-*aout* *-*-netbsd *-*-riscix*
+#name: MOVS relocations against local symbols for armv6s-m
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> 2000        movs    r0, #0
+                       0: R_ARM_THM_ALU_ABS_G3_NC      bar
+0[0-9a-f]+ <[^>]+> 2000        movs    r0, #0
+                       2: R_ARM_THM_ALU_ABS_G2_NC      bar
+0[0-9a-f]+ <[^>]+> 2000        movs    r0, #0
+                       4: R_ARM_THM_ALU_ABS_G1_NC      bar
+0[0-9a-f]+ <[^>]+> 2000        movs    r0, #0
+                       6: R_ARM_THM_ALU_ABS_G0_NC      bar
+#...
diff --git a/gas/testsuite/gas/arm/movs-thumb1-reloc-local.s b/gas/testsuite/gas/arm/movs-thumb1-reloc-local.s
new file mode 100644 (file)
index 0000000..c0fc383
--- /dev/null
@@ -0,0 +1,13 @@
+.arch armv6s-m
+.text
+.syntax unified
+.thumb
+foo:
+movs r0, #:upper8_15:#bar
+movs r0, #:upper0_7:#bar
+movs r0, #:lower8_15:#bar
+movs r0, #:lower0_7:#bar
+
+.space 0x10000
+
+bar:
index c64e7886e9266b4084e11a04b2e60636dda62bd5..5691118ea7255b21b3131aabd99bd509a3892f50 100644 (file)
@@ -230,6 +230,11 @@ START_RELOC_NUMBERS (elf_arm_reloc_type)
   RELOC_NUMBER (R_ARM_ME_TOO,          128)   /* obsolete */
   RELOC_NUMBER (R_ARM_THM_TLS_DESCSEQ  ,129)
 
+  RELOC_NUMBER (R_ARM_THM_ALU_ABS_G0_NC,132)
+  RELOC_NUMBER (R_ARM_THM_ALU_ABS_G1_NC,133)
+  RELOC_NUMBER (R_ARM_THM_ALU_ABS_G2_NC,134)
+  RELOC_NUMBER (R_ARM_THM_ALU_ABS_G3_NC,135)
+
   RELOC_NUMBER (R_ARM_IRELATIVE,       160)
 
   /* Extensions?  R=read-only?  */
index 1d9b1c83f4b8f961d0397672ccca705d016e3e52..23c9e57e48c61a8de0fcae6ffaad7061bc674bf9 100644 (file)
@@ -223,6 +223,12 @@ set armelftests_common {
      "" {pcrel-shared.s}
      {{readelf -dr pcrel-shared.rd}}
      "pcrel-shared.so"}
+    {"MOVS thumb1 relocations" "-static -T arm.ld" "" "" {thumb1-movs.s}
+     {{objdump -dw thumb1-movs.d}}
+     "thumb1-movs"}
+    {"ADDS thumb1 relocations" "-static -T arm.ld" "" "" {thumb1-adds.s}
+     {{objdump -dw thumb1-adds.d}}
+     "thumb1-adds"}
 }
 
 set armelftests_nonacl {
diff --git a/ld/testsuite/ld-arm/thumb1-adds.d b/ld/testsuite/ld-arm/thumb1-adds.d
new file mode 100644 (file)
index 0000000..68ef68e
--- /dev/null
@@ -0,0 +1,38 @@
+
+.*:     file format.*
+
+Disassembly of section .text:
+
+00008000 <[^>]*>:
+    8000:      3012            adds    r0, #18
+    8002:      3134            adds    r1, #52 ; 0x34
+    8004:      3280            adds    r2, #128        ; 0x80
+    8006:      3301            adds    r3, #1
+    8008:      3401            adds    r4, #1
+    800a:      3500            adds    r5, #0
+    800c:      3600            adds    r6, #0
+    800e:      3700            adds    r7, #0
+
+00008010 <[^>]*>:
+    8010:      3012            adds    r0, #18
+    8012:      3100            adds    r1, #0
+    8014:      3200            adds    r2, #0
+    8016:      33ca            adds    r3, #202        ; 0xca
+    8018:      3700            adds    r7, #0
+    801a:      3634            adds    r6, #52 ; 0x34
+    801c:      3581            adds    r5, #129        ; 0x81
+    801e:      3423            adds    r4, #35 ; 0x23
+
+00008020 <[^>]*>:
+    8020:      01              .byte   0x01
+
+00008021 <[^>]*>:
+    8021:      02              .byte   0x02
+
+Disassembly of section .far:
+
+12340000 <[^>]*>:
+12340000:      3000            adds    r0, #0
+12340002:      3100            adds    r1, #0
+12340004:      3200            adds    r2, #0
+12340006:      3301            adds    r3, #1
diff --git a/ld/testsuite/ld-arm/thumb1-adds.s b/ld/testsuite/ld-arm/thumb1-adds.s
new file mode 100644 (file)
index 0000000..3dde045
--- /dev/null
@@ -0,0 +1,43 @@
+       .text
+       .arch armv6s-m
+       .syntax unified
+       .global _start
+       .thumb_func
+       .type   _start, %function
+_start:
+       .thumb_func
+       .type   thumb1, %function
+thumb1:
+       adds r0, #:upper8_15:#thumb3
+       adds r1, #:upper0_7:#thumb3
+       adds r2, #:lower8_15:#thumb1
+       adds r3, #:lower0_7:#thumb1
+       adds r4, #:lower0_7:#thumb3
+       adds r5, #:lower8_15:#thumb3
+       adds r6, #:upper0_7:#thumb1
+       adds r7, #:upper8_15:#thumb1
+       .thumb_func
+       .type   thumb2, %function
+thumb2:
+       adds r0, #:upper8_15:#thumb3
+       adds r1, #:upper0_7:#(var2 + 1)
+       adds r2, #:lower8_15:#(thumb3 + 255)
+       adds r3, #:lower0_7:#(var1 + 0xaa)
+       adds r7, #:upper8_15:#var1 + 4
+       adds r6, #:upper0_7:#thumb3
+       adds r5, #:lower8_15:#var2 + 0xff
+       adds r4, #:lower0_7:#var2 - (-2)
+var1:
+       .byte 1
+var2:
+       .byte 2
+
+       .section .far, "ax", %progbits
+       .thumb_func
+       .type   thumb3, %function
+thumb3:
+       adds r0, #:upper8_15:#thumb1
+       adds r1, #:upper0_7:#thumb2
+       adds r2, #:lower8_15:#thumb3
+       adds r3, #:lower0_7:#thumb1
+
diff --git a/ld/testsuite/ld-arm/thumb1-movs.d b/ld/testsuite/ld-arm/thumb1-movs.d
new file mode 100644 (file)
index 0000000..6a72bc1
--- /dev/null
@@ -0,0 +1,38 @@
+
+.*:     file format.*
+
+Disassembly of section .text:
+
+00008000 <[^>]*>:
+    8000:      2012            movs    r0, #18
+    8002:      2134            movs    r1, #52 ; 0x34
+    8004:      2280            movs    r2, #128        ; 0x80
+    8006:      2301            movs    r3, #1
+    8008:      2401            movs    r4, #1
+    800a:      2500            movs    r5, #0
+    800c:      2600            movs    r6, #0
+    800e:      2700            movs    r7, #0
+
+00008010 <[^>]*>:
+    8010:      2012            movs    r0, #18
+    8012:      2100            movs    r1, #0
+    8014:      2281            movs    r2, #129        ; 0x81
+    8016:      2320            movs    r3, #32
+    8018:      2700            movs    r7, #0
+    801a:      2600            movs    r6, #0
+    801c:      2581            movs    r5, #129        ; 0x81
+    801e:      2422            movs    r4, #34 ; 0x22
+
+00008020 <[^>]*>:
+    8020:      01              .byte   0x01
+
+00008021 <[^>]*>:
+    8021:      02              .byte   0x02
+
+Disassembly of section .far:
+
+12340000 <[^>]*>:
+12340000:      2000            movs    r0, #0
+12340002:      2100            movs    r1, #0
+12340004:      2200            movs    r2, #0
+12340006:      2301            movs    r3, #1
diff --git a/ld/testsuite/ld-arm/thumb1-movs.s b/ld/testsuite/ld-arm/thumb1-movs.s
new file mode 100644 (file)
index 0000000..80acfd5
--- /dev/null
@@ -0,0 +1,43 @@
+       .text
+       .arch armv6s-m
+       .syntax unified
+       .global _start
+       .thumb_func
+       .type   _start, %function
+_start:
+       .thumb_func
+       .type   thumb1, %function
+thumb1:
+       movs r0, #:upper8_15:#thumb3
+       movs r1, #:upper0_7:#thumb3
+       movs r2, #:lower8_15:#thumb1
+       movs r3, #:lower0_7:#thumb1
+       movs r4, #:lower0_7:#thumb3
+       movs r5, #:lower8_15:#thumb3
+       movs r6, #:upper0_7:#thumb1
+       movs r7, #:upper8_15:#thumb1
+       .thumb_func
+       .type   thumb2, %function
+thumb2:
+       movs r0, #:upper8_15:#(thumb3 + 0)
+       movs r1, #:upper0_7:#(thumb2 + 1)
+       movs r2, #:lower8_15:#(var1 + 255)
+       movs r3, #:lower0_7:#var1
+       movs r7, #:upper8_15:#var1 + 4
+       movs r6, #:upper0_7:#var2
+       movs r5, #:lower8_15:#var2 + 0xff
+       movs r4, #:lower0_7:#var2 - (-1)
+var1:
+       .byte 1
+var2:
+       .byte 2
+
+       .section .far, "ax", %progbits
+       .thumb_func
+       .type   thumb3, %function
+thumb3:
+       movs r0, #:upper8_15:#thumb1
+       movs r1, #:upper0_7:#thumb2
+       movs r2, #:lower8_15:#thumb3
+       movs r3, #:lower0_7:#thumb1
+