This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH v2] ARM: Add support for thumb1 PCROP relocations.


Hi all,

This is second version for a patch proposal that implements the new
relocations needed to support execute-only code segment for thumb1
sequences.

Changes since v1:

 * Take into account Nick's remarks.
 * Take into account Ramana's remarks. Change gas directive names from
low_low, low_high, high_low and high_high to lower0_7, lower8_15,
upper0_7 and upper8_15 respectively. Add documentation about these
directives usage.

Changelogs:

include/ChangeLog:

2015-11-17  Mickael Guene <mickael.guene@st.com>

    * elf/arm.h: Add new arm relocations.

bfd/ChangeLog:

2015-11-17  Mickael Guene <mickael.guene@st.com>

    * bfd-in2.h: Regenerate.
    * reloc.c: Add new relocations.
    * libbfd.h (bfd_reloc_code_real_names): Add new relocations display
    names.
    * elf32-arm.c (elf32_arm_howto_table_1): Add HOWTO for new relocations.
    (elf32_arm_reloc_map): Add bfd/arm mapping for new relocations.
    (elf32_arm_final_link_relocate): Implement new relocations resolution.

gas/ChangeLog:

2015-12-07 Mickael Guene <mickael.guene@st.com>

    * doc/c-arm.texi: Add documentation about new directives.

2015-11-17  Mickael Guene <mickael.guene@st.com>

    * config/tc-arm.c (group_reloc_table): Add mapping between gas syntax
    and new relocations.
    (do_t_add_sub): Keep new relocations for add operand.
    (do_t_mov_cmp): Keep new relocations for mov operand.
    (insns): Use 'shifter operand with possible group relocation' operand
    parse code for movs operand.
    (md_apply_fix): Implement mov and add encoding when new relocations
    on them.
    (tc_gen_reloc): Add new relocations.
    (arm_fix_adjustable): Since offset has a limited range ([0:255]) we
    disable adjust_reloc_syms() for new relocations.

gas/testsuite/ChangeLog:

2015-11-17  Mickael Guene <mickael.guene@st.com>

    * gas/arm/adds-thumb1-reloc-local.d: New
    * gas/arm/adds-thumb1-reloc-local.s: New
    * gas/arm/movs-thumb1-reloc-local.d: New
    * gas/arm/movs-thumb1-reloc-local.s: New

ld/testsuite/ChangeLog:

2015-11-17  Mickael Guene <mickael.guene@st.com>

    * ld-arm/arm-elf.exp (armelftests_common): Add new relocations tests.
    * ld-arm/thumb1-adds.d: New
    * ld-arm/thumb1-adds.s: New
    * ld-arm/thumb1-movs.d: New
    * ld-arm/thumb1-movs.s: New
>From 1a33505e8d31cc169b10c7e2dd0dd24a3a207ec8 Mon Sep 17 00:00:00 2001
From: Mickael Guene <mickael.guene@st.com>
Date: Fri, 9 Oct 2015 10:01:33 +0200
Subject: [PATCH]  Add support for thumb1 pcrop relocations.

 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
