desc.c v0.62

From: Chuck Ebbert (76306.1226@compuserve.com)
Date: Wed Apr 30 2003 - 09:32:30 EST


#define PROG_NAME "desc"
#define PROG_TITLE "dump i386 CPU descriptor tables"
#define VERSION "0.62"
/* v0.62 : almost all TSS fields, all Pentium segtypes */
#define AUTHOR "Chuck Ebbert <76306.1226@compuserve.com>"
#define COPYRIGHT "Copyright (c) 2003 Chuck Ebbert"
#define LICENSE "Released under the GPL"

#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>

typedef struct { /* from Linux */
        unsigned short back_link,__blh;
        unsigned long esp0;
        unsigned short ss0,__ss0h;
        unsigned long esp1;
        unsigned short ss1,__ss1h;
        unsigned long esp2;
        unsigned short ss2,__ss2h;
        unsigned long __cr3;
        unsigned long eip;
        unsigned long eflags;
        unsigned long eax,ecx,edx,ebx;
        unsigned long esp;
        unsigned long ebp;
        unsigned long esi;
        unsigned long edi;
        unsigned short es, __esh;
        unsigned short cs, __csh;
        unsigned short ss, __ssh;
        unsigned short ds, __dsh;
        unsigned short fs, __fsh;
        unsigned short gs, __gsh;
        unsigned short ldt, __ldth;
        unsigned short trace, bitmap;
} __attribute__ ((packed)) tss_t;

typedef struct {
        unsigned short limit;
        unsigned int base;
} __attribute__ ((packed)) dtr_t;

typedef struct {
        unsigned short off1;
        unsigned short sel;
        unsigned char none,flags;
        unsigned short off2;
} __attribute__ ((packed)) gate_desc_t;

typedef struct {
        unsigned a,b;
} __attribute__ ((packed)) desc_t;

/* read/write from kmem */
#define BUILD_IO_FN(fn_name, fn_fn) \
        static int fn_name (int fd, int offset, void *buf, int size) { \
                if (lseek(fd, offset, 0) != offset) return 0; \
                if (fn_fn(fd, buf, size) != size) return 0; \
                return size; \
        }
BUILD_IO_FN(rkm, read)
BUILD_IO_FN(wkm, write)

#define perr(err) { perror(err), exit(1); }
/* read/write wrapper with err handling */
#define xkm(f, p1, p2, p3, p4, msg) { \
        int _p4 = (p4); if ((f)((p1), (p2), (p3), _p4) != _p4) perr(msg); }
#define TEST_BIT(v,b) ( !!((v) & (1 << (b))) )
#define nl printf("\n")

int kmem;

