--- old/usr/src/cmd/sgs/libld/common/machrel.amd.c	2012-11-05 20:40:46.272602832 -0500
+++ new/usr/src/cmd/sgs/libld/common/machrel.amd.c	2012-11-05 20:40:46.296428071 -0500
@@ -514,6 +514,23 @@
 	0x00, 0x00, 0x00, 0x00
 };
 
+#define	REX_B		0x1
+#define	REX_X		0x2
+#define	REX_R		0x4
+#define	REX_W		0x8
+#define	REX_PREFIX	0x40
+
+#define	REX_RW		(REX_PREFIX | REX_R | REX_W)
+#define	REX_BW		(REX_PREFIX | REX_B | REX_W)
+#define	REX_BRW		(REX_PREFIX | REX_B | REX_R | REX_W)
+
+#define	REG_ESP		0x4
+
+#define	INSN_ADDMR	0x03	/* addq mem,reg */
+#define	INSN_ADDIR	0x81	/* addq imm,reg */
+#define	INSN_MOVMR	0x8b	/* movq mem,reg */
+#define	INSN_MOVIR	0xc7	/* movq imm,reg */
+#define	INSN_LEA	0x8d	/* leaq mem,reg */
 
 static Fixupret
 tls_fixups(Ofl_desc *ofl, Rel_desc *arsp)
@@ -526,6 +543,10 @@
 	    (uintptr_t)_elf_getxoff(arsp->rel_isdesc->is_indata) +
 	    (uintptr_t)RELAUX_GET_OSDESC(arsp)->os_outdata->d_buf);
 
