diff --git a/config-x86-common.mak b/config-x86-common.mak
index 2269c4a..367c0be 100644
--- a/config-x86-common.mak
+++ b/config-x86-common.mak
@@ -11,7 +11,7 @@ cflatobjs += \
 cflatobjs += lib/x86/fwcfg.o
 cflatobjs += lib/x86/apic.o
 cflatobjs += lib/x86/atomic.o
-cflatobjs += lib/x86/idt.o
+cflatobjs += lib/x86/desc.o
 
 $(libcflat): LDFLAGS += -nostdlib
 $(libcflat): CFLAGS += -ffreestanding -I lib
diff --git a/lib/x86/desc.c b/lib/x86/desc.c
new file mode 100644
index 0000000..25a25bc
--- /dev/null
+++ b/lib/x86/desc.c
@@ -0,0 +1,159 @@
+#include "libcflat.h"
+#include "desc.h"
+#include "processor.h"
+
+typedef struct {
+    unsigned short offset0;
+    unsigned short selector;
+    unsigned short ist : 3;
+    unsigned short : 5;
+    unsigned short type : 4;
+    unsigned short : 1;
+    unsigned short dpl : 2;
+    unsigned short p : 1;
+    unsigned short offset1;
+#ifdef __x86_64__
+    unsigned offset2;
+    unsigned reserved;
+#endif
+} idt_entry_t;
+
+static idt_entry_t idt[256];
+
+void load_lidt(idt_entry_t *idt, int nentries)
+{
+    struct descriptor_table_ptr dt;
+
+    dt.limit = nentries * sizeof(*idt) - 1;
+    dt.base = (unsigned long)idt;
+    lidt(&dt);
+    asm volatile ("lidt %0" : : "m"(dt));
+}
+
+void set_idt_entry(int vec, void *addr, int dpl)
+{
+    idt_entry_t *e = &idt[vec];
+    memset(e, 0, sizeof *e);
+    e->offset0 = (unsigned long)addr;
+    e->selector = read_cs();
+    e->ist = 0;
+    e->type = 14;
+    e->dpl = dpl;
+    e->p = 1;
+    e->offset1 = (unsigned long)addr >> 16;
+#ifdef __x86_64__
+    e->offset2 = (unsigned long)addr >> 32;
+#endif
+}
+
+struct ex_regs {
+    unsigned long rax, rcx, rdx, rbx;
+    unsigned long dummy, rbp, rsi, rdi;
+#ifdef __x86_64__
+    unsigned long r8, r9, r10, r11;
+    unsigned long r12, r13, r14, r15;
+#endif
+    unsigned long vector;
+    unsigned long error_code;
+    unsigned long rip;
+    unsigned long cs;
+    unsigned long rflags;
+};
+
+struct ex_record {
+    unsigned long rip;
+    unsigned long handler;
+};
+
+extern struct ex_record exception_table_start, exception_table_end;
+
+void do_handle_exception(struct ex_regs *regs)
+{
+    struct ex_record *ex;
+    unsigned ex_val;
+
+    ex_val = regs->vector | (regs->error_code << 16);
+
+    asm("mov %0, %%gs:4" : : "r"(ex_val));
+
+    for (ex = &exception_table_start; ex != &exception_table_end; ++ex) {
+        if (ex->rip == regs->rip) {
+            regs->rip = ex->handler;
+            return;
+        }
+    }
+    printf("unhandled excecption\n");
+    exit(7);
+}
+
+#ifdef __x86_64__
+#  define R "r"
+#  define W "q"
+#  define S "8"
+#else
+#  define R "e"
+#  define W "l"
+#  define S "4"
+#endif
+
+asm (".pushsection .text \n\t"
+     "ud_fault: \n\t"
+     "push"W" $0 \n\t"
+     "push"W" $6 \n\t"
+     "jmp handle_exception \n\t"
+
+     "gp_fault: \n\t"
+     "push"W" $13 \n\t"
+     "jmp handle_exception \n\t"
+
+     "de_fault: \n\t"
+     "push"W" $0 \n\t"
+     "push"W" $0 \n\t"
+     "jmp handle_exception \n\t"
+
+     "handle_exception: \n\t"
+#ifdef __x86_64__
+     "push %r15; push %r14; push %r13; push %r12 \n\t"
+     "push %r11; push %r10; push %r9; push %r8 \n\t"
+#endif
+     "push %"R"di; push %"R"si; push %"R"bp; sub $"S", %"R"sp \n\t"
+     "push %"R"bx; push %"R"dx; push %"R"cx; push %"R"ax \n\t"
+     "mov %"R"sp, %"R"di \n\t"
+     "call do_handle_exception \n\t"
+     "pop %"R"ax; pop %"R"cx; pop %"R"dx; pop %"R"bx \n\t"
+     "add $"S", %"R"sp; pop %"R"bp; pop %"R"si; pop %"R"di \n\t"
+#ifdef __x86_64__
+     "pop %r8; pop %r9; pop %r10; pop %r11 \n\t"
+     "pop %r12; pop %r13; pop %r14; pop %r15 \n\t"
+#endif
+     "add $"S", %"R"sp \n\t"
+     "add $"S", %"R"sp \n\t"
+     "iret"W" \n\t"
+     ".popsection");
+
+
+void setup_idt(void)
+{
+    extern char ud_fault, gp_fault, de_fault;
+
+    load_lidt(idt, 256);
+    set_idt_entry(0, &de_fault, 0);
+    set_idt_entry(6, &ud_fault, 0);
+    set_idt_entry(13, &gp_fault, 0);
+}
+
+unsigned exception_vector(void)
+{
+    unsigned short vector;
+
+    asm("mov %%gs:4, %0" : "=rm"(vector));
+    return vector;
+}
+
+unsigned exception_error_code(void)
+{
+    unsigned short error_code;
+
+    asm("mov %%gs:6, %0" : "=rm"(error_code));
+    return error_code;
+}
diff --git a/lib/x86/desc.h b/lib/x86/desc.h
new file mode 100644
index 0000000..81b8944
--- /dev/null
+++ b/lib/x86/desc.h
@@ -0,0 +1,20 @@
+#ifndef __IDT_TEST__
+#define __IDT_TEST__
+
+void setup_idt(void);
+
+#define ASM_TRY(catch)                                  \
+    "movl $0, %%gs:4 \n\t"                              \
+    ".pushsection .data.ex \n\t"                        \
+    ".quad 1111f, " catch "\n\t"                        \
+    ".popsection \n\t"                                  \
+    "1111:"
+
+#define UD_VECTOR   6
+#define GP_VECTOR   13
+
+unsigned exception_vector(void);
+unsigned exception_error_code(void);
+void set_idt_entry(int vec, void *addr, int dpl);
+
+#endif
diff --git a/lib/x86/idt.c b/lib/x86/idt.c
deleted file mode 100644
index b3e47d4..0000000
--- a/lib/x86/idt.c
+++ /dev/null
@@ -1,159 +0,0 @@
-#include "idt.h"
-#include "libcflat.h"
-#include "processor.h"
-
-typedef struct {
-    unsigned short offset0;
-    unsigned short selector;
-    unsigned short ist : 3;
-    unsigned short : 5;
-    unsigned short type : 4;
-    unsigned short : 1;
-    unsigned short dpl : 2;
-    unsigned short p : 1;
-    unsigned short offset1;
-#ifdef __x86_64__
-    unsigned offset2;
-    unsigned reserved;
-#endif
-} idt_entry_t;
-
-static idt_entry_t idt[256];
-
-void load_lidt(idt_entry_t *idt, int nentries)
-{
-    struct descriptor_table_ptr dt;
-
-    dt.limit = nentries * sizeof(*idt) - 1;
-    dt.base = (unsigned long)idt;
-    lidt(&dt);
-    asm volatile ("lidt %0" : : "m"(dt));
-}
-
-void set_idt_entry(int vec, void *addr, int dpl)
-{
-    idt_entry_t *e = &idt[vec];
-    memset(e, 0, sizeof *e);
-    e->offset0 = (unsigned long)addr;
-    e->selector = read_cs();
-    e->ist = 0;
-    e->type = 14;
-    e->dpl = dpl;
-    e->p = 1;
-    e->offset1 = (unsigned long)addr >> 16;
-#ifdef __x86_64__
-    e->offset2 = (unsigned long)addr >> 32;
-#endif
-}
-
-struct ex_regs {
-    unsigned long rax, rcx, rdx, rbx;
-    unsigned long dummy, rbp, rsi, rdi;
-#ifdef __x86_64__
-    unsigned long r8, r9, r10, r11;
-    unsigned long r12, r13, r14, r15;
-#endif
-    unsigned long vector;
-    unsigned long error_code;
-    unsigned long rip;
-    unsigned long cs;
-    unsigned long rflags;
-};
-
-struct ex_record {
-    unsigned long rip;
-    unsigned long handler;
-};
-
-extern struct ex_record exception_table_start, exception_table_end;
-
-void do_handle_exception(struct ex_regs *regs)
-{
-    struct ex_record *ex;
-    unsigned ex_val;
-
-    ex_val = regs->vector | (regs->error_code << 16);
-
-    asm("mov %0, %%gs:4" : : "r"(ex_val));
-
-    for (ex = &exception_table_start; ex != &exception_table_end; ++ex) {
-        if (ex->rip == regs->rip) {
-            regs->rip = ex->handler;
-            return;
-        }
-    }
-    printf("unhandled excecption\n");
-    exit(7);
-}
-
-#ifdef __x86_64__
-#  define R "r"
-#  define W "q"
-#  define S "8"
-#else
-#  define R "e"
-#  define W "l"
-#  define S "4"
-#endif
-
-asm (".pushsection .text \n\t"
-     "ud_fault: \n\t"
-     "push"W" $0 \n\t"
-     "push"W" $6 \n\t"
-     "jmp handle_exception \n\t"
-
-     "gp_fault: \n\t"
-     "push"W" $13 \n\t"
-     "jmp handle_exception \n\t"
-
-     "de_fault: \n\t"
-     "push"W" $0 \n\t"
-     "push"W" $0 \n\t"
-     "jmp handle_exception \n\t"
-
-     "handle_exception: \n\t"
-#ifdef __x86_64__
-     "push %r15; push %r14; push %r13; push %r12 \n\t"
-     "push %r11; push %r10; push %r9; push %r8 \n\t"
-#endif
-     "push %"R"di; push %"R"si; push %"R"bp; sub $"S", %"R"sp \n\t"
-     "push %"R"bx; push %"R"dx; push %"R"cx; push %"R"ax \n\t"
-     "mov %"R"sp, %"R"di \n\t"
-     "call do_handle_exception \n\t"
-     "pop %"R"ax; pop %"R"cx; pop %"R"dx; pop %"R"bx \n\t"
-     "add $"S", %"R"sp; pop %"R"bp; pop %"R"si; pop %"R"di \n\t"
-#ifdef __x86_64__
-     "pop %r8; pop %r9; pop %r10; pop %r11 \n\t"
-     "pop %r12; pop %r13; pop %r14; pop %r15 \n\t"
-#endif
-     "add $"S", %"R"sp \n\t"
-     "add $"S", %"R"sp \n\t"
-     "iret"W" \n\t"
-     ".popsection");
-
-
-void setup_idt(void)
-{
-    extern char ud_fault, gp_fault, de_fault;
-
-    load_lidt(idt, 256);
-    set_idt_entry(0, &de_fault, 0);
-    set_idt_entry(6, &ud_fault, 0);
-    set_idt_entry(13, &gp_fault, 0);
-}
-
-unsigned exception_vector(void)
-{
-    unsigned short vector;
-
-    asm("mov %%gs:4, %0" : "=rm"(vector));
-    return vector;
-}
-
-unsigned exception_error_code(void)
-{
-    unsigned short error_code;
-
-    asm("mov %%gs:6, %0" : "=rm"(error_code));
-    return error_code;
-}
diff --git a/lib/x86/idt.h b/lib/x86/idt.h
deleted file mode 100644
index 81b8944..0000000
--- a/lib/x86/idt.h
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef __IDT_TEST__
-#define __IDT_TEST__
-
-void setup_idt(void);
-
-#define ASM_TRY(catch)                                  \
-    "movl $0, %%gs:4 \n\t"                              \
-    ".pushsection .data.ex \n\t"                        \
-    ".quad 1111f, " catch "\n\t"                        \
-    ".popsection \n\t"                                  \
-    "1111:"
-
-#define UD_VECTOR   6
-#define GP_VECTOR   13
-
-unsigned exception_vector(void);
-unsigned exception_error_code(void);
-void set_idt_entry(int vec, void *addr, int dpl);
-
-#endif
diff --git a/x86/access.c b/x86/access.c
index df943d9..120682d 100644
--- a/x86/access.c
+++ b/x86/access.c
@@ -1,6 +1,6 @@
 
 #include "libcflat.h"
