diff options
author | Stu Grossman <grossman@cygnus> | 1996-02-24 06:39:44 +0000 |
---|---|---|
committer | Stu Grossman <grossman@cygnus> | 1996-02-24 06:39:44 +0000 |
commit | b5eccf74821ba768c8ed42e7113e5d8a22b955b4 (patch) | |
tree | 4b41c7bdd924765898f85af6af0d9f35ab3c312a /gdb/remote-e7000.c | |
parent | 805e36ab5d5b69a8ce62f3e2da4316a91e648f1c (diff) | |
download | gdb-b5eccf74821ba768c8ed42e7113e5d8a22b955b4.zip gdb-b5eccf74821ba768c8ed42e7113e5d8a22b955b4.tar.gz gdb-b5eccf74821ba768c8ed42e7113e5d8a22b955b4.tar.bz2 |
* remote-e7000.c (e7000_load): New routine to download via the
network.
* (e7000_wait): Don't backup PC when we hit a breakpoint.
Apparantly new sh2 pods get this right...
* (e7000_ops): Add call to e7000_load.
Diffstat (limited to 'gdb/remote-e7000.c')
-rw-r--r-- | gdb/remote-e7000.c | 167 |
1 files changed, 164 insertions, 3 deletions
diff --git a/gdb/remote-e7000.c b/gdb/remote-e7000.c index 105ae83..01c9856 100644 --- a/gdb/remote-e7000.c +++ b/gdb/remote-e7000.c @@ -1,5 +1,5 @@ /* Remote debugging interface for Hitachi E7000 ICE, for GDB - Copyright 1993, 1994 Free Software Foundation, Inc. + Copyright 1993, 1994, 1996 Free Software Foundation, Inc. Contributed by Cygnus Support. Written by Steve Chamberlain for Cygnus Support. @@ -1376,6 +1376,167 @@ e7000_kill (args, from_tty) { } +static void +e7000_load (args, from_tty) + char *args; + int from_tty; +{ + struct cleanup *old_chain; + asection *section; + bfd *pbfd; + bfd_vma entry; + int i; +#define WRITESIZE 0x1000 + char buf[2 + 4 + 4 + WRITESIZE]; /* `DT' + <addr> + <len> + <data> */ + char *filename; + int quiet; + int nostart; + + if (!strchr (dev_name, ':')) + { + generic_load (args, from_tty); + return; + } + + buf[0] = 'D'; + buf[1] = 'T'; + quiet = 0; + nostart = 0; + filename = NULL; + + while (*args != '\000') + { + char *arg; + + while (isspace (*args)) args++; + + arg = args; + + while ((*args != '\000') && !isspace (*args)) args++; + + if (*args != '\000') + *args++ = '\000'; + + if (*arg != '-') + filename = arg; + else if (strncmp (arg, "-quiet", strlen (arg)) == 0) + quiet = 1; + else if (strncmp (arg, "-nostart", strlen (arg)) == 0) + nostart = 1; + else + error ("unknown option `%s'", arg); + } + + if (!filename) + filename = get_exec_file (1); + + pbfd = bfd_openr (filename, gnutarget); + if (pbfd == NULL) + { + perror_with_name (filename); + return; + } + old_chain = make_cleanup (bfd_close, pbfd); + + if (!bfd_check_format (pbfd, bfd_object)) + error ("\"%s\" is not an object file: %s", filename, + bfd_errmsg (bfd_get_error ())); + + puts_e7000debug ("mw\r"); + + expect ("\nOK"); + + for (section = pbfd->sections; section; section = section->next) + { + if (bfd_get_section_flags (pbfd, section) & SEC_LOAD) + { + bfd_vma section_address; + bfd_size_type section_size; + file_ptr fptr; + + section_address = bfd_get_section_vma (pbfd, section); + section_size = bfd_get_section_size_before_reloc (section); + + if (!quiet) + printf_filtered ("[Loading section %s at 0x%x (%d bytes)]\n", + bfd_get_section_name (pbfd, section), + section_address, + section_size); + + fptr = 0; + + while (section_size > 0) + { + int count; + static char inds[] = "|/-\\"; + static int k = 0; + + QUIT; + + count = min (section_size, WRITESIZE); + + buf[2] = section_address >> 24; + buf[3] = section_address >> 16; + buf[4] = section_address >> 8; + buf[5] = section_address; + + buf[6] = count >> 24; + buf[7] = count >> 16; + buf[8] = count >> 8; + buf[9] = count; + + bfd_get_section_contents (pbfd, section, buf + 10, fptr, count); + + if (SERIAL_WRITE (e7000_desc, buf, count + 10)) + fprintf_unfiltered (gdb_stderr, "e7000_load: SERIAL_WRITE failed: %s\n", safe_strerror(errno)); + + expect ("OK"); + + if (!quiet) + { + printf_unfiltered ("\r%c", inds[k++ % 4]); + gdb_flush (gdb_stdout); + } + + section_address += count; + fptr += count; + section_size -= count; + } + } + } + + write_e7000 ("ED"); + + expect_prompt (); + +/* Finally, make the PC point at the start address */ + + if (exec_bfd) + write_pc (bfd_get_start_address (exec_bfd)); + + inferior_pid = 0; /* No process now */ + +/* This is necessary because many things were based on the PC at the time that + we attached to the monitor, which is no longer valid now that we have loaded + new code (and just changed the PC). Another way to do this might be to call + normal_stop, except that the stack may not be valid, and things would get + horribly confused... */ + + clear_symtab_users (); + + if (!nostart) + { + entry = bfd_get_start_address (pbfd); + + if (!quiet) + printf_unfiltered ("[Starting %s at 0x%x]\n", filename, entry); + +/* start_routine (entry);*/ + } + + do_cleanups (old_chain); +} + /* Clean up when a program exits. The program actually lives on in the remote processor's RAM, and may be @@ -1773,7 +1934,7 @@ e7000_wait (pid, status) switch (stop_reason) { case 1: /* Breakpoint */ - write_pc (read_pc () - 2); /* PC is always off by 2 for breakpoints */ + write_pc (read_pc ()); /* PC is always off by 2 for breakpoints */ status->value.sig = TARGET_SIGNAL_TRAP; break; case 0: /* Single step */ @@ -1846,7 +2007,7 @@ target e7000 foobar", 0, /* to_terminal_ours */ 0, /* to_terminal_info */ e7000_kill, /* to_kill */ - generic_load, /* to_load */ + e7000_load, /* to_load */ 0, /* to_lookup_symbol */ e7000_create_inferior, /* to_create_inferior */ e7000_mourn_inferior, /* to_mourn_inferior */ |