Hopefully do a better job disassembling code in 16 bit mode.
authorMatthew Dillon <dillon@dragonflybsd.org>
Sat, 8 Nov 2003 03:06:53 +0000 (03:06 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Sat, 8 Nov 2003 03:06:53 +0000 (03:06 +0000)
sys/cpu/i386/misc/db_disasm.c
sys/ddb/db_examine.c
sys/ddb/db_print.c
sys/ddb/db_run.c
sys/ddb/db_trap.c
sys/ddb/ddb.h
sys/i386/i386/db_disasm.c
sys/platform/pc32/i386/db_disasm.c

index aa03b9e..ae84126 100644 (file)
@@ -24,7 +24,7 @@
  * rights to redistribute these changes.
  *
  * $FreeBSD: src/sys/i386/i386/db_disasm.c,v 1.23.2.1 2001/07/29 22:48:37 kris Exp $
- * $DragonFly: src/sys/cpu/i386/misc/db_disasm.c,v 1.3 2003/08/26 21:42:18 rob Exp $
+ * $DragonFly: src/sys/cpu/i386/misc/db_disasm.c,v 1.4 2003/11/08 03:06:52 dillon Exp $
  */
 
 /*
@@ -821,6 +821,7 @@ struct i_addr {
        const char *    base;
        const char *    index;
        int             ss;
+       int             defss;  /* default stack segment */
 };
 
 static const char * const db_index_reg_16[8] = {
@@ -892,10 +893,27 @@ db_read_address(loc, short_addr, regmodrm, addrp)
        }
        addrp->is_reg = FALSE;
        addrp->index = 0;
