blob: bf289e5a5eea4d8b1d2b66f902269e281535993f [file] [log] [blame]
#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);
}