---
 bfd/bfd-in2.h                                   |   6 ++
 bfd/elf32-arm.c                                 |  87 ++++++++++++++++++-
 bfd/libbfd.h                                    |   4 +
 bfd/reloc.c                                     |  11 +++
 gas/config/tc-arm.c                             | 108 ++++++++++++++++++++++--
 gas/doc/c-arm.texi                              |  16 ++++
 gas/testsuite/gas/arm/adds-thumb1-reloc-local.d |  16 ++++
 gas/testsuite/gas/arm/adds-thumb1-reloc-local.s |  13 +++
 gas/testsuite/gas/arm/movs-thumb1-reloc-local.d |  16 ++++
 gas/testsuite/gas/arm/movs-thumb1-reloc-local.s |  13 +++
 include/elf/arm.h                               |   5 ++
 ld/testsuite/ld-arm/arm-elf.exp                 |   6 ++
 ld/testsuite/ld-arm/thumb1-adds.d               |  38 +++++++++
 ld/testsuite/ld-arm/thumb1-adds.s               |  42 +++++++++
 ld/testsuite/ld-arm/thumb1-movs.d               |  38 +++++++++
 ld/testsuite/ld-arm/thumb1-movs.s               |  42 +++++++++
 16 files changed, 455 insertions(+), 6 deletions(-)
 create mode 100644 gas/testsuite/gas/arm/adds-thumb1-reloc-local.d
 create mode 100644 gas/testsuite/gas/arm/adds-thumb1-reloc-local.s
 create mode 100644 gas/testsuite/gas/arm/movs-thumb1-reloc-local.d
 create mode 100644 gas/testsuite/gas/arm/movs-thumb1-reloc-local.s
 create mode 100644 ld/testsuite/ld-arm/thumb1-adds.d
 create mode 100644 ld/testsuite/ld-arm/thumb1-adds.s
 create mode 100644 ld/testsuite/ld-arm/thumb1-movs.d
 create mode 100644 ld/testsuite/ld-arm/thumb1-movs.s

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index bca5181..77d57f1 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -3469,6 +3469,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,
diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c
index 9fd5720..4be5295 100644
--- a/bfd/elf32-arm.c
+++ b/bfd/elf32-arm.c
@@ -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 *
@@ -10406,6 +10464,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;
     }
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 1c54d0f..84f7244 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -1525,6 +1525,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",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index ba73ef7..55ccfaa 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -3250,6 +3250,17 @@ 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
   BFD_RELOC_ARM_ADRL_IMMEDIATE
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 2ab8bbea..32cec23 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -5305,7 +5305,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
@@ -10234,7 +10255,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;
 		}
@@ -11585,9 +11608,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
 	    {
@@ -18409,7 +18436,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),
 
@@ -22942,6 +22969,67 @@ 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);
+      if (!seg->use_rela_p)
+	{
+	  bfd_vma insn;
+	  bfd_boolean is_mov;
+	  bfd_vma encoded_addend = value;
+
+	  /* Check that addend can be encoded.  */
+	  if (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)
+	    {
+	      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.  */
+	      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:
@@ -23279,6 +23367,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;
 
@@ -23581,6 +23673,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) */
diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi
index 7a3bf85..a37e0c2 100644
--- a/gas/doc/c-arm.texi
+++ b/gas/doc/c-arm.texi
@@ -502,6 +502,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
index 0000000..190f0ab
--- /dev/null
+++ b/gas/testsuite/gas/arm/adds-thumb1-reloc-local.d
@@ -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
index 0000000..4e1ebcc
--- /dev/null
+++ b/gas/testsuite/gas/arm/adds-thumb1-reloc-local.s
@@ -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
index 0000000..3febca3
--- /dev/null
+++ b/gas/testsuite/gas/arm/movs-thumb1-reloc-local.d
@@ -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
index 0000000..c0fc383
--- /dev/null
+++ b/gas/testsuite/gas/arm/movs-thumb1-reloc-local.s
@@ -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:
diff --git a/include/elf/arm.h b/include/elf/arm.h
index 34afdfd..92101c0 100644
--- a/include/elf/arm.h
+++ b/include/elf/arm.h
@@ -231,6 +231,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?  */
diff --git a/ld/testsuite/ld-arm/arm-elf.exp b/ld/testsuite/ld-arm/arm-elf.exp
index 3c8cc68..36bcaae 100644
--- a/ld/testsuite/ld-arm/arm-elf.exp
+++ b/ld/testsuite/ld-arm/arm-elf.exp
@@ -207,6 +207,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
index 0000000..68ef68e
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-adds.d
@@ -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
index 0000000..9d6f7ce
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-adds.s
@@ -0,0 +1,42 @@
+	.text
+	.arch armv6s-m
+	.syntax unified
+	.global	_start
+	.thumb_func
+	.type	_start, %function
+	.type	thumb1, %function
+_start:
+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
index 0000000..6a72bc1
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-movs.d
@@ -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
index 0000000..a488318
--- /dev/null
+++ b/ld/testsuite/ld-arm/thumb1-movs.s
@@ -0,0 +1,42 @@
+	.text
+	.arch armv6s-m
+	.syntax unified
+	.global	_start
+	.thumb_func
+	.type	_start, %function
+	.type	thumb1, %function
+_start:
+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
+
-- 
2.6.2


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]