| #include <stdio.h> |
| #include <stdint.h> |
| #include <xmmintrin.h> |
| |
| /* returns GDT limit */ |
| static uint16_t show_gdt_and_idt(void) |
| { |
| struct { |
| unsigned short limit; |
| unsigned long base; |
| } __attribute__((packed)) val; |
| |
| uint16_t ret; |
| |
| __asm__ ("sgdt %0" : "=m" (val)); |
| printf("GDT: base = 0x%016lX limit = 0x%04hX\n", val.base, val.limit); |
| |
| ret = val.limit; |
| |
| __asm__ ("sidt %0" : "=m" (val)); |
| printf("IDT: base = 0x%016lX limit = 0x%04hX\n", val.base, val.limit); |
| |
| return ret; |
| } |
| |
| static void show_ldt(void) |
| { |
| unsigned short ldt; |
| asm ("sldt %0" : "=rm" (ldt)); |
| printf("LDT: 0x%04hX\n", ldt); |
| } |
| |
| static void show_tr(void) |
| { |
| unsigned short tr; |
| asm ("str %0" : "=rm" (tr)); |
| printf("TR: 0x%04X\n", tr); |
| } |
| |
| static void show_msw(void) |
| { |
| unsigned short msw; |
| asm ("smsww %0" : "=rm" (msw)); |
| printf("MSW: 0x%04X\n", msw); |
| } |
| |
| static void show_flags(void) |
| { |
| unsigned long flags; |
| asm ("sub $128, %%sp\n\t" |
| "pushf\n\t" |
| "pop %0\n\t" |
| "add $128, %%sp" : "=r" (flags)); |
| printf("FLAGS: 0x%016lX\n", flags); |
| } |
| |
| static void show_rdtscp(void) |
| { |
| unsigned int cpu; |
| __builtin_ia32_rdtscp(&cpu); |
| printf("RDTSCP: cpu %d\n", cpu); |
| } |
| |
| static void show_segment(uint16_t index) |
| { |
| uint32_t has_limit = 0, has_ar = 0, limit, ar; |
| asm ("lsl %[index], %[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" |
| "jnz 1f\n\t" |
| "mov $1, %[has_ar]\n\t" |
| "1:" |
| : [ar] "=r" (ar), [has_ar] "+rm" (has_ar) |
| : [index] "r" ((index << 3) + 3)); |
| |
| if (!has_limit && !has_ar) |
| return; |
| |
| printf("GDT entry %02hu", index); |
| |
| if (has_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), |
| ARSTR(12, "S"), ARSTR(15, "P"), |
| ARSTR(20, "software-available"), |
| ARSTR(21, "L"), ARSTR(22, "D/B"), ARSTR(23, "G")); |
| #undef ARSTR |
| #undef ARBITS |
| } |
| |
| printf("\n"); |
| } |
| |
| int main() |
| { |
| uint16_t gdtlimit = show_gdt_and_idt(); |
| show_ldt(); |
| show_tr(); |
| show_msw(); |
| show_flags(); |
| show_rdtscp(); |
| for (int i = 0; i <= gdtlimit; i++) |
| show_segment(i); |
| } |