More misc improvements
diff --git a/syscall_exit_regs.c b/syscall_exit_regs.c
index 4c7f97e..337dbf5 100644
--- a/syscall_exit_regs.c
+++ b/syscall_exit_regs.c
@@ -1,19 +1,29 @@
 #include <stdio.h>
+#include <asm/prctl.h>
 
 int main()
 {
 	extern const char syscall_rip[];
 	unsigned long rcx = 1;
 	unsigned long orig_rcx = rcx;
-	asm ("mov $-1, %%eax\n\t"
+	unsigned short orig_ss, ss;
+
+#ifdef __x86_64__
+	arch_prctl(ARCH_SET_GS, 500);  // Enable segment 13
+	asm volatile ("mov %0,%%ss" : : "r" ((13 << 3) | 3));
+#endif
+
+	asm ("mov %%ss,%[orig_ss]\n\t"
+	     "mov $0x80000000, %%eax\n\t"
 	     "syscall\n\t"
 	     "syscall_rip:"
-	     : "+c" (rcx) : :
+	     "mov %%ss,%[ss]\n\t"
+	     : "+c" (rcx), [orig_ss] "=rm" (orig_ss), [ss] "=rm" (ss) : :
 #ifdef __x86_64__
 	       "r11"
 #endif
 	     );
-	printf("syscall: RCX = %lX  RIP = %lX  orig RCX = %lx\n",
-	       rcx, (unsigned long)syscall_rip, orig_rcx);
+	printf("syscall: RCX = %lX  RIP = %lX  orig RCX = %lx  ss = %hx  orig_ss = %hx\n",
+	       rcx, (unsigned long)syscall_rip, orig_rcx, ss, orig_ss);
 	return 0;
 }
diff --git a/user_visible_state.c b/user_visible_state.c
index bf289e5..4616ca4 100644
--- a/user_visible_state.c
+++ b/user_visible_state.c
@@ -1,6 +1,10 @@
 #include <stdio.h>
 #include <stdint.h>
 #include <xmmintrin.h>
+#include <asm/prctl.h>
+#include <sys/prctl.h>
+
+extern int arch_prctl(int, unsigned long);
 
 /* returns GDT limit */
 static uint16_t show_gdt_and_idt(void)
@@ -61,6 +65,17 @@
 	printf("RDTSCP: cpu %d\n", cpu);
 }
 
+static const char *user_seg_types[] = {
+	"RO data",
+	"RW data",
+	"RO data, exp-down",
+	"RW data, exp-down",
+	"XO code",
+	"XR code",
+	"XO code, conforming",
+	"XR code, confirming",
+};
+
 static void show_segment(uint16_t index)
 {
 	uint32_t has_limit = 0, has_ar = 0, limit, ar;
@@ -80,18 +95,21 @@
 	if (!has_limit && !has_ar)
 		return;
 
-	printf("GDT entry %02hu", index);
+	printf("GDT entry %02hu: ", index);
 
 	if (has_limit)
-		printf(" limit: 0x%08X", limit);
+		printf(" limit = 0x%08X", limit);
 
 	if (has_ar) {
 #define ARBITS(low, high) ((ar >> low) & ((1 << (high - low + 1)) - 1))
 #define ARSTR(bit, str) (ARBITS(bit,bit) ? " " str : "")
-		printf(" access rights: 0x%08X (type=%d DPL=%d%s%s%s%s%s%s)",
-		       ar, ARBITS(8,11), ARBITS(13,14),
+		printf(" access rights = 0x%08X\n"
+		       "               type=%x (%s%s) DPL=%d%s%s%s%s%s%s",
+		       ar, ARBITS(8,11), user_seg_types[ARBITS(9,11)],
+		       (ARBITS(8,8) ? ", accessed" : ""),
+		       ARBITS(13,14),
 		       ARSTR(12, "S"), ARSTR(15, "P"),
-		       ARSTR(20, "software-available"),
+		       ARSTR(20, "AVL"),  /* AVL is reserved for the OS */
 		       ARSTR(21, "L"), ARSTR(22, "D/B"), ARSTR(23, "G"));
 #undef ARSTR
 #undef ARBITS
@@ -102,6 +120,9 @@
 
 int main()
 {
+	// Optional: gives some visibility into how TLS works.
+	arch_prctl(ARCH_SET_GS, 500);
+
 	uint16_t gdtlimit = show_gdt_and_idt();
 	show_ldt();
 	show_tr();