[1/2,GAS,AARCH64] Add BFD_RELOC_AARCH64_TLSLE_LDST8/16/32/64_TPREL_LO12 support in GAS

Message ID 9d110a02-4943-fc37-3025-2333c222986c@foss.arm.com
State New
Headers show
Series
  • [1/2,GAS,AARCH64] Add BFD_RELOC_AARCH64_TLSLE_LDST8/16/32/64_TPREL_LO12 support in GAS
Related show

Commit Message

Renlin Li March 28, 2018, 2:54 p.m.
Hi all,

This is the first patch to add the following relocation support into binutils.
BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12,
BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC,
BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12,
BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC,
BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12,
BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC,
BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12,
BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC.

Those relocations includes both ip64 and ilp32 variant.

Regard,
Renlin

include/ChangeLog:

     2018-03-28  Renlin Li  <renlin.li@arm.com>

         PR ld/22970
         * elf/aarch64.h: Add relocation number for
         R_AARCH64_P32_TLSLE_LDST16_TPREL_LO12,
         R_AARCH64_P32_TLSLE_LDST16_TPREL_LO12_NC,
         R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12,
         R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12_NC,
         R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12,
         R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12_NC,
         R_AARCH64_P32_TLSLE_LDST8_TPREL_LO12,
         R_AARCH64_P32_TLSLE_LDST8_TPREL_LO12_NC.

bfd/ChangeLog:

2018-03-28  Renlin Li  <renlin.li@arm.com>

         PR ld/22970
	* reloc.c: Add BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12
	BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC,
	BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12,
	BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC,
	BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12,
	BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC,
	BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12,
	BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC,
	BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12,
	BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC.
	* elfnn-aarch64.c (elfNN_aarch64_howto_table): Add table entry for
	TLSLE_LDST16_TPREL_LO12,
	TLSLE_LDST16_TPREL_LO12_NC,
	TLSLE_LDST32_TPREL_LO12,
	TLSLE_LDST32_TPREL_LO12_NC,
	TLSLE_LDST64_TPREL_LO12,
	TLSLE_LDST64_TPREL_LO12_NC,
	TLSLE_LDST8_TPREL_LO12,
	TLSLE_LDST8_TPREL_LO12_NC.
	* bfd-in2.h: Regenerated.
	* libbfd.h: Regenerated.

gas/ChangeLog:

2018-03-28  Renlin Li  <renlin.li@arm.com>

         PR ld/22970
	* config/tc-aarch64.c (reloc_table): Update entry for tprel_lo12 and
	tprel_lo12_nc with pseudo relocations.
	(ldst_lo12_determine_real_reloc_type): Add new relocations support.
	(parse_operands): Handle BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12 and
	BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC pseudo relocations.
	(md_apply_fix): Add handling for new relocation.
	(aarch64_force_relocation): Likewise.
	* testsuite/gas/aarch64/reloc-tprel_lo12-ldst16.d: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12-ldst16.s: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12-ldst32.d: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12-ldst32.s: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12-ldst64.d: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12-ldst64.s: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12-ldst8.d: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12-ldst8.s: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16.d: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16.s: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32.d: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32.s: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64.d: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64.s: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8.d: New.
	* testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8.s: New.
         * testsuite/gas/aarch64/reloc-tprel_lo12-ldst16-ilp32.d: New.
         * testsuite/gas/aarch64/reloc-tprel_lo12-ldst32-ilp32.d: New.
         * testsuite/gas/aarch64/reloc-tprel_lo12-ldst64-ilp32.d: New.
         * testsuite/gas/aarch64/reloc-tprel_lo12-ldst8-ilp32.d: New.
         * testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16-ilp32.d: New.
         * testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32-ilp32.d: New.
         * testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64-ilp32.d: New.
         * testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8-ilp32.d: New.

On 28/03/18 15:52, Renlin Li wrote:
> Hi all,

> 

> This patch is to add the following relocation support into binutils:

> BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12,

> BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC.

> BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12,

> BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC,

> BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12,

> BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC,

> BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12,

> BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC,

> 

> Those relocations includes both ip64 and ilp32 variant.

> Test cases are added.

> 

> This patch will resolve PR22970: https://sourceware.org/bugzilla/show_bug.cgi?id=22970

> 

> Binutils test Okay, Okay to commit?

> 

