From 21ed3dcdbe9c5071a7e194ad910396dcf056665c Mon Sep 17 00:00:00 2001 From: Rob Savoye Date: Tue, 18 Oct 1994 00:55:51 +0000 Subject: [PATCH] * monitor.c (set_loadtype_command): Fixed so it doesn't core dump. * monitor.c (monitor_load): check the load type and load the file accordingly. Default to gr_load_image(). * monitor.c (monitor_load_ascii_srec): Load an ascii file in srecord format by downloading to the monitor. * w89k-rom.c, op50n-rom.c: set supported load types. --- gdb/monitor.c | 329 ++++++++++++++++++++++++++++++++++++++++++------- gdb/op50-rom.c | 2 +- gdb/w89k-rom.c | 2 +- 3 files changed, 287 insertions(+), 46 deletions(-) diff --git a/gdb/monitor.c b/gdb/monitor.c index 4fdb2fb1e2..0113a05787 100644 --- a/gdb/monitor.c +++ b/gdb/monitor.c @@ -52,6 +52,9 @@ struct monitor_ops *current_monitor; extern struct cmd_list_element *setlist; extern struct cmd_list_element *unsetlist; struct cmd_list_element *showlist; +extern char *version; +extern char *host_name; +extern char *target_name; static int hashmark; /* flag set by "set hash" */ @@ -72,6 +75,8 @@ static serial_t monitor_desc = NULL; char *loadtype; static char *loadtype_str; static void set_loadtype_command(); +static void monitor_load_srec(); +static int monitor_write_srec(); /* * set_loadtype_command -- set the type for downloading. Check to make @@ -83,24 +88,27 @@ set_loadtype_command (ignore, from_tty, c) int from_tty; struct cmd_list_element *c; { -#if 0 + char *tmp; char *type; - if (strcmp (LOADTYPES, "")) { + if (STREQ (LOADTYPES, "")) { error ("No loadtype set"); return; } - type = strtok(LOADTYPES, ","); + tmp = savestring (LOADTYPES, strlen(LOADTYPES)); + type = strtok(tmp, ","); if (STREQ (type, (*(char **) c->var))) { loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var)); return; } - while (type = strtok (NULL, ",") != (char *)NULL) + while ((type = strtok (NULL, ",")) != (char *)NULL) { if (STREQ (type, (*(char **) c->var))) loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var)); -#endif - loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var)); + return; + } + free (tmp); + error ("Loadtype \"%s\" does not exist.", (*(char **) c->var)); } /* @@ -473,6 +481,9 @@ monitor_open(args, name, from_tty) log_file = fopen (LOG_FILE, "w"); if (log_file == NULL) perror_with_name (LOG_FILE); + fprintf_filtered (log_file, "GDB %s (%s", version, host_name); + fprintf_filtered (log_file, " --target %s)\n", target_name); + fprintf_filtered (log_file, "Remote target %s connected to %s\n\n", TARGET_NAME, dev_name); #endif /* wake up the monitor and see if it's alive */ @@ -949,60 +960,96 @@ monitor_remove_breakpoint (addr, shadow) return 1; } -/* Load a file. This is usually an srecord, which is ascii. No - protocol, just sent line by line. */ +/* monitor_load -- load a file. This file determines which of the + * supported formats to use. The current types are: + * FIXME: not all types supported yet. + * default - reads any file using bfd and writes it to memory. + * srec - reads binary file using bfd and writes it as an + * ascii srecord. + * xmodem-bin - reads a binary file using bfd, and downloads it + * using xmodem protocol. + * xmodem-srec - reads a binary file using bfd, and after converting + * it downloads it as an srecord using xmodem protocol. + * ascii-srec - reads a ascii srecord file and downloads it + * without a change. + * ascii-xmodem - reads a ascii file and downloads using xmodem + * protocol. + */ +void +monitor_load (file, fromtty) + char *file; + int fromtty; +{ + FILE *download; + int i, bytes_read; + + debuglogs (1, "Loading %s to monitor", file); + if (STREQ (loadtype_str, "default")) { /* default, load a binary */ + gr_load_image (file, fromtty); /* by writing it into memory */ + } + + if (STREQ (loadtype_str, "srec")) { /* load an srecord by converting */ + monitor_load_srec(file, fromtty); /* if from a binary */ + } + + if (STREQ (loadtype_str, "ascii-srec")) { /* load an srecord file */ + monitor_load_ascii_srec(file, fromtty); /* if from a binary */ + } + + if (STREQ (loadtype_str, "xmodem-srec")) { /* load an srecord using the */ + error ("This protocol is not implemented yet."); /* xmodem protocol */ + } +} + +/* + * monitor_load_ascii_srec -- download an ASCII srecord file. + */ #define DOWNLOAD_LINE_SIZE 100 -void -monitor_load (arg) - char *arg; +int +monitor_load_ascii_srec (file, fromtty) + char *file; + int fromtty; { FILE *download; char buf[DOWNLOAD_LINE_SIZE]; int i, bytes_read; - if (sr_get_debug()) - printf ("Loading %s to monitor\n", arg); + debuglogs (1, "Loading an ASCII srecord file, %s.", file); - download = fopen (arg, "r"); - if (download == NULL) - { - error (sprintf (buf, "%s Does not exist", arg)); + download = fopen (file, "r"); + if (download == NULL) { + error ("%s Does not exist", file); return; } printf_monitor (LOAD_CMD); -/* expect ("Waiting for S-records from host... ", 1); */ - - while (!feof (download)) - { - bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download); - if (hashmark) - { - putchar ('.'); - fflush (stdout); - } - if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) { - fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno)); - break; - } - i = 0; - while (i++ <=200000) {} ; /* Ugly HACK, probably needs flow control */ - if (bytes_read < DOWNLOAD_LINE_SIZE) - { - if (!feof (download)) - error ("Only read %d bytes\n", bytes_read); - break; - } + while (!feof (download)) { + bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download); + if (hashmark) { + putchar ('.'); + fflush (stdout); } - - if (hashmark) - { - putchar ('\n'); + if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) { + fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno)); + break; + } + i = 0; + while (i++ <=200) {} ; /* Ugly HACK, probably needs flow control */ + if (bytes_read < DOWNLOAD_LINE_SIZE) { + if (!feof (download)) + error ("Only read %d bytes\n", bytes_read); + break; } + } + + if (hashmark) { + putchar ('\n'); + } if (!feof (download)) error ("Never got EOF while downloading"); + expect_prompt(1); fclose (download); } @@ -1035,6 +1082,200 @@ monitor_command (args, fromtty) expect_prompt(0); } +/* + * monitor_load_srec -- download a binary file by converting it to srecords. + */ +static void +monitor_load_srec (args, fromtty) + char *args; + int fromtty; +{ + bfd *abfd; + asection *s; + char buffer[1024]; + int srec_frame = SREC_SIZE; + + abfd = bfd_openr (args, 0); + if (!abfd) { + printf_filtered ("Unable to open file %s\n", args); + return; + } + + if (bfd_check_format (abfd, bfd_object) == 0) { + printf_filtered ("File is not an object file\n"); + return; + } + + s = abfd->sections; + while (s != (asection *) NULL) { + srec_frame = SREC_SIZE; + if (s->flags & SEC_LOAD) { + int i; + char *buffer = xmalloc (srec_frame); + printf_filtered ("%s\t: 0x%4x .. 0x%4x ", s->name, s->vma, s->vma + s + ->_raw_size); + fflush (stdout); + for (i = 0; i < s->_raw_size; i += srec_frame) { + if (srec_frame > s->_raw_size - i) + srec_frame = s->_raw_size - i; + + bfd_get_section_contents (abfd, s, buffer, i, srec_frame); + monitor_write_srec (s->vma + i, buffer, srec_frame); + printf_filtered ("*"); + fflush (stdout); + } + printf_filtered ("\n"); + free (buffer); + } + s = s->next; + } + sprintf (buffer, "rs ip %lx", (unsigned long) abfd->start_address); + printf_monitor (buffer); + expect_prompt (); +} + + +static int +monitor_write_srec (memaddr, myaddr, len) + CORE_ADDR memaddr; + unsigned char *myaddr; + int len; +{ + int done; + int checksum; + int x; + int retries; + int srec_bytes = 40; + int srec_max_retries = 3; + int srec_echo_pace = 0; + int srec_sleep = 0; + int srec_noise = 0; + char *buffer = alloca ((srec_bytes + 8) << 1); + + retries = 0; + + while (1) { /* FIXME !!! */ + done = 0; + + if (retries > srec_max_retries) + return(-1); + + if (retries > 0) { + if (sr_get_debug() > 0) + printf("\n\n"); + + /* This gr_expect_prompt call is extremely important. Without + it, we will tend to resend our packet so fast that it + will arrive before the bug monitor is ready to receive + it. This would lead to a very ugly resend loop. */ + + gr_expect_prompt(); + } + + /* FIXME: this is just start_load pasted in... */ + { char *command; + command = (srec_echo_pace ? "lo 0 ;x" : "lo 0"); + sr_write_cr (command); + sr_expect (command); + sr_expect ("\r\n"); +#if 0 + bug_srec_write_cr ("S0030000FC"); +#endif + } + /* end of hack */ + + while (done < len) { + int thisgo; + int idx; + char *buf = buffer; + CORE_ADDR address; + + checksum = 0; + thisgo = len - done; + if (thisgo > srec_bytes) + thisgo = srec_bytes; + + address = memaddr + done; + sprintf (buf, "S3%02X%08X", thisgo + 4 + 1, address); + buf += 12; + + checksum += (thisgo + 4 + 1 + + (address & 0xff) + + ((address >> 8) & 0xff) + + ((address >> 16) & 0xff) + + ((address >> 24) & 0xff)); + + for (idx = 0; idx < thisgo; idx++) { + sprintf (buf, "%02X", myaddr[idx + done]); + checksum += myaddr[idx + done]; + buf += 2; + } + + if (srec_noise > 0) { + /* FIXME-NOW: insert a deliberate error every now and then. + This is intended for testing/debugging the error handling + stuff. */ + static int counter = 0; + if (++counter > srec_noise) { + counter = 0; + ++checksum; + } + } + + sprintf(buf, "%02X", ~checksum & 0xff); +#if 0 + bug_srec_write_cr (buffer); +#endif + + if (srec_sleep != 0) + sleep(srec_sleep); + + /* This pollchar is probably redundant to the gr_multi_scan + below. Trouble is, we can't be sure when or where an + error message will appear. Apparently, when running at + full speed from a typical sun4, error messages tend to + appear to arrive only *after* the s7 record. */ + + if ((x = sr_pollchar()) != 0) { + if (sr_get_debug() > 0) + printf("\n\n"); + + ++retries; + + /* flush any remaining input and verify that we are back + at the prompt level. */ + gr_expect_prompt(); + /* start all over again. */ + /* FIXME: this is just start_load pasted in... */ + { char *command; + command = (srec_echo_pace ? "lo 0 ;x" : "lo 0"); + sr_write_cr (command); + sr_expect (command); + sr_expect ("\r\n"); +#if 0 + bug_srec_write_cr ("S0030000FC"); +#endif + } + /* end of hack */ + + done = 0; + continue; + } + + done += thisgo; + } +#if 0 + bug_srec_write_cr("S7060000000000F9"); +#endif + ++retries; + + /* Having finished the load, we need to figure out whether we + had any errors. */ + } + + return(0); +} + /* * _initialize_remote_monitors -- setup a few addtitional commands that * are usually only used by monitors. @@ -1049,7 +1290,7 @@ _initialize_remote_monitors () "Set the type of the remote load protocol.\n", &setlist); c->function.sfunc = set_loadtype_command; add_show_from_set (c, &showlist); - loadtype_str = savestring ("generic", 8); + loadtype_str = savestring ("default", 8); add_show_from_set (add_set_cmd ("hash", no_class, var_boolean, (char *)&hashmark, diff --git a/gdb/op50-rom.c b/gdb/op50-rom.c index 37aa61e58b..b0c853abf9 100644 --- a/gdb/op50-rom.c +++ b/gdb/op50-rom.c @@ -119,7 +119,7 @@ struct monitor_ops op50n_cmds = { " ", /* end-of-command delimitor */ ".\n", /* optional command terminator */ &op50n_ops, /* target operations */ - "srec,binary", /* load types */ + "srec,ascii-srec,default", /* load types */ op50n_regnames }; diff --git a/gdb/w89k-rom.c b/gdb/w89k-rom.c index 7e8a628b63..45e14fe0ca 100644 --- a/gdb/w89k-rom.c +++ b/gdb/w89k-rom.c @@ -114,7 +114,7 @@ struct monitor_ops w89k_cmds = { "", /* end-of-command delimitor */ "", /* optional command terminator */ &w89k_ops, /* target operations */ - "xmodem-srec,xmodem-som", /* load types */ + "srec,xmodem-ascii,xmodem-srec,default",/* load types */ w89k_regnames /* registers names */ }; -- 2.34.1