Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 29 Mar 95 08:36:41 PST
From:      minshall@ipsilon.com (Greg Minshall)
To:        pace@prep.ai.mit.edu, hassey@dg-rtp.dg.com, paul@freefall.cdrom.com, bugs@FreeBSD.org, roland@albert.gnu.ai.mit.edu
Subject:   GDB and Intelx86 and 16-bit code disassembly
Message-ID:  <v0211010eab9ecab86d8e@[204.160.240.227]>

index | next in thread | raw e-mail

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 ();




home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?v0211010eab9ecab86d8e>