+       addrp->ss = 0;
+       addrp->defss = 0;
 
        if (short_addr) {
-           addrp->index = 0;
-           addrp->ss = 0;
+           if (mod != 3) {
+               switch(rm) {
+               case 0:
+               case 1:
+                   addrp->index = "%bx";
+                   break;
+               case 2:
+               case 3:
+                   addrp->index = "%bp";
+                   addrp->defss = 1;
+                   break;
+               case 6:
+                   if (mod == 1 || mod == 2)
+                       addrp->defss = 1;
+                   break;
+               }
+           }
            switch (mod) {
                case 0:
                    if (rm == 6) {
@@ -920,8 +938,7 @@ db_read_address(loc, short_addr, regmodrm, addrp)
                    addrp->base = db_index_reg_16[rm];
                    break;
            }
-       }
-       else {
+       } else {
            if (mod != 3 && rm == 4) {
                get_value_inc(sib, loc, 1, FALSE);
                rm = sib_base(sib);
@@ -972,6 +989,8 @@ db_print_address(seg, size, addrp)
 
        if (seg) {
            db_printf("%s:", seg);
+       } else if (addrp->defss) {
+           db_printf("%%ss:");
        }
 
        db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY);
@@ -1082,13 +1101,14 @@ db_disasm_esc(loc, inst, short_addr, size, seg)
 
 /*
  * Disassemble instruction at 'loc'.  'altfmt' specifies an
- * (optional) alternate format.  Return address of start of
- * next instruction.
+ * (optional) alternate format.  Return the address of the
+ * start of the next instruction.
+ *
+ * If regs is non-null it may be used to obtain context, such as
+ * whether we are in word or long mode.
  */
 db_addr_t
-db_disasm(loc, altfmt)
-       db_addr_t       loc;
-       boolean_t       altfmt;
+db_disasm(db_addr_t loc, boolean_t altfmt, db_regs_t *regs)
 {
        int     inst;
        int     size;
@@ -1108,10 +1128,16 @@ db_disasm(loc, altfmt)
        struct i_addr   address;
 
        get_value_inc(inst, loc, 1, FALSE);
-       short_addr = FALSE;
-       size = LONG;
        seg = 0;
 
+       if (regs && gdt[mycpu->gd_cpuid * NGDT + IDXSEL(regs->tf_cs & 0xFFFF)].sd.sd_def32 == 0) {
+               size = WORD;
+               short_addr = TRUE;
+       } else {
+               size = LONG;
+               short_addr = FALSE;
+       }
+
        /*
         * Get prefixes
         */
index 9cc6628..98f1669 100644 (file)
@@ -24,7 +24,7 @@
  * rights to redistribute these changes.
  *
  * $FreeBSD: src/sys/ddb/db_examine.c,v 1.27 1999/08/28 00:41:07 peter Exp $
- * $DragonFly: src/sys/ddb/db_examine.c,v 1.4 2003/08/27 10:47:13 rob Exp $
+ * $DragonFly: src/sys/ddb/db_examine.c,v 1.5 2003/11/08 03:06:53 dillon Exp $
  */
 
 /*
@@ -171,10 +171,10 @@ db_examine(addr, fmt, count)
                                }
                                break;
                            case 'i':   /* instruction */
-                               addr = db_disasm(addr, FALSE);
+                               addr = db_disasm(addr, FALSE, NULL);
                                break;
                            case 'I':   /* instruction, alternate form */
-                               addr = db_disasm(addr, TRUE);
+                               addr = db_disasm(addr, TRUE, NULL);
                                break;
                            default:
                                break;
@@ -240,12 +240,11 @@ db_print_cmd(addr, have_addr, count, modif)
 }
 
 void
-db_print_loc_and_inst(loc)
-       db_addr_t       loc;
+db_print_loc_and_inst(db_addr_t        loc, db_regs_t *regs)
 {
        db_printsym(loc, DB_STGY_PROC);
        db_printf(":\t");
-       (void) db_disasm(loc, TRUE);
+       (void) db_disasm(loc, TRUE, regs);
 }
 
 /*
index e0fbc30..3379b5d 100644 (file)
@@ -24,7 +24,7 @@
  * rights to redistribute these changes.
  *
  * $FreeBSD: src/sys/ddb/db_print.c,v 1.26 1999/08/28 00:41:09 peter Exp $
- * $DragonFly: src/sys/ddb/db_print.c,v 1.3 2003/07/26 14:18:51 rob Exp $
+ * $DragonFly: src/sys/ddb/db_print.c,v 1.4 2003/11/08 03:06:53 dillon Exp $
  */
 
 /*
@@ -64,5 +64,5 @@ db_show_regs(dummy1, dummy2, dummy3, dummy4)
            }
            db_printf("\n");
        }
-       db_print_loc_and_inst(PC_REGS(DDB_REGS));
+       db_print_loc_and_inst(PC_REGS(DDB_REGS), DDB_REGS);
 }
index afc8dcf..caafb15 100644 (file)
@@ -24,7 +24,7 @@
  * rights to redistribute these changes.
  *
  * $FreeBSD: src/sys/ddb/db_run.c,v 1.18 1999/08/28 00:41:10 peter Exp $
- * $DragonFly: src/sys/ddb/db_run.c,v 1.4 2003/08/27 10:47:13 rob Exp $
+ * $DragonFly: src/sys/ddb/db_run.c,v 1.5 2003/11/08 03:06:53 dillon Exp $
  */
 
 /*
@@ -123,7 +123,7 @@ db_stop_at_pc(is_breakpoint)
            if (--db_loop_count > 0) {
                if (db_sstep_print) {
                    db_printf("\t\t");
-                   db_print_loc_and_inst(pc);
+                   db_print_loc_and_inst(pc, DDB_REGS);
                    db_printf("\n");
                }
                return (FALSE); /* continue */
@@ -143,7 +143,7 @@ db_stop_at_pc(is_breakpoint)
                        db_printf("[after %6d]     ", db_inst_count);
                        for (i = db_call_depth; --i > 0; )
                            db_printf("  ");
-                       db_print_loc_and_inst(pc);
+                       db_print_loc_and_inst(pc, DDB_REGS);
                        db_printf("\n");
                    }
                }
index c2fc20b..89bf00a 100644 (file)
@@ -24,7 +24,7 @@
  * rights to redistribute these changes.
  *
  * $FreeBSD: src/sys/ddb/db_trap.c,v 1.14 1999/08/28 00:41:11 peter Exp $
