diff options
Diffstat (limited to 'gdb/remote-utils.c')
-rw-r--r-- | gdb/remote-utils.c | 610 |
1 files changed, 0 insertions, 610 deletions
diff --git a/gdb/remote-utils.c b/gdb/remote-utils.c deleted file mode 100644 index 4dd6626..0000000 --- a/gdb/remote-utils.c +++ /dev/null @@ -1,610 +0,0 @@ -/* Generic support for remote debugging interfaces. - - Copyright (C) 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2007 - Free Software Foundation, Inc. - - This file is part of GDB. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* This file actually contains two distinct logical "packages". They - are packaged together in this one file because they are typically - used together. - - The first package is an addition to the serial package. The - addition provides reading and writing with debugging output and - timeouts based on user settable variables. These routines are - intended to support serial port based remote backends. These - functions are prefixed with sr_. - - The second package is a collection of more or less generic - functions for use by remote backends. They support user settable - variables for debugging, retries, and the like. - - Todo: - - * a pass through mode a la kermit or telnet. - * autobaud. - * ask remote to change his baud rate. - */ - -#include <ctype.h> - -#include "defs.h" -#include "gdb_string.h" -#include "gdbcmd.h" -#include "target.h" -#include "serial.h" -#include "gdbcore.h" /* for exec_bfd */ -#include "inferior.h" /* for generic_mourn_inferior */ -#include "remote-utils.h" -#include "regcache.h" - - -void _initialize_sr_support (void); - -struct _sr_settings sr_settings = -{ - 4, /* timeout: - remote-hms.c had 2 - remote-bug.c had "with a timeout of 2, we time out waiting for - the prompt after an s-record dump." - - remote.c had (2): This was 5 seconds, which is a long time to - sit and wait. Unless this is going though some terminal server - or multiplexer or other form of hairy serial connection, I - would think 2 seconds would be plenty. - */ - - 10, /* retries */ - NULL, /* device */ - NULL, /* descriptor */ -}; - -struct gr_settings *gr_settings = NULL; - -static void usage (char *, char *); -static void sr_com (char *, int); - -static void -usage (char *proto, char *junk) -{ - if (junk != NULL) - fprintf_unfiltered (gdb_stderr, "Unrecognized arguments: `%s'.\n", junk); - - error (_("Usage: target %s [DEVICE [SPEED [DEBUG]]]\n\ -where DEVICE is the name of a device or HOST:PORT"), proto); - - return; -} - -#define CHECKDONE(p, q) \ -{ \ - if (q == p) \ - { \ - if (*p == '\0') \ - return; \ - else \ - usage(proto, p); \ - } \ -} - -void -sr_scan_args (char *proto, char *args) -{ - int n; - char *p, *q; - - /* if no args, then nothing to do. */ - if (args == NULL || *args == '\0') - return; - - /* scan off white space. */ - for (p = args; isspace (*p); ++p);; - - /* find end of device name. */ - for (q = p; *q != '\0' && !isspace (*q); ++q);; - - /* check for missing or empty device name. */ - CHECKDONE (p, q); - sr_set_device (savestring (p, q - p)); - - /* look for baud rate. */ - n = strtol (q, &p, 10); - - /* check for missing or empty baud rate. */ - CHECKDONE (p, q); - baud_rate = n; - - /* look for debug value. */ - n = strtol (p, &q, 10); - - /* check for missing or empty debug value. */ - CHECKDONE (p, q); - sr_set_debug (n); - - /* scan off remaining white space. */ - for (p = q; isspace (*p); ++p);; - - /* if not end of string, then there's unrecognized junk. */ - if (*p != '\0') - usage (proto, p); - - return; -} - -void -gr_generic_checkin (void) -{ - sr_write_cr (""); - gr_expect_prompt (); -} - -void -gr_open (char *args, int from_tty, struct gr_settings *gr) -{ - target_preopen (from_tty); - sr_scan_args (gr->ops->to_shortname, args); - unpush_target (gr->ops); - - gr_settings = gr; - - if (sr_get_desc () != NULL) - gr_close (0); - - /* If no args are specified, then we use the device specified by a - previous command or "set remotedevice". But if there is no - device, better stop now, not dump core. */ - - if (sr_get_device () == NULL) - usage (gr->ops->to_shortname, NULL); - - sr_set_desc (serial_open (sr_get_device ())); - if (!sr_get_desc ()) - perror_with_name ((char *) sr_get_device ()); - - if (baud_rate != -1) - { - if (serial_setbaudrate (sr_get_desc (), baud_rate) != 0) - { - serial_close (sr_get_desc ()); - perror_with_name (sr_get_device ()); - } - } - - serial_raw (sr_get_desc ()); - - /* If there is something sitting in the buffer we might take it as a - response to a command, which would be bad. */ - serial_flush_input (sr_get_desc ()); - - /* default retries */ - if (sr_get_retries () == 0) - sr_set_retries (1); - - /* default clear breakpoint function */ - if (gr_settings->clear_all_breakpoints == NULL) - gr_settings->clear_all_breakpoints = remove_breakpoints; - - if (from_tty) - { - printf_filtered ("Remote debugging using `%s'", sr_get_device ()); - if (baud_rate != -1) - printf_filtered (" at baud rate of %d", - baud_rate); - printf_filtered ("\n"); - } - - push_target (gr->ops); - gr_checkin (); - gr_clear_all_breakpoints (); - return; -} - -/* Read a character from the remote system masking it down to 7 bits - and doing all the fancy timeout stuff. */ - -int -sr_readchar (void) -{ - int buf; - - buf = serial_readchar (sr_get_desc (), sr_get_timeout ()); - - if (buf == SERIAL_TIMEOUT) - error (_("Timeout reading from remote system.")); - - if (sr_get_debug () > 0) - printf_unfiltered ("%c", buf); - - return buf & 0x7f; -} - -int -sr_pollchar (void) -{ - int buf; - - buf = serial_readchar (sr_get_desc (), 0); - if (buf == SERIAL_TIMEOUT) - buf = 0; - if (sr_get_debug () > 0) - { - if (buf) - printf_unfiltered ("%c", buf); - else - printf_unfiltered ("<empty character poll>"); - } - - return buf & 0x7f; -} - -/* Keep discarding input from the remote system, until STRING is found. - Let the user break out immediately. */ -void -sr_expect (char *string) -{ - char *p = string; - - immediate_quit++; - while (1) - { - if (sr_readchar () == *p) - { - p++; - if (*p == '\0') - { - immediate_quit--; - return; - } - } - else - p = string; - } -} - -void -sr_write (char *a, int l) -{ - int i; - - if (serial_write (sr_get_desc (), a, l) != 0) - perror_with_name (_("sr_write: Error writing to remote")); - - if (sr_get_debug () > 0) - for (i = 0; i < l; i++) - printf_unfiltered ("%c", a[i]); - - return; -} - -void -sr_write_cr (char *s) -{ - sr_write (s, strlen (s)); - sr_write ("\r", 1); - return; -} - -int -sr_timed_read (char *buf, int n) -{ - int i; - char c; - - i = 0; - while (i < n) - { - c = sr_readchar (); - - if (c == 0) - return i; - buf[i] = c; - i++; - - } - return i; -} - -/* Get a hex digit from the remote system & return its value. If - ignore_space is nonzero, ignore spaces (not newline, tab, etc). */ - -int -sr_get_hex_digit (int ignore_space) -{ - int ch; - - while (1) - { - ch = sr_readchar (); - if (ch >= '0' && ch <= '9') - return ch - '0'; - else if (ch >= 'A' && ch <= 'F') - return ch - 'A' + 10; - else if (ch >= 'a' && ch <= 'f') - return ch - 'a' + 10; - else if (ch != ' ' || !ignore_space) - { - gr_expect_prompt (); - error (_("Invalid hex digit from remote system.")); - } - } -} - -/* Get a byte from the remote and put it in *BYT. Accept any number - leading spaces. */ -void -sr_get_hex_byte (char *byt) -{ - int val; - - val = sr_get_hex_digit (1) << 4; - val |= sr_get_hex_digit (0); - *byt = val; -} - -/* Read a 32-bit hex word from the remote, preceded by a space */ -long -sr_get_hex_word (void) -{ - long val; - int j; - - val = 0; - for (j = 0; j < 8; j++) - val = (val << 4) + sr_get_hex_digit (j == 0); - return val; -} - -/* Put a command string, in args, out to the remote. The remote is assumed to - be in raw mode, all writing/reading done through desc. - Ouput from the remote is placed on the users terminal until the - prompt from the remote is seen. - FIXME: Can't handle commands that take input. */ - -static void -sr_com (char *args, int fromtty) -{ - sr_check_open (); - - if (!args) - return; - - /* Clear all input so only command relative output is displayed */ - - sr_write_cr (args); - sr_write ("\030", 1); - registers_changed (); - gr_expect_prompt (); -} - -void -gr_close (int quitting) -{ - gr_clear_all_breakpoints (); - - if (sr_is_open ()) - { - serial_close (sr_get_desc ()); - sr_set_desc (NULL); - } - - return; -} - -/* gr_detach() - takes a program previously attached to and detaches it. - We better not have left any breakpoints - in the program or it'll die when it hits one. - Close the open connection to the remote debugger. - Use this when you want to detach and do something else - with your gdb. */ - -void -gr_detach (char *args, int from_tty) -{ - if (args) - error (_("Argument given to \"detach\" when remotely debugging.")); - - if (sr_is_open ()) - gr_clear_all_breakpoints (); - - pop_target (); - if (from_tty) - puts_filtered ("Ending remote debugging.\n"); - - return; -} - -void -gr_files_info (struct target_ops *ops) -{ -#ifdef __GO32__ - printf_filtered ("\tAttached to DOS asynctsr\n"); -#else - printf_filtered ("\tAttached to %s", sr_get_device ()); - if (baud_rate != -1) - printf_filtered ("at %d baud", baud_rate); - printf_filtered ("\n"); -#endif - - if (exec_bfd) - { - printf_filtered ("\tand running program %s\n", - bfd_get_filename (exec_bfd)); - } - printf_filtered ("\tusing the %s protocol.\n", ops->to_shortname); -} - -void -gr_mourn (void) -{ - gr_clear_all_breakpoints (); - unpush_target (gr_get_ops ()); - generic_mourn_inferior (); -} - -void -gr_kill (void) -{ - return; -} - -/* This is called not only when we first attach, but also when the - user types "run" after having attached. */ -void -gr_create_inferior (char *execfile, char *args, char **env) -{ - int entry_pt; - - if (args && *args) - error (_("Can't pass arguments to remote process.")); - - if (execfile == 0 || exec_bfd == 0) - error (_("No executable file specified")); - - entry_pt = (int) bfd_get_start_address (exec_bfd); - sr_check_open (); - - gr_kill (); - gr_clear_all_breakpoints (); - - init_wait_for_inferior (); - gr_checkin (); - - insert_breakpoints (); /* Needed to get correct instruction in cache */ - proceed (entry_pt, -1, 0); -} - -/* Given a null terminated list of strings LIST, read the input until we find one of - them. Return the index of the string found or -1 on error. '?' means match - any single character. Note that with the algorithm we use, the initial - character of the string cannot recur in the string, or we will not find some - cases of the string in the input. If PASSTHROUGH is non-zero, then - pass non-matching data on. */ - -int -gr_multi_scan (char *list[], int passthrough) -{ - char *swallowed = NULL; /* holding area */ - char *swallowed_p = swallowed; /* Current position in swallowed. */ - int ch; - int ch_handled; - int i; - int string_count; - int max_length; - char **plist; - - /* Look through the strings. Count them. Find the largest one so we can - allocate a holding area. */ - - for (max_length = string_count = i = 0; - list[i] != NULL; - ++i, ++string_count) - { - int length = strlen (list[i]); - - if (length > max_length) - max_length = length; - } - - /* if we have no strings, then something is wrong. */ - if (string_count == 0) - return (-1); - - /* otherwise, we will need a holding area big enough to hold almost two - copies of our largest string. */ - swallowed_p = swallowed = alloca (max_length << 1); - - /* and a list of pointers to current scan points. */ - plist = (char **) alloca (string_count * sizeof (*plist)); - - /* and initialize */ - for (i = 0; i < string_count; ++i) - plist[i] = list[i]; - - for (ch = sr_readchar (); /* loop forever */ ; ch = sr_readchar ()) - { - QUIT; /* Let user quit and leave process running */ - ch_handled = 0; - - for (i = 0; i < string_count; ++i) - { - if (ch == *plist[i] || *plist[i] == '?') - { - ++plist[i]; - if (*plist[i] == '\0') - return (i); - - if (!ch_handled) - *swallowed_p++ = ch; - - ch_handled = 1; - } - else - plist[i] = list[i]; - } - - if (!ch_handled) - { - char *p; - - /* Print out any characters which have been swallowed. */ - if (passthrough) - { - for (p = swallowed; p < swallowed_p; ++p) - fputc_unfiltered (*p, gdb_stdout); - - fputc_unfiltered (ch, gdb_stdout); - } - - swallowed_p = swallowed; - } - } -#if 0 - /* Never reached. */ - return (-1); -#endif -} - -/* Get ready to modify the registers array. On machines which store - individual registers, this doesn't need to do anything. On machines - which store all the registers in one fell swoop, this makes sure - that registers contains all the registers from the program being - debugged. */ - -void -gr_prepare_to_store (void) -{ - /* Do nothing, since we assume we can store individual regs */ -} - -void -_initialize_sr_support (void) -{ - /* FIXME-now: if target is open... */ - add_setshow_filename_cmd ("remotedevice", no_class, &sr_settings.device, _("\ -Set device for remote serial I/O."), _("\ -Show device for remote serial I/O."), _("\ -This device is used as the serial port when debugging using remote targets."), - NULL, - NULL, /* FIXME: i18n: */ - &setlist, &showlist); - - add_com ("remote", class_obscure, sr_com, - _("Send a command to the remote monitor.")); - -} |