| Index: gdb/monitor.c
|
| diff --git a/gdb/monitor.c b/gdb/monitor.c
|
| index b9f345e4538056e358a86e30f8c7d331e8ee3718..2d94d4234b4c0138f92311ef7ad779659fda8e2f 100644
|
| --- a/gdb/monitor.c
|
| +++ b/gdb/monitor.c
|
| @@ -1,6 +1,6 @@
|
| /* Remote debugging interface for boot monitors, for GDB.
|
|
|
| - Copyright (C) 1990-2002, 2006-2012 Free Software Foundation, Inc.
|
| + Copyright (C) 1990-2013 Free Software Foundation, Inc.
|
|
|
| Contributed by Cygnus Support. Written by Rob Savoye for Cygnus.
|
| Resurrected from the ashes by Stu Grossman.
|
| @@ -43,7 +43,7 @@
|
| #include "exceptions.h"
|
| #include <signal.h>
|
| #include <ctype.h>
|
| -#include "gdb_string.h"
|
| +#include <string.h>
|
| #include <sys/types.h>
|
| #include "command.h"
|
| #include "serial.h"
|
| @@ -54,6 +54,7 @@
|
| #include "srec.h"
|
| #include "regcache.h"
|
| #include "gdbthread.h"
|
| +#include "readline/readline.h"
|
|
|
| static char *dev_name;
|
| static struct target_ops *targ_ops;
|
| @@ -120,7 +121,7 @@ static ptid_t monitor_ptid;
|
|
|
| static void monitor_debug (const char *fmt, ...) ATTRIBUTE_PRINTF (1, 2);
|
|
|
| -static int monitor_debug_p = 0;
|
| +static unsigned int monitor_debug_p = 0;
|
|
|
| /* NOTE: This file alternates between monitor_debug_p and remote_debug
|
| when determining if debug information is printed. Perhaps this
|
| @@ -217,11 +218,11 @@ monitor_error (char *function, char *message,
|
|
|
| if (final_char)
|
| error (_("%s (%s): %s: %s%c"),
|
| - function, paddress (target_gdbarch, memaddr),
|
| + function, paddress (target_gdbarch (), memaddr),
|
| message, safe_string, final_char);
|
| else
|
| error (_("%s (%s): %s: %s"),
|
| - function, paddress (target_gdbarch, memaddr),
|
| + function, paddress (target_gdbarch (), memaddr),
|
| message, safe_string);
|
| }
|
|
|
| @@ -256,7 +257,7 @@ fromhex (int a)
|
| static void
|
| monitor_vsprintf (char *sndbuf, char *pattern, va_list args)
|
| {
|
| - int addr_bit = gdbarch_addr_bit (target_gdbarch);
|
| + int addr_bit = gdbarch_addr_bit (target_gdbarch ());
|
| char format[10];
|
| char fmt;
|
| char *p;
|
| @@ -512,6 +513,7 @@ monitor_expect (char *string, char *buf, int buflen)
|
| }
|
|
|
| immediate_quit++;
|
| + QUIT;
|
| while (1)
|
| {
|
| if (buf)
|
| @@ -851,7 +853,7 @@ monitor_open (char *args, struct monitor_ops *mon_ops, int from_tty)
|
| control. */
|
|
|
| void
|
| -monitor_close (int quitting)
|
| +monitor_close (void)
|
| {
|
| if (monitor_desc)
|
| serial_close (monitor_desc);
|
| @@ -873,9 +875,9 @@ monitor_close (int quitting)
|
| when you want to detach and do something else with your gdb. */
|
|
|
| static void
|
| -monitor_detach (struct target_ops *ops, char *args, int from_tty)
|
| +monitor_detach (struct target_ops *ops, const char *args, int from_tty)
|
| {
|
| - pop_target (); /* calls monitor_close to do the real work. */
|
| + unpush_target (ops); /* calls monitor_close to do the real work. */
|
| if (from_tty)
|
| printf_unfiltered (_("Ending remote %s debugging\n"), target_shortname);
|
| }
|
| @@ -1034,7 +1036,7 @@ monitor_interrupt_query (void)
|
| Give up (and stop debugging it)? ")))
|
| {
|
| target_mourn_inferior ();
|
| - deprecated_throw_reason (RETURN_QUIT);
|
| + quit ();
|
| }
|
|
|
| target_terminal_inferior ();
|
| @@ -1437,17 +1439,17 @@ monitor_files_info (struct target_ops *ops)
|
| }
|
|
|
| static int
|
| -monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
|
| +monitor_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
|
| {
|
| - enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
|
| + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
|
| unsigned int val, hostval;
|
| char *cmd;
|
| int i;
|
|
|
| - monitor_debug ("MON write %d %s\n", len, paddress (target_gdbarch, memaddr));
|
| + monitor_debug ("MON write %d %s\n", len, paddress (target_gdbarch (), memaddr));
|
|
|
| if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
|
| - memaddr = gdbarch_addr_bits_remove (target_gdbarch, memaddr);
|
| + memaddr = gdbarch_addr_bits_remove (target_gdbarch (), memaddr);
|
|
|
| /* Use memory fill command for leading 0 bytes. */
|
|
|
| @@ -1540,7 +1542,7 @@ monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len)
|
|
|
|
|
| static int
|
| -monitor_write_memory_bytes (CORE_ADDR memaddr, char *myaddr, int len)
|
| +monitor_write_memory_bytes (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
|
| {
|
| unsigned char val;
|
| int written = 0;
|
| @@ -1636,7 +1638,7 @@ longlong_hexchars (unsigned long long value,
|
| Which possably entails endian conversions. */
|
|
|
| static int
|
| -monitor_write_memory_longlongs (CORE_ADDR memaddr, char *myaddr, int len)
|
| +monitor_write_memory_longlongs (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
|
| {
|
| static char hexstage[20]; /* At least 16 digits required, plus null. */
|
| char *endstring;
|
| @@ -1644,7 +1646,7 @@ monitor_write_memory_longlongs (CORE_ADDR memaddr, char *myaddr, int len)
|
| long long value;
|
| int written = 0;
|
|
|
| - llptr = (unsigned long long *) myaddr;
|
| + llptr = (long long *) myaddr;
|
| if (len == 0)
|
| return 0;
|
| monitor_printf (current_monitor->setmem.cmdll, memaddr);
|
| @@ -1684,7 +1686,7 @@ monitor_write_memory_longlongs (CORE_ADDR memaddr, char *myaddr, int len)
|
| monitor variations. */
|
|
|
| static int
|
| -monitor_write_memory_block (CORE_ADDR memaddr, char *myaddr, int len)
|
| +monitor_write_memory_block (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
|
| {
|
| int written;
|
|
|
| @@ -1704,9 +1706,9 @@ monitor_write_memory_block (CORE_ADDR memaddr, char *myaddr, int len)
|
| which can only read a single byte/word/etc. at a time. */
|
|
|
| static int
|
| -monitor_read_memory_single (CORE_ADDR memaddr, char *myaddr, int len)
|
| +monitor_read_memory_single (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
|
| {
|
| - enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch);
|
| + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch ());
|
| unsigned int val;
|
| char membuf[sizeof (int) * 2 + 1];
|
| char *p;
|
| @@ -1835,7 +1837,7 @@ monitor_read_memory_single (CORE_ADDR memaddr, char *myaddr, int len)
|
| than 16 bytes at a time. */
|
|
|
| static int
|
| -monitor_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
|
| +monitor_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
|
| {
|
| unsigned int val;
|
| char buf[512];
|
| @@ -1851,11 +1853,11 @@ monitor_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
|
| }
|
|
|
| monitor_debug ("MON read block ta(%s) ha(%s) %d\n",
|
| - paddress (target_gdbarch, memaddr),
|
| + paddress (target_gdbarch (), memaddr),
|
| host_address_to_string (myaddr), len);
|
|
|
| if (current_monitor->flags & MO_ADDR_BITS_REMOVE)
|
| - memaddr = gdbarch_addr_bits_remove (target_gdbarch, memaddr);
|
| + memaddr = gdbarch_addr_bits_remove (target_gdbarch (), memaddr);
|
|
|
| if (current_monitor->flags & MO_GETMEM_READ_SINGLE)
|
| return monitor_read_memory_single (memaddr, myaddr, len);
|
| @@ -2013,31 +2015,49 @@ monitor_read_memory (CORE_ADDR memaddr, char *myaddr, int len)
|
| return len;
|
| }
|
|
|
| -/* Transfer LEN bytes between target address MEMADDR and GDB address
|
| - MYADDR. Returns 0 for success, errno code for failure. TARGET is
|
| - unused. */
|
| +/* Helper for monitor_xfer_partial that handles memory transfers.
|
| + Arguments are like target_xfer_partial. */
|
|
|
| -static int
|
| -monitor_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write,
|
| - struct mem_attrib *attrib, struct target_ops *target)
|
| +static LONGEST
|
| +monitor_xfer_memory (gdb_byte *readbuf, const gdb_byte *writebuf,
|
| + ULONGEST memaddr, LONGEST len)
|
| {
|
| int res;
|
|
|
| - if (write)
|
| + if (writebuf != NULL)
|
| {
|
| if (current_monitor->flags & MO_HAS_BLOCKWRITES)
|
| - res = monitor_write_memory_block(memaddr, myaddr, len);
|
| + res = monitor_write_memory_block (memaddr, writebuf, len);
|
| else
|
| - res = monitor_write_memory(memaddr, myaddr, len);
|
| + res = monitor_write_memory (memaddr, writebuf, len);
|
| }
|
| else
|
| {
|
| - res = monitor_read_memory(memaddr, myaddr, len);
|
| + res = monitor_read_memory (memaddr, readbuf, len);
|
| }
|
|
|
| + if (res == 0)
|
| + return TARGET_XFER_E_IO;
|
| return res;
|
| }
|
|
|
| +/* Target to_xfer_partial implementation. */
|
| +
|
| +static LONGEST
|
| +monitor_xfer_partial (struct target_ops *ops, enum target_object object,
|
| + const char *annex, gdb_byte *readbuf,
|
| + const gdb_byte *writebuf, ULONGEST offset, LONGEST len)
|
| +{
|
| + switch (object)
|
| + {
|
| + case TARGET_OBJECT_MEMORY:
|
| + return monitor_xfer_memory (readbuf, writebuf, offset, len);
|
| +
|
| + default:
|
| + return TARGET_XFER_E_IO;
|
| + }
|
| +}
|
| +
|
| static void
|
| monitor_kill (struct target_ops *ops)
|
| {
|
| @@ -2174,37 +2194,53 @@ monitor_wait_srec_ack (void)
|
| /* monitor_load -- download a file. */
|
|
|
| static void
|
| -monitor_load (char *file, int from_tty)
|
| +monitor_load (char *args, int from_tty)
|
| {
|
| + CORE_ADDR load_offset = 0;
|
| + char **argv;
|
| + struct cleanup *old_cleanups;
|
| + char *filename;
|
| +
|
| monitor_debug ("MON load\n");
|
|
|
| - if (current_monitor->load_routine)
|
| - current_monitor->load_routine (monitor_desc, file, hashmark);
|
| - else
|
| - { /* The default is ascii S-records. */
|
| - int n;
|
| - unsigned long load_offset;
|
| - char buf[128];
|
| -
|
| - /* Enable user to specify address for downloading as 2nd arg to load. */
|
| - n = sscanf (file, "%s 0x%lx", buf, &load_offset);
|
| - if (n > 1)
|
| - file = buf;
|
| - else
|
| - load_offset = 0;
|
| + if (args == NULL)
|
| + error_no_arg (_("file to load"));
|
|
|
| - monitor_printf (current_monitor->load);
|
| - if (current_monitor->loadresp)
|
| - monitor_expect (current_monitor->loadresp, NULL, 0);
|
| + argv = gdb_buildargv (args);
|
| + old_cleanups = make_cleanup_freeargv (argv);
|
|
|
| - load_srec (monitor_desc, file, (bfd_vma) load_offset,
|
| - 32, SREC_ALL, hashmark,
|
| - current_monitor->flags & MO_SREC_ACK ?
|
| - monitor_wait_srec_ack : NULL);
|
| + filename = tilde_expand (argv[0]);
|
| + make_cleanup (xfree, filename);
|
|
|
| - monitor_expect_prompt (NULL, 0);
|
| + /* Enable user to specify address for downloading as 2nd arg to load. */
|
| + if (argv[1] != NULL)
|
| + {
|
| + const char *endptr;
|
| +
|
| + load_offset = strtoulst (argv[1], &endptr, 0);
|
| +
|
| + /* If the last word was not a valid number then
|
| + treat it as a file name with spaces in. */
|
| + if (argv[1] == endptr)
|
| + error (_("Invalid download offset:%s."), argv[1]);
|
| +
|
| + if (argv[2] != NULL)
|
| + error (_("Too many parameters."));
|
| }
|
|
|
| + monitor_printf (current_monitor->load);
|
| + if (current_monitor->loadresp)
|
| + monitor_expect (current_monitor->loadresp, NULL, 0);
|
| +
|
| + load_srec (monitor_desc, filename, load_offset,
|
| + 32, SREC_ALL, hashmark,
|
| + current_monitor->flags & MO_SREC_ACK ?
|
| + monitor_wait_srec_ack : NULL);
|
| +
|
| + monitor_expect_prompt (NULL, 0);
|
| +
|
| + do_cleanups (old_cleanups);
|
| +
|
| /* Finally, make the PC point at the start address. */
|
| if (exec_bfd)
|
| regcache_write_pc (get_current_regcache (),
|
| @@ -2326,7 +2362,7 @@ init_base_monitor_ops (void)
|
| monitor_ops.to_fetch_registers = monitor_fetch_registers;
|
| monitor_ops.to_store_registers = monitor_store_registers;
|
| monitor_ops.to_prepare_to_store = monitor_prepare_to_store;
|
| - monitor_ops.deprecated_xfer_memory = monitor_xfer_memory;
|
| + monitor_ops.to_xfer_partial = monitor_xfer_partial;
|
| monitor_ops.to_files_info = monitor_files_info;
|
| monitor_ops.to_insert_breakpoint = monitor_insert_breakpoint;
|
| monitor_ops.to_remove_breakpoint = monitor_remove_breakpoint;
|
| @@ -2376,14 +2412,14 @@ When enabled, a hashmark \'#\' is displayed."),
|
| NULL, /* FIXME: i18n: */
|
| &setlist, &showlist);
|
|
|
| - add_setshow_zinteger_cmd ("monitor", no_class, &monitor_debug_p, _("\
|
| + add_setshow_zuinteger_cmd ("monitor", no_class, &monitor_debug_p, _("\
|
| Set debugging of remote monitor communication."), _("\
|
| Show debugging of remote monitor communication."), _("\
|
| When enabled, communication between GDB and the remote monitor\n\
|
| is displayed."),
|
| - NULL,
|
| - NULL, /* FIXME: i18n: */
|
| - &setdebuglist, &showdebuglist);
|
| + NULL,
|
| + NULL, /* FIXME: i18n: */
|
| + &setdebuglist, &showdebuglist);
|
|
|
| /* Yes, 42000 is arbitrary. The only sense out of it, is that it
|
| isn't 0. */
|
|
|