> Regards,

> Renlin

Patch

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 9742c1ac7fe1c0077b4cb8066d83c9d3c1d9feac..de5f68d6ecfe8762c57ef17ae5925867faeb867f 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6229,6 +6229,34 @@  instructions.  */
 /* AArch64 TLS LOCAL EXEC relocation.  */
   BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC,
 
+/* bit[11:1] of byte offset to module TLS base address, encoded in ldst
+instructions.  */
+  BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12,
+
+/* Similar as BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, but no overflow check.  */
+  BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC,
+
+/* bit[11:2] of byte offset to module TLS base address, encoded in ldst
+instructions.  */
+  BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12,
+
+/* Similar as BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, but no overflow check.  */
+  BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC,
+
+/* bit[11:3] of byte offset to module TLS base address, encoded in ldst
+instructions.  */
+  BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12,
+
+/* Similar as BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, but no overflow check.  */
+  BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC,
+
+/* bit[11:0] of byte offset to module TLS base address, encoded in ldst
+instructions.  */
+  BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12,
+
+/* Similar as BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, but no overflow check.  */
+  BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC,
+
 /* AArch64 TLS DESC relocation.  */
   BFD_RELOC_AARCH64_TLSDESC_LD_PREL19,
 
@@ -6312,6 +6340,14 @@  any object files.  */
 /* Similar as BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12, but no overflow check.  */
   BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC,
 
+/* AArch64 pseudo relocation code for TLS local exec mode.  It's to be
+used internally by the AArch64 assembler and not (currently) written to
+any object files.  */
+  BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12,
+
+/* Similar as BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12, but no overflow check.  */
+  BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC,
+
 /* AArch64 pseudo relocation code to be used internally by the AArch64
 assembler and not (currently) written to any object files.  */
   BFD_RELOC_AARCH64_LD_GOT_LO12_NC,
diff --git a/bfd/elfnn-aarch64.c b/bfd/elfnn-aarch64.c
index c1986b72f2aa1ef63ed841ef4c94259561705ff9..d6a215e8e3643e0a63c6f9cc525d8d00e968fd4e 100644
--- a/bfd/elfnn-aarch64.c
+++ b/bfd/elfnn-aarch64.c
@@ -1635,6 +1635,126 @@  static reloc_howto_type elfNN_aarch64_howto_table[] =
 	 0xfff,			/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 