+	/*
+	 * Note that in certain of the original insn sequences below, the
+	 * instructions are not necessarily adjacent
+	 */
 	if (sdp->sd_ref == REF_DYN_NEED) {
 		/*
 		 * IE reference model
@@ -605,35 +626,88 @@
 		(void) memcpy(offset, tlsinstr_gd_le, sizeof (tlsinstr_gd_le));
 		return (FIX_RELOC);
 
-	case R_AMD64_GOTTPOFF:
+	case R_AMD64_GOTTPOFF: {
 		/*
 		 * IE -> LE
 		 *
-		 * Transition:
-		 *	0x00 movq %fs:0, %rax
-		 *	0x09 addq x@gottopoff(%rip), %rax
-		 *	0x10
+		 * Transition 1:
+		 *	movq %fs:0, %reg
+		 *	addq x@gottpoff(%rip), %reg
 		 * To:
-		 *	0x00 movq %fs:0, %rax
-		 *	0x09 leaq x@tpoff(%rax), %rax
-		 *	0x10
+		 *	movq %fs:0, %reg
+		 *	leaq x@tpoff(%reg), %reg
+		 *
+		 * Transition (as a special case):
+		 *	movq %fs:0, %r12/%rsp
+		 *	addq x@gottpoff(%rip), %r12/%rsp
+		 * To:
+		 *	movq %fs:0, %r12/%rsp
+		 *	addq x@tpoff(%rax), %r12/%rsp
+		 *
+		 * Transition 2:
+		 *	movq x@gottpoff(%rip), %reg
+		 *	movq %fs:(%reg), %reg
+		 * To:
+		 *	movq x@tpoff(%reg), %reg
+		 *	movq %fs:(%reg), %reg
 		 */
+		Conv_inv_buf_t	inv_buf;
+		uint8_t reg;		/* Register */
+
+		offset -= 3;
+
+		reg = offset[2] >> 3; /* Encoded dest. reg. operand */
+
 		DBG_CALL(Dbg_reloc_transition(ofl->ofl_lml, M_MACH,
 		    R_AMD64_TPOFF32, arsp, ld_reloc_sym_name));
 		arsp->rel_rtype = R_AMD64_TPOFF32;
 		arsp->rel_raddend = 0;
 
 		/*
-		 * Adjust 'offset' to beginning of instruction sequence.
+		 * This is transition 2, and the special case of form 1 where
+		 * a normal transition would index %rsp or %r12 and need a SIB
+		 * byte in the leaq for which we lack space
 		 */
-		offset -= 12;
+		if ((offset[1] == INSN_MOVMR) ||
+		    ((offset[1] == INSN_ADDMR) && (reg == REG_ESP))) {
+			/*
+			 * If we needed an extra bit of MOD.reg to refer to
+			 * this register as the dest of the original movq we
+			 * need an extra bit of MOD.rm to refer to it in the
+			 * dest of the replacement movq or addq.
+			 */
+			if (offset[0] == REX_RW)
+				offset[0] = REX_BW;
 
-		/*
-		 * Same code sequence used in the GD -> LE transition.
-		 */
-		(void) memcpy(offset, tlsinstr_gd_le, sizeof (tlsinstr_gd_le));
-		return (FIX_RELOC);
+			offset[1] = (offset[1] == INSN_MOVMR) ?
+			    INSN_MOVIR : INSN_ADDIR;
+			offset[2] = 0xc0 | reg;
+
+			return (FIX_RELOC);
+		} else if (offset[1] == INSN_ADDMR) {
+			/*
+			 * If we needed an extra bit of MOD.reg to refer to
+			 * this register in the dest of the addq we need an
+			 * extra bit of both MOD.reg and MOD.rm to refer to it
+			 * in the source and dest of the leaq
+			 */
+			if (offset[0] == REX_RW)
+				offset[0] = REX_BRW;
+
+			offset[1] = INSN_LEA;
+			offset[2] = 0x80 | (reg << 3) | reg;
 
+			return (FIX_RELOC);
+		}
+
+		ld_eprintf(ofl, ERR_FATAL, MSG_INTL(MSG_REL_BADTLSINS),
+		    conv_reloc_amd64_type(arsp->rel_rtype, 0, &inv_buf),
+		    arsp->rel_isdesc->is_file->ifl_name,
+		    ld_reloc_sym_name(arsp),
+		    arsp->rel_isdesc->is_name,
+		    EC_OFF(arsp->rel_roffset));
+		return (FIX_ERROR);
+	}
 	case R_AMD64_TLSLD:
 		/*
 		 * LD -> LE
--- /dev/null	2012-11-05 20:40:46.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/Makefile	2012-11-05 20:40:46.886046136 -0500
@@ -0,0 +1,87 @@
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+# Copyright 2012, Richard Lowe.
+
+include $(SRC)/Makefile.master
+
+# We have to use GCC, and only GCC.  The best way is to ask cw(1) which GCC to use.
+CC_CMD =	$(ONBLD_TOOLS)/bin/$(MACH)/cw -_gcc -_compiler
+CC =		$(CC_CMD:sh)
+CFLAGS = 	-O1 -m64
+
+LINK.c = env LD_ALTEXEC=$(PROTO)/usr/bin/amd64/ld $(CC) $(CFLAGS) -o $@ $^
+COMPILE.c = $(CC) $(CFLAGS) -c -o $@ $^
+COMPILE.s = $(CC) $(CFLAGS) -c -o $@ $^
+
+.KEEP_STATE:
+
+install default: all
+
+.c.o:
+	$(COMPILE.c)
+
+.s.o:
+	$(COMPILE.s)
+
+# A basic use of TLS that uses the movq m/r --> movq i/r variant
+PROGS += 	style2
+STYLE2OBJS =	style2.o
+style2: $(STYLE2OBJS)
+	$(LINK.c)
+
+# A copy of style2 that uses %r13 in the TLS sequence, and thus excercises the
+# REX transitions of the movq mem,reg -> movq imm,reg variant.
+PROGS +=	style2-with-r13
+STYLE2R13OBJS =	style2-with-r13.o
+style2-with-r13: $(STYLE2R13OBJS)
+	$(LINK.c)
+
+# A copy of style2 that uses %r12 in the TLS sequence, so we can verify that
+# it is _not_ special to this variant
+PROGS +=	style2-with-r12
+STYLE2R12OBJS =	style2-with-r12.o
+style2-with-r12: $(STYLE2R12OBJS)
+	$(LINK.c)
+
+# A copy of style2 that has a R_AMD64_GOTTPOFF relocation with a bad insn sequence
+STYLE2BADNESSOBJS =	style2-with-badness.o
+style2-with-badness: $(STYLE2BADNESSOBJS)
+	-$(LINK.c)
+
+# A basic use of TLS that uses the addq mem/reg --> leaq mem,reg variant
+PROGS +=	style1
+STYLE1OBJS =	style1-main.o style1-func.o
+style1: $(STYLE1OBJS)
+	$(LINK.c)
+
+# A copy of style1-func that uses %r13 in the TLS sequence and thus excercises
+# the REX transitions. of the addq mem,reg --> leaq mem,reg variant
+PROGS +=	style1-with-r13
+STYLE1R13OBJS =	style1-main.o style1-func-with-r13.o
+style1-with-r13: $(STYLE1R13OBJS)
+	$(LINK.c)
+
+# A copy of style1-func that uses %r12 to test the addq mem,reg --> addq imm,reg variant
+PROGS +=	style1-with-r12
+STYLE1R12OBJS =	style1-main.o style1-func-with-r12.o
+style1-with-r12: $(STYLE1R12OBJS)
+	$(LINK.c)
+
+all:	$(PROGS)
+
+clobber clean: 
+	rm -f $(PROGS) $(STYLE1OBJS) $(STYLE1R13OBJS) $(STYLE1R12OBJS) \
+	    $(STYLE2OBJS) $(STYLE2R13OBJS) $(STYLE2R12OBJS) $(STYLE2BADNESSOBJS)
+
+fail: style2-with-badness FRC
+
+FRC:
--- /dev/null	2012-11-05 20:40:47.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/README	2012-11-05 20:40:47.081053995 -0500
@@ -0,0 +1,9 @@
+This tests the x64 link-editor's handling of Initial Executable TLS sequences.
+
+The original C source files are in orig/ but unused, since we need to avoid
+any changes to the compiler influencing our tests.
+
+    % ksh test.sh /path/to/proto/root
+    pass: addq-->leaq 1
+    ...
+    pass: bad insn sequence
--- /dev/null	2012-11-05 20:40:47.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/orig/style1-func.c	2012-11-05 20:40:47.255302829 -0500
@@ -0,0 +1,24 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+
+extern __thread char *foo, *bar;
+
+void
+func()
+{
+	printf("foo: %p bar: %p\n", &foo, &bar);
+}
--- /dev/null	2012-11-05 20:40:47.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/orig/style1-main.c	2012-11-05 20:40:47.628216937 -0500
@@ -0,0 +1,29 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+
+extern void func();
+
+__thread char *foo = "foo";
+__thread char *bar = "bar";
+
+int
+main(void)
+{
+	printf("foo: %p bar: %p\n", &foo, &bar);
+	func();
+	return (0);
+}
--- /dev/null	2012-11-05 20:40:47.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/orig/style2.c	2012-11-05 20:40:47.803826709 -0500
@@ -0,0 +1,25 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+#include <stdio.h>
+
+__thread char *foo __attribute__((tls_model("initial-exec"))) = "foo";
+
+int
+main(void)
+{
+	printf("foo: %p\n", &foo);
+	return (0);
+}
--- /dev/null	2012-11-05 20:40:47.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/style1-func-with-r12.s	2012-11-05 20:40:47.977081490 -0500
@@ -0,0 +1,39 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"foo: %p bar: %p\n"
+	.text
+.globl func
+	.type	func, @function
+func:
+.LFB0:
+	pushq	%rbp
+.LCFI0:
+	movq	%rsp, %rbp
+.LCFI1:
+	movq	%fs:0, %r12
+	movq	%r12, %rdx
+	addq	bar@GOTTPOFF(%rip), %rdx
+	addq	foo@GOTTPOFF(%rip), %r12
+        movq    %r12, %rsi     
+	movl	$.LC0, %edi
+	movl	$0, %eax
+	call	printf
+	leave
+	ret
+.LFE0:
+	.size	func, .-func
--- /dev/null	2012-11-05 20:40:48.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/style1-func-with-r13.s	2012-11-05 20:40:48.236690958 -0500
@@ -0,0 +1,38 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"foo: %p bar: %p\n"
+	.text
+.globl func
+	.type	func, @function
+func:
+.LFB0:
+	pushq	%rbp
+.LCFI0:
+	movq	%rsp, %rbp
+.LCFI1:
+	movq	%fs:0, %r13
+	movq	%r13, %rdx
+	addq	bar@GOTTPOFF(%rip), %rdx
+	addq	foo@GOTTPOFF(%rip), %r13
+        movq    %r13, %rsi
+	movl	$.LC0, %edi
+	movl	$0, %eax
+	call	printf
+	leave
+	ret
+.LFE0:
+	.size	func, .-func
--- /dev/null	2012-11-05 20:40:48.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/style1-func.s	2012-11-05 20:40:48.411122533 -0500
@@ -0,0 +1,38 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"foo: %p bar: %p\n"
+	.text
+.globl func
+	.type	func, @function
+func:
+.LFB0:
+	pushq	%rbp
+.LCFI0:
+	movq	%rsp, %rbp
+.LCFI1:
+	movq	%fs:0, %rsi
+	movq	%rsi, %rdx
+	addq	bar@GOTTPOFF(%rip), %rdx
+	addq	foo@GOTTPOFF(%rip), %rsi
+	movl	$.LC0, %edi
+	movl	$0, %eax
+	call	printf
+	leave
+	ret
+.LFE0:
+	.size	func, .-func
--- /dev/null	2012-11-05 20:40:48.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/style1-main.s	2012-11-05 20:40:48.584884319 -0500
@@ -0,0 +1,60 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */
+
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"foo: %p bar: %p\n"
+	.text
+.globl main
+	.type	main, @function
+main:
+.LFB0:
+	pushq	%rbp
+.LCFI0:
+	movq	%rsp, %rbp
+.LCFI1:
+	movq	%fs:0, %rsi
+	leaq	bar@TPOFF(%rsi), %rdx
+	addq	$foo@TPOFF, %rsi
+	movl	$.LC0, %edi
+	movl	$0, %eax
+	call	printf
+	movl	$0, %eax
+	call	func
+	movl	$0, %eax
+	leave
+	ret
+.LFE0:
+	.size	main, .-main
+.globl foo
+	.section	.rodata.str1.1
+.LC1:
+	.string	"foo"
+	.section	.tdata,"awT",@progbits
+	.align 8
+	.type	foo, @object
+	.size	foo, 8
+foo:
+	.quad	.LC1
+.globl bar
+	.section	.rodata.str1.1
+.LC2:
+	.string	"bar"
+	.section	.tdata
+	.align 8
+	.type	bar, @object
+	.size	bar, 8
+bar:
+	.quad	.LC2
--- /dev/null	2012-11-05 20:40:48.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/style2-with-badness.s	2012-11-05 20:40:48.758276203 -0500
@@ -0,0 +1,47 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */	
+
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"foo: %p\n"
+	.text
+.globl main
+	.type	main, @function
+main:
+.LFB0:
+	pushq	%rbp
+.LCFI0:
+	movq	%rsp, %rbp
+.LCFI1:
+	leaq	foo@GOTTPOFF(%rip), %rsi
+	addq	%fs:0, %rsi
+	movl	$.LC0, %edi
+	movl	$0, %eax
+	call	printf
+	movl	$0, %eax
+	leave
+	ret
+.LFE0:
+	.size	main, .-main
+.globl foo
+	.section	.rodata.str1.1
+.LC1:
+	.string	"foo"
+	.section	.tdata,"awT",@progbits
+	.align 8
+	.type	foo, @object
+	.size	foo, 8
+foo:
+	.quad	.LC1
--- /dev/null	2012-11-05 20:40:48.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/style2-with-r12.s	2012-11-05 20:40:48.947035848 -0500
@@ -0,0 +1,48 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */	
+
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"foo: %p\n"
+	.text
+.globl main
+	.type	main, @function
+main:
+.LFB0:
+	pushq	%rbp
+.LCFI0:
+	movq	%rsp, %rbp
+.LCFI1:
+	movq	foo@GOTTPOFF(%rip), %r12
+	addq	%fs:0, %r12
+        movq    %r12, %rsi
+	movl	$.LC0, %edi
+	movl	$0, %eax
+	call	printf
+	movl	$0, %eax
+	leave
+	ret
+.LFE0:
+	.size	main, .-main
+.globl foo
+	.section	.rodata.str1.1
+.LC1:
+	.string	"foo"
+	.section	.tdata,"awT",@progbits
+	.align 8
+	.type	foo, @object
+	.size	foo, 8
+foo:
+	.quad	.LC1
--- /dev/null	2012-11-05 20:40:49.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/style2-with-r13.s	2012-11-05 20:40:49.125411782 -0500
@@ -0,0 +1,48 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */	
+
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"foo: %p\n"
+	.text
+.globl main
+	.type	main, @function
+main:
+.LFB0:
+	pushq	%rbp
+.LCFI0:
+	movq	%rsp, %rbp
+.LCFI1:
+	movq	foo@GOTTPOFF(%rip), %r13
+	addq	%fs:0, %r13
+        movq    %r13, %rsi
+	movl	$.LC0, %edi
+	movl	$0, %eax
+	call	printf
+	movl	$0, %eax
+	leave
+	ret
+.LFE0:
+	.size	main, .-main
+.globl foo
+	.section	.rodata.str1.1
+.LC1:
+	.string	"foo"
+	.section	.tdata,"awT",@progbits
+	.align 8
+	.type	foo, @object
+	.size	foo, 8
+foo:
+	.quad	.LC1
--- /dev/null	2012-11-05 20:40:49.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/style2.s	2012-11-05 20:40:49.299024697 -0500
@@ -0,0 +1,47 @@
+/*
+ * This file and its contents are supplied under the terms of the
+ * Common Development and Distribution License ("CDDL"), version 1.0.
+ * You may only use this file in accordance with the terms of version
+ * 1.0 of the CDDL.
+ *
+ * A full copy of the text of the CDDL should have accompanied this
+ * source.  A copy of the CDDL is also available via the Internet at
+ * http://www.illumos.org/license/CDDL.
+ */
+
+/*
+ * Copyright 2012, Richard Lowe.
+ */	
+
+	.section	.rodata.str1.1,"aMS",@progbits,1
+.LC0:
+	.string	"foo: %p\n"
+	.text
+.globl main
+	.type	main, @function
+main:
+.LFB0:
+	pushq	%rbp
+.LCFI0:
+	movq	%rsp, %rbp
+.LCFI1:
+	movq	foo@GOTTPOFF(%rip), %rsi
+	addq	%fs:0, %rsi
+	movl	$.LC0, %edi
+	movl	$0, %eax
+	call	printf
+	movl	$0, %eax
+	leave
+	ret
+.LFE0:
+	.size	main, .-main
+.globl foo
+	.section	.rodata.str1.1
+.LC1:
+	.string	"foo"
+	.section	.tdata,"awT",@progbits
+	.align 8
+	.type	foo, @object
+	.size	foo, 8
+foo:
+	.quad	.LC1
--- /dev/null	2012-11-05 20:40:49.000000000 -0500
+++ new/usr/src/cmd/sgs/test/ld/x64/tls/ie/x64-ie-test.sh	2012-11-05 20:40:49.471572959 -0500
@@ -0,0 +1,62 @@
+#!/bin/ksh
+#
+# This file and its contents are supplied under the terms of the
+# Common Development and Distribution License ("CDDL"), version 1.0.
+# You may only use this file in accordance with the terms of version
+# 1.0 of the CDDL.
+#
+# A full copy of the text of the CDDL should have accompanied this
+# source.  A copy of the CDDL is also available via the Internet at
+# http://www.illumos.org/license/CDDL.
+#
+
+# Copyright 2012, Richard Lowe.
+
+function grep_test {
+    name=$1
+    pattern=$2
+
+    if /usr/xpg4/bin/fgrep -q "${pattern}"; then
+	print -u2 "pass: $name"
+    else
+        print -u2 "FAIL: $name"
+    fi
+}        
+
+function dis_test {
+    name=${1}
+    func=${2}
+    file=${3}
+    pattern=${4}
+
+    dis -F${func} ${file} | grep_test "${name}" "${pattern}"
+}
+
+make PROTO="${1}"
+
+dis_test "addq-->leaq 1" func style1 \
+    'func+0x10: 48 8d 92 f8 ff ff  leaq   -0x8(%rdx),%rdx'
+dis_test "addq-->leaq 2" func style1 \
+    'func+0x17: 48 8d b6 f0 ff ff  leaq   -0x10(%rsi),%rsi'
+
+dis_test "addq-->leaq w/REX 1" func style1-with-r13 \
+    'func+0x10: 48 8d 92 f8 ff ff  leaq   -0x8(%rdx),%rdx'
+dis_test "addq-->leaq w/REX 2" func style1-with-r13 \
+    'func+0x17: 4d 8d ad f0 ff ff  leaq   -0x10(%r13),%r13'
+
+dis_test "addq-->addq for SIB 1" func style1-with-r12 \
+    'func+0x10: 48 8d 92 f8 ff ff  leaq   -0x8(%rdx),%rdx'
+dis_test "addq-->addq for SIB 2" func style1-with-r12 \
+    'func+0x17: 49 81 c4 f0 ff ff  addq   $-0x10,%r12	<0xfffffffffffffff0>'
+
+dis_test "movq-->movq" main style2 \
+    'main+0x4:  48 c7 c6 f0 ff ff  movq   $-0x10,%rsi	<0xfffffffffffffff0>'
+
+dis_test "movq-->movq w/REX" main style2-with-r13 \
+    'main+0x4:  49 c7 c5 f0 ff ff  movq   $-0x10,%r13	<0xfffffffffffffff0>'
+
+dis_test "movq-->movq incase of SIB" main style2-with-r12 \
+    'main+0x4:  49 c7 c4 f0 ff ff  movq   $-0x10,%r12	<0xfffffffffffffff0>'
+
+make PROTO="${1}" fail 2>&1 | grep_test "bad insn sequence" \
+   'ld: fatal: relocation error: R_AMD64_TPOFF32: file style2-with-badness.o: symbol foo: section .text: offset 0x7, relocation against unknown TLS instruction sequence'