void dump_sel (char *nm, unsigned short s) {
        printf("%s:%04x <%s#%02d,RPL%d>",
               nm, s, (s & 4) ? "LDT" : "GDT", s >> 3, s & 3);
}
void dump_table (char * name, unsigned base, unsigned num) {
        unsigned cdt, db, dl, a, b, t, i, f;
        desc_t desc;
        gate_desc_t *gate = (gate_desc_t *)&desc; /* FIXME */
        tss_t tss;

        printf(" %s at %08x, %d entries:\n\n", name, base, num);
        for (i = 0; i < num; i++) {
                xkm(rkm, kmem, base + 8*i, &desc, sizeof(desc), "rkm gdtldt");
                a = desc.a, b = desc.b, f = (b & 0xf0ff00) >> 8, t = f & 0x1f;
                if (!a & !b) continue; /* empty */
                if ((t & 0x04) == 0x04) { /* gate */
                        f = gate->flags, t = f & 0x1f;
                        printf("%s#%3d: ", name, i);
                        dump_sel("sel", gate->sel);
                        printf(" off:%08x flags:%02x <%s,DPL%d,%s Gate>\n",
                               (unsigned)((gate->off2 << 16) | gate->off1),
                               f, TEST_BIT(f,7) ? "P" : "N", (f & 0x60) >> 5,
                               (t == 0x05) ? "Task" :
                                                (t == 0x0c) ? "32b,Call" :
                                                (t == 0x0e) ? "32b,Intr" :
                                                (t == 0x0f) ? "32b,Trap" :
                                                (t == 0x04) ? "16b,Call" :
                                                (t == 0x06) ? "16b,Intr" :
                                                (t == 0x07) ? "16b,Trap" :
                                                "Unknown");
                        continue;
                }
                cdt = f & 0x401e; /* code/data type, base, limit */
                dl = (a & 0xffff) | (b & 0x0f0000);
                db = (b & 0xff000000) | ((b & 0xff) << 16) | (a >> 16);
                printf("%s#%3d: base:%08x limit:%05x%s"
                       " flags:%04x <%s,DPL%d,%s>\n",
                       name, i, db, dl, TEST_BIT(b,23) ? "fff" : " ",
                       f, TEST_BIT(b,15) ? "P" : "N", (b & 0x6000) >> 13,
                       (t == 0x01) ? "16b,Avail TSS" :
                                        (t == 0x02) ? "LDT" :
                                        (t == 0x03) ? "16b,Busy TSS" :
                                        (t == 0x09) ? "32b,Avail TSS" :
                                        (t == 0x0b) ? "32b,Busy TSS" :
                                        (cdt == 0x0010) ? "16b,RO Data" :
                                        (cdt == 0x0012) ? "16b,RW Data" :
                                        (cdt == 0x0014) ? "16b,RO Expd Data" :
                                        (cdt == 0x0016) ? "16b,RW Expd Data" :
                                        (cdt == 0x0018) ? "16b,XO Code" :
                                        (cdt == 0x001a) ? "16b,RX Code" :
                                        (cdt == 0x001c) ? "16b,XO Conf Code" :
                                        (cdt == 0x001e) ? "16b,RX Conf Code" :
                                        (cdt == 0x4010) ? "32b,RO Data" :
                                        (cdt == 0x4012) ? "32b,RW Data" :
                                        (cdt == 0x4014) ? "32b,RO Expd Data" :
                                        (cdt == 0x4016) ? "32b,RW Expd Data" :
                                        (cdt == 0x4018) ? "32b,XO Code" :
                                        (cdt == 0x401a) ? "32b,RX Code" :
                                        (cdt == 0x401c) ? "32b,XO Conf Code" :
                                        (cdt == 0x401e) ? "32b,RX Conf Code" :
                                        "Unknown");
                if (t == 0x02)
                        nl, dump_table(" LDT", db, (dl + 1) >> 3);
                if ((t == 0x09) | (t == 0x0b)) {
                        xkm(rkm, kmem, db, &tss, sizeof(tss), "rkm tss");
                        printf("\n TSS at %08x, %d bytes:\n\n", db, dl + 1);
                        dump_sel(" CS", tss.cs);
                        printf(" EIP:%08x eflags:%08x\n",
                               tss.eip, tss.eflags);
                        dump_sel(" SS0", tss.ss0);
                        printf(" ESP0:%08x\n", tss.esp0);
                        dump_sel(" SS1", tss.ss1);
                        printf(" ESP1:%08x\n", tss.esp1);
                        dump_sel(" SS2", tss.ss2);
                        printf(" ESP2:%08x\n", tss.esp2);
                        dump_sel(" SS", tss.ss);
                        printf(" ESP:%08x\n", tss.esp);
                        dump_sel(" DS", tss.ds);
                        dump_sel(" ES", tss.es), nl;
                        dump_sel(" FS", tss.fs);
                        dump_sel(" GS", tss.gs), nl;
                        printf(" EAX:%08x EBX:%08x ECX:%08x EDX:%08x\n",
                               tss.eax, tss.ebx, tss.ecx, tss.edx);
                        printf(" ESI:%08x EDI:%08x EBP:%08x\n",
                               tss.esi, tss.edi, tss.ebp);
                        dump_sel(" LDT", tss.ldt);
                        printf(" CR3:%08x\n\n", tss.__cr3);
                }
        }
        nl;
}
main() {
        dtr_t dtr;

        printf(PROG_NAME " v" VERSION " -- " PROG_TITLE "\n\n");
        kmem = open("/dev/kmem", O_RDONLY);
        if (kmem < 0) perr("open /dev/kmem");

        asm("sgdt %0" : "=m" (dtr));
        dump_table("GDT", dtr.base, (dtr.limit + 1) >> 3);
        asm("sidt %0" : "=m" (dtr));
        dump_table("IDT", dtr.base, (dtr.limit + 1) >> 3);

        close(kmem);
}
------
 Chuck
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed Apr 30 2003 - 22:00:35 EST