+  /* LD/ST16: bit[11:1] of byte offset to module TLS base address.  */
+  HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12),	/* type */
+	 1,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 11,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 10,			/* bitpos */
+	 complain_overflow_unsigned,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12),	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x1ffc00,		/* src_mask */
+	 0x1ffc00,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* Same as BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, but no overflow check.  */
+  HOWTO (AARCH64_R (TLSLE_LDST16_TPREL_LO12_NC),	/* type */
+	 1,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 11,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 10,			/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 AARCH64_R_STR (TLSLE_LDST16_TPREL_LO12_NC),	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x1ffc00,		/* src_mask */
+	 0x1ffc00,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* LD/ST32: bit[11:2] of byte offset to module TLS base address.  */
+  HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12),	/* type */
+	 2,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 10,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 10,			/* bitpos */
+	 complain_overflow_unsigned,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12),	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xffc00,		/* src_mask */
+	 0xffc00,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* Same as BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, but no overflow check.  */
+  HOWTO (AARCH64_R (TLSLE_LDST32_TPREL_LO12_NC),	/* type */
+	 2,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 10,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 10,			/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 AARCH64_R_STR (TLSLE_LDST32_TPREL_LO12_NC),	/* name */
+	 FALSE,			/* partial_inplace */
+	 0xffc00,		/* src_mask */
+	 0xffc00,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* LD/ST64: bit[11:3] of byte offset to module TLS base address.  */
+  HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12),	/* type */
+	 3,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 9,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 10,			/* bitpos */
+	 complain_overflow_unsigned,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12),	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x7fc00,		/* src_mask */
+	 0x7fc00,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* Same as BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, but no overflow check.  */
+  HOWTO (AARCH64_R (TLSLE_LDST64_TPREL_LO12_NC),	/* type */
+	 3,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 9,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 10,			/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 AARCH64_R_STR (TLSLE_LDST64_TPREL_LO12_NC),	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x7fc00,		/* src_mask */
+	 0x7fc00,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* LD/ST8: bit[11:0] of byte offset to module TLS base address.  */
+  HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12),	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 12,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 10,			/* bitpos */
+	 complain_overflow_unsigned,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12),	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x3ffc00,		/* src_mask */
+	 0x3ffc00,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
+  /* Same as BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, but no overflow check.  */
+  HOWTO (AARCH64_R (TLSLE_LDST8_TPREL_LO12_NC),	/* type */
+	 0,			/* rightshift */
+	 2,			/* size (0 = byte, 1 = short, 2 = long) */
+	 12,			/* bitsize */
+	 FALSE,			/* pc_relative */
+	 10,			/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 bfd_elf_generic_reloc,	/* special_function */
+	 AARCH64_R_STR (TLSLE_LDST8_TPREL_LO12_NC),	/* name */
+	 FALSE,			/* partial_inplace */
+	 0x3ffc00,		/* src_mask */
+	 0x3ffc00,		/* dst_mask */
+	 FALSE),		/* pcrel_offset */
+
   HOWTO (AARCH64_R (TLSDESC_LD_PREL19),	/* type */
 	 2,			/* rightshift */
 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 0fba5bea3e994f342c0e70ceed8537cef716d3ac..4af1019ca82fe32592b51d754b9f72dfbdc37dce 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -2944,6 +2944,14 @@  static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12",
   "BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12",
   "BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC",
+  "BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12",
+  "BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC",
+  "BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12",
+  "BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC",
+  "BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12",
+  "BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC",
+  "BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12",
+  "BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC",
   "BFD_RELOC_AARCH64_TLSDESC_LD_PREL19",
   "BFD_RELOC_AARCH64_TLSDESC_ADR_PREL21",
   "BFD_RELOC_AARCH64_TLSDESC_ADR_PAGE21",
@@ -2969,6 +2977,8 @@  static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_AARCH64_LDST_LO12",
   "BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12",
   "BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC",
+  "BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12",
+  "BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC",
   "BFD_RELOC_AARCH64_LD_GOT_LO12_NC",
   "BFD_RELOC_AARCH64_TLSIE_LD_GOTTPREL_LO12_NC",
   "BFD_RELOC_AARCH64_TLSDESC_LD_LO12_NC",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 42e35b91ed1f7c0dbb2bb0febba04ea7a2006490..ca1d81ca61fa1617c70d20f1093fb8cbd3945b1a 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -7396,6 +7396,42 @@  ENUM
 ENUMDOC
   AArch64 TLS LOCAL EXEC relocation.
 ENUM
+  BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12
+ENUMDOC
+  bit[11:1] of byte offset to module TLS base address, encoded in ldst
+  instructions.
+ENUM
+  BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC
+ENUMDOC
+  Similar as BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12, but no overflow check.
+ENUM
+  BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12
+ENUMDOC
+  bit[11:2] of byte offset to module TLS base address, encoded in ldst
+  instructions.
+ENUM
+  BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC
+ENUMDOC
+  Similar as BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12, but no overflow check.
+ENUM
+  BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12
+ENUMDOC
+  bit[11:3] of byte offset to module TLS base address, encoded in ldst
+  instructions.
+ENUM
+  BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC
+ENUMDOC
+  Similar as BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12, but no overflow check.
+ENUM
+  BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12
+ENUMDOC
+  bit[11:0] of byte offset to module TLS base address, encoded in ldst
+  instructions.
+ENUM
+  BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC
+ENUMDOC
+  Similar as BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12, but no overflow check.
+ENUM
   BFD_RELOC_AARCH64_TLSDESC_LD_PREL19
 ENUMDOC
   AArch64 TLS DESC relocation.
@@ -7504,6 +7540,16 @@  ENUM
 ENUMDOC
   Similar as BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12, but no overflow check.
 ENUM
+  BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12
+ENUMDOC
+  AArch64 pseudo relocation code for TLS local exec mode.  It's to be
+  used internally by the AArch64 assembler and not (currently) written to
+  any object files.
+ENUM
+  BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC
+ENUMDOC
+  Similar as BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12, but no overflow check.
+ENUM
   BFD_RELOC_AARCH64_LD_GOT_LO12_NC
 ENUMDOC
   AArch64 pseudo relocation code to be used internally by the AArch64
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 3a0cde95196df91392558577d8a8b20b48946794..bb867560e6ca5b7334d21fca1004d23cb9531dc0 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -2902,7 +2902,7 @@  static struct reloc_table_entry reloc_table[] = {
    0,
    0,
    BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12,
-   0,
+   BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12,
    0},
 
   /* Get tp offset for a symbol.  */
@@ -2920,7 +2920,7 @@  static struct reloc_table_entry reloc_table[] = {
    0,
    0,
    BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC,
-   0,
+   BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC,
    0},
 
   /* Most significant bits 32-47 of address/value: MOVZ.  */
@@ -5253,7 +5253,7 @@  ldst_lo12_determine_real_reloc_type (void)
   enum aarch64_opnd_qualifier opd0_qlf = inst.base.operands[0].qualifier;
   enum aarch64_opnd_qualifier opd1_qlf = inst.base.operands[1].qualifier;
 
-  const bfd_reloc_code_real_type reloc_ldst_lo12[3][5] = {
+  const bfd_reloc_code_real_type reloc_ldst_lo12[5][5] = {
     {
       BFD_RELOC_AARCH64_LDST8_LO12,
       BFD_RELOC_AARCH64_LDST16_LO12,
@@ -5274,13 +5274,31 @@  ldst_lo12_determine_real_reloc_type (void)
       BFD_RELOC_AARCH64_TLSLD_LDST32_DTPREL_LO12_NC,
       BFD_RELOC_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC,
       BFD_RELOC_AARCH64_NONE
+    },
+    {
+      BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12,
+      BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12,
+      BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12,
+      BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12,
+      BFD_RELOC_AARCH64_NONE
+    },
+    {
+      BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC,
+      BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC,
+      BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC,
+      BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC,
+      BFD_RELOC_AARCH64_NONE
     }
   };
 
   gas_assert (inst.reloc.type == BFD_RELOC_AARCH64_LDST_LO12
 	      || inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12
 	      || (inst.reloc.type
-		  == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC));
+		  == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC)
+	      || (inst.reloc.type
+		  == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12)
+	      || (inst.reloc.type
+		  == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC));
   gas_assert (inst.base.opcode->operands[1] == AARCH64_OPND_ADDR_UIMM12);
 
   if (opd1_qlf == AARCH64_OPND_QLF_NIL)
