From owner-freebsd-bugs Wed Mar 29 08:38:19 1995 Return-Path: bugs-owner Received: (from majordom@localhost) by freefall.cdrom.com (8.6.10/8.6.6) id IAA19801 for bugs-outgoing; Wed, 29 Mar 1995 08:38:19 -0800 Received: from nic1.barrnet.net (NIC1.BARRNET.NET [131.119.245.5]) by freefall.cdrom.com (8.6.10/8.6.6) with ESMTP id IAA19795; Wed, 29 Mar 1995 08:38:17 -0800 Received: from ipsilon.com by nic1.barrnet.net (8.6.10/BARRNET-RELAY.1) id IAA19187; Wed, 29 Mar 1995 08:38:04 -0800 Received: from [204.160.240.227] (green.ipsilon.COM) by ipsilon.com (4.1/SMI-4.1MDV1.0) id AA08398; Wed, 29 Mar 95 08:36:42 PST Date: Wed, 29 Mar 95 08:36:41 PST X-Sender: minshall@servo.ipsilon.com Message-Id: Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" To: pace@prep.ai.mit.edu, hassey@dg-rtp.dg.com, paul@freefall.cdrom.com, bugs@FreeBSD.org, roland@albert.gnu.ai.mit.edu From: minshall@ipsilon.com (Greg Minshall) Subject: GDB and Intelx86 and 16-bit code disassembly Sender: bugs-owner@FreeBSD.org Precedence: bulk Hi. I've been beating my head on some bug with boot blocks on the disk on my FreeBSD 2.0 system (it boots from NCR adapters, but hangs when i install BusLogic adapters -- any ideas?). As part of this, i've been using GDB to disassemble the 16-bit code that is found in these boot blocks. As the doc says, it doesn't actually work on 16-bit code. So, i hacked on it a bit. Below are changes that seemed to do as much 16-bit as *I* needed, but i didn't do an exhaustive search. I.e., i think these changes make things *much* better than current code, but i'm sure there are other things that will need to be changed to fully support 16-bit code. (If i had spent the time to understand GDB's command structures, i would have added commands like "set x86-16-bit-code" and "set x86-32-bit-code"...) Hope this is understandable. If anyone would like a different form of "diff" output, let me know. Greg Minshall ---- =================================================================== RCS file: RCS/i386-dis.c,v retrieving revision 1.1 diff -c -r1.1 i386-dis.c *** 1.1 1995/03/25 23:08:18 --- i386-dis.c 1995/03/26 03:11:27 *************** *** 702,707 **** --- 702,710 ---- static char *names_seg[] = { "%es","%cs","%ss","%ds","%fs","%gs","%?","%?", }; + static char *names_ea16bit[] = { + "%bx,%si","%bx,%di","%bp,%si","%bp,%di","%si","%di","%bp","%bx" + }; struct dis386 grps[][8] = { /* GRP1b */ *************** *** 949,954 **** --- 952,961 ---- } } + /* Initialization values - suitable for tweaking (0 --> 16 bit mode) */ + static int Dflag = 1; + static int Aflag = 1; + static int dflag; static int aflag; *************** *** 1025,1032 **** } /* these would be initialized to 0 if disassembling for 8086 or 286 */ ! dflag = 1; ! aflag = 1; if (prefixes & PREFIX_DATA) dflag ^= 1; --- 1032,1039 ---- } /* these would be initialized to 0 if disassembling for 8086 or 286 */ ! dflag = Dflag; ! aflag = Aflag; if (prefixes & PREFIX_DATA) dflag ^= 1; *************** *** 1034,1040 **** if (prefixes & PREFIX_ADR) { aflag ^= 1; ! oappend ("addr16 "); } if (*codep == 0x0f) --- 1041,1051 ---- if (prefixes & PREFIX_ADR) { aflag ^= 1; ! if (Aflag) { ! oappend ("addr16 "); ! } else { ! oappend("addr32 "); ! } } if (*codep == 0x0f) *************** *** 1532,1538 **** } append_prefix (); ! if (rm == 4) { havesib = 1; havebase = 1; --- 1543,1549 ---- } append_prefix (); ! if (dflag && (rm == 4)) /* In 32-bit mode, rm 4 ==> SIB byte */ { havesib = 1; havebase = 1; *************** *** 1546,1581 **** switch (mod) { case 0: ! switch (rm) ! { ! case 4: ! /* implies havesib and havebase */ ! if (base == 5) { ! havebase = 0; ! disp = get32 (); ! } ! break; ! case 5: ! disp = get32 (); ! break; ! default: ! havebase = 1; ! base = rm; ! break; ! } break; case 1: FETCH_DATA (the_info, codep + 1); disp = *(char *)codep++; ! if (rm != 4) { havebase = 1; base = rm; } break; case 2: ! disp = get32 (); ! if (rm != 4) { havebase = 1; base = rm; --- 1557,1590 ---- switch (mod) { case 0: ! if ((rm == 4) && dflag && (base == 5)) { ! /* implies havesib and havebase */ ! havebase = 0; /* mod 0 and SIB base 5 ==> disp32, no base */ ! disp = get32 (); ! } else if ((rm == 5) && dflag) { ! disp = get32 (); /* disp32 */ ! } else if ((rm == 6) && !dflag) { ! disp = get16 (); /* disp16 */ ! } else { ! havebase = 1; ! base = rm; ! } break; case 1: FETCH_DATA (the_info, codep + 1); disp = *(char *)codep++; ! if ((dflag == 0) || (rm != 4)) { havebase = 1; base = rm; } break; case 2: ! if (dflag) ! disp = get32 (); ! else ! disp = get16 (); ! if ((dflag == 0) || (rm != 4)) { havebase = 1; base = rm; *************** *** 1583,1589 **** break; } ! if (mod != 0 || rm == 5 || (havesib && base == 5)) { sprintf (scratchbuf, "0x%x", disp); oappend (scratchbuf); --- 1592,1601 ---- break; } ! if (mod != 0 || ! (dflag && (rm == 5)) || /* 32-bit mode ==> mod 0, rm 5 */ ! (!dflag && (rm == 6)) || /* 32-bit mode ==> mod 0, rm 6 */ ! (havesib && base == 5)) { sprintf (scratchbuf, "0x%x", disp); oappend (scratchbuf); *************** *** 1592,1599 **** if (havebase || havesib) { oappend ("("); ! if (havebase) ! oappend (names32[base]); if (havesib) { if (index != 4) --- 1604,1615 ---- if (havebase || havesib) { oappend ("("); ! if (havebase) { ! if (dflag) ! oappend (names32[base]); ! else ! oappend (names_ea16bit[base]); ! } if (havesib) { if (index != 4) *************** *** 1823,1829 **** switch (size) { case lptr: ! if (aflag) { offset = get32 (); seg = get16 (); --- 1839,1845 ---- switch (size) { case lptr: ! if (dflag) /* depending on operand size (not address) */ { offset = get32 (); seg = get16 ();