diff options
author | Andy Lutomirski <luto@amacapital.net> | 2014-11-23 13:59:35 -0800 |
---|---|---|
committer | Andy Lutomirski <luto@amacapital.net> | 2014-11-23 13:59:35 -0800 |
commit | 92ab0e82faa75814f28f2a184a8fa6f3b6f5158a (patch) | |
tree | cc1fbc2e7401c5ff0f16547a5fe6b3b6bc476d8c | |
parent | 5655bd41ffedc002af69e3a8d1b0a168c22f2549 (diff) | |
download | misc-tests-92ab0e82faa75814f28f2a184a8fa6f3b6f5158a.tar.gz |
user_visible_state: Add LDT decoding (useless without other changes)
-rw-r--r-- | user_visible_state.c | 20 |
1 files changed, 13 insertions, 7 deletions
diff --git a/user_visible_state.c b/user_visible_state.c index d878e1a..0d61de6 100644 --- a/user_visible_state.c +++ b/user_visible_state.c @@ -7,6 +7,7 @@ #include <xmmintrin.h> #include <asm/prctl.h> #include <sys/prctl.h> +#include <asm/ldt.h> extern int arch_prctl(int, unsigned long); @@ -174,26 +175,28 @@ static const char *user_seg_types[] = { "XR code, confirming", }; -static void show_segment(uint16_t index) +static void show_segment(uint16_t index, int ldt) { uint32_t has_limit = 0, has_ar = 0, limit, ar; - asm ("lsl %[index], %[limit]\n\t" + uint32_t selector = (index << 3) | (ldt << 2) | 3; + + asm ("lsl %[selector], %[limit]\n\t" "jnz 1f\n\t" "mov $1, %[has_limit]\n\t" "1:" : [limit] "=r" (limit), [has_limit] "+rm" (has_limit) - : [index] "r" ((index << 3) + 3)); - asm ("larl %[index], %[ar]\n\t" + : [selector] "r" (selector)); + asm ("larl %[selector], %[ar]\n\t" "jnz 1f\n\t" "mov $1, %[has_ar]\n\t" "1:" : [ar] "=r" (ar), [has_ar] "+rm" (has_ar) - : [index] "r" ((index << 3) + 3)); + : [selector] "r" (selector)); if (!has_limit && !has_ar) return; - printf("GDT entry %02hu: ", index); + printf("%s entry %02hu: ", (ldt ? "LDT" : "GDT"), index); if (has_limit) printf(" limit = 0x%08X", limit); @@ -221,6 +224,7 @@ int main() // Optional: gives some visibility into how TLS works. arch_prctl(ARCH_SET_GS, 500); + set_ldt(); uint16_t gdtlimit = show_gdt_and_idt(); show_ldt(); show_tr(); @@ -228,5 +232,7 @@ int main() show_flags(); show_rdtscp(); for (int i = 0; i <= gdtlimit; i++) - show_segment(i); + show_segment(i, 0); + for (int i = 0; i < 10; i++) + show_segment(i, 1); } |