@@ -5291,7 +5309,9 @@  ldst_lo12_determine_real_reloc_type (void)
 
   logsz = get_logsz (aarch64_get_qualifier_esize (opd1_qlf));
   if (inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12
-      || inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC)
+      || inst.reloc.type == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC
+      || inst.reloc.type == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12
+      || inst.reloc.type == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC)
     gas_assert (logsz <= 3);
   else
     gas_assert (logsz <= 4);
@@ -6167,7 +6187,11 @@  parse_operands (char *str, const aarch64_opcode *opcode)
 		   || (inst.reloc.type
 		       == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12)
 		   || (inst.reloc.type
-		       == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC))
+		       == BFD_RELOC_AARCH64_TLSLD_LDST_DTPREL_LO12_NC)
+		   || (inst.reloc.type
+		       == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12)
+		   || (inst.reloc.type
+		       == BFD_RELOC_AARCH64_TLSLE_LDST_TPREL_LO12_NC))
 	    inst.reloc.type = ldst_lo12_determine_real_reloc_type ();
 	  /* Leave qualifier to be determined by libopcodes.  */
 	  break;
@@ -7841,6 +7865,14 @@  md_apply_fix (fixS * fixP, valueT * valP, segT seg)
     case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1:
     case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC:
     case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2:
+    case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
+    case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
+    case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
+    case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
     case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
     case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
     case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
@@ -8075,6 +8107,14 @@  aarch64_force_relocation (struct fix *fixp)
     case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1:
     case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G1_NC:
     case BFD_RELOC_AARCH64_TLSLD_MOVW_DTPREL_G2:
