X-Git-Url: https://repo.jachan.dev/binutils.git/blobdiff_plain/6aba47ca06d9150c6196a374b745c2711b46e045..9f9d052e600ed9436f9fd558d62a189c8cc3d43e:/gdb/monitor.c diff --git a/gdb/monitor.c b/gdb/monitor.c index 0ed6f3de2d..c5b0ec669c 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 Free Software Foundation, Inc. Contributed by Cygnus Support. Written by Rob Savoye for Cygnus. Resurrected from the ashes by Stu Grossman. @@ -10,7 +10,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, @@ -19,9 +19,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ + along with this program. If not, see . */ /* This file was derived from various remote-* modules. It is a collection of generic support functions so GDB can talk directly to a ROM based @@ -56,14 +54,15 @@ #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_dump_regs (void); +static void monitor_stop (ptid_t); +static void monitor_dump_regs (struct regcache *regcache); #if 0 static int from_hex (int a); @@ -107,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 @@ -760,7 +766,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"); @@ -806,7 +812,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 */ @@ -832,6 +844,9 @@ 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 @@ -848,7 +863,7 @@ monitor_detach (char *args, int from_tty) /* Convert VALSTR into the target byte-ordered value of REGNO and store it. */ char * -monitor_supply_register (int regno, char *valstr) +monitor_supply_register (struct regcache *regcache, int regno, char *valstr) { ULONGEST val; unsigned char regbuf[MAX_REGISTER_SIZE]; @@ -885,9 +900,11 @@ monitor_supply_register (int regno, char *valstr) /* supply register stores in target byte order, so swap here */ - store_unsigned_integer (regbuf, register_size (current_gdbarch, regno), val); + store_unsigned_integer (regbuf, + register_size (get_regcache_arch (regcache), regno), + val); - regcache_raw_supply (current_regcache, regno, regbuf); + regcache_raw_supply (regcache, regno, regbuf); return p; } @@ -926,7 +943,7 @@ monitor_resume (ptid_t ptid, int step, enum target_signal sig) string which are passed down to monitor specific code. */ static void -parse_register_dump (char *buf, int len) +parse_register_dump (struct regcache *regcache, char *buf, int len) { monitor_debug ("MON Parsing register dump\n"); while (1) @@ -948,7 +965,8 @@ parse_register_dump (char *buf, int len) vallen = register_strings.end[2] - register_strings.start[2]; val = buf + register_strings.start[2]; - current_monitor->supply_register (regname, regnamelen, val, vallen); + current_monitor->supply_register (regcache, regname, regnamelen, + val, vallen); buf += register_strings.end[0]; len -= register_strings.end[0]; @@ -967,7 +985,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. */ @@ -1108,10 +1126,10 @@ monitor_wait (ptid_t ptid, struct target_waitstatus *status) } if (current_monitor->register_pattern) - parse_register_dump (buf, resp_len); + parse_register_dump (get_current_regcache (), buf, resp_len); #else monitor_debug ("Wait fetching registers after stop\n"); - monitor_dump_regs (); + monitor_dump_regs (get_current_regcache ()); #endif status->kind = TARGET_WAITKIND_STOPPED; @@ -1128,7 +1146,7 @@ monitor_wait (ptid_t ptid, struct target_waitstatus *status) errno value. */ static void -monitor_fetch_register (int regno) +monitor_fetch_register (struct regcache *regcache, int regno) { const char *name; char *zerobuf; @@ -1148,7 +1166,7 @@ monitor_fetch_register (int regno) if (!name || (*name == '\0')) { monitor_debug ("No register known for %d\n", regno); - regcache_raw_supply (current_regcache, regno, zerobuf); + regcache_raw_supply (regcache, regno, zerobuf); return; } @@ -1191,7 +1209,7 @@ monitor_fetch_register (int regno) spaces, but stop reading if something else is seen. Some monitors like to drop leading zeros. */ - for (i = 0; i < register_size (current_gdbarch, regno) * 2; i++) + for (i = 0; i < register_size (get_regcache_arch (regcache), regno) * 2; i++) { int c; c = readchar (timeout); @@ -1227,7 +1245,7 @@ monitor_fetch_register (int regno) current_monitor->getreg.term_cmd) /* ack expected */ monitor_expect_prompt (NULL, 0); /* get response */ - monitor_supply_register (regno, regbuf); + monitor_supply_register (regcache, regno, regbuf); } /* Sometimes, it takes several commands to dump the registers */ @@ -1235,13 +1253,13 @@ monitor_fetch_register (int regno) case they need to compose the operation. */ int -monitor_dump_reg_block (char *block_cmd) +monitor_dump_reg_block (struct regcache *regcache, char *block_cmd) { char buf[TARGET_BUF_SIZE]; int resp_len; monitor_printf (block_cmd); resp_len = monitor_expect_prompt (buf, sizeof (buf)); - parse_register_dump (buf, resp_len); + parse_register_dump (regcache, buf, resp_len); return 1; } @@ -1250,47 +1268,48 @@ monitor_dump_reg_block (char *block_cmd) /* Call the specific function if it has been provided */ static void -monitor_dump_regs (void) +monitor_dump_regs (struct regcache *regcache) { char buf[TARGET_BUF_SIZE]; int resp_len; if (current_monitor->dumpregs) - (*(current_monitor->dumpregs)) (); /* call supplied function */ + (*(current_monitor->dumpregs)) (regcache); /* call supplied function */ else if (current_monitor->dump_registers) /* default version */ { monitor_printf (current_monitor->dump_registers); resp_len = monitor_expect_prompt (buf, sizeof (buf)); - parse_register_dump (buf, resp_len); + parse_register_dump (regcache, buf, resp_len); } else internal_error (__FILE__, __LINE__, _("failed internal consistency check")); /* Need some way to read registers */ } static void -monitor_fetch_registers (int regno) +monitor_fetch_registers (struct regcache *regcache, int regno) { monitor_debug ("MON fetchregs\n"); if (current_monitor->getreg.cmd) { if (regno >= 0) { - monitor_fetch_register (regno); + monitor_fetch_register (regcache, regno); return; } - for (regno = 0; regno < NUM_REGS; regno++) - monitor_fetch_register (regno); + for (regno = 0; regno < gdbarch_num_regs (get_regcache_arch (regcache)); + regno++) + monitor_fetch_register (regcache, regno); } else { - monitor_dump_regs (); + monitor_dump_regs (regcache); } } /* Store register REGNO, or all if REGNO == 0. Return errno value. */ static void -monitor_store_register (int regno) +monitor_store_register (struct regcache *regcache, int regno) { const char *name; ULONGEST val; @@ -1306,9 +1325,10 @@ monitor_store_register (int regno) return; } - val = read_register (regno); + regcache_cooked_read_unsigned (regcache, regno, &val); monitor_debug ("MON storeg %d %s\n", regno, - phex (val, register_size (current_gdbarch, regno))); + phex (val, + register_size (get_regcache_arch (regcache), regno))); /* send the register deposit command */ @@ -1347,16 +1367,17 @@ monitor_store_register (int regno) /* Store the remote registers. */ static void -monitor_store_registers (int regno) +monitor_store_registers (struct regcache *regcache, int regno) { if (regno >= 0) { - monitor_store_register (regno); + monitor_store_register (regcache, regno); return; } - for (regno = 0; regno < NUM_REGS; regno++) - monitor_store_register (regno); + for (regno = 0; regno < gdbarch_num_regs (get_regcache_arch (regcache)); + regno++) + monitor_store_register (regcache, regno); } /* Get ready to modify the registers array. On machines which store @@ -1366,7 +1387,7 @@ monitor_store_registers (int regno) debugged. */ static void -monitor_prepare_to_store (void) +monitor_prepare_to_store (struct regcache *regcache) { /* Do nothing, since we can store individual regs */ } @@ -1387,7 +1408,7 @@ monitor_write_memory (CORE_ADDR memaddr, char *myaddr, int len) monitor_debug ("MON write %d %s\n", len, paddr (memaddr)); if (current_monitor->flags & MO_ADDR_BITS_REMOVE) - memaddr = ADDR_BITS_REMOVE (memaddr); + memaddr = gdbarch_addr_bits_remove (current_gdbarch, memaddr); /* Use memory fill command for leading 0 bytes. */ @@ -1786,7 +1807,7 @@ monitor_read_memory (CORE_ADDR memaddr, char *myaddr, int len) paddr_nz (memaddr), (long) myaddr, len); if (current_monitor->flags & MO_ADDR_BITS_REMOVE) - memaddr = ADDR_BITS_REMOVE (memaddr); + memaddr = gdbarch_addr_bits_remove (current_gdbarch, memaddr); if (current_monitor->flags & MO_GETMEM_READ_SINGLE) return monitor_read_memory_single (memaddr, myaddr, len); @@ -1995,6 +2016,7 @@ monitor_mourn_inferior (void) { 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. */ @@ -2012,7 +2034,7 @@ monitor_insert_breakpoint (struct bp_target_info *bp_tgt) error (_("No set_break defined for this monitor")); if (current_monitor->flags & MO_ADDR_BITS_REMOVE) - addr = ADDR_BITS_REMOVE (addr); + addr = gdbarch_addr_bits_remove (current_gdbarch, addr); /* Determine appropriate breakpoint size for this address. */ bp = gdbarch_breakpoint_from_pc (current_gdbarch, &addr, &bplen); @@ -2148,7 +2170,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) @@ -2207,6 +2229,35 @@ monitor_get_dev_name (void) return dev_name; } +/* Check to see if a thread is still alive. */ + +static int +monitor_thread_alive (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 (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 @@ -2229,6 +2280,9 @@ 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; @@ -2273,4 +2327,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); }