X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fmonitor.c;h=1e61afdebbdaf65b9642851eab830e1a4f54428d;hb=e17a4113357102b55cfa5b80557d590a46a43300;hp=410ce629c63b67cf0a4dc4e57e874187cf42a123;hpb=9b072297d839dae1448ecaccc3480c720cfc4c35;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/monitor.c b/gdb/monitor.c index 410ce629c6..1e61afdebb 100644 --- a/gdb/monitor.c +++ b/gdb/monitor.c @@ -1,7 +1,7 @@ /* Remote debugging interface for boot monitors, for GDB. Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2006, 2007 Free Software Foundation, Inc. + 2000, 2001, 2002, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Cygnus Support. Written by Rob Savoye for Cygnus. Resurrected from the ashes by Stu Grossman. @@ -54,13 +54,14 @@ #include "gdb_regex.h" #include "srec.h" #include "regcache.h" +#include "gdbthread.h" static char *dev_name; static struct target_ops *targ_ops; static void monitor_interrupt_query (void); static void monitor_interrupt_twice (int); -static void monitor_stop (void); +static void monitor_stop (ptid_t); static void monitor_dump_regs (struct regcache *regcache); #if 0 @@ -105,6 +106,13 @@ static int dump_reg_flag; /* Non-zero means do a dump_registers cmd when static int first_time = 0; /* is this the first time we're executing after gaving created the child proccess? */ + +/* This is the ptid we use while we're connected to a monitor. Its + value is arbitrary, as monitor targets don't have a notion of + processes or threads, but we need something non-null to place in + inferior_ptid. */ +static ptid_t monitor_ptid; + #define TARGET_BUF_SIZE 2048 /* Monitor specific debugging information. Typically only useful to @@ -206,9 +214,13 @@ monitor_error (char *function, char *message, monitor_printable_string (safe_string, string, real_len); if (final_char) - error (_("%s (0x%s): %s: %s%c"), function, paddr_nz (memaddr), message, safe_string, final_char); + error (_("%s (%s): %s: %s%c"), + function, paddress (target_gdbarch, memaddr), + message, safe_string, final_char); else - error (_("%s (0x%s): %s: %s"), function, paddr_nz (memaddr), message, safe_string); + error (_("%s (%s): %s: %s"), + function, paddress (target_gdbarch, memaddr), + message, safe_string); } /* Convert hex digit A to a number. */ @@ -243,6 +255,7 @@ fromhex (int a) static void monitor_vsprintf (char *sndbuf, char *pattern, va_list args) { + int addr_bit = gdbarch_addr_bit (target_gdbarch); char format[10]; char fmt; char *p; @@ -271,7 +284,7 @@ monitor_vsprintf (char *sndbuf, char *pattern, va_list args) break; case 'A': arg_addr = va_arg (args, CORE_ADDR); - strcpy (sndbuf, paddr_nz (arg_addr)); + strcpy (sndbuf, phex_nz (arg_addr, addr_bit / 8)); break; case 's': arg_string = va_arg (args, char *); @@ -758,7 +771,7 @@ monitor_open (char *args, struct monitor_ops *mon_ops, int from_tty) if (current_monitor->stop) { - monitor_stop (); + monitor_stop (inferior_ptid); if ((current_monitor->flags & MO_NO_ECHO_ON_OPEN) == 0) { monitor_debug ("EXP Open echo\n"); @@ -804,7 +817,13 @@ monitor_open (char *args, struct monitor_ops *mon_ops, int from_tty) push_target (targ_ops); - inferior_ptid = pid_to_ptid (42000); /* Make run command think we are busy... */ + /* Start afresh. */ + init_thread_list (); + + /* Make run command think we are busy... */ + inferior_ptid = monitor_ptid; + add_inferior_silent (ptid_get_pid (inferior_ptid)); + add_thread_silent (inferior_ptid); /* Give monitor_wait something to read */ @@ -830,13 +849,16 @@ monitor_close (int quitting) } monitor_desc = NULL; + + delete_thread_silent (monitor_ptid); + delete_inferior_silent (ptid_get_pid (monitor_ptid)); } /* Terminate the open connection to the remote debugger. Use this when you want to detach and do something else with your gdb. */ static void -monitor_detach (char *args, int from_tty) +monitor_detach (struct target_ops *ops, char *args, int from_tty) { pop_target (); /* calls monitor_close to do the real work */ if (from_tty) @@ -848,6 +870,8 @@ monitor_detach (char *args, int from_tty) char * monitor_supply_register (struct regcache *regcache, int regno, char *valstr) { + struct gdbarch *gdbarch = get_regcache_arch (regcache); + enum bfd_endian byte_order = gdbarch_byte_order (gdbarch); ULONGEST val; unsigned char regbuf[MAX_REGISTER_SIZE]; char *p; @@ -883,8 +907,7 @@ monitor_supply_register (struct regcache *regcache, int regno, char *valstr) /* supply register stores in target byte order, so swap here */ - store_unsigned_integer (regbuf, - register_size (get_regcache_arch (regcache), regno), + store_unsigned_integer (regbuf, register_size (gdbarch, regno), byte_order, val); regcache_raw_supply (regcache, regno, regbuf); @@ -895,7 +918,8 @@ monitor_supply_register (struct regcache *regcache, int regno, char *valstr) /* Tell the remote machine to resume. */ static void -monitor_resume (ptid_t ptid, int step, enum target_signal sig) +monitor_resume (struct target_ops *ops, + ptid_t ptid, int step, enum target_signal sig) { /* Some monitors require a different command when starting a program */ monitor_debug ("MON resume\n"); @@ -968,7 +992,7 @@ monitor_interrupt (int signo) if (monitor_debug_p || remote_debug) fprintf_unfiltered (gdb_stdlog, "monitor_interrupt called\n"); - target_stop (); + target_stop (inferior_ptid); } /* The user typed ^C twice. */ @@ -990,8 +1014,8 @@ monitor_interrupt_query (void) { target_terminal_ours (); - if (query ("Interrupted while waiting for the program.\n\ -Give up (and stop debugging it)? ")) + if (query (_("Interrupted while waiting for the program.\n\ +Give up (and stop debugging it)? "))) { target_mourn_inferior (); deprecated_throw_reason (RETURN_QUIT); @@ -1046,7 +1070,8 @@ monitor_wait_filter (char *buf, status just as `wait' would. */ static ptid_t -monitor_wait (ptid_t ptid, struct target_waitstatus *status) +monitor_wait (struct target_ops *ops, + ptid_t ptid, struct target_waitstatus *status, int options) { int old_timeout = timeout; char buf[TARGET_BUF_SIZE]; @@ -1268,7 +1293,8 @@ monitor_dump_regs (struct regcache *regcache) } static void -monitor_fetch_registers (struct regcache *regcache, int regno) +monitor_fetch_registers (struct target_ops *ops, + struct regcache *regcache, int regno) { monitor_debug ("MON fetchregs\n"); if (current_monitor->getreg.cmd) @@ -1294,6 +1320,7 @@ monitor_fetch_registers (struct regcache *regcache, int regno) static void monitor_store_register (struct regcache *regcache, int regno) { + int reg_size = register_size (get_regcache_arch (regcache), regno); const char *name; ULONGEST val; @@ -1309,9 +1336,7 @@ monitor_store_register (struct regcache *regcache, int regno) } regcache_cooked_read_unsigned (regcache, regno, &val); - monitor_debug ("MON storeg %d %s\n", regno, - phex (val, - register_size (get_regcache_arch (regcache), regno))); + monitor_debug ("MON storeg %d %s\n", regno, phex (val, reg_size)); /* send the register deposit command */ @@ -1327,14 +1352,14 @@ monitor_store_register (struct regcache *regcache, int regno) monitor_debug ("EXP setreg.resp_delim\n"); monitor_expect_regexp (&setreg_resp_delim_pattern, NULL, 0); if (current_monitor->flags & MO_SETREG_INTERACTIVE) - monitor_printf ("%s\r", paddr_nz (val)); + monitor_printf ("%s\r", phex_nz (val, reg_size)); } if (current_monitor->setreg.term) { monitor_debug ("EXP setreg.term\n"); monitor_expect (current_monitor->setreg.term, NULL, 0); if (current_monitor->flags & MO_SETREG_INTERACTIVE) - monitor_printf ("%s\r", paddr_nz (val)); + monitor_printf ("%s\r", phex_nz (val, reg_size)); monitor_expect_prompt (NULL, 0); } else @@ -1350,7 +1375,8 @@ monitor_store_register (struct regcache *regcache, int regno) /* Store the remote registers. */ static void -monitor_store_registers (struct regcache *regcache, int regno) +monitor_store_registers (struct target_ops *ops, + struct regcache *regcache, int regno) { if (regno >= 0) { @@ -1384,14 +1410,15 @@ monitor_files_info (struct target_ops *ops) static int monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len) { + 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, paddr (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 (current_gdbarch, memaddr); + memaddr = gdbarch_addr_bits_remove (target_gdbarch, memaddr); /* Use memory fill command for leading 0 bytes. */ @@ -1440,7 +1467,7 @@ monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len) cmd = current_monitor->setmem.cmdb; } - val = extract_unsigned_integer (myaddr, len); + val = extract_unsigned_integer (myaddr, len, byte_order); if (len == 4) { @@ -1645,6 +1672,7 @@ monitor_write_memory_block (CORE_ADDR memaddr, char *myaddr, int len) static int monitor_read_memory_single (CORE_ADDR memaddr, char *myaddr, int len) { + enum bfd_endian byte_order = gdbarch_byte_order (target_gdbarch); unsigned int val; char membuf[sizeof (int) * 2 + 1]; char *p; @@ -1761,7 +1789,7 @@ monitor_read_memory_single (CORE_ADDR memaddr, char *myaddr, int len) /* supply register stores in target byte order, so swap here */ - store_unsigned_integer (myaddr, len, val); + store_unsigned_integer (myaddr, len, byte_order, val); return len; } @@ -1787,10 +1815,10 @@ monitor_read_memory (CORE_ADDR memaddr, char *myaddr, int len) } monitor_debug ("MON read block ta(%s) ha(%lx) %d\n", - paddr_nz (memaddr), (long) myaddr, len); + paddress (target_gdbarch, memaddr), (long) myaddr, len); if (current_monitor->flags & MO_ADDR_BITS_REMOVE) - memaddr = gdbarch_addr_bits_remove (current_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); @@ -1970,7 +1998,7 @@ monitor_xfer_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len, int write, } static void -monitor_kill (void) +monitor_kill (struct target_ops *ops) { return; /* ignore attempts to kill target system */ } @@ -1978,15 +2006,16 @@ monitor_kill (void) /* All we actually do is set the PC to the start address of exec_bfd. */ static void -monitor_create_inferior (char *exec_file, char *args, char **env, - int from_tty) +monitor_create_inferior (struct target_ops *ops, char *exec_file, + char *args, char **env, int from_tty) { if (args && (*args != '\000')) error (_("Args are not supported by the monitor.")); first_time = 1; clear_proceed_status (); - write_pc (bfd_get_start_address (exec_bfd)); + regcache_write_pc (get_current_regcache (), + bfd_get_start_address (exec_bfd)); } /* Clean up when a program exits. @@ -1995,31 +2024,32 @@ monitor_create_inferior (char *exec_file, char *args, char **env, instructions. */ static void -monitor_mourn_inferior (void) +monitor_mourn_inferior (struct target_ops *ops) { unpush_target (targ_ops); generic_mourn_inferior (); /* Do all the proper things now */ + delete_thread_silent (monitor_ptid); } /* Tell the monitor to add a breakpoint. */ static int -monitor_insert_breakpoint (struct bp_target_info *bp_tgt) +monitor_insert_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) { CORE_ADDR addr = bp_tgt->placed_address; int i; - const unsigned char *bp; int bplen; - monitor_debug ("MON inst bkpt %s\n", paddr (addr)); + monitor_debug ("MON inst bkpt %s\n", paddress (gdbarch, addr)); if (current_monitor->set_break == NULL) error (_("No set_break defined for this monitor")); if (current_monitor->flags & MO_ADDR_BITS_REMOVE) - addr = gdbarch_addr_bits_remove (current_gdbarch, addr); + addr = gdbarch_addr_bits_remove (gdbarch, addr); /* Determine appropriate breakpoint size for this address. */ - bp = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &bplen); + gdbarch_breakpoint_from_pc (gdbarch, &addr, &bplen); bp_tgt->placed_address = addr; bp_tgt->placed_size = bplen; @@ -2040,12 +2070,13 @@ monitor_insert_breakpoint (struct bp_target_info *bp_tgt) /* Tell the monitor to remove a breakpoint. */ static int -monitor_remove_breakpoint (struct bp_target_info *bp_tgt) +monitor_remove_breakpoint (struct gdbarch *gdbarch, + struct bp_target_info *bp_tgt) { CORE_ADDR addr = bp_tgt->placed_address; int i; - monitor_debug ("MON rmbkpt %s\n", paddr (addr)); + monitor_debug ("MON rmbkpt %s\n", paddress (gdbarch, addr)); if (current_monitor->clr_break == NULL) error (_("No clr_break defined for this monitor")); @@ -2066,8 +2097,8 @@ monitor_remove_breakpoint (struct bp_target_info *bp_tgt) } } fprintf_unfiltered (gdb_stderr, - "Can't find breakpoint associated with 0x%s\n", - paddr_nz (addr)); + "Can't find breakpoint associated with %s\n", + paddress (gdbarch, addr)); return 1; } @@ -2134,7 +2165,8 @@ monitor_load (char *file, int from_tty) /* Finally, make the PC point at the start address */ if (exec_bfd) - write_pc (bfd_get_start_address (exec_bfd)); + regcache_write_pc (get_current_regcache (), + bfd_get_start_address (exec_bfd)); /* There used to be code here which would clear inferior_ptid and call clear_symtab_users. None of that should be necessary: @@ -2152,7 +2184,7 @@ monitor_load (char *file, int from_tty) } static void -monitor_stop (void) +monitor_stop (ptid_t ptid) { monitor_debug ("MON stop\n"); if ((current_monitor->flags & MO_SEND_BREAK_ON_STOP) != 0) @@ -2211,6 +2243,35 @@ monitor_get_dev_name (void) return dev_name; } +/* Check to see if a thread is still alive. */ + +static int +monitor_thread_alive (struct target_ops *ops, ptid_t ptid) +{ + if (ptid_equal (ptid, monitor_ptid)) + /* The monitor's task is always alive. */ + return 1; + + return 0; +} + +/* Convert a thread ID to a string. Returns the string in a static + buffer. */ + +static char * +monitor_pid_to_str (struct target_ops *ops, ptid_t ptid) +{ + static char buf[64]; + + if (ptid_equal (monitor_ptid, ptid)) + { + xsnprintf (buf, sizeof buf, "Thread
"); + return buf; + } + + return normal_pid_to_str (ptid); +} + static struct target_ops monitor_ops; static void @@ -2233,12 +2294,15 @@ init_base_monitor_ops (void) monitor_ops.to_mourn_inferior = monitor_mourn_inferior; monitor_ops.to_stop = monitor_stop; monitor_ops.to_rcmd = monitor_rcmd; + monitor_ops.to_log_command = serial_log_command; + monitor_ops.to_thread_alive = monitor_thread_alive; + monitor_ops.to_pid_to_str = monitor_pid_to_str; monitor_ops.to_stratum = process_stratum; - monitor_ops.to_has_all_memory = 1; - monitor_ops.to_has_memory = 1; - monitor_ops.to_has_stack = 1; - monitor_ops.to_has_registers = 1; - monitor_ops.to_has_execution = 1; + monitor_ops.to_has_all_memory = default_child_has_all_memory; + monitor_ops.to_has_memory = default_child_has_memory; + monitor_ops.to_has_stack = default_child_has_stack; + monitor_ops.to_has_registers = default_child_has_registers; + monitor_ops.to_has_execution = default_child_has_execution; monitor_ops.to_magic = OPS_MAGIC; } /* init_base_monitor_ops */ @@ -2277,4 +2341,8 @@ is displayed."), NULL, NULL, /* FIXME: i18n: */ &setdebuglist, &showdebuglist); + + /* Yes, 42000 is arbitrary. The only sense out of it, is that it + isn't 0. */ + monitor_ptid = ptid_build (42000, 0, 42000); }