diff options
Diffstat (limited to 'gnu/usr.bin/gdb/remote.c')
-rw-r--r-- | gnu/usr.bin/gdb/remote.c | 626 |
1 files changed, 0 insertions, 626 deletions
diff --git a/gnu/usr.bin/gdb/remote.c b/gnu/usr.bin/gdb/remote.c deleted file mode 100644 index 59658a88673d..000000000000 --- a/gnu/usr.bin/gdb/remote.c +++ /dev/null @@ -1,626 +0,0 @@ -/*- - * Copyright (c) 1991 The Regents of the University of California. - * All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Van Jacobson and Steven McCanne of Lawrence Berkeley Laboratory. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $Header: /home/cvs/386BSD/src/usr.bin/gdb/remote.c,v 1.1.1.1 1993/06/12 14:52:22 rgrimes Exp $; - */ - -#ifndef lint -static char sccsid[] = "@(#)remote.c 6.5 (Berkeley) 5/8/91"; -#endif /* not lint */ - -#include "param.h" - -#include <stdio.h> -#include <varargs.h> - -#include <signal.h> -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/file.h> - -#include "defs.h" -#include "frame.h" -#include "inferior.h" -#include "wait.h" - -#include "kgdb_proto.h" - -static FILE *kiodebug; -static int icache = 1; -extern int kernel_debugging; - -static int remote_cache_valid; -static int remote_instub; - -static void remote_signal(); -static void remote_debug(); -static void print_msg(); - -static int remote_mtu; -static int (*send_msg)(); -static int (*recv_msg)(); -static void (*closelink)(); - -static u_char *inbuffer; -static u_char *outbuffer; - -/* - * Statistics. - */ -static int remote_ierrs; -static int remote_oerrs; -static int remote_seqerrs; -static int remote_spurious; - -#define PUTCMD(cmd) m_xchg(cmd, (u_char *)0, 0, (u_char *)0, (int *)0) - -/* - * Send an outbound message to the remote machine and read the reply. - * Either or both message buffers may be NULL. - */ -static int -m_xchg(type, out, outlen, in, inlen) - int type; - u_char *out; - int outlen; - u_char *in; - int *inlen; -{ - register int err, (*send)() = send_msg, (*recv)() = recv_msg; - int ack; - static int seqbit = 0; - - if (!remote_instub) { - remote_instub = 1; - PUTCMD(KGDB_EXEC); - } - - seqbit ^= KGDB_SEQ; - while (1) { - err = (*send)(type | seqbit, out, outlen); - if (err) { - ++remote_oerrs; - if (kiodebug) - remote_debug("send error %d\n", err); - } - if (kiodebug) - print_msg(type | seqbit, out, outlen, 'O'); - - recv: - err = (*recv)(&ack, in, inlen); - if (err) { - ++remote_ierrs; - if (kiodebug) - remote_debug("recv error %d\n", err); - remote_cache_valid = 0; - } else if (kiodebug) - print_msg(ack, in, inlen ? *inlen : 0, 'I'); - - if (err) - continue; - - if ((ack & KGDB_ACK) == 0 || KGDB_CMD(ack) != KGDB_CMD(type)) { - ++remote_spurious; - continue; - } - if ((ack & KGDB_SEQ) ^ seqbit) { - ++remote_seqerrs; - goto recv; - } - return ack; - } -} - -/* - * Wait for the specified message type. Discard anything else. - * (this is used by 'remote-signal' to help us resync with other side.) - */ -static void -m_recv(type, in, inlen) - int type; - u_char *in; - int *inlen; -{ - int reply, err; - - while (1) { - err = (*recv_msg)(&reply, in, inlen); - if (err) { - ++remote_ierrs; - if (kiodebug) - remote_debug("recv error %d\n", err); - } else if (kiodebug) - print_msg(reply, in, inlen ? *inlen : 0, 'I'); - - if (KGDB_CMD(reply) == type) - return; - ++remote_spurious; - } -} - -/* - * Send a message. Do not wait for *any* response from the other side. - * Some other thread of control will pick up the ack that will be generated. - */ -static void -m_send(type, buf, len) - int type; - u_char *buf; - int len; -{ - int err; - - if (!remote_instub) { - remote_instub = 1; - PUTCMD(KGDB_EXEC); - } - - err = (*send_msg)(type, buf, len); - if (err) { - ++remote_ierrs; - if (kiodebug) - remote_debug("[send error %d] ", err); - } - if (kiodebug) - print_msg(type, buf, len, 'O'); -} - -/* - * Open a connection to a remote debugger. - * NAME is the filename used for communication. - */ -void -remote_open(name, from_tty) - char *name; - int from_tty; -{ - int bufsize; - - remote_debugging = 0; - if (sl_open(name, &send_msg, &recv_msg, &closelink, &remote_mtu, - &bufsize)) - return; - if (from_tty) - printf("Remote debugging using %s\n", name); - remote_debugging = 1; - - remote_cache_valid = 0; - - inbuffer = (u_char *)malloc(bufsize); - outbuffer = (u_char *)malloc(bufsize); - - remote_signal(); - - remote_ierrs = 0; - remote_oerrs = 0; - remote_spurious = 0; -} - -/* - * Close the open connection to the remote debugger. Use this when you want - * to detach and do something else with your gdb. - */ -void -remote_close(from_tty) - int from_tty; -{ - if (!remote_debugging) - error("remote debugging not enabled"); - - remote_debugging = 0; - /* - * Take remote machine out of debug mode. - */ - (void)PUTCMD(KGDB_KILL); - (*closelink)(); - if (from_tty) - printf("Ending remote debugging\n"); - - free((char *)inbuffer); - free((char *)outbuffer); -} - -/* - * Tell the remote machine to resume. - */ -int -remote_resume(step, signal) - int step, signal; -{ - if (!step) { - (void)PUTCMD(KGDB_CONT); - remote_instub = 0; - } else { -#ifdef NO_SINGLE_STEP - single_step(0); -#else - (void)PUTCMD(KGDB_STEP); -#endif - } -} - -/* - * Wait until the remote machine stops, then return, storing status in STATUS - * just as `wait' would. - */ -int -remote_wait(status) - WAITTYPE *status; -{ - int len; - - WSETEXIT((*status), 0); - /* - * When the machine stops, it will send us a KGDB_SIGNAL message, - * so we wait for one of these. - */ - m_recv(KGDB_SIGNAL, inbuffer, &len); - WSETSTOP((*status), inbuffer[0]); -} - -/* - * Register context as of last remote_fetch_registers(). - */ -static char reg_cache[REGISTER_BYTES]; - -/* - * Read the remote registers into the block REGS. - */ -void -remote_fetch_registers(regs) - char *regs; -{ - int regno, len, rlen, ack; - u_char *cp, *ep; - - regno = -1; - do { - outbuffer[0] = regno + 1; - ack = m_xchg(remote_cache_valid ? - KGDB_REG_R|KGDB_DELTA : KGDB_REG_R, - outbuffer, 1, inbuffer, &len); - cp = inbuffer; - ep = cp + len; - while (cp < ep) { - regno = *cp++; - rlen = REGISTER_RAW_SIZE(regno); - bcopy((char *)cp, - ®_cache[REGISTER_BYTE(regno)], rlen); - cp += rlen; - } - } while (ack & KGDB_MORE); - - remote_cache_valid = 1; - bcopy(reg_cache, regs, REGISTER_BYTES); -} - -/* - * Store the remote registers from the contents of the block REGS. - */ -void -remote_store_registers(regs) - char *regs; -{ - u_char *cp, *ep; - int regno, off, rlen; - - cp = outbuffer; - ep = cp + remote_mtu; - - for (regno = 0; regno < NUM_REGS; ++regno) { - off = REGISTER_BYTE(regno); - rlen = REGISTER_RAW_SIZE(regno); - if (!remote_cache_valid || - bcmp(®s[off], ®_cache[off], rlen) != 0) { - if (cp + rlen + 1 >= ep) { - (void)m_xchg(KGDB_REG_W, - outbuffer, cp - outbuffer, - (u_char *)0, (int *)0); - cp = outbuffer; - } - *cp++ = regno; - bcopy(®s[off], cp, rlen); - cp += rlen; - } - } - if (cp != outbuffer) - (void)m_xchg(KGDB_REG_W, outbuffer, cp - outbuffer, - (u_char *)0, (int *)0); - bcopy(regs, reg_cache, REGISTER_BYTES); -} - -/* - * Store a chunk of memory into the remote host. - * 'remote_addr' is the address in the remote memory space. - * 'cp' is the address of the buffer in our space, and 'len' is - * the number of bytes. Returns an errno status. - */ -int -remote_write_inferior_memory(remote_addr, cp, len) - CORE_ADDR remote_addr; - u_char *cp; - int len; -{ - int cnt; - - while (len > 0) { - cnt = min(len, remote_mtu - 4); - bcopy((char *)&remote_addr, outbuffer, 4); - bcopy(cp, outbuffer + 4, cnt); - (void)m_xchg(KGDB_MEM_W, outbuffer, cnt + 4, inbuffer, &len); - - if (inbuffer[0]) - return inbuffer[0]; - - remote_addr += cnt; - cp += cnt; - len -= cnt; - } - return 0; -} - -/* - * Read memory data directly from the remote machine. - * 'remote_addr' is the address in the remote memory space. - * 'cp' is the address of the buffer in our space, and 'len' is - * the number of bytes. Returns an errno status. - */ -static int -remote_read_memory(remote_addr, cp, len) - CORE_ADDR remote_addr; - u_char *cp; - int len; -{ - int cnt, inlen; - - while (len > 0) { - cnt = min(len, remote_mtu - 1); - outbuffer[0] = cnt; - bcopy((char *)&remote_addr, (char *)&outbuffer[1], 4); - - (void)m_xchg(KGDB_MEM_R, outbuffer, 5, inbuffer, &inlen); - - if (inbuffer[0] != 0) - return inbuffer[0]; - - if (cnt != inlen - 1) - /* XXX */ - error("remote_read_memory() request botched"); - - bcopy((char *)&inbuffer[1], (char *)cp, cnt); - - remote_addr += cnt; - cp += cnt; - len -= cnt; - } - return 0; -} - -int -remote_read_inferior_memory(remote_addr, cp, len) - CORE_ADDR remote_addr; - char *cp; - int len; -{ - int stat = 0; - - if (icache) { - extern CORE_ADDR text_start, text_end; - CORE_ADDR xferend = remote_addr + len; - - if (remote_addr < text_end && text_start < xferend) { - /* - * at least part of this xfer is in the text - * space -- xfer the overlap from the exec file. - */ - if (remote_addr >= text_start && xferend < text_end) - return (xfer_core_file(remote_addr, cp, len)); - if (remote_addr >= text_start) { - int i = text_end - remote_addr; - - if (stat = xfer_core_file(remote_addr, cp, i)) - return (stat); - remote_addr += i; - cp += i; - len -= i; - } else if (xferend <= text_end) { - int i = xferend - text_start; - - len = text_start - remote_addr; - if (stat = xfer_core_file(text_start, - cp + len, i)) - return (stat); - } - } - } - return remote_read_memory(remote_addr, cp, len); -} - -/* - * Signal the remote machine. The remote end might be idle or it might - * already be in debug mode -- we need to handle both case. Thus, we use - * the framing character as the wakeup byte, and send a SIGNAL packet. - * If the remote host is idle, the framing character will wake it up. - * If it is in the kgdb stub, then we will get a SIGNAL reply. - */ -static void -remote_signal() -{ - if (!remote_debugging) - printf("Remote debugging not enabled.\n"); - else { - remote_instub = 0; - m_send(KGDB_SIGNAL, (u_char *)0, 0); - } -} - -static void -remote_signal_command() -{ - extern int stop_after_attach; - - if (!remote_debugging) - error("Not debugging remote."); - remote_cache_valid = 0; - remote_signal(); - restart_remote(); -} - -/* - * Print a message for debugging. - */ -static void -print_msg(type, buf, len, dir) - int type; - u_char *buf; - int len; - int dir; -{ - int i; - char *s; - - switch (KGDB_CMD(type)) { - case KGDB_MEM_R: s = "memr"; break; - case KGDB_MEM_W: s = "memw"; break; - case KGDB_REG_R: s = "regr"; break; - case KGDB_REG_W: s = "regw"; break; - case KGDB_CONT: s = "cont"; break; - case KGDB_STEP: s = "step"; break; - case KGDB_KILL: s = "kill"; break; - case KGDB_SIGNAL: s = "sig "; break; - case KGDB_EXEC: s = "exec"; break; - default: s = "unk "; break; - } - remote_debug("%c %c%c%c%c %s (%02x): ", dir, - (type & KGDB_ACK) ? 'A' : '.', - (type & KGDB_DELTA) ? 'D' : '.', - (type & KGDB_MORE) ? 'M' : '.', - (type & KGDB_SEQ) ? '-' : '+', - s, type); - if (buf) - for (i = 0; i < len; ++i) - remote_debug("%02x", buf[i]); - remote_debug("\n"); -} - -static void -set_remote_text_refs_command(arg, from_tty) - char *arg; - int from_tty; -{ - icache = !parse_binary_operation("set remote-text-refs", arg); -} - -static void -remote_debug_command(arg, from_tty) - char *arg; - int from_tty; -{ - char *name; - - if (kiodebug != 0 && kiodebug != stderr) - (void)fclose(kiodebug); - - if (arg == 0) { - kiodebug = 0; - printf("Remote debugging off.\n"); - return; - } - if (arg[0] == '-') { - kiodebug = stderr; - name = "stderr"; - } else { - kiodebug = fopen(arg, "w"); - if (kiodebug == 0) { - printf("Cannot open '%s'.\n", arg); - return; - } - name = arg; - } - printf("Remote debugging output routed to %s.\n", name); -} - -/* ARGSUSED */ -static void -remote_info(arg, from_tty) - char *arg; - int from_tty; -{ - printf("Using %s for text references.\n", - icache? "local executable" : "remote"); - printf("Protocol debugging is %s.\n", kiodebug? "on" : "off"); - printf("%d spurious input messages.\n", remote_spurious); - printf("%d input errors; %d output errors; %d sequence errors.\n", - remote_ierrs, remote_oerrs, remote_seqerrs); -} - -/* VARARGS */ -static void -remote_debug(va_alist) - va_dcl -{ - register char *cp; - va_list ap; - - va_start(ap); - cp = va_arg(ap, char *); - (void)vfprintf(kiodebug, cp, ap); - va_end(ap); - fflush(kiodebug); -} - -extern struct cmd_list_element *setlist; - -void -_initialize_remote() -{ - add_com("remote-signal", class_run, remote_signal_command, - "If remote debugging, send interrupt signal to remote."); - add_cmd("remote-text-refs", class_support, - set_remote_text_refs_command, -"Enable/disable use of local executable for text segment references.\n\ -If on, all memory read/writes go to remote.\n\ -If off, text segment reads use the local executable.", - &setlist); - - add_com("remote-debug", class_run, remote_debug_command, -"With a file name argument, enables output of remote protocol debugging\n\ -messages to said file. If file is `-', stderr is used.\n\ -With no argument, remote debugging is disabled."); - - add_info("remote", remote_info, - "Show current settings of remote debugging options."); -} - |