#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>
#include <unistd.h>
#include "MacsBug.h"
Gdb_Cmd_Class macsbug_class;
Gdb_Cmd_Class macsbug_internal_class;
Gdb_Cmd_Class macsbug_screen_class;
Gdb_Cmd_Class macsbug_testing_class;
Gdb_Cmd_Class macsbug_useful_class;
static int find_size = 0;
static char *findName;
static Gdb_Plugin gdb_continue_command = NULL;
static void ra(char *arg, int from_tty);
static void brc(char *arg, int from_tty)
{
if (arg && *arg)
gdb_execute_command("clear %s", arg);
else
gdb_execute_command("delete");
gdb_set_int("$__lastcmd__", 1);
}
#define BRC_HELP \
"BRC [addr] -- Clear all breakpoints or one breakpoint at addr.\n" \
"See also gdb's DELETE command (clears breakpoints by number), and DISABLE."
static void brd(char *arg, int from_tty)
{
if (arg && *arg)
gdb_execute_command("info breakpoints %s", arg);
else
gdb_execute_command("info breakpoints");
gdb_set_int("$__lastcmd__", 2);
}
#define BRD_HELP "BRD -- Show all breakpoints (or breakpoint n)."
static void brm(char *arg, int from_tty)
{
if (!arg || !*arg)
gdb_error("usage: BRM regex (regex expected)");
gdb_execute_command("rbreak %s", arg);
gdb_set_int("$__lastcmd__", 38);
}
#define BRM_HELP \
"BRM regex -- Set breakpoints at all functions matching regular expression.\n" \
"This sets unconditional breakpoints on all matches, printing a list of all\n" \
"breakpoints set. This command is equivalent to a gdb RBREAK command."
static void brp(char *arg, int from_tty)
{
if (!arg || !*arg)
gdb_error("usage: BRP [gdb-spec [expr]]");
gdb_execute_command("br %s", arg);
gdb_set_int("$__lastcmd__", 33);
}
#define BRP_HELP \
"BRP [gdb-spec [expr]] -- Break at gdb-spec (under specified condition).\n" \
"This implements the gdb \"BREAK gdb-spec [if condition]\". See gdb BREAK\n" \
"documentation for further details.\n" \
"\n" \
"Macsbug features not supported: Interation count.\n" \
" No semicolon before the command.\n" \
" Command is not enclosed in quotes.\n" \
" Only a single command is allowed."
static void back_up_over_prompt(GDB_ADDRESS addr, int branchTaken, int from_tty)
{
if (!macsbug_screen && isatty(STDOUT_FILENO)) {
gdb_eval("$__accessible__=*(char*)0x%llx", (long long)addr);
if (from_tty)
gdb_printf(CURSOR_UP CLEAR_LINE, 2 + (branchTaken != 0));
}
}
static void db_dw_dl_dll(char *arg, int from_tty, int size, int cmdNbr)
{
unsigned char b;
unsigned short w;
unsigned long l;
unsigned long long ll;
GDB_ADDRESS addr;
char line[20], addrStr[20];
__is_running("The program is not running.", 0);
if (arg && *arg) {
addr = gdb_get_address(arg);
gdb_set_address("$dot", addr);
} else if (gdb_get_int("$__lastcmd__") == cmdNbr) {
addr = gdb_get_address("$dot") + size;
back_up_over_prompt(addr, 0, from_tty);
gdb_set_address("$dot", addr);
} else
addr = gdb_get_address("$dot");
sprintf(addrStr, "0x%llX", (long long)addr);
switch (size) {
case 1:
gdb_read_memory(&b, addrStr, 1);
gdb_printf("Byte at %.8llX = 0x%.2X %uu %d ", (long long)addr, b, b, (char)b);
sprintf(line, "0x%X", b);
__print_1(line, from_tty);
gdb_puts("\n");
break;
case 2:
gdb_read_memory(&w, addrStr, 2);
gdb_printf("Two bytes at %.8llX = 0x%.4X %uu %d ", (long long)addr, w, w, (short)w);
sprintf(line, "0x%X", w);
__print_2(line, from_tty);
gdb_puts("\n");
break;
case 4:
gdb_read_memory(&l, addrStr, 4);
gdb_printf("Four bytes at %.8llX = 0x%.8lX %uul %dl ", (long long)addr, l, l, (long)l);
sprintf(line, "0x%lX", l);
__print_4(line, from_tty);
gdb_puts("\n");
break;
case 8:
gdb_read_memory(&ll, addrStr, 8);
gdb_printf("Eight bytes at %.8llX = 0x%.16llX %lluull %lldll ", (long long)addr, ll, ll,
(long long)ll);
sprintf(line, "0x%llX", ll);
__print_8(line, from_tty);
gdb_puts("\n");
break;
}
gdb_set_int("$__lastcmd__", cmdNbr);
}
static void db(char *arg, int from_tty)
{
db_dw_dl_dll(arg, from_tty, 1, 3);
}
#define DB_HELP "DB addr -- Display in hex the byte at addr (or $dot)."
static void dl(char *arg, int from_tty)
{
db_dw_dl_dll(arg, from_tty, 4, 4);
}
#define DL_HELP "DL [addr] -- Display in hex the 4 bytes at addr (or $dot)."
static void dll(char *arg, int from_tty)
{
db_dw_dl_dll(arg, from_tty, 8, 49);
}
#define DLL_HELP "DLL [addr] -- Display in hex the 8 bytes at addr (or $dot)."
static void dm(char *arg, int from_tty)
{
int argc, n, i;
unsigned char b;
unsigned short w;
unsigned long l;
unsigned long long ll;
GDB_ADDRESS addr;
char *basicType, *argv[5], addrStr[20], buf[20], line[1024], tmpCmdLine[1024];
struct {
short top;
short left;
short bottom;
short right;
} rect;
static char *basic_types[] = {
"Byte", "Word", "Long", "LongLong",
"SignedByte", "SignedWord", "SignedLong", "SignedLongLong",
"UnsignedByte", "UnsignedWord", "UnsignedLong", "UnsignedLongLong",
"PString", "CString",
"Boolean",
"Binary8", "Binary16", "Binary32", "Binary64",
"OSType", "Rect",
"Text", "Pointer", "Handle",
"IORefNum", "VRefNum", "Seconds", "ATrapWord",
"AbsTicks", "TickInterval", "RgnHandle", "IOTrapWord",
"Version", "RGBColor", "Fixed", "ShortFixed", "UnsignedFixed",
"Fract", "Region",
NULL
};
__is_running("The program is not running.", 0);
gdb_setup_argv(safe_strcpy(tmpCmdLine, arg), "DM", &argc, argv, 4);
if (argc == 1) {
if (gdb_get_int("$__lastcmd__") == 5) {
addr = gdb_get_address("$dot") + gdb_get_int("$__prev_dm_n__");
back_up_over_prompt(addr, 0, from_tty);
gdb_set_address("$dot", addr);
} else {
gdb_printf("Displaying memory from %.8llX\n", (long long)gdb_get_address("$dot"));
gdb_set_int("$__prev_dm_n__", hexdump_width);
}
__hexdump("$dot $__prev_dm_n__", from_tty);
gdb_set_int("$__lastcmd__", 5);
return;
}
addr = gdb_get_address(argv[1]);
if (argc == 2) {
gdb_set_address("$dot", addr);
gdb_set_int("$__prev_dm_n__", hexdump_width);
gdb_printf("Displaying memory from %.8llX\n", (long long)addr);
__hexdump("$dot", from_tty);
gdb_set_int("$__lastcmd__", 5);
return;
}
if (argc > 3)
gdb_error("usage: DM [addr [n | basicType]] (wrong number of arguments)");
if (isdigit(argv[2][0]) || argv[2][0] == '(' || argv[2][0] =='\'') {
n = gdb_get_int(argv[2]);
gdb_set_address("$dot", addr);
gdb_set_int("$__prev_dm_n__", n);
gdb_printf("Displaying memory from %.8llX\n", (long long)addr);
__hexdump("$dot $__prev_dm_n__", from_tty);
gdb_set_int("$__lastcmd__", 5);
return;
}
gdb_set_int("$__lastcmd__", -5);
sprintf(addrStr, "0x%llX", (long long)addr);
basicType = (argv[2][0] != '"') ? argv[2] : gdb_get_string(argv[2], line, 30);
switch (n = gdb_keyword(basicType, basic_types)) {
case 0:
gdb_read_memory(&b, addrStr, 1);
gdb_printf("Displaying Byte\n"
" %.8llX: %.2X\n", (long long)addr, (unsigned char)b);
break;
case 1:
gdb_read_memory(&w, addrStr, 2);
gdb_printf("Displaying Word\n"
" %.8llX: %.4X\n", (long long)addr, (unsigned short)w);
break;
case 2:
gdb_read_memory(&l, addrStr, 4);
gdb_printf("Displaying Long\n"
" %.8llX: %.8lX\n", (long long)addr, (unsigned long)l);
break;
case 3:
gdb_read_memory(&ll, addrStr, 8);
gdb_printf("Displaying Long Long\n"
" %.8llX: %.16llX\n", (long long)addr, (unsigned long long)ll);
break;
case 4:
gdb_read_memory(&b, addrStr, 1);
gdb_printf("Displaying SignedByte\n"
" %.8llX: %d\n", (long long)addr, (char)b);
break;
case 5:
gdb_read_memory(&w, addrStr, 2);
gdb_printf("Displaying SignedWord\n"
" %s%s: %d\n", (long long)addr, (short)w);
break;
case 6:
gdb_read_memory(&l, addrStr, 4);
gdb_printf("Displaying SignedLong\n"
" %.8llX: %ld\n", (long long)addr, (long)l);
break;
case 7:
gdb_read_memory(&ll, addrStr, 8);
gdb_printf("Displaying SignedLongLong\n"
" %.8llX: %lld\n", (long long)addr, (long long)ll);
break;
case 8:
gdb_read_memory(&b, addrStr, 1);
gdb_printf("Displaying UnsignedByte\n"
" %.8llX: %u\n", (long long)addr, (unsigned char)b);
break;
case 9:
gdb_read_memory(&w, addrStr, 2);
gdb_printf("Displaying UnsignedWord\n"
" %.8llX: %u\n", (long long)addr, (unsigned short)w);
break;
case 10:
gdb_read_memory(&l, addrStr, 4);
gdb_printf("Displaying UnsignedLong\n"
" %.8llX: %lu\n", (long long)addr, (unsigned long)l);
break;
case 11:
gdb_read_memory(&ll, addrStr, 8);
gdb_printf("Displaying UnsignedLongLong\n"
" %.8llX: %llu\n", (long long)addr, (unsigned long long)ll);
break;
case 12:
gdb_read_memory(&b, addrStr, 1);
gdb_read_memory(line, addrStr, b + 1);
gdb_printf("Displaying PString\n"
" %.8llX: (%d) \"", (long long)addr, b);
for (i = 1; i <= b; ++i)
gdb_printf("%s", filter_char(line[i], 1, buf));
gdb_puts("\"\n");
break;
case 13:
gdb_printf("Displaying CString\n"
" %.8llX: \"", (long long)addr);
gdb_read_memory(&b, addrStr, 1);
while (b) {
gdb_printf("%s", filter_char(b, 1, buf));
sprintf(addrStr, "0x%llX", ++addr);
gdb_read_memory(&b, addrStr, 1);
}
gdb_puts("\"\n");
break;
case 14:
gdb_read_memory(&b, addrStr, 1);
gdb_printf("Displaying Boolean\n"
" %.8llX: %s\n", (long long)addr, b ? "true" : "false");
break;
case 15:
gdb_read_memory(&b, addrStr, 1);
gdb_printf("Displaying Binary8\n"
" %.8llX: %.2X = ", (long long)addr, (unsigned char)b);
sprintf(line, "0x%X 4", (b >> 4) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", b & 0x0F);
__binary(line, from_tty);
gdb_puts("\n");
break;
case 16:
gdb_read_memory(&w, addrStr, 2);
gdb_printf("Displaying Binary16\n"
" %.8llX: %.4X = ", (long long)addr, (unsigned short)w);
sprintf(line, "0x%X 4", (w >> 12) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", (w >> 8) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", (w >> 4) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", w & 0x0F);
__binary(line, from_tty);
gdb_puts("\n");
break;
case 17:
gdb_read_memory(&l, addrStr, 4);
gdb_printf("Displaying Binary32\n"
" %.8llX: %.8lX = ", (long long)addr, (unsigned long)l);
Binary32:
sprintf(line, "0x%X 4", (l >> 28) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", (l >> 24) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", (l >> 20) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", (l >> 16) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", (l >> 12) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", (l >> 8) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", (l >> 4) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%X 4", l & 0x0F);
__binary(line, from_tty);
gdb_puts("\n");
break;
case 18:
gdb_read_memory(&ll, addrStr, 8);
gdb_printf("Displaying Binary64\n"
" %.8llX: %.16llX = ", (long long)addr, ll);
sprintf(line, "0x%llX 4", (ll >> 60) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%llX 4", (ll >> 56) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%llX 4", (ll >> 52) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%llX 4", (ll >> 48) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%llX 4", (ll >> 44) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%llX 4", (ll >> 40) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%llX 4", (ll >> 36) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
sprintf(line, "0x%llX 4", (ll >> 32) & 0x0F);
__binary(line, from_tty);
gdb_puts(" ");
l = (unsigned long)ll;
goto Binary32;
break;
case 19:
gdb_read_memory(&l, addrStr, 4);
gdb_printf("Displaying OSType\n"
" %.8llX: %.8X = ", (long long)addr, l);
sprintf(line, "0x%.lX", l);
__print_4(line, from_tty);
gdb_puts("\n");
break;
case 20:
gdb_read_memory(&rect, addrStr, sizeof(rect));
gdb_printf("Displaying Rect\n"
" %.8llX: %d %d %d %d (t,l,b,r) %d %d (w,h)\n",
(long long)addr, rect.top, rect.left, rect.bottom, rect.right,
rect.right - rect.left, rect.bottom - rect.top);
break;
default:
if (n < 0)
gdb_error("Unrecognized type.");
else
gdb_fprintf(gdb_current_stderr,
"%s is not supported in the gdb MacsBug commands.\n"
"Use the gdb PRINT command. With appropriate type\n"
"casts you'll probably get better results anyhow.\n", argv[2]);
break;
}
}
#define DM_HELP \
"DM [addr [n | basicType]] -- Display memory from addr for n bytes or as a basic type.\n" \
"The basic types are Byte, Word, Long, LongLong,\n" \
"SignedByte, SignedWord, SignedLong, SignedLongLong,\n" \
"UnsignedByte, UnsignedWord, UnsignedLong, UnsignedLongLong,\n" \
"PString, CString, Boolean, Binary8, Binary16, Binary32, Binary64,\n" \
"OSType, and Rect.\n" \
"\n" \
"Also see SET for [mb-]ditto mode (HELP set mb-ditto).\n" \
"\n" \
"Macsbug features not supported: templates and the following basic types.\n" \
" Pointer, Handle, RGBColor, Text, IORefNum,\n" \
" VRefNum, Seconds, ATrapWord, AbsTicks,\n" \
" TickInterval, Region, RgnHandle, IOTrapWord,\n" \
" Version, Fixed, ShortFixed, UnsignedFixed,\n" \
" and Fract."
static void dma(char *arg, int from_tty)
{
int argc, n;
GDB_ADDRESS addr;
char *argv[5], tmpCmdLine[1024];
__is_running("The program is not running.", 0);
gdb_setup_argv(safe_strcpy(tmpCmdLine, arg), "DDMAM", &argc, argv, 4);
if (argc == 1) {
if (gdb_get_int("$__lastcmd__") == 37) {
addr = gdb_get_address("$dot") + gdb_get_int("$__prev_dma_n__");
back_up_over_prompt(gdb_get_address("$dot"), 0, from_tty);
gdb_set_address("$dot", addr);
} else {
gdb_printf("Displaying memory from %.8llX\n", (long long)gdb_get_address("$dot"));
gdb_set_int("$__prev_dma_n__", 512);
}
__asciidump("$dot $__prev_dma_n__", from_tty);
gdb_set_int("$__lastcmd__", 37);
return;
}
addr = gdb_get_address(argv[1]);
if (argc == 2) {
gdb_set_address("$dot", addr);
gdb_set_int("$__prev_dma_n__", 512);
gdb_printf("Displaying memory from %.8llX\n", (long long)addr);
__asciidump("$dot 512", from_tty);
gdb_set_int("$__lastcmd__", 37);
return;
}
if (argc > 3)
gdb_error("usage: DMA [addr [n]] (wrong number of arguments)");
n = gdb_get_int(argv[2]);
gdb_set_address("$dot", addr);
gdb_set_int("$__prev_dma_n__", n);
gdb_printf("Displaying memory from %.8llX\n", (long long)addr);
__asciidump("$dot $__prev_dma_n__", from_tty);
gdb_set_int("$__lastcmd__", 37);
}
#define DMA_HELP \
"DMA [addr [n]] -- Display memory as ASCII from addr for n (default 512) bytes.\n" \
"ASCII characters outside the range 0x20 to 0x7F are shown as '.'s.\n"
static void dp(char *arg, int from_tty)
{
GDB_ADDRESS addr;
__is_running("The program is not running.", 0);
if (arg && *arg) {
addr = gdb_get_address(arg);
gdb_set_address("$dot", addr);
gdb_printf("Displaying memory from %.8llX\n", (long long)addr);
} else if (gdb_get_int("$__lastcmd__") == 6) {
addr = gdb_get_address("$dot") + 128;
back_up_over_prompt(addr, 0, from_tty);
gdb_set_address("$dot", addr);
} else {
addr = gdb_get_address("$dot");
gdb_printf("Displaying memory from %.8llX\n", (long long)addr);
}
__hexdump("$dot 128", from_tty);
gdb_set_int("$__lastcmd__", 6);
}
#define DP_HELP "DP [addr] -- Display 128 bytes at addr (or $dot)."
static void dv(char *arg, int from_tty)
{
time_t t;
struct tm *ts;
long year;
gdb_printf("\nGdb/Macsbug " VERSION ", Copyright Apple Computer, Inc. 2000");
time(&t);
ts = localtime(&t);
year = 1900 + ts->tm_year;
if (year > 2000)
gdb_printf("-%d", year);
gdb_printf("\n\n");
gdb_set_int("$__lastcmd__", 12);
if (arg && *arg && !gdb_strcmpl(arg, "V"))
gdb_error("Invalid option (V exprected)");
else if (!arg)
gdb_printf(" Written by Ira L. Ruben.\n\n");
}
#define DV_HELP \
"DV [V] -- Display MacsBug version.\n" \
"V: Display version only, do not show credits."
static void dw(char *arg, int from_tty)
{
db_dw_dl_dll(arg, from_tty, 2, 7);
}
#define DW_HELP "DW [addr] -- Display in hex the two bytes at addr (or $dot)."
static void fill(char *arg, int from_tty)
{
int argc, n, len, i;
unsigned short w;
unsigned long l;
GDB_ADDRESS addr, addr0;
unsigned long long value;
char b, *argv[6], addrStr[20], str[1025], tmpCmdLine[1024];
__is_running("The program is not running.", 0);
gdb_setup_argv(safe_strcpy(tmpCmdLine, arg), "FILL", &argc, argv, 5);
if (argc != 4)
gdb_error("usage: FILL addr n expr|\"string\" (wrong number of arguments)");
addr = addr0 = gdb_get_address(argv[1]);
n = gdb_get_int(argv[2]);
gdb_set_address("$dot", addr);
if (gdb_is_string(argv[3])) {
gdb_get_string(argv[3], str, 1024);
len = strlen(str);
i = 0;
while (n--) {
sprintf(addrStr, "0x%llX", (long long)(addr++));
gdb_write_memory(addrStr, &str[i], 1);
if (++i >= len)
i = 0;
}
} else {
value = gdb_get_long_long(argv[3]);
if ((long long)value >= -128 && (long long)value <= 255) {
b = value;
while (n--) {
sprintf(addrStr, "0x%llX", (long long)(addr++));
gdb_write_memory(addrStr, &b, 1);
}
} else if ((long long)value >= -32768 && (long long)value <= 65535) {
w = value;
i = 0;
while (n--) {
sprintf(addrStr, "0x%llX", (long long)(addr++));
b = (value >> (8 - (i++%2)*8)) & 0xFF;
gdb_write_memory(addrStr, &b, 1);
}
} else if ((long long)value >= -2147483648LL && (long long)value <= 4294967296LL) {
l = value;
i = 0;
while (n--) {
sprintf(addrStr, "0x%llX", (long long)(addr++));
b = (value >> (24 - (i++%4)*8)) & 0xFF;
gdb_write_memory(addrStr, &b, 1);
}
} else {
i = 0;
while (n--) {
sprintf(addrStr, "0x%llX", (long long)(addr++));
b = (value >> (56 - (i++%8)*8)) & 0xFF;
gdb_write_memory(addrStr, &b, 1);
}
}
}
sprintf(addrStr, "0x%llX", (long long)addr0);
gdb_printf("Memory set starting at %s\n", addrStr);
__hexdump(addrStr, from_tty);
gdb_set_int("$__lastcmd__", 34);
}
#define FILL_HELP \
"FILL addr n expr|\"string\" -- Fill from addr to addr+n-1 with expr or string.\n" \
"The fill is repeatedly used as a byte, word, or long (determined by the size\n" \
"of the expr value) or the string."
static void find(char *arg, int from_tty)
{
int argc, size, found, len, i;
unsigned short w;
GDB_ADDRESS addr, limit;
unsigned long l;
unsigned long long value, ll;
unsigned char b;
char *buf, s[20], *argv[7], str[1025], addrStr[20], tmpCmdLine[1024];
size = find_size;
find_size = 0;
if (size == 0)
findName = "FIND";
gdb_setup_argv(safe_strcpy(tmpCmdLine, arg), findName, &argc, argv, 6);
if (argc != 4 ||
(argc >= 4 && (strcmp(argv[2], "if") == 0 || strcmp(argv[2], "thread") == 0))) {
if (size == 1 ) {
gdb_execute_command("future %s", arg ? arg : "");
return;
}
if (size == 0 && argc <= 2) {
gdb_execute_command("frame %s", arg ? arg : "");
return;
}
gdb_error("usage: %s addr n expr|\"string\" (wrong number or invalid of arguments)", findName);
}
__is_running("The program is not running.", 0);
addr = gdb_get_address(argv[1]);
limit = addr + gdb_get_int(argv[2]);
found = 0;
if (gdb_is_string(argv[3])) {
gdb_get_string(argv[3], str, 1024);
len = strlen(str);
gdb_printf("Searching for \"");
for (i = 0; i < len; ++i)
gdb_printf("%s", filter_char(str[i], 1, s));
gdb_printf("\" from %.8llX to %.8llX\n", (long long)addr, (unsigned long long)limit-1ul);
buf = gdb_malloc(len);
limit -= len;
while (addr < limit) {
sprintf(addrStr, "0x%llX", (long long)(addr++));
gdb_read_memory(buf, addrStr, len);
if (memcmp(buf, str, len) == 0) {
found = 1;
break;
}
}
gdb_free(buf);
} else {
value = gdb_get_long_long(argv[3]);
switch (size) {
case 0:
if ((long long)value >= -128 && (long long)value <= 255)
goto FB;
else if ((long long)value >= -32768 && (long long)value <= 65535)
goto FW;
else if ((long long)value >= -2147483648LL && (long long)value <= 4294967296LL)
goto FL;
else
goto FLL;
case 1:
FB: value = (unsigned char)(value & 0xFF);
gdb_printf("Searching for 0x%.2X from 0x%.8llX to 0x%.8llX\n", (unsigned char)value,
(long long)addr, (unsigned long long)limit-1ul);
while (addr < limit) {
sprintf(addrStr, "0x%llX", (long long)(addr++));
gdb_read_memory(&b, addrStr, 1);
if (b == (unsigned char)value) {
found = 1;
break;
}
}
break;
case 2:
FW: value = (unsigned short)(value & 0xFFFF);
gdb_printf("Searching for 0x%.4X from 0x%.8llX to 0x%.8llX\n", (unsigned short)value,
(long long)addr, (unsigned long long)limit-1ul);
limit -= 2;
while (addr <= limit) {
sprintf(addrStr, "0x%llX", (long long)(addr++));
gdb_read_memory(&w, addrStr, 2);
if (w == (unsigned short)value) {
found = 1;
break;
}
}
break;
case 4:
FL: value = (unsigned long)(value & 0xFFFFFFFF);
gdb_printf("Searching for 0x%.8lX from 0x%.8llX to 0x%.8llX\n", (unsigned long)value,
(long long)addr, (unsigned long long)limit-1ul);
limit -= 4;
while (addr <= limit) {
sprintf(addrStr, "0x%llX", (long long)(addr++));
gdb_read_memory(&l, addrStr, 4);
if (l == (unsigned long)value) {
found = 1;
break;
}
}
break;
case 8:
FLL:gdb_printf("Searching for 0x%.16llX from 0x%.8llX to 0x%.8llX\n", value,
(long long)addr, (unsigned long long)limit-1ul);
limit -= 8;
while (addr <= limit) {
sprintf(addrStr, "0x%llX", (long long)(addr++));
gdb_read_memory(&ll, addrStr, 16);
if (ll == value) {
found = 1;
break;
}
}
break;
default:
gdb_error("Internal error -- invalid size passed to %s", findName);
}
}
if (found) {
gdb_set_address("$dot", addr);
__hexdump(addrStr, from_tty);
} else if (macsbug_screen)
gdb_fprintf(gdb_current_stderr, " Not found\n");
else
gdb_printf(COLOR_RED " Not found" COLOR_OFF "\n");
gdb_set_int("$__lastcmd__", 35);
}
#define FIND_HELP \
"FIND addr n expr or FRAME -- Search from addr to addr+n-1 for pattern.\n" \
"Abbreviated as F [arg] means this is a FRAME command (do HELP FRAME).\n" \
"Abbreviated as F addr n expr means this is the Macsbug FIND command.\n" \
"\n" \
"If pattern is an expr then the width of the pattern is the smallest unit\n" \
"(byte, word, long, or long long) that contains its value.\n" \
"\n" \
"Restriction: The expr value may not have any embedded blanks. For example\n" \
" a value like (unsigned char *)&a is invalid.\n" \
"\n" \
"Macsbug features not supported: Double quoted \"string\" instead of single\n" \
" quoted 'string'."
static void f(char *arg, int from_tty)
{
find_size = 0;
findName = "F";
find(arg, from_tty);
}
static void fb(char *arg, int from_tty)
{
find_size = 1;
findName = "FB";
find(arg, from_tty);
}
#define FB_HELP \
"FB addr n expr|\"string\" -- Search from addr to addr+n-1 for the byte.\n" \
"\n" \
"Note, FB is also an alias for gdb's FUTURE-BREAK command. The syntax of\n" \
"the FB parameters determines whether FB is treated as a MacsBug FB or a\n" \
"gdb FUTURE-BREAK alias."
static void fl(char *arg, int from_tty)
{
find_size = 4;
findName = "FL";
find(arg, from_tty);
}
#define FL_HELP \
"FL addr n expr|\"string\" -- Search from addr to addr+n-1 for the 4-byte long."
static void fll(char *arg, int from_tty)
{
find_size = 8;
findName = "FLL";
find(arg, from_tty);
}
#define FLL_HELP \
"FLL addr n expr|\"string\" -- Search from addr to addr+n-1 for the 8-byte long long."
static void fw(char *arg, int from_tty)
{
find_size = 2;
findName = "FW";
find(arg, from_tty);
}
#define FW_HELP \
"FW addr n expr|\"string\" -- Search from addr to addr+n-1 for the 2-byte word."
static void g(char *arg, int from_tty)
{
if (!gdb_target_running())
ra(arg, from_tty);
else {
if (arg && *arg)
gdb_eval("$pc=%s", arg);
gdb_set_int("$__lastcmd__", 8);
gdb_continue_command(NULL, from_tty);
}
}
#define G_HELP \
"G [addr] -- Continue execution (at addr if supplied).\n" \
"\n" \
"Note, G is treated as a RA (\"run again\") command if the target\n" \
"program is not currently running."
static void gt(char *arg, int from_tty)
{
if (!arg || !*arg)
gdb_error("usage: GT gdb-spec (gdb-spec expected)");
gdb_execute_command("tbreak %s", arg);
gdb_set_int("$__lastcmd__", 36);
if (gdb_target_running())
gdb_continue_command(NULL, from_tty);
else
ra(NULL, from_tty);
}
#define GT_HELP \
"GT gdb-spec -- Go (continue) until the gdb-spec is reached.\n" \
"This implements the gdb \"TBREAK gdb-spec\" followed by a CONTINUE\n" \
"command. See gdb TBREAK documentation for further details.\n" \
"\n" \
"Note, GT is treated as a TBREAK followed by RA (\"run again\")\n" \
"command if the target program is not currently running.\n" \
"\n" \
"Macsbug features not supported: Command list not allowed." \
static void id(char *arg, int from_tty)
{
GDB_ADDRESS addr;
char line[1024];
__is_running("The program is not running.", 0);
if (arg && *arg) {
__reset_current_function(NULL, 0);
addr = gdb_get_address(arg);
if (macsbug_screen && isatty(STDOUT_FILENO))
gdb_printf("\n");
} else if (gdb_get_int("$__lastcmd__") == 9) {
addr = gdb_get_address("$dot") + 4;
back_up_over_prompt(addr, branchTaken, from_tty);
} else {
__reset_current_function(NULL, 0);
gdb_get_register("$pc", &addr);
if (macsbug_screen && isatty(STDOUT_FILENO))
gdb_printf("\n");
}
gdb_set_address("$dot", addr);
sprintf(line, "0x%llx 1 %d", (long long)addr, macsbug_screen);
__disasm(line, from_tty);
gdb_set_int("$__lastcmd__", 9);
}
#define ID_HELP \
"ID [addr] -- Disassemble 1 line starting at addr (or pc).\n" \
"\n" \
"Macsbug features not supported: -c option."
static void il(char *arg, int from_tty)
{
int argc, n;
GDB_ADDRESS addr;
char *argv[5], tmpCmdLine[1024];
__is_running("The program is not running.", 0);
gdb_setup_argv(safe_strcpy(tmpCmdLine, arg), "IL", &argc, argv, 4);
if (argc == 1) {
if (gdb_get_int("$__lastcmd__") == 11) {
addr = gdb_get_address("$dot") + 4*20;
back_up_over_prompt(addr, branchTaken, from_tty);
} else {
__reset_current_function(NULL, 0);
gdb_get_register("$pc", &addr);
if (macsbug_screen && isatty(STDOUT_FILENO))
gdb_printf("\n");
}
n = 20;
} else {
__reset_current_function(NULL, 0);
if (argc == 2) {
addr = gdb_get_address(argv[1]);
n = 20;
} else if (argc == 3) {
addr = gdb_get_address(argv[1]);
n = gdb_get_int(argv[2]);
} else
gdb_error("usage: IL [addr [n]] (wrong number of arguments)");
if (macsbug_screen && isatty(STDOUT_FILENO))
gdb_printf("\n");
}
gdb_set_address("$dot", addr);
sprintf(tmpCmdLine, "0x%llx %ld", (long long)addr, n);
__disasm(tmpCmdLine, from_tty);
gdb_set_int("$__lastcmd__", 11);
}
#define IL_HELP \
"IL [addr [n]] -- Disassemble n (default 20) lines from the addr or pc.\n" \
"\n" \
"Macsbug features not supported: -c option."
static void ip(char *arg, int from_tty)
{
int argc;
GDB_ADDRESS addr;
char *argv[4], tmpCmdLine[1024];
__is_running("The program is not running.", 0);
gdb_setup_argv(safe_strcpy(tmpCmdLine, arg), "IL", &argc, argv, 3);
if (argc == 1) {
if (gdb_get_int("$__lastcmd__") == 13) {
addr = gdb_get_address("$dot") + 4*21;
back_up_over_prompt(addr - 40, branchTaken, from_tty);
} else {
__reset_current_function(NULL, 0);
gdb_get_register("$pc", &addr);
if (macsbug_screen && isatty(STDOUT_FILENO))
gdb_printf("\n");
}
} else {
__reset_current_function(NULL, 0);
if (argc != 2)
gdb_error("usage: IP [addr] (wrong number of arguments)");
addr = gdb_get_address(argv[1]);
if (macsbug_screen && isatty(STDOUT_FILENO))
gdb_printf("\n");
}
gdb_set_address("$dot", addr);
sprintf(tmpCmdLine, "0x%llx 21", (unsigned long long)addr-40ul);
__disasm(tmpCmdLine, from_tty);
gdb_set_int("$__lastcmd__", 13);
}
#define IP_HELP \
"IP [addr] -- Disassemble 20 lines centered around the addr (or pc).\n" \
"\n" \
"Macsbug features not supported: -c option."
static void mr(char *arg, int from_tty)
{
if (arg && *arg)
gdb_error("Only the parameterless form of MR is supported.");
else
gdb_execute_command("finish");
gdb_set_int("$__lastcmd__", 15);
}
#define MR_HELP \
"MR -- Return from current frame.\n" \
"\n" \
"Macsbug features not supported: offset and addr arguments."
static void _rn(int r, int from_tty)
{
int i;
unsigned long l;
GDB_ADDRESS value;
char regName[10], uc_regName[10];
(void)gdb_get_address("$pc");
if (r >= 0) {
sprintf(regName, "$r%d", r);
gdb_get_register(regName, &value);
} else if (r == -1) {
gdb_get_register("$pc", &value);
strcpy(regName, "$pc");
} else {
gdb_get_register("$r1", &value);
strcpy(regName, "$sp");
}
i = strlen(strcpy(uc_regName, regName));
while (--i >= 1)
uc_regName[i] = toupper(uc_regName[i]);
if (target_arch == 4) {
l = (unsigned long) value;
gdb_printf("%s = 0x%.8lX %luul %ldl ", &uc_regName[1], l, l, l);
__print_4(regName, from_tty);
} else {
gdb_printf("%s = 0x%.16llX %lluull %lldll ", &uc_regName[1], value, value, value);
__print_8(regName, from_tty);
}
gdb_printf("\n");
gdb_set_int("$__lastcmd__", 41);
}
static void pc(char *arg, int from_tty)
{
_rn(-1, from_tty);
}
#define HELP_PC "PC -- Display the value of PC"
static char *check_confirm_status(FILE *f, char *line, void *data)
{
if (line)
*(int *)data = (strstr(line, "off.") != NULL) ? 0 : 1;
return (NULL);
}
static void ra(char *arg, int from_tty)
{
GDB_FILE *redirect_stdout, *redirect_stderr;
int confirm_status;
char *cmdLine = gdb_get_previous_command();
redirect_stdout = gdb_open_output(stdout, check_confirm_status, &confirm_status);
gdb_redirect_output(redirect_stdout);
gdb_execute_command("show confirm");
gdb_close_output(redirect_stdout);
if (confirm_status) {
gdb_execute_command("set confirm off");
run_command(arg, from_tty);
gdb_execute_command("set confirm on");
} else
run_command(arg, from_tty);
gdb_set_previous_command(cmdLine);
gdb_free(cmdLine);
}
#define RA_HELP \
"Unconditionaly restart debugged program (\"run again\").\n" \
"This is identical to RUN except no prompt is displayed if the program\n" \
"is currently running. The debugged program is unconditionally restarted.\n" \
"See gdb RUN documentation for further details."
#define Rn(n) static void r##n(char *arg, int from_tty) {_rn(n, from_tty);}
#if 0
#define Rstr(x) #x
#define R_COMMAND(n) MACSBUG_COMMAND(r##n, Rstr(R##n) " -- display the value of " Rstr(R##n))
#else
#define R_COMMAND(n) MACSBUG_INTERNAL_COMMAND(r##n, NULL)
static void rn(char *arg, int from_tty)
{
gdb_error("Type R<n>, where \"n\" is 0 to 31 to display the register value");
}
#define RN_HELP "R<n> [n = 0 to 31] -- Display value of register"
#endif
Rn(0); Rn(1); Rn(2); Rn(3); Rn(4); Rn(5); Rn(6); Rn(7); Rn(8); Rn(9);
Rn(10); Rn(11); Rn(12); Rn(13); Rn(14); Rn(15); Rn(16); Rn(17); Rn(18); Rn(19);
Rn(20); Rn(21); Rn(22); Rn(23); Rn(24); Rn(25); Rn(26); Rn(27); Rn(28); Rn(29);
Rn(30); Rn(31);
static void sb_sw_sl_sll_sm(char *arg, int from_tty, int size, int cmdNbr, char *cmdName)
{
int i, argc, isstr, len;
unsigned char b;
unsigned short w;
unsigned long l;
unsigned long long value;
GDB_ADDRESS addr, start;
char *argv[41], addrStr[20], str[1024], tmpCmdLine[1024];
__is_running("The program is not running.", 0);
gdb_setup_argv(safe_strcpy(tmpCmdLine, arg), cmdName, &argc, argv, 40);
if (argc < 3)
gdb_error("usage: %s addr value1 [... valueN]", cmdName);
addr = start = gdb_get_address(argv[1]);
for (i = 2; i < argc; ++i) {
isstr = gdb_is_string(argv[i]);
if (i == 2)
gdb_set_address("$dot", addr);
if (isstr) {
gdb_get_string(argv[i], str, 1023);
len = strlen(str);
sprintf(addrStr, "0x%llx", (long long)addr);
gdb_write_memory(addrStr, str, len);
addr += len;
} else {
sprintf(addrStr, "0x%llx", (long long)addr);
b = w = l = value = gdb_get_long_long(argv[i]);
switch (size) {
case 0:
if ((long long)value >= -128 && (long long)value <= 255)
goto SB;
else if ((long long)value >= -32768 && (long long)value <= 65535)
goto SW;
else if ((long long)value >= -2147483648LL && (long long)value <= 4294967296LL)
goto SL;
else
goto SLL;
case 1:
SB: gdb_write_memory(addrStr, &b, 1);
++addr;
break;
case 2:
SW: gdb_write_memory(addrStr, &w, 2);
addr += 2;
break;
case 4:
SL: gdb_write_memory(addrStr, &l, 4);
addr += 4;
break;
case 8:
SLL:gdb_write_memory(addrStr, &value, 8);
addr += 8;
break;
default:
gdb_error("Internal error -- invalid size passed to %s", cmdName);
}
}
}
gdb_printf("Memory set starting at %.8llX\n", (long long)start);
sprintf(str, "0x%llX %lld", (long long)start,
((addr - start + hexdump_width - 1)/hexdump_width)*hexdump_width);
__hexdump(str, from_tty);
fix_pc_area_if_necessary(start);
gdb_set_int("$__lastcmd__", cmdNbr);
}
static void sb(char *arg, int from_tty)
{
sb_sw_sl_sll_sm(arg, from_tty, 1, 17, "SB");
}
#define SB_HELP \
"SB addr values -- Assign values to bytes starting at addr.\n" \
"String values are fully assigned at the next assignable byte.\n" \
"\n" \
"Macsbug features not supported: Double quoted \"string\" instead of single quoted\n" \
" 'string'."
static void sc(char *arg, int from_tty)
{
if (macsbug_screen && isatty(STDOUT_FILENO) && gdb_get_int("$__prevcmd__") == 18)
gdb_printf("\n");
if (arg && *arg)
gdb_execute_command("bt %s", arg);
else
gdb_execute_command("bt");
gdb_set_int("$__lastcmd__", 18);
}
#define SC_HELP \
"SC [n] -- Display back trace (stack crawl).\n" \
"\n" \
"MacsBug extensions: Optional \"n\" is a positive or negative value. A positive\n" \
" value indicates to display only the innermost n frames.\n" \
" Negative means display only the outermost n frames."
static char *so_si_filter(FILE *f, char *line, void *data)
{
if (line) {
if (!macsbug_screen)
gdb_fprintf(*(GDB_FILE **)data, "%s", line);
else if (show_so_si_src && (line[0] != '0' || line[1] != 'x'))
gdb_fprintf(*(GDB_FILE **)data, "%s", line);
}
return (NULL);
}
static void so_and_si(char *arg, int from_tty, int cmdNbr, char *cmdName, char *gdbCmd)
{
GDB_FILE *redirect_stdout, *prev_stdout;
int argc, step, n;
GDB_ADDRESS pc;
char *argv[5], line[1024], tmpCmdLine[1024];
if (!gdb_target_running())
gdb_error("The program is not running.");
gdb_setup_argv(safe_strcpy(tmpCmdLine, arg), cmdName, &argc, argv, 4);
if (argc > 3)
gdb_error("%s called with wrong number of arguments.", cmdName);
if (argc == 1) {
step = 1;
n = macsbug_screen ? 1 : pc_area_lines;
} else if (argc == 2) {
step = gdb_get_int(argv[1]);
n = macsbug_screen ? 1 : pc_area_lines;
} else {
step = gdb_get_int(argv[1]);
n = gdb_get_int(argv[2]);
}
if (!macsbug_screen)
__reset_current_function(NULL, 0);
if (macsbug_screen) {
sprintf(line, "$pc %ld 1", n);
__disasm(line, from_tty);
}
redirect_stdout = gdb_open_output(stdout, so_si_filter, &prev_stdout);
prev_stdout = gdb_redirect_output(redirect_stdout);
sprintf(line, "%s %ld\n", gdbCmd, step);
gdb_execute_command(line);
gdb_close_output(redirect_stdout);
gdb_get_register("$pc", &pc);
gdb_set_address("$dot", pc);
if (!macsbug_screen) {
sprintf(line, "$pc %ld", n);
__disasm(line, from_tty);
}
gdb_set_int("$__lastcmd__", cmdNbr);
}
static void si(char *arg, int from_tty)
{
so_and_si(arg, from_tty, 16, "SI", "stepi");
}
#define SI_HELP \
"SI [n] [m] -- Step n (or 1) instruction(s) and disassemble m lines from new pc.\n" \
"See also gdb's next and step instructions, which step by source lines,\n" \
"not instructions.\n" \
"\n" \
"The second argument is a extension to the MacsBug syntax to allow a disassembly\n" \
"of m lines to show the next instructions to be executed. This approximates the\n" \
"disassembly window that MacsBug always shows.\n" \
"\n" \
"Macsbug features not supported: S expr\n" \
"\n" \
" The MacsBug S is SI here. This was done to preserve\n" \
" gdb's definition of S[tep] to single statement step.\n" \
" There is (was) a gdb SI to which does exactly what\n" \
" this MacsBug SI does except that now the instruction\n" \
" is also displayed at each instruction step.\n" \
"\n" \
"Note, the gdb SI abbreviation for STEPI is overridden by this MacsBug command."
static void sl(char *arg, int from_tty)
{
sb_sw_sl_sll_sm(arg, from_tty, 4, 21, "SL");
}
#define SL_HELP \
"SL addr values -- Assign values to (4-byte) longs starting at addr.\n" \
"String values are fully assigned at the next assignable byte.\n" \
"\n" \
"Macsbug features not supported: Double quoted \"string\" instead of single quoted\n" \
" 'string'."
static void sll(char *arg, int from_tty)
{
sb_sw_sl_sll_sm(arg, from_tty, 8, 50, "SLL");
}
#define SLL_HELP \
"SLL addr values -- Assign values to (8-byte) long longs starting at addr.\n" \
"String values are fully assigned at the next assignable byte.\n"
static void sm(char *arg, int from_tty)
{
sb_sw_sl_sll_sm(arg, from_tty, 0, 22, "SM");
}
#define SM_HELP \
"SM addr value -- Assign values to memory starting at addr.\n" \
"Each value determines the assignment size (byte, 2-byte word, or 4-byte\n" \
"long). Specific sizes can be set using SB, SW, or SL. String values\n" \
"are fully assigned at the next assignable byte.\n" \
"\n" \
"Macsbug features not supported: Double quoted \"string\" instead of single quoted\n" \
" 'string'."
static void so(char *arg, int from_tty)
{
so_and_si(arg, from_tty, 23, "SO", "nexti");
}
#define SO_HELP \
"SO [n] [m] -- Step over n instructions and disassemble m lines from new pc.\n" \
"See also gdb's next and step instructions, which step by source lines,\n" \
"not instructions.\n" \
"\n" \
"The second argument is a extension to the MacsBug syntax to allow a disassembly\n" \
"of m lines to show the next instructions to be executed. This approximates the\n" \
"disassembly window that MacsBug always shows."
static void sp(char *arg, int from_tty)
{
_rn(-2, from_tty);
}
#define HELP_SP "SP -- Display the value of SP (r1)"
static void sw(char *arg, int from_tty)
{
sb_sw_sl_sll_sm(arg, from_tty, 2, 24, "SW");
}
#define SW_HELP \
"SW addr values -- Assign values to (2-byte) words starting at addr.\n" \
"String values are fully assigned at the next assignable byte.\n" \
"\n" \
"Macsbug features not supported: Double quoted \"string\" instead of single quoted\n" \
" 'string'."
static void t(char *arg, int from_tty)
{
so_and_si(arg, from_tty, 25, "SO", "nexti");
}
#define T_HELP "T [n] [m] -- Same as SO."
static void td(char *arg, int from_tty)
{
int i, j, reg;
unsigned long cr, xer32;
GDB_ADDRESS rn, pc, lr, ctr, msr, xer;
char regName[20], tmpCmdLine[100];
(void)gdb_get_int("$pc");
gdb_printf("PowerPC Registers\n");
gdb_printf(" CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7\n");
gdb_get_register("$pc", &pc);
if (target_arch == 4)
gdb_printf(" PC = %.8lX CR ", (unsigned long)pc);
else
gdb_printf(" PC = %.16llX CR ", (unsigned long long)pc);
gdb_get_register("$cr", &cr);
for (i = 28; i >= 0; i -= 4) {
sprintf(tmpCmdLine, "0x%X 4", (cr >> i) & 0x0F);
gdb_printf(" ");
__binary(tmpCmdLine, from_tty);
}
gdb_printf("\n");
gdb_get_register("$lr", &lr);
gdb_get_register("$ctr", &ctr);
gdb_get_register("$ps", &msr);
if (target_arch == 4) {
gdb_printf(" LR = %.8lX <>=O XEVO\n", (unsigned long)lr);
gdb_printf(" CTR = %.8lX\n", (unsigned long)ctr);
gdb_printf(" MSR = %.8lX SOC Compare Count\n", (unsigned long)msr);
} else {
gdb_printf(" LR = %.16llX <>=O XEVO\n", (unsigned long long)lr);
gdb_printf(" CTR = %.16llX\n", (unsigned long long)ctr);
gdb_printf(" MSR = %.16llX SOC Compare Count\n", (unsigned long long)msr);
}
gdb_printf(" XER ");
gdb_get_register("$xer", &xer);
xer32 = (unsigned long)xer;
sprintf(tmpCmdLine, "0x%lX 3", (xer32>>29) & 7);
__binary(tmpCmdLine, from_tty);
#if 1
gdb_printf(" %.2lX %.2lX\n", (xer32>>8) & 0xFF, (xer32 & 0x7F));
#else
gdb_printf(" %.2lX %.2lX MQ = %.8lX\n",
(xer32>>8) & 0xFF, (xer32 & 0x7F), gdb_get_int("$mq"));
#endif
gdb_printf("\n");
if (target_arch == 4) {
for (i = 0; i < 8; ++i) {
for (j = 0; j < 4; ++j) {
reg = i + j*8;
sprintf(regName, "$r%d", reg);
gdb_get_register(regName, &rn);
if (reg <= 7)
if (reg != 1)
gdb_printf(" R%-2d = %.8lX", reg, (unsigned long)rn);
else
gdb_printf(" SP = %.8lX", (unsigned long)rn);
else
gdb_printf(" R%-2d = %.8lX", reg, (unsigned long)rn);
}
gdb_puts("\n");
}
} else {
for (i = 0; i < 16; ++i) {
for (j = 0; j < 2; ++j) {
reg = i + j*16;
sprintf(regName, "$r%d", reg);
gdb_get_register(regName, &rn);
if (reg <= 15)
if (reg != 1)
gdb_printf(" R%-2d = %.16llX", reg, rn);
else
gdb_printf(" SP = %.16llX", rn);
else
gdb_printf(" R%-2d = %.16llX", reg, rn);
}
gdb_puts("\n");
}
}
gdb_set_int("$__lastcmd__", 26);
}
#define TD_HELP "TD -- Display integer and machine registers."
static void tf(char *arg, int from_tty)
{
int i;
char f[4];
union {
unsigned long long fpscr_err;
unsigned long fpscr;
} fpscr;
union {
char msg[50];
double d;
struct {
unsigned long hi;
unsigned long lo;
} hilo;
} value, *v;
gdb_get_register("$fpscr", &fpscr.fpscr);
gdb_printf("FPU Registers\n");
gdb_printf(" S S\n");
gdb_printf(" F N I I Z I O Q C\n");
gdb_printf(" FPSCR F E V O U Z X A S D D M V F F F R V V O U Z X N\n");
gdb_printf(" X X X X X X X N I I Z Z C R I C < > = ? T T I E E E E E I RN\n");
gdb_printf(" ");
for (i = 31; i >= 2; --i)
gdb_printf("%d ", (fpscr.fpscr >> i) & 1);
gdb_printf("%d%d\n\n", (fpscr.fpscr >> 1) & 1, fpscr.fpscr & 1);
for (i = 0; i < 32; ++i) {
sprintf(f, "$f%d", i);
gdb_printf(" FPR%-2d = ", i);
v = gdb_get_register(f, &value);
if (v == NULL)
gdb_error(value.msg);
gdb_printf("%.3lX %.5lX%.8lX %- 15.15e\n",
(value.hilo.hi >> 20) & 0xFFF, value.hilo.hi & 0x000FFFFF, value.hilo.lo,
value.d);
}
gdb_set_int("$__lastcmd__", 27);
}
#define TF_HELP "TF -- Display the floating point registers."
static void tv(char *arg, int from_tty)
{
int i, j, k;
unsigned long vrsave, vscr;
double d;
char vn[4], vf[13];
union {
char msg[50];
unsigned long l[4];
float f[4];
} value, *v;
gdb_get_register("$vrsave", &vrsave);
gdb_printf("Vector Registers\n");
gdb_printf(" S\n");
gdb_printf(" VRsave = %.8lX", vrsave);
gdb_printf(" N A\n");
gdb_printf(" J T\n");
vscr = 0;
gdb_get_register("$vscr", &vscr);
gdb_printf(" VSCR = ");
for (i = 31; i >= 0; --i)
gdb_printf("%d ", (vscr >> i) & 1);
gdb_printf("\n\n");
for (i = 0; i < 32; ++i) {
sprintf(vn, "$v%d", i);
gdb_printf(" V%-2d = ", i);
v = gdb_get_register(vn, &value);
if (v == NULL)
gdb_error(value.msg);
gdb_printf("%.8lX %.8lX %.8lX %.8lX ",
value.l[0], value.l[1],value.l[2],value.l[3]);
for (k = 0; k < 4; ++k) {
strcpy(vf, " ");
d = value.f[k];
j = sprintf(vf, "%- 4.4e", d);
vf[j] = ' ';
gdb_printf("%s ", vf);
}
gdb_printf("\n");
}
gdb_set_int("$__lastcmd__", 28);
}
#define TV_HELP "TV -- Display the vector registers."
static void wh(char *arg, int from_tty)
{
int argc;
char *addr, *argv[4], tmpCmdLine[1024];
static char *prev_arg;
__is_running("The program is not running.", 0);
gdb_setup_argv(safe_strcpy(tmpCmdLine, arg), "WH", &argc, argv, 2);
if (argc == 1)
addr = "*$pc";
else
addr = argv[1];
gdb_print_address(addr);
prev_arg = addr;
gdb_set_int("$__lastcmd__", 42);
}
#define WH_HELP \
"WH [*addr | linespec] -- Find the name and addr of the parameter.\n" \
"If no parameter then assume WH *$pc. Type HELP INFO LINE or HELP\n" \
"LIST for more info on linespecs.\n" \
"\n" \
"Note that, if possible, the source line is listed exactly like it\n" \
"was done using the gdb LIST command. Thus the amount of context\n" \
"lines is controlled by the SET listsize command.\n" \
"\n" \
"If source lines cannot be displayed then, if possible, the pathname\n" \
"of the file containing the specified address is displayed.\n" \
"\n" \
"Macsbug features not supported: Traps.\n" \
" Numeric addresses and gdb convenience\n" \
" variables must start with a '*'."
void init_from_gdb(void)
{
if (!gdb_initialize())
return;
macsbug_class = gdb_define_class("macsbug", "MacsBug commands");
macsbug_internal_class = Gdb_Private;
macsbug_screen_class = gdb_define_class("screen", "MacsBug screen commands");
macsbug_testing_class = Gdb_Private;
macsbug_useful_class = gdb_define_class("useful", "Possibly useful for DEFINE commands (some used by MacsBug)");
gdb_change_class("mb-notes", Gdb_Private);
MACSBUG_COMMAND(brc, BRC_HELP);
MACSBUG_COMMAND(brd, BRD_HELP);
MACSBUG_COMMAND(brm, BRM_HELP);
MACSBUG_COMMAND(brp, BRP_HELP);
MACSBUG_COMMAND(db, DB_HELP);
MACSBUG_COMMAND(dl, DL_HELP);
MACSBUG_COMMAND(dll, DLL_HELP);
MACSBUG_COMMAND(dm, DM_HELP);
MACSBUG_COMMAND(dma, DMA_HELP);
MACSBUG_COMMAND(dv, DV_HELP);
MACSBUG_COMMAND(dp, DP_HELP);
MACSBUG_COMMAND(dw, DW_HELP);
MACSBUG_COMMAND(fb, FB_HELP);
MACSBUG_COMMAND(fill, FILL_HELP);
MACSBUG_COMMAND(find, FIND_HELP);
MACSBUG_COMMAND(f, FIND_HELP);
MACSBUG_COMMAND(fl, FL_HELP);
MACSBUG_COMMAND(fll, FLL_HELP);
MACSBUG_COMMAND(fw, FW_HELP);
MACSBUG_COMMAND(g, G_HELP);
MACSBUG_COMMAND(gt, GT_HELP);
MACSBUG_COMMAND(id, ID_HELP);
MACSBUG_COMMAND(il, IL_HELP);
MACSBUG_COMMAND(ip, IP_HELP);
MACSBUG_COMMAND(mr, MR_HELP);
MACSBUG_COMMAND(sb, SB_HELP);
MACSBUG_COMMAND(sc, SC_HELP);
MACSBUG_COMMAND(si, SI_HELP);
MACSBUG_COMMAND(sl, SL_HELP);
MACSBUG_COMMAND(sll, SLL_HELP);
MACSBUG_COMMAND(sm, SM_HELP);
MACSBUG_COMMAND(so, SO_HELP);
MACSBUG_COMMAND(sw, SW_HELP);
MACSBUG_COMMAND(t, T_HELP);
MACSBUG_COMMAND(td, TD_HELP);
MACSBUG_COMMAND(tf, TF_HELP);
MACSBUG_COMMAND(tv, TV_HELP);
MACSBUG_COMMAND(wh, WH_HELP);
COMMAND_ALIAS(id, idp);
COMMAND_ALIAS(il, ilp);
COMMAND_ALIAS(ip, ipp);
COMMAND_ALIAS(sc, sc6);
COMMAND_ALIAS(sc, sc7);
R_COMMAND(0); R_COMMAND(1); R_COMMAND(2); R_COMMAND(3); R_COMMAND(4);
R_COMMAND(5); R_COMMAND(6); R_COMMAND(7); R_COMMAND(8); R_COMMAND(9);
R_COMMAND(10); R_COMMAND(11); R_COMMAND(12); R_COMMAND(13); R_COMMAND(14);
R_COMMAND(15); R_COMMAND(16); R_COMMAND(17); R_COMMAND(18); R_COMMAND(19);
R_COMMAND(20); R_COMMAND(21); R_COMMAND(22); R_COMMAND(23); R_COMMAND(24);
R_COMMAND(25); R_COMMAND(26); R_COMMAND(27); R_COMMAND(28); R_COMMAND(29);
R_COMMAND(30); R_COMMAND(31);
MACSBUG_COMMAND(pc, HELP_PC);
MACSBUG_COMMAND(sp, HELP_SP);
MACSBUG_COMMAND(rn, RN_HELP);
gdb_define_cmd("ra", ra, Gdb_Running, RA_HELP);
gdb_enable_filename_completion("ra");
init_macsbug_utils();
init_macsbug_display();
init_macsbug_patches();
init_macsbug_set();
init_macsbug_cmdline();
gdb_continue_command = gdb_replace_command("continue", NULL);
if (!gdb_continue_command)
gdb_internal_error("internal error - continue command not found");
if (!isatty(STDOUT_FILENO)) {
gdb_fixup_document_help("mb-notes");
}
}