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]

Re: TLS descriptors for ARM


On 01/06/11 17:11, Nick Clifton wrote:
Hi Nathan,

This patch adds support for TLS descriptors for ARM. Refer to
http://www.codesourcery.com/publications/RFC-TLSDESC-ARM.txt for the
current specification.

built and tested for arm-none-linux-gnueabi, ok?

Almost. Please build and test an arm-netbsdelf toolchain. I get some new failures with this:

Fixed now.


Which I believe is due to interworking discrepancies.

Some were interlinking, and I moved them to the armeabi part of the ld tests. The other 2 were a failure to support attributes, which leads to a different kind of nop. I slackened the testcases.


retested for arm-eabi, arm-none-linux-gnueabi and arm-netbsdelf

ok?

nathan

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::         CodeSourcery

2011-01-07  Nathan Sidwell  <nathan@codesourcery.com>
	    Glauber de Oliveira Costa  <glommer@gmail.com>

	bfd/
	* reloc.c (BFD_RELOC_ARM_TLS_GOTDESC, BFD_RELOC_ARM_TLS_CALL,
	BFD_RELOC_ARM_THM_TLS_CALL, BFD_RELOC_ARM_TLS_DESCSEQ,
	BFD_RELOC_ARM_THM_TLS_DESCSEQ, BFD_RELOC_ARM_TLS_DESC): New
	relocations.
	* libbfd.h: Rebuilt.
	* bfd-in2.h: Rebuilt.
	* elf32-arm.c (elf32_arm_howto_table_1): Add new relocations.
	(elf32_arm_reloc_map): Likewise.
	(tls_trampoline, dl_tlsdesc_lazy_trampoline): New PLT templates.
	(elf32_arm_stub_long_branch_any_tls_pic,
	elf32_arm_stub_long_branch_v4t_thumb_tls_pic): New stub templates.
	(DEF_STUBS): Add new stubs.
	(struct_elf_arm_obj_data): Add local_tlsdesc_gotent field.
	(elf32_arm_local_tlsdesc_gotent): New.
	(GOT_TLS_GDESC): New mask.
	(GOT_TLS_GD_ANY): Define.
	(struct elf32_arm_link_hash_entry): Add tlsdesc_got field.
	(elf32_arm_compute_jump_table_size): New.
	(struct elf32_arm_link_hash_table): Add next_tls_desc_index,
	num_tls_desc, dt_tlsdesc_plt, dt_tlsdesc_got, tls_trampoline,
	sgotplt_jump_table_size fields.
	(elf32_arm_link_hash_newfunc): Initialize tlsdesc_got field.
	(elf32_arm_link_hash_table_create): Initialize new fields.
	(arm_type_of_stub): Check TLS desc relocs too.
	(elf32_arm_stub_name): TLS desc relocs can be shared.
	(elf32_arm_tls_transition): Determine relaxation.
	(arm_stub_required_alignment): Add tls stubs.
	(elf32_arm_size_stubs): Likewise.
	(elf32_arm_tls_relax): Perform TLS relaxing.
	(elf32_arm_final_link_relocate): Process TLS DESC relocations.
	(IS_ARM_TLS_GNU_RELOC): New.
	(IS_ARM_TLS_RELOC): Use it.
	(elf32_arm_relocate_section): Perform TLS relaxing.
	(elf32_arm_check_relocs): Anticipate TLS relaxing, process tls
	desc relocations.
	(allocate_dynrelocs): Allocate tls desc relcoations.
	(elf32_arm_output_arch_local_syms): Emit tls trampoline mapping
	symbols.
	(elf32_arm_size_dynamic_sections): Allocate tls trampolines and
	got slots.
	(elf32_arm_always_size_sections): New. Create _TLS_MODULE_BASE
	symbol.
	(elf32_arm_finish_dynamic_symbol): Adjust.
	(arm_put_trampoline): New.
	(elf32_arm_finish_dynamic_sections): Emit new dynamic tags and tls
	trampolines.
	(elf_backend_always_size_sections): Define.

	include/elf/
	* arm.h (R_ARM_TLS_DESC, R_ARM_TLS_GOTDESC, R_ARM_TLS_CALL,
	R_ARM_TLS_DESCSEQ, T_ARM_THM_TLS_CALL, R_ARM_THM_TLS_DESCSEQ): New
	relocations.

	gas/
	* doc/c-arm.texi: Document TLSDESC and TLSCALL relocations, and
	.tlsdescseq directive.
	* config/tc-arm.c (arm_typed_reg_parse): Check for potential reloc
	following a symbol.
	(s_arm_tls_descseq): New directive.
	(md_pseudo_table): Add it.
	(encode_branch): Allow TLS_CALL relocs too.
	(do_t_blx, do_t_branch23): Use encode_branch.
	(reloc_names): Add tlsdesc and tlscall.
	(md_apply_fix): Process tls desc relocations.
	(tc_gen_reloc): Likewise.
	(arm_fix_adjustable): Likewise.

	gas/testsuite/
	* gas/arm/tls.s: Add tlsdesc tests.
	* gas/arm/tls.d: Adjust.

	ld/testsuite/
	* ld-arm/arm-elf.exp: Added tests for new TLS handling
	relocations.
	* ld-arm/tls-descrelax-be32.d: New.
	* ld-arm/tls-descrelax-be32.s: New.
	* ld-arm/tls-descrelax-be8.d: New.
	* ld-arm/tls-descrelax-be8.s: New.
	* ld-arm/tls-descrelax-v7.d: New.
	* ld-arm/tls-descrelax-v7.s: New.
	* ld-arm/tls-descrelax.d: New.
	* ld-arm/tls-descrelax.s: New.
	* ld-arm/tls-descseq.d: New.
	* ld-arm/tls-descseq.r: New.
	* ld-arm/tls-descseq.s: New.
	* ld-arm/tls-gdesc-got.d: New.
	* ld-arm/tls-gdesc-got.s: New.
	* ld-arm/tls-gdesc-nlazy.g: New.
	* ld-arm/tls-gdesc-nlazy.s: New.
	* ld-arm/tls-gdesc.d: New.
	* ld-arm/tls-gdesc.r: New.
	* ld-arm/tls-gdesc.s: New.
	* ld-arm/tls-gdierelax.d: New.
	* ld-arm/tls-gdierelax.s: New.
	* ld-arm/tls-gdierelax2.d: New.
	* ld-arm/tls-gdierelax2.s: New.
	* ld-arm/tls-gdlerelax.d: New.
	* ld-arm/tls-gdlerelax.s: New.
	* ld-arm/tls-lib-loc.d: New.
	* ld-arm/tls-lib-loc.r: New.
	* ld-arm/tls-lib-loc.s: New.
	* ld-arm/tls-longplt-lib.d: New.
	* ld-arm/tls-longplt-lib.s: New.
	* ld-arm/tls-longplt.d: New.
	* ld-arm/tls-longplt.s: New.
	* ld-arm/tls-mixed.r: New.
	* ld-arm/tls-mixed.s: New.
	* ld-arm/tls-thumb1.d: New.
	* ld-arm/tls-thumb1.s: New.
	* ld-arm/arm-elf.exp: New.

Index: bfd/bfd-in2.h
===================================================================
RCS file: /cvs/src/src/bfd/bfd-in2.h,v
retrieving revision 1.527
diff -c -3 -p -r1.527 bfd-in2.h
*** bfd/bfd-in2.h	5 Jan 2011 22:04:08 -0000	1.527
--- bfd/bfd-in2.h	7 Jan 2011 13:08:56 -0000
*************** pc-relative or some form of GOT-indirect
*** 3146,3151 ****
--- 3146,3157 ----
    BFD_RELOC_ARM_TLS_TPOFF32,
    BFD_RELOC_ARM_TLS_IE32,
    BFD_RELOC_ARM_TLS_LE32,
+   BFD_RELOC_ARM_TLS_GOTDESC,
+   BFD_RELOC_ARM_TLS_CALL,
+   BFD_RELOC_ARM_THM_TLS_CALL,
+   BFD_RELOC_ARM_TLS_DESCSEQ,
+   BFD_RELOC_ARM_THM_TLS_DESCSEQ,
+   BFD_RELOC_ARM_TLS_DESC,
  
  /* ARM group relocations.  */
    BFD_RELOC_ARM_ALU_PC_G0_NC,
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.251
diff -c -3 -p -r1.251 elf32-arm.c
*** bfd/elf32-arm.c	2 Dec 2010 13:28:35 -0000	1.251
--- bfd/elf32-arm.c	7 Jan 2011 13:09:01 -0000
*************** static reloc_howto_type elf32_arm_howto_
*** 261,278 ****
  	 0xffffffff,		/* dst_mask */
  	 FALSE),		/* pcrel_offset */
  
!   HOWTO (R_ARM_SWI24,		/* type */
  	 0,			/* rightshift */
! 	 0,			/* size (0 = byte, 1 = short, 2 = long) */
! 	 0,			/* bitsize */
  	 FALSE,			/* pc_relative */
  	 0,			/* bitpos */
! 	 complain_overflow_signed,/* complain_on_overflow */
  	 bfd_elf_generic_reloc,	/* special_function */
! 	 "R_ARM_SWI24",		/* name */
  	 FALSE,			/* partial_inplace */
! 	 0x00000000,		/* src_mask */
! 	 0x00000000,		/* dst_mask */
  	 FALSE),		/* pcrel_offset */
  
    HOWTO (R_ARM_THM_SWI8,	/* type */
--- 261,278 ----
  	 0xffffffff,		/* dst_mask */
  	 FALSE),		/* pcrel_offset */
  
!   HOWTO (R_ARM_TLS_DESC,	/* type */
  	 0,			/* rightshift */
! 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
! 	 32,			/* bitsize */
  	 FALSE,			/* pc_relative */
  	 0,			/* bitpos */
! 	 complain_overflow_bitfield,/* complain_on_overflow */
  	 bfd_elf_generic_reloc,	/* special_function */
! 	 "R_ARM_TLS_DESC",	/* name */
  	 FALSE,			/* partial_inplace */
! 	 0xffffffff,		/* src_mask */
! 	 0xffffffff,		/* dst_mask */
  	 FALSE),		/* pcrel_offset */
  
    HOWTO (R_ARM_THM_SWI8,	/* type */
*************** static reloc_howto_type elf32_arm_howto_
*** 1352,1361 ****
  	 0x040f70ff,		/* dst_mask */
  	 FALSE),		/* pcrel_offset */
  
!   EMPTY_HOWTO (90),   /* Unallocated.  */
!   EMPTY_HOWTO (91),
!   EMPTY_HOWTO (92),
!   EMPTY_HOWTO (93),
  
    HOWTO (R_ARM_PLT32_ABS,	/* type */
  	 0,			/* rightshift */
--- 1352,1412 ----
  	 0x040f70ff,		/* dst_mask */
  	 FALSE),		/* pcrel_offset */
  
!   HOWTO (R_ARM_TLS_GOTDESC,	/* type */
! 	 0,			/* rightshift */
! 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
! 	 32,			/* bitsize */
! 	 FALSE,			/* pc_relative */
! 	 0,			/* bitpos */
! 	 complain_overflow_bitfield,/* complain_on_overflow */
! 	 NULL,			/* special_function */
! 	 "R_ARM_TLS_GOTDESC",	/* name */
! 	 TRUE,			/* partial_inplace */
! 	 0xffffffff,		/* src_mask */
! 	 0xffffffff,		/* dst_mask */
! 	 FALSE),		/* pcrel_offset */
! 
!   HOWTO (R_ARM_TLS_CALL,	/* type */
! 	 0,			/* rightshift */
! 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
! 	 24,			/* bitsize */
! 	 FALSE,			/* pc_relative */
! 	 0,			/* bitpos */
! 	 complain_overflow_dont,/* complain_on_overflow */
! 	 bfd_elf_generic_reloc,	/* special_function */
! 	 "R_ARM_TLS_CALL",	/* name */
! 	 FALSE,			/* partial_inplace */
! 	 0x00ffffff,		/* src_mask */
! 	 0x00ffffff,		/* dst_mask */
! 	 FALSE),		/* pcrel_offset */
! 
!   HOWTO (R_ARM_TLS_DESCSEQ,	/* type */
! 	 0,			/* rightshift */
! 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
! 	 0,			/* bitsize */
! 	 FALSE,			/* pc_relative */
! 	 0,			/* bitpos */
! 	 complain_overflow_bitfield,/* complain_on_overflow */
! 	 bfd_elf_generic_reloc,	/* special_function */
! 	 "R_ARM_TLS_DESCSEQ",	/* name */
! 	 FALSE,			/* partial_inplace */
! 	 0x00000000,		/* src_mask */
! 	 0x00000000,		/* dst_mask */
! 	 FALSE),		/* pcrel_offset */
! 
!   HOWTO (R_ARM_THM_TLS_CALL,	/* type */
! 	 0,			/* rightshift */
! 	 2,			/* size (0 = byte, 1 = short, 2 = long) */
! 	 24,			/* bitsize */
! 	 FALSE,			/* pc_relative */
! 	 0,			/* bitpos */
! 	 complain_overflow_dont,/* complain_on_overflow */
! 	 bfd_elf_generic_reloc,	/* special_function */
! 	 "R_ARM_THM_TLS_CALL",	/* name */
! 	 FALSE,			/* partial_inplace */
! 	 0x07ff07ff,		/* src_mask */
! 	 0x07ff07ff,		/* dst_mask */
! 	 FALSE),		/* pcrel_offset */
  
    HOWTO (R_ARM_PLT32_ABS,	/* type */
  	 0,			/* rightshift */
*************** static reloc_howto_type elf32_arm_howto_
*** 1599,1604 ****
--- 1650,1687 ----
  	 0x00000fff,		/* src_mask */
  	 0x00000fff,		/* dst_mask */
  	 FALSE),		/* pcrel_offset */
+ 
+   EMPTY_HOWTO (112),
+   EMPTY_HOWTO (113),
+   EMPTY_HOWTO (114),
+   EMPTY_HOWTO (115),
+   EMPTY_HOWTO (116),
+   EMPTY_HOWTO (117),
+   EMPTY_HOWTO (118),
+   EMPTY_HOWTO (119),
+   EMPTY_HOWTO (120),
+   EMPTY_HOWTO (121),
+   EMPTY_HOWTO (122),
+   EMPTY_HOWTO (123),
+   EMPTY_HOWTO (124),
+   EMPTY_HOWTO (125),
+   EMPTY_HOWTO (126),
+   EMPTY_HOWTO (127),
+   EMPTY_HOWTO (128),
+ 
+   HOWTO (R_ARM_THM_TLS_DESCSEQ,	/* type */
+ 	 0,			/* rightshift */
+ 	 1,			/* size (0 = byte, 1 = short, 2 = long) */
+ 	 0,			/* bitsize */
+ 	 FALSE,			/* pc_relative */
+ 	 0,			/* bitpos */
+ 	 complain_overflow_bitfield,/* complain_on_overflow */
+ 	 bfd_elf_generic_reloc,	/* special_function */
+ 	 "R_ARM_THM_TLS_DESCSEQ",/* name */
+ 	 FALSE,			/* partial_inplace */
+ 	 0x00000000,		/* src_mask */
+ 	 0x00000000,		/* dst_mask */
+ 	 FALSE),		/* pcrel_offset */
  };
  
  /* 112-127 private relocations
*************** static const struct elf32_arm_reloc_map 
*** 1730,1735 ****
--- 1813,1824 ----
      {BFD_RELOC_ARM_PREL31,	     R_ARM_PREL31},
      {BFD_RELOC_ARM_TARGET2,	     R_ARM_TARGET2},
      {BFD_RELOC_ARM_PLT32,            R_ARM_PLT32},
+     {BFD_RELOC_ARM_TLS_GOTDESC,      R_ARM_TLS_GOTDESC},
+     {BFD_RELOC_ARM_TLS_CALL,         R_ARM_TLS_CALL},
+     {BFD_RELOC_ARM_THM_TLS_CALL,     R_ARM_THM_TLS_CALL},
+     {BFD_RELOC_ARM_TLS_DESCSEQ,      R_ARM_TLS_DESCSEQ},
+     {BFD_RELOC_ARM_THM_TLS_DESCSEQ,  R_ARM_THM_TLS_DESCSEQ},
+     {BFD_RELOC_ARM_TLS_DESC,         R_ARM_TLS_DESC},
      {BFD_RELOC_ARM_TLS_GD32,	     R_ARM_TLS_GD32},
      {BFD_RELOC_ARM_TLS_LDO32,	     R_ARM_TLS_LDO32},
      {BFD_RELOC_ARM_TLS_LDM32,	     R_ARM_TLS_LDM32},
*************** typedef unsigned short int insn16;
*** 1912,1917 ****
--- 2001,2026 ----
     section.  */
  #define ELF_DYNAMIC_INTERPRETER     "/usr/lib/ld.so.1"
  
+ static const unsigned long tls_trampoline [] =
+   {
+     0xe08e0000,		/* add r0, lr, r0 */
+     0xe5901004,		/* ldr r1, [r0,#4] */
+     0xe12fff11,		/* bx  r1 */
+   };
+ 
+ static const unsigned long dl_tlsdesc_lazy_trampoline [] =
+   {
+     0xe52d2004, /*	push    {r2}			*/
+     0xe59f200c, /*      ldr     r2, [pc, #3f - . - 8]	*/
+     0xe59f100c, /*      ldr     r1, [pc, #4f - . - 8]	*/
+     0xe79f2002, /* 1:   ldr     r2, [pc, r2]		*/
+     0xe081100f, /* 2:   add     r1, pc			*/
+     0xe12fff12, /*      bx      r2			*/
+     0x00000014, /* 3:   .word  _GLOBAL_OFFSET_TABLE_ - 1b - 8
+ 		   		+ dl_tlsdesc_lazy_resolver(GOT)   */
+     0x00000018, /* 4:   .word  _GLOBAL_OFFSET_TABLE_ - 2b - 8 */ 
+   };
+ 
  #ifdef FOUR_WORD_PLT
  
  /* The first entry in a procedure linkage table looks like
*************** static const insn_sequence elf32_arm_stu
*** 2167,2172 ****
--- 2276,2301 ----
      DATA_WORD(0, R_ARM_REL32, 0),     /* dcd  R_ARM_REL32(X) */
    };
  
+ /* Thumb2/ARM -> TLS trampoline.  Lowest common denominator, which is a
+    long PIC stub.  We can use r1 as a scratch -- and cannot use ip.  */
+ static const insn_sequence elf32_arm_stub_long_branch_any_tls_pic[] =
+ {
+     ARM_INSN(0xe59f1000),             /* ldr   r1, [pc] */
+     ARM_INSN(0xe08ff001),             /* add   pc, pc, r1 */
+     DATA_WORD(0, R_ARM_REL32, -4),    /* dcd   R_ARM_REL32(X-4) */
+ };
+ 
+ /* V4T Thumb -> TLS trampoline.  lowest common denominator, which is a
+    long PIC stub.  We can use r1 as a scratch -- and cannot use ip.  */
+ static const insn_sequence elf32_arm_stub_long_branch_v4t_thumb_tls_pic[] =
+ {
+     THUMB16_INSN(0x4778),             /* bx   pc */
+     THUMB16_INSN(0x46c0),             /* nop */
+     ARM_INSN(0xe59f1000),             /* ldr  r1, [pc, #0] */
+     ARM_INSN(0xe081f00f),             /* add  pc, r1, pc */
+     DATA_WORD(0, R_ARM_REL32, -4),    /* dcd  R_ARM_REL32(X) */
+ };
+ 
  /* Cortex-A8 erratum-workaround stubs.  */
  
  /* Stub used for conditional branches (which may be beyond +/-1MB away, so we
*************** static const insn_sequence elf32_arm_stu
*** 2218,2223 ****
--- 2347,2354 ----
    DEF_STUB(long_branch_v4t_arm_thumb_pic) \
    DEF_STUB(long_branch_v4t_thumb_arm_pic) \
    DEF_STUB(long_branch_thumb_only_pic) \
+   DEF_STUB(long_branch_any_tls_pic) \
+   DEF_STUB(long_branch_v4t_thumb_tls_pic) \
    DEF_STUB(a8_veneer_b_cond) \
    DEF_STUB(a8_veneer_b) \
    DEF_STUB(a8_veneer_bl) \
*************** struct elf_arm_obj_tdata
*** 2426,2431 ****
--- 2557,2565 ----
    /* tls_type for each local got entry.  */
    char *local_got_tls_type;
  
+   /* GOTPLT entries for TLS descriptors.  */
+   bfd_vma *local_tlsdesc_gotent;
+ 
    /* Zero to warn when linking objects with incompatible enum sizes.  */
    int no_enum_size_warning;
  
*************** struct elf_arm_obj_tdata
*** 2439,2444 ****
--- 2573,2581 ----
  #define elf32_arm_local_got_tls_type(bfd) \
    (elf_arm_tdata (bfd)->local_got_tls_type)
  
+ #define elf32_arm_local_tlsdesc_gotent(bfd) \
+   (elf_arm_tdata (bfd)->local_tlsdesc_gotent)
+ 
  #define is_arm_elf(bfd) \
    (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
     && elf_tdata (bfd) != NULL \
*************** struct elf32_arm_link_hash_entry
*** 2478,2485 ****
--- 2615,2628 ----
  #define GOT_NORMAL	1
  #define GOT_TLS_GD	2
  #define GOT_TLS_IE	4
+ #define GOT_TLS_GDESC	8
+ #define GOT_TLS_GD_ANY_P(type)	((type & GOT_TLS_GD) || (type & GOT_TLS_GDESC))
      unsigned char tls_type;
  
+     /* Offset of the GOTPLT entry reserved for the TLS descriptor,
+        starting at the end of the jump table.  */
+     bfd_vma tlsdesc_got;
+ 
      /* The symbol marking the real symbol location for exported thumb
         symbols with Arm stubs.  */
      struct elf_link_hash_entry *export_glue;
*************** struct map_stub
*** 2516,2521 ****
--- 2659,2667 ----
    asection *stub_sec;
  };
  
