X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fremote.c;h=efdc7d94a07a1fe1a9d12a000c28ce5ea3191704;hb=a94abe5bb7a71b207691f8b50406166eefda8186;hp=f9d04f4826e6ae12a5e4c6070c8bc260238ac57d;hpb=ac7a377f64a19b1bda507a6aecaaab3f81f7ebbb;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/remote.c b/gdb/remote.c index f9d04f4826..efdc7d94a0 100644 --- a/gdb/remote.c +++ b/gdb/remote.c @@ -90,6 +90,21 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ AA = signal number n... = register number r... = register contents + or... WAA The process extited, and AA is + the exit status. This is only + applicable for certains sorts of + targets. + or... NAATT;DD;BB Relocate the object file. + AA = signal number + TT = text address + DD = data address + BB = bss address + This is used by the NLM stub, + which is why it only has three + addresses rather than one per + section: the NLM stub always + sees only three sections, even + though gdb may see more. kill request k @@ -114,8 +129,11 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "wait.h" #include "terminal.h" #include "gdbcmd.h" +#include "objfiles.h" +#include "gdb-stabs.h" #include "dcache.h" +#include "remote-utils.h" #if !defined(DONT_USE_REMOTE) #ifdef USG @@ -203,6 +221,10 @@ static int timeout = 2; int icache; #endif +/* FIXME: This is a hack which lets this file compile. It should be getting + this setting from remote-utils.c. */ +#define remote_debug (0) + /* Descriptor for I/O to remote machine. Initialize it to NULL so that remote_open knows that we don't have a file open when the program starts. */ @@ -276,16 +298,10 @@ device is attached to the remote system (e.g. /dev/ttya)."); if (!remote_desc) perror_with_name (name); - if (baud_rate) + if (SERIAL_SETBAUDRATE (remote_desc, sr_get_baud_rate())) { - int rate; - - if (sscanf (baud_rate, "%d", &rate) == 1) - if (SERIAL_SETBAUDRATE (remote_desc, rate)) - { - SERIAL_CLOSE (remote_desc); - perror_with_name (name); - } + SERIAL_CLOSE (remote_desc); + perror_with_name (name); } SERIAL_RAW (remote_desc); @@ -432,72 +448,136 @@ remote_wait (status) WAITTYPE *status; { unsigned char buf[PBUFSIZ]; - unsigned char *p; - int i; - long regno; - char regs[MAX_REGISTER_RAW_SIZE]; WSETEXIT ((*status), 0); - ofunc = (void (*)()) signal (SIGINT, remote_interrupt); - getpkt ((char *) buf, 1); - signal (SIGINT, ofunc); - - if (buf[0] == 'E') - error ("Remote failure reply: %s", buf); - if (buf[0] == 'T') + while (1) { - /* Expedited reply, containing Signal, {regno, reg} repeat */ - /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where - ss = signal number - n... = register number - r... = register contents - */ + unsigned char *p; - p = &buf[3]; /* after Txx */ + ofunc = (void (*)()) signal (SIGINT, remote_interrupt); + getpkt ((char *) buf, 1); + signal (SIGINT, ofunc); - while (*p) + if (buf[0] == 'E') + warning ("Remote failure reply: %s", buf); + else if (buf[0] == 'T') { - unsigned char *p1; + int i; + long regno; + char regs[MAX_REGISTER_RAW_SIZE]; - regno = strtol (p, &p1, 16); /* Read the register number */ + /* Expedited reply, containing Signal, {regno, reg} repeat */ + /* format is: 'Tssn...:r...;n...:r...;n...:r...;#cc', where + ss = signal number + n... = register number + r... = register contents + */ - if (p1 == p) - error ("Remote sent badly formed register number: %s\nPacket: '%s'\n", - p1, buf); + p = &buf[3]; /* after Txx */ - p = p1; + while (*p) + { + unsigned char *p1; - if (*p++ != ':') - error ("Malformed packet (missing colon): %s\nPacket: '%s'\n", - p, buf); + regno = strtol (p, &p1, 16); /* Read the register number */ - if (regno >= NUM_REGS) - error ("Remote sent bad register number %d: %s\nPacket: '%s'\n", - regno, p, buf); + if (p1 == p) + warning ("Remote sent badly formed register number: %s\nPacket: '%s'\n", + p1, buf); - for (i = 0; i < REGISTER_RAW_SIZE (regno); i++) - { - if (p[0] == 0 || p[1] == 0) - error ("Remote reply is too short: %s", buf); - regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]); - p += 2; - } + p = p1; + + if (*p++ != ':') + warning ("Malformed packet (missing colon): %s\nPacket: '%s'\n", + p, buf); + + if (regno >= NUM_REGS) + warning ("Remote sent bad register number %d: %s\nPacket: '%s'\n", + regno, p, buf); - if (*p++ != ';') - error("Remote register badly formatted: %s", buf); + for (i = 0; i < REGISTER_RAW_SIZE (regno); i++) + { + if (p[0] == 0 || p[1] == 0) + warning ("Remote reply is too short: %s", buf); + regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]); + p += 2; + } + + if (*p++ != ';') + warning ("Remote register badly formatted: %s", buf); + + supply_register (regno, regs); + } + break; + } + else if (buf[0] == 'N') + { + unsigned char *p1; + bfd_vma text_addr, data_addr, bss_addr; + + /* Relocate object file. Format is NAATT;DD;BB where AA is + the signal number, TT is the new text address, DD is the + new data address, and BB is the new bss address. This is + used by the NLM stub; gdb may see more sections. */ + p = &buf[3]; + text_addr = strtol (p, &p1, 16); + if (p1 == p || *p1 != ';') + warning ("Malformed relocation packet: Packet '%s'", buf); + p = p1 + 1; + data_addr = strtol (p, &p1, 16); + if (p1 == p || *p1 != ';') + warning ("Malformed relocation packet: Packet '%s'", buf); + p = p1 + 1; + bss_addr = strtol (p, &p1, 16); + if (p1 == p) + warning ("Malformed relocation packet: Packet '%s'", buf); - supply_register (regno, regs); + if (symfile_objfile != NULL) + { + struct section_offsets *offs; + + /* FIXME: Why don't the various symfile_offsets routines + in the sym_fns vectors set this? */ + if (symfile_objfile->num_sections == 0) + symfile_objfile->num_sections = SECT_OFF_MAX; + + offs = ((struct section_offsets *) + alloca (sizeof (struct section_offsets) + + (symfile_objfile->num_sections + * sizeof (offs->offsets)))); + memcpy (offs, symfile_objfile->section_offsets, + (sizeof (struct section_offsets) + + (symfile_objfile->num_sections + * sizeof (offs->offsets)))); + ANOFFSET (offs, SECT_OFF_TEXT) = text_addr; + ANOFFSET (offs, SECT_OFF_DATA) = data_addr; + ANOFFSET (offs, SECT_OFF_BSS) = bss_addr; + + objfile_relocate (symfile_objfile, offs); + } + break; } + else if (buf[0] == 'W') + { + /* The remote process exited. */ + WSETEXIT (*status, (fromhex (buf[1]) << 4) + fromhex (buf[2])); + return 0; + } + else if (buf[0] == 'S') + break; + else + warning ("Invalid remote reply: %s", buf); } - else if (buf[0] != 'S') - error ("Invalid remote reply: %s", buf); WSETSTOP ((*status), (((fromhex (buf[1])) << 4) + (fromhex (buf[2])))); return 0; } +/* Number of bytes of registers this stub implements. */ +static int register_bytes_found; + /* Read the remote registers into the block REGS. */ /* Currently we just read all the registers, so we don't use regno. */ /* ARGSUSED */ @@ -513,6 +593,9 @@ remote_fetch_registers (regno) sprintf (buf, "g"); remote_send (buf); + /* Unimplemented registers read as all bits zero. */ + memset (regs, 0, REGISTER_BYTES); + /* Reply describes registers byte by byte, each byte encoded as two hex characters. Suck them all up, then supply them to the register cacheing/storage mechanism. */ @@ -520,11 +603,29 @@ remote_fetch_registers (regno) p = buf; for (i = 0; i < REGISTER_BYTES; i++) { - if (p[0] == 0 || p[1] == 0) - error ("Remote reply is too short: %s", buf); + if (p[0] == 0) + break; + if (p[1] == 0) + { + warning ("Remote reply is of odd length: %s", buf); + /* Don't change register_bytes_found in this case, and don't + print a second warning. */ + goto supply_them; + } regs[i] = fromhex (p[0]) * 16 + fromhex (p[1]); p += 2; } + + if (i != register_bytes_found) + { + register_bytes_found = i; +#ifdef REGISTER_BYTES_OK + if (!REGISTER_BYTES_OK (i)) + warning ("Remote reply is too short: %s", buf); +#endif + } + + supply_them: for (i = 0; i < NUM_REGS; i++) supply_register (i, ®s[REGISTER_BYTE(i)]); } @@ -557,7 +658,8 @@ remote_store_registers (regno) each byte encoded as two hex characters. */ p = buf + 1; - for (i = 0; i < REGISTER_BYTES; i++) + /* remote_prepare_to_store insures that register_bytes_found gets set. */ + for (i = 0; i < register_bytes_found; i++) { *p++ = tohex ((registers[i] >> 4) & 0xf); *p++ = tohex (registers[i] & 0xf);