+    case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC:
+    case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC:
+    case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC:
+    case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12:
+    case BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC:
     case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_HI12:
     case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12:
     case BFD_RELOC_AARCH64_TLSLE_ADD_TPREL_LO12_NC:
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst16-ilp32.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst16-ilp32.d
new file mode 100644
index 0000000000000000000000000000000000000000..57f6a8126e5437a43c648ba89ae60a6925015e2a
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst16-ilp32.d
@@ -0,0 +1,12 @@ 
+#as: -mabi=ilp32
+#source: reloc-tprel_lo12-ldst16.s
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <.*>:
+   0:	7980009b 	ldrsh	x27, \[x4\]
+			0: R_AARCH64_P32_TLSLE_LDST16_TPREL_LO12	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst16.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst16.d
new file mode 100644
index 0000000000000000000000000000000000000000..9e064430bd910ae4a1a87c68c691e7991eb00ab3
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst16.d
@@ -0,0 +1,11 @@ 
+#as: -mabi=lp64
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0000000000000000 <.*>:
+   0:	7980009b 	ldrsh	x27, \[x4\]
+			0: R_AARCH64_TLSLE_LDST16_TPREL_LO12	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst16.s b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst16.s
new file mode 100644
index 0000000000000000000000000000000000000000..4496c4862f5b5dc7b17c46f840cc9bb8b54bd6bd
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst16.s
@@ -0,0 +1,6 @@ 
+// Test file for AArch64 GAS -- tprel_lo12 for LDST16
+
+func:
+	// BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12
+	ldrsh  x27, [x4, #:tprel_lo12:sym]
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst32-ilp32.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst32-ilp32.d
new file mode 100644
index 0000000000000000000000000000000000000000..c35cd129a2c8ab32a41b544269f59d833e4884b8
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst32-ilp32.d
@@ -0,0 +1,12 @@ 
+#as: -mabi=ilp32
+#source: reloc-tprel_lo12-ldst32.s
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <.*>:
+   0:	b980009b 	ldrsw	x27, \[x4\]
+			0: R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst32.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst32.d
new file mode 100644
index 0000000000000000000000000000000000000000..ee0311b2ca8c21c063eb41a3871d7b13f98a0a14
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst32.d
@@ -0,0 +1,11 @@ 
+#as: -mabi=lp64
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0000000000000000 <.*>:
+   0:	b980009b 	ldrsw	x27, \[x4\]
+			0: R_AARCH64_TLSLE_LDST32_TPREL_LO12	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst32.s b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst32.s
new file mode 100644
index 0000000000000000000000000000000000000000..cd5d6c9be4134c3c4628dbc48d06d8e58c1f5a74
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst32.s
@@ -0,0 +1,6 @@ 
+// Test file for AArch64 GAS -- tprel_lo12 for LDST32
+
+func:
+	// BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12
+	ldrsw  x27, [x4, #:tprel_lo12:sym]
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst64-ilp32.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst64-ilp32.d
new file mode 100644
index 0000000000000000000000000000000000000000..3f8e106c2699aa4e7ec770d1823f430b1989253b
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst64-ilp32.d
@@ -0,0 +1,13 @@ 
+#as: -mabi=ilp32
+#source: reloc-tprel_lo12-ldst64.s
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <.*>:
+   0:	f940009b 	ldr	x27, \[x4\]
+			0: R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12	sym
+
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst64.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst64.d
new file mode 100644
index 0000000000000000000000000000000000000000..12edd0168ba5f638d2c1fb13c6261c0a31d8ace6
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst64.d
@@ -0,0 +1,11 @@ 
+#as: -mabi=lp64
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0000000000000000 <.*>:
+   0:	f940009b 	ldr	x27, \[x4\]
+			0: R_AARCH64_TLSLE_LDST64_TPREL_LO12	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst64.s b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst64.s
new file mode 100644
index 0000000000000000000000000000000000000000..4358008c323e7a5333f3afc8758347671133f30f
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst64.s
@@ -0,0 +1,6 @@ 
+// Test file for AArch64 GAS -- tprel_lo12 for LDST64
+
+func:
+	// BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12
+	ldr  x27, [x4, #:tprel_lo12:sym]
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst8-ilp32.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst8-ilp32.d
new file mode 100644
index 0000000000000000000000000000000000000000..7066e5a15415e34dca7577f366d553cc4fd30c33
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst8-ilp32.d
@@ -0,0 +1,12 @@ 
+#as: -mabi=ilp32
+#source: reloc-tprel_lo12-ldst8.s
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <.*>:
+   0:	39800115 	ldrsb	x21, \[x8\]
+			0: R_AARCH64_P32_TLSLE_LDST8_TPREL_LO12	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst8.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst8.d
new file mode 100644
index 0000000000000000000000000000000000000000..07794afe89bbba101d92f18458a894d3c9bc2db0
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst8.d
@@ -0,0 +1,11 @@ 
+#as: -mabi=lp64
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0000000000000000 <.*>:
+   0:	39800115 	ldrsb	x21, \[x8\]
+			0: R_AARCH64_TLSLE_LDST8_TPREL_LO12	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst8.s b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst8.s
new file mode 100644
index 0000000000000000000000000000000000000000..c59eee34649b9faea006f425ddf3e59f14997f8a
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12-ldst8.s
@@ -0,0 +1,6 @@ 
+// Test file for AArch64 GAS -- tprel_lo12 for LDST8
+
+func:
+	// BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12
+	ldrsb  x21, [x8, #:tprel_lo12:sym]
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16-ilp32.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16-ilp32.d
new file mode 100644
index 0000000000000000000000000000000000000000..0380830dd8b8d1dd39d41d4d97cc9c513475a561
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16-ilp32.d
@@ -0,0 +1,13 @@ 
+#as: -mabi=ilp32
+#source: reloc-tprel_lo12_nc-ldst16.s
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <.*>:
+   0:	7940009b 	ldrh	w27, \[x4\]
+			0: R_AARCH64_P32_TLSLE_LDST16_TPREL_LO12_NC	sym
+
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16.d
new file mode 100644
index 0000000000000000000000000000000000000000..813086053a359340293ea36f97babb76107a94b6
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16.d
@@ -0,0 +1,11 @@ 
+#as: -mabi=lp64
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0000000000000000 <.*>:
+   0:	7940009b 	ldrh	w27, \[x4\]
+			0: R_AARCH64_TLSLE_LDST16_TPREL_LO12_NC	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16.s b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16.s
new file mode 100644
index 0000000000000000000000000000000000000000..65f9df7bb0b7c596a62f91cb30e1bfa3697fb55e
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst16.s
@@ -0,0 +1,5 @@ 
+// Test file for AArch64 GAS -- tprel_lo12_nc for LDST16
+
+func:
+	// BFD_RELOC_AARCH64_TLSLE_LDST16_TPREL_LO12_NC
+	ldrh  w27, [x4, #:tprel_lo12_nc:sym]
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32-ilp32.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32-ilp32.d
new file mode 100644
index 0000000000000000000000000000000000000000..94cb62d1f2090f0d4fcdf552b006dcb73016245d
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32-ilp32.d
@@ -0,0 +1,13 @@ 
+#as: -mabi=ilp32
+#source: reloc-tprel_lo12_nc-ldst32.s
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <.*>:
+   0:	b98000f4 	ldrsw	x20, \[x7\]
+			0: R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12_NC	sym
+
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32.d
new file mode 100644
index 0000000000000000000000000000000000000000..16ece1b7c5e8ee06a695833f8ee96ccc342e1f83
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32.d
@@ -0,0 +1,11 @@ 
+#as: -mabi=lp64
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0000000000000000 <.*>:
+   0:	b98000f4 	ldrsw	x20, \[x7\]
+			0: R_AARCH64_TLSLE_LDST32_TPREL_LO12_NC	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32.s b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32.s
new file mode 100644
index 0000000000000000000000000000000000000000..bdebc92f72b1136379db9094c34628c1551a531d
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst32.s
@@ -0,0 +1,6 @@ 
+// Test file for AArch64 GAS -- tprel_lo12_nc for LDST32
+
+func:
+	// BFD_RELOC_AARCH64_TLSLE_LDST32_TPREL_LO12_NC
+	ldrsw  x20, [x7, #:tprel_lo12_nc:sym]
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64-ilp32.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64-ilp32.d
new file mode 100644
index 0000000000000000000000000000000000000000..d513444f7f800ab7b8c59a6222c2e75a6bf7c0f0
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64-ilp32.d
@@ -0,0 +1,13 @@ 
+#as: -mabi=ilp32
+#source: reloc-tprel_lo12_nc-ldst64.s
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <.*>:
+   0:	f940009b 	ldr	x27, \[x4\]
+			0: R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12_NC	sym
+
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64.d
new file mode 100644
index 0000000000000000000000000000000000000000..d5cf86d0356e9204a5d2e7aadf09bd85474a8437
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64.d
@@ -0,0 +1,11 @@ 
+#as: -mabi=lp64
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0000000000000000 <.*>:
+   0:	f940009b 	ldr	x27, \[x4\]
+			0: R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64.s b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64.s
new file mode 100644
index 0000000000000000000000000000000000000000..8b2b3b217b93ad7fa5d5cb9c8952959a69b419dc
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst64.s
@@ -0,0 +1,6 @@ 
+// Test file for AArch64 GAS -- tprel_lo12_nc for LDST64
+
+func:
+	// BFD_RELOC_AARCH64_TLSLE_LDST64_TPREL_LO12_NC
+	ldr  x27, [x4, #:tprel_lo12_nc:sym]
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8-ilp32.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8-ilp32.d
new file mode 100644
index 0000000000000000000000000000000000000000..90051331daddb14038aab62e060017b9d2212d43
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8-ilp32.d
@@ -0,0 +1,13 @@ 
+#as: -mabi=ilp32
+#source: reloc-tprel_lo12_nc-ldst8.s
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+00000000 <.*>:
+   0:	3940005d 	ldrb	w29, \[x2\]
+			0: R_AARCH64_P32_TLSLE_LDST8_TPREL_LO12_NC	sym
+
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8.d b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8.d
new file mode 100644
index 0000000000000000000000000000000000000000..36300090c1ebbfd155426ea3bb1cde98e04bb325
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8.d
@@ -0,0 +1,11 @@ 
+#as: -mabi=lp64
+#objdump: -dr
+
+.*:     file format .*
+
+Disassembly of section \.text:
+
+0000000000000000 <.*>:
+   0:	3940005d 	ldrb	w29, \[x2\]
+			0: R_AARCH64_TLSLE_LDST8_TPREL_LO12_NC	sym
+
diff --git a/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8.s b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8.s
new file mode 100644
index 0000000000000000000000000000000000000000..816aede6180884786e51580c601575fe7e5b7acc
--- /dev/null
+++ b/gas/testsuite/gas/aarch64/reloc-tprel_lo12_nc-ldst8.s
@@ -0,0 +1,6 @@ 
+// Test file for AArch64 GAS -- tprel_lo12_nc for LDST8
+
+func:
+	// BFD_RELOC_AARCH64_TLSLE_LDST8_TPREL_LO12_NC
+	ldrb  w29, [x2, #:tprel_lo12_nc:sym]
+
diff --git a/include/elf/aarch64.h b/include/elf/aarch64.h
index 4900fc5e57a866317c881c10a0c9b60b091b7be9..ea823a309db1b828c0591330432674d6e3ed7cb1 100644
--- a/include/elf/aarch64.h
+++ b/include/elf/aarch64.h
@@ -147,6 +147,14 @@  RELOC_NUMBER (R_AARCH64_P32_TLSLE_MOVW_TPREL_G0_NC, 108)
 RELOC_NUMBER (R_AARCH64_P32_TLSLE_ADD_TPREL_HI12, 109)
 RELOC_NUMBER (R_AARCH64_P32_TLSLE_ADD_TPREL_LO12, 110)
 RELOC_NUMBER (R_AARCH64_P32_TLSLE_ADD_TPREL_LO12_NC, 111)
+RELOC_NUMBER (R_AARCH64_P32_TLSLE_LDST8_TPREL_LO12, 112)
+RELOC_NUMBER (R_AARCH64_P32_TLSLE_LDST8_TPREL_LO12_NC, 113)
+RELOC_NUMBER (R_AARCH64_P32_TLSLE_LDST16_TPREL_LO12, 114)
+RELOC_NUMBER (R_AARCH64_P32_TLSLE_LDST16_TPREL_LO12_NC, 115)
+RELOC_NUMBER (R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12, 116)
+RELOC_NUMBER (R_AARCH64_P32_TLSLE_LDST32_TPREL_LO12_NC, 117)
+RELOC_NUMBER (R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12, 118)
+RELOC_NUMBER (R_AARCH64_P32_TLSLE_LDST64_TPREL_LO12_NC, 119)
 
 RELOC_NUMBER (R_AARCH64_P32_TLSDESC_LD_PREL19, 122)
 RELOC_NUMBER (R_AARCH64_P32_TLSDESC_ADR_PREL21, 123)