+ #define elf32_arm_compute_jump_table_size(htab) \
+   ((htab)->next_tls_desc_index * 4)
+ 
  /* ARM ELF linker hash table.  */
  struct elf32_arm_link_hash_table
  {
*************** struct elf32_arm_link_hash_table
*** 2594,2599 ****
--- 2740,2751 ----
    /* True if the target uses REL relocations.  */
    int use_rel;
  
+   /* The index of the next unused R_ARM_TLS_DESC slot in .rel.plt.  */
+   bfd_vma next_tls_desc_index;
+ 
+   /* How many R_ARM_TLS_DESC relocations were generated so far.  */
+   bfd_vma num_tls_desc;
+ 
    /* Short-cuts to get to dynamic linker sections.  */
    asection *sdynbss;
    asection *srelbss;
*************** struct elf32_arm_link_hash_table
*** 2601,2606 ****
--- 2753,2771 ----
    /* The (unloaded but important) VxWorks .rela.plt.unloaded section.  */
    asection *srelplt2;
  
+   /* The offset into splt of the PLT entry for the TLS descriptor
+      resolver.  Special values are 0, if not necessary (or not found
+      to be necessary yet), and -1 if needed but not determined
+      yet.  */
+   bfd_vma dt_tlsdesc_plt;
+ 
+   /* The offset into sgot of the GOT entry used by the PLT entry
+      above.  */
+   bfd_vma dt_tlsdesc_got;    
+ 
+   /* Offset in .plt section of tls_arm_trampoline.  */
+   bfd_vma tls_trampoline;
+ 
    /* Data for R_ARM_TLS_LDM32 relocations.  */
    union
    {
*************** struct elf32_arm_link_hash_table
*** 2614,2619 ****
--- 2779,2788 ----
    /* For convenience in allocate_dynrelocs.  */
    bfd * obfd;
  
+   /* The amount of space used by the reserved portion of the sgotplt
+      section, plus whatever space is used by the jump slots.  */
+   bfd_vma sgotplt_jump_table_size;
+ 
    /* The stub hash table.  */
    struct bfd_hash_table stub_hash_table;
  
*************** elf32_arm_link_hash_newfunc (struct bfd_
*** 2663,2668 ****
--- 2832,2838 ----
      {
        ret->dyn_relocs = NULL;
        ret->tls_type = GOT_UNKNOWN;
+       ret->tlsdesc_got = (bfd_vma) -1;
        ret->plt_thumb_refcount = 0;
        ret->plt_maybe_thumb_refcount = 0;
        ret->plt_got_offset = -1;
*************** elf32_arm_link_hash_table_create (bfd *a
*** 2877,2882 ****
--- 3047,3057 ----
    ret->sdynbss = NULL;
    ret->srelbss = NULL;
    ret->srelplt2 = NULL;
+   ret->dt_tlsdesc_plt = 0;
+   ret->dt_tlsdesc_got = 0;
+   ret->tls_trampoline = 0;
+   ret->next_tls_desc_index = 0;
+   ret->num_tls_desc = 0;
    ret->thumb_glue_size = 0;
    ret->arm_glue_size = 0;
    ret->bx_glue_size = 0;
*************** arm_type_of_stub (struct bfd_link_info *
*** 3075,3081 ****
  
    branch_offset = (bfd_signed_vma)(destination - location);
  
!   if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24)
      {
        /* Handle cases where:
  	 - this call goes too far (different Thumb/Thumb2 max
--- 3250,3257 ----
  
    branch_offset = (bfd_signed_vma)(destination - location);
  
!   if (r_type == R_ARM_THM_CALL || r_type == R_ARM_THM_JUMP24
!       || r_type == R_ARM_THM_TLS_CALL)
      {
        /* Handle cases where:
  	 - this call goes too far (different Thumb/Thumb2 max
*************** arm_type_of_stub (struct bfd_link_info *
*** 3092,3098 ****
  	      && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
  		  || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
  	  || ((st_type != STT_ARM_TFUNC)
! 	      && (((r_type == R_ARM_THM_CALL) && !globals->use_blx)
  		  || (r_type == R_ARM_THM_JUMP24))
  	      && !use_plt))
  	{
--- 3268,3275 ----
  	      && (branch_offset > THM2_MAX_FWD_BRANCH_OFFSET
  		  || (branch_offset < THM2_MAX_BWD_BRANCH_OFFSET)))
  	  || ((st_type != STT_ARM_TFUNC)
! 	      && (((r_type == R_ARM_THM_CALL
! 		    || r_type == R_ARM_THM_TLS_CALL) && !globals->use_blx)
  		  || (r_type == R_ARM_THM_JUMP24))
  	      && !use_plt))
  	{
*************** arm_type_of_stub (struct bfd_link_info *
*** 3143,3160 ****
  		     sym_sec->owner, input_bfd, name);
  		}
  
! 	      stub_type = (info->shared | globals->pic_veneer)
  		/* PIC stubs.  */
! 		? ((globals->use_blx
! 		    && (r_type ==R_ARM_THM_CALL))
! 		   /* V5T and above.  */
! 		   ? arm_stub_long_branch_any_arm_pic
! 		   /* V4T PIC stub.  */
! 		   : arm_stub_long_branch_v4t_thumb_arm_pic)
  
  		/* non-PIC stubs.  */
! 		: ((globals->use_blx
! 		    && (r_type ==R_ARM_THM_CALL))
  		   /* V5T and above.  */
  		   ? arm_stub_long_branch_any_any
  		   /* V4T.  */
--- 3320,3340 ----
  		     sym_sec->owner, input_bfd, name);
  		}
  
! 	      stub_type =
! 		(info->shared | globals->pic_veneer)
  		/* PIC stubs.  */
! 		? (r_type == R_ARM_THM_TLS_CALL
! 		   /* TLS PIC stubs */
! 		   ? (globals->use_blx ? arm_stub_long_branch_any_tls_pic
! 		      : arm_stub_long_branch_v4t_thumb_tls_pic)
! 		   : ((globals->use_blx && r_type == R_ARM_THM_CALL)
! 		      /* V5T PIC and above.  */
! 		      ? arm_stub_long_branch_any_arm_pic
! 		      /* V4T PIC stub.  */
! 		      : arm_stub_long_branch_v4t_thumb_arm_pic))
  
  		/* non-PIC stubs.  */
! 		: ((globals->use_blx && r_type == R_ARM_THM_CALL)
  		   /* V5T and above.  */
  		   ? arm_stub_long_branch_any_any
  		   /* V4T.  */
*************** arm_type_of_stub (struct bfd_link_info *
*** 3170,3176 ****
      }
    else if (r_type == R_ARM_CALL
  	   || r_type == R_ARM_JUMP24
! 	   || r_type == R_ARM_PLT32)
      {
        if (st_type == STT_ARM_TFUNC)
  	{
--- 3350,3357 ----
      }
    else if (r_type == R_ARM_CALL
  	   || r_type == R_ARM_JUMP24
! 	   || r_type == R_ARM_PLT32
! 	   || r_type == R_ARM_TLS_CALL)
      {
        if (st_type == STT_ARM_TFUNC)
  	{
*************** arm_type_of_stub (struct bfd_link_info *
*** 3190,3196 ****
  	     the mode change (bit 24 (H) of BLX encoding).  */
  	  if (branch_offset > (ARM_MAX_FWD_BRANCH_OFFSET + 2)
  	      || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET)
! 	      || ((r_type == R_ARM_CALL) && !globals->use_blx)
  	      || (r_type == R_ARM_JUMP24)
  	      || (r_type == R_ARM_PLT32))
  	    {
--- 3371,3377 ----
  	     the mode change (bit 24 (H) of BLX encoding).  */
  	  if (branch_offset > (ARM_MAX_FWD_BRANCH_OFFSET + 2)
  	      || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET)
! 	      || (r_type == R_ARM_CALL && !globals->use_blx)
  	      || (r_type == R_ARM_JUMP24)
  	      || (r_type == R_ARM_PLT32))
  	    {
*************** arm_type_of_stub (struct bfd_link_info *
*** 3216,3224 ****
  	  if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET
  	      || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET))
  	    {
! 	      stub_type = (info->shared | globals->pic_veneer)
  		/* PIC stubs.  */
! 		? arm_stub_long_branch_any_arm_pic
  		/* non-PIC stubs.  */
  		: arm_stub_long_branch_any_any;
  	    }
--- 3397,3409 ----
  	  if (branch_offset > ARM_MAX_FWD_BRANCH_OFFSET
  	      || (branch_offset < ARM_MAX_BWD_BRANCH_OFFSET))
  	    {
! 	      stub_type =
! 		(info->shared | globals->pic_veneer)
  		/* PIC stubs.  */
! 		? (r_type == R_ARM_TLS_CALL
! 		   /* TLS PIC Stub */
! 		   ? arm_stub_long_branch_any_tls_pic
! 		   : arm_stub_long_branch_any_arm_pic)
  		/* non-PIC stubs.  */
  		: arm_stub_long_branch_any_any;
  	    }
*************** elf32_arm_stub_name (const asection *inp
*** 3263,3269 ****
  	sprintf (stub_name, "%08x_%x:%x+%x_%d",
  		 input_section->id & 0xffffffff,
  		 sym_sec->id & 0xffffffff,
! 		 (int) ELF32_R_SYM (rel->r_info) & 0xffffffff,
  		 (int) rel->r_addend & 0xffffffff,
  		 (int) stub_type);
      }
--- 3448,3456 ----
  	sprintf (stub_name, "%08x_%x:%x+%x_%d",
  		 input_section->id & 0xffffffff,
  		 sym_sec->id & 0xffffffff,
! 		 ELF32_R_TYPE (rel->r_info) == R_ARM_TLS_CALL
! 		 || ELF32_R_TYPE (rel->r_info) == R_ARM_THM_TLS_CALL
! 		 ? 0 : (int) ELF32_R_SYM (rel->r_info) & 0xffffffff,
  		 (int) rel->r_addend & 0xffffffff,
  		 (int) stub_type);
      }
*************** put_thumb_insn (struct elf32_arm_link_ha
*** 3426,3431 ****
--- 3613,3644 ----
      bfd_putb16 (val, ptr);
  }
  
+ /* If it's possible to change R_TYPE to a more efficient access
+    model, return the new reloc type.  */
+ 
+ static unsigned
+ elf32_arm_tls_transition (struct bfd_link_info *info, int r_type, 
+ 			  struct elf_link_hash_entry *h)
+ {
+   int is_local = (h == NULL);
+ 
+   if (info->shared || (h && h->root.type == bfd_link_hash_undefweak))
+     return r_type;
+ 
+   /* We do not support relaxations for Old TLS models.  */ 
+   switch (r_type)
+     {
+     case R_ARM_TLS_GOTDESC:
+     case R_ARM_TLS_CALL:
+     case R_ARM_THM_TLS_CALL:
+     case R_ARM_TLS_DESCSEQ:
+     case R_ARM_THM_TLS_DESCSEQ:
+       return is_local ? R_ARM_TLS_LE32 : R_ARM_TLS_IE32;
+     }
+ 
+   return r_type;
+ }
+ 
  static bfd_reloc_status_type elf32_arm_final_link_relocate
    (reloc_howto_type *, bfd *, bfd *, asection *, bfd_byte *,
     Elf_Internal_Rela *, bfd_vma, struct bfd_link_info *, asection *,
*************** arm_stub_required_alignment (enum elf32_
*** 3453,3458 ****
--- 3666,3673 ----
      case arm_stub_long_branch_v4t_arm_thumb_pic:
      case arm_stub_long_branch_v4t_thumb_arm_pic:
      case arm_stub_long_branch_thumb_only_pic:
+     case arm_stub_long_branch_any_tls_pic:
+     case arm_stub_long_branch_v4t_thumb_tls_pic:
      case arm_stub_a8_veneer_blx:
        return 4;
      
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 4419,4433 ****
  			free (internal_relocs);
  		      goto error_ret_free_local;
  		    }
! 
! 		  /* Only look for stubs on branch instructions.  */
  		  if ((r_type != (unsigned int) R_ARM_CALL)
  		      && (r_type != (unsigned int) R_ARM_THM_CALL)
  		      && (r_type != (unsigned int) R_ARM_JUMP24)
  		      && (r_type != (unsigned int) R_ARM_THM_JUMP19)
  		      && (r_type != (unsigned int) R_ARM_THM_XPC22)
  		      && (r_type != (unsigned int) R_ARM_THM_JUMP24)
! 		      && (r_type != (unsigned int) R_ARM_PLT32))
  		    continue;
  
  		  /* Now determine the call target, its name, value,
--- 4634,4663 ----
  			free (internal_relocs);
  		      goto error_ret_free_local;
  		    }
! 		  
! 		  hash = NULL;
! 		  if (r_indx >= symtab_hdr->sh_info)
! 		    hash = elf32_arm_hash_entry
! 		      (elf_sym_hashes (input_bfd)
! 		       [r_indx - symtab_hdr->sh_info]);
! 		  
! 		  /* Only look for stubs on branch instructions, or
! 		     non-relaxed TLSCALL  */
  		  if ((r_type != (unsigned int) R_ARM_CALL)
  		      && (r_type != (unsigned int) R_ARM_THM_CALL)
  		      && (r_type != (unsigned int) R_ARM_JUMP24)
  		      && (r_type != (unsigned int) R_ARM_THM_JUMP19)
  		      && (r_type != (unsigned int) R_ARM_THM_XPC22)
  		      && (r_type != (unsigned int) R_ARM_THM_JUMP24)
! 		      && (r_type != (unsigned int) R_ARM_PLT32)
! 		      && !((r_type == (unsigned int) R_ARM_TLS_CALL
! 			    || r_type == (unsigned int) R_ARM_THM_TLS_CALL)
! 			   && r_type == elf32_arm_tls_transition
! 			       (info, r_type, &hash->root)
! 			   && ((hash ? hash->tls_type
! 				: (elf32_arm_local_got_tls_type
! 				   (input_bfd)[r_indx]))
! 			       & GOT_TLS_GDESC) != 0))
  		    continue;
  
  		  /* Now determine the call target, its name, value,
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 4435,4443 ****
  		  sym_sec = NULL;
  		  sym_value = 0;
  		  destination = 0;
- 		  hash = NULL;
  		  sym_name = NULL;
! 		  if (r_indx < symtab_hdr->sh_info)
  		    {
  		      /* It's a local symbol.  */
  		      Elf_Internal_Sym *sym;
--- 4665,4685 ----
  		  sym_sec = NULL;
  		  sym_value = 0;
  		  destination = 0;
  		  sym_name = NULL;
! 		  
! 		  if (r_type == (unsigned int) R_ARM_TLS_CALL
! 		      || r_type == (unsigned int) R_ARM_THM_TLS_CALL)
! 		    {
! 		      /* A non-relaxed TLS call.  The target is the
! 			 plt-resident trampoline and nothing to do
! 			 with the symbol.  */
! 		      BFD_ASSERT (htab->tls_trampoline > 0);
! 		      sym_sec = htab->root.splt;
! 		      sym_value = htab->tls_trampoline;
! 		      hash = 0;
! 		      st_type = STT_FUNC;
! 		    }
! 		  else if (!hash)
  		    {
  		      /* It's a local symbol.  */
  		      Elf_Internal_Sym *sym;
*************** elf32_arm_size_stubs (bfd *output_bfd,
*** 4485,4496 ****
  		  else
  		    {
  		      /* It's an external symbol.  */
- 		      int e_indx;
- 
- 		      e_indx = r_indx - symtab_hdr->sh_info;
- 		      hash = ((struct elf32_arm_link_hash_entry *)
- 			      elf_sym_hashes (input_bfd)[e_indx]);
- 
  		      while (hash->root.root.type == bfd_link_hash_indirect
  			     || hash->root.root.type == bfd_link_hash_warning)
  			hash = ((struct elf32_arm_link_hash_entry *)
--- 4727,4732 ----
*************** elf32_arm_abs12_reloc (bfd *abfd, void *
*** 6743,6748 ****
--- 6979,7126 ----
    return bfd_reloc_ok;
  }
  
+ /* Handle TLS relaxations.  Relaxing is possible for symbols that use
+    R_ARM_GOTDESC, R_ARM_{,THM_}TLS_CALL or
+    R_ARM_{,THM_}TLS_DESCSEQ relocations, during a static link.
+ 
+    Return bfd_reloc_ok if we're done, bfd_reloc_continue if the caller
+    is to then call final_link_relocate.  Return other values in the
+    case of error.  */
+  
+ 
+ static bfd_reloc_status_type 
+ elf32_arm_tls_relax (struct elf32_arm_link_hash_table *globals,
+ 		     bfd *input_bfd, asection *input_sec, bfd_byte *contents, 
+ 		     Elf_Internal_Rela *rel, unsigned long is_local)
+ {
+   unsigned long insn;
+   
+   switch (ELF32_R_TYPE (rel->r_info))
+     {
+     default:
+       return bfd_reloc_notsupported;
+       
+     case R_ARM_TLS_GOTDESC:
+       if (is_local)
+ 	insn = 0;
+       else
+ 	{
+ 	  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+ 	  if (insn & 1)
+ 	    insn -= 5; /* THUMB */
+ 	  else
+ 	    insn -= 8; /* ARM */
+ 	}
+       bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+       return bfd_reloc_continue;
+ 
+     case R_ARM_THM_TLS_DESCSEQ:
+       /* Thumb insn.  */
+       insn = bfd_get_16 (input_bfd, contents + rel->r_offset);
+       if ((insn & 0xff78) == 0x4478)	  /* add rx, pc */
+ 	{
+ 	  if (is_local)
+ 	    /* nop */
+ 	    bfd_put_16 (input_bfd, 0x46c0, contents + rel->r_offset);
+ 	}
+       else if ((insn & 0xffc0) == 0x6840)  /* ldr rx,[ry,#4] */
+ 	{
+ 	  if (is_local)
+ 	    /* nop */
+ 	    bfd_put_16 (input_bfd, 0x46c0, contents + rel->r_offset);
+ 	  else
+ 	    /* ldr rx,[ry] */
+ 	    bfd_put_16 (input_bfd, insn & 0xf83f, contents + rel->r_offset);
+ 	}
+       else if ((insn & 0xff87) == 0x4780)  /* blx rx */
+ 	{
+ 	  if (is_local)
+ 	    /* nop */
+ 	    bfd_put_16 (input_bfd, 0x46c0, contents + rel->r_offset);
+ 	  else
+ 	    /* mov r0, rx */
+ 	    bfd_put_16 (input_bfd, 0x4600 | (insn & 0x78),
+ 			contents + rel->r_offset);
+ 	}
+       else
+ 	{
+ 	  if ((insn & 0xf000) == 0xf000 || (insn & 0xf800) == 0xe800)
+ 	    /* It's a 32 bit instruction, fetch the rest of it for
+ 	       error generation.  */
+ 	    insn = (insn << 16)
+ 	      | bfd_get_16 (input_bfd, contents + rel->r_offset + 2);
+ 	  (*_bfd_error_handler)
+ 	    (_("%B(%A+0x%lx):unexpected Thumb instruction '0x%x' in TLS trampoline"),
+ 	     input_bfd, input_sec, (unsigned long)rel->r_offset, insn);
+ 	  return bfd_reloc_notsupported;
+ 	}
+       break;
+       
+     case R_ARM_TLS_DESCSEQ:
+       /* arm insn.  */
+       insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+       if ((insn & 0xffff0ff0) == 0xe08f0000) /* add rx,pc,ry */
+ 	{
+ 	  if (is_local)
+ 	    /* mov rx, ry */
+ 	    bfd_put_32 (input_bfd, 0xe1a00000 | (insn & 0xffff),
+ 			contents + rel->r_offset);
+ 	}
+       else if ((insn & 0xfff00fff) == 0xe5900004) /* ldr rx,[ry,#4]*/
+ 	{
+ 	  if (is_local)
+ 	    /* nop */
+ 	    bfd_put_32 (input_bfd, 0xe1a00000, contents + rel->r_offset);
+ 	  else
+ 	    /* ldr rx,[ry] */
+ 	    bfd_put_32 (input_bfd, insn & 0xfffff000,
+ 			contents + rel->r_offset);
+ 	}
+       else if ((insn & 0xfffffff0) == 0xe12fff30) /* blx rx */
+ 	{
+ 	  if (is_local)
+ 	    /* nop */
+ 	    bfd_put_32 (input_bfd, 0xe1a00000, contents + rel->r_offset);
+ 	  else
+ 	    /* mov r0, rx */
+ 	    bfd_put_32 (input_bfd, 0xe1a00000 | (insn & 0xf),
+ 			contents + rel->r_offset);
+ 	}
+       else
+ 	{
+ 	  (*_bfd_error_handler)
+ 	    (_("%B(%A+0x%lx):unexpected ARM instruction '0x%x' in TLS trampoline"),
+ 	     input_bfd, input_sec, (unsigned long)rel->r_offset, insn);
+ 	  return bfd_reloc_notsupported;
+ 	}
+       break;
+ 
+     case R_ARM_TLS_CALL:
+       /* GD->IE relaxation, turn the instruction into 'nop' or
+ 	 'ldr r0, [pc,r0]'  */
+       insn = is_local ? 0xe1a00000 : 0xe79f0000;
+       bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+       break;
+       
+     case R_ARM_THM_TLS_CALL:
+       /* GD->IE relaxation */
+       if (!is_local)
+ 	/* add r0,pc; ldr r0, [r0]  */
+ 	insn = 0x44786800;
+       else if (arch_has_thumb2_nop (globals))
+ 	/* nop.w */
+ 	insn = 0xf3af8000;
+       else
+ 	/* nop; nop */
+ 	insn = 0xbf00bf00;
+ 	
+       bfd_put_16 (input_bfd, insn >> 16, contents + rel->r_offset);
+       bfd_put_16 (input_bfd, insn & 0xffff, contents + rel->r_offset + 2);
+       break;
+     }
+   return bfd_reloc_ok;
+ }
+ 
  /* For a given value of n, calculate the value of G_n as required to
     deal with group relocations.  We return it in the form of an
     encoded constant-and-rotation, together with the final residual.  If n is
*************** elf32_arm_final_link_relocate (reloc_how
*** 6834,6839 ****
--- 7212,7218 ----
    unsigned long                 r_symndx;
    bfd_byte *                    hit_data = contents + rel->r_offset;
    bfd_vma *                     local_got_offsets;
+   bfd_vma *                     local_tlsdesc_gotents;
    asection *                    sgot = NULL;
    asection *                    splt = NULL;
    asection *                    sreloc = NULL;
*************** elf32_arm_final_link_relocate (reloc_how
*** 6851,6856 ****
--- 7230,7240 ----
    /* Some relocation types map to different relocations depending on the
       target.  We pick the right one here.  */
    r_type = arm_real_reloc_type (globals, r_type);
+ 
+   /* It is possible to have linker relaxations on some TLS access
+      models.  Update our information here.  */
+   r_type = elf32_arm_tls_transition (info, r_type, h);
+ 
    if (r_type != howto->type)
      howto = elf32_arm_howto_from_type (r_type);
  
*************** elf32_arm_final_link_relocate (reloc_how
*** 6870,6875 ****
--- 7254,7261 ----
    splt = globals->root.splt;
    srelgot = globals->root.srelgot;
    local_got_offsets = elf_local_got_offsets (input_bfd);
+   local_tlsdesc_gotents = elf32_arm_local_tlsdesc_gotent (input_bfd);
+ 
    r_symndx = ELF32_R_SYM (rel->r_info);
  
    if (globals->use_rel)
*************** elf32_arm_final_link_relocate (reloc_how
*** 8010,8026 ****
  					 rel->r_addend);
        }
  
      case R_ARM_TLS_GD32:
      case R_ARM_TLS_IE32:
        {
! 	bfd_vma off;
! 	int indx;
  	char tls_type;
  
! 	if (sgot == NULL)
! 	  abort ();
  
- 	indx = 0;
  	if (h != NULL)
  	  {
  	    bfd_boolean dyn;
--- 8396,8415 ----
  					 rel->r_addend);
        }
  
+     case R_ARM_TLS_CALL:
+     case R_ARM_THM_TLS_CALL:
      case R_ARM_TLS_GD32:
      case R_ARM_TLS_IE32:
+     case R_ARM_TLS_GOTDESC:
+     case R_ARM_TLS_DESCSEQ:
+     case R_ARM_THM_TLS_DESCSEQ:
        {
! 	bfd_vma off, offplt;
! 	int indx = 0;
  	char tls_type;
  
! 	BFD_ASSERT (sgot != NULL);
  
  	if (h != NULL)
  	  {
  	    bfd_boolean dyn;
*************** elf32_arm_final_link_relocate (reloc_how
*** 8033,8050 ****
  		indx = h->dynindx;
  	      }
  	    off = h->got.offset;
  	    tls_type = ((struct elf32_arm_link_hash_entry *) h)->tls_type;
  	  }
  	else
  	  {
! 	    if (local_got_offsets == NULL)
! 	      abort ();
  	    off = local_got_offsets[r_symndx];
  	    tls_type = elf32_arm_local_got_tls_type (input_bfd)[r_symndx];
  	  }
  
! 	if (tls_type == GOT_UNKNOWN)
! 	  abort ();
  
  	if ((off & 1) != 0)
  	  off &= ~1;
--- 8422,8444 ----
  		indx = h->dynindx;
  	      }
  	    off = h->got.offset;
+ 	    offplt = elf32_arm_hash_entry (h)->tlsdesc_got;
  	    tls_type = ((struct elf32_arm_link_hash_entry *) h)->tls_type;
  	  }
  	else
  	  {
! 	    BFD_ASSERT (local_got_offsets != NULL);
  	    off = local_got_offsets[r_symndx];
+ 	    offplt = local_tlsdesc_gotents[r_symndx];
  	    tls_type = elf32_arm_local_got_tls_type (input_bfd)[r_symndx];
  	  }
  
! 	/* Linker relaxations happens from one of the
! 	   R_ARM_{GOTDESC,CALL,DESCSEQ} relocations to IE or LE.  */ 
! 	if (ELF32_R_TYPE(rel->r_info) != r_type)
! 	  tls_type = GOT_TLS_IE; 
! 
! 	BFD_ASSERT (tls_type != GOT_UNKNOWN);
  
  	if ((off & 1) != 0)
  	  off &= ~1;
*************** elf32_arm_final_link_relocate (reloc_how
*** 8065,8076 ****
  		    || h->root.type != bfd_link_hash_undefweak))
  	      {
  		need_relocs = TRUE;
! 		if (srelgot == NULL)
! 		  abort ();
! 		loc = srelgot->contents;
! 		loc += srelgot->reloc_count * RELOC_SIZE (globals);
  	      }
  
  	    if (tls_type & GOT_TLS_GD)
  	      {
  		if (need_relocs)
--- 8459,8507 ----
  		    || h->root.type != bfd_link_hash_undefweak))
  	      {
  		need_relocs = TRUE;
! 		BFD_ASSERT (srelgot != NULL);
  	      }
  
+ 	    if (tls_type & GOT_TLS_GDESC)
+ 	      {
+ 		/* We should have relaxed, unless this is an undefined
+ 		   weak symbol.  */
+ 		BFD_ASSERT ((h && (h->root.type == bfd_link_hash_undefweak))
+ 			    || info->shared);
+ 		BFD_ASSERT (globals->sgotplt_jump_table_size + offplt + 8
+                             <= globals->root.sgotplt->size);
+ 
+ 		outrel.r_addend = 0;
+ 		outrel.r_offset = (globals->root.sgotplt->output_section->vma
+ 				   + globals->root.sgotplt->output_offset
+ 				   + offplt
+ 				   + globals->sgotplt_jump_table_size);
+ 		
+ 		outrel.r_info = ELF32_R_INFO (indx, R_ARM_TLS_DESC);
+ 		sreloc = globals->root.srelplt;
+ 		loc = sreloc->contents;
+ 		loc += globals->next_tls_desc_index++ * RELOC_SIZE (globals);
+ 		BFD_ASSERT (loc + RELOC_SIZE (globals)
+ 		   	   <= sreloc->contents + sreloc->size);
+ 
+ 		SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
+ 
+ 		/* For globals, the first word in the relocation gets
+ 		   the relocation index and the top bit set, or zero,
+ 		   if we're binding now.  For locals, it gets the
+ 		   symbol's offset in the tls section.  */
+ 	    	bfd_put_32 (output_bfd,
+ 			    !h ? value - elf_hash_table (info)->tls_sec->vma
+ 			    : info->flags & DF_BIND_NOW ? 0
+ 			    : 0x80000000 | ELF32_R_SYM (outrel.r_info),
+ 			    globals->root.sgotplt->contents + offplt +
+ 			    globals->sgotplt_jump_table_size);
+ 		
+ 		/* Second word in the relocation is always zero.  */
+ 	    	bfd_put_32 (output_bfd, 0,
+ 			    globals->root.sgotplt->contents + offplt +
+ 			    globals->sgotplt_jump_table_size + 4);
+ 	      }
  	    if (tls_type & GOT_TLS_GD)
  	      {
  		if (need_relocs)
*************** elf32_arm_final_link_relocate (reloc_how
*** 8084,8093 ****
  		    if (globals->use_rel)
  		      bfd_put_32 (output_bfd, outrel.r_addend,
  				  sgot->contents + cur_off);
  
  		    SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
- 		    srelgot->reloc_count++;
- 		    loc += RELOC_SIZE (globals);
  
  		    if (indx == 0)
  		      bfd_put_32 (output_bfd, value - dtpoff_base (info),
--- 8515,8524 ----
  		    if (globals->use_rel)
  		      bfd_put_32 (output_bfd, outrel.r_addend,
  				  sgot->contents + cur_off);
+ 		    loc = srelgot->contents;
+ 		    loc += srelgot->reloc_count++ * RELOC_SIZE (globals);
  
  		    SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
  
  		    if (indx == 0)
  		      bfd_put_32 (output_bfd, value - dtpoff_base (info),
*************** elf32_arm_final_link_relocate (reloc_how
*** 8103,8112 ****
  			  bfd_put_32 (output_bfd, outrel.r_addend,
  				      sgot->contents + cur_off + 4);
  
  
  			SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
- 			srelgot->reloc_count++;
- 			loc += RELOC_SIZE (globals);
  		      }
  		  }
  		else
--- 8534,8543 ----
  			  bfd_put_32 (output_bfd, outrel.r_addend,
  				      sgot->contents + cur_off + 4);
  
+ 		    	loc = srelgot->contents;
+ 		   	loc += srelgot->reloc_count++ * RELOC_SIZE (globals);
  
  			SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
  		      }
  		  }
  		else
*************** elf32_arm_final_link_relocate (reloc_how
*** 8142,8150 ****
  		      bfd_put_32 (output_bfd, outrel.r_addend,
  				  sgot->contents + cur_off);
  
  		    SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
- 		    srelgot->reloc_count++;
- 		    loc += RELOC_SIZE (globals);
  		  }
  		else
  		  bfd_put_32 (output_bfd, tpoff (info, value),
--- 8573,8582 ----
  		      bfd_put_32 (output_bfd, outrel.r_addend,
  				  sgot->contents + cur_off);
  
+ 		    loc = srelgot->contents;
+ 		    loc += srelgot->reloc_count++ * RELOC_SIZE (globals);
+ 
  		    SWAP_RELOC_OUT (globals) (output_bfd, &outrel, loc);
  		  }
  		else
  		  bfd_put_32 (output_bfd, tpoff (info, value),
*************** elf32_arm_final_link_relocate (reloc_how
*** 8160,8167 ****
  
  	if ((tls_type & GOT_TLS_GD) && r_type != R_ARM_TLS_GD32)
  	  off += 8;
! 	value = sgot->output_section->vma + sgot->output_offset + off
! 	  - (input_section->output_section->vma + input_section->output_offset + rel->r_offset);
  
  	return _bfd_final_link_relocate (howto, input_bfd, input_section,
  					 contents, rel->r_offset, value,
--- 8592,8733 ----
  
  	if ((tls_type & GOT_TLS_GD) && r_type != R_ARM_TLS_GD32)
  	  off += 8;
! 	else if (tls_type & GOT_TLS_GDESC)
! 	  off = offplt;
! 
! 	if (ELF32_R_TYPE(rel->r_info) == R_ARM_TLS_CALL
! 	    || ELF32_R_TYPE(rel->r_info) == R_ARM_THM_TLS_CALL)
! 	  {
! 	    bfd_signed_vma offset;
! 	    enum elf32_arm_stub_type stub_type
! 	      = arm_type_of_stub (info, input_section, rel, &sym_flags,
! 				  (struct elf32_arm_link_hash_entry *)h,
! 				  globals->tls_trampoline, globals->root.splt,
! 				  input_bfd, sym_name);
! 
! 	    if (stub_type != arm_stub_none)
! 	      {
! 		struct elf32_arm_stub_hash_entry *stub_entry
! 		  = elf32_arm_get_stub_entry
! 		  (input_section, globals->root.splt, 0, rel,
! 		   globals, stub_type);
! 		offset = (stub_entry->stub_offset
! 			  + stub_entry->stub_sec->output_offset
! 			  + stub_entry->stub_sec->output_section->vma);
! 	      }
! 	    else
! 	      offset = (globals->root.splt->output_section->vma
! 			+ globals->root.splt->output_offset
! 			+ globals->tls_trampoline);
! 
! 	    if (ELF32_R_TYPE(rel->r_info) == R_ARM_TLS_CALL)
! 	      {
! 		unsigned long inst;
! 		
! 		offset -= (input_section->output_section->vma +
! 			   input_section->output_offset + rel->r_offset + 8);
! 
! 		inst = offset >> 2;
! 		inst &= 0x00ffffff;
! 		value = inst | (globals->use_blx ? 0xfa000000 : 0xeb000000);
! 	      }
! 	    else
! 	      {
! 		/* Thumb blx encodes the offset in a complicated
! 		   fashion.  */
! 		unsigned upper_insn, lower_insn;
! 		unsigned neg;
! 
! 		offset -= (input_section->output_section->vma + 
! 			   input_section->output_offset
! 			   + rel->r_offset + 4);
! 	    
! 		/* Round up the offset to a word boundary */
! 		offset = (offset + 2) & ~2;
! 		neg = offset < 0;
! 		upper_insn = (0xf000
! 			      | ((offset >> 12) & 0x3ff)
! 			      | (neg << 10));
! 		lower_insn = (0xc000
! 			      | (((!((offset >> 23) & 1)) ^ neg) << 13)
! 			      | (((!((offset >> 22) & 1)) ^ neg) << 11)
! 			      | ((offset >> 1) & 0x7ff));
! 		bfd_put_16 (input_bfd, upper_insn, hit_data);
! 		bfd_put_16 (input_bfd, lower_insn, hit_data + 2);
! 		return bfd_reloc_ok;
! 	      }
! 	  }
! 	/* These relocations needs special care, as besides the fact
! 	   they point somewhere in .gotplt, the addend must be
! 	   adjusted accordingly depending on the type of instruction
! 	   we refer to */
! 	else if ((r_type == R_ARM_TLS_GOTDESC) && (tls_type & GOT_TLS_GDESC))
! 	  {
! 	    unsigned long data, insn;
! 	    unsigned thumb;
! 	    
! 	    data = bfd_get_32 (input_bfd, hit_data);
! 	    thumb = data & 1;
! 	    data &= ~1u;
! 	    
! 	    if (thumb)
! 	      {
! 		insn = bfd_get_16 (input_bfd, contents + rel->r_offset - data);
! 		if ((insn & 0xf000) == 0xf000 || (insn & 0xf800) == 0xe800)
! 		  insn = (insn << 16)
! 		    | bfd_get_16 (input_bfd,
! 				  contents + rel->r_offset - data + 2);
! 		if ((insn & 0xf800c000) == 0xf000c000)
! 		  /* bl/blx */
! 		  value = -6;
! 		else if ((insn & 0xffffff00) == 0x4400)
! 		  /* add */
! 		  value = -5;
! 		else
! 		  {
! 		    (*_bfd_error_handler)
! 		      (_("%B(%A+0x%lx):unexpected Thumb instruction '0x%x' referenced by TLS_GOTDESC"),
! 		       input_bfd, input_section,
! 		       (unsigned long)rel->r_offset, insn);
! 		    return bfd_reloc_notsupported;
! 		  }
! 	      }
! 	    else
! 	      {
! 		insn = bfd_get_32 (input_bfd, contents + rel->r_offset - data);
! 
! 		switch (insn >> 24)
! 		  {
! 		  case 0xeb:  /* bl */
! 		  case 0xfa:  /* blx */
! 		    value = -4;
! 		    break;
! 
! 		  case 0xe0:	/* add */
! 		    value = -8;
! 		    break;
! 		    
! 		  default:
! 		    (*_bfd_error_handler)
! 		      (_("%B(%A+0x%lx):unexpected ARM instruction '0x%x' referenced by TLS_GOTDESC"),
! 		       input_bfd, input_section,
! 		       (unsigned long)rel->r_offset, insn);
! 		    return bfd_reloc_notsupported;
! 		  }
! 	      }
!  
! 	    value += ((globals->root.sgotplt->output_section->vma
! 		       + globals->root.sgotplt->output_offset + off)
! 		      - (input_section->output_section->vma
! 			 + input_section->output_offset
! 			 + rel->r_offset)
! 		      + globals->sgotplt_jump_table_size);
! 	  }
! 	else
! 	  value = ((globals->root.sgot->output_section->vma
! 		    + globals->root.sgot->output_offset + off)
! 		   - (input_section->output_section->vma
! 		      + input_section->output_offset + rel->r_offset));
  
  	return _bfd_final_link_relocate (howto, input_bfd, input_section,
  					 contents, rel->r_offset, value,
*************** arm_add_to_rel (bfd *              abfd,
*** 8789,8795 ****
     || (R_TYPE) == R_ARM_TLS_DTPMOD32	\
     || (R_TYPE) == R_ARM_TLS_TPOFF32	\
     || (R_TYPE) == R_ARM_TLS_LE32	\
!    || (R_TYPE) == R_ARM_TLS_IE32)
  
  /* Relocate an ARM ELF section.  */
  
--- 9355,9370 ----
     || (R_TYPE) == R_ARM_TLS_DTPMOD32	\
     || (R_TYPE) == R_ARM_TLS_TPOFF32	\
     || (R_TYPE) == R_ARM_TLS_LE32	\
!    || (R_TYPE) == R_ARM_TLS_IE32	\
!    || IS_ARM_TLS_GNU_RELOC (R_TYPE))
! 
! /* Specific set of relocations for the gnu tls dialect.  */
! #define IS_ARM_TLS_GNU_RELOC(R_TYPE)	\
!   ((R_TYPE) == R_ARM_TLS_GOTDESC	\
!    || (R_TYPE) == R_ARM_TLS_CALL	\
!    || (R_TYPE) == R_ARM_THM_TLS_CALL	\
!    || (R_TYPE) == R_ARM_TLS_DESCSEQ	\
!    || (R_TYPE) == R_ARM_THM_TLS_DESCSEQ)
  
  /* Relocate an ARM ELF section.  */
  
*************** elf32_arm_relocate_section (bfd *       
*** 9032,9043 ****
  	     name);
  	}
  
!       r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
! 					 input_section, contents, rel,
! 					 relocation, info, sec, name,
! 					 (h ? ELF_ST_TYPE (h->type) :
! 					  ELF_ST_TYPE (sym->st_info)), h,
! 					 &unresolved_reloc, &error_message);
  
        /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
  	 because such sections are not SEC_ALLOC and thus ld.so will
--- 9607,9639 ----
  	     name);
  	}
  
!       /* We call elf32_arm_final_link_relocate unless we're completely
!          done, i.e., the relaxation produced the final output we want,
!          and we won't let anybody mess with it. Also, we have to do
!          addend adjustments in case of a R_ARM_TLS_GOTDESC relocation
!          both in relaxed and non-relaxed cases */
!      if ((elf32_arm_tls_transition (info, r_type, h) != (unsigned)r_type)
! 	 || (IS_ARM_TLS_GNU_RELOC (r_type)
! 	     && !((h ? elf32_arm_hash_entry (h)->tls_type : 
! 		   elf32_arm_local_got_tls_type (input_bfd)[r_symndx])
! 		  & GOT_TLS_GDESC)))
!        {
! 	 r = elf32_arm_tls_relax (globals, input_bfd, input_section,
! 				  contents, rel, h == NULL);
! 	 /* This may have been marked unresolved because it came from
! 	    a shared library.  But we've just dealt with that.  */
! 	 unresolved_reloc = 0;
!        }
!      else
!        r = bfd_reloc_continue;
!      
!      if (r == bfd_reloc_continue)
!        r = elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
! 					  input_section, contents, rel,
! 					  relocation, info, sec, name,
! 					  (h ? ELF_ST_TYPE (h->type) :
! 					   ELF_ST_TYPE (sym->st_info)), h,
! 					  &unresolved_reloc, &error_message);
  
        /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
  	 because such sections are not SEC_ALLOC and thus ld.so will
*************** elf32_arm_check_relocs (bfd *abfd, struc
*** 10780,10791 ****
--- 11376,11394 ----
  
        eh = (struct elf32_arm_link_hash_entry *) h;
  
+       /* Could be done earlier, if h were already available.  */
+       r_type = elf32_arm_tls_transition (info, r_type, h);
        switch (r_type)
          {
  	  case R_ARM_GOT32:
  	  case R_ARM_GOT_PREL:
  	  case R_ARM_TLS_GD32:
  	  case R_ARM_TLS_IE32:
+ 	  case R_ARM_TLS_GOTDESC:
+ 	  case R_ARM_TLS_DESCSEQ:
+ 	  case R_ARM_THM_TLS_DESCSEQ:
+ 	  case R_ARM_TLS_CALL:
+ 	  case R_ARM_THM_TLS_CALL:
  	    /* This symbol requires a global offset table entry.  */
  	    {
  	      int tls_type, old_tls_type;
*************** elf32_arm_check_relocs (bfd *abfd, struc
*** 10793,10799 ****
--- 11396,11409 ----
  	      switch (r_type)
  		{
  		case R_ARM_TLS_GD32: tls_type = GOT_TLS_GD; break;
+ 		  
  		case R_ARM_TLS_IE32: tls_type = GOT_TLS_IE; break;
+ 		  
+ 		case R_ARM_TLS_GOTDESC:
+ 		case R_ARM_TLS_CALL: case R_ARM_THM_TLS_CALL:
+ 		case R_ARM_TLS_DESCSEQ: case R_ARM_THM_TLS_DESCSEQ:
+ 		  tls_type = GOT_TLS_GDESC; break;
+ 		  
  		default: tls_type = GOT_NORMAL; break;
  		}
  
*************** elf32_arm_check_relocs (bfd *abfd, struc
*** 10813,10839 ****
  		      bfd_size_type size;
  
  		      size = symtab_hdr->sh_info;
! 		      size *= (sizeof (bfd_signed_vma) + sizeof (char));
  		      local_got_refcounts = (bfd_signed_vma *)
                            bfd_zalloc (abfd, size);
  		      if (local_got_refcounts == NULL)
  			return FALSE;
  		      elf_local_got_refcounts (abfd) = local_got_refcounts;
  		      elf32_arm_local_got_tls_type (abfd)
! 			= (char *) (local_got_refcounts + symtab_hdr->sh_info);
  		    }
  		  local_got_refcounts[r_symndx] += 1;
  		  old_tls_type = elf32_arm_local_got_tls_type (abfd) [r_symndx];
  		}
  
! 	      /* We will already have issued an error message if there is a
! 		 TLS / non-TLS mismatch, based on the symbol type.  We don't
! 		 support any linker relaxations.  So just combine any TLS
! 		 types needed.  */
  	      if (old_tls_type != GOT_UNKNOWN && old_tls_type != GOT_NORMAL
  		  && tls_type != GOT_NORMAL)
  		tls_type |= old_tls_type;
  
  	      if (old_tls_type != tls_type)
  		{
  		  if (h != NULL)
--- 11423,11466 ----
  		      bfd_size_type size;
  
  		      size = symtab_hdr->sh_info;
! 		      size *= (sizeof (bfd_signed_vma)
! 			       + sizeof (bfd_vma) + sizeof (char));
  		      local_got_refcounts = (bfd_signed_vma *)
                            bfd_zalloc (abfd, size);
  		      if (local_got_refcounts == NULL)
  			return FALSE;
  		      elf_local_got_refcounts (abfd) = local_got_refcounts;
+ 		      elf32_arm_local_tlsdesc_gotent (abfd)
+ 		        = (bfd_vma *) (local_got_refcounts
+ 				       + symtab_hdr->sh_info);
  		      elf32_arm_local_got_tls_type (abfd)
! 			= (char *) (elf32_arm_local_tlsdesc_gotent (abfd)
! 				    + symtab_hdr->sh_info);
  		    }
  		  local_got_refcounts[r_symndx] += 1;
  		  old_tls_type = elf32_arm_local_got_tls_type (abfd) [r_symndx];
  		}
  
! 	      /* If a variable is accessed with both tls methods, two
! 	         slots may be created.  */
! 	      if (GOT_TLS_GD_ANY_P (old_tls_type)
! 		  && GOT_TLS_GD_ANY_P (tls_type))
! 		tls_type |= old_tls_type;
! 
! 	      /* We will already have issued an error message if there
! 		 is a TLS/non-TLS mismatch, based on the symbol
! 		 type.  So just combine any TLS types needed.  */
  	      if (old_tls_type != GOT_UNKNOWN && old_tls_type != GOT_NORMAL
  		  && tls_type != GOT_NORMAL)
  		tls_type |= old_tls_type;
  
+ 	      /* If the symbol is accessed in both IE and GDESC
+ 	         method, we're able to relax. Turn off the GDESC flag,
+ 	         without messing up with any other kind of tls types
+ 	         that may be involved */
+ 	      if ((tls_type & GOT_TLS_IE) && (tls_type & GOT_TLS_GDESC))
+ 		tls_type &= ~GOT_TLS_GDESC;
+ 
  	      if (old_tls_type != tls_type)
  		{
  		  if (h != NULL)
*************** allocate_dynrelocs (struct elf_link_hash
*** 11454,11465 ****
  	    {
  	      /* We also need to make an entry in the .got.plt section, which
  		 will be placed in the .got section by the linker script.  */
! 	      eh->plt_got_offset = htab->root.sgotplt->size;
  	      htab->root.sgotplt->size += 4;
  	    }
  
  	  /* We also need to make an entry in the .rel(a).plt section.  */
  	  htab->root.srelplt->size += RELOC_SIZE (htab);
  
  	  /* VxWorks executables have a second set of relocations for
  	     each PLT entry.  They go in a separate relocation section,
--- 12081,12094 ----
  	    {
  	      /* We also need to make an entry in the .got.plt section, which
  		 will be placed in the .got section by the linker script.  */
! 	      eh->plt_got_offset = (htab->root.sgotplt->size
! 				    - 8 * htab->num_tls_desc);
  	      htab->root.sgotplt->size += 4;
  	    }
  
  	  /* We also need to make an entry in the .rel(a).plt section.  */
  	  htab->root.srelplt->size += RELOC_SIZE (htab);
+ 	  htab->next_tls_desc_index++;
  
  	  /* VxWorks executables have a second set of relocations for
  	     each PLT entry.  They go in a separate relocation section,
*************** allocate_dynrelocs (struct elf_link_hash
*** 11489,11494 ****
--- 12118,12126 ----
        h->needs_plt = 0;
      }
  
+   eh = (struct elf32_arm_link_hash_entry *) h;
+   eh->tlsdesc_got = (bfd_vma) -1;
+ 
    if (h->got.refcount > 0)
      {
        asection *s;
*************** allocate_dynrelocs (struct elf_link_hash
*** 11518,11526 ****
  	    s->size += 4;
  	  else
  	    {
  	      if (tls_type & GOT_TLS_GD)
! 		/* R_ARM_TLS_GD32 needs 2 consecutive GOT slots.  */
! 		s->size += 8;
  	      if (tls_type & GOT_TLS_IE)
  		/* R_ARM_TLS_IE32 needs one GOT slot.  */
  		s->size += 4;
--- 12150,12177 ----
  	    s->size += 4;
  	  else
  	    {
+               if (tls_type & GOT_TLS_GDESC)
+ 	        {
+ 		  /* R_ARM_TLS_DESC needs 2 GOT slots.  */
+ 	          eh->tlsdesc_got
+ 		    = (htab->root.sgotplt->size
+ 		       - elf32_arm_compute_jump_table_size (htab));
+ 	          htab->root.sgotplt->size += 8;
+ 	          h->got.offset = (bfd_vma) -2;
+ 		  /* plt_got_offset needs to know there's a TLS_DESC
+ 		     reloc in the middle of .got.plt.  */
+                   htab->num_tls_desc++;
+ 	        }
+ 
  	      if (tls_type & GOT_TLS_GD)
! 		{
! 		  /* R_ARM_TLS_GD32 needs 2 consecutive GOT slots.  If
! 		     the symbol is both GD and GDESC, got.offset may
! 		     have been overwritten.  */
! 		  h->got.offset = s->size;
! 		  s->size += 8;
! 		}
! 
  	      if (tls_type & GOT_TLS_IE)
  		/* R_ARM_TLS_IE32 needs one GOT slot.  */
  		s->size += 4;
*************** allocate_dynrelocs (struct elf_link_hash
*** 11545,11552 ****
  	      if (tls_type & GOT_TLS_GD)
  		htab->root.srelgot->size += RELOC_SIZE (htab);
  
! 	      if ((tls_type & GOT_TLS_GD) && indx != 0)
! 		htab->root.srelgot->size += RELOC_SIZE (htab);
  	    }
  	  else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
  		    || h->root.type != bfd_link_hash_undefweak)
--- 12196,12212 ----
  	      if (tls_type & GOT_TLS_GD)
  		htab->root.srelgot->size += RELOC_SIZE (htab);
  
! 	      if (tls_type & GOT_TLS_GDESC) 
! 		{
! 		  htab->root.srelplt->size += RELOC_SIZE (htab); 
! 		  /* GDESC needs a trampoline to jump to.  */
! 		  htab->tls_trampoline = -1;
! 		}
! 
! 	      /* Only GD needs it.  GDESC just emits one relocation per
! 		 2 entries.  */
! 	      if ((tls_type & GOT_TLS_GD) && indx != 0)  
! 		htab->root.srelgot->size += RELOC_SIZE (htab); 
  	    }
  	  else if ((ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
  		    || h->root.type != bfd_link_hash_undefweak)
*************** elf32_arm_size_dynamic_sections (bfd * o
*** 11788,11793 ****
--- 12448,12454 ----
        bfd_signed_vma *local_got;
        bfd_signed_vma *end_local_got;
        char *local_tls_type;
+       bfd_vma *local_tlsdesc_gotent;
        bfd_size_type locsymcount;
        Elf_Internal_Shdr *symtab_hdr;
        asection *srel;
*************** elf32_arm_size_dynamic_sections (bfd * o
*** 11836,11858 ****
        locsymcount = symtab_hdr->sh_info;
        end_local_got = local_got + locsymcount;
        local_tls_type = elf32_arm_local_got_tls_type (ibfd);
        s = htab->root.sgot;
        srel = htab->root.srelgot;
!       for (; local_got < end_local_got; ++local_got, ++local_tls_type)
  	{
  	  if (*local_got > 0)
  	    {
  	      *local_got = s->size;
  	      if (*local_tls_type & GOT_TLS_GD)
  		/* TLS_GD relocs need an 8-byte structure in the GOT.  */
  		s->size += 8;
  	      if (*local_tls_type & GOT_TLS_IE)
  		s->size += 4;
- 	      if (*local_tls_type == GOT_NORMAL)
- 		s->size += 4;
  
! 	      if (info->shared || *local_tls_type == GOT_TLS_GD)
  		srel->size += RELOC_SIZE (htab);
  	    }
  	  else
  	    *local_got = (bfd_vma) -1;
--- 12497,12545 ----
        locsymcount = symtab_hdr->sh_info;
        end_local_got = local_got + locsymcount;
        local_tls_type = elf32_arm_local_got_tls_type (ibfd);
+       local_tlsdesc_gotent = elf32_arm_local_tlsdesc_gotent (ibfd);
        s = htab->root.sgot;
        srel = htab->root.srelgot;
!       for (; local_got < end_local_got;
! 	   ++local_got, ++local_tls_type, ++local_tlsdesc_gotent)
  	{
+ 	  *local_tlsdesc_gotent = (bfd_vma) -1;
  	  if (*local_got > 0)
  	    {
  	      *local_got = s->size;
  	      if (*local_tls_type & GOT_TLS_GD)
  		/* TLS_GD relocs need an 8-byte structure in the GOT.  */
  		s->size += 8;
+ 	      if (*local_tls_type & GOT_TLS_GDESC)
+ 		{
+ 		  *local_tlsdesc_gotent = htab->root.sgotplt->size
+ 		    - elf32_arm_compute_jump_table_size (htab);
+ 		  htab->root.sgotplt->size += 8;
+ 		  *local_got = (bfd_vma) -2;
+ 		  /* plt_got_offset needs to know there's a TLS_DESC
+ 		     reloc in the middle of .got.plt.  */
+                   htab->num_tls_desc++;
+ 		}
  	      if (*local_tls_type & GOT_TLS_IE)
  		s->size += 4;
  
! 	      if (*local_tls_type & GOT_NORMAL)
! 		{
! 		  /* If the symbol is both GD and GDESC, *local_got
! 		     may have been overwritten.  */
! 		  *local_got = s->size;
! 		  s->size += 4;
! 		}
! 
! 	      if ((info->shared && !(*local_tls_type & GOT_TLS_GDESC))
! 		  || *local_tls_type & GOT_TLS_GD)
  		srel->size += RELOC_SIZE (htab);
+ 
+ 	      if (info->shared && *local_tls_type & GOT_TLS_GDESC)
+ 		{
+ 		  htab->root.srelplt->size += RELOC_SIZE (htab);
+ 		  htab->tls_trampoline = -1;
+ 		}
  	    }
  	  else
  	    *local_got = (bfd_vma) -1;
*************** elf32_arm_size_dynamic_sections (bfd * o
*** 11894,11899 ****
--- 12581,12614 ----
    /* Allocate space for the glue sections now that we've sized them.  */
    bfd_elf32_arm_allocate_interworking_sections (info);
  
+   /* For every jump slot reserved in the sgotplt, reloc_count is
+      incremented.  However, when we reserve space for TLS descriptors,
+      it's not incremented, so in order to compute the space reserved
+      for them, it suffices to multiply the reloc count by the jump
+      slot size.  */
+   if (htab->root.srelplt)
+     htab->sgotplt_jump_table_size = elf32_arm_compute_jump_table_size(htab);
+ 
+   if (htab->tls_trampoline)
+     {
+       if (htab->root.splt->size == 0)
+ 	htab->root.splt->size += htab->plt_header_size;
+       
+       htab->tls_trampoline = htab->root.splt->size;
+       htab->root.splt->size += htab->plt_entry_size;
+       
+       /* If we're not using lazy TLS relocations, don't generate the
+          PLT and GOT entries they require.  */
+       if (!(info->flags & DF_BIND_NOW))
+ 	{
+ 	  htab->dt_tlsdesc_got = htab->root.sgot->size;
+ 	  htab->root.sgot->size += 4;
+ 
+ 	  htab->dt_tlsdesc_plt = htab->root.splt->size;
+ 	  htab->root.splt->size += 4 * ARRAY_SIZE (dl_tlsdesc_lazy_trampoline);
+ 	}
+     }
+ 
    /* The check_relocs and adjust_dynamic_symbol entry points have
       determined the sizes of the various dynamic sections.  Allocate
       memory for them.  */
*************** elf32_arm_size_dynamic_sections (bfd * o
*** 11984,11989 ****
--- 12699,12709 ----
  				     htab->use_rel ? DT_REL : DT_RELA)
  	      || !add_dynamic_entry (DT_JMPREL, 0))
  	    return FALSE;
+ 
+ 	  if (htab->dt_tlsdesc_plt &&
+ 		(!add_dynamic_entry (DT_TLSDESC_PLT,0) 
+ 		 || !add_dynamic_entry (DT_TLSDESC_GOT,0)))
+ 	    return FALSE; 
  	}
  
        if (relocs)
*************** elf32_arm_size_dynamic_sections (bfd * o
*** 12024,12029 ****
--- 12744,12792 ----
    return TRUE;
  }
  
+ /* Size sections even though they're not dynamic.  We use it to setup
+    _TLS_MODULE_BASE_, if needed.  */
+ 
+ static bfd_boolean
+ elf32_arm_always_size_sections (bfd *output_bfd,
+ 	                        struct bfd_link_info *info)
+ {
+   asection *tls_sec;
+ 
+   if (info->relocatable)
+     return TRUE;
+ 
+   tls_sec = elf_hash_table (info)->tls_sec;
+ 
+   if (tls_sec)
+     {
+       struct elf_link_hash_entry *tlsbase;
+ 
+       tlsbase = elf_link_hash_lookup
+ 	(elf_hash_table (info), "_TLS_MODULE_BASE_", TRUE, TRUE, FALSE);
+ 
+       if (tlsbase)
+         {
+           struct bfd_link_hash_entry *bh = NULL;
+ 	  const struct elf_backend_data *bed
+             = get_elf_backend_data (output_bfd);
+ 
+           if (!(_bfd_generic_link_add_one_symbol
+ 		(info, output_bfd, "_TLS_MODULE_BASE_", BSF_LOCAL,
+ 		 tls_sec, 0, NULL, FALSE,
+ 		 bed->collect, &bh)))
+ 	    return FALSE;
+ 	  
+       	  tlsbase->type = STT_TLS;
+           tlsbase = (struct elf_link_hash_entry *)bh;
+           tlsbase->def_regular = 1;
+           tlsbase->other = STV_HIDDEN;
+           (*bed->elf_backend_hide_symbol) (info, tlsbase, TRUE);
+ 	}
+     }
+   return TRUE;
+ }
+ 
  /* Finish up dynamic symbol handling.  We set the contents of various
     dynamic sections here.  */
  
*************** elf32_arm_finish_dynamic_symbol (bfd * o
*** 12240,12246 ****
      }
  
    if (h->got.offset != (bfd_vma) -1
!       && (elf32_arm_hash_entry (h)->tls_type & GOT_TLS_GD) == 0
        && (elf32_arm_hash_entry (h)->tls_type & GOT_TLS_IE) == 0)
      {
        asection * sgot;
--- 13003,13009 ----
      }
  
    if (h->got.offset != (bfd_vma) -1
!       && (! GOT_TLS_GD_ANY_P (elf32_arm_hash_entry (h)->tls_type)) 
        && (elf32_arm_hash_entry (h)->tls_type & GOT_TLS_IE) == 0)
      {
        asection * sgot;
*************** elf32_arm_finish_dynamic_symbol (bfd * o
*** 12321,12326 ****
--- 13084,13107 ----
    return TRUE;
  }
  
+ static void
+ arm_put_trampoline (struct elf32_arm_link_hash_table *htab, bfd *output_bfd,
+ 		    void *contents,
+ 		    const unsigned long *template, unsigned count)
+ {
+   unsigned ix;
+   
+   for (ix = 0; ix != count; ix++)
+     {
+       unsigned long insn = template[ix];
+ 
+       /* Emit mov pc,rx if bx is not permitted.  */
+       if (htab->fix_v4bx == 1 && (insn & 0x0ffffff0) == 0x012fff10)
+ 	insn = (insn & 0xf000000f) | 0x01a0f000;
+       put_arm_insn (htab, output_bfd, insn, (char *)contents + ix*4);
+     }
+ }
+ 
  /* Finish up the dynamic sections.  */
  
  static bfd_boolean
*************** elf32_arm_finish_dynamic_sections (bfd *
*** 12474,12479 ****
--- 13255,13274 ----
  		}
  	      break;
  
+ 	    case DT_TLSDESC_PLT:
+               s = htab->root.splt;
+ 	      dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
+ 				+ htab->dt_tlsdesc_plt);
+ 	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ 	      break;
+ 
+ 	    case DT_TLSDESC_GOT:
+               s = htab->root.sgot;
+ 	      dyn.d_un.d_ptr = (s->output_section->vma + s->output_offset
+ 		      		+ htab->dt_tlsdesc_got);
+ 	      bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
+ 	      break;
+ 
  	      /* Set the bottom bit of DT_INIT/FINI if the
  		 corresponding function is Thumb.  */
  	    case DT_INIT:
*************** elf32_arm_finish_dynamic_sections (bfd *
*** 12563,12568 ****
--- 13358,13398 ----
        if (splt->output_section->owner == output_bfd)
  	elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
  
+       if (htab->dt_tlsdesc_plt)
+ 	{
+ 	  bfd_vma got_address
+ 	    = sgot->output_section->vma + sgot->output_offset;
+ 	  bfd_vma gotplt_address = (htab->root.sgot->output_section->vma
+ 				    + htab->root.sgot->output_offset);
+ 	  bfd_vma plt_address
+ 	    = splt->output_section->vma + splt->output_offset;
+ 
+ 	  arm_put_trampoline (htab, output_bfd, 
+ 			      splt->contents + htab->dt_tlsdesc_plt,
+ 			      dl_tlsdesc_lazy_trampoline, 6);
+ 
+ 	  bfd_put_32 (output_bfd,
+ 		      gotplt_address + htab->dt_tlsdesc_got
+ 		      - (plt_address + htab->dt_tlsdesc_plt)
+ 		      - dl_tlsdesc_lazy_trampoline[6],
+ 		      splt->contents + htab->dt_tlsdesc_plt + 24);
+ 	  bfd_put_32 (output_bfd,
+ 		      got_address - (plt_address + htab->dt_tlsdesc_plt)
+ 		      - dl_tlsdesc_lazy_trampoline[7],
+ 		      splt->contents + htab->dt_tlsdesc_plt + 24 + 4);
+ 	}
+ 
+       if (htab->tls_trampoline)
+ 	{
+ 	  arm_put_trampoline (htab, output_bfd, 
+ 			      splt->contents + htab->tls_trampoline,
+ 			      tls_trampoline, 3);
+ #ifdef FOUR_WORD_PLT
+ 	  bfd_put_32 (output_bfd, 0x00000000,
+ 		      splt->contents + htab->tls_trampoline + 12);
+ #endif 
+ 	}
+ 
        if (htab->vxworks_p && !info->shared && htab->root.splt->size > 0)
  	{
  	  /* Correct the .rel(a).plt.unloaded relocations.  They will have
*************** elf32_arm_output_arch_local_syms (bfd *o
*** 13137,13142 ****
--- 13967,13994 ----
  #endif
      }
  
+   if (htab->dt_tlsdesc_plt != 0)
+     {
+       /* Mapping symbols for the lazy tls trampoline.  */
+       if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, htab->dt_tlsdesc_plt))
+ 	return FALSE;
+        
+       if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA,
+ 				     htab->dt_tlsdesc_plt + 24))
+ 	return FALSE;
+     }
+   if (htab->tls_trampoline != 0)
+     {
+       /* Mapping symbols for the tls trampoline.  */
+       if (!elf32_arm_output_map_sym (&osi, ARM_MAP_ARM, htab->tls_trampoline))
+ 	return FALSE;
+ #ifdef FOUR_WORD_PLT
+       if (!elf32_arm_output_map_sym (&osi, ARM_MAP_DATA,
+ 				     htab->tls_trampoline + 12))
+ 	return FALSE;
+ #endif 
+     }
+   
    elf_link_hash_traverse (&htab->root, elf32_arm_output_plt_map, (void *) &osi);
    return TRUE;
  }
*************** const struct elf_size_info elf32_arm_siz
*** 13795,13800 ****
--- 14647,14653 ----
  #define elf_backend_finish_dynamic_symbol	elf32_arm_finish_dynamic_symbol
  #define elf_backend_finish_dynamic_sections	elf32_arm_finish_dynamic_sections
  #define elf_backend_size_dynamic_sections	elf32_arm_size_dynamic_sections
+ #define elf_backend_always_size_sections	elf32_arm_always_size_sections
  #define elf_backend_init_index_section		_bfd_elf_init_2_index_sections
  #define elf_backend_post_process_headers	elf32_arm_post_process_headers
  #define elf_backend_reloc_type_class		elf32_arm_reloc_type_class
Index: bfd/libbfd.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd.h,v
retrieving revision 1.245
diff -c -3 -p -r1.245 libbfd.h
*** bfd/libbfd.h	5 Jan 2011 22:04:08 -0000	1.245
--- bfd/libbfd.h	7 Jan 2011 13:09:02 -0000
*************** static const char *const bfd_reloc_code_
*** 1377,1382 ****
--- 1377,1388 ----
    "BFD_RELOC_ARM_TLS_TPOFF32",
    "BFD_RELOC_ARM_TLS_IE32",
    "BFD_RELOC_ARM_TLS_LE32",
+   "BFD_RELOC_ARM_TLS_GOTDESC",
+   "BFD_RELOC_ARM_TLS_CALL",
+   "BFD_RELOC_ARM_THM_TLS_CALL",
+   "BFD_RELOC_ARM_TLS_DESCSEQ",
+   "BFD_RELOC_ARM_THM_TLS_DESCSEQ",
+   "BFD_RELOC_ARM_TLS_DESC",
    "BFD_RELOC_ARM_ALU_PC_G0_NC",
    "BFD_RELOC_ARM_ALU_PC_G0",
    "BFD_RELOC_ARM_ALU_PC_G1_NC",
Index: bfd/reloc.c
===================================================================
RCS file: /cvs/src/src/bfd/reloc.c,v
retrieving revision 1.210
diff -c -3 -p -r1.210 reloc.c
*** bfd/reloc.c	5 Jan 2011 22:04:09 -0000	1.210
--- bfd/reloc.c	7 Jan 2011 13:09:03 -0000
*************** ENUMX
*** 2962,2967 ****
--- 2962,2979 ----
    BFD_RELOC_ARM_TLS_IE32
  ENUMX
    BFD_RELOC_ARM_TLS_LE32
+ ENUMX
+   BFD_RELOC_ARM_TLS_GOTDESC
+ ENUMX
+   BFD_RELOC_ARM_TLS_CALL
+ ENUMX
+   BFD_RELOC_ARM_THM_TLS_CALL
+ ENUMX
+   BFD_RELOC_ARM_TLS_DESCSEQ
+ ENUMX
+   BFD_RELOC_ARM_THM_TLS_DESCSEQ
+ ENUMX
+   BFD_RELOC_ARM_TLS_DESC
  ENUMDOC
    ARM thread-local storage relocations.
  
Index: gas/config/tc-arm.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-arm.c,v
retrieving revision 1.473
diff -c -3 -p -r1.473 tc-arm.c
*** gas/config/tc-arm.c	15 Nov 2010 10:03:04 -0000	1.473
--- gas/config/tc-arm.c	7 Jan 2011 13:09:10 -0000
*************** arm_typed_reg_parse (char **ccp, enum ar
*** 1472,1477 ****
--- 1472,1481 ----
    if (reg == FAIL)
      return FAIL;
  
+   /* Do not allow regname(... to parse as a register.  */
+   if (*str == '(')
+     return FAIL;
+ 
    /* Do not allow a scalar (reg+index) to parse as a register.  */
    if ((atype.defined & NTA_HASINDEX) != 0)
      {
*************** s_arm_eabi_attribute (int ignored ATTRIB
*** 4273,4278 ****
--- 4277,4306 ----
  }
  #endif /* OBJ_ELF */
  
+ /* Emit a tls fix for the symbol.  */
+ 
+ static void
+ s_arm_tls_descseq (int ignored ATTRIBUTE_UNUSED)
+ {
+   char *p;
+   expressionS exp;
+ #ifdef md_flush_pending_output
+   md_flush_pending_output ();
+ #endif
+ 
+ #ifdef md_cons_align
+   md_cons_align (4);
+ #endif
+ 
+   /* Since we're just labelling the code, there's no need to define a
+      mapping symbol.  */
+   expression (&exp);
+   p = obstack_next_free (&frchain_now->frch_obstack);
+   fix_new_arm (frag_now, p - frag_now->fr_literal, 4, &exp, 0,
+ 	       thumb_mode ? BFD_RELOC_ARM_THM_TLS_DESCSEQ
+ 	       : BFD_RELOC_ARM_TLS_DESCSEQ);
+ }
+ 
  static void s_arm_arch (int);
  static void s_arm_object_arch (int);
  static void s_arm_cpu (int);
*************** const pseudo_typeS md_pseudo_table[] =
*** 4352,4357 ****
--- 4380,4386 ----
    { "setfp",		s_arm_unwind_setfp,	0 },
    { "unwind_raw",	s_arm_unwind_raw,	0 },
    { "eabi_attribute",	s_arm_eabi_attribute,	0 },
+   { "tlsdescseq",	s_arm_tls_descseq,      0 },
  #else
    { "word",	   cons, 4},
  
*************** encode_branch (int default_reloc)
*** 7281,7289 ****
  {
    if (inst.operands[0].hasreloc)
      {
!       constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32,
! 		  _("the only suffix valid here is '(plt)'"));
!       inst.reloc.type  = BFD_RELOC_ARM_PLT32;
      }
    else
      inst.reloc.type = (bfd_reloc_code_real_type) default_reloc;
--- 7310,7321 ----
  {
    if (inst.operands[0].hasreloc)
      {
!       constraint (inst.operands[0].imm != BFD_RELOC_ARM_PLT32
! 		  && inst.operands[0].imm != BFD_RELOC_ARM_TLS_CALL,
! 		  _("the only valid suffixes here are '(plt)' and '(tlscall)'"));
!       inst.reloc.type = inst.operands[0].imm == BFD_RELOC_ARM_PLT32
! 	? BFD_RELOC_ARM_PLT32
! 	: thumb_mode ? BFD_RELOC_ARM_THM_TLS_CALL : BFD_RELOC_ARM_TLS_CALL;
      }
    else
      inst.reloc.type = (bfd_reloc_code_real_type) default_reloc;
*************** do_t_blx (void)
*** 9655,9662 ****
      {
        /* No register.  This must be BLX(1).  */
        inst.instruction = 0xf000e800;
!       inst.reloc.type = BFD_RELOC_THUMB_PCREL_BLX;
!       inst.reloc.pc_rel = 1;
      }
  }
  
--- 9687,9693 ----
      {
        /* No register.  This must be BLX(1).  */
        inst.instruction = 0xf000e800;
!       encode_branch (BFD_RELOC_THUMB_PCREL_BLX);
      }
  }
  
*************** static void
*** 9734,9741 ****
  do_t_branch23 (void)
  {
    set_it_insn_type_last ();
!   inst.reloc.type   = BFD_RELOC_THUMB_PCREL_BRANCH23;
!   inst.reloc.pc_rel = 1;
  
  #if defined(OBJ_COFF)
    /* If the destination of the branch is a defined symbol which does not have
--- 9765,9779 ----
  do_t_branch23 (void)
  {
    set_it_insn_type_last ();
!   encode_branch (BFD_RELOC_THUMB_PCREL_BRANCH23);
!   
!   /* md_apply_fix blows up with 'bl foo(PLT)' where foo is defined in
!      this file.  We used to simply ignore the PLT reloc type here --
!      the branch encoding is now needed to deal with TLSCALL relocs.
!      So if we see a PLT reloc now, put it back to how it used to be to
!      keep the preexisting behaviour.  */
!   if (inst.reloc.type == BFD_RELOC_ARM_PLT32)
!     inst.reloc.type = BFD_RELOC_THUMB_PCREL_BRANCH23;
  
  #if defined(OBJ_COFF)
    /* If the destination of the branch is a defined symbol which does not have
*************** static struct reloc_entry reloc_names[] 
*** 16517,16523 ****
    { "tlsldo",  BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO",  BFD_RELOC_ARM_TLS_LDO32},
    { "gottpoff",BFD_RELOC_ARM_TLS_IE32},  { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
    { "tpoff",   BFD_RELOC_ARM_TLS_LE32},  { "TPOFF",   BFD_RELOC_ARM_TLS_LE32},
!   { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL}
  };
  #endif
  
--- 16555,16567 ----
    { "tlsldo",  BFD_RELOC_ARM_TLS_LDO32}, { "TLSLDO",  BFD_RELOC_ARM_TLS_LDO32},
    { "gottpoff",BFD_RELOC_ARM_TLS_IE32},  { "GOTTPOFF",BFD_RELOC_ARM_TLS_IE32},
    { "tpoff",   BFD_RELOC_ARM_TLS_LE32},  { "TPOFF",   BFD_RELOC_ARM_TLS_LE32},
!   { "got_prel", BFD_RELOC_ARM_GOT_PREL}, { "GOT_PREL", BFD_RELOC_ARM_GOT_PREL},
!   { "tlsdesc", BFD_RELOC_ARM_TLS_GOTDESC},
!   	{ "TLSDESC", BFD_RELOC_ARM_TLS_GOTDESC},
!   { "tlscall", BFD_RELOC_ARM_TLS_CALL},
!   	{ "TLSCALL", BFD_RELOC_ARM_TLS_CALL},
!   { "tlsdescseq", BFD_RELOC_ARM_TLS_DESCSEQ},
!   	{ "TLSDESCSEQ", BFD_RELOC_ARM_TLS_DESCSEQ}
  };
  #endif
  
*************** md_apply_fix (fixS *	fixP,
*** 20835,20840 ****
--- 20879,20892 ----
        break;
  
  #ifdef OBJ_ELF
+     case BFD_RELOC_ARM_TLS_CALL:
+     case BFD_RELOC_ARM_THM_TLS_CALL:
+     case BFD_RELOC_ARM_TLS_DESCSEQ:
+     case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
+       S_SET_THREAD_LOCAL (fixP->fx_addsy);
+       break;
+ 
+     case BFD_RELOC_ARM_TLS_GOTDESC:
      case BFD_RELOC_ARM_TLS_GD32:
      case BFD_RELOC_ARM_TLS_LE32:
      case BFD_RELOC_ARM_TLS_IE32:
*************** tc_gen_reloc (asection *section, fixS *f
*** 21436,21441 ****
--- 21488,21497 ----
        return NULL;
  
  #ifdef OBJ_ELF
+     case BFD_RELOC_ARM_TLS_CALL:
+     case BFD_RELOC_ARM_THM_TLS_CALL:
+     case BFD_RELOC_ARM_TLS_DESCSEQ:
+     case BFD_RELOC_ARM_THM_TLS_DESCSEQ:
      case BFD_RELOC_ARM_GOT32:
      case BFD_RELOC_ARM_GOTOFF:
      case BFD_RELOC_ARM_GOT_PREL:
*************** tc_gen_reloc (asection *section, fixS *f
*** 21481,21486 ****
--- 21537,21543 ----
        code = fixp->fx_r_type;
        break;
  
+     case BFD_RELOC_ARM_TLS_GOTDESC:
      case BFD_RELOC_ARM_TLS_GD32:
      case BFD_RELOC_ARM_TLS_IE32:
      case BFD_RELOC_ARM_TLS_LDM32:
*************** arm_fix_adjustable (fixS * fixP)
*** 21742,21747 ****
--- 21799,21809 ----
        || fixP->fx_r_type == BFD_RELOC_ARM_TLS_IE32
        || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDM32
        || fixP->fx_r_type == BFD_RELOC_ARM_TLS_LDO32
+       || fixP->fx_r_type == BFD_RELOC_ARM_TLS_GOTDESC
+       || fixP->fx_r_type == BFD_RELOC_ARM_TLS_CALL
+       || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_CALL
+       || fixP->fx_r_type == BFD_RELOC_ARM_TLS_DESCSEQ
+       || fixP->fx_r_type == BFD_RELOC_ARM_THM_TLS_DESCSEQ
        || fixP->fx_r_type == BFD_RELOC_ARM_TARGET2)
      return FALSE;
  
Index: gas/doc/c-arm.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-arm.texi,v
retrieving revision 1.81
diff -c -3 -p -r1.81 c-arm.texi
*** gas/doc/c-arm.texi	23 Sep 2010 15:52:18 -0000	1.81
--- gas/doc/c-arm.texi	7 Jan 2011 13:09:11 -0000
*************** The following relocations are supported:
*** 478,483 ****
--- 478,485 ----
  @code{TLSGD},
  @code{TLSLDM},
  @code{TLSLDO},
+ @code{TLSDESC},
+ @code{TLSCALL},
  @code{GOTTPOFF},
  @code{GOT_PREL}
  and
*************** defined).  This directive also has the a
*** 864,869 ****
--- 866,877 ----
  the aliased symbol as being a thumb function entry point, in the same
  way that the @code{.thumb_func} directive does.
  
+ @cindex @code{.tlsdescseq} directive, ARM
+ @item .tlsdescseq @var{tls-variable}
+ This directive is used to annotate parts of an inlined TLS descriptor
+ trampoline.  Normally the trampoline is provided by the linker, and
+ this directive is not needed.
+ 
  @c UUUUUUUUUUUUUUUUUUUUUUUUUU
  
  @cindex @code{.unreq} directive, ARM
Index: gas/testsuite/gas/arm/tls.d
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/tls.d,v
retrieving revision 1.5
diff -c -3 -p -r1.5 tls.d
*** gas/testsuite/gas/arm/tls.d	30 Jun 2009 11:57:05 -0000	1.5
--- gas/testsuite/gas/arm/tls.d	7 Jan 2011 13:09:11 -0000
***************
*** 11,25 ****
  
  Disassembly of section .text:
  
! 00+0 <main>:
!    0:	e1a00000 	nop			; \(mov r0, r0\)
!    4:	e1a00000 	nop			; \(mov r0, r0\)
!    8:	e1a0f00e 	mov	pc, lr
!    c:	00000000 	.word	0x00000000
! 			c: R_ARM_TLS_GD32	a
!   10:	00000004 	.word	0x00000004
! 			10: R_ARM_TLS_LDM32	b
!   14:	00000008 	.word	0x00000008
! 			14: R_ARM_TLS_IE32	c
!   18:	00000000 	.word	0x00000000
! 			18: R_ARM_TLS_LE32	d
--- 11,49 ----
  
  Disassembly of section .text:
  
! 0+00 <arm_fn>:
!    0:	e1a00000 	nop			; .*
! 			0: R_ARM_TLS_DESCSEQ	af
!    4:	e59f0014 	ldr	r0, \[pc, #20\]	; 20 .*
!    8:	fa000000 	blx	8 <ae\+.*>
! 			8: R_ARM_TLS_CALL	ae
!    c:	e1a00000 	nop			; .*
! 0+10 <.arm_pool>:
!   10:	00000008 	.word	0x00000008
! 			10: R_ARM_TLS_GD32	aa
!   14:	0000000c 	.word	0x0000000c
! 			14: R_ARM_TLS_LDM32	ab
!   18:	00000010 	.word	0x00000010
! 			18: R_ARM_TLS_IE32	ac
!   1c:	00000000 	.word	0x00000000
! 			1c: R_ARM_TLS_LE32	ad
!   20:	00000018 	.word	0x00000018
! 			20: R_ARM_TLS_GOTDESC	ae
! 0+24 <thumb_fn>:
!   24:	46c0      	nop			; .*
!   26:	46c0      	nop			; .*
! 			26: R_ARM_THM_TLS_DESCSEQ	tf
!   28:	4805      	ldr	r0, \[pc, #20\]	; \(40 .*\)
!   2a:	f000 e800 	blx	4 <te\+0x4>
! 			2a: R_ARM_THM_TLS_CALL	te
!   2e:	46c0      	nop			; .*
!   30:	00000002 	.word	0x00000002
! 			30: R_ARM_TLS_GD32	ta
!   34:	00000006 	.word	0x00000006
! 			34: R_ARM_TLS_LDM32	tb
!   38:	0000000a 	.word	0x0000000a
! 			38: R_ARM_TLS_IE32	tc
!   3c:	00000000 	.word	0x00000000
! 			3c: R_ARM_TLS_LE32	td
!   40:	00000017 	.word	0x00000017
! 			40: R_ARM_TLS_GOTDESC	te
Index: gas/testsuite/gas/arm/tls.s
===================================================================
RCS file: /cvs/src/src/gas/testsuite/gas/arm/tls.s,v
retrieving revision 1.2
diff -c -3 -p -r1.2 tls.s
*** gas/testsuite/gas/arm/tls.s	29 Mar 2005 16:54:22 -0000	1.2
--- gas/testsuite/gas/arm/tls.s	7 Jan 2011 13:09:11 -0000
***************
*** 1,14 ****
  	.text
! 	.globl main
! 	.type main, %function
! main:
  	nop
! .L2:
  	nop
- 	mov	pc, lr
  
  .Lpool:
! 	.word	a(tlsgd) + (. - .L2 - 8)
! 	.word	b(tlsldm) + (. - .L2 - 8)
! 	.word	c(gottpoff) + (. - .L2 - 8)
! 	.word	d(tpoff)
--- 1,38 ----
  	.text
! 	.arm
! 	.globl arm_fn
! 	.type arm_fn, %function
! arm_fn:
! 1:
! .tlsdescseq  af
  	nop
! 	ldr	r0, 1f
! 2:	blx	ae(tlscall)
  	nop
  
+ .arm_pool:
+ 	.word	aa(tlsgd) + (. - 1b - 8)
+ 	.word	ab(tlsldm) + (. - 1b- 8)
+ 	.word	ac(gottpoff) + (. - 1b - 8)
+ 	.word	ad(tpoff)
+ 1:	.word	ae(tlsdesc) + (. - 2b)
+ 	
+ 	.thumb
+ 	.globl	thumb_fn
+ 	.type thumb_fn, %function
+ thumb_fn:
+ 	nop
+ 1:	
+ .tlsdescseq tf
+ 	nop
+ 	ldr	r0, 1f
+ 2:	blx	te(tlscall)
+ 	nop
+ 
+ 	.p2align 2
  .Lpool:
! 	.word	ta(tlsgd) + (. - 1b - 8)
! 	.word	tb(tlsldm) + (. - 1b - 8)
! 	.word	tc(gottpoff) + (. - 1b - 8)
! 	.word	td(tpoff)
! 1:	.word	te(tlsdesc) + (. - 2b + 1)
Index: include/elf/arm.h
===================================================================
RCS file: /cvs/src/src/include/elf/arm.h,v
retrieving revision 1.40
diff -c -3 -p -r1.40 arm.h
*** include/elf/arm.h	15 Apr 2010 10:56:36 -0000	1.40
--- include/elf/arm.h	7 Jan 2011 13:09:14 -0000
*************** START_RELOC_NUMBERS (elf_arm_reloc_type)
*** 123,129 ****
    RELOC_NUMBER (R_ARM_THM_CALL,        	 10)
    RELOC_NUMBER (R_ARM_THM_PC8,         	 11)
    RELOC_NUMBER (R_ARM_BREL_ADJ,	       	 12)
!   RELOC_NUMBER (R_ARM_SWI24,           	 13)   /* obsolete */
    RELOC_NUMBER (R_ARM_THM_SWI8,        	 14)   /* obsolete */
    RELOC_NUMBER (R_ARM_XPC25,           	 15)   /* obsolete */
    RELOC_NUMBER (R_ARM_THM_XPC22,       	 16)   /* obsolete */
--- 123,129 ----
    RELOC_NUMBER (R_ARM_THM_CALL,        	 10)
    RELOC_NUMBER (R_ARM_THM_PC8,         	 11)
    RELOC_NUMBER (R_ARM_BREL_ADJ,	       	 12)
!   RELOC_NUMBER (R_ARM_TLS_DESC,          13)
    RELOC_NUMBER (R_ARM_THM_SWI8,        	 14)   /* obsolete */
    RELOC_NUMBER (R_ARM_XPC25,           	 15)   /* obsolete */
    RELOC_NUMBER (R_ARM_THM_XPC22,       	 16)   /* obsolete */
*************** START_RELOC_NUMBERS (elf_arm_reloc_type)
*** 200,206 ****
    RELOC_NUMBER (R_ARM_THM_MOVW_BREL_NC,	 87)
    RELOC_NUMBER (R_ARM_THM_MOVT_BREL,   	 88)
    RELOC_NUMBER (R_ARM_THM_MOVW_BREL,   	 89)
!   /* 90-93 unallocated */
    RELOC_NUMBER (R_ARM_PLT32_ABS,       	 94)
    RELOC_NUMBER (R_ARM_GOT_ABS,	       	 95)
    RELOC_NUMBER (R_ARM_GOT_PREL,	       	 96)
--- 200,209 ----
    RELOC_NUMBER (R_ARM_THM_MOVW_BREL_NC,	 87)
    RELOC_NUMBER (R_ARM_THM_MOVT_BREL,   	 88)
    RELOC_NUMBER (R_ARM_THM_MOVW_BREL,   	 89)
!   RELOC_NUMBER (R_ARM_TLS_GOTDESC,       90)
!   RELOC_NUMBER (R_ARM_TLS_CALL,          91)
!   RELOC_NUMBER (R_ARM_TLS_DESCSEQ,       92)
!   RELOC_NUMBER (R_ARM_THM_TLS_CALL,      93)
    RELOC_NUMBER (R_ARM_PLT32_ABS,       	 94)
    RELOC_NUMBER (R_ARM_GOT_ABS,	       	 95)
    RELOC_NUMBER (R_ARM_GOT_PREL,	       	 96)
*************** START_RELOC_NUMBERS (elf_arm_reloc_type)
*** 221,226 ****
--- 224,230 ----
    RELOC_NUMBER (R_ARM_TLS_IE12GP,     	111)
    /* 112 - 127 private range */
    RELOC_NUMBER (R_ARM_ME_TOO,	        128)   /* obsolete */
+   RELOC_NUMBER (R_ARM_THM_TLS_DESCSEQ  ,129)
  
    /* Extensions?  R=read-only?  */
    RELOC_NUMBER (R_ARM_RXPC25,         	249)
Index: ld/testsuite/ld-arm/arm-elf.exp
===================================================================
RCS file: /cvs/src/src/ld/testsuite/ld-arm/arm-elf.exp,v
retrieving revision 1.79
diff -c -3 -p -r1.79 arm-elf.exp
*** ld/testsuite/ld-arm/arm-elf.exp	25 Nov 2010 09:34:43 -0000	1.79
--- ld/testsuite/ld-arm/arm-elf.exp	7 Jan 2011 13:09:15 -0000
*************** set armelftests {
*** 135,140 ****
--- 135,173 ----
      {"TLS dynamic application" "-T arm-dyn.ld tmpdir/tls-lib.so" "" {tls-app.s}
       {{objdump -fdw tls-app.d} {objdump -Rw tls-app.r}}
       "tls-app"}
+     {"TLS gnu shared library got" "-shared -T arm-dyn.ld" "" {tls-gdesc-got.s}
+      {{objdump "-fDR -j .got" tls-gdesc-got.d}}
+      "tls-lib2-got.so"}
+     {"TLS gnu shared library inlined trampoline" "-shared -T arm-dyn.ld" "" {tls-descseq.s}
+      {{objdump -fdw tls-descseq.d} {objdump -Rw tls-descseq.r}}
+      "tls-lib2inline.so"}
+     {"TLS shared library gdesc local" "-shared -T arm-dyn.ld" "" {tls-lib-loc.s}
+      {{objdump -fdw tls-lib-loc.d} {objdump -Rw tls-lib-loc.r}}
+      "tls-lib-loc.so"}
+     {"TLS gnu GD to IE relaxation" "-static -T arm-dyn.ld" "" {tls-gdierelax.s}
+      {{objdump -fdw tls-gdierelax.d}}
+      "tls-app-rel-ie"}
+     {"TLS gnu GD to IE shared relaxation" "-shared -T arm-dyn.ld" "" {tls-gdierelax2.s}
+      {{objdump -fdw tls-gdierelax2.d}}
+      "tls-app-rel-ie2"}
+     {"TLS gnu GD to LE relaxation" "-T arm-dyn.ld" "" {tls-gdlerelax.s}
+      {{objdump -fdw tls-gdlerelax.d}}
+      "tls-app-rel-le"}
+     {"TLS mixed models shared lib" "-shared -T arm-dyn.ld" "" {tls-mixed.s}
+      {{objdump -Rw tls-mixed.r}}
+      "tls-mixed.so"}
+     {"TLS descseq relaxation" "-T arm-dyn.ld" "" {tls-descrelax.s}
+      {{objdump -fdw tls-descrelax.d}}
+      "tls-descrelax"}
+     {"TLS descseq relaxation v7" "-T arm-dyn.ld" "" {tls-descrelax-v7.s}
+      {{objdump -fdw tls-descrelax-v7.d}}
+      "tls-descrelax-v7"}
+     {"TLS descseq relaxation BE8" "-T arm-dyn.ld -EB --be8" "-mbig-endian" {tls-descrelax-be8.s}
+      {{objdump -fdw tls-descrelax-be8.d}}
+      "tls-descrelax-be8"}
+     {"TLS descseq relaxation BE32" "-T arm-dyn.ld -EB" "-mbig-endian" {tls-descrelax-be32.s}
+      {{objdump -fdw tls-descrelax-be32.d}}
+      "tls-descrelax-be32"}
      {"Thumb entry point" "-T arm.ld" "" {thumb-entry.s}
       {{readelf -h thumb-entry.d}}
       "thumb-entry"}
*************** set armeabitests {
*** 481,486 ****
--- 514,534 ----
       {jump-reloc-veneers.s}
       {{objdump -d jump-reloc-veneers-long.d}}
       "jump-reloc-veneers-long"}
+     {"TLS gnu shared library" "-shared -T arm-dyn.ld" "" {tls-gdesc.s}
+      {{objdump -fdw tls-gdesc.d} {objdump -Rw tls-gdesc.r}}
+      "tls-lib2.so"}
+     {"TLS gnu shared library non-lazy" "-z now -shared -T arm-dyn.ld" "" {tls-gdesc.s}
+      {{readelf "-x .got" tls-gdesc-nlazy.g}}
+      "tls-lib2-nlazy.so"}
+     {"TLS long plt library" "-shared -T arm-dyn.ld --section-start .foo=0x4001000" "" {tls-longplt-lib.s}
+      {{objdump -fdw tls-longplt-lib.d}}
+      "tls-longplt-lib.so"}
+     {"TLS long plt" "-T arm-dyn.ld --section-start .foo=0x4001000 tmpdir/tls-longplt-lib.so" "" {tls-longplt.s}
+      {{objdump -fdw tls-longplt.d}}
+      "tls-longplt"}
+     {"TLS thumb1" "-shared -T arm-dyn.ld --section-start .foo=0x4001000" "" {tls-thumb1.s}
+      {{objdump -fdw tls-thumb1.d}}
+      "tls-thumb1"}
  }
  
  run_ld_link_tests $armeabitests
Index: ld/testsuite/ld-arm/tls-descrelax-be32.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descrelax-be32.d
diff -N ld/testsuite/ld-arm/tls-descrelax-be32.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descrelax-be32.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,108 ----
+ .*:     file format elf32-.*
+ architecture: arm, flags 0x[0-9a-f]+:
+ EXEC_P, HAS_SYMS, D_PAGED
+ start address 0x[0-9a-f]+
+ 
+ Disassembly of section .text:
+ 
+ 00008000 <foo>:
+     8000:	e59f0004 	ldr	r0, \[pc, #4\]	; 800c <foo\+0xc>
+     8004:	e79f0000 	ldr	r0, \[pc, r0\]
+     8008:	e1a00000 	nop			; .*
+     800c:	00008138 	.word	0x00008138
+     8010:	e59f0004 	ldr	r0, \[pc, #4\]	; 801c <foo\+0x1c>
+     8014:	e79f0000 	ldr	r0, \[pc, r0\]
+     8018:	e1a00000 	nop			; .*
+     801c:	00008128 	.word	0x00008128
+     8020:	e59f0004 	ldr	r0, \[pc, #4\]	; 802c <foo\+0x2c>
+     8024:	e1a00000 	nop			; .*
+     8028:	e1a00000 	nop			; .*
+     802c:	0000000c 	.word	0x0000000c
+     8030:	e59f0004 	ldr	r0, \[pc, #4\]	; 803c <foo\+0x3c>
+     8034:	e1a00000 	nop			; .*
+     8038:	e1a00000 	nop			; .*
+     803c:	0000000c 	.word	0x0000000c
+     8040:	e59f000c 	ldr	r0, \[pc, #12\]	; 8054 <foo\+0x54>
+     8044:	e08f0000 	add	r0, pc, r0
+     8048:	e5901000 	ldr	r1, \[r0\]
+     804c:	e1a00001 	mov	r0, r1
+     8050:	e1a00000 	nop			; .*
+     8054:	000080f8 	.word	0x000080f8
+     8058:	e59f000c 	ldr	r0, \[pc, #12\]	; 806c <foo\+0x6c>
+     805c:	e08f0000 	add	r0, pc, r0
+     8060:	e5901000 	ldr	r1, \[r0\]
+     8064:	e1a00001 	mov	r0, r1
+     8068:	e1a00000 	nop			; .*
+     806c:	000080e0 	.word	0x000080e0
+     8070:	e59f000c 	ldr	r0, \[pc, #12\]	; 8084 <foo\+0x84>
+     8074:	e1a00000 	nop			; .*
+     8078:	e1a00000 	nop			; .*
+     807c:	e1a00000 	nop			; .*
+     8080:	e1a00000 	nop			; .*
+     8084:	0000000c 	.word	0x0000000c
+     8088:	e59f000c 	ldr	r0, \[pc, #12\]	; 809c <foo\+0x9c>
+     808c:	e1a00000 	nop			; .*
+     8090:	e1a00000 	nop			; .*
+     8094:	e1a00000 	nop			; .*
+     8098:	e1a00000 	nop			; .*
+     809c:	0000000c 	.word	0x0000000c
+ 
+ 000080a0 <bar>:
+     80a0:	4801      	ldr	r0, \[pc, #4\]	; \(80a8 <bar\+0x8>\)
+     80a2:	4478      	add	r0, pc
+     80a4:	6800      	ldr	r0, \[r0, #0\]
+     80a6:	46c0      	nop			; .*
+     80a8:	0000809e 	.word	0x0000809e
+     80ac:	4801      	ldr	r0, \[pc, #4\]	; \(80b4 <bar\+0x14>\)
+     80ae:	4478      	add	r0, pc
+     80b0:	6800      	ldr	r0, \[r0, #0\]
+     80b2:	46c0      	nop			; .*
+     80b4:	00008092 	.word	0x00008092
+     80b8:	4801      	ldr	r0, \[pc, #4\]	; \(80c0 <bar\+0x20>\)
+     80ba:	4478      	add	r0, pc
+     80bc:	6800      	ldr	r0, \[r0, #0\]
+     80be:	46c0      	nop			; .*
+     80c0:	0000808a 	.word	0x0000808a
+     80c4:	4801      	ldr	r0, \[pc, #4\]	; \(80cc <bar\+0x2c>\)
+     80c6:	46c0      	nop			; .*
+     80c8:	46c0      	nop			; .*
+     80ca:	46c0      	nop			; .*
+     80cc:	0000000c 	.word	0x0000000c
+     80d0:	4801      	ldr	r0, \[pc, #4\]	; \(80d8 <bar\+0x38>\)
+     80d2:	bf00      	nop
+     80d4:	bf00      	nop
+     80d6:	46c0      	nop			; .*
+     80d8:	0000000c 	.word	0x0000000c
+     80dc:	4801      	ldr	r0, \[pc, #4\]	; \(80e4 <bar\+0x44>\)
+     80de:	bf00      	nop
+     80e0:	bf00      	nop
+     80e2:	46c0      	nop			; .*
+     80e4:	00000014 	.word	0x00000014
+     80e8:	4802      	ldr	r0, \[pc, #8\]	; \(80f4 <bar\+0x54>\)
+     80ea:	4478      	add	r0, pc
+     80ec:	6801      	ldr	r1, \[r0, #0\]
+     80ee:	1c08      	adds	r0, r1, #0
+     80f0:	46c0      	nop			; .*
+     80f2:	46c0      	nop			; .*
+     80f4:	00008056 	.word	0x00008056
+     80f8:	4802      	ldr	r0, \[pc, #8\]	; \(8104 <bar\+0x64>\)
+     80fa:	4478      	add	r0, pc
+     80fc:	6801      	ldr	r1, \[r0, #0\]
+     80fe:	4608      	mov	r0, r1
+     8100:	46c0      	nop			; .*
+     8102:	46c0      	nop			; .*
+     8104:	00008046 	.word	0x00008046
+     8108:	4802      	ldr	r0, \[pc, #8\]	; \(8114 <bar\+0x74>\)
+     810a:	46c0      	nop			; .*
+     810c:	46c0      	nop			; .*
+     810e:	46c0      	nop			; .*
+     8110:	46c0      	nop			; .*
+     8112:	46c0      	nop			; .*
+     8114:	0000000c 	.word	0x0000000c
+     8118:	4802      	ldr	r0, \[pc, #8\]	; \(8124 <bar\+0x84>\)
+     811a:	46c0      	nop			; .*
+     811c:	46c0      	nop			; .*
+     811e:	46c0      	nop			; .*
+     8120:	46c0      	nop			; .*
+     8122:	46c0      	nop			; .*
+     8124:	0000000c 	.word	0x0000000c
Index: ld/testsuite/ld-arm/tls-descrelax-be32.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descrelax-be32.s
diff -N ld/testsuite/ld-arm/tls-descrelax-be32.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descrelax-be32.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,198 ----
+ @ we can relax local and non-weak globals for non-shared links
+ 
+ 	.arch	armv5te
+ 	.text
+ 	.arm
+ 
+ 	.p2align 2
+ foo:
+ @tlscall global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:	ldr	r0, [pc, r0]
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 8)
+ 	
+ 	.p2align 2
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	gd1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @tlscall local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 
+ 	.p2align 2
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	ld1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @open coded global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:
+ 	add	r0, pc, r0
+ 	ldr	r1, [r0]
+ 	mov	r0, r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 8)
+ 
+ 	.p2align 2
+ @open coded global, should relax to IE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq gd1
+ 	add	r0, pc, r0
+ .tlsdescseq gd1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq gd1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @open coded local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 2:
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 	
+ 	.p2align 2
+ @open coded local, should relax to LE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq ld1
+ 	add	r0, pc, r0
+ .tlsdescseq ld1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq ld1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b)
+ 
+ 
+ 	.thumb
+ 	.p2align 1
+ bar:	
+ @tlscall global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:	add	r0, pc, r0
+ 	ldr	r0, [r0]
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 4)
+ 	
+ 	.p2align 1
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	gd1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	r1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	r1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 
+ 	.p2align 1
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	ld1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	r0(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	r0(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @open coded global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:
+ 	add	r0, pc
+ 	ldr	r1, [r0]
+ 	mov	r0, r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 4)
+ 
+ 	.p2align 1
+ @open coded global, should relax to IE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq gd1
+ 	add	r0, pc
+ .tlsdescseq gd1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq gd1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @open coded local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 2:
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 	
+ 	.p2align 1
+ @open coded local, should relax to LE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq ld1
+ 	add	r0, pc
+ .tlsdescseq ld1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq ld1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section .tdata,"awT"
+ 	.global	gd1
+ gd1:	.space 4
+ ld1:	.space 4
+ 	.globl r1
+ r1:	.space 4
+ r0:	.space 4
Index: ld/testsuite/ld-arm/tls-descrelax-be8.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descrelax-be8.d
diff -N ld/testsuite/ld-arm/tls-descrelax-be8.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descrelax-be8.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,108 ----
+ .*:     file format elf32-.*
+ architecture: arm, flags 0x[0-9a-f]+:
+ EXEC_P, HAS_SYMS, D_PAGED
+ start address 0x[0-9a-f]+
+ 
+ Disassembly of section .text:
+ 
+ 00008000 <foo>:
+     8000:	e59f0004 	ldr	r0, \[pc, #4\]	; 800c <foo\+0xc>
+     8004:	e79f0000 	ldr	r0, \[pc, r0\]
+     8008:	e320f000 	nop	\{0\}
+     800c:	00008138 	.word	0x00008138
+     8010:	e59f0004 	ldr	r0, \[pc, #4\]	; 801c <foo\+0x1c>
+     8014:	e79f0000 	ldr	r0, \[pc, r0\]
+     8018:	e320f000 	nop	\{0\}
+     801c:	00008128 	.word	0x00008128
+     8020:	e59f0004 	ldr	r0, \[pc, #4\]	; 802c <foo\+0x2c>
+     8024:	e320f000 	nop	\{0\}
+     8028:	e320f000 	nop	\{0\}
+     802c:	0000000c 	.word	0x0000000c
+     8030:	e59f0004 	ldr	r0, \[pc, #4\]	; 803c <foo\+0x3c>
+     8034:	e1a00000 	nop			; .*
+     8038:	e320f000 	nop	\{0\}
+     803c:	0000000c 	.word	0x0000000c
+     8040:	e59f000c 	ldr	r0, \[pc, #12\]	; 8054 <foo\+0x54>
+     8044:	e08f0000 	add	r0, pc, r0
+     8048:	e5901000 	ldr	r1, \[r0\]
+     804c:	e1a00001 	mov	r0, r1
+     8050:	e320f000 	nop	\{0\}
+     8054:	000080f8 	.word	0x000080f8
+     8058:	e59f000c 	ldr	r0, \[pc, #12\]	; 806c <foo\+0x6c>
+     805c:	e08f0000 	add	r0, pc, r0
+     8060:	e5901000 	ldr	r1, \[r0\]
+     8064:	e1a00001 	mov	r0, r1
+     8068:	e320f000 	nop	\{0\}
+     806c:	000080e0 	.word	0x000080e0
+     8070:	e59f000c 	ldr	r0, \[pc, #12\]	; 8084 <foo\+0x84>
+     8074:	e320f000 	nop	\{0\}
+     8078:	e320f000 	nop	\{0\}
+     807c:	e320f000 	nop	\{0\}
+     8080:	e320f000 	nop	\{0\}
+     8084:	0000000c 	.word	0x0000000c
+     8088:	e59f000c 	ldr	r0, \[pc, #12\]	; 809c <foo\+0x9c>
+     808c:	e1a00000 	nop			; .*
+     8090:	e1a00000 	nop			; .*
+     8094:	e1a00000 	nop			; .*
+     8098:	e320f000 	nop	\{0\}
+     809c:	0000000c 	.word	0x0000000c
+ 
+ 000080a0 <bar>:
+     80a0:	4801      	ldr	r0, \[pc, #4\]	; \(80a8 <bar\+0x8>\)
+     80a2:	4478      	add	r0, pc
+     80a4:	6800      	ldr	r0, \[r0, #0\]
+     80a6:	46c0      	nop			; .*
+     80a8:	0000809e 	.word	0x0000809e
+     80ac:	4801      	ldr	r0, \[pc, #4\]	; \(80b4 <bar\+0x14>\)
+     80ae:	4478      	add	r0, pc
+     80b0:	6800      	ldr	r0, \[r0, #0\]
+     80b2:	46c0      	nop			; \(mov r8, r8\)
+     80b4:	00008092 	.word	0x00008092
+     80b8:	4801      	ldr	r0, \[pc, #4\]	; \(80c0 <bar\+0x20>\)
+     80ba:	4478      	add	r0, pc
+     80bc:	6800      	ldr	r0, \[r0, #0\]
+     80be:	46c0      	nop			; \(mov r8, r8\)
+     80c0:	0000808a 	.word	0x0000808a
+     80c4:	4801      	ldr	r0, \[pc, #4\]	; \(80cc <bar\+0x2c>\)
+     80c6:	46c0      	nop			; \(mov r8, r8\)
+     80c8:	46c0      	nop			; \(mov r8, r8\)
+     80ca:	bf00      	nop
+     80cc:	0000000c 	.word	0x0000000c
+     80d0:	4801      	ldr	r0, \[pc, #4\]	; \(80d8 <bar\+0x38>\)
+     80d2:	(f3af 8000)|(bf00     ) 	nop(.w)?
+ #...
+     80d6:	46c0      	nop			; \(mov r8, r8\)
+     80d8:	0000000c 	.word	0x0000000c
+     80dc:	4801      	ldr	r0, \[pc, #4\]	; \(80e4 <bar\+0x44>\)
+     80de:	(f3af 8000)|(bf00     ) 	nop(.w)?
+ #...
+     80e2:	46c0      	nop			; \(mov r8, r8\)
+     80e4:	00000014 	.word	0x00000014
+     80e8:	4802      	ldr	r0, \[pc, #8\]	; \(80f4 <bar\+0x54>\)
+     80ea:	4478      	add	r0, pc
+     80ec:	6801      	ldr	r1, \[r0, #0\]
+     80ee:	1c08      	adds	r0, r1, #0
+     80f0:	46c0      	nop			; \(mov r8, r8\)
+     80f2:	bf00      	nop
+     80f4:	00008056 	.word	0x00008056
+     80f8:	4802      	ldr	r0, \[pc, #8\]	; \(8104 <bar\+0x64>\)
+     80fa:	4478      	add	r0, pc
+     80fc:	6801      	ldr	r1, \[r0, #0\]
+     80fe:	4608      	mov	r0, r1
+     8100:	46c0      	nop			; \(mov r8, r8\)
+     8102:	bf00      	nop
+     8104:	00008046 	.word	0x00008046
+     8108:	4802      	ldr	r0, \[pc, #8\]	; \(8114 <bar\+0x74>\)
+     810a:	46c0      	nop			; \(mov r8, r8\)
+     810c:	46c0      	nop			; \(mov r8, r8\)
+     810e:	46c0      	nop			; \(mov r8, r8\)
+     8110:	46c0      	nop			; \(mov r8, r8\)
+     8112:	bf00      	nop
+     8114:	0000000c 	.word	0x0000000c
+     8118:	4802      	ldr	r0, \[pc, #8\]	; \(8124 <bar\+0x84>\)
+     811a:	46c0      	nop			; \(mov r8, r8\)
+     811c:	46c0      	nop			; \(mov r8, r8\)
+     811e:	46c0      	nop			; \(mov r8, r8\)
+     8120:	46c0      	nop			; \(mov r8, r8\)
+     8122:	bf00      	nop
+     8124:	0000000c 	.word	0x0000000c
Index: ld/testsuite/ld-arm/tls-descrelax-be8.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descrelax-be8.s
diff -N ld/testsuite/ld-arm/tls-descrelax-be8.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descrelax-be8.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,198 ----
+ @ we can relax local and non-weak globals for non-shared links
+ 
+ 	.arch	armv7-a
+ 	.text
+ 	.arm
+ 
+ 	.p2align 2
+ foo:
+ @tlscall global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:	ldr	r0, [pc, r0]
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 8)
+ 	
+ 	.p2align 2
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	gd1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @tlscall local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 
+ 	.p2align 2
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	ld1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @open coded global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:
+ 	add	r0, pc, r0
+ 	ldr	r1, [r0]
+ 	mov	r0, r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 8)
+ 
+ 	.p2align 2
+ @open coded global, should relax to IE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq gd1
+ 	add	r0, pc, r0
+ .tlsdescseq gd1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq gd1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @open coded local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 2:
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 	
+ 	.p2align 2
+ @open coded local, should relax to LE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq ld1
+ 	add	r0, pc, r0
+ .tlsdescseq ld1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq ld1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b)
+ 
+ 
+ 	.thumb
+ 	.p2align 1
+ bar:	
+ @tlscall global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:	add	r0, pc, r0
+ 	ldr	r0, [r0]
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 4)
+ 	
+ 	.p2align 1
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	gd1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	r1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	r1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 
+ 	.p2align 1
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	ld1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	r0(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	r0(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @open coded global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:
+ 	add	r0, pc
+ 	ldr	r1, [r0]
+ 	mov	r0, r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 4)
+ 
+ 	.p2align 1
+ @open coded global, should relax to IE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq gd1
+ 	add	r0, pc
+ .tlsdescseq gd1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq gd1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @open coded local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 2:
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 	
+ 	.p2align 1
+ @open coded local, should relax to LE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq ld1
+ 	add	r0, pc
+ .tlsdescseq ld1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq ld1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section .tdata,"awT"
+ 	.global	gd1
+ gd1:	.space 4
+ ld1:	.space 4
+ 	.globl r1
+ r1:	.space 4
+ r0:	.space 4
Index: ld/testsuite/ld-arm/tls-descrelax-v7.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descrelax-v7.d
diff -N ld/testsuite/ld-arm/tls-descrelax-v7.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descrelax-v7.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,108 ----
+ .*:     file format elf32-.*
+ architecture: arm, flags 0x[0-9a-f]+:
+ EXEC_P, HAS_SYMS, D_PAGED
+ start address 0x[0-9a-f]+
+ 
+ Disassembly of section .text:
+ 
+ 00008000 <foo>:
+     8000:	e59f0004 	ldr	r0, \[pc, #4\]	; 800c <foo\+0xc>
+     8004:	e79f0000 	ldr	r0, \[pc, r0\]
+     8008:	e320f000 	nop	\{0\}
+     800c:	00008138 	.word	0x00008138
+     8010:	e59f0004 	ldr	r0, \[pc, #4\]	; 801c <foo\+0x1c>
+     8014:	e79f0000 	ldr	r0, \[pc, r0\]
+     8018:	e320f000 	nop	\{0\}
+     801c:	00008128 	.word	0x00008128
+     8020:	e59f0004 	ldr	r0, \[pc, #4\]	; 802c <foo\+0x2c>
+     8024:	e320f000 	nop	\{0\}
+     8028:	e320f000 	nop	\{0\}
+     802c:	0000000c 	.word	0x0000000c
+     8030:	e59f0004 	ldr	r0, \[pc, #4\]	; 803c <foo\+0x3c>
+     8034:	e1a00000 	nop			; .*
+     8038:	e320f000 	nop	\{0\}
+     803c:	0000000c 	.word	0x0000000c
+     8040:	e59f000c 	ldr	r0, \[pc, #12\]	; 8054 <foo\+0x54>
+     8044:	e08f0000 	add	r0, pc, r0
+     8048:	e5901000 	ldr	r1, \[r0\]
+     804c:	e1a00001 	mov	r0, r1
+     8050:	e320f000 	nop	\{0\}
+     8054:	000080f8 	.word	0x000080f8
+     8058:	e59f000c 	ldr	r0, \[pc, #12\]	; 806c <foo\+0x6c>
+     805c:	e08f0000 	add	r0, pc, r0
+     8060:	e5901000 	ldr	r1, \[r0\]
+     8064:	e1a00001 	mov	r0, r1
+     8068:	e320f000 	nop	\{0\}
+     806c:	000080e0 	.word	0x000080e0
+     8070:	e59f000c 	ldr	r0, \[pc, #12\]	; 8084 <foo\+0x84>
+     8074:	e320f000 	nop	\{0\}
+     8078:	e320f000 	nop	\{0\}
+     807c:	e320f000 	nop	\{0\}
+     8080:	e320f000 	nop	\{0\}
+     8084:	0000000c 	.word	0x0000000c
+     8088:	e59f000c 	ldr	r0, \[pc, #12\]	; 809c <foo\+0x9c>
+     808c:	e1a00000 	nop			; .*
+     8090:	e1a00000 	nop			; .*
+     8094:	e1a00000 	nop			; .*
+     8098:	e320f000 	nop	\{0\}
+     809c:	0000000c 	.word	0x0000000c
+ 
+ 000080a0 <bar>:
+     80a0:	4801      	ldr	r0, \[pc, #4\]	; \(80a8 <bar\+0x8>\)
+     80a2:	4478      	add	r0, pc
+     80a4:	6800      	ldr	r0, \[r0, #0\]
+     80a6:	46c0      	nop			; .*
+     80a8:	0000809e 	.word	0x0000809e
+     80ac:	4801      	ldr	r0, \[pc, #4\]	; \(80b4 <bar\+0x14>\)
+     80ae:	4478      	add	r0, pc
+     80b0:	6800      	ldr	r0, \[r0, #0\]
+     80b2:	46c0      	nop			; \(mov r8, r8\)
+     80b4:	00008092 	.word	0x00008092
+     80b8:	4801      	ldr	r0, \[pc, #4\]	; \(80c0 <bar\+0x20>\)
+     80ba:	4478      	add	r0, pc
+     80bc:	6800      	ldr	r0, \[r0, #0\]
+     80be:	46c0      	nop			; \(mov r8, r8\)
+     80c0:	0000808a 	.word	0x0000808a
+     80c4:	4801      	ldr	r0, \[pc, #4\]	; \(80cc <bar\+0x2c>\)
+     80c6:	46c0      	nop			; \(mov r8, r8\)
+     80c8:	46c0      	nop			; \(mov r8, r8\)
+     80ca:	bf00      	nop
+     80cc:	0000000c 	.word	0x0000000c
+     80d0:	4801      	ldr	r0, \[pc, #4\]	; \(80d8 <bar\+0x38>\)
+     80d2:	(f3af 8000)|(bf00     ) 	nop(.w)?
+ #...
+     80d6:	46c0      	nop			; \(mov r8, r8\)
+     80d8:	0000000c 	.word	0x0000000c
+     80dc:	4801      	ldr	r0, \[pc, #4\]	; \(80e4 <bar\+0x44>\)
+     80de:	(f3af 8000)|(bf00     ) 	nop(.w)?
+ #...
+     80e2:	46c0      	nop			; \(mov r8, r8\)
+     80e4:	00000014 	.word	0x00000014
+     80e8:	4802      	ldr	r0, \[pc, #8\]	; \(80f4 <bar\+0x54>\)
+     80ea:	4478      	add	r0, pc
+     80ec:	6801      	ldr	r1, \[r0, #0\]
+     80ee:	1c08      	adds	r0, r1, #0
+     80f0:	46c0      	nop			; \(mov r8, r8\)
+     80f2:	bf00      	nop
+     80f4:	00008056 	.word	0x00008056
+     80f8:	4802      	ldr	r0, \[pc, #8\]	; \(8104 <bar\+0x64>\)
+     80fa:	4478      	add	r0, pc
+     80fc:	6801      	ldr	r1, \[r0, #0\]
+     80fe:	4608      	mov	r0, r1
+     8100:	46c0      	nop			; \(mov r8, r8\)
+     8102:	bf00      	nop
+     8104:	00008046 	.word	0x00008046
+     8108:	4802      	ldr	r0, \[pc, #8\]	; \(8114 <bar\+0x74>\)
+     810a:	46c0      	nop			; \(mov r8, r8\)
+     810c:	46c0      	nop			; \(mov r8, r8\)
+     810e:	46c0      	nop			; \(mov r8, r8\)
+     8110:	46c0      	nop			; \(mov r8, r8\)
+     8112:	bf00      	nop
+     8114:	0000000c 	.word	0x0000000c
+     8118:	4802      	ldr	r0, \[pc, #8\]	; \(8124 <bar\+0x84>\)
+     811a:	46c0      	nop			; \(mov r8, r8\)
+     811c:	46c0      	nop			; \(mov r8, r8\)
+     811e:	46c0      	nop			; \(mov r8, r8\)
+     8120:	46c0      	nop			; \(mov r8, r8\)
+     8122:	bf00      	nop
+     8124:	0000000c 	.word	0x0000000c
Index: ld/testsuite/ld-arm/tls-descrelax-v7.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descrelax-v7.s
diff -N ld/testsuite/ld-arm/tls-descrelax-v7.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descrelax-v7.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,198 ----
+ @ we can relax local and non-weak globals for non-shared links
+ 
+ 	.arch	armv7-a
+ 	.text
+ 	.arm
+ 
+ 	.p2align 2
+ foo:
+ @tlscall global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:	ldr	r0, [pc, r0]
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 8)
+ 	
+ 	.p2align 2
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	gd1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @tlscall local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 
+ 	.p2align 2
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	ld1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @open coded global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:
+ 	add	r0, pc, r0
+ 	ldr	r1, [r0]
+ 	mov	r0, r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 8)
+ 
+ 	.p2align 2
+ @open coded global, should relax to IE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq gd1
+ 	add	r0, pc, r0
+ .tlsdescseq gd1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq gd1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @open coded local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 2:
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 	
+ 	.p2align 2
+ @open coded local, should relax to LE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq ld1
+ 	add	r0, pc, r0
+ .tlsdescseq ld1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq ld1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b)
+ 
+ 
+ 	.thumb
+ 	.p2align 1
+ bar:	
+ @tlscall global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:	add	r0, pc, r0
+ 	ldr	r0, [r0]
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 4)
+ 	
+ 	.p2align 1
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	gd1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	r1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	r1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 
+ 	.p2align 1
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	ld1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	r0(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	r0(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @open coded global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:
+ 	add	r0, pc
+ 	ldr	r1, [r0]
+ 	mov	r0, r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 4)
+ 
+ 	.p2align 1
+ @open coded global, should relax to IE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq gd1
+ 	add	r0, pc
+ .tlsdescseq gd1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq gd1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @open coded local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 2:
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 	
+ 	.p2align 1
+ @open coded local, should relax to LE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq ld1
+ 	add	r0, pc
+ .tlsdescseq ld1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq ld1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section .tdata,"awT"
+ 	.global	gd1
+ gd1:	.space 4
+ ld1:	.space 4
+ 	.globl r1
+ r1:	.space 4
+ r0:	.space 4
Index: ld/testsuite/ld-arm/tls-descrelax.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descrelax.d
diff -N ld/testsuite/ld-arm/tls-descrelax.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descrelax.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,108 ----
+ .*:     file format elf32-.*
+ architecture: arm, flags 0x[0-9a-f]+:
+ EXEC_P, HAS_SYMS, D_PAGED
+ start address 0x[0-9a-f]+
+ 
+ Disassembly of section .text:
+ 
+ 00008000 <foo>:
+     8000:	e59f0004 	ldr	r0, \[pc, #4\]	; 800c <foo\+0xc>
+     8004:	e79f0000 	ldr	r0, \[pc, r0\]
+     8008:	e1a00000 	nop			; \(mov r0, r0\)
+     800c:	00008138 	.word	0x00008138
+     8010:	e59f0004 	ldr	r0, \[pc, #4\]	; 801c <foo\+0x1c>
+     8014:	e79f0000 	ldr	r0, \[pc, r0\]
+     8018:	e1a00000 	nop			; \(mov r0, r0\)
+     801c:	00008128 	.word	0x00008128
+     8020:	e59f0004 	ldr	r0, \[pc, #4\]	; 802c <foo\+0x2c>
+     8024:	e1a00000 	nop			; \(mov r0, r0\)
+     8028:	e1a00000 	nop			; \(mov r0, r0\)
+     802c:	0000000c 	.word	0x0000000c
+     8030:	e59f0004 	ldr	r0, \[pc, #4\]	; 803c <foo\+0x3c>
+     8034:	e1a00000 	nop			; \(mov r0, r0\)
+     8038:	e1a00000 	nop			; \(mov r0, r0\)
+     803c:	0000000c 	.word	0x0000000c
+     8040:	e59f000c 	ldr	r0, \[pc, #12\]	; 8054 <foo\+0x54>
+     8044:	e08f0000 	add	r0, pc, r0
+     8048:	e5901000 	ldr	r1, \[r0\]
+     804c:	e1a00001 	mov	r0, r1
+     8050:	e1a00000 	nop			; \(mov r0, r0\)
+     8054:	000080f8 	.word	0x000080f8
+     8058:	e59f000c 	ldr	r0, \[pc, #12\]	; 806c <foo\+0x6c>
+     805c:	e08f0000 	add	r0, pc, r0
+     8060:	e5901000 	ldr	r1, \[r0\]
+     8064:	e1a00001 	mov	r0, r1
+     8068:	e1a00000 	nop			; \(mov r0, r0\)
+     806c:	000080e0 	.word	0x000080e0
+     8070:	e59f000c 	ldr	r0, \[pc, #12\]	; 8084 <foo\+0x84>
+     8074:	e1a00000 	nop			; \(mov r0, r0\)
+     8078:	e1a00000 	nop			; \(mov r0, r0\)
+     807c:	e1a00000 	nop			; \(mov r0, r0\)
+     8080:	e1a00000 	nop			; \(mov r0, r0\)
+     8084:	0000000c 	.word	0x0000000c
+     8088:	e59f000c 	ldr	r0, \[pc, #12\]	; 809c <foo\+0x9c>
+     808c:	e1a00000 	nop			; \(mov r0, r0\)
+     8090:	e1a00000 	nop			; \(mov r0, r0\)
+     8094:	e1a00000 	nop			; \(mov r0, r0\)
+     8098:	e1a00000 	nop			; \(mov r0, r0\)
+     809c:	0000000c 	.word	0x0000000c
+ 
+ 000080a0 <bar>:
+     80a0:	4801      	ldr	r0, \[pc, #4\]	; \(80a8 <bar\+0x8>\)
+     80a2:	4478      	add	r0, pc
+     80a4:	6800      	ldr	r0, \[r0, #0\]
+     80a6:	46c0      	nop			; \(mov r8, r8\)
+     80a8:	0000809e 	.word	0x0000809e
+     80ac:	4801      	ldr	r0, \[pc, #4\]	; \(80b4 <bar\+0x14>\)
+     80ae:	4478      	add	r0, pc
+     80b0:	6800      	ldr	r0, \[r0, #0\]
+     80b2:	46c0      	nop			; \(mov r8, r8\)
+     80b4:	00008092 	.word	0x00008092
+     80b8:	4801      	ldr	r0, \[pc, #4\]	; \(80c0 <bar\+0x20>\)
+     80ba:	4478      	add	r0, pc
+     80bc:	6800      	ldr	r0, \[r0, #0\]
+     80be:	46c0      	nop			; \(mov r8, r8\)
+     80c0:	0000808a 	.word	0x0000808a
+     80c4:	4801      	ldr	r0, \[pc, #4\]	; \(80cc <bar\+0x2c>\)
+     80c6:	46c0      	nop			; \(mov r8, r8\)
+     80c8:	46c0      	nop			; \(mov r8, r8\)
+     80ca:	46c0      	nop			; \(mov r8, r8\)
+     80cc:	0000000c 	.word	0x0000000c
+     80d0:	4801      	ldr	r0, \[pc, #4\]	; \(80d8 <bar\+0x38>\)
+     80d2:	bf00      	nop
+     80d4:	bf00      	nop
+     80d6:	46c0      	nop			; \(mov r8, r8\)
+     80d8:	0000000c 	.word	0x0000000c
+     80dc:	4801      	ldr	r0, \[pc, #4\]	; \(80e4 <bar\+0x44>\)
+     80de:	bf00      	nop
+     80e0:	bf00      	nop
+     80e2:	46c0      	nop			; \(mov r8, r8\)
+     80e4:	00000014 	.word	0x00000014
+     80e8:	4802      	ldr	r0, \[pc, #8\]	; \(80f4 <bar\+0x54>\)
+     80ea:	4478      	add	r0, pc
+     80ec:	6801      	ldr	r1, \[r0, #0\]
+     80ee:	1c08      	adds	r0, r1, #0
+     80f0:	46c0      	nop			; \(mov r8, r8\)
+     80f2:	46c0      	nop			; \(mov r8, r8\)
+     80f4:	00008056 	.word	0x00008056
+     80f8:	4802      	ldr	r0, \[pc, #8\]	; \(8104 <bar\+0x64>\)
+     80fa:	4478      	add	r0, pc
+     80fc:	6801      	ldr	r1, \[r0, #0\]
+     80fe:	4608      	mov	r0, r1
+     8100:	46c0      	nop			; \(mov r8, r8\)
+     8102:	46c0      	nop			; \(mov r8, r8\)
+     8104:	00008046 	.word	0x00008046
+     8108:	4802      	ldr	r0, \[pc, #8\]	; \(8114 <bar\+0x74>\)
+     810a:	46c0      	nop			; \(mov r8, r8\)
+     810c:	46c0      	nop			; \(mov r8, r8\)
+     810e:	46c0      	nop			; \(mov r8, r8\)
+     8110:	46c0      	nop			; \(mov r8, r8\)
+     8112:	46c0      	nop			; \(mov r8, r8\)
+     8114:	0000000c 	.word	0x0000000c
+     8118:	4802      	ldr	r0, \[pc, #8\]	; \(8124 <bar\+0x84>\)
+     811a:	46c0      	nop			; \(mov r8, r8\)
+     811c:	46c0      	nop			; \(mov r8, r8\)
+     811e:	46c0      	nop			; \(mov r8, r8\)
+     8120:	46c0      	nop			; \(mov r8, r8\)
+     8122:	46c0      	nop			; \(mov r8, r8\)
+     8124:	0000000c 	.word	0x0000000c
Index: ld/testsuite/ld-arm/tls-descrelax.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descrelax.s
diff -N ld/testsuite/ld-arm/tls-descrelax.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descrelax.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,197 ----
+ @ we can relax local and non-weak globals for non-shared links
+ 
+ 	.text
+ 	.arm
+ 
+ 	.p2align 2
+ foo:
+ @tlscall global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:	ldr	r0, [pc, r0]
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 8)
+ 	
+ 	.p2align 2
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	gd1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @tlscall local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 
+ 	.p2align 2
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	ld1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @open coded global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:
+ 	add	r0, pc, r0
+ 	ldr	r1, [r0]
+ 	mov	r0, r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 8)
+ 
+ 	.p2align 2
+ @open coded global, should relax to IE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq gd1
+ 	add	r0, pc, r0
+ .tlsdescseq gd1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq gd1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b)
+ 
+ 	.p2align 2
+ @open coded local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 2:
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 	
+ 	.p2align 2
+ @open coded local, should relax to LE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq ld1
+ 	add	r0, pc, r0
+ .tlsdescseq ld1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq ld1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b)
+ 
+ 
+ 	.thumb
+ 	.p2align 1
+ bar:	
+ @tlscall global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:	add	r0, pc, r0
+ 	ldr	r0, [r0]
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 4)
+ 	
+ 	.p2align 1
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	gd1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall global, should relax to IE
+ 	ldr	r0, 1f
+ 2:	blx	r1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	r1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 
+ 	.p2align 1
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	ld1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @tlscall local, should relax to LE
+ 	ldr	r0, 1f
+ 2:	blx	r0(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	r0(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @open coded global, manually relaxed to IE
+ 	ldr	r0, 1f
+ 2:
+ 	add	r0, pc
+ 	ldr	r1, [r0]
+ 	mov	r0, r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(gottpoff) + (. - 2b - 4)
+ 
+ 	.p2align 1
+ @open coded global, should relax to IE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq gd1
+ 	add	r0, pc
+ .tlsdescseq gd1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq gd1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	gd1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.p2align 1
+ @open coded local, manually relaxed to LE
+ 	ldr	r0, 1f
+ 2:
+ 	nop
+ 	nop
+ 	nop
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tpoff)
+ 	
+ 	.p2align 1
+ @open coded local, should relax to LE
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq ld1
+ 	add	r0, pc
+ .tlsdescseq ld1
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq ld1
+ 	blx	r1
+ 	nop
+ 	.p2align 2
+ 1:	.word	ld1(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section .tdata,"awT"
+ 	.global	gd1
+ gd1:	.space 4
+ ld1:	.space 4
+ 	.globl r1
+ r1:	.space 4
+ r0:	.space 4
Index: ld/testsuite/ld-arm/tls-descseq.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descseq.d
diff -N ld/testsuite/ld-arm/tls-descseq.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descseq.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,44 ----
+ 
+ tmpdir/tls-lib2inline.so:     file format elf32-.*arm
+ architecture: arm, flags 0x[0-9a-f]+:
+ HAS_SYMS, DYNAMIC, D_PAGED
+ start address 0x[0-9a-f]+
+ 
+ Disassembly of section .plt:
+ 
+ [0-9a-f]+ <.plt>:
+     [0-9a-f]+:	e52de004 	push	{lr}		; .*
+     [0-9a-f]+:	e59fe004 	ldr	lr, \[pc, #4\]	; .*
+     [0-9a-f]+:	e08fe00e 	add	lr, pc, lr
+     [0-9a-f]+:	e5bef008 	ldr	pc, \[lr, #8\]!
+     [0-9a-f]+:	000080e4 	.word	0x000080e4
+     [0-9a-f]+:	e08e0000 	add	r0, lr, r0
+     [0-9a-f]+:	e5901004 	ldr	r1, \[r0, #4\]
+     [0-9a-f]+:	e12fff11 	bx	r1
+     [0-9a-f]+:	e52d2004 	push	{r2}		; .*
+     [0-9a-f]+:	e59f200c 	ldr	r2, \[pc, #12\]	; .*
+     [0-9a-f]+:	e59f100c 	ldr	r1, \[pc, #12\]	; .*
+     [0-9a-f]+:	e79f2002 	ldr	r2, \[pc, r2\]
+     [0-9a-f]+:	e081100f 	add	r1, r1, pc
+     [0-9a-f]+:	e12fff12 	bx	r2
+     [0-9a-f]+:	000080d4 	.word	0x000080d4
+     [0-9a-f]+:	000080bc 	.word	0x000080bc
+ 
+ Disassembly of section .text:
+ 
+ [0-9a-f]+ <foo>:
+     [0-9a-f]+:	e59f000c 	ldr	r0, \[pc, #12\]	; .*
+     [0-9a-f]+:	e08f0000 	add	r0, pc, r0
+     [0-9a-f]+:	e5901004 	ldr	r1, \[r0, #4\]
+     [0-9a-f]+:	e12fff31 	blx	r1
+     [0-9a-f]+:	e1a00000 	nop			; .*
+     [0-9a-f]+:	000080b4 	.word	0x000080b4
+ 
+ [0-9a-f]+ <bar>:
+     [0-9a-f]+:	4802      	ldr	r0, \[pc, #8\]	; .*
+     [0-9a-f]+:	4478      	add	r0, pc
+     [0-9a-f]+:	6841      	ldr	r1, \[r0, #4\]
+     [0-9a-f]+:	4788      	blx	r1
+     [0-9a-f]+:	46c0      	nop			; .*
+     [0-9a-f]+:	46c0      	nop			; .*
+     [0-9a-f]+:	000080a2 	.word	0x000080a2
Index: ld/testsuite/ld-arm/tls-descseq.r
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descseq.r
diff -N ld/testsuite/ld-arm/tls-descseq.r
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descseq.r	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,6 ----
+ 
+ .*:     file format elf32-.*arm
+ 
+ DYNAMIC RELOCATION RECORDS
+ OFFSET   TYPE              VALUE 
+ [0-9a-f]+ R_ARM_TLS_DESC    lib_gd2
Index: ld/testsuite/ld-arm/tls-descseq.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-descseq.s
diff -N ld/testsuite/ld-arm/tls-descseq.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-descseq.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,41 ----
+ 	.text
+ 	.arm
+ 	.globl foo
+ 	.type foo, %function
+ foo:
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq lib_gd2
+ 	add	r0, pc, r0
+ .tlsdescseq lib_gd2
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq lib_gd2
+ 	blx	r1
+ 	nop
+ 
+ 1:
+ 	.word	lib_gd2(tlsdesc) + (. - 2b)
+ 
+ 	.thumb
+ 	.globl bar
+ 	.type bar, %function
+ bar:
+ 	ldr	r0, 1f
+ 2:
+ .tlsdescseq lib_gd2
+ 	add	r0, pc
+ .tlsdescseq lib_gd2
+ 	ldr	r1, [r0,#4]
+ .tlsdescseq lib_gd2
+ 	blx	r1
+ 	nop
+ 
+ 	.p2align 2
+ 1:
+ 	.word	lib_gd2(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section .tdata,"awT"
+ 	.global lib_gd2
+ lib_gd2:
+ 	.space	4
+ 
Index: ld/testsuite/ld-arm/tls-gdesc-got.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdesc-got.d
diff -N ld/testsuite/ld-arm/tls-gdesc-got.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdesc-got.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,30 ----
+ 
+ .*/tls-lib2-got.so:     file format elf32-.*arm
+ architecture: arm, flags 0x00000150:
+ HAS_SYMS, DYNAMIC, D_PAGED
+ start address 0x00008210
+ 
+ 
+ Disassembly of section .got:
+ 
+ 00010310 <.*>:
+    10310:	00010288 	.*
+ 	...
+    1031c:	00000008 	.*
+ 			1031c: R_ARM_TLS_DESC	\*ABS\*
+    10320:	00000000 	.*
+    10324:	0000000c 	.*
+ 			10324: R_ARM_TLS_DESC	\*ABS\*
+    10328:	00000000 	.*
+    1032c:	80000004 	.*
+ 			1032c: R_ARM_TLS_DESC	glob1
+    10330:	00000000 	.*
+    10334:	80000006 	.*
+ 			10334: R_ARM_TLS_DESC	ext2
+    10338:	00000000 	.*
+    1033c:	80000007 	.*
+ 			1033c: R_ARM_TLS_DESC	ext1
+    10340:	00000000 	.*
+    10344:	80000009 	.*
+ 			10344: R_ARM_TLS_DESC	glob2
+ 	...
Index: ld/testsuite/ld-arm/tls-gdesc-got.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdesc-got.s
diff -N ld/testsuite/ld-arm/tls-gdesc-got.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdesc-got.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,45 ----
+ 
+ 	.arm
+ foo:
+ 	ldr	r0,1f
+ 2:	bl	loc1(tlscall)
+ 	nop
+ 1:	.word	loc1(tlsdesc) + (. - 2b)
+ 
+ 	ldr	r0,1f
+ 2:	bl	loc2(tlscall)
+ 	nop
+ 1:	.word	loc2(tlsdesc) + (. - 2b)
+ 
+ 	ldr	r0,1f
+ 2:	bl	glob1(tlscall)
+ 	nop
+ 1:	.word	glob1(tlsdesc) + (. - 2b)
+ 
+ 	ldr	r0,1f
+ 2:	bl	glob2(tlscall)
+ 	nop
+ 1:	.word	glob2(tlsdesc) + (. - 2b)
+ 
+ 	ldr	r0,1f
+ 2:	bl	ext1(tlscall)
+ 	nop
+ 1:	.word	ext1(tlsdesc) + (. - 2b)
+ 
+ 	ldr	r0,1f
+ 2:	bl	ext2(tlscall)
+ 	nop
+ 1:	.word	ext2(tlsdesc) + (. - 2b)
+ 
+ 	.section	.tdata,"awT",%progbits
+ 	.space	8
+ 	.type	loc1, %object
+ loc1:	.space	4
+ 	.type	loc2, %object
+ loc2:	.space	4
+ 	.globl	glob1
+ 	.type	glob1, %object
+ glob1:	.space	4
+ 	.globl	glob2
+ 	.type	glob2, %object
+ glob2:	.space	4
Index: ld/testsuite/ld-arm/tls-gdesc-nlazy.g
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdesc-nlazy.g
diff -N ld/testsuite/ld-arm/tls-gdesc-nlazy.g
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdesc-nlazy.g	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,4 ----
+ 
+ Hex dump of section '.got':
+   0x[0-9a-f]+ [0-9a-f]+ 00000000 00000000 00000000 ................
+   0x[0-9a-f]+ 00000000 00000000 00000000          ............
Index: ld/testsuite/ld-arm/tls-gdesc-nlazy.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdesc-nlazy.s
diff -N ld/testsuite/ld-arm/tls-gdesc-nlazy.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdesc-nlazy.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,17 ----
+ 	.text
+ 	.globl foo
+ 	.type foo, %function
+ foo:
+ 	nop
+ .L2:
+ 	blx	lib_gd2(tlscall) 
+ 	mov	pc, lr
+ 
+ .Lpool:
+ 	.word	lib_gd2(tlsdesc) + (. - .L2)
+ 
+ 	.section .tdata,"awT"
+ 	.global lib_gd2
+ lib_gd2:
+ 	.space	4
+ 
Index: ld/testsuite/ld-arm/tls-gdesc.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdesc.d
diff -N ld/testsuite/ld-arm/tls-gdesc.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdesc.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,42 ----
+ 
+ tmpdir/tls-lib2.so:     file format elf32-.*arm
+ architecture: arm, flags 0x[0-9a-f]+:
+ HAS_SYMS, DYNAMIC, D_PAGED
+ start address 0x[0-9a-f]+
+ 
+ Disassembly of section .plt:
+ 
+ [0-9a-f]+ <.plt>:
+     [0-9a-f]+:	e52de004 	push	{lr}		; .*
+     [0-9a-f]+:	e59fe004 	ldr	lr, \[pc, #4\]	; .*
+     [0-9a-f]+:	e08fe00e 	add	lr, pc, lr
+     [0-9a-f]+:	e5bef008 	ldr	pc, \[lr, #8\]!
+     [0-9a-f]+:	000080e8 	.word	0x000080e8
+     [0-9a-f]+:	e08e0000 	add	r0, lr, r0
+     [0-9a-f]+:	e5901004 	ldr	r1, \[r0, #4\]
+     [0-9a-f]+:	e12fff11 	bx	r1
+     [0-9a-f]+:	e52d2004 	push	{r2}		; .*
+     [0-9a-f]+:	e59f200c 	ldr	r2, \[pc, #12\]	; .*
+     [0-9a-f]+:	e59f100c 	ldr	r1, \[pc, #12\]	; .*
+     [0-9a-f]+:	e79f2002 	ldr	r2, \[pc, r2\]
+     [0-9a-f]+:	e081100f 	add	r1, r1, pc
+     [0-9a-f]+:	e12fff12 	bx	r2
+     [0-9a-f]+:	000080e0 	.word	0x000080e0
+     [0-9a-f]+:	000080c0 	.word	0x000080c0
+ Disassembly of section .text:
+ 
+ [0-9a-f]+ <foo>:
+     [0-9a-f]+:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+     [0-9a-f]+:	fafffff2 	blx	[0-9a-f]+ .*
+     [0-9a-f]+:	e1a00000 	nop			; .*
+     [0-9a-f]+:	000080c4 	.word	0x000080c4
+ 
+ [0-9a-f]+ <bar>:
+     [0-9a-f]+:	4801      	ldr	r0, \[pc, #4\]	; .*
+     [0-9a-f]+:	f7ff efe0 	blx	[0-9a-f]+ .*
+     [0-9a-f]+:	46c0      	nop			; .*
+     [0-9a-f]+:	000080b5 	.word	0x000080b5
+     [0-9a-f]+:	4801      	ldr	r0, \[pc, #4\]	; .*
+     [0-9a-f]+:	f7ff efda 	blx	[0-9a-f]+ .*
+     [0-9a-f]+:	46c0      	nop			; .*
+     [0-9a-f]+:	000080a1 	.word	0x000080a1
Index: ld/testsuite/ld-arm/tls-gdesc.r
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdesc.r
diff -N ld/testsuite/ld-arm/tls-gdesc.r
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdesc.r	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,7 ----
+ 
+ .*:     file format elf32-.*arm
+ 
+ DYNAMIC RELOCATION RECORDS
+ OFFSET   TYPE              VALUE 
+ [0-9a-f]+ R_ARM_TLS_DESC    lib_gd2
+ [0-9a-f]+ R_ARM_TLS_DESC    r0
Index: ld/testsuite/ld-arm/tls-gdesc.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdesc.s
diff -N ld/testsuite/ld-arm/tls-gdesc.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdesc.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,41 ----
+ 	.text
+ 	.arm
+ 	.globl foo
+ 	.type foo, %function
+ foo:
+ 	ldr	r0,1f
+ 2:
+ 	blx	lib_gd2(tlscall) 
+ 	nop
+ 
+ 1:
+ 	.word	lib_gd2(tlsdesc) + (. - 2b)
+ 
+ 	.thumb
+ 	.globl bar
+ 	.type bar, %function
+ bar:
+ 	ldr	r0,1f
+ 2:
+ 	blx	lib_gd2(tlscall) 
+ 	nop
+ 
+ 	.p2align 2
+ 1:
+ 	.word	lib_gd2(tlsdesc) + (. - 2b + 1)
+ 
+ 	ldr	r0,1f
+ 2:
+ 	blx	r0(tlscall) 
+ 	nop
+ 
+ 	.p2align 2
+ 1:
+ 	.word	r0(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section .tdata,"awT"
+ 	.global lib_gd2
+ lib_gd2:
+ 	.space	4
+ 	.globl r0
+ r0:	.space 4
Index: ld/testsuite/ld-arm/tls-gdierelax.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdierelax.d
diff -N ld/testsuite/ld-arm/tls-gdierelax.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdierelax.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,20 ----
+ 
+ tmpdir/tls-app-rel-ie:     file format elf32-.*arm
+ architecture: arm, flags 0x[0-9a-f]+:
+ EXEC_P, HAS_SYMS, D_PAGED
+ start address 0x[0-9a-f]+
+ 
+ Disassembly of section .text:
+ 
+ [0-9a-f]+ <foo>:
+     [0-9a-f]+:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+     [0-9a-f]+:	e79f0000 	ldr	r0, \[pc, r0\]
+     [0-9a-f]+:	e1a00000 	nop			; .*
+     [0-9a-f]+:	00008020 	.word	0x00008020
+ 
+ [0-9a-f]+ <bar>:
+     [0-9a-f]+:	4801      	ldr	r0, \[pc, #4\]	; .*
+     [0-9a-f]+:	4478      	add	r0, pc
+     [0-9a-f]+:	6800      	ldr	r0, \[r0, #0\]
+     [0-9a-f]+:	46c0      	nop			; .*
+     [0-9a-f]+:	00008016 	.word	0x00008016
Index: ld/testsuite/ld-arm/tls-gdierelax.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdierelax.s
diff -N ld/testsuite/ld-arm/tls-gdierelax.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdierelax.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,34 ----
+ 	.text
+ 	.arm
+ 	.globl foo
+ 	.type foo, %function
+ foo:
+ 	ldr	r0, 1f
+ 2:
+ 	blx	lib_gd2(tlscall) 
+ 	nop
+ 
+ 1:
+ 	.word	lib_gd2(tlsdesc) + (. - 2b)
+ 
+ 	.thumb
+ 	.globl bar
+ 	.type bar, %function
+ bar:
+ 	ldr	r0,1f
+ 2:
+ 	blx	lib_gd2(tlscall) 
+ 	nop
+ 
+ 	.p2align 2
+ 1:
+ 	.word	lib_gd2(tlsdesc) + (. - 2b + 1)
+ 
+ 	.globl _start
+ _start:
+ 	
+ 	.section .tdata,"awT"
+ 	.global lib_gd2
+ lib_gd2:
+ 	.space	4
+ 
Index: ld/testsuite/ld-arm/tls-gdierelax2.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdierelax2.d
diff -N ld/testsuite/ld-arm/tls-gdierelax2.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdierelax2.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,23 ----
+ 
+ tmpdir/tls-app-rel-ie2:     file format elf32-.*arm
+ architecture: arm, flags 0x[0-9a-f]+:
+ HAS_SYMS, DYNAMIC, D_PAGED
+ start address 0x[0-9a-f]+
+ 
+ Disassembly of section .text:
+ 
+ [0-9a-f]+ <foo>:
+     [0-9a-f]+:	e1a00000 	nop			; .*
+     [0-9a-f]+:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+     [0-9a-f]+:	e79f0000 	ldr	r0, \[pc, r0\]
+     [0-9a-f]+:	e1a00000 	nop			; .*
+     [0-9a-f]+:	00008098 	.word	0x00008098
+     [0-9a-f]+:	0000809c 	.word	0x0000809c
+ 
+ [0-9a-f]+ <bar>:
+     [0-9a-f]+:	4801      	ldr	r0, \[pc, #4\]	; .*
+     [0-9a-f]+:	4478      	add	r0, pc
+     [0-9a-f]+:	6800      	ldr	r0, \[r0, #0\]
+     [0-9a-f]+:	46c0      	nop			; .*
+     [0-9a-f]+:	0000808a 	.word	0x0000808a
+     [0-9a-f]+:	0000808c 	.word	0x0000808c
Index: ld/testsuite/ld-arm/tls-gdierelax2.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdierelax2.s
diff -N ld/testsuite/ld-arm/tls-gdierelax2.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdierelax2.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,35 ----
+ 	.text
+ 	.arm
+ 	.globl foo
+ 	.type foo, %function
+ foo:
+ 	nop
+ 3:	ldr	r0,1f
+ 2:	bl	lib_gd2(tlscall) 
+ 	nop
+ 
+ 1:
+ 	.word	lib_gd2(tlsdesc) + (. - 2b)
+ 	.word	lib_gd2(gottpoff) + (. - 3b - 8)
+ 
+ 	.thumb
+ 	.globl bar
+ 	.type bar, %function
+ bar:
+ 3:	ldr	r0,1f
+ 2:	blx	lib_gd2(tlscall) 
+ 	nop
+ 
+ 	.p2align 2
+ 1:
+ 	.word	lib_gd2(tlsdesc) + (. - 2b + 1)
+ 	.word	lib_gd2(gottpoff) + (. - 3b - 4)
+ 
+ 	.globl _start
+ _start:
+ 
+ 	.section .tdata,"awT"
+ 	.global lib_gd2
+ lib_gd2:
+ 	.space	4
+ 
Index: ld/testsuite/ld-arm/tls-gdlerelax.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdlerelax.d
diff -N ld/testsuite/ld-arm/tls-gdlerelax.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdlerelax.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,13 ----
+ 
+ tmpdir/tls-app-rel-le:     file format elf32-.*arm
+ architecture: arm, flags 0x[0-9a-f]+:
+ EXEC_P, HAS_SYMS, D_PAGED
+ start address 0x[0-9a-f]+
+ 
+ Disassembly of section .text:
+ 
+ [0-9a-f]+ <foo>:
+     [0-9a-f]+:	e1a00000 	nop			; .*
+     [0-9a-f]+:	e1a00000 	nop			; .*
+     [0-9a-f]+:	e1a0f00e 	mov	pc, lr
+     [0-9a-f]+:	00000008 	.word	0x00000008
Index: ld/testsuite/ld-arm/tls-gdlerelax.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-gdlerelax.s
diff -N ld/testsuite/ld-arm/tls-gdlerelax.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-gdlerelax.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,16 ----
+ 	.text
+ 	.globl foo
+ 	.type foo, %function
+ foo:
+ 	nop
+ .L2:
+ 	blx	lib_gd2(tlscall) 
+ 	mov	pc, lr
+ 
+ .Lpool:
+ 	.word	lib_gd2(tlsdesc) + (. - .L2)
+ 
+ 	.section .tdata,"awT"
+ lib_gd2:
+ 	.space	4
+ 
Index: ld/testsuite/ld-arm/tls-lib-loc.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-lib-loc.d
diff -N ld/testsuite/ld-arm/tls-lib-loc.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-lib-loc.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,33 ----
+ 
+ .*:     file format elf32-.*arm
+ architecture: arm, flags 0x00000150:
+ HAS_SYMS, DYNAMIC, D_PAGED
+ start address 0x.*
+ 
+ Disassembly of section .plt:
+ 
+ [0-9a-f]+ <.plt>:
+     [0-9a-f]+:	e52de004 	push	{lr}		; .*
+     [0-9a-f]+:	e59fe004 	ldr	lr, \[pc, #4\]	; 8150 .*
+     [0-9a-f]+:	e08fe00e 	add	lr, pc, lr
+     [0-9a-f]+:	e5bef008 	ldr	pc, \[lr, #8\]!
+     8150:	000080cc 	.word	0x000080cc
+     8154:	e08e0000 	add	r0, lr, r0
+     [0-9a-f]+:	e5901004 	ldr	r1, \[r0, #4\]
+     [0-9a-f]+:	e12fff11 	bx	r1
+     [0-9a-f]+:	e52d2004 	push	{r2}		; .*
+     8164:	e59f200c 	ldr	r2, \[pc, #12\]	; 8178 .*
+     [0-9a-f]+:	e59f100c 	ldr	r1, \[pc, #12\]	; 817c .*
+     [0-9a-f]+:	e79f2002 	ldr	r2, \[pc, r2\]
+     [0-9a-f]+:	e081100f 	add	r1, r1, pc
+     [0-9a-f]+:	e12fff12 	bx	r2
+     8178:	000080bc 	.word	0x000080bc
+     817c:	000080a4 	.word	0x000080a4
+ 
+ Disassembly of section .text:
+ 
+ [0-9a-f]+ <foo>:
+     [0-9a-f]+:	e59f0004 	ldr	r0, \[pc, #4\]	; 818c .*
+     [0-9a-f]+:	fafffff2 	blx	8154 <.*\+0x8154>
+     [0-9a-f]+:	e1a00000 	nop			; .*
+     818c:	000080a0 	.word	0x000080a0
Index: ld/testsuite/ld-arm/tls-lib-loc.r
===================================================================
RCS file: ld/testsuite/ld-arm/tls-lib-loc.r
diff -N ld/testsuite/ld-arm/tls-lib-loc.r
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-lib-loc.r	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,6 ----
+ 
+ .*:     file format elf32-.*arm
+ 
+ DYNAMIC RELOCATION RECORDS
+ OFFSET   TYPE              VALUE 
+ .* R_ARM_TLS_DESC    \*ABS\*
Index: ld/testsuite/ld-arm/tls-lib-loc.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-lib-loc.s
diff -N ld/testsuite/ld-arm/tls-lib-loc.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-lib-loc.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,14 ----
+ 	.text
+ 	.arm
+ 
+ foo:
+ 	ldr	r0,1f
+ 2:	blx	loc(tlscall)
+ 	nop
+ 
+ 	.p2align 2
+ 1:	.word	loc(tlsdesc) + (. - 2b)
+ 
+ 	.section .tdata,"awT"
+ loc:
+ 	.space	4
Index: ld/testsuite/ld-arm/tls-longplt-lib.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-longplt-lib.d
diff -N ld/testsuite/ld-arm/tls-longplt-lib.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-longplt-lib.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,59 ----
+ .*:     file format elf32-.*arm
+ architecture: arm, flags 0x00000150:
+ HAS_SYMS, DYNAMIC, D_PAGED
+ start address 0x.*
+ 
+ Disassembly of section .plt:
+ 
+ 00008198 <.plt>:
+     8198:	e52de004 	push	{lr}		; .*
+     819c:	e59fe004 	ldr	lr, \[pc, #4\]	; .*
+     81a0:	e08fe00e 	add	lr, pc, lr
+     81a4:	e5bef008 	ldr	pc, \[lr, #8\]!
+     81a8:	000080e0 	.word	0x000080e0
+     81ac:	e08e0000 	add	r0, lr, r0
+     81b0:	e5901004 	ldr	r1, \[r0, #4\]
+     81b4:	e12fff11 	bx	r1
+     81b8:	e52d2004 	push	{r2}		; .*
+     81bc:	e59f200c 	ldr	r2, \[pc, #12\]	; .*
+     81c0:	e59f100c 	ldr	r1, \[pc, #12\]	; .*
+     81c4:	e79f2002 	ldr	r2, \[pc, r2\]
+     81c8:	e081100f 	add	r1, r1, pc
+     81cc:	e12fff12 	bx	r2
+     81d0:	000080d8 	.word	0x000080d8
+     81d4:	000080b8 	.word	0x000080b8
+ 
+ Disassembly of section .text:
+ 
+ 000081d8 <text>:
+     81d8:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+     81dc:	fafffff2 	blx	81ac .*
+     81e0:	e1a00000 	nop			; .*
+     81e4:	000080b4 	.word	0x000080b4
+     81e8:	4801      	ldr	r0, \[pc, #4\]	; .*
+     81ea:	f7ff efe0 	blx	81ac <.*>
+     81ee:	46c0      	nop			; .*
+     81f0:	000080a5 	.word	0x000080a5
+ 
+ Disassembly of section .foo:
+ 
+ 04001000 <foo>:
+  4001000:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+  4001004:	fa000009 	blx	4001030 .*
+  4001008:	e1a00000 	nop			; .*
+  400100c:	fc00f28c 	.word	0xfc00f28c
+  4001010:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+  4001014:	fa000005 	blx	4001030 .*
+  4001018:	e1a00000 	nop			; .*
+  400101c:	fc00f284 	.word	0xfc00f284
+  4001020:	4801      	ldr	r0, \[pc, #4\]	; .*
+  4001022:	f000 e806 	blx	4001030 .*
+  4001026:	46c0      	nop			; .*
+  4001028:	fc00f26d 	.word	0xfc00f26d
+  400102c:	00000000 	.word	0x00000000
+ 
+ 04001030 <__unnamed_veneer>:
+  4001030:	e59f1000 	ldr	r1, \[pc, #0\]	; .*
+  4001034:	e08ff001 	add	pc, pc, r1
+  4001038:	fc007170 	.word	0xfc007170
+  400103c:	00000000 	.word	0x00000000
Index: ld/testsuite/ld-arm/tls-longplt-lib.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-longplt-lib.s
diff -N ld/testsuite/ld-arm/tls-longplt-lib.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-longplt-lib.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,51 ----
+ 	.syntax unified
+ 	.text
+ text:
+ 	.arm
+ 	ldr	r0,1f
+ 2:	blx	loc(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	loc(tlsdesc) + (. - 2b)
+ 
+ 	.thumb
+ 	ldr	r0,1f
+ 2:	blx	loc(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	loc(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section ".foo","ax"
+ foo:
+ 	.arm
+ 	ldr	r0,1f
+ 2:	blx	loc(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	loc(tlsdesc) + (. - 2b)
+ 
+ 	.arm
+ 	ldr	r0,1f
+ 2:	blx	glob(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	glob(tlsdesc) + (. - 2b)
+ 
+ 	.thumb
+ 	ldr	r0,1f
+ 2:	blx	loc(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	loc(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section .tdata,"awT"
+ 	.type	loc, %object
+ loc:	.space	4
+ 
+ 	@ glob1 and glob2 used by tls-longplt
+ 	.type	glob1, %object
+ 	.globl	glob1
+ glob1:	.space	4
+ 	.type	glob2, %object
+ 	.globl	glob2
+ glob2:	.space	4
Index: ld/testsuite/ld-arm/tls-longplt.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-longplt.d
diff -N ld/testsuite/ld-arm/tls-longplt.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-longplt.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,64 ----
+ .*:     file format elf32-.*arm
+ architecture: arm, flags 0x00000112:
+ EXEC_P, HAS_SYMS, D_PAGED
+ start address 0x.*
+ 
+ Disassembly of section .plt:
+ 
+ 0000819c <.plt>:
+     819c:	e52de004 	push	{lr}		; .*
+     81a0:	e59fe004 	ldr	lr, \[pc, #4\]	; .*
+     81a4:	e08fe00e 	add	lr, pc, lr
+     81a8:	e5bef008 	ldr	pc, \[lr, #8\]!
+     81ac:	00008100 	.word	0x00008100
+     81b0:	e08e0000 	add	r0, lr, r0
+     81b4:	e5901004 	ldr	r1, \[r0, #4]
+     81b8:	e12fff11 	bx	r1
+     81bc:	e52d2004 	push	{r2}		; .*
+     81c0:	e59f200c 	ldr	r2, \[pc, #12\]	; .*
+     81c4:	e59f100c 	ldr	r1, \[pc, #12\]	; .*
+     81c8:	e79f2002 	ldr	r2, \[pc, r2\]
+     81cc:	e081100f 	add	r1, r1, pc
+     81d0:	e12fff12 	bx	r2
+     81d4:	000080f4 	.word	0x000080f4
+     81d8:	000080d8 	.word	0x000080d8
+ 
+ Disassembly of section .text:
+ 
+ 000081dc <text>:
+     81dc:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+     81e0:	fafffff2 	blx	81b0 .*
+     81e4:	e1a00000 	nop			; .*
+     81e8:	000080d4 	.word	0x000080d4
+     81ec:	4801      	ldr	r0, \[pc, #4\]	; .*
+     81ee:	f7ff efe0 	blx	81b0 .*
+     81f2:	46c0      	nop			; .*
+     81f4:	000080c5 	.word	0x000080c5
+ 
+ Disassembly of section .foo:
+ 
+ 04001000 <foo>:
+  4001000:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+  4001004:	e79f0000 	ldr	r0, \[pc, r0\]
+  4001008:	e1a00000 	nop			; .*
+  400100c:	fc00f2b4 	.word	0xfc00f2b4
+  4001010:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+  4001014:	fa000005 	blx	4001030 .*
+  4001018:	e1a00000 	nop			; .*
+  400101c:	fc00f2a0 	.word	0xfc00f2a0
+  4001020:	4801      	ldr	r0, \[pc, #4\]	; .*
+  4001022:	f000 e80a 	blx	4001038 .*
+  4001026:	46c0      	nop			; .*
+  4001028:	fc00f291 	.word	0xfc00f291
+  400102c:	00000000 	.word	0x00000000
+ 
+ 04001030 <__unnamed_veneer>:
+  4001030:	e51ff004 	ldr	pc, \[pc, #-4\]	; .*
+  4001034:	000081b0 	.word	0x000081b0
+ 
+ 04001038 <__unnamed_veneer>:
+  4001038:	4778      	bx	pc
+  400103a:	46c0      	nop			; .*
+  400103c:	e51ff004 	ldr	pc, \[pc, #-4\]	; .*
+  4001040:	000081b0 	.word	0x000081b0
+  4001044:	00000000 	.word	0x00000000
Index: ld/testsuite/ld-arm/tls-longplt.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-longplt.s
diff -N ld/testsuite/ld-arm/tls-longplt.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-longplt.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,47 ----
+ 	.syntax unified
+ 	.text
+ text:
+ 	.arm
+ 	ldr	r0,1f
+ 2:	blx	udefw(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	udefw(tlsdesc) + (. - 2b)
+ 
+ 	.thumb
+ 	ldr	r0,1f
+ 2:	blx	udefw(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	udefw(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section ".foo","ax"
+ foo:
+ 	.arm
+ 	ldr	r0,1f
+ 2:	blx	glob1(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	glob1(tlsdesc) + (. - 2b)
+ 
+ 	.arm
+ 	ldr	r0,1f
+ 2:	blx	udefw(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	udefw(tlsdesc) + (. - 2b)
+ 
+ 	.thumb
+ 	ldr	r0,1f
+ 2:	blx	udefw(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	udefw(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section .tdata,"awT"
+ 	@ glob used by tls-longplt-lib
+ 	.type	glob, %object
+ 	.globl	glob
+ glob:	.space	4
+ 	.globl  udefw
+ 	.weak	udefw
Index: ld/testsuite/ld-arm/tls-mixed.r
===================================================================
RCS file: ld/testsuite/ld-arm/tls-mixed.r
diff -N ld/testsuite/ld-arm/tls-mixed.r
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-mixed.r	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,10 ----
+ 
+ .*:     file format elf32-.*arm
+ 
+ DYNAMIC RELOCATION RECORDS
+ OFFSET   TYPE              VALUE 
+ [0-9a-f]+ R_ARM_TLS_DTPMOD32  lib_gd2
+ [0-9a-f]+ R_ARM_TLS_DTPOFF32  lib_gd2
+ [0-9a-f]+ R_ARM_TLS_DTPMOD32  lib_gd
+ [0-9a-f]+ R_ARM_TLS_DTPOFF32  lib_gd
+ [0-9a-f]+ R_ARM_TLS_DESC    lib_gd2
Index: ld/testsuite/ld-arm/tls-mixed.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-mixed.s
diff -N ld/testsuite/ld-arm/tls-mixed.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-mixed.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,25 ----
+ 	.text
+ 	.globl foo
+ 	.type foo, %function
+ foo:
+ 	nop
+ .L1:
+ 	nop	
+ .L2:
+ 	bl	lib_gd2(tlscall) 
+ 	mov	pc, lr
+ 
+ .Lpool:
+ 	.word	lib_gd(tlsgd)	+  (. - .L1 - 8)
+ .Lpool2:
+ 	.word	lib_gd2(tlsdesc) + (. - .L2)
+ 	.word	lib_gd2(tlsgd)	+  (. - .L2 - 8)
+ 
+ 	.section .tdata,"awT"
+ 	.global lib_gd
+ lib_gd:
+ 	.space	4 
+ 	.global lib_gd2
+ lib_gd2:
+ 	.space	4
+ 
Index: ld/testsuite/ld-arm/tls-thumb1.d
===================================================================
RCS file: ld/testsuite/ld-arm/tls-thumb1.d
diff -N ld/testsuite/ld-arm/tls-thumb1.d
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-thumb1.d	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,74 ----
+ .*:     file format elf32-.*arm
+ architecture: arm, flags 0x00000150:
+ HAS_SYMS, DYNAMIC, D_PAGED
+ start address 0x.*
+ 
+ Disassembly of section .plt:
+ 
+ 00008164 <.plt>:
+     8164:	e52de004 	push	{lr}		; .*
+     8168:	e59fe004 	ldr	lr, \[pc, #4\]	; .*
+     816c:	e08fe00e 	add	lr, pc, lr
+     8170:	e5bef008 	ldr	pc, \[lr, #8\]!
+     8174:	000080f0 	.word	0x000080f0
+     8178:	e08e0000 	add	r0, lr, r0
+     817c:	e5901004 	ldr	r1, \[r0, #4\]
+     8180:	e12fff11 	bx	r1
+     8184:	e52d2004 	push	{r2}		; .*
+     8188:	e59f200c 	ldr	r2, \[pc, #12\]	; .*
+     818c:	e59f100c 	ldr	r1, \[pc, #12\]	; .*
+     8190:	e79f2002 	ldr	r2, \[pc, r2\]
+     8194:	e081100f 	add	r1, r1, pc
+     8198:	e12fff12 	bx	r2
+     819c:	000080e8 	.word	0x000080e8
+     81a0:	000080c8 	.word	0x000080c8
+ 
+ Disassembly of section .text:
+ 
+ 000081a8 <text>:
+     81a8:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+     81ac:	ebfffff1 	bl	8178 .*
+     81b0:	e1a00000 	nop			; .*
+     81b4:	000080c0 	.word	0x000080c0
+     81b8:	4801      	ldr	r0, \[pc, #4\]	; .*
+     81ba:	f000 e806 	blx	81c8 .*
+     81be:	46c0      	nop			; .*
+     81c0:	000080b1 	.word	0x000080b1
+     81c4:	00000000 	.word	0x00000000
+ 
+ 000081c8 <__unnamed_veneer>:
+     81c8:	4778      	bx	pc
+     81ca:	46c0      	nop			; .*
+     81cc:	e59f1000 	ldr	r1, \[pc, #0\]	; .*
+     81d0:	e081f00f 	add	pc, r1, pc
+     81d4:	ffffffa0 	.word	0xffffffa0
+ 
+ Disassembly of section .foo:
+ 
+ 04001000 <foo>:
+  4001000:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+  4001004:	eb000009 	bl	4001030 .*
+  4001008:	e1a00000 	nop			; .*
+  400100c:	fc00f268 	.word	0xfc00f268
+  4001010:	e59f0004 	ldr	r0, \[pc, #4\]	; .*
+  4001014:	eb000005 	bl	4001030 .*
+  4001018:	e1a00000 	nop			; .*
+  400101c:	fc00f260 	.word	0xfc00f260
+  4001020:	4801      	ldr	r0, \[pc, #4\]	; .*
+  4001022:	f000 e80c 	blx	400103c .*
+  4001026:	46c0      	nop			; .*
+  4001028:	fc00f249 	.word	0xfc00f249
+  400102c:	00000000 	.word	0x00000000
+ 
+ 04001030 <__unnamed_veneer>:
+  4001030:	e59f1000 	ldr	r1, \[pc, #0\]	; .*
+  4001034:	e08ff001 	add	pc, pc, r1
+  4001038:	fc00713c 	.word	0xfc00713c
+ 
+ 0400103c <__unnamed_veneer>:
+  400103c:	4778      	bx	pc
+  400103e:	46c0      	nop			; .*
+  4001040:	e59f1000 	ldr	r1, \[pc, #0\]	; .*
+  4001044:	e081f00f 	add	pc, r1, pc
+  4001048:	fc00712c 	.word	0xfc00712c
+  400104c:	00000000 	.word	0x00000000
Index: ld/testsuite/ld-arm/tls-thumb1.s
===================================================================
RCS file: ld/testsuite/ld-arm/tls-thumb1.s
diff -N ld/testsuite/ld-arm/tls-thumb1.s
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- ld/testsuite/ld-arm/tls-thumb1.s	7 Jan 2011 13:09:15 -0000
***************
*** 0 ****
--- 1,43 ----
+ 	.arch armv4t
+ 	.syntax unified
+ 	.text
+ text:
+ 	.arm
+ 	ldr	r0,1f
+ 2:	bl	+loc(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	loc(tlsdesc) + (. - 2b)
+ 
+ 	.thumb
+ 	ldr	r0,1f
+ 2:	bl	+loc(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	loc(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section ".foo","ax"
+ foo:
+ 	.arm
+ 	ldr	r0,1f
+ 2:	bl	+loc(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	loc(tlsdesc) + (. - 2b)
+ 
+ 	.arm
+ 	ldr	r0,1f
+ 2:	bl	+glob(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	glob(tlsdesc) + (. - 2b)
+ 
+ 	.thumb
+ 	ldr	r0,1f
+ 2:	bl	+loc(tlscall)
+ 	nop
+ 	.p2align 2
+ 1:	.word	loc(tlsdesc) + (. - 2b + 1)
+ 
+ 	.section .tdata,"awT"
+ loc:	.space	4

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