new file from bothner, fixes sparc cross-disassembly core dumps

This commit is contained in:
David D. Zuhn 1992-06-08 07:46:10 +00:00
parent ab37d4f663
commit 6ba70f641e
1 changed files with 87 additions and 67 deletions

View File

@ -24,6 +24,11 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include <stdio.h> #include <stdio.h>
#include "opcode/m68k.h" #include "opcode/m68k.h"
#ifndef GDB
#define fprintf_filtered fprintf
#define fputs_filtered fputs
#endif
/* Sign-extend an (unsigned char). */ /* Sign-extend an (unsigned char). */
#if __STDC__ == 1 #if __STDC__ == 1
#define COERCE_SIGNED_CHAR(ch) ((signed char)(ch)) #define COERCE_SIGNED_CHAR(ch) ((signed char)(ch))
@ -57,11 +62,24 @@ static int fetch_arg ();
#define NEXTLONG(p) \ #define NEXTLONG(p) \
(p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1]) (p += 4, (((((p[-4] << 8) + p[-3]) << 8) + p[-2]) << 8) + p[-1])
#define NEXTSINGLE(p) \ /* NEXTSINGLE and NEXTDOUBLE handle alignment problems, but not
(p += 4, *((float *)(p - 4))) * byte-swapping or other float format differences. FIXME! */
#define NEXTDOUBLE(p) \ union number {
(p += 8, *((double *)(p - 8))) double d;
float f;
char c[10];
};
#define NEXTSINGLE(val, p) \
{ int i; union number u;\
for (i = 0; i < sizeof(float); i++) u.c[i] = *p++; \
val = u.f; }
#define NEXTDOUBLE(val, p) \
{ int i; union number u;\
for (i = 0; i < sizeof(double); i++) u.c[i] = *p++; \
val = u.d; }
#define NEXTEXTEND(p) \ #define NEXTEXTEND(p) \
(p += 12, 0.0) /* Need a function to convert from extended to double (p += 12, 0.0) /* Need a function to convert from extended to double
@ -127,11 +145,11 @@ unsigned char *buffer;
/* Handle undefined instructions. */ /* Handle undefined instructions. */
if (best < 0) if (best < 0)
{ {
fprintf (stream, "0%o", (unsigned) (buffer[0] << 8) + buffer[1]); fprintf_filtered (stream, "0%o", (unsigned) (buffer[0] << 8) + buffer[1]);
return 2; return 2;
} }
fprintf (stream, "%s", m68k_opcodes[best].name); fprintf_filtered (stream, "%s", m68k_opcodes[best].name);
/* Point at first word of argument data, /* Point at first word of argument data,
and at descriptor for first argument. */ and at descriptor for first argument. */
@ -158,14 +176,14 @@ unsigned char *buffer;
d = m68k_opcodes[best].args; d = m68k_opcodes[best].args;
if (*d) if (*d)
fputs (" ", stream); fputs_filtered (" ", stream);
while (*d) while (*d)
{ {
p = print_insn_arg (d, buffer, p, addr + p - buffer, stream); p = print_insn_arg (d, buffer, p, addr + p - buffer, stream);
d += 2; d += 2;
if (*d && *(d - 2) != 'I' && *d != 'k') if (*d && *(d - 2) != 'I' && *d != 'k')
fputs (",", stream); fputs_filtered (",", stream);
} }
return p - buffer; return p - buffer;
} }
@ -189,15 +207,15 @@ print_insn_arg (d, buffer, p, addr, stream)
switch (*d) switch (*d)
{ {
case 'C': case 'C':
fprintf (stream, "ccr"); fprintf_filtered (stream, "ccr");
break; break;
case 'S': case 'S':
fprintf (stream, "sr"); fprintf_filtered (stream, "sr");
break; break;
case 'U': case 'U':
fprintf (stream, "usp"); fprintf_filtered (stream, "usp");
break; break;
case 'J': case 'J':
@ -211,79 +229,81 @@ print_insn_arg (d, buffer, p, addr, stream)
for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--) for (regno = sizeof names / sizeof names[0] - 1; regno >= 0; regno--)
if (names[regno].value == val) if (names[regno].value == val)
{ {
fprintf (stream, names[regno].name); fprintf_filtered (stream, names[regno].name);
break; break;
} }
if (regno < 0) if (regno < 0)
fprintf (stream, "%d", val); fprintf_filtered (stream, "%d", val);
} }
break; break;
case 'Q': case 'Q':
val = fetch_arg (buffer, place, 3); val = fetch_arg (buffer, place, 3);
if (val == 0) val = 8; /* 0 means 8, except for the bkpt instruction... */
fprintf (stream, "#%d", val); if (val == 0 && d[1] != 's')
val = 8;
fprintf_filtered (stream, "#%d", val);
break; break;
case 'M': case 'M':
val = fetch_arg (buffer, place, 8); val = fetch_arg (buffer, place, 8);
if (val & 0x80) if (val & 0x80)
val = val - 0x100; val = val - 0x100;
fprintf (stream, "#%d", val); fprintf_filtered (stream, "#%d", val);
break; break;
case 'T': case 'T':
val = fetch_arg (buffer, place, 4); val = fetch_arg (buffer, place, 4);
fprintf (stream, "#%d", val); fprintf_filtered (stream, "#%d", val);
break; break;
case 'D': case 'D':
fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 3)]); fprintf_filtered (stream, "%s", reg_names[fetch_arg (buffer, place, 3)]);
break; break;
case 'A': case 'A':
fprintf (stream, "%s", fprintf_filtered (stream, "%s",
reg_names[fetch_arg (buffer, place, 3) + 010]); reg_names[fetch_arg (buffer, place, 3) + 010]);
break; break;
case 'R': case 'R':
fprintf (stream, "%s", reg_names[fetch_arg (buffer, place, 4)]); fprintf_filtered (stream, "%s", reg_names[fetch_arg (buffer, place, 4)]);
break; break;
case 'F': case 'F':
fprintf (stream, "fp%d", fetch_arg (buffer, place, 3)); fprintf_filtered (stream, "fp%d", fetch_arg (buffer, place, 3));
break; break;
case 'O': case 'O':
val = fetch_arg (buffer, place, 6); val = fetch_arg (buffer, place, 6);
if (val & 0x20) if (val & 0x20)
fprintf (stream, "%s", reg_names [val & 7]); fprintf_filtered (stream, "%s", reg_names [val & 7]);
else else
fprintf (stream, "%d", val); fprintf_filtered (stream, "%d", val);
break; break;
case '+': case '+':
fprintf (stream, "%s@+", fprintf_filtered (stream, "%s@+",
reg_names[fetch_arg (buffer, place, 3) + 8]); reg_names[fetch_arg (buffer, place, 3) + 8]);
break; break;
case '-': case '-':
fprintf (stream, "%s@-", fprintf_filtered (stream, "%s@-",
reg_names[fetch_arg (buffer, place, 3) + 8]); reg_names[fetch_arg (buffer, place, 3) + 8]);
break; break;
case 'k': case 'k':
if (place == 'k') if (place == 'k')
fprintf (stream, "{%s}", reg_names[fetch_arg (buffer, place, 3)]); fprintf_filtered (stream, "{%s}", reg_names[fetch_arg (buffer, place, 3)]);
else if (place == 'C') else if (place == 'C')
{ {
val = fetch_arg (buffer, place, 7); val = fetch_arg (buffer, place, 7);
if ( val > 63 ) /* This is a signed constant. */ if ( val > 63 ) /* This is a signed constant. */
val -= 128; val -= 128;
fprintf (stream, "{#%d}", val); fprintf_filtered (stream, "{#%d}", val);
} }
else else
fprintf(stderr, "Invalid arg format in opcode table: \"%c%c\".", fprintf_filtered(stderr, "Invalid arg format in opcode table: \"%c%c\".",
*d, place); *d, place);
break; break;
@ -305,9 +325,9 @@ print_insn_arg (d, buffer, p, addr, stream)
else if (place == 'l') else if (place == 'l')
val = NEXTLONG (p1); val = NEXTLONG (p1);
else else
fprintf(stderr, "Invalid arg format in opcode table: \"%c%c\".", fprintf_filtered(stderr, "Invalid arg format in opcode table: \"%c%c\".",
*d, place); *d, place);
fprintf (stream, "#%d", val); fprintf_filtered (stream, "#%d", val);
break; break;
case 'B': case 'B':
@ -335,26 +355,26 @@ print_insn_arg (d, buffer, p, addr, stream)
val = NEXTWORD (p); val = NEXTWORD (p);
} }
else else
fprintf(stderr, "Invalid arg format in opcode table: \"%c%c\".", fprintf_filtered(stderr, "Invalid arg format in opcode table: \"%c%c\".",
*d, place); *d, place);
print_address (addr + val, stream); print_address (addr + val, stream);
break; break;
case 'd': case 'd':
val = NEXTWORD (p); val = NEXTWORD (p);
fprintf (stream, "%s@(%d)", fprintf_filtered (stream, "%s@(%d)",
reg_names[fetch_arg (buffer, place, 3)], val); reg_names[fetch_arg (buffer, place, 3)], val);
break; break;
case 's': case 's':
fprintf (stream, "%s", fprintf_filtered (stream, "%s",
fpcr_names[fetch_arg (buffer, place, 3)]); fpcr_names[fetch_arg (buffer, place, 3)]);
break; break;
case 'I': case 'I':
val = fetch_arg (buffer, 'd', 3); /* Get coprocessor ID... */ val = fetch_arg (buffer, 'd', 3); /* Get coprocessor ID... */
if (val != 1) /* Unusual coprocessor ID? */ if (val != 1) /* Unusual coprocessor ID? */
fprintf (stream, "(cpid=%d) ", val); fprintf_filtered (stream, "(cpid=%d) ", val);
if (place == 'i') if (place == 'i')
p += 2; /* Skip coprocessor extended operands */ p += 2; /* Skip coprocessor extended operands */
break; break;
@ -384,28 +404,28 @@ print_insn_arg (d, buffer, p, addr, stream)
switch (val >> 3) switch (val >> 3)
{ {
case 0: case 0:
fprintf (stream, "%s", reg_names[val]); fprintf_filtered (stream, "%s", reg_names[val]);
break; break;
case 1: case 1:
fprintf (stream, "%s", regname); fprintf_filtered (stream, "%s", regname);
break; break;
case 2: case 2:
fprintf (stream, "%s@", regname); fprintf_filtered (stream, "%s@", regname);
break; break;
case 3: case 3:
fprintf (stream, "%s@+", regname); fprintf_filtered (stream, "%s@+", regname);
break; break;
case 4: case 4:
fprintf (stream, "%s@-", regname); fprintf_filtered (stream, "%s@-", regname);
break; break;
case 5: case 5:
val = NEXTWORD (p); val = NEXTWORD (p);
fprintf (stream, "%s@(%d)", regname, val); fprintf_filtered (stream, "%s@(%d)", regname, val);
break; break;
case 6: case 6:
@ -417,13 +437,13 @@ print_insn_arg (d, buffer, p, addr, stream)
{ {
case 0: case 0:
val = NEXTWORD (p); val = NEXTWORD (p);
fprintf (stream, "@#"); fprintf_filtered (stream, "@#");
print_address (val, stream); print_address (val, stream);
break; break;
case 1: case 1:
val = NEXTLONG (p); val = NEXTLONG (p);
fprintf (stream, "@#"); fprintf_filtered (stream, "@#");
print_address (val, stream); print_address (val, stream);
break; break;
@ -456,11 +476,11 @@ print_insn_arg (d, buffer, p, addr, stream)
break; break;
case 'f': case 'f':
flval = NEXTSINGLE(p); NEXTSINGLE(flval, p);
break; break;
case 'F': case 'F':
flval = NEXTDOUBLE(p); NEXTDOUBLE(flval, p);
break; break;
case 'x': case 'x':
@ -472,17 +492,17 @@ print_insn_arg (d, buffer, p, addr, stream)
break; break;
default: default:
fprintf(stderr, "Invalid arg format in opcode table: \"%c%c\".", fprintf_filtered(stderr, "Invalid arg format in opcode table: \"%c%c\".",
*d, place); *d, place);
} }
if ( flt_p ) /* Print a float? */ if ( flt_p ) /* Print a float? */
fprintf (stream, "#%g", flval); fprintf_filtered (stream, "#%g", flval);
else else
fprintf (stream, "#%d", val); fprintf_filtered (stream, "#%d", val);
break; break;
default: default:
fprintf (stream, "<invalid address mode 0%o>", (unsigned) val); fprintf_filtered (stream, "<invalid address mode 0%o>", (unsigned) val);
} }
} }
break; break;
@ -499,7 +519,7 @@ print_insn_arg (d, buffer, p, addr, stream)
p = p1 > p ? p1 : p; p = p1 > p ? p1 : p;
if (val == 0) if (val == 0)
{ {
fputs ("#0", stream); fputs_filtered ("#0", stream);
break; break;
} }
if (*d == 'l') if (*d == 'l')
@ -517,14 +537,14 @@ print_insn_arg (d, buffer, p, addr, stream)
{ {
int first_regno; int first_regno;
if (doneany) if (doneany)
fputs ("/", stream); fputs_filtered ("/", stream);
doneany = 1; doneany = 1;
fprintf (stream, "%s", reg_names[regno]); fprintf_filtered (stream, "%s", reg_names[regno]);
first_regno = regno; first_regno = regno;
while (val & (1 << (regno + 1))) while (val & (1 << (regno + 1)))
++regno; ++regno;
if (regno > first_regno) if (regno > first_regno)
fprintf (stream, "-%s", reg_names[regno]); fprintf_filtered (stream, "-%s", reg_names[regno]);
} }
} }
else if (place == '3') else if (place == '3')
@ -534,7 +554,7 @@ print_insn_arg (d, buffer, p, addr, stream)
val = fetch_arg (buffer, place, 8); val = fetch_arg (buffer, place, 8);
if (val == 0) if (val == 0)
{ {
fputs ("#0", stream); fputs_filtered ("#0", stream);
break; break;
} }
if (*d == 'l') if (*d == 'l')
@ -552,22 +572,22 @@ print_insn_arg (d, buffer, p, addr, stream)
{ {
int first_regno; int first_regno;
if (doneany) if (doneany)
fputs ("/", stream); fputs_filtered ("/", stream);
doneany = 1; doneany = 1;
fprintf (stream, "fp%d", regno); fprintf_filtered (stream, "fp%d", regno);
first_regno = regno; first_regno = regno;
while (val & (1 << (regno + 1))) while (val & (1 << (regno + 1)))
++regno; ++regno;
if (regno > first_regno) if (regno > first_regno)
fprintf (stream, "-fp%d", regno); fprintf_filtered (stream, "-fp%d", regno);
} }
} }
else else
abort (); goto de_fault;
break; break;
default: default: de_fault:
fprintf(stderr, "Invalid arg format in opcode table: \"%c\".", *d); fprintf_filtered(stderr, "Invalid arg format in opcode table: \"%c\".", *d);
} }
return (unsigned char *) p; return (unsigned char *) p;
@ -708,7 +728,7 @@ bfd_vma addr;
((word & 0x80) ? word | 0xff00 : word & 0xff) ((word & 0x80) ? word | 0xff00 : word & 0xff)
+ ((basereg == -1) ? addr : 0), + ((basereg == -1) ? addr : 0),
stream); stream);
fputs (buf, stream); fputs_filtered (buf, stream);
return p; return p;
} }
@ -736,7 +756,7 @@ bfd_vma addr;
if ((word & 7) == 0) if ((word & 7) == 0)
{ {
print_base (basereg, base_disp, stream); print_base (basereg, base_disp, stream);
fputs (buf, stream); fputs_filtered (buf, stream);
return p; return p;
} }
@ -752,15 +772,15 @@ bfd_vma addr;
outer_disp = NEXTLONG (p); outer_disp = NEXTLONG (p);
} }
fprintf (stream, "%d(", outer_disp); fprintf_filtered (stream, "%d(", outer_disp);
print_base (basereg, base_disp, stream); print_base (basereg, base_disp, stream);
/* If postindexed, print the closeparen before the index. */ /* If postindexed, print the closeparen before the index. */
if (word & 4) if (word & 4)
fprintf (stream, ")%s", buf); fprintf_filtered (stream, ")%s", buf);
/* If preindexed, print the closeparen after the index. */ /* If preindexed, print the closeparen after the index. */
else else
fprintf (stream, "%s)", buf); fprintf_filtered (stream, "%s)", buf);
return p; return p;
} }
@ -775,9 +795,9 @@ print_base (regno, disp, stream)
FILE *stream; FILE *stream;
{ {
if (regno == -2) if (regno == -2)
fprintf (stream, "%d", disp); fprintf_filtered (stream, "%d", disp);
else if (regno == -1) else if (regno == -1)
fprintf (stream, "0x%x", (unsigned) disp); fprintf_filtered (stream, "0x%x", (unsigned) disp);
else else
fprintf (stream, "%d(%s)", disp, reg_names[regno]); fprintf_filtered (stream, "%d(%s)", disp, reg_names[regno]);
} }