- * $DragonFly: src/sys/ddb/db_trap.c,v 1.2 2003/06/17 04:28:20 dillon Exp $
+ * $DragonFly: src/sys/ddb/db_trap.c,v 1.3 2003/11/08 03:06:53 dillon Exp $
  */
 
 /*
@@ -67,7 +67,7 @@ db_trap(type, code)
                db_printf("Stopped at\t");
            db_dot = PC_REGS(DDB_REGS);
            if (setjmp(db_jmpbuf) == 0)
-               db_print_loc_and_inst(db_dot);
+               db_print_loc_and_inst(db_dot, DDB_REGS);
 
            db_command_loop();
        }
index e1fff9b..da2fd10 100644 (file)
@@ -28,7 +28,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/ddb/ddb.h,v 1.24.2.2 2002/08/30 22:27:49 gibbs Exp $
- * $DragonFly: src/sys/ddb/ddb.h,v 1.5 2003/08/27 10:47:13 rob Exp $
+ * $DragonFly: src/sys/ddb/ddb.h,v 1.6 2003/11/08 03:06:53 dillon Exp $
  */
 
 /*
@@ -83,7 +83,7 @@ struct vm_map;
 
 void           db_check_interrupt (void);
 void           db_clear_watchpoints (void);
-db_addr_t      db_disasm (db_addr_t loc, boolean_t altfmt);
+db_addr_t      db_disasm (db_addr_t loc, boolean_t altfmt, db_regs_t *regs);
                                /* instruction disassembler */
 void           db_error (char *s);
 int            db_expression (db_expr_t *valuep);
@@ -92,7 +92,7 @@ void          db_iprintf (const char *,...) __printflike(1, 2);
 struct vm_map  *db_map_addr (vm_offset_t);
 boolean_t      db_map_current (struct vm_map *);
 boolean_t      db_map_equal (struct vm_map *, struct vm_map *);
-void           db_print_loc_and_inst (db_addr_t loc);
+void           db_print_loc_and_inst (db_addr_t loc, db_regs_t *regs);
 void           db_printf (const char *fmt, ...) __printflike(1, 2);
 void           db_read_bytes (vm_offset_t addr, size_t size, char *data);
                                /* machine-dependent */
index 3ad35c2..9882fd1 100644 (file)
@@ -24,7 +24,7 @@
  * rights to redistribute these changes.
  *
  * $FreeBSD: src/sys/i386/i386/db_disasm.c,v 1.23.2.1 2001/07/29 22:48:37 kris Exp $
- * $DragonFly: src/sys/i386/i386/Attic/db_disasm.c,v 1.3 2003/08/26 21:42:18 rob Exp $
+ * $DragonFly: src/sys/i386/i386/Attic/db_disasm.c,v 1.4 2003/11/08 03:06:52 dillon Exp $
  */
 
 /*
@@ -821,6 +821,7 @@ struct i_addr {
        const char *    base;
        const char *    index;
        int             ss;
+       int             defss;  /* default stack segment */
 };
 
 static const char * const db_index_reg_16[8] = {
@@ -892,10 +893,27 @@ db_read_address(loc, short_addr, regmodrm, addrp)
        }
        addrp->is_reg = FALSE;
        addrp->index = 0;
