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>
