summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Lutomirski <luto@amacapital.net>2014-07-05 09:22:55 -0700
committerAndy Lutomirski <luto@amacapital.net>2014-07-05 09:22:55 -0700
commitd9a083999ddfff824e2ddc4ae20e4ec24b0682bc (patch)
treea64e57fa9ac0b5a421048861bcf3f33535040de0
parenteab1732d0553cffad95f31181183eee069227548 (diff)
downloadmisc-tests-d9a083999ddfff824e2ddc4ae20e4ec24b0682bc.tar.gz
More misc improvements
-rw-r--r--syscall_exit_regs.c18
-rw-r--r--user_visible_state.c31
2 files changed, 40 insertions, 9 deletions
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 @@ static void show_rdtscp(void)
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 @@ static void show_segment(uint16_t index)
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 @@ static void show_segment(uint16_t index)
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();