119370Spst/* Generic support for remote debugging interfaces. 219370Spst 398944Sobrien Copyright 1993, 1994, 1995, 1996, 1998, 2000, 2001 498944Sobrien Free Software Foundation, Inc. 519370Spst 698944Sobrien This file is part of GDB. 719370Spst 898944Sobrien This program is free software; you can redistribute it and/or modify 998944Sobrien it under the terms of the GNU General Public License as published by 1098944Sobrien the Free Software Foundation; either version 2 of the License, or 1198944Sobrien (at your option) any later version. 1219370Spst 1398944Sobrien This program is distributed in the hope that it will be useful, 1498944Sobrien but WITHOUT ANY WARRANTY; without even the implied warranty of 1598944Sobrien MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1698944Sobrien GNU General Public License for more details. 1719370Spst 1898944Sobrien You should have received a copy of the GNU General Public License 1998944Sobrien along with this program; if not, write to the Free Software 2098944Sobrien Foundation, Inc., 59 Temple Place - Suite 330, 2198944Sobrien Boston, MA 02111-1307, USA. */ 2219370Spst 2319370Spst/* This file actually contains two distinct logical "packages". They 2498944Sobrien are packaged together in this one file because they are typically 2598944Sobrien used together. 2619370Spst 2798944Sobrien The first package is an addition to the serial package. The 2898944Sobrien addition provides reading and writing with debugging output and 2998944Sobrien timeouts based on user settable variables. These routines are 3098944Sobrien intended to support serial port based remote backends. These 3198944Sobrien functions are prefixed with sr_. 3219370Spst 3398944Sobrien The second package is a collection of more or less generic 3498944Sobrien functions for use by remote backends. They support user settable 3598944Sobrien variables for debugging, retries, and the like. 3619370Spst 3719370Spst Todo: 3819370Spst 3919370Spst * a pass through mode a la kermit or telnet. 4019370Spst * autobaud. 4119370Spst * ask remote to change his baud rate. 4298944Sobrien */ 4319370Spst 4419370Spst#include <ctype.h> 4519370Spst 4619370Spst#include "defs.h" 4719370Spst#include "gdb_string.h" 4819370Spst#include "gdbcmd.h" 4919370Spst#include "target.h" 5019370Spst#include "serial.h" 5198944Sobrien#include "gdbcore.h" /* for exec_bfd */ 5298944Sobrien#include "inferior.h" /* for generic_mourn_inferior */ 5319370Spst#include "remote-utils.h" 5498944Sobrien#include "regcache.h" 5519370Spst 5646283Sdfr 5798944Sobrienvoid _initialize_sr_support (void); 5846283Sdfr 5998944Sobrienstruct _sr_settings sr_settings = 6098944Sobrien{ 6198944Sobrien 4, /* timeout: 6298944Sobrien remote-hms.c had 2 6398944Sobrien remote-bug.c had "with a timeout of 2, we time out waiting for 6498944Sobrien the prompt after an s-record dump." 6519370Spst 6698944Sobrien remote.c had (2): This was 5 seconds, which is a long time to 6798944Sobrien sit and wait. Unless this is going though some terminal server 6898944Sobrien or multiplexer or other form of hairy serial connection, I 6998944Sobrien would think 2 seconds would be plenty. 7098944Sobrien */ 7119370Spst 7298944Sobrien 10, /* retries */ 7398944Sobrien NULL, /* device */ 7498944Sobrien NULL, /* descriptor */ 7519370Spst}; 7619370Spst 7719370Spststruct gr_settings *gr_settings = NULL; 7819370Spst 7998944Sobrienstatic void usage (char *, char *); 8098944Sobrienstatic void sr_com (char *, int); 8146283Sdfr 8219370Spststatic void 8398944Sobrienusage (char *proto, char *junk) 8419370Spst{ 8519370Spst if (junk != NULL) 8698944Sobrien fprintf_unfiltered (gdb_stderr, "Unrecognized arguments: `%s'.\n", junk); 8719370Spst 8819370Spst error ("Usage: target %s [DEVICE [SPEED [DEBUG]]]\n\ 89130803Smarcelwhere DEVICE is the name of a device or HOST:PORT", proto); 9019370Spst 9119370Spst return; 9219370Spst} 9319370Spst 9419370Spst#define CHECKDONE(p, q) \ 9519370Spst{ \ 9619370Spst if (q == p) \ 9719370Spst { \ 9819370Spst if (*p == '\0') \ 9919370Spst return; \ 10019370Spst else \ 10119370Spst usage(proto, p); \ 10219370Spst } \ 10319370Spst} 10419370Spst 10519370Spstvoid 10698944Sobriensr_scan_args (char *proto, char *args) 10719370Spst{ 10819370Spst int n; 10919370Spst char *p, *q; 11019370Spst 11119370Spst /* if no args, then nothing to do. */ 11219370Spst if (args == NULL || *args == '\0') 11319370Spst return; 11419370Spst 11519370Spst /* scan off white space. */ 11698944Sobrien for (p = args; isspace (*p); ++p);; 11719370Spst 11819370Spst /* find end of device name. */ 11998944Sobrien for (q = p; *q != '\0' && !isspace (*q); ++q);; 12019370Spst 12119370Spst /* check for missing or empty device name. */ 12298944Sobrien CHECKDONE (p, q); 12398944Sobrien sr_set_device (savestring (p, q - p)); 12419370Spst 12519370Spst /* look for baud rate. */ 12698944Sobrien n = strtol (q, &p, 10); 12719370Spst 12819370Spst /* check for missing or empty baud rate. */ 12998944Sobrien CHECKDONE (p, q); 13019370Spst baud_rate = n; 13119370Spst 13219370Spst /* look for debug value. */ 13398944Sobrien n = strtol (p, &q, 10); 13419370Spst 13519370Spst /* check for missing or empty debug value. */ 13698944Sobrien CHECKDONE (p, q); 13798944Sobrien sr_set_debug (n); 13819370Spst 13919370Spst /* scan off remaining white space. */ 14098944Sobrien for (p = q; isspace (*p); ++p);; 14119370Spst 14219370Spst /* if not end of string, then there's unrecognized junk. */ 14319370Spst if (*p != '\0') 14498944Sobrien usage (proto, p); 14519370Spst 14619370Spst return; 14719370Spst} 14819370Spst 14919370Spstvoid 15098944Sobriengr_generic_checkin (void) 15119370Spst{ 15298944Sobrien sr_write_cr (""); 15398944Sobrien gr_expect_prompt (); 15419370Spst} 15519370Spst 15619370Spstvoid 15798944Sobriengr_open (char *args, int from_tty, struct gr_settings *gr) 15819370Spst{ 15998944Sobrien target_preopen (from_tty); 16098944Sobrien sr_scan_args (gr->ops->to_shortname, args); 16198944Sobrien unpush_target (gr->ops); 16219370Spst 16319370Spst gr_settings = gr; 16419370Spst 16598944Sobrien if (sr_get_desc () != NULL) 16619370Spst gr_close (0); 16719370Spst 16819370Spst /* If no args are specified, then we use the device specified by a 16919370Spst previous command or "set remotedevice". But if there is no 17019370Spst device, better stop now, not dump core. */ 17119370Spst 17219370Spst if (sr_get_device () == NULL) 17319370Spst usage (gr->ops->to_shortname, NULL); 17419370Spst 17598944Sobrien sr_set_desc (serial_open (sr_get_device ())); 17698944Sobrien if (!sr_get_desc ()) 17798944Sobrien perror_with_name ((char *) sr_get_device ()); 17819370Spst 17919370Spst if (baud_rate != -1) 18019370Spst { 18198944Sobrien if (serial_setbaudrate (sr_get_desc (), baud_rate) != 0) 18219370Spst { 18398944Sobrien serial_close (sr_get_desc ()); 18498944Sobrien perror_with_name (sr_get_device ()); 18519370Spst } 18619370Spst } 18719370Spst 18898944Sobrien serial_raw (sr_get_desc ()); 18919370Spst 19019370Spst /* If there is something sitting in the buffer we might take it as a 19119370Spst response to a command, which would be bad. */ 19298944Sobrien serial_flush_input (sr_get_desc ()); 19319370Spst 19419370Spst /* default retries */ 19598944Sobrien if (sr_get_retries () == 0) 19698944Sobrien sr_set_retries (1); 19719370Spst 19819370Spst /* default clear breakpoint function */ 19919370Spst if (gr_settings->clear_all_breakpoints == NULL) 20019370Spst gr_settings->clear_all_breakpoints = remove_breakpoints; 20119370Spst 20219370Spst if (from_tty) 20319370Spst { 20419370Spst printf_filtered ("Remote debugging using `%s'", sr_get_device ()); 20519370Spst if (baud_rate != -1) 20619370Spst printf_filtered (" at baud rate of %d", 20719370Spst baud_rate); 20819370Spst printf_filtered ("\n"); 20919370Spst } 21019370Spst 21198944Sobrien push_target (gr->ops); 21298944Sobrien gr_checkin (); 21319370Spst gr_clear_all_breakpoints (); 21419370Spst return; 21519370Spst} 21619370Spst 21719370Spst/* Read a character from the remote system masking it down to 7 bits 21819370Spst and doing all the fancy timeout stuff. */ 21919370Spst 22019370Spstint 22198944Sobriensr_readchar (void) 22219370Spst{ 22319370Spst int buf; 22419370Spst 22598944Sobrien buf = serial_readchar (sr_get_desc (), sr_get_timeout ()); 22619370Spst 22719370Spst if (buf == SERIAL_TIMEOUT) 22819370Spst error ("Timeout reading from remote system."); 22919370Spst 23098944Sobrien if (sr_get_debug () > 0) 23119370Spst printf_unfiltered ("%c", buf); 23219370Spst 23319370Spst return buf & 0x7f; 23419370Spst} 23519370Spst 23619370Spstint 23798944Sobriensr_pollchar (void) 23819370Spst{ 23919370Spst int buf; 24019370Spst 24198944Sobrien buf = serial_readchar (sr_get_desc (), 0); 24219370Spst if (buf == SERIAL_TIMEOUT) 24319370Spst buf = 0; 24498944Sobrien if (sr_get_debug () > 0) 24546283Sdfr { 24646283Sdfr if (buf) 24798944Sobrien printf_unfiltered ("%c", buf); 24846283Sdfr else 24998944Sobrien printf_unfiltered ("<empty character poll>"); 25046283Sdfr } 25119370Spst 25219370Spst return buf & 0x7f; 25319370Spst} 25419370Spst 25519370Spst/* Keep discarding input from the remote system, until STRING is found. 25619370Spst Let the user break out immediately. */ 25719370Spstvoid 25898944Sobriensr_expect (char *string) 25919370Spst{ 26019370Spst char *p = string; 26119370Spst 26298944Sobrien immediate_quit++; 26319370Spst while (1) 26419370Spst { 26519370Spst if (sr_readchar () == *p) 26619370Spst { 26719370Spst p++; 26819370Spst if (*p == '\0') 26919370Spst { 27098944Sobrien immediate_quit--; 27119370Spst return; 27219370Spst } 27319370Spst } 27419370Spst else 27519370Spst p = string; 27619370Spst } 27719370Spst} 27819370Spst 27919370Spstvoid 28098944Sobriensr_write (char *a, int l) 28119370Spst{ 28219370Spst int i; 28319370Spst 28498944Sobrien if (serial_write (sr_get_desc (), a, l) != 0) 28519370Spst perror_with_name ("sr_write: Error writing to remote"); 28619370Spst 28798944Sobrien if (sr_get_debug () > 0) 28819370Spst for (i = 0; i < l; i++) 28919370Spst printf_unfiltered ("%c", a[i]); 29019370Spst 29119370Spst return; 29219370Spst} 29319370Spst 29419370Spstvoid 29598944Sobriensr_write_cr (char *s) 29619370Spst{ 29719370Spst sr_write (s, strlen (s)); 29819370Spst sr_write ("\r", 1); 29919370Spst return; 30019370Spst} 30119370Spst 30219370Spstint 30398944Sobriensr_timed_read (char *buf, int n) 30419370Spst{ 30519370Spst int i; 30619370Spst char c; 30719370Spst 30819370Spst i = 0; 30919370Spst while (i < n) 31019370Spst { 31119370Spst c = sr_readchar (); 31219370Spst 31319370Spst if (c == 0) 31419370Spst return i; 31519370Spst buf[i] = c; 31619370Spst i++; 31719370Spst 31819370Spst } 31919370Spst return i; 32019370Spst} 32119370Spst 32219370Spst/* Get a hex digit from the remote system & return its value. If 32319370Spst ignore_space is nonzero, ignore spaces (not newline, tab, etc). */ 32419370Spst 32519370Spstint 32698944Sobriensr_get_hex_digit (int ignore_space) 32719370Spst{ 32819370Spst int ch; 32919370Spst 33019370Spst while (1) 33119370Spst { 33219370Spst ch = sr_readchar (); 33319370Spst if (ch >= '0' && ch <= '9') 33419370Spst return ch - '0'; 33519370Spst else if (ch >= 'A' && ch <= 'F') 33619370Spst return ch - 'A' + 10; 33719370Spst else if (ch >= 'a' && ch <= 'f') 33819370Spst return ch - 'a' + 10; 33919370Spst else if (ch != ' ' || !ignore_space) 34019370Spst { 34119370Spst gr_expect_prompt (); 34219370Spst error ("Invalid hex digit from remote system."); 34319370Spst } 34419370Spst } 34519370Spst} 34619370Spst 34719370Spst/* Get a byte from the remote and put it in *BYT. Accept any number 34819370Spst leading spaces. */ 34919370Spstvoid 35098944Sobriensr_get_hex_byte (char *byt) 35119370Spst{ 35219370Spst int val; 35319370Spst 35419370Spst val = sr_get_hex_digit (1) << 4; 35519370Spst val |= sr_get_hex_digit (0); 35619370Spst *byt = val; 35719370Spst} 35819370Spst 35919370Spst/* Read a 32-bit hex word from the remote, preceded by a space */ 36019370Spstlong 36198944Sobriensr_get_hex_word (void) 36219370Spst{ 36319370Spst long val; 36419370Spst int j; 36519370Spst 36619370Spst val = 0; 36719370Spst for (j = 0; j < 8; j++) 36819370Spst val = (val << 4) + sr_get_hex_digit (j == 0); 36919370Spst return val; 37019370Spst} 37119370Spst 37219370Spst/* Put a command string, in args, out to the remote. The remote is assumed to 37319370Spst be in raw mode, all writing/reading done through desc. 37419370Spst Ouput from the remote is placed on the users terminal until the 37519370Spst prompt from the remote is seen. 37619370Spst FIXME: Can't handle commands that take input. */ 37719370Spst 37846283Sdfrstatic void 37998944Sobriensr_com (char *args, int fromtty) 38019370Spst{ 38119370Spst sr_check_open (); 38219370Spst 38319370Spst if (!args) 38419370Spst return; 38519370Spst 38619370Spst /* Clear all input so only command relative output is displayed */ 38719370Spst 38819370Spst sr_write_cr (args); 38919370Spst sr_write ("\030", 1); 39019370Spst registers_changed (); 39119370Spst gr_expect_prompt (); 39219370Spst} 39319370Spst 39419370Spstvoid 39598944Sobriengr_close (int quitting) 39619370Spst{ 39798944Sobrien gr_clear_all_breakpoints (); 39819370Spst 39998944Sobrien if (sr_is_open ()) 40019370Spst { 40198944Sobrien serial_close (sr_get_desc ()); 40298944Sobrien sr_set_desc (NULL); 40319370Spst } 40419370Spst 40519370Spst return; 40619370Spst} 40719370Spst 40819370Spst/* gr_detach() 40919370Spst takes a program previously attached to and detaches it. 41019370Spst We better not have left any breakpoints 41119370Spst in the program or it'll die when it hits one. 41219370Spst Close the open connection to the remote debugger. 41319370Spst Use this when you want to detach and do something else 41419370Spst with your gdb. */ 41519370Spst 41619370Spstvoid 41798944Sobriengr_detach (char *args, int from_tty) 41819370Spst{ 41919370Spst if (args) 42019370Spst error ("Argument given to \"detach\" when remotely debugging."); 42198944Sobrien 42298944Sobrien if (sr_is_open ()) 42319370Spst gr_clear_all_breakpoints (); 42419370Spst 42519370Spst pop_target (); 42619370Spst if (from_tty) 42719370Spst puts_filtered ("Ending remote debugging.\n"); 42819370Spst 42919370Spst return; 43098944Sobrien} 43119370Spst 43219370Spstvoid 43398944Sobriengr_files_info (struct target_ops *ops) 43419370Spst{ 43519370Spst#ifdef __GO32__ 43619370Spst printf_filtered ("\tAttached to DOS asynctsr\n"); 43719370Spst#else 43898944Sobrien printf_filtered ("\tAttached to %s", sr_get_device ()); 43919370Spst if (baud_rate != -1) 44019370Spst printf_filtered ("at %d baud", baud_rate); 44119370Spst printf_filtered ("\n"); 44219370Spst#endif 44319370Spst 44419370Spst if (exec_bfd) 44519370Spst { 44619370Spst printf_filtered ("\tand running program %s\n", 44719370Spst bfd_get_filename (exec_bfd)); 44819370Spst } 44919370Spst printf_filtered ("\tusing the %s protocol.\n", ops->to_shortname); 45019370Spst} 45119370Spst 45219370Spstvoid 45398944Sobriengr_mourn (void) 45419370Spst{ 45519370Spst gr_clear_all_breakpoints (); 45698944Sobrien unpush_target (gr_get_ops ()); 45719370Spst generic_mourn_inferior (); 45819370Spst} 45919370Spst 46019370Spstvoid 46198944Sobriengr_kill (void) 46219370Spst{ 46319370Spst return; 46419370Spst} 46519370Spst 46619370Spst/* This is called not only when we first attach, but also when the 46719370Spst user types "run" after having attached. */ 46819370Spstvoid 46998944Sobriengr_create_inferior (char *execfile, char *args, char **env) 47019370Spst{ 47119370Spst int entry_pt; 47219370Spst 47319370Spst if (args && *args) 47419370Spst error ("Can't pass arguments to remote process."); 47519370Spst 47619370Spst if (execfile == 0 || exec_bfd == 0) 47746283Sdfr error ("No executable file specified"); 47819370Spst 47919370Spst entry_pt = (int) bfd_get_start_address (exec_bfd); 48019370Spst sr_check_open (); 48119370Spst 48219370Spst gr_kill (); 48319370Spst gr_clear_all_breakpoints (); 48419370Spst 48519370Spst init_wait_for_inferior (); 48698944Sobrien gr_checkin (); 48719370Spst 48819370Spst insert_breakpoints (); /* Needed to get correct instruction in cache */ 48919370Spst proceed (entry_pt, -1, 0); 49019370Spst} 49119370Spst 49219370Spst/* Given a null terminated list of strings LIST, read the input until we find one of 49319370Spst them. Return the index of the string found or -1 on error. '?' means match 49419370Spst any single character. Note that with the algorithm we use, the initial 49519370Spst character of the string cannot recur in the string, or we will not find some 49619370Spst cases of the string in the input. If PASSTHROUGH is non-zero, then 49719370Spst pass non-matching data on. */ 49819370Spst 49919370Spstint 50098944Sobriengr_multi_scan (char *list[], int passthrough) 50119370Spst{ 50298944Sobrien char *swallowed = NULL; /* holding area */ 50398944Sobrien char *swallowed_p = swallowed; /* Current position in swallowed. */ 50419370Spst int ch; 50519370Spst int ch_handled; 50619370Spst int i; 50719370Spst int string_count; 50819370Spst int max_length; 50919370Spst char **plist; 51019370Spst 51119370Spst /* Look through the strings. Count them. Find the largest one so we can 51219370Spst allocate a holding area. */ 51319370Spst 51419370Spst for (max_length = string_count = i = 0; 51519370Spst list[i] != NULL; 51619370Spst ++i, ++string_count) 51719370Spst { 51898944Sobrien int length = strlen (list[i]); 51919370Spst 52019370Spst if (length > max_length) 52119370Spst max_length = length; 52219370Spst } 52319370Spst 52419370Spst /* if we have no strings, then something is wrong. */ 52519370Spst if (string_count == 0) 52698944Sobrien return (-1); 52719370Spst 52819370Spst /* otherwise, we will need a holding area big enough to hold almost two 52919370Spst copies of our largest string. */ 53098944Sobrien swallowed_p = swallowed = alloca (max_length << 1); 53119370Spst 53219370Spst /* and a list of pointers to current scan points. */ 53398944Sobrien plist = (char **) alloca (string_count * sizeof (*plist)); 53419370Spst 53519370Spst /* and initialize */ 53619370Spst for (i = 0; i < string_count; ++i) 53719370Spst plist[i] = list[i]; 53819370Spst 53998944Sobrien for (ch = sr_readchar (); /* loop forever */ ; ch = sr_readchar ()) 54019370Spst { 54198944Sobrien QUIT; /* Let user quit and leave process running */ 54219370Spst ch_handled = 0; 54319370Spst 54419370Spst for (i = 0; i < string_count; ++i) 54519370Spst { 54619370Spst if (ch == *plist[i] || *plist[i] == '?') 54719370Spst { 54819370Spst ++plist[i]; 54919370Spst if (*plist[i] == '\0') 55098944Sobrien return (i); 55119370Spst 55219370Spst if (!ch_handled) 55319370Spst *swallowed_p++ = ch; 55419370Spst 55519370Spst ch_handled = 1; 55619370Spst } 55719370Spst else 55819370Spst plist[i] = list[i]; 55919370Spst } 56019370Spst 56119370Spst if (!ch_handled) 56219370Spst { 56319370Spst char *p; 56419370Spst 56519370Spst /* Print out any characters which have been swallowed. */ 56619370Spst if (passthrough) 56719370Spst { 56819370Spst for (p = swallowed; p < swallowed_p; ++p) 56919370Spst fputc_unfiltered (*p, gdb_stdout); 57019370Spst 57119370Spst fputc_unfiltered (ch, gdb_stdout); 57219370Spst } 57319370Spst 57419370Spst swallowed_p = swallowed; 57519370Spst } 57619370Spst } 57719370Spst#if 0 57819370Spst /* Never reached. */ 57998944Sobrien return (-1); 58019370Spst#endif 58119370Spst} 58219370Spst 58319370Spst/* Get ready to modify the registers array. On machines which store 58419370Spst individual registers, this doesn't need to do anything. On machines 58519370Spst which store all the registers in one fell swoop, this makes sure 58619370Spst that registers contains all the registers from the program being 58719370Spst debugged. */ 58819370Spst 58919370Spstvoid 59098944Sobriengr_prepare_to_store (void) 59119370Spst{ 59219370Spst /* Do nothing, since we assume we can store individual regs */ 59319370Spst} 59419370Spst 59519370Spstvoid 59698944Sobrien_initialize_sr_support (void) 59719370Spst{ 59819370Spst/* FIXME-now: if target is open... */ 59919370Spst add_show_from_set (add_set_cmd ("remotedevice", no_class, 60098944Sobrien var_filename, (char *) &sr_settings.device, 60119370Spst "Set device for remote serial I/O.\n\ 60219370SpstThis device is used as the serial port when debugging using remote\n\ 60319370Spsttargets.", &setlist), 60419370Spst &showlist); 60519370Spst 60619370Spst add_com ("remote <command>", class_obscure, sr_com, 60719370Spst "Send a command to the remote monitor."); 60819370Spst 60919370Spst} 610