diff options
author | Andy Lutomirski <luto@amacapital.net> | 2014-07-05 09:22:55 -0700 |
---|---|---|
committer | Andy Lutomirski <luto@amacapital.net> | 2014-07-05 09:22:55 -0700 |
commit | d9a083999ddfff824e2ddc4ae20e4ec24b0682bc (patch) | |
tree | a64e57fa9ac0b5a421048861bcf3f33535040de0 | |
parent | eab1732d0553cffad95f31181183eee069227548 (diff) | |
download | misc-tests-d9a083999ddfff824e2ddc4ae20e4ec24b0682bc.tar.gz |
More misc improvements
-rw-r--r-- | syscall_exit_regs.c | 18 | ||||
-rw-r--r-- | user_visible_state.c | 31 |
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(); |