+       addrp->ss = 0;
+       addrp->defss = 0;
 
        if (short_addr) {
-           addrp->index = 0;
-           addrp->ss = 0;
+           if (mod != 3) {
+               switch(rm) {
+               case 0:
+               case 1:
+                   addrp->index = "%bx";
+                   break;
+               case 2:
+               case 3:
+                   addrp->index = "%bp";
+                   addrp->defss = 1;
+                   break;
+               case 6:
+                   if (mod == 1 || mod == 2)
+                       addrp->defss = 1;
+                   break;
+               }
+           }
            switch (mod) {
                case 0:
                    if (rm == 6) {
@@ -920,8 +938,7 @@ db_read_address(loc, short_addr, regmodrm, addrp)
                    addrp->base = db_index_reg_16[rm];
                    break;
            }
-       }
-       else {
+       } else {
            if (mod != 3 && rm == 4) {
                get_value_inc(sib, loc, 1, FALSE);
                rm = sib_base(sib);
@@ -972,6 +989,8 @@ db_print_address(seg, size, addrp)
 
        if (seg) {
            db_printf("%s:", seg);
+       } else if (addrp->defss) {
+           db_printf("%%ss:");
        }
 
        db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY);
@@ -1082,13 +1101,14 @@ db_disasm_esc(loc, inst, short_addr, size, seg)
 
 /*
  * Disassemble instruction at 'loc'.  'altfmt' specifies an
- * (optional) alternate format.  Return address of start of
- * next instruction.
+ * (optional) alternate format.  Return the address of the
+ * start of the next instruction.
+ *
+ * If regs is non-null it may be used to obtain context, such as
+ * whether we are in word or long mode.
  */
 db_addr_t
-db_disasm(loc, altfmt)
-       db_addr_t       loc;
-       boolean_t       altfmt;
+db_disasm(db_addr_t loc, boolean_t altfmt, db_regs_t *regs)
 {
        int     inst;
        int     size;
@@ -1108,10 +1128,16 @@ db_disasm(loc, altfmt)
        struct i_addr   address;
 
        get_value_inc(inst, loc, 1, FALSE);
-       short_addr = FALSE;
-       size = LONG;
        seg = 0;
 
+       if (regs && gdt[mycpu->gd_cpuid * NGDT + IDXSEL(regs->tf_cs & 0xFFFF)].sd.sd_def32 == 0) {
+               size = WORD;
+               short_addr = TRUE;
+       } else {
+               size = LONG;
+               short_addr = FALSE;
+       }
+
        /*
         * Get prefixes
         */
index 4c26139..67ce65e 100644 (file)
@@ -24,7 +24,7 @@
  * rights to redistribute these changes.
  *
  * $FreeBSD: src/sys/i386/i386/db_disasm.c,v 1.23.2.1 2001/07/29 22:48:37 kris Exp $
- * $DragonFly: src/sys/platform/pc32/i386/Attic/db_disasm.c,v 1.3 2003/08/26 21:42:18 rob Exp $
+ * $DragonFly: src/sys/platform/pc32/i386/Attic/db_disasm.c,v 1.4 2003/11/08 03:06:52 dillon Exp $
  */
 
 /*
@@ -821,6 +821,7 @@ struct i_addr {
        const char *    base;
        const char *    index;
        int             ss;
+       int             defss;  /* default stack segment */
 };
 
 static const char * const db_index_reg_16[8] = {
@@ -892,10 +893,27 @@ db_read_address(loc, short_addr, regmodrm, addrp)
        }
        addrp->is_reg = FALSE;
        addrp->index = 0;
+       addrp->ss = 0;
+       addrp->defss = 0;
 
        if (short_addr) {
-           addrp->index = 0;
-           addrp->ss = 0;
+           if (mod != 3) {
+               switch(rm) {
+               case 0:
+               case 1:
+                   addrp->index = "%bx";
+                   break;
+               case 2:
+               case 3:
+                   addrp->index = "%bp";
+                   addrp->defss = 1;
+                   break;
+               case 6:
+                   if (mod == 1 || mod == 2)
+                       addrp->defss = 1;
+                   break;
+               }
+           }
            switch (mod) {
                case 0:
                    if (rm == 6) {
@@ -920,8 +938,7 @@ db_read_address(loc, short_addr, regmodrm, addrp)
                    addrp->base = db_index_reg_16[rm];
                    break;
            }
-       }
-       else {
+       } else {
            if (mod != 3 && rm == 4) {
                get_value_inc(sib, loc, 1, FALSE);
                rm = sib_base(sib);
@@ -972,6 +989,8 @@ db_print_address(seg, size, addrp)
 
        if (seg) {
            db_printf("%s:", seg);
+       } else if (addrp->defss) {
+           db_printf("%%ss:");
        }
 
        db_printsym((db_addr_t)addrp->disp, DB_STGY_ANY);
@@ -1082,13 +1101,14 @@ db_disasm_esc(loc, inst, short_addr, size, seg)
 
 /*
  * Disassemble instruction at 'loc'.  'altfmt' specifies an
- * (optional) alternate format.  Return address of start of
- * next instruction.
+ * (optional) alternate format.  Return the address of the
+ * start of the next instruction.
+ *
+ * If regs is non-null it may be used to obtain context, such as
+ * whether we are in word or long mode.
  */
 db_addr_t
-db_disasm(loc, altfmt)
-       db_addr_t       loc;
-       boolean_t       altfmt;
+db_disasm(db_addr_t loc, boolean_t altfmt, db_regs_t *regs)
 {
        int     inst;
        int     size;
@@ -1108,10 +1128,16 @@ db_disasm(loc, altfmt)
        struct i_addr   address;
 
        get_value_inc(inst, loc, 1, FALSE);
-       short_addr = FALSE;
-       size = LONG;
        seg = 0;
 
+       if (regs && gdt[mycpu->gd_cpuid * NGDT + IDXSEL(regs->tf_cs & 0xFFFF)].sd.sd_def32 == 0) {
+               size = WORD;
+               short_addr = TRUE;
+       } else {
+               size = LONG;
+               short_addr = FALSE;
+       }
+
        /*
         * Get prefixes
         */