aboutsummaryrefslogtreecommitdiff
path: root/libgloss/debug.c
diff options
context:
space:
mode:
Diffstat (limited to 'libgloss/debug.c')
-rw-r--r--libgloss/debug.c848
1 files changed, 0 insertions, 848 deletions
diff --git a/libgloss/debug.c b/libgloss/debug.c
deleted file mode 100644
index 3b1c8ff..0000000
--- a/libgloss/debug.c
+++ /dev/null
@@ -1,848 +0,0 @@
-/*
- * Copyright (c) 1995, 1996 Cygnus Support
- *
- * The authors hereby grant permission to use, copy, modify, distribute,
- * and license this software and its documentation for any purpose, provided
- * that existing copyright notices are retained in all copies and that this
- * notice is included verbatim in any distributions. No written agreement,
- * license, or royalty fee is required for any of the authorized uses.
- * Modifications to this software may be copyrighted by their authors
- * and need not follow the licensing terms described here, provided that
- * the new terms are clearly indicated on the first page of each file where
- * they apply.
- */
-
-/*
- * A debug packet whose contents are <data> looks like:
- *
- * $ <data> # CSUM1 CSUM2
- *
- * <data> must be ASCII alphanumeric and cannot include characters
- * '$' or '#'. If <data> starts with two characters followed by
- * ':', then the existing stubs interpret this as a sequence number.
- *
- * CSUM1 and CSUM2 are ascii hex representation of an 8-bit
- * checksum of <data>, the most significant nibble is sent first.
- * the hex digits 0-9,a-f are used.
- *
- * We respond with:
- *
- * + - if CSUM is correct and ready for next packet
- * - - if CSUM is incorrect
- *
- * <data> is as follows:
- * Most values are encoded in ascii hex digits.
- */
-
-#include "debug.h"
-#include <signal.h>
-
-/*
- * buffers that hold the packets while they're being constructed.
- */
-char packet_in_buf[BUFMAX];
-char packet_out_buf[BUFMAX];
-int packet_index;
-
-/*
- * indicate to caller of mem2hex or hex2mem that there has been an error.
- * 0 means ok, 1 means error
- */
-volatile int mem_err = 0;
-
-/*
- * 1 means print debugging messages from the target, 0 means be quiet. This is
- * changed by gdb_debug().
- */
-int remote_debug = 0;
-
-/*
- * indicate whether the debug vectors ahave been initialized
- * 0 means not yet, 1 means yep, it's ready.
- */
-int initialized = 0;
-
-/*
- * These variables are instantialted in the GDB stub code.
- */
-
-/* this is a list of signal to exception mappings. */
-extern struct trap_info hard_trap_info[];
-
-/* this is a memory fault exception handler, used by mem2hex & hex2mem */
-extern void set_mem_fault_trap();
-
-/*
- * print debugging messages. This uses print, rather than one of the
- * stdio routines, cause if there are stack or memory problems, the
- * stdio routines don't work.
- * params are the debug level, and the string to print
- * it doesn't return anything.
- */
-void
-debuglog(int level, char *msg)
-{
- char *p;
- unsigned char buf[BUFMAX];
- char newmsg[BUFMAX];
- int i;
-
- if (level > remote_debug)
- return;
-
- if ((level <0) || (level > 100)) {
- print ("ERROR: debug print level out of range");
- return;
- }
-
- /* convert some characters so it'll look right in the log */
- p = newmsg;
- for (i = 0 ; msg[i] != '\0'; i++) {
- if (i > BUFMAX)
- print ("\r\nERROR: Debug message too long\r\n");
- switch (msg[i]) {
- case '\n': /* newlines */
- *p++ = '\\';
- *p++ = 'n';
- continue;
- case '\r': /* carriage returns */
- *p++ = '\\';
- *p++ = 'r';
- continue;
- case '\033': /* escape */
- *p++ = '\\';
- *p++ = 'e';
- continue;
- case '\t': /* tab */
- *p++ = '\\';
- *p++ = 't';
- continue;
- case '\b': /* backspace */
- *p++ = '\\';
- *p++ = 'b';
- continue;
- default: /* no change */
- *p++ = msg[i];
- }
-
- if (msg[i] < 26) { /* modify control characters */
- *p++ = '^';
- *p++ = msg[i] + 'A';
- continue;
- }
- if (msg[i] >= 127) { /* modify control characters */
- *p++ = '!';
- *p++ = msg[i] + 'A';
- continue;
- }
- }
- *p = '\0'; /* terminate the string */
- print (newmsg);
- print ("\r\n");
-}
-
-/*
- * convert an ascii hex digit to a number.
- * param is hex digit.
- * returns a decimal digit.
- */
-int
-hex2digit (int digit)
-{
- if (digit == 0)
- return 0;
-
- if (digit >= '0' && digit <= '9')
- return digit - '0';
- if (digit >= 'a' && digit <= 'f')
- return digit - 'a' + 10;
- if (digit >= 'A' && digit <= 'F')
- return digit - 'A' + 10;
-
- /* shouldn't ever get this far */
- return ERROR;
-}
-
-/*
- * convert number NIB to a hex digit.
- * param is a decimal digit.
- * returns a hex digit.
- */
-char
-digit2hex(int digit)
-{
- if (digit < 10)
- return '0' + digit;
- else
- return 'a' + digit - 10;
-}
-
-/*
- * Convert the memory pointed to by mem into hex, placing result in buf.
- * Return a pointer to the last char put in buf (null), in case of mem fault,
- * return 0.
- * If MAY_FAULT is non-zero, then we will handle memory faults by returning
- * a 0, else treat a fault like any other fault in the stub.
- */
-unsigned char *
-mem2hex(unsigned char *mem, unsigned char *buf, int count, int may_fault)
-{
- unsigned char ch;
-
- DEBUG (1, "In mem2hex");
-
- set_mem_fault_trap(MAY_FAULT);
-
- while (count-- > 0) {
- ch = *mem++;
- if (mem_err) {
- DEBUG (1, "memory fault in mem2hex");
- return 0;
- }
- *buf++ = digit2hex(ch >> 4);
- *buf++ = digit2hex(ch & 0xf);
- }
-
- *buf = 0;
-
- set_mem_fault_trap(OK);
-
- return buf;
-}
-
-/*
- * Convert the hex array pointed to by buf into binary to be placed in mem
- * return a pointer to the character AFTER the last byte written
- */
-unsigned char *
-hex2mem(unsigned char *buf, unsigned char *mem, int count, int may_fault)
-{
- int i;
- unsigned char ch;
-
- DEBUG (1, "In hex2mem");
-
- set_mem_fault_trap(may_fault);
-
- for (i=0; i<count; i++) {
- ch = hex2digit(*buf++) << 4;
- ch |= hex2digit(*buf++);
- *mem++ = ch;
- if (mem_err)
- return 0;
- }
-
- set_mem_fault_trap(0);
-
- return mem;
-}
-
-/*
- * while we find nice hex chars, build an int.
- * param is a pointer to the string.
- * returns the int in the param field, and the number of chars processed.
- */
-int
-hex2int (char **ptr, int *intValue)
-{
- int numChars = 0;
- int hexValue;
-
- *intValue = 0;
-
- while (**ptr)
- {
- hexValue = hex2digit(**ptr);
- if (hexValue < 0)
- break;
-
- *intValue = (*intValue << 4) | hexValue;
- numChars ++;
- (*ptr)++;
- }
- return (numChars);
-}
-
-/*
- * Scan for the sequence $<data>#<checksum>
- */
-void
-getpacket(unsigned char *buffer)
-{
- unsigned char checksum;
- unsigned char xmitcsum;
- int i;
- int count;
- unsigned char ch;
-
- do {
- /* wait around for the start character, ignore all other characters */
- while ((ch = (inbyte() & 0x7f)) != '$') ;
-
- checksum = 0;
- xmitcsum = -1;
-
- count = 0;
-
- /* now, read until a # or end of buffer is found */
- while (count < BUFMAX) {
- ch = inbyte() & 0x7f;
- if (ch == '#')
- break;
- checksum = checksum + ch;
- buffer[count] = ch;
- count = count + 1;
- }
-
- if (count >= BUFMAX)
- continue;
-
- buffer[count] = 0;
-
- if (ch == '#') {
- xmitcsum = hex2digit(inbyte() & 0x7f) << 4;
- xmitcsum |= hex2digit(inbyte() & 0x7f);
-#if 1
- /* Humans shouldn't have to figure out checksums to type to it. */
- outbyte ('+');
- return;
-#endif
- if (checksum != xmitcsum)
- outbyte('-'); /* failed checksum */
- else {
- outbyte('+'); /* successful transfer */
- /* if a sequence char is present, reply the sequence ID */
- if (buffer[2] == ':') {
- outbyte(buffer[0]);
- outbyte(buffer[1]);
- /* remove sequence chars from buffer */
- count = strlen(buffer);
- for (i=3; i <= count; i++)
- buffer[i-3] = buffer[i];
- }
- }
- }
- }
- while (checksum != xmitcsum);
-}
-
-/*
- * Send the packet in buffer.
- */
-void
-putpacket(unsigned char *buffer)
-{
- unsigned char checksum;
- int count;
- unsigned char ch;
-
- /* $<packet info>#<checksum>. */
- do {
- outbyte('$');
- checksum = 0;
- count = 0;
-
- while (ch = buffer[count]) {
- if (! outbyte(ch))
- return;
- checksum += ch;
- count += 1;
- }
-
- outbyte('#');
- outbyte(digit2hex(checksum >> 4));
- outbyte(digit2hex(checksum & 0xf));
-
- }
- while ((inbyte() & 0x7f) != '+');
-}
-
-/*
- *
- */
-void
-gdb_event_loop(int sigval, unsigned long *registers)
-{
- int addr;
- int length;
- unsigned char *ptr;
- ptr = packet_out_buf;
-
- DEBUG (1, "In gdb_event_loop");
-
- while (1) {
- packet_out_buf[0] = 0;
-
- getpacket(packet_in_buf);
- ptr = &packet_in_buf[1];
-
- switch (packet_in_buf[0]) {
- case '?': /* get the last known signal */
- gdb_last_signal(sigval);
- break;
-
- case 'd': /* toggle debug messages from the stub */
- gdb_toggle();
- break;
-
- case 'g': /* return the value of the CPU registers */
- target_read_registers(registers);
- break;
-
- case 'G': /* set the value of the CPU registers - return OK */
- target_write_registers(registers);
- break;
-
- case 'm': /* mAA..AA,LLLL Read LLLL bytes at address AA..AA */
- /* Try to read %x,%x. */
- if (hex2int((char **)&ptr, &addr)
- && *ptr++ == ','
- && hex2int((char **)&ptr, &length)) {
- gdb_read_memory(addr, length);
- } else {
- make_return_packet(1);
- }
- break;
-
- case 'M': /* MAA..AA,LLLL: Write LLLL bytes at address AA.AA return OK */
- /* Try to read '%x,%x:'. */
- if (hex2int((char **)&ptr, &addr)
- && *ptr++ == ','
- && hex2int((char **)&ptr, &length)
- && *ptr++ == ':') {
- gdb_write_memory (addr, length, ptr);
- } else {
- make_return_packet(2);
- }
- break;
-
- case 'c': /* cAA..AA Continue at address AA..AA(optional) */
- /* try to read optional parameter, pc unchanged if no parm */
- if (hex2int((char **)&ptr, &addr)) {
- write_pc(registers, addr);
- }
-
- /*
- * we need to flush the instruction cache here, as we may have
- * deposited a breakpoint, and the icache probably has no way of
- * knowing that a data ref to some location may have changed
- * something that is in the instruction cache.
- */
-
- flush_i_cache();
- /* by returning, we pick up execution where we left off */
- return;
-
- /* kill the program */
- case 'k' :
- gdb_kill();
- break;
- case 'r': /* Reset */
- target_reset();
- break;
- } /* switch */
-
- /* reply to the request */
- putpacket(packet_out_buf);
- }
- DEBUG (1, "Leaving handle_exception()");
-}
-
-/* Convert the hardware trap type code to a unix signal number. */
-
-int
-computeSignal(int tt)
-{
- struct trap_info *ht;
-
- for (ht = hard_trap_info; ht->tt && ht->signo; ht++)
- if (ht->tt == tt)
- return ht->signo;
-
- return SIGHUP; /* default for things we don't know about */
-}
-
-/*
- * Set up exception handlers for tracing and breakpoints
- */
-void
-set_debug_traps()
-{
- struct trap_info *ht;
-
- DEBUG (1, "Entering set_debug_traps()");
-
- if (hard_trap_info->tt == 0) {
- print ("ERROR: ARG#$@%^&*!! no hard trap info!!\r\n");
- }
-
- for (ht = hard_trap_info; ht->tt && ht->signo; ht++) {
- exception_handler(ht->tt, (unsigned long)default_trap_hook);
- }
-
- /* In case GDB is started before us, ack any packets (presumably
- "$?#xx") sitting there. */
-
- outbyte ('+');
- initialized = 1;
-
- DEBUG (1, "Leaving set_debug_traps()");
-}
-
-/*
- * make a return packet.
- * param is the value to return.
- * 0 = OK, any other value is converted to a two digit hex number.
- * returns a string or "OK" or "ENN", where NN is the error number. Each N
- * is an ASCII encoded hex digit.
- */
-char *
-make_return_packet(int val)
-{
- if (val == 0) {
- packet_out_buf[0] = 'O';
- packet_out_buf[1] = 'K';
- packet_out_buf[2] = 0;
- } else {
- packet_out_buf[0] = 'E';
- packet_out_buf[1] = digit2hex((val >> 4) & 0xf);
- packet_out_buf[2] = digit2hex(val & 0xf);
- packet_out_buf[3] = 0;
- }
- return(packet_out_buf);
-}
-
-/*
- * g - read registers.
- * no params.
- * returns a vector of words, size is NUM_REGS.
- */
-char *
-gdb_read_registers()
-{
-}
-
-/*
- * G - write registers.
- * param is a vector of words, size is NUM_REGS.
- * returns an OK or an error number.
- */
-char *
-gdb_write_registers(char *regs)
-{
-}
-
-/*
- * m - read memory.
- * params are the address to start the read at and the number of
- * bytes to read.
- * returns a vector of nbytes or an error number.
- * Can be fewer bytes than requested if able to read only part of the
- * data.
- */
-char *
-gdb_read_memory(long addr, int nbytes)
-{
- if (mem2hex((char *)addr, packet_out_buf, nbytes, MAY_FAULT))
- return(packet_out_buf);
- else {
- return(make_return_packet(3));
- }
-}
-
-/*
- * M write memory
- * params are the address to start writing to, the number of
- * bytes to write, and the new values of the bytes.
- * returns an OK or an error number.
- */
-char *
-gdb_write_memory(long addr, int nbytes, char *mem)
-{
- if (hex2mem(mem, (char *)addr, nbytes, MAY_FAULT))
- return(make_return_packet(OK));
- else {
- return(make_return_packet(3));
- }
-}
-
-/*
- * c - continue at address.
- * param is the address to start at, and an optional signal. If
- * sig is zero, then ignore it.
- * returns an OK or an error number.
- */
-char *
-gdb_continue(int sig, long addr)
-{
-}
-
-/*
- * s - step instruction(s)
- * param is the address to start at, and an optional signal. If
- * sig is zero, then ignore it.
- * returns an OK or an error number.
- */
-char *
-gdb_step(int sig, long addr)
-{
-}
-
-/*
- * k - kill program.
- * no params.
- * returns an OK or an error number.
- */
-char *
-gdb_kill()
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-/*
- * ? - last signal.
- * no params.
- * returns the last signal number.
- */
-char *
-gdb_last_signal(int val)
-{
- DEBUG (1, "Entering gdb_last_signal()");
-
- packet_out_buf[0] = 'S';
- packet_out_buf[1] = digit2hex(val >> 4);
- packet_out_buf[2] = digit2hex(val & 0xf);
- packet_out_buf[3] = 0;
-
- DEBUG (1, "Leaving gdb_last_signal()");
- return (packet_out_buf);
-}
-
-/*
- * b - change baud rate.
- * param is the new baudrate
- * returns the baud rate.
- */
-char *
-gdb_baudrate(int baud)
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-/*
- * T - dump state.
- * no params.
- * returns the signal number, the registers, the thread ID, and
- * possible extensions in a vector that looks like:
- * TAAn...:r...;n...:r...;n...:r...; where:
- * AA = signal number
- * n... = register number (hex)
- * r... = register contents
- * n... = `thread'
- * r... = thread process ID. This is a hex integer.
- * n... = other string not starting with valid hex digit.
- * gdb should ignore this n,r pair and go on to
- * the next. This way we can extend the protocol.
- */
-char *
-gdb_dump_state()
-{
-}
-
-/*
- * D - host requests a detach
- * no params.
- * returns either a S, T, W, or X command.
- * returns an OK or an error number.
- */
-char *
-gdb_detach()
-{
-}
-
-/*
- * H - set thread.
- * params are the command to execute and the thread ID.
- * cmd = 'c' for thread used in step and continue;
- * cmd = 'g' for thread used in other operations.
- * tid = -1 for all threads.
- * tid = zero, pick a thread,any thread.
- * returns an OK or an error number.
- */
-char *
-gdb_set_thread(int cmd, int tid)
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-/*
- * p - read one register.
- * param is the register number.
- * returns the register value or ENN.
- */
-char *
-gdb_read_reg(int reg)
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-/*
- * P - write one register.
- * params are the register number, and it's new value.
- * returns the register value or ENN.
- */
-char *
-gdb_write_reg(int reg, long val)
-{
- /* generically, we can't do anything for this command */
-
- return(make_return_packet(OK));
-}
-
-/*
- * W - process exited.
- * no params.
- * returns the exit status.
- */
-char *
-gdb_exited()
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-/*
- * X - process terminated.
- * no params.
- * returns the last signal.
- */
-char *
-gdb_terminated()
-{
-}
-
-/*
- * O - hex encoding.
- * params are a vector of bytes, and the number of bytes to encode.
- * returns a vector of ASCII encoded hex numbers.
- */
-char *
-gdb_hex(char *str, int nbytes)
-{
-}
-
-/*
- * A - tread alive request.
- * param is the thread ID.
- * returns an OK or an error number.
- */
-char *
-gdb_thread_alive(int tid)
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-/*
- * ! - extended protocol.
- * no params.
- * returns an OK or an error number.
- */
-char *
-gdb_extended()
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-/*
- * d - toggle gdb stub diagnostics.
- * no params.
- * returns an OK or an error number.
- */
-char *
-gdb_debug()
-{
- if (remote_debug > 0)
- remote_debug = 0;
- else
- remote_debug = 1;
-
- return(make_return_packet(OK));
-}
-
-/*
- * d - toggle gdb stub.
- * no params.
- * returns an OK or an error number.
- */
-char *
-gdb_toggle()
-{
- static int level = 0;
-
- if (remote_debug) {
- level = remote_debug;
- remote_debug = 0;
- } else {
- remote_debug = level;
- }
-
- return(make_return_packet(OK));
-}
-
-/*
- * r - reset target
- * no params.
- * returns an OK or an error number.
- */
-char *
-gdb_reset()
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-/*
- * t - search backwards.
- * params are the address to start searching from, a pattern to match, and
- * the mask to use.
- * FIXME: not entirely sure what this is supposed to return.
- */
-char *
-gdb_search(long addr, long pat, long mask)
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-/*
- * q - general get query.
- * param is a string, that's the query to be executed.
- * FIXME: not entirely sure what this is supposed to return.
- */
-char *
-gdb_get_query(char *query)
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-/*
- * Q - general set query
- * param is a string, that's the query to be executed.
- * FIXME: not entirely sure what this means.
- * returns an OK or an error number.
- */
-char *
-gdb_set(char *query)
-{
- /* generically, we can't do anything for this command */
- return(make_return_packet(OK));
-}
-
-