mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-06-28 23:39:35 +08:00
* 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.
This commit is contained in:
301
gdb/monitor.c
301
gdb/monitor.c
@ -52,6 +52,9 @@ struct monitor_ops *current_monitor;
|
|||||||
extern struct cmd_list_element *setlist;
|
extern struct cmd_list_element *setlist;
|
||||||
extern struct cmd_list_element *unsetlist;
|
extern struct cmd_list_element *unsetlist;
|
||||||
struct cmd_list_element *showlist;
|
struct cmd_list_element *showlist;
|
||||||
|
extern char *version;
|
||||||
|
extern char *host_name;
|
||||||
|
extern char *target_name;
|
||||||
|
|
||||||
static int hashmark; /* flag set by "set hash" */
|
static int hashmark; /* flag set by "set hash" */
|
||||||
|
|
||||||
@ -72,6 +75,8 @@ static serial_t monitor_desc = NULL;
|
|||||||
char *loadtype;
|
char *loadtype;
|
||||||
static char *loadtype_str;
|
static char *loadtype_str;
|
||||||
static void set_loadtype_command();
|
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
|
* 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;
|
int from_tty;
|
||||||
struct cmd_list_element *c;
|
struct cmd_list_element *c;
|
||||||
{
|
{
|
||||||
#if 0
|
char *tmp;
|
||||||
char *type;
|
char *type;
|
||||||
if (strcmp (LOADTYPES, "")) {
|
if (STREQ (LOADTYPES, "")) {
|
||||||
error ("No loadtype set");
|
error ("No loadtype set");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
type = strtok(LOADTYPES, ",");
|
tmp = savestring (LOADTYPES, strlen(LOADTYPES));
|
||||||
|
type = strtok(tmp, ",");
|
||||||
if (STREQ (type, (*(char **) c->var))) {
|
if (STREQ (type, (*(char **) c->var))) {
|
||||||
loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
|
loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (type = strtok (NULL, ",") != (char *)NULL)
|
while ((type = strtok (NULL, ",")) != (char *)NULL) {
|
||||||
if (STREQ (type, (*(char **) c->var)))
|
if (STREQ (type, (*(char **) c->var)))
|
||||||
loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
|
loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
|
||||||
#endif
|
return;
|
||||||
loadtype_str = savestring (*(char **) c->var, strlen (*(char **) c->var));
|
}
|
||||||
|
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");
|
log_file = fopen (LOG_FILE, "w");
|
||||||
if (log_file == NULL)
|
if (log_file == NULL)
|
||||||
perror_with_name (LOG_FILE);
|
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
|
#endif
|
||||||
|
|
||||||
/* wake up the monitor and see if it's alive */
|
/* wake up the monitor and see if it's alive */
|
||||||
@ -949,60 +960,96 @@ monitor_remove_breakpoint (addr, shadow)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load a file. This is usually an srecord, which is ascii. No
|
/* monitor_load -- load a file. This file determines which of the
|
||||||
protocol, just sent line by line. */
|
* supported formats to use. The current types are:
|
||||||
|
* FIXME: not all types supported yet.
|
||||||
#define DOWNLOAD_LINE_SIZE 100
|
* 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
|
void
|
||||||
monitor_load (arg)
|
monitor_load (file, fromtty)
|
||||||
char *arg;
|
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
|
||||||
|
int
|
||||||
|
monitor_load_ascii_srec (file, fromtty)
|
||||||
|
char *file;
|
||||||
|
int fromtty;
|
||||||
{
|
{
|
||||||
FILE *download;
|
FILE *download;
|
||||||
char buf[DOWNLOAD_LINE_SIZE];
|
char buf[DOWNLOAD_LINE_SIZE];
|
||||||
int i, bytes_read;
|
int i, bytes_read;
|
||||||
|
|
||||||
if (sr_get_debug())
|
debuglogs (1, "Loading an ASCII srecord file, %s.", file);
|
||||||
printf ("Loading %s to monitor\n", arg);
|
|
||||||
|
|
||||||
download = fopen (arg, "r");
|
download = fopen (file, "r");
|
||||||
if (download == NULL)
|
if (download == NULL) {
|
||||||
{
|
error ("%s Does not exist", file);
|
||||||
error (sprintf (buf, "%s Does not exist", arg));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf_monitor (LOAD_CMD);
|
printf_monitor (LOAD_CMD);
|
||||||
/* expect ("Waiting for S-records from host... ", 1); */
|
|
||||||
|
|
||||||
while (!feof (download))
|
while (!feof (download)) {
|
||||||
{
|
|
||||||
bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
|
bytes_read = fread (buf, sizeof (char), DOWNLOAD_LINE_SIZE, download);
|
||||||
if (hashmark)
|
if (hashmark) {
|
||||||
{
|
|
||||||
putchar ('.');
|
putchar ('.');
|
||||||
fflush (stdout);
|
fflush (stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
|
if (SERIAL_WRITE(monitor_desc, buf, bytes_read)) {
|
||||||
fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
|
fprintf(stderr, "SERIAL_WRITE failed: (while downloading) %s\n", safe_strerror(errno));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
i = 0;
|
i = 0;
|
||||||
while (i++ <=200000) {} ; /* Ugly HACK, probably needs flow control */
|
while (i++ <=200) {} ; /* Ugly HACK, probably needs flow control */
|
||||||
if (bytes_read < DOWNLOAD_LINE_SIZE)
|
if (bytes_read < DOWNLOAD_LINE_SIZE) {
|
||||||
{
|
|
||||||
if (!feof (download))
|
if (!feof (download))
|
||||||
error ("Only read %d bytes\n", bytes_read);
|
error ("Only read %d bytes\n", bytes_read);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hashmark)
|
if (hashmark) {
|
||||||
{
|
|
||||||
putchar ('\n');
|
putchar ('\n');
|
||||||
}
|
}
|
||||||
if (!feof (download))
|
if (!feof (download))
|
||||||
error ("Never got EOF while downloading");
|
error ("Never got EOF while downloading");
|
||||||
|
expect_prompt(1);
|
||||||
fclose (download);
|
fclose (download);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1035,6 +1082,200 @@ monitor_command (args, fromtty)
|
|||||||
expect_prompt(0);
|
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<retrying...>\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<retrying...>\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
|
* _initialize_remote_monitors -- setup a few addtitional commands that
|
||||||
* are usually only used by monitors.
|
* are usually only used by monitors.
|
||||||
@ -1049,7 +1290,7 @@ _initialize_remote_monitors ()
|
|||||||
"Set the type of the remote load protocol.\n", &setlist);
|
"Set the type of the remote load protocol.\n", &setlist);
|
||||||
c->function.sfunc = set_loadtype_command;
|
c->function.sfunc = set_loadtype_command;
|
||||||
add_show_from_set (c, &showlist);
|
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,
|
add_show_from_set (add_set_cmd ("hash", no_class, var_boolean,
|
||||||
(char *)&hashmark,
|
(char *)&hashmark,
|
||||||
|
@ -119,7 +119,7 @@ struct monitor_ops op50n_cmds = {
|
|||||||
" ", /* end-of-command delimitor */
|
" ", /* end-of-command delimitor */
|
||||||
".\n", /* optional command terminator */
|
".\n", /* optional command terminator */
|
||||||
&op50n_ops, /* target operations */
|
&op50n_ops, /* target operations */
|
||||||
"srec,binary", /* load types */
|
"srec,ascii-srec,default", /* load types */
|
||||||
op50n_regnames
|
op50n_regnames
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,7 +114,7 @@ struct monitor_ops w89k_cmds = {
|
|||||||
"", /* end-of-command delimitor */
|
"", /* end-of-command delimitor */
|
||||||
"", /* optional command terminator */
|
"", /* optional command terminator */
|
||||||
&w89k_ops, /* target operations */
|
&w89k_ops, /* target operations */
|
||||||
"xmodem-srec,xmodem-som", /* load types */
|
"srec,xmodem-ascii,xmodem-srec,default",/* load types */
|
||||||
w89k_regnames /* registers names */
|
w89k_regnames /* registers names */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user