#include "gdbcmd.h"
#include "symtab.h"
#include "inferior.h"
+#include "infrun.h"
#include "bfd.h"
#include "symfile.h"
#include "objfiles.h"
static void target_info (char *, int);
+static void generic_tls_error (void) ATTRIBUTE_NORETURN;
+
static void default_terminal_info (struct target_ops *, const char *, int);
static int default_watchpoint_addr_within_range (struct target_ops *,
static int default_region_ok_for_hw_watchpoint (struct target_ops *,
CORE_ADDR, int);
-static void default_rcmd (struct target_ops *, char *, struct ui_file *);
+static void default_rcmd (struct target_ops *, const char *, struct ui_file *);
static ptid_t default_get_ada_task_ptid (struct target_ops *self,
long lwp, long tid);
const gdb_byte *data,
CORE_ADDR memaddr, ULONGEST size);
+static struct address_space *default_thread_address_space
+ (struct target_ops *self, ptid_t ptid);
+
static void tcomplain (void) ATTRIBUTE_NORETURN;
static int return_zero (struct target_ops *);
static void debug_to_terminal_ours (struct target_ops *self);
-static void debug_to_load (struct target_ops *self, char *, int);
+static void debug_to_load (struct target_ops *self, const char *, int);
static int debug_to_can_run (struct target_ops *self);
}
void
-target_load (char *arg, int from_tty)
+target_load (const char *arg, int from_tty)
{
target_dcache_invalidate ();
(*current_target.to_load) (¤t_target, arg, from_tty);
return 0;
}
+/* Default implementation of to_get_thread_local_address. */
+
+static void
+generic_tls_error (void)
+{
+ throw_error (TLS_GENERIC_ERROR,
+ _("Cannot find thread-local variables on this target"));
+}
+
/* Using the objfile specified in OBJFILE, find the address for the
current thread's thread-local storage with offset OFFSET. */
CORE_ADDR
target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
{
volatile CORE_ADDR addr = 0;
- struct target_ops *target;
-
- for (target = current_target.beneath;
- target != NULL;
- target = target->beneath)
- {
- if (target->to_get_thread_local_address != NULL)
- break;
- }
+ struct target_ops *target = ¤t_target;
- if (target != NULL
- && gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
+ if (gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
{
ptid_t ptid = inferior_ptid;
volatile struct gdb_exception ex;
/* Fetch the load module address for this objfile. */
lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch (),
objfile);
- /* If it's 0, throw the appropriate exception. */
- if (lm_addr == 0)
- throw_error (TLS_LOAD_MODULE_NOT_FOUND_ERROR,
- _("TLS load module not found"));
addr = target->to_get_thread_local_address (target, ptid,
lm_addr, offset);
}
void
-target_disconnect (char *args, int from_tty)
+target_disconnect (const char *args, int from_tty)
{
/* If we're in breakpoints-always-inserted mode or if breakpoints
are global across processes, we have to remove them before
gdb_signal_to_name (signal));
registers_changed_ptid (ptid);
+ /* We only set the internal executing state here. The user/frontend
+ running state is set at a higher level. */
set_executing (ptid, 1);
- set_running (ptid, 1);
clear_inline_frame_state (ptid);
}
internal_error (__FILE__, __LINE__, _("No targets found"));
}
+/* Whether GDB is allowed to fall back to the default run target for
+ "run", "attach", etc. when no target is connected yet. */
+static int auto_connect_native_target = 1;
+
+static void
+show_auto_connect_native_target (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c, const char *value)
+{
+ fprintf_filtered (file,
+ _("Whether GDB may automatically connect to the "
+ "native target is %s.\n"),
+ value);
+}
+
/* Look through the list of possible targets for a target that can
execute a run or attach command without any other data. This is
used to locate the default process stratum.
static struct target_ops *
find_default_run_target (char *do_mesg)
{
- struct target_ops **t;
struct target_ops *runable = NULL;
- int count;
- count = 0;
-
- for (t = target_structs; t < target_structs + target_struct_size;
- ++t)
+ if (auto_connect_native_target)
{
- if ((*t)->to_can_run != delegate_can_run && target_can_run (*t))
+ struct target_ops **t;
+ int count = 0;
+
+ for (t = target_structs; t < target_structs + target_struct_size;
+ ++t)
{
- runable = *t;
- ++count;
+ if ((*t)->to_can_run != delegate_can_run && target_can_run (*t))
+ {
+ runable = *t;
+ ++count;
+ }
}
+
+ if (count != 1)
+ runable = NULL;
}
- if (count != 1)
+ if (runable == NULL)
{
if (do_mesg)
error (_("Don't know how to %s. Try \"help target\"."), do_mesg);
/* Implement the "info proc" command. */
int
-target_info_proc (char *args, enum info_proc_what what)
+target_info_proc (const char *args, enum info_proc_what what)
{
struct target_ops *t;
return target_read_stralloc (t, TARGET_OBJECT_OSDATA, type);
}
-/* Determine the current address space of thread PTID. */
-
-struct address_space *
-target_thread_address_space (ptid_t ptid)
+static struct address_space *
+default_thread_address_space (struct target_ops *self, ptid_t ptid)
{
- struct address_space *aspace;
struct inferior *inf;
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- {
- if (t->to_thread_address_space != NULL)
- {
- aspace = t->to_thread_address_space (t, ptid);
- gdb_assert (aspace);
-
- if (targetdebug)
- fprintf_unfiltered (gdb_stdlog,
- "target_thread_address_space (%s) = %d\n",
- target_pid_to_str (ptid),
- address_space_num (aspace));
- return aspace;
- }
- }
/* Fall-back to the "main" address space of the inferior. */
inf = find_inferior_pid (ptid_get_pid (ptid));
return inf->aspace;
}
+/* Determine the current address space of thread PTID. */
+
+struct address_space *
+target_thread_address_space (ptid_t ptid)
+{
+ struct address_space *aspace;
+
+ aspace = current_target.to_thread_address_space (¤t_target, ptid);
+ gdb_assert (aspace != NULL);
+
+ if (targetdebug)
+ fprintf_unfiltered (gdb_stdlog,
+ "target_thread_address_space (%s) = %d\n",
+ target_pid_to_str (ptid),
+ address_space_num (aspace));
+
+ return aspace;
+}
+
/* Target file operations. */
/* See target.h. */
-void
-target_info_record (void)
-{
- struct target_ops *t;
-
- for (t = current_target.beneath; t != NULL; t = t->beneath)
- if (t->to_info_record != NULL)
- {
- t->to_info_record (t);
- return;
- }
-
- tcomplain ();
-}
-
-/* See target.h. */
-
void
target_save_record (const char *filename)
{
return current_target.to_decr_pc_after_break (¤t_target, gdbarch);
}
+/* See target.h. */
+
+void
+target_prepare_to_generate_core (void)
+{
+ current_target.to_prepare_to_generate_core (¤t_target);
+}
+
+/* See target.h. */
+
+void
+target_done_generating_core (void)
+{
+ current_target.to_done_generating_core (¤t_target);
+}
+
static void
debug_to_files_info (struct target_ops *target)
{
}
static void
-debug_to_load (struct target_ops *self, char *args, int from_tty)
+debug_to_load (struct target_ops *self, const char *args, int from_tty)
{
debug_target.to_load (&debug_target, args, from_tty);
}
static void
-debug_to_rcmd (struct target_ops *self, char *command,
+debug_to_rcmd (struct target_ops *self, const char *command,
struct ui_file *outbuf)
{
debug_target.to_rcmd (&debug_target, command, outbuf);
core-file, and process, if any), as well as the symbol file name.";
static void
-default_rcmd (struct target_ops *self, char *command, struct ui_file *output)
+default_rcmd (struct target_ops *self, const char *command,
+ struct ui_file *output)
{
error (_("\"monitor\" command not supported by this target."));
}
}
}
-/* Controls if async mode is permitted. */
-int target_async_permitted = 0;
+/* Controls if targets can report that they can/are async. This is
+ just for maintainers to use when debugging gdb. */
+int target_async_permitted = 1;
/* The set command writes to this variable. If the inferior is
executing, target_async_permitted is *not* updated. */
-static int target_async_permitted_1 = 0;
+static int target_async_permitted_1 = 1;
static void
-set_target_async_command (char *args, int from_tty,
- struct cmd_list_element *c)
+maint_set_target_async_command (char *args, int from_tty,
+ struct cmd_list_element *c)
{
if (have_live_inferiors ())
{
}
static void
-show_target_async_command (struct ui_file *file, int from_tty,
- struct cmd_list_element *c,
- const char *value)
+maint_show_target_async_command (struct ui_file *file, int from_tty,
+ struct cmd_list_element *c,
+ const char *value)
{
fprintf_filtered (file,
_("Controlling the inferior in "
Set whether gdb controls the inferior in asynchronous mode."), _("\
Show whether gdb controls the inferior in asynchronous mode."), _("\
Tells gdb whether to control the inferior in asynchronous mode."),
- set_target_async_command,
- show_target_async_command,
- &setlist,
- &showlist);
+ maint_set_target_async_command,
+ maint_show_target_async_command,
+ &maintenance_set_cmdlist,
+ &maintenance_show_cmdlist);
add_setshow_boolean_cmd ("may-write-registers", class_support,
&may_write_registers_1, _("\
Otherwise, any attempt to interrupt or stop will be ignored."),
set_target_permissions, NULL,
&setlist, &showlist);
+
+ add_setshow_boolean_cmd ("auto-connect-native-target", class_support,
+ &auto_connect_native_target, _("\
+Set whether GDB may automatically connect to the native target."), _("\
+Show whether GDB may automatically connect to the native target."), _("\
+When on, and GDB is not connected to a target yet, GDB\n\
+attempts \"run\" and other commands with the native target."),
+ NULL, show_auto_connect_native_target,
+ &setlist, &showlist);
}