-#include "idt.h"
+#include "desc.h"
 #include "processor.h"
 
 #define smp_id() 0
diff --git a/x86/apic.c b/x86/apic.c
index bcb9fc1..4f05b02 100644
--- a/x86/apic.c
+++ b/x86/apic.c
@@ -2,7 +2,7 @@
 #include "apic.h"
 #include "vm.h"
 #include "smp.h"
-#include "idt.h"
+#include "desc.h"
 
 typedef struct {
     ulong regs[sizeof(ulong)*2];
diff --git a/x86/emulator.c b/x86/emulator.c
index 845e7a0..0486d38 100644
--- a/x86/emulator.c
+++ b/x86/emulator.c
@@ -1,7 +1,7 @@
 #include "ioram.h"
 #include "vm.h"
 #include "libcflat.h"
-#include "idt.h"
+#include "desc.h"
 
 #define memset __builtin_memset
 #define TESTDEV_IO_PORT 0xe0
diff --git a/x86/idt_test.c b/x86/idt_test.c
index 59256d4..2d2e0c2 100644
--- a/x86/idt_test.c
+++ b/x86/idt_test.c
@@ -1,5 +1,5 @@
 #include "libcflat.h"
-#include "idt.h"
+#include "desc.h"
 
 int test_ud2(void)
 {
diff --git a/x86/xsave.c b/x86/xsave.c
index a22b44c..057b0ff 100644
--- a/x86/xsave.c
+++ b/x86/xsave.c
@@ -1,5 +1,5 @@
 #include "libcflat.h"
-#include "idt.h"
+#include "desc.h"
 
 #ifdef __x86_64__
 #define uint64_t unsigned long
