aboutsummaryrefslogtreecommitdiff
path: root/gnu/usr.bin/gdb/remote.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/gdb/remote.c')
-rw-r--r--gnu/usr.bin/gdb/remote.c626
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,
- &reg_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(&regs[off], &reg_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(&regs[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.");
-}
-