X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ftarget.c;h=81389a778fbb54cbd5e5046a0e2fd7d164814dd4;hb=f33e9acf1b9d497a366d072caee34548fcfdf1cb;hp=b50ec1c94ab0068cbbe9066498fbb90b1149a83e;hpb=fba45db2faf619e71856ee38ec63949c0ef6903e;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/target.c b/gdb/target.c index b50ec1c94a..81389a778f 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -1,5 +1,8 @@ /* Select target systems and architectures at runtime for GDB. - Copyright 1990, 1992-1995, 1998-2000 Free Software Foundation, Inc. + + Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, + 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. + Contributed by Cygnus Support. This file is part of GDB. @@ -21,7 +24,6 @@ #include "defs.h" #include -#include #include "gdb_string.h" #include "target.h" #include "gdbcmd.h" @@ -31,24 +33,22 @@ #include "symfile.h" #include "objfiles.h" #include "gdb_wait.h" +#include "dcache.h" #include - -extern int errno; +#include "regcache.h" +#include "gdb_assert.h" +#include "gdbcore.h" static void target_info (char *, int); -static void cleanup_target (struct target_ops *); - -static void maybe_kill_then_create_inferior (char *, char *, char **); - -static void default_clone_and_follow_inferior (int, int *); - static void maybe_kill_then_attach (char *, int); static void kill_or_be_killed (int); static void default_terminal_info (char *, int); +static int default_region_size_ok_for_hw_watchpoint (int); + static int nosymbol (char *, CORE_ADDR *); static void tcomplain (void); @@ -59,17 +59,21 @@ static int return_zero (void); static int return_one (void); +static int return_minus_one (void); + void target_ignore (void); static void target_command (char *, int); static struct target_ops *find_default_run_target (char *); -static void update_current_target (void); - static void nosupport_runtime (void); -static void normal_target_post_startup_inferior (int pid); +static LONGEST default_xfer_partial (struct target_ops *ops, + enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, + ULONGEST offset, LONGEST len); /* Transfer LEN bytes between target address MEMADDR and GDB address MYADDR. Returns 0 for success, errno code for failure (which @@ -77,11 +81,13 @@ static void normal_target_post_startup_inferior (int pid); partial transfers, try either target_read_memory_partial or target_write_memory_partial). */ -static int -target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write); +static int target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write); static void init_dummy_target (void); +static struct target_ops debug_target; + static void debug_to_open (char *, int); static void debug_to_close (int); @@ -90,9 +96,11 @@ static void debug_to_attach (char *, int); static void debug_to_detach (char *, int); -static void debug_to_resume (int, int, enum target_signal); +static void debug_to_disconnect (char *, int); -static int debug_to_wait (int, struct target_waitstatus *); +static void debug_to_resume (ptid_t, int, enum target_signal); + +static ptid_t debug_to_wait (ptid_t, struct target_waitstatus *); static void debug_to_fetch_registers (int); @@ -100,8 +108,9 @@ static void debug_to_store_registers (int); static void debug_to_prepare_to_store (void); -static int -debug_to_xfer_memory (CORE_ADDR, char *, int, int, struct target_ops *); +static int deprecated_debug_xfer_memory (CORE_ADDR, char *, int, int, + struct mem_attrib *, + struct target_ops *); static void debug_to_files_info (struct target_ops *); @@ -109,12 +118,30 @@ static int debug_to_insert_breakpoint (CORE_ADDR, char *); static int debug_to_remove_breakpoint (CORE_ADDR, char *); +static int debug_to_can_use_hw_breakpoint (int, int, int); + +static int debug_to_insert_hw_breakpoint (CORE_ADDR, char *); + +static int debug_to_remove_hw_breakpoint (CORE_ADDR, char *); + +static int debug_to_insert_watchpoint (CORE_ADDR, int, int); + +static int debug_to_remove_watchpoint (CORE_ADDR, int, int); + +static int debug_to_stopped_by_watchpoint (void); + +static int debug_to_stopped_data_address (struct target_ops *, CORE_ADDR *); + +static int debug_to_region_size_ok_for_hw_watchpoint (int); + static void debug_to_terminal_init (void); static void debug_to_terminal_inferior (void); static void debug_to_terminal_ours_for_output (void); +static void debug_to_terminal_save_ours (void); + static void debug_to_terminal_ours (void); static void debug_to_terminal_info (char *, int); @@ -125,19 +152,21 @@ static void debug_to_load (char *, int); static int debug_to_lookup_symbol (char *, CORE_ADDR *); -static void debug_to_create_inferior (char *, char *, char **); - static void debug_to_mourn_inferior (void); static int debug_to_can_run (void); -static void debug_to_notice_signals (int); +static void debug_to_notice_signals (ptid_t); -static int debug_to_thread_alive (int); +static int debug_to_thread_alive (ptid_t); static void debug_to_stop (void); -static int debug_to_query (int /*char */ , char *, char *, int *); +/* NOTE: cagney/2004-09-29: Many targets reference this variable in + wierd and mysterious ways. Putting the variable here lets those + wierd and mysterious ways keep building while they are being + converted to the inferior inheritance structure. */ +struct target_ops deprecated_child_ops; /* Pointer to array of target architecture structures; the size of the array; the current index into the array; the allocated size of the @@ -155,7 +184,7 @@ static struct target_ops dummy_target; /* Top of target stack. */ -struct target_stack_item *target_stack; +static struct target_ops *target_stack; /* The target structure we are currently using to talk to a process or file or whatever "inferior" we have. */ @@ -177,9 +206,10 @@ static int targetdebug = 0; static void setup_target_debug (void); +DCACHE *target_dcache; + /* The user just typed 'target' without the name of a target. */ -/* ARGSUSED */ static void target_command (char *arg, int from_tty) { @@ -192,6 +222,10 @@ target_command (char *arg, int from_tty) void add_target (struct target_ops *t) { + /* Provide default values for all "must have" methods. */ + if (t->to_xfer_partial == NULL) + t->to_xfer_partial = default_xfer_partial; + if (!target_structs) { target_struct_allocsize = DEFAULT_ALLOCSIZE; @@ -206,7 +240,6 @@ add_target (struct target_ops *t) target_struct_allocsize * sizeof (*target_structs)); } target_structs[target_struct_size++] = t; -/* cleanup_target (t); */ if (targetlist == NULL) add_prefix_cmd ("target", class_run, target_command, @@ -229,10 +262,10 @@ target_ignore (void) void target_load (char *arg, int from_tty) { + dcache_invalidate (target_dcache); (*current_target.to_load) (arg, from_tty); } -/* ARGSUSED */ static int nomemory (CORE_ADDR memaddr, char *myaddr, int len, int write, struct target_ops *t) @@ -254,25 +287,22 @@ noprocess (void) error ("You can't do that without a process to debug."); } -/* ARGSUSED */ static int nosymbol (char *name, CORE_ADDR *addrp) { return 1; /* Symbol does not exist in target env */ } -/* ARGSUSED */ static void nosupport_runtime (void) { - if (!inferior_pid) + if (ptid_equal (inferior_ptid, null_ptid)) noprocess (); else error ("No run-time support for this"); } -/* ARGSUSED */ static void default_terminal_info (char *args, int from_tty) { @@ -314,28 +344,127 @@ maybe_kill_then_attach (char *args, int from_tty) } static void -maybe_kill_then_create_inferior (char *exec, char *args, char **env) +maybe_kill_then_create_inferior (char *exec, char *args, char **env, + int from_tty) { kill_or_be_killed (0); - target_create_inferior (exec, args, env); + target_create_inferior (exec, args, env, from_tty); } -static void -default_clone_and_follow_inferior (int child_pid, int *followed_child) -{ - target_clone_and_follow_inferior (child_pid, followed_child); -} +/* Go through the target stack from top to bottom, copying over zero + entries in current_target, then filling in still empty entries. In + effect, we are doing class inheritance through the pushed target + vectors. -/* Clean up a target struct so it no longer has any zero pointers in it. - We default entries, at least to stubs that print error messages. */ + NOTE: cagney/2003-10-17: The problem with this inheritance, as it + is currently implemented, is that it discards any knowledge of + which target an inherited method originally belonged to. + Consequently, new new target methods should instead explicitly and + locally search the target stack for the target that can handle the + request. */ static void -cleanup_target (struct target_ops *t) +update_current_target (void) { + struct target_ops *t; + + /* First, reset curren'ts contents. */ + memset (¤t_target, 0, sizeof (current_target)); + +#define INHERIT(FIELD, TARGET) \ + if (!current_target.FIELD) \ + current_target.FIELD = (TARGET)->FIELD + + for (t = target_stack; t; t = t->beneath) + { + INHERIT (to_shortname, t); + INHERIT (to_longname, t); + INHERIT (to_doc, t); + INHERIT (to_open, t); + INHERIT (to_close, t); + INHERIT (to_attach, t); + INHERIT (to_post_attach, t); + INHERIT (to_detach, t); + INHERIT (to_disconnect, t); + INHERIT (to_resume, t); + INHERIT (to_wait, t); + INHERIT (to_fetch_registers, t); + INHERIT (to_store_registers, t); + INHERIT (to_prepare_to_store, t); + INHERIT (deprecated_xfer_memory, t); + INHERIT (to_files_info, t); + INHERIT (to_insert_breakpoint, t); + INHERIT (to_remove_breakpoint, t); + INHERIT (to_can_use_hw_breakpoint, t); + INHERIT (to_insert_hw_breakpoint, t); + INHERIT (to_remove_hw_breakpoint, t); + INHERIT (to_insert_watchpoint, t); + INHERIT (to_remove_watchpoint, t); + INHERIT (to_stopped_data_address, t); + INHERIT (to_stopped_by_watchpoint, t); + INHERIT (to_have_continuable_watchpoint, t); + INHERIT (to_region_size_ok_for_hw_watchpoint, t); + INHERIT (to_terminal_init, t); + INHERIT (to_terminal_inferior, t); + INHERIT (to_terminal_ours_for_output, t); + INHERIT (to_terminal_ours, t); + INHERIT (to_terminal_save_ours, t); + INHERIT (to_terminal_info, t); + INHERIT (to_kill, t); + INHERIT (to_load, t); + INHERIT (to_lookup_symbol, t); + INHERIT (to_create_inferior, t); + INHERIT (to_post_startup_inferior, t); + INHERIT (to_acknowledge_created_inferior, t); + INHERIT (to_insert_fork_catchpoint, t); + INHERIT (to_remove_fork_catchpoint, t); + INHERIT (to_insert_vfork_catchpoint, t); + INHERIT (to_remove_vfork_catchpoint, t); + INHERIT (to_follow_fork, t); + INHERIT (to_insert_exec_catchpoint, t); + INHERIT (to_remove_exec_catchpoint, t); + INHERIT (to_reported_exec_events_per_exec_call, t); + INHERIT (to_has_exited, t); + INHERIT (to_mourn_inferior, t); + INHERIT (to_can_run, t); + INHERIT (to_notice_signals, t); + INHERIT (to_thread_alive, t); + INHERIT (to_find_new_threads, t); + INHERIT (to_pid_to_str, t); + INHERIT (to_extra_thread_info, t); + INHERIT (to_stop, t); + /* Do not inherit to_xfer_partial. */ + INHERIT (to_rcmd, t); + INHERIT (to_enable_exception_callback, t); + INHERIT (to_get_current_exception_event, t); + INHERIT (to_pid_to_exec_file, t); + INHERIT (to_stratum, t); + INHERIT (to_has_all_memory, t); + INHERIT (to_has_memory, t); + INHERIT (to_has_stack, t); + INHERIT (to_has_registers, t); + INHERIT (to_has_execution, t); + INHERIT (to_has_thread_control, t); + INHERIT (to_sections, t); + INHERIT (to_sections_end, t); + INHERIT (to_can_async_p, t); + INHERIT (to_is_async_p, t); + INHERIT (to_async, t); + INHERIT (to_async_mask_value, t); + INHERIT (to_find_memory_regions, t); + INHERIT (to_make_corefile_notes, t); + INHERIT (to_get_thread_local_address, t); + INHERIT (to_magic, t); + } +#undef INHERIT + + /* Clean up a target struct so it no longer has any zero pointers in + it. Some entries are defaulted to a method that print an error, + others are hard-wired to a standard recursive default. */ #define de_fault(field, value) \ - if (!t->field) \ - t->field = value + if (!current_target.field) \ + current_target.field = value de_fault (to_open, (void (*) (char *, int)) @@ -348,23 +477,18 @@ cleanup_target (struct target_ops *t) de_fault (to_post_attach, (void (*) (int)) target_ignore); - de_fault (to_require_attach, - maybe_kill_then_attach); de_fault (to_detach, (void (*) (char *, int)) target_ignore); - de_fault (to_require_detach, - (void (*) (int, char *, int)) - target_ignore); + de_fault (to_disconnect, + (void (*) (char *, int)) + tcomplain); de_fault (to_resume, - (void (*) (int, int, enum target_signal)) + (void (*) (ptid_t, int, enum target_signal)) noprocess); de_fault (to_wait, - (int (*) (int, struct target_waitstatus *)) + (ptid_t (*) (ptid_t, struct target_waitstatus *)) noprocess); - de_fault (to_post_wait, - (void (*) (int, int)) - target_ignore); de_fault (to_fetch_registers, (void (*) (int)) target_ignore); @@ -374,8 +498,8 @@ cleanup_target (struct target_ops *t) de_fault (to_prepare_to_store, (void (*) (void)) noprocess); - de_fault (to_xfer_memory, - (int (*) (CORE_ADDR, char *, int, int, struct target_ops *)) + de_fault (deprecated_xfer_memory, + (int (*) (CORE_ADDR, char *, int, int, struct mem_attrib *, struct target_ops *)) nomemory); de_fault (to_files_info, (void (*) (struct target_ops *)) @@ -384,6 +508,29 @@ cleanup_target (struct target_ops *t) memory_insert_breakpoint); de_fault (to_remove_breakpoint, memory_remove_breakpoint); + de_fault (to_can_use_hw_breakpoint, + (int (*) (int, int, int)) + return_zero); + de_fault (to_insert_hw_breakpoint, + (int (*) (CORE_ADDR, char *)) + return_minus_one); + de_fault (to_remove_hw_breakpoint, + (int (*) (CORE_ADDR, char *)) + return_minus_one); + de_fault (to_insert_watchpoint, + (int (*) (CORE_ADDR, int, int)) + return_minus_one); + de_fault (to_remove_watchpoint, + (int (*) (CORE_ADDR, int, int)) + return_minus_one); + de_fault (to_stopped_by_watchpoint, + (int (*) (void)) + return_zero); + de_fault (to_stopped_data_address, + (int (*) (struct target_ops *, CORE_ADDR *)) + return_zero); + de_fault (to_region_size_ok_for_hw_watchpoint, + default_region_size_ok_for_hw_watchpoint); de_fault (to_terminal_init, (void (*) (void)) target_ignore); @@ -396,6 +543,9 @@ cleanup_target (struct target_ops *t) de_fault (to_terminal_ours, (void (*) (void)) target_ignore); + de_fault (to_terminal_save_ours, + (void (*) (void)) + target_ignore); de_fault (to_terminal_info, default_terminal_info); de_fault (to_kill, @@ -410,16 +560,11 @@ cleanup_target (struct target_ops *t) de_fault (to_create_inferior, maybe_kill_then_create_inferior); de_fault (to_post_startup_inferior, - (void (*) (int)) + (void (*) (ptid_t)) target_ignore); de_fault (to_acknowledge_created_inferior, (void (*) (int)) target_ignore); - de_fault (to_clone_and_follow_inferior, - default_clone_and_follow_inferior); - de_fault (to_post_follow_inferior_by_clone, - (void (*) (void)) - target_ignore); de_fault (to_insert_fork_catchpoint, (int (*) (int)) tcomplain); @@ -432,17 +577,8 @@ cleanup_target (struct target_ops *t) de_fault (to_remove_vfork_catchpoint, (int (*) (int)) tcomplain); - de_fault (to_has_forked, - (int (*) (int, int *)) - return_zero); - de_fault (to_has_vforked, - (int (*) (int, int *)) - return_zero); - de_fault (to_can_follow_vfork_prior_to_exec, - (int (*) (void)) - return_zero); - de_fault (to_post_follow_vfork, - (void (*) (int, int, int, int)) + de_fault (to_follow_fork, + (int (*) (int)) target_ignore); de_fault (to_insert_exec_catchpoint, (int (*) (int)) @@ -450,15 +586,9 @@ cleanup_target (struct target_ops *t) de_fault (to_remove_exec_catchpoint, (int (*) (int)) tcomplain); - de_fault (to_has_execd, - (int (*) (int, char **)) - return_zero); de_fault (to_reported_exec_events_per_exec_call, (int (*) (void)) return_one); - de_fault (to_has_syscall_event, - (int (*) (int, enum target_waitkind *, int *)) - return_zero); de_fault (to_has_exited, (int (*) (int, int, int *)) return_zero); @@ -468,10 +598,10 @@ cleanup_target (struct target_ops *t) de_fault (to_can_run, return_zero); de_fault (to_notice_signals, - (void (*) (int)) + (void (*) (ptid_t)) target_ignore); de_fault (to_thread_alive, - (int (*) (int)) + (int (*) (ptid_t)) return_zero); de_fault (to_find_new_threads, (void (*) (void)) @@ -482,9 +612,7 @@ cleanup_target (struct target_ops *t) de_fault (to_stop, (void (*) (void)) target_ignore); - de_fault (to_query, - (int (*) (int, char *, char *, int *)) - return_zero); + current_target.to_xfer_partial = default_xfer_partial; de_fault (to_rcmd, (void (*) (char *, struct ui_file *)) tcomplain); @@ -497,9 +625,6 @@ cleanup_target (struct target_ops *t) de_fault (to_pid_to_exec_file, (char *(*) (int)) return_zero); - de_fault (to_core_file_to_sym_file, - (char *(*) (char *)) - return_zero); de_fault (to_can_async_p, (int (*) (void)) return_zero); @@ -510,108 +635,11 @@ cleanup_target (struct target_ops *t) (void (*) (void (*) (enum inferior_event_type, void*), void*)) tcomplain); #undef de_fault -} - -/* Go through the target stack from top to bottom, copying over zero entries in - current_target. In effect, we are doing class inheritance through the - pushed target vectors. */ - -static void -update_current_target (void) -{ - struct target_stack_item *item; - struct target_ops *t; - - /* First, reset current_target */ - memset (¤t_target, 0, sizeof current_target); - - for (item = target_stack; item; item = item->next) - { - t = item->target_ops; - -#define INHERIT(FIELD, TARGET) \ - if (!current_target.FIELD) \ - current_target.FIELD = TARGET->FIELD - - INHERIT (to_shortname, t); - INHERIT (to_longname, t); - INHERIT (to_doc, t); - INHERIT (to_open, t); - INHERIT (to_close, t); - INHERIT (to_attach, t); - INHERIT (to_post_attach, t); - INHERIT (to_require_attach, t); - INHERIT (to_detach, t); - INHERIT (to_require_detach, t); - INHERIT (to_resume, t); - INHERIT (to_wait, t); - INHERIT (to_post_wait, t); - INHERIT (to_fetch_registers, t); - INHERIT (to_store_registers, t); - INHERIT (to_prepare_to_store, t); - INHERIT (to_xfer_memory, t); - INHERIT (to_files_info, t); - INHERIT (to_insert_breakpoint, t); - INHERIT (to_remove_breakpoint, t); - INHERIT (to_terminal_init, t); - INHERIT (to_terminal_inferior, t); - INHERIT (to_terminal_ours_for_output, t); - INHERIT (to_terminal_ours, t); - INHERIT (to_terminal_info, t); - INHERIT (to_kill, t); - INHERIT (to_load, t); - INHERIT (to_lookup_symbol, t); - INHERIT (to_create_inferior, t); - INHERIT (to_post_startup_inferior, t); - INHERIT (to_acknowledge_created_inferior, t); - INHERIT (to_clone_and_follow_inferior, t); - INHERIT (to_post_follow_inferior_by_clone, t); - INHERIT (to_insert_fork_catchpoint, t); - INHERIT (to_remove_fork_catchpoint, t); - INHERIT (to_insert_vfork_catchpoint, t); - INHERIT (to_remove_vfork_catchpoint, t); - INHERIT (to_has_forked, t); - INHERIT (to_has_vforked, t); - INHERIT (to_can_follow_vfork_prior_to_exec, t); - INHERIT (to_post_follow_vfork, t); - INHERIT (to_insert_exec_catchpoint, t); - INHERIT (to_remove_exec_catchpoint, t); - INHERIT (to_has_execd, t); - INHERIT (to_reported_exec_events_per_exec_call, t); - INHERIT (to_has_syscall_event, t); - INHERIT (to_has_exited, t); - INHERIT (to_mourn_inferior, t); - INHERIT (to_can_run, t); - INHERIT (to_notice_signals, t); - INHERIT (to_thread_alive, t); - INHERIT (to_find_new_threads, t); - INHERIT (to_pid_to_str, t); - INHERIT (to_extra_thread_info, t); - INHERIT (to_stop, t); - INHERIT (to_query, t); - INHERIT (to_rcmd, t); - INHERIT (to_enable_exception_callback, t); - INHERIT (to_get_current_exception_event, t); - INHERIT (to_pid_to_exec_file, t); - INHERIT (to_core_file_to_sym_file, t); - INHERIT (to_stratum, t); - INHERIT (DONT_USE, t); - INHERIT (to_has_all_memory, t); - INHERIT (to_has_memory, t); - INHERIT (to_has_stack, t); - INHERIT (to_has_registers, t); - INHERIT (to_has_execution, t); - INHERIT (to_has_thread_control, t); - INHERIT (to_sections, t); - INHERIT (to_sections_end, t); - INHERIT (to_can_async_p, t); - INHERIT (to_is_async_p, t); - INHERIT (to_async, t); - INHERIT (to_async_mask_value, t); - INHERIT (to_magic, t); -#undef INHERIT - } + /* Finally, position the target-stack beneath the squashed + "current_target". That way code looking for a non-inherited + target method can quickly and simply find it. */ + current_target.beneath = target_stack; } /* Push a new target type into the stack of the existing target accessors, @@ -627,7 +655,7 @@ update_current_target (void) int push_target (struct target_ops *t) { - struct target_stack_item *cur, *prev, *tmp; + struct target_ops **cur; /* Check magic number. If wrong, it probably means someone changed the struct definition, but not all the places that initialize one. */ @@ -636,54 +664,40 @@ push_target (struct target_ops *t) fprintf_unfiltered (gdb_stderr, "Magic number of %s target struct wrong\n", t->to_shortname); - abort (); + internal_error (__FILE__, __LINE__, "failed internal consistency check"); } - /* Find the proper stratum to install this target in. */ - - for (prev = NULL, cur = target_stack; cur; prev = cur, cur = cur->next) + /* Find the proper stratum to install this target in. */ + for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath) { - if ((int) (t->to_stratum) >= (int) (cur->target_ops->to_stratum)) + if ((int) (t->to_stratum) >= (int) (*cur)->to_stratum) break; } - /* If there's already targets at this stratum, remove them. */ - - if (cur) - while (t->to_stratum == cur->target_ops->to_stratum) - { - /* There's already something on this stratum. Close it off. */ - if (cur->target_ops->to_close) - (cur->target_ops->to_close) (0); - if (prev) - prev->next = cur->next; /* Unchain old target_ops */ - else - target_stack = cur->next; /* Unchain first on list */ - tmp = cur->next; - free (cur); - cur = tmp; - } + /* If there's already targets at this stratum, remove them. */ + /* FIXME: cagney/2003-10-15: I think this should be poping all + targets to CUR, and not just those at this stratum level. */ + while ((*cur) != NULL && t->to_stratum == (*cur)->to_stratum) + { + /* There's already something at this stratum level. Close it, + and un-hook it from the stack. */ + struct target_ops *tmp = (*cur); + (*cur) = (*cur)->beneath; + tmp->beneath = NULL; + target_close (tmp, 0); + } /* We have removed all targets in our stratum, now add the new one. */ - - tmp = (struct target_stack_item *) - xmalloc (sizeof (struct target_stack_item)); - tmp->next = cur; - tmp->target_ops = t; - - if (prev) - prev->next = tmp; - else - target_stack = tmp; + t->beneath = (*cur); + (*cur) = t; update_current_target (); - cleanup_target (¤t_target); /* Fill in the gaps */ - if (targetdebug) setup_target_debug (); - return prev != 0; + /* Not on top? */ + return (t != target_stack); } /* Remove a target_ops vector from the stack, wherever it may be. @@ -692,32 +706,35 @@ push_target (struct target_ops *t) int unpush_target (struct target_ops *t) { - struct target_stack_item *cur, *prev; - - if (t->to_close) - t->to_close (0); /* Let it clean up */ + struct target_ops **cur; + struct target_ops *tmp; /* Look for the specified target. Note that we assume that a target can only occur once in the target stack. */ - for (cur = target_stack, prev = NULL; cur; prev = cur, cur = cur->next) - if (cur->target_ops == t) - break; + for (cur = &target_stack; (*cur) != NULL; cur = &(*cur)->beneath) + { + if ((*cur) == t) + break; + } - if (!cur) + if ((*cur) == NULL) return 0; /* Didn't find target_ops, quit now */ - /* Unchain the target */ - - if (!prev) - target_stack = cur->next; - else - prev->next = cur->next; + /* NOTE: cagney/2003-12-06: In '94 the close call was made + unconditional by moving it to before the above check that the + target was in the target stack (something about "Change the way + pushing and popping of targets work to support target overlays + and inheritance"). This doesn't make much sense - only open + targets should be closed. */ + target_close (t, 0); - free (cur); /* Release the target_stack_item */ + /* Unchain the target */ + tmp = (*cur); + (*cur) = (*cur)->beneath; + tmp->beneath = NULL; update_current_target (); - cleanup_target (¤t_target); return 1; } @@ -725,14 +742,14 @@ unpush_target (struct target_ops *t) void pop_target (void) { - (current_target.to_close) (0); /* Let it clean up */ - if (unpush_target (target_stack->target_ops) == 1) + target_close (¤t_target, 0); /* Let it clean up */ + if (unpush_target (target_stack) == 1) return; fprintf_unfiltered (gdb_stderr, "pop_target couldn't find target %s\n", current_target.to_shortname); - abort (); + internal_error (__FILE__, __LINE__, "failed internal consistency check"); } #undef MIN @@ -767,7 +784,7 @@ target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop) tlen = MIN (len, 4 - (memaddr & 3)); offset = memaddr & 3; - errcode = target_xfer_memory (memaddr & ~3, buf, 4, 0); + errcode = target_read_memory (memaddr & ~3, buf, 4); if (errcode != 0) { /* The transfer request might have crossed the boundary to an @@ -775,7 +792,7 @@ target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop) a single byte. */ tlen = 1; offset = 0; - errcode = target_xfer_memory (memaddr, buf, 1, 0); + errcode = target_read_memory (memaddr, buf, 1); if (errcode != 0) goto done; } @@ -811,74 +828,256 @@ done: return nbytes_read; } -/* Read LEN bytes of target memory at address MEMADDR, placing the results in - GDB's memory at MYADDR. Returns either 0 for success or an errno value - if any error occurs. - - If an error occurs, no guarantee is made about the contents of the data at - MYADDR. In particular, the caller should not depend upon partial reads - filling the buffer with good data. There is no way for the caller to know - how much good data might have been transfered anyway. Callers that can - deal with partial reads should call target_read_memory_partial. */ +/* Find a section containing ADDR. */ +struct section_table * +target_section_by_addr (struct target_ops *target, CORE_ADDR addr) +{ + struct section_table *secp; + for (secp = target->to_sections; + secp < target->to_sections_end; + secp++) + { + if (addr >= secp->addr && addr < secp->endaddr) + return secp; + } + return NULL; +} -int -target_read_memory (CORE_ADDR memaddr, char *myaddr, int len) +/* Return non-zero when the target vector has supplied an xfer_partial + method and it, rather than xfer_memory, should be used. */ +static int +target_xfer_partial_p (void) { - return target_xfer_memory (memaddr, myaddr, len, 0); + return (target_stack != NULL + && target_stack->to_xfer_partial != default_xfer_partial); } -int -target_write_memory (CORE_ADDR memaddr, char *myaddr, int len) +static LONGEST +target_xfer_partial (struct target_ops *ops, + enum target_object object, const char *annex, + void *readbuf, const void *writebuf, + ULONGEST offset, LONGEST len) { - return target_xfer_memory (memaddr, myaddr, len, 1); + LONGEST retval; + + gdb_assert (ops->to_xfer_partial != NULL); + retval = ops->to_xfer_partial (ops, object, annex, readbuf, writebuf, + offset, len); + if (targetdebug) + { + const unsigned char *myaddr = NULL; + + fprintf_unfiltered (gdb_stdlog, + "%s:target_xfer_partial (%d, %s, 0x%lx, 0x%lx, 0x%s, %s) = %s", + ops->to_shortname, + (int) object, + (annex ? annex : "(null)"), + (long) readbuf, (long) writebuf, + paddr_nz (offset), paddr_d (len), paddr_d (retval)); + + if (readbuf) + myaddr = readbuf; + if (writebuf) + myaddr = writebuf; + if (retval > 0 && myaddr != NULL) + { + int i; + + fputs_unfiltered (", bytes =", gdb_stdlog); + for (i = 0; i < retval; i++) + { + if ((((long) &(myaddr[i])) & 0xf) == 0) + { + if (targetdebug < 2 && i > 0) + { + fprintf_unfiltered (gdb_stdlog, " ..."); + break; + } + fprintf_unfiltered (gdb_stdlog, "\n"); + } + + fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff); + } + } + + fputc_unfiltered ('\n', gdb_stdlog); + } + return retval; } -/* Move memory to or from the targets. Iterate until all of it has - been moved, if necessary. The top target gets priority; anything - it doesn't want, is offered to the next one down, etc. Note the - business with curlen: if an early target says "no, but I have a - boundary overlapping this xfer" then we shorten what we offer to - the subsequent targets so the early guy will get a chance at the - tail before the subsequent ones do. +/* Attempt a transfer all LEN bytes starting at OFFSET between the + inferior's KIND:ANNEX space and GDB's READBUF/WRITEBUF buffer. If + the transfer succeeds, return zero, otherwize the host ERRNO is + returned. - Result is 0 or errno value. */ + The inferior is formed from several layers. In the case of + corefiles, inf-corefile is layered above inf-exec and a request for + text (corefiles do not include text pages) will be first sent to + the core-stratum, fail, and then sent to the object-file where it + will succeed. -static int -target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write) + NOTE: cagney/2004-09-30: + + The old code tried to use four separate mechanisms for mapping an + object:offset:len tuple onto an inferior and its address space: the + target stack; the inferior's TO_SECTIONS; solib's SO_LIST; + overlays. + + This is stupid. + + The code below is instead using a single mechanism (currently + strata). If that mechanism proves insufficient then re-factor it + implementing another singluar mechanism (for instance, a generic + object:annex onto inferior:object:annex say). */ + +static LONGEST +xfer_using_stratum (enum target_object object, const char *annex, + ULONGEST offset, LONGEST len, void *readbuf, + const void *writebuf) { - int curlen; - int res; - struct target_ops *t; - struct target_stack_item *item; + LONGEST xfered; + struct target_ops *target; - /* Zero length requests are ok and require no work. */ + /* Always successful. */ if (len == 0) return 0; + /* Never successful. */ + if (target_stack == NULL) + return EIO; - /* to_xfer_memory is not guaranteed to set errno, even when it returns - 0. */ - errno = 0; + target = target_stack; + while (1) + { + xfered = target_xfer_partial (target, object, annex, + readbuf, writebuf, offset, len); + if (xfered > 0) + { + /* The partial xfer succeeded, update the counts, check that + the xfer hasn't finished and if it hasn't set things up + for the next round. */ + len -= xfered; + if (len <= 0) + return 0; + offset += xfered; + if (readbuf != NULL) + readbuf = (bfd_byte *) readbuf + xfered; + if (writebuf != NULL) + writebuf = (bfd_byte *) writebuf + xfered; + target = target_stack; + } + else if (xfered < 0) + { + /* Something totally screwed up, abandon the attempt to + xfer. */ + if (errno) + return errno; + else + return EIO; + } + else + { + /* This "stratum" didn't work, try the next one down. */ + target = target->beneath; + if (target == NULL) + return EIO; + } + } +} + +/* Read LEN bytes of target memory at address MEMADDR, placing the results in + GDB's memory at MYADDR. Returns either 0 for success or an errno value + if any error occurs. + + If an error occurs, no guarantee is made about the contents of the data at + MYADDR. In particular, the caller should not depend upon partial reads + filling the buffer with good data. There is no way for the caller to know + how much good data might have been transfered anyway. Callers that can + deal with partial reads should call target_read_memory_partial. */ + +int +target_read_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + if (target_xfer_partial_p ()) + return xfer_using_stratum (TARGET_OBJECT_MEMORY, NULL, + memaddr, len, myaddr, NULL); + else + return target_xfer_memory (memaddr, myaddr, len, 0); +} + +int +target_write_memory (CORE_ADDR memaddr, char *myaddr, int len) +{ + if (target_xfer_partial_p ()) + return xfer_using_stratum (TARGET_OBJECT_MEMORY, NULL, + memaddr, len, NULL, myaddr); + else + return target_xfer_memory (memaddr, myaddr, len, 1); +} + +#ifndef target_stopped_data_address_p +int +target_stopped_data_address_p (struct target_ops *target) +{ + if (target->to_stopped_data_address + == (int (*) (struct target_ops *, CORE_ADDR *)) return_zero) + return 0; + if (target->to_stopped_data_address == debug_to_stopped_data_address + && (debug_target.to_stopped_data_address + == (int (*) (struct target_ops *, CORE_ADDR *)) return_zero)) + return 0; + return 1; +} +#endif + +static int trust_readonly = 0; + +/* Move memory to or from the targets. The top target gets priority; + if it cannot handle it, it is offered to the next one down, etc. + + Result is -1 on error, or the number of bytes transfered. */ + +int +do_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, + struct mem_attrib *attrib) +{ + int res; + int done = 0; + struct target_ops *t; - /* The quick case is that the top target does it all. */ - res = current_target.to_xfer_memory - (memaddr, myaddr, len, write, ¤t_target); - if (res == len) + /* Zero length requests are ok and require no work. */ + if (len == 0) return 0; - if (res > 0) - goto bump; - /* If res <= 0 then we call it again in the loop. Ah well. */ + /* deprecated_xfer_memory is not guaranteed to set errno, even when + it returns 0. */ + errno = 0; - for (; len > 0;) + if (!write && trust_readonly) { - curlen = len; /* Want to do it all */ - for (item = target_stack; item; item = item->next) + struct section_table *secp; + /* User-settable option, "trust-readonly-sections". If true, + then memory from any SEC_READONLY bfd section may be read + directly from the bfd file. */ + secp = target_section_by_addr (¤t_target, memaddr); + if (secp != NULL + && (bfd_get_section_flags (secp->bfd, secp->the_bfd_section) + & SEC_READONLY)) + return xfer_memory (memaddr, myaddr, len, 0, attrib, ¤t_target); + } + + /* The quick case is that the top target can handle the transfer. */ + res = current_target.deprecated_xfer_memory + (memaddr, myaddr, len, write, attrib, ¤t_target); + + /* If res <= 0 then we call it again in the loop. Ah well. */ + if (res <= 0) + { + for (t = target_stack; t != NULL; t = t->beneath) { - t = item->target_ops; if (!t->to_has_memory) continue; - res = t->to_xfer_memory (memaddr, myaddr, curlen, write, t); + res = t->deprecated_xfer_memory (memaddr, myaddr, len, write, attrib, t); if (res > 0) break; /* Handled all or part of xfer */ if (t->to_has_all_memory) @@ -886,36 +1085,96 @@ target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write) } if (res <= 0) + return -1; + } + + return res; +} + + +/* Perform a memory transfer. Iterate until the entire region has + been transfered. + + Result is 0 or errno value. */ + +static int +target_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write) +{ + int res; + int reg_len; + struct mem_region *region; + + /* Zero length requests are ok and require no work. */ + if (len == 0) + { + return 0; + } + + while (len > 0) + { + region = lookup_mem_region(memaddr); + if (memaddr + len < region->hi) + reg_len = len; + else + reg_len = region->hi - memaddr; + + switch (region->attrib.mode) { - /* If this address is for nonexistent memory, - read zeros if reading, or do nothing if writing. Return error. */ + case MEM_RO: + if (write) + return EIO; + break; + + case MEM_WO: if (!write) - memset (myaddr, 0, len); - if (errno == 0) return EIO; + break; + } + + while (reg_len > 0) + { + if (region->attrib.cache) + res = dcache_xfer_memory (target_dcache, memaddr, myaddr, + reg_len, write); else - return errno; + res = do_xfer_memory (memaddr, myaddr, reg_len, write, + ®ion->attrib); + + if (res <= 0) + { + /* If this address is for nonexistent memory, read zeros + if reading, or do nothing if writing. Return + error. */ + if (!write) + memset (myaddr, 0, len); + if (errno == 0) + return EIO; + else + return errno; + } + + memaddr += res; + myaddr += res; + len -= res; + reg_len -= res; } - bump: - memaddr += res; - myaddr += res; - len -= res; } + return 0; /* We managed to cover it all somehow. */ } -/* Perform a partial memory transfer. */ +/* Perform a partial memory transfer. + + Result is -1 on error, or the number of bytes transfered. */ static int -target_xfer_memory_partial (CORE_ADDR memaddr, char *buf, int len, +target_xfer_memory_partial (CORE_ADDR memaddr, char *myaddr, int len, int write_p, int *err) { int res; - int err_res; - int len_res; - struct target_ops *t; - struct target_stack_item *item; + int reg_len; + struct mem_region *region; /* Zero length requests are ok and require no work. */ if (len == 0) @@ -924,76 +1183,216 @@ target_xfer_memory_partial (CORE_ADDR memaddr, char *buf, int len, return 0; } - /* The quick case is that the top target does it all. */ - res = current_target.to_xfer_memory (memaddr, buf, len, write_p, ¤t_target); - if (res > 0) - { - *err = 0; - return res; - } - - /* xfer memory doesn't always reliably set errno. */ - errno = 0; + region = lookup_mem_region(memaddr); + if (memaddr + len < region->hi) + reg_len = len; + else + reg_len = region->hi - memaddr; - /* Try all levels of the target stack to see one can handle it. */ - for (item = target_stack; item; item = item->next) + switch (region->attrib.mode) { - t = item->target_ops; - if (!t->to_has_memory) - continue; - res = t->to_xfer_memory (memaddr, buf, len, write_p, t); - if (res > 0) + case MEM_RO: + if (write_p) { - /* Handled all or part of xfer */ - *err = 0; - return res; + *err = EIO; + return -1; } - if (t->to_has_all_memory) - break; + break; + + case MEM_WO: + if (write_p) + { + *err = EIO; + return -1; + } + break; } - /* Total failure. Return error. */ - if (errno != 0) + if (region->attrib.cache) + res = dcache_xfer_memory (target_dcache, memaddr, myaddr, + reg_len, write_p); + else + res = do_xfer_memory (memaddr, myaddr, reg_len, write_p, + ®ion->attrib); + + if (res <= 0) { - *err = errno; - return -1; + if (errno != 0) + *err = errno; + else + *err = EIO; + + return -1; } - *err = EIO; - return -1; + + *err = 0; + return res; } int target_read_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err) { - return target_xfer_memory_partial (memaddr, buf, len, 0, err); + if (target_xfer_partial_p ()) + return target_xfer_partial (target_stack, TARGET_OBJECT_MEMORY, NULL, + buf, NULL, memaddr, len); + else + return target_xfer_memory_partial (memaddr, buf, len, 0, err); } int target_write_memory_partial (CORE_ADDR memaddr, char *buf, int len, int *err) { - return target_xfer_memory_partial (memaddr, buf, len, 1, err); + if (target_xfer_partial_p ()) + return target_xfer_partial (target_stack, TARGET_OBJECT_MEMORY, NULL, + NULL, buf, memaddr, len); + else + return target_xfer_memory_partial (memaddr, buf, len, 1, err); +} + +/* More generic transfers. */ + +static LONGEST +default_xfer_partial (struct target_ops *ops, enum target_object object, + const char *annex, void *readbuf, + const void *writebuf, ULONGEST offset, LONGEST len) +{ + if (object == TARGET_OBJECT_MEMORY + && ops->deprecated_xfer_memory != NULL) + /* If available, fall back to the target's + "deprecated_xfer_memory" method. */ + { + int xfered = -1; + errno = 0; + if (writebuf != NULL) + { + void *buffer = xmalloc (len); + struct cleanup *cleanup = make_cleanup (xfree, buffer); + memcpy (buffer, writebuf, len); + xfered = ops->deprecated_xfer_memory (offset, buffer, len, + 1/*write*/, NULL, ops); + do_cleanups (cleanup); + } + if (readbuf != NULL) + xfered = ops->deprecated_xfer_memory (offset, readbuf, len, 0/*read*/, + NULL, ops); + if (xfered > 0) + return xfered; + else if (xfered == 0 && errno == 0) + /* "deprecated_xfer_memory" uses 0, cross checked against + ERRNO as one indication of an error. */ + return 0; + else + return -1; + } + else if (ops->beneath != NULL) + return target_xfer_partial (ops->beneath, object, annex, + readbuf, writebuf, offset, len); + else + return -1; +} + +/* Target vector read/write partial wrapper functions. + + NOTE: cagney/2003-10-21: I wonder if having "to_xfer_partial + (inbuf, outbuf)", instead of separate read/write methods, make life + easier. */ + +LONGEST +target_read_partial (struct target_ops *ops, + enum target_object object, + const char *annex, void *buf, + ULONGEST offset, LONGEST len) +{ + return target_xfer_partial (ops, object, annex, buf, NULL, offset, len); +} + +LONGEST +target_write_partial (struct target_ops *ops, + enum target_object object, + const char *annex, const void *buf, + ULONGEST offset, LONGEST len) +{ + return target_xfer_partial (ops, object, annex, NULL, buf, offset, len); +} + +/* Wrappers to perform the full transfer. */ +LONGEST +target_read (struct target_ops *ops, + enum target_object object, + const char *annex, void *buf, + ULONGEST offset, LONGEST len) +{ + LONGEST xfered = 0; + while (xfered < len) + { + LONGEST xfer = target_read_partial (ops, object, annex, + (bfd_byte *) buf + xfered, + offset + xfered, len - xfered); + /* Call an observer, notifying them of the xfer progress? */ + if (xfer <= 0) + /* Call memory_error? */ + return -1; + xfered += xfer; + QUIT; + } + return len; +} + +LONGEST +target_write (struct target_ops *ops, + enum target_object object, + const char *annex, const void *buf, + ULONGEST offset, LONGEST len) +{ + LONGEST xfered = 0; + while (xfered < len) + { + LONGEST xfer = target_write_partial (ops, object, annex, + (bfd_byte *) buf + xfered, + offset + xfered, len - xfered); + /* Call an observer, notifying them of the xfer progress? */ + if (xfer <= 0) + /* Call memory_error? */ + return -1; + xfered += xfer; + QUIT; + } + return len; +} + +/* Memory transfer methods. */ + +void +get_target_memory (struct target_ops *ops, CORE_ADDR addr, void *buf, + LONGEST len) +{ + if (target_read (ops, TARGET_OBJECT_MEMORY, NULL, buf, addr, len) + != len) + memory_error (EIO, addr); +} + +ULONGEST +get_target_memory_unsigned (struct target_ops *ops, + CORE_ADDR addr, int len) +{ + char buf[sizeof (ULONGEST)]; + + gdb_assert (len <= sizeof (buf)); + get_target_memory (ops, addr, buf, len); + return extract_unsigned_integer (buf, len); } -/* ARGSUSED */ static void target_info (char *args, int from_tty) { struct target_ops *t; - struct target_stack_item *item; int has_all_mem = 0; if (symfile_objfile != NULL) printf_unfiltered ("Symbols from \"%s\".\n", symfile_objfile->name); -#ifdef FILES_INFO_HOOK - if (FILES_INFO_HOOK ()) - return; -#endif - - for (item = target_stack; item; item = item->next) + for (t = target_stack; t != NULL; t = t->beneath) { - t = item->target_ops; - if (!t->to_has_memory) continue; @@ -1036,17 +1435,19 @@ target_preopen (int from_tty) void target_detach (char *args, int from_tty) { - /* Handle any optimized stores to the inferior. */ -#ifdef DO_DEFERRED_STORES - DO_DEFERRED_STORES; -#endif (current_target.to_detach) (args, from_tty); } +void +target_disconnect (char *args, int from_tty) +{ + (current_target.to_disconnect) (args, from_tty); +} + void target_link (char *modname, CORE_ADDR *t_reloc) { - if (STREQ (current_target.to_shortname, "rombug")) + if (DEPRECATED_STREQ (current_target.to_shortname, "rombug")) { (current_target.to_lookup_symbol) (modname, t_reloc); if (*t_reloc == 0) @@ -1106,43 +1507,20 @@ find_default_attach (char *args, int from_tty) } void -find_default_require_attach (char *args, int from_tty) -{ - struct target_ops *t; - - t = find_default_run_target ("require_attach"); - (t->to_require_attach) (args, from_tty); - return; -} - -void -find_default_require_detach (int pid, char *args, int from_tty) -{ - struct target_ops *t; - - t = find_default_run_target ("require_detach"); - (t->to_require_detach) (pid, args, from_tty); - return; -} - -void -find_default_create_inferior (char *exec_file, char *allargs, char **env) +find_default_create_inferior (char *exec_file, char *allargs, char **env, + int from_tty) { struct target_ops *t; t = find_default_run_target ("run"); - (t->to_create_inferior) (exec_file, allargs, env); + (t->to_create_inferior) (exec_file, allargs, env, from_tty); return; } -void -find_default_clone_and_follow_inferior (int child_pid, int *followed_child) +static int +default_region_size_ok_for_hw_watchpoint (int byte_count) { - struct target_ops *t; - - t = find_default_run_target ("run"); - (t->to_clone_and_follow_inferior) (child_pid, followed_child); - return; + return (byte_count <= TYPE_LENGTH (builtin_type_void_data_ptr)); } static int @@ -1157,6 +1535,12 @@ return_one (void) return 1; } +static int +return_minus_one (void) +{ + return -1; +} + /* * Resize the to_sections pointer. Also make sure that anyone that * was holding on to an old value of it gets updated. @@ -1201,6 +1585,13 @@ target_resize_to_sections (struct target_ops *target, int num_added) (*t)->to_sections_end = target->to_sections_end; } } + /* There is a flattened view of the target stack in current_target, + so its to_sections pointer might also need updating. */ + if (current_target.to_sections == old_value) + { + current_target.to_sections = target->to_sections; + current_target.to_sections_end = target->to_sections_end; + } } return old_count; @@ -1270,750 +1661,62 @@ find_run_target (void) struct target_ops * find_core_target (void) { - 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 ((*t)->to_stratum == core_stratum) - { - runable = *t; - ++count; - } - } - - return (count == 1 ? runable : NULL); -} - -/* - * Find the next target down the stack from the specified target. - */ - -struct target_ops * -find_target_beneath (struct target_ops *t) -{ - struct target_stack_item *cur; - - for (cur = target_stack; cur; cur = cur->next) - if (cur->target_ops == t) - break; - - if (cur == NULL || cur->next == NULL) - return NULL; - else - return cur->next->target_ops; -} - - -/* The inferior process has died. Long live the inferior! */ - -void -generic_mourn_inferior (void) -{ - extern int show_breakpoint_hit_counts; - - inferior_pid = 0; - attach_flag = 0; - breakpoint_init_inferior (inf_exited); - registers_changed (); - -#ifdef CLEAR_DEFERRED_STORES - /* Delete any pending stores to the inferior... */ - CLEAR_DEFERRED_STORES; -#endif - - reopen_exec_file (); - reinit_frame_cache (); - - /* It is confusing to the user for ignore counts to stick around - from previous runs of the inferior. So clear them. */ - /* However, it is more confusing for the ignore counts to disappear when - using hit counts. So don't clear them if we're counting hits. */ - if (!show_breakpoint_hit_counts) - breakpoint_clear_ignore_counts (); -} - -/* This table must match in order and size the signals in enum target_signal - in target.h. */ -/* *INDENT-OFF* */ -static struct { - char *name; - char *string; - } signals [] = -{ - {"0", "Signal 0"}, - {"SIGHUP", "Hangup"}, - {"SIGINT", "Interrupt"}, - {"SIGQUIT", "Quit"}, - {"SIGILL", "Illegal instruction"}, - {"SIGTRAP", "Trace/breakpoint trap"}, - {"SIGABRT", "Aborted"}, - {"SIGEMT", "Emulation trap"}, - {"SIGFPE", "Arithmetic exception"}, - {"SIGKILL", "Killed"}, - {"SIGBUS", "Bus error"}, - {"SIGSEGV", "Segmentation fault"}, - {"SIGSYS", "Bad system call"}, - {"SIGPIPE", "Broken pipe"}, - {"SIGALRM", "Alarm clock"}, - {"SIGTERM", "Terminated"}, - {"SIGURG", "Urgent I/O condition"}, - {"SIGSTOP", "Stopped (signal)"}, - {"SIGTSTP", "Stopped (user)"}, - {"SIGCONT", "Continued"}, - {"SIGCHLD", "Child status changed"}, - {"SIGTTIN", "Stopped (tty input)"}, - {"SIGTTOU", "Stopped (tty output)"}, - {"SIGIO", "I/O possible"}, - {"SIGXCPU", "CPU time limit exceeded"}, - {"SIGXFSZ", "File size limit exceeded"}, - {"SIGVTALRM", "Virtual timer expired"}, - {"SIGPROF", "Profiling timer expired"}, - {"SIGWINCH", "Window size changed"}, - {"SIGLOST", "Resource lost"}, - {"SIGUSR1", "User defined signal 1"}, - {"SIGUSR2", "User defined signal 2"}, - {"SIGPWR", "Power fail/restart"}, - {"SIGPOLL", "Pollable event occurred"}, - {"SIGWIND", "SIGWIND"}, - {"SIGPHONE", "SIGPHONE"}, - {"SIGWAITING", "Process's LWPs are blocked"}, - {"SIGLWP", "Signal LWP"}, - {"SIGDANGER", "Swap space dangerously low"}, - {"SIGGRANT", "Monitor mode granted"}, - {"SIGRETRACT", "Need to relinquish monitor mode"}, - {"SIGMSG", "Monitor mode data available"}, - {"SIGSOUND", "Sound completed"}, - {"SIGSAK", "Secure attention"}, - {"SIGPRIO", "SIGPRIO"}, - {"SIG33", "Real-time event 33"}, - {"SIG34", "Real-time event 34"}, - {"SIG35", "Real-time event 35"}, - {"SIG36", "Real-time event 36"}, - {"SIG37", "Real-time event 37"}, - {"SIG38", "Real-time event 38"}, - {"SIG39", "Real-time event 39"}, - {"SIG40", "Real-time event 40"}, - {"SIG41", "Real-time event 41"}, - {"SIG42", "Real-time event 42"}, - {"SIG43", "Real-time event 43"}, - {"SIG44", "Real-time event 44"}, - {"SIG45", "Real-time event 45"}, - {"SIG46", "Real-time event 46"}, - {"SIG47", "Real-time event 47"}, - {"SIG48", "Real-time event 48"}, - {"SIG49", "Real-time event 49"}, - {"SIG50", "Real-time event 50"}, - {"SIG51", "Real-time event 51"}, - {"SIG52", "Real-time event 52"}, - {"SIG53", "Real-time event 53"}, - {"SIG54", "Real-time event 54"}, - {"SIG55", "Real-time event 55"}, - {"SIG56", "Real-time event 56"}, - {"SIG57", "Real-time event 57"}, - {"SIG58", "Real-time event 58"}, - {"SIG59", "Real-time event 59"}, - {"SIG60", "Real-time event 60"}, - {"SIG61", "Real-time event 61"}, - {"SIG62", "Real-time event 62"}, - {"SIG63", "Real-time event 63"}, - {"SIGCANCEL", "LWP internal signal"}, - {"SIG32", "Real-time event 32"}, - -#if defined(MACH) || defined(__MACH__) - /* Mach exceptions */ - {"EXC_BAD_ACCESS", "Could not access memory"}, - {"EXC_BAD_INSTRUCTION", "Illegal instruction/operand"}, - {"EXC_ARITHMETIC", "Arithmetic exception"}, - {"EXC_EMULATION", "Emulation instruction"}, - {"EXC_SOFTWARE", "Software generated exception"}, - {"EXC_BREAKPOINT", "Breakpoint"}, -#endif - {"SIGINFO", "Information request"}, - - {NULL, "Unknown signal"}, - {NULL, "Internal error: printing TARGET_SIGNAL_DEFAULT"}, - - /* Last entry, used to check whether the table is the right size. */ - {NULL, "TARGET_SIGNAL_MAGIC"} -}; -/* *INDENT-ON* */ - - - -/* Return the string for a signal. */ -char * -target_signal_to_string (enum target_signal sig) -{ - if ((sig >= TARGET_SIGNAL_FIRST) && (sig <= TARGET_SIGNAL_LAST)) - return signals[sig].string; - else - return signals[TARGET_SIGNAL_UNKNOWN].string; -} - -/* Return the name for a signal. */ -char * -target_signal_to_name (enum target_signal sig) -{ - if (sig == TARGET_SIGNAL_UNKNOWN) - /* I think the code which prints this will always print it along with - the string, so no need to be verbose. */ - return "?"; - return signals[sig].name; -} - -/* Given a name, return its signal. */ -enum target_signal -target_signal_from_name (char *name) -{ - enum target_signal sig; - - /* It's possible we also should allow "SIGCLD" as well as "SIGCHLD" - for TARGET_SIGNAL_SIGCHLD. SIGIOT, on the other hand, is more - questionable; seems like by now people should call it SIGABRT - instead. */ - - /* This ugly cast brought to you by the native VAX compiler. */ - for (sig = TARGET_SIGNAL_HUP; - signals[sig].name != NULL; - sig = (enum target_signal) ((int) sig + 1)) - if (STREQ (name, signals[sig].name)) - return sig; - return TARGET_SIGNAL_UNKNOWN; -} - -/* The following functions are to help certain targets deal - with the signal/waitstatus stuff. They could just as well be in - a file called native-utils.c or unixwaitstatus-utils.c or whatever. */ - -/* Convert host signal to our signals. */ -enum target_signal -target_signal_from_host (int hostsig) -{ - /* A switch statement would make sense but would require special kludges - to deal with the cases where more than one signal has the same number. */ - - if (hostsig == 0) - return TARGET_SIGNAL_0; - -#if defined (SIGHUP) - if (hostsig == SIGHUP) - return TARGET_SIGNAL_HUP; -#endif -#if defined (SIGINT) - if (hostsig == SIGINT) - return TARGET_SIGNAL_INT; -#endif -#if defined (SIGQUIT) - if (hostsig == SIGQUIT) - return TARGET_SIGNAL_QUIT; -#endif -#if defined (SIGILL) - if (hostsig == SIGILL) - return TARGET_SIGNAL_ILL; -#endif -#if defined (SIGTRAP) - if (hostsig == SIGTRAP) - return TARGET_SIGNAL_TRAP; -#endif -#if defined (SIGABRT) - if (hostsig == SIGABRT) - return TARGET_SIGNAL_ABRT; -#endif -#if defined (SIGEMT) - if (hostsig == SIGEMT) - return TARGET_SIGNAL_EMT; -#endif -#if defined (SIGFPE) - if (hostsig == SIGFPE) - return TARGET_SIGNAL_FPE; -#endif -#if defined (SIGKILL) - if (hostsig == SIGKILL) - return TARGET_SIGNAL_KILL; -#endif -#if defined (SIGBUS) - if (hostsig == SIGBUS) - return TARGET_SIGNAL_BUS; -#endif -#if defined (SIGSEGV) - if (hostsig == SIGSEGV) - return TARGET_SIGNAL_SEGV; -#endif -#if defined (SIGSYS) - if (hostsig == SIGSYS) - return TARGET_SIGNAL_SYS; -#endif -#if defined (SIGPIPE) - if (hostsig == SIGPIPE) - return TARGET_SIGNAL_PIPE; -#endif -#if defined (SIGALRM) - if (hostsig == SIGALRM) - return TARGET_SIGNAL_ALRM; -#endif -#if defined (SIGTERM) - if (hostsig == SIGTERM) - return TARGET_SIGNAL_TERM; -#endif -#if defined (SIGUSR1) - if (hostsig == SIGUSR1) - return TARGET_SIGNAL_USR1; -#endif -#if defined (SIGUSR2) - if (hostsig == SIGUSR2) - return TARGET_SIGNAL_USR2; -#endif -#if defined (SIGCLD) - if (hostsig == SIGCLD) - return TARGET_SIGNAL_CHLD; -#endif -#if defined (SIGCHLD) - if (hostsig == SIGCHLD) - return TARGET_SIGNAL_CHLD; -#endif -#if defined (SIGPWR) - if (hostsig == SIGPWR) - return TARGET_SIGNAL_PWR; -#endif -#if defined (SIGWINCH) - if (hostsig == SIGWINCH) - return TARGET_SIGNAL_WINCH; -#endif -#if defined (SIGURG) - if (hostsig == SIGURG) - return TARGET_SIGNAL_URG; -#endif -#if defined (SIGIO) - if (hostsig == SIGIO) - return TARGET_SIGNAL_IO; -#endif -#if defined (SIGPOLL) - if (hostsig == SIGPOLL) - return TARGET_SIGNAL_POLL; -#endif -#if defined (SIGSTOP) - if (hostsig == SIGSTOP) - return TARGET_SIGNAL_STOP; -#endif -#if defined (SIGTSTP) - if (hostsig == SIGTSTP) - return TARGET_SIGNAL_TSTP; -#endif -#if defined (SIGCONT) - if (hostsig == SIGCONT) - return TARGET_SIGNAL_CONT; -#endif -#if defined (SIGTTIN) - if (hostsig == SIGTTIN) - return TARGET_SIGNAL_TTIN; -#endif -#if defined (SIGTTOU) - if (hostsig == SIGTTOU) - return TARGET_SIGNAL_TTOU; -#endif -#if defined (SIGVTALRM) - if (hostsig == SIGVTALRM) - return TARGET_SIGNAL_VTALRM; -#endif -#if defined (SIGPROF) - if (hostsig == SIGPROF) - return TARGET_SIGNAL_PROF; -#endif -#if defined (SIGXCPU) - if (hostsig == SIGXCPU) - return TARGET_SIGNAL_XCPU; -#endif -#if defined (SIGXFSZ) - if (hostsig == SIGXFSZ) - return TARGET_SIGNAL_XFSZ; -#endif -#if defined (SIGWIND) - if (hostsig == SIGWIND) - return TARGET_SIGNAL_WIND; -#endif -#if defined (SIGPHONE) - if (hostsig == SIGPHONE) - return TARGET_SIGNAL_PHONE; -#endif -#if defined (SIGLOST) - if (hostsig == SIGLOST) - return TARGET_SIGNAL_LOST; -#endif -#if defined (SIGWAITING) - if (hostsig == SIGWAITING) - return TARGET_SIGNAL_WAITING; -#endif -#if defined (SIGCANCEL) - if (hostsig == SIGCANCEL) - return TARGET_SIGNAL_CANCEL; -#endif -#if defined (SIGLWP) - if (hostsig == SIGLWP) - return TARGET_SIGNAL_LWP; -#endif -#if defined (SIGDANGER) - if (hostsig == SIGDANGER) - return TARGET_SIGNAL_DANGER; -#endif -#if defined (SIGGRANT) - if (hostsig == SIGGRANT) - return TARGET_SIGNAL_GRANT; -#endif -#if defined (SIGRETRACT) - if (hostsig == SIGRETRACT) - return TARGET_SIGNAL_RETRACT; -#endif -#if defined (SIGMSG) - if (hostsig == SIGMSG) - return TARGET_SIGNAL_MSG; -#endif -#if defined (SIGSOUND) - if (hostsig == SIGSOUND) - return TARGET_SIGNAL_SOUND; -#endif -#if defined (SIGSAK) - if (hostsig == SIGSAK) - return TARGET_SIGNAL_SAK; -#endif -#if defined (SIGPRIO) - if (hostsig == SIGPRIO) - return TARGET_SIGNAL_PRIO; -#endif - - /* Mach exceptions. Assumes that the values for EXC_ are positive! */ -#if defined (EXC_BAD_ACCESS) && defined (_NSIG) - if (hostsig == _NSIG + EXC_BAD_ACCESS) - return TARGET_EXC_BAD_ACCESS; -#endif -#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG) - if (hostsig == _NSIG + EXC_BAD_INSTRUCTION) - return TARGET_EXC_BAD_INSTRUCTION; -#endif -#if defined (EXC_ARITHMETIC) && defined (_NSIG) - if (hostsig == _NSIG + EXC_ARITHMETIC) - return TARGET_EXC_ARITHMETIC; -#endif -#if defined (EXC_EMULATION) && defined (_NSIG) - if (hostsig == _NSIG + EXC_EMULATION) - return TARGET_EXC_EMULATION; -#endif -#if defined (EXC_SOFTWARE) && defined (_NSIG) - if (hostsig == _NSIG + EXC_SOFTWARE) - return TARGET_EXC_SOFTWARE; -#endif -#if defined (EXC_BREAKPOINT) && defined (_NSIG) - if (hostsig == _NSIG + EXC_BREAKPOINT) - return TARGET_EXC_BREAKPOINT; -#endif - -#if defined (SIGINFO) - if (hostsig == SIGINFO) - return TARGET_SIGNAL_INFO; -#endif - -#if defined (REALTIME_LO) - if (hostsig >= REALTIME_LO && hostsig < REALTIME_HI) - { - /* This block of TARGET_SIGNAL_REALTIME value is in order. */ - if (33 <= hostsig && hostsig <= 63) - return (enum target_signal) - (hostsig - 33 + (int) TARGET_SIGNAL_REALTIME_33); - else if (hostsig == 32) - return TARGET_SIGNAL_REALTIME_32; - else - error ("GDB bug: target.c (target_signal_from_host): unrecognized real-time signal"); - } -#endif - return TARGET_SIGNAL_UNKNOWN; -} - -/* Convert a OURSIG (an enum target_signal) to the form used by the - target operating system (refered to as the ``host'') or zero if the - equivalent host signal is not available. Set/clear OURSIG_OK - accordingly. */ - -static int -do_target_signal_to_host (enum target_signal oursig, - int *oursig_ok) -{ - *oursig_ok = 1; - switch (oursig) - { - case TARGET_SIGNAL_0: - return 0; - -#if defined (SIGHUP) - case TARGET_SIGNAL_HUP: - return SIGHUP; -#endif -#if defined (SIGINT) - case TARGET_SIGNAL_INT: - return SIGINT; -#endif -#if defined (SIGQUIT) - case TARGET_SIGNAL_QUIT: - return SIGQUIT; -#endif -#if defined (SIGILL) - case TARGET_SIGNAL_ILL: - return SIGILL; -#endif -#if defined (SIGTRAP) - case TARGET_SIGNAL_TRAP: - return SIGTRAP; -#endif -#if defined (SIGABRT) - case TARGET_SIGNAL_ABRT: - return SIGABRT; -#endif -#if defined (SIGEMT) - case TARGET_SIGNAL_EMT: - return SIGEMT; -#endif -#if defined (SIGFPE) - case TARGET_SIGNAL_FPE: - return SIGFPE; -#endif -#if defined (SIGKILL) - case TARGET_SIGNAL_KILL: - return SIGKILL; -#endif -#if defined (SIGBUS) - case TARGET_SIGNAL_BUS: - return SIGBUS; -#endif -#if defined (SIGSEGV) - case TARGET_SIGNAL_SEGV: - return SIGSEGV; -#endif -#if defined (SIGSYS) - case TARGET_SIGNAL_SYS: - return SIGSYS; -#endif -#if defined (SIGPIPE) - case TARGET_SIGNAL_PIPE: - return SIGPIPE; -#endif -#if defined (SIGALRM) - case TARGET_SIGNAL_ALRM: - return SIGALRM; -#endif -#if defined (SIGTERM) - case TARGET_SIGNAL_TERM: - return SIGTERM; -#endif -#if defined (SIGUSR1) - case TARGET_SIGNAL_USR1: - return SIGUSR1; -#endif -#if defined (SIGUSR2) - case TARGET_SIGNAL_USR2: - return SIGUSR2; -#endif -#if defined (SIGCHLD) || defined (SIGCLD) - case TARGET_SIGNAL_CHLD: -#if defined (SIGCHLD) - return SIGCHLD; -#else - return SIGCLD; -#endif -#endif /* SIGCLD or SIGCHLD */ -#if defined (SIGPWR) - case TARGET_SIGNAL_PWR: - return SIGPWR; -#endif -#if defined (SIGWINCH) - case TARGET_SIGNAL_WINCH: - return SIGWINCH; -#endif -#if defined (SIGURG) - case TARGET_SIGNAL_URG: - return SIGURG; -#endif -#if defined (SIGIO) - case TARGET_SIGNAL_IO: - return SIGIO; -#endif -#if defined (SIGPOLL) - case TARGET_SIGNAL_POLL: - return SIGPOLL; -#endif -#if defined (SIGSTOP) - case TARGET_SIGNAL_STOP: - return SIGSTOP; -#endif -#if defined (SIGTSTP) - case TARGET_SIGNAL_TSTP: - return SIGTSTP; -#endif -#if defined (SIGCONT) - case TARGET_SIGNAL_CONT: - return SIGCONT; -#endif -#if defined (SIGTTIN) - case TARGET_SIGNAL_TTIN: - return SIGTTIN; -#endif -#if defined (SIGTTOU) - case TARGET_SIGNAL_TTOU: - return SIGTTOU; -#endif -#if defined (SIGVTALRM) - case TARGET_SIGNAL_VTALRM: - return SIGVTALRM; -#endif -#if defined (SIGPROF) - case TARGET_SIGNAL_PROF: - return SIGPROF; -#endif -#if defined (SIGXCPU) - case TARGET_SIGNAL_XCPU: - return SIGXCPU; -#endif -#if defined (SIGXFSZ) - case TARGET_SIGNAL_XFSZ: - return SIGXFSZ; -#endif -#if defined (SIGWIND) - case TARGET_SIGNAL_WIND: - return SIGWIND; -#endif -#if defined (SIGPHONE) - case TARGET_SIGNAL_PHONE: - return SIGPHONE; -#endif -#if defined (SIGLOST) - case TARGET_SIGNAL_LOST: - return SIGLOST; -#endif -#if defined (SIGWAITING) - case TARGET_SIGNAL_WAITING: - return SIGWAITING; -#endif -#if defined (SIGCANCEL) - case TARGET_SIGNAL_CANCEL: - return SIGCANCEL; -#endif -#if defined (SIGLWP) - case TARGET_SIGNAL_LWP: - return SIGLWP; -#endif -#if defined (SIGDANGER) - case TARGET_SIGNAL_DANGER: - return SIGDANGER; -#endif -#if defined (SIGGRANT) - case TARGET_SIGNAL_GRANT: - return SIGGRANT; -#endif -#if defined (SIGRETRACT) - case TARGET_SIGNAL_RETRACT: - return SIGRETRACT; -#endif -#if defined (SIGMSG) - case TARGET_SIGNAL_MSG: - return SIGMSG; -#endif -#if defined (SIGSOUND) - case TARGET_SIGNAL_SOUND: - return SIGSOUND; -#endif -#if defined (SIGSAK) - case TARGET_SIGNAL_SAK: - return SIGSAK; -#endif -#if defined (SIGPRIO) - case TARGET_SIGNAL_PRIO: - return SIGPRIO; -#endif - - /* Mach exceptions. Assumes that the values for EXC_ are positive! */ -#if defined (EXC_BAD_ACCESS) && defined (_NSIG) - case TARGET_EXC_BAD_ACCESS: - return _NSIG + EXC_BAD_ACCESS; -#endif -#if defined (EXC_BAD_INSTRUCTION) && defined (_NSIG) - case TARGET_EXC_BAD_INSTRUCTION: - return _NSIG + EXC_BAD_INSTRUCTION; -#endif -#if defined (EXC_ARITHMETIC) && defined (_NSIG) - case TARGET_EXC_ARITHMETIC: - return _NSIG + EXC_ARITHMETIC; -#endif -#if defined (EXC_EMULATION) && defined (_NSIG) - case TARGET_EXC_EMULATION: - return _NSIG + EXC_EMULATION; -#endif -#if defined (EXC_SOFTWARE) && defined (_NSIG) - case TARGET_EXC_SOFTWARE: - return _NSIG + EXC_SOFTWARE; -#endif -#if defined (EXC_BREAKPOINT) && defined (_NSIG) - case TARGET_EXC_BREAKPOINT: - return _NSIG + EXC_BREAKPOINT; -#endif + struct target_ops **t; + struct target_ops *runable = NULL; + int count; -#if defined (SIGINFO) - case TARGET_SIGNAL_INFO: - return SIGINFO; -#endif + count = 0; - default: -#if defined (REALTIME_LO) - if (oursig >= TARGET_SIGNAL_REALTIME_33 - && oursig <= TARGET_SIGNAL_REALTIME_63) - { - /* This block of signals is continuous, and - TARGET_SIGNAL_REALTIME_33 is 33 by definition. */ - int retsig = - (int) oursig - (int) TARGET_SIGNAL_REALTIME_33 + 33; - if (retsig >= REALTIME_LO && retsig < REALTIME_HI) - return retsig; - } -#if (REALTIME_LO < 33) - else if (oursig == TARGET_SIGNAL_REALTIME_32) + for (t = target_structs; t < target_structs + target_struct_size; + ++t) + { + if ((*t)->to_stratum == core_stratum) { - /* TARGET_SIGNAL_REALTIME_32 isn't contiguous with - TARGET_SIGNAL_REALTIME_33. It is 32 by definition. */ - return 32; + runable = *t; + ++count; } -#endif -#endif - *oursig_ok = 0; - return 0; } + + return (count == 1 ? runable : NULL); } -int -target_signal_to_host_p (enum target_signal oursig) +/* + * Find the next target down the stack from the specified target. + */ + +struct target_ops * +find_target_beneath (struct target_ops *t) { - int oursig_ok; - do_target_signal_to_host (oursig, &oursig_ok); - return oursig_ok; + return t->beneath; } -int -target_signal_to_host (enum target_signal oursig) + +/* The inferior process has died. Long live the inferior! */ + +void +generic_mourn_inferior (void) { - int oursig_ok; - int targ_signo = do_target_signal_to_host (oursig, &oursig_ok); - if (!oursig_ok) - { - /* The user might be trying to do "signal SIGSAK" where this system - doesn't have SIGSAK. */ - warning ("Signal %s does not exist on this system.\n", - target_signal_to_name (oursig)); - return 0; - } - else - return targ_signo; -} + extern int show_breakpoint_hit_counts; + + inferior_ptid = null_ptid; + attach_flag = 0; + breakpoint_init_inferior (inf_exited); + registers_changed (); + + reopen_exec_file (); + reinit_frame_cache (); + + /* It is confusing to the user for ignore counts to stick around + from previous runs of the inferior. So clear them. */ + /* However, it is more confusing for the ignore counts to disappear when + using hit counts. So don't clear them if we're counting hits. */ + if (!show_breakpoint_hit_counts) + breakpoint_clear_ignore_counts (); + if (deprecated_detach_hook) + deprecated_detach_hook (); +} + /* Helper function for child_wait and the Lynx derivatives of child_wait. HOSTSTATUS is the waitstatus from wait() or the equivalent; store our translation of that in OURSTATUS. */ @@ -2044,23 +1747,6 @@ store_waitstatus (struct target_waitstatus *ourstatus, int hoststatus) } } -/* In some circumstances we allow a command to specify a numeric - signal. The idea is to keep these circumstances limited so that - users (and scripts) develop portable habits. For comparison, - POSIX.2 `kill' requires that 1,2,3,6,9,14, and 15 work (and using a - numeric signal at all is obscelescent. We are slightly more - lenient and allow 1-15 which should match host signal numbers on - most systems. Use of symbolic signal names is strongly encouraged. */ - -enum target_signal -target_signal_from_command (int num) -{ - if (num >= 1 && num <= 15) - return (enum target_signal) num; - error ("Only signals 1-15 are valid as numeric signals.\n\ -Use \"info signals\" for a list of symbolic signals."); -} - /* Returns zero to leave the inferior alone, one to interrupt it. */ int (*target_activity_function) (void); int target_activity_fd; @@ -2069,34 +1755,26 @@ int target_activity_fd; buffer. */ char * -normal_pid_to_str (int pid) +normal_pid_to_str (ptid_t ptid) { static char buf[30]; - if (STREQ (current_target.to_shortname, "remote")) - sprintf (buf, "thread %d", pid); - else - sprintf (buf, "process %d", pid); - + sprintf (buf, "process %d", PIDGET (ptid)); return buf; } -/* Some targets (such as ttrace-based HPUX) don't allow us to request - notification of inferior events such as fork and vork immediately - after the inferior is created. (This because of how gdb gets an - inferior created via invoking a shell to do it. In such a scenario, - if the shell init file has commands in it, the shell will fork and - exec for each of those commands, and we will see each such fork - event. Very bad.) +/* Error-catcher for target_find_memory_regions */ +static int dummy_find_memory_regions (int (*ignore1) (), void *ignore2) +{ + error ("No target."); + return 0; +} - This function is used by all targets that allow us to request - notification of forks, etc at inferior creation time; e.g., in - target_acknowledge_forked_child. - */ -static void -normal_target_post_startup_inferior (int pid) +/* Error-catcher for target_make_corefile_notes */ +static char * dummy_make_corefile_notes (bfd *ignore1, int *ignore2) { - /* This space intentionally left blank. */ + error ("No target."); + return NULL; } /* Set up the handful of non-empty slots needed by the dummy target @@ -2109,18 +1787,15 @@ init_dummy_target (void) dummy_target.to_longname = "None"; dummy_target.to_doc = ""; dummy_target.to_attach = find_default_attach; - dummy_target.to_require_attach = find_default_require_attach; - dummy_target.to_require_detach = find_default_require_detach; dummy_target.to_create_inferior = find_default_create_inferior; - dummy_target.to_clone_and_follow_inferior = find_default_clone_and_follow_inferior; dummy_target.to_pid_to_str = normal_pid_to_str; dummy_target.to_stratum = dummy_stratum; + dummy_target.to_find_memory_regions = dummy_find_memory_regions; + dummy_target.to_make_corefile_notes = dummy_make_corefile_notes; + dummy_target.to_xfer_partial = default_xfer_partial; dummy_target.to_magic = OPS_MAGIC; } - -static struct target_ops debug_target; - static void debug_to_open (char *args, int from_tty) { @@ -2132,11 +1807,19 @@ debug_to_open (char *args, int from_tty) static void debug_to_close (int quitting) { - debug_target.to_close (quitting); - + target_close (&debug_target, quitting); fprintf_unfiltered (gdb_stdlog, "target_close (%d)\n", quitting); } +void +target_close (struct target_ops *targ, int quitting) +{ + if (targ->to_xclose != NULL) + targ->to_xclose (targ, quitting); + else if (targ->to_close != NULL) + targ->to_close (quitting); +} + static void debug_to_attach (char *args, int from_tty) { @@ -2154,15 +1837,6 @@ debug_to_post_attach (int pid) fprintf_unfiltered (gdb_stdlog, "target_post_attach (%d)\n", pid); } -static void -debug_to_require_attach (char *args, int from_tty) -{ - debug_target.to_require_attach (args, from_tty); - - fprintf_unfiltered (gdb_stdlog, - "target_require_attach (%s, %d)\n", args, from_tty); -} - static void debug_to_detach (char *args, int from_tty) { @@ -2172,33 +1846,34 @@ debug_to_detach (char *args, int from_tty) } static void -debug_to_require_detach (int pid, char *args, int from_tty) +debug_to_disconnect (char *args, int from_tty) { - debug_target.to_require_detach (pid, args, from_tty); + debug_target.to_disconnect (args, from_tty); - fprintf_unfiltered (gdb_stdlog, - "target_require_detach (%d, %s, %d)\n", pid, args, from_tty); + fprintf_unfiltered (gdb_stdlog, "target_disconnect (%s, %d)\n", + args, from_tty); } static void -debug_to_resume (int pid, int step, enum target_signal siggnal) +debug_to_resume (ptid_t ptid, int step, enum target_signal siggnal) { - debug_target.to_resume (pid, step, siggnal); + debug_target.to_resume (ptid, step, siggnal); - fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n", pid, + fprintf_unfiltered (gdb_stdlog, "target_resume (%d, %s, %s)\n", PIDGET (ptid), step ? "step" : "continue", target_signal_to_name (siggnal)); } -static int -debug_to_wait (int pid, struct target_waitstatus *status) +static ptid_t +debug_to_wait (ptid_t ptid, struct target_waitstatus *status) { - int retval; + ptid_t retval; - retval = debug_target.to_wait (pid, status); + retval = debug_target.to_wait (ptid, status); fprintf_unfiltered (gdb_stdlog, - "target_wait (%d, status) = %d, ", pid, retval); + "target_wait (%d, status) = %d, ", PIDGET (ptid), + PIDGET (retval)); fprintf_unfiltered (gdb_stdlog, "status->kind = "); switch (status->kind) { @@ -2238,40 +1913,47 @@ debug_to_wait (int pid, struct target_waitstatus *status) } static void -debug_to_post_wait (int pid, int status) +debug_print_register (const char * func, int regno) { - debug_target.to_post_wait (pid, status); - - fprintf_unfiltered (gdb_stdlog, "target_post_wait (%d, %d)\n", - pid, status); + fprintf_unfiltered (gdb_stdlog, "%s ", func); + if (regno >= 0 && regno < NUM_REGS + NUM_PSEUDO_REGS + && REGISTER_NAME (regno) != NULL && REGISTER_NAME (regno)[0] != '\0') + fprintf_unfiltered (gdb_stdlog, "(%s)", REGISTER_NAME (regno)); + else + fprintf_unfiltered (gdb_stdlog, "(%d)", regno); + if (regno >= 0) + { + int i; + unsigned char buf[MAX_REGISTER_SIZE]; + deprecated_read_register_gen (regno, buf); + fprintf_unfiltered (gdb_stdlog, " = "); + for (i = 0; i < register_size (current_gdbarch, regno); i++) + { + fprintf_unfiltered (gdb_stdlog, "%02x", buf[i]); + } + if (register_size (current_gdbarch, regno) <= sizeof (LONGEST)) + { + fprintf_unfiltered (gdb_stdlog, " 0x%s %s", + paddr_nz (read_register (regno)), + paddr_d (read_register (regno))); + } + } + fprintf_unfiltered (gdb_stdlog, "\n"); } static void debug_to_fetch_registers (int regno) { debug_target.to_fetch_registers (regno); - - fprintf_unfiltered (gdb_stdlog, "target_fetch_registers (%s)", - regno != -1 ? REGISTER_NAME (regno) : "-1"); - if (regno != -1) - fprintf_unfiltered (gdb_stdlog, " = 0x%lx %ld", - (unsigned long) read_register (regno), - (unsigned long) read_register (regno)); - fprintf_unfiltered (gdb_stdlog, "\n"); + debug_print_register ("target_fetch_registers", regno); } static void debug_to_store_registers (int regno) { debug_target.to_store_registers (regno); - - if (regno >= 0 && regno < NUM_REGS) - fprintf_unfiltered (gdb_stdlog, "target_store_registers (%s) = 0x%lx %ld\n", - REGISTER_NAME (regno), - (unsigned long) read_register (regno), - (unsigned long) read_register (regno)); - else - fprintf_unfiltered (gdb_stdlog, "target_store_registers (%d)\n", regno); + debug_print_register ("target_store_registers", regno); + fprintf_unfiltered (gdb_stdlog, "\n"); } static void @@ -2283,20 +1965,20 @@ debug_to_prepare_to_store (void) } static int -debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, - struct target_ops *target) +deprecated_debug_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, + int write, struct mem_attrib *attrib, + struct target_ops *target) { int retval; - retval = debug_target.to_xfer_memory (memaddr, myaddr, len, write, target); + retval = debug_target.deprecated_xfer_memory (memaddr, myaddr, len, write, + attrib, target); fprintf_unfiltered (gdb_stdlog, "target_xfer_memory (0x%x, xxx, %d, %s, xxx) = %d", (unsigned int) memaddr, /* possable truncate long long */ len, write ? "write" : "read", retval); - - if (retval > 0) { int i; @@ -2305,7 +1987,15 @@ debug_to_xfer_memory (CORE_ADDR memaddr, char *myaddr, int len, int write, for (i = 0; i < retval; i++) { if ((((long) &(myaddr[i])) & 0xf) == 0) - fprintf_unfiltered (gdb_stdlog, "\n"); + { + if (targetdebug < 2 && i > 0) + { + fprintf_unfiltered (gdb_stdlog, " ..."); + break; + } + fprintf_unfiltered (gdb_stdlog, "\n"); + } + fprintf_unfiltered (gdb_stdlog, " %02x", myaddr[i] & 0xff); } } @@ -2351,6 +2041,117 @@ debug_to_remove_breakpoint (CORE_ADDR addr, char *save) return retval; } +static int +debug_to_can_use_hw_breakpoint (int type, int cnt, int from_tty) +{ + int retval; + + retval = debug_target.to_can_use_hw_breakpoint (type, cnt, from_tty); + + fprintf_unfiltered (gdb_stdlog, + "target_can_use_hw_breakpoint (%ld, %ld, %ld) = %ld\n", + (unsigned long) type, + (unsigned long) cnt, + (unsigned long) from_tty, + (unsigned long) retval); + return retval; +} + +static int +debug_to_region_size_ok_for_hw_watchpoint (int byte_count) +{ + CORE_ADDR retval; + + retval = debug_target.to_region_size_ok_for_hw_watchpoint (byte_count); + + fprintf_unfiltered (gdb_stdlog, + "TARGET_REGION_SIZE_OK_FOR_HW_WATCHPOINT (%ld) = 0x%lx\n", + (unsigned long) byte_count, + (unsigned long) retval); + return retval; +} + +static int +debug_to_stopped_by_watchpoint (void) +{ + int retval; + + retval = debug_target.to_stopped_by_watchpoint (); + + fprintf_unfiltered (gdb_stdlog, + "STOPPED_BY_WATCHPOINT () = %ld\n", + (unsigned long) retval); + return retval; +} + +static int +debug_to_stopped_data_address (struct target_ops *target, CORE_ADDR *addr) +{ + int retval; + + retval = debug_target.to_stopped_data_address (target, addr); + + fprintf_unfiltered (gdb_stdlog, + "target_stopped_data_address ([0x%lx]) = %ld\n", + (unsigned long)*addr, + (unsigned long)retval); + return retval; +} + +static int +debug_to_insert_hw_breakpoint (CORE_ADDR addr, char *save) +{ + int retval; + + retval = debug_target.to_insert_hw_breakpoint (addr, save); + + fprintf_unfiltered (gdb_stdlog, + "target_insert_hw_breakpoint (0x%lx, xxx) = %ld\n", + (unsigned long) addr, + (unsigned long) retval); + return retval; +} + +static int +debug_to_remove_hw_breakpoint (CORE_ADDR addr, char *save) +{ + int retval; + + retval = debug_target.to_remove_hw_breakpoint (addr, save); + + fprintf_unfiltered (gdb_stdlog, + "target_remove_hw_breakpoint (0x%lx, xxx) = %ld\n", + (unsigned long) addr, + (unsigned long) retval); + return retval; +} + +static int +debug_to_insert_watchpoint (CORE_ADDR addr, int len, int type) +{ + int retval; + + retval = debug_target.to_insert_watchpoint (addr, len, type); + + fprintf_unfiltered (gdb_stdlog, + "target_insert_watchpoint (0x%lx, %d, %d) = %ld\n", + (unsigned long) addr, len, type, (unsigned long) retval); + return retval; +} + +static int +debug_to_remove_watchpoint (CORE_ADDR addr, int len, int type) +{ + int retval; + + retval = debug_target.to_insert_watchpoint (addr, len, type); + + fprintf_unfiltered (gdb_stdlog, + "target_insert_watchpoint (0x%lx, %d, %d) = %ld\n", + (unsigned long) addr, len, type, (unsigned long) retval); + return retval; +} + static void debug_to_terminal_init (void) { @@ -2383,6 +2184,14 @@ debug_to_terminal_ours (void) fprintf_unfiltered (gdb_stdlog, "target_terminal_ours ()\n"); } +static void +debug_to_terminal_save_ours (void) +{ + debug_target.to_terminal_save_ours (); + + fprintf_unfiltered (gdb_stdlog, "target_terminal_save_ours ()\n"); +} + static void debug_to_terminal_info (char *arg, int from_tty) { @@ -2421,21 +2230,22 @@ debug_to_lookup_symbol (char *name, CORE_ADDR *addrp) } static void -debug_to_create_inferior (char *exec_file, char *args, char **env) +debug_to_create_inferior (char *exec_file, char *args, char **env, + int from_tty) { - debug_target.to_create_inferior (exec_file, args, env); + debug_target.to_create_inferior (exec_file, args, env, from_tty); - fprintf_unfiltered (gdb_stdlog, "target_create_inferior (%s, %s, xxx)\n", - exec_file, args); + fprintf_unfiltered (gdb_stdlog, "target_create_inferior (%s, %s, xxx, %d)\n", + exec_file, args, from_tty); } static void -debug_to_post_startup_inferior (int pid) +debug_to_post_startup_inferior (ptid_t ptid) { - debug_target.to_post_startup_inferior (pid); + debug_target.to_post_startup_inferior (ptid); fprintf_unfiltered (gdb_stdlog, "target_post_startup_inferior (%d)\n", - pid); + PIDGET (ptid)); } static void @@ -2447,24 +2257,6 @@ debug_to_acknowledge_created_inferior (int pid) pid); } -static void -debug_to_clone_and_follow_inferior (int child_pid, int *followed_child) -{ - debug_target.to_clone_and_follow_inferior (child_pid, followed_child); - - fprintf_unfiltered (gdb_stdlog, - "target_clone_and_follow_inferior (%d, %d)\n", - child_pid, *followed_child); -} - -static void -debug_to_post_follow_inferior_by_clone (void) -{ - debug_target.to_post_follow_inferior_by_clone (); - - fprintf_unfiltered (gdb_stdlog, "target_post_follow_inferior_by_clone ()\n"); -} - static int debug_to_insert_fork_catchpoint (int pid) { @@ -2518,53 +2310,14 @@ debug_to_remove_vfork_catchpoint (int pid) } static int -debug_to_has_forked (int pid, int *child_pid) -{ - int has_forked; - - has_forked = debug_target.to_has_forked (pid, child_pid); - - fprintf_unfiltered (gdb_stdlog, "target_has_forked (%d, %d) = %d\n", - pid, *child_pid, has_forked); - - return has_forked; -} - -static int -debug_to_has_vforked (int pid, int *child_pid) -{ - int has_vforked; - - has_vforked = debug_target.to_has_vforked (pid, child_pid); - - fprintf_unfiltered (gdb_stdlog, "target_has_vforked (%d, %d) = %d\n", - pid, *child_pid, has_vforked); - - return has_vforked; -} - -static int -debug_to_can_follow_vfork_prior_to_exec (void) +debug_to_follow_fork (int follow_child) { - int can_immediately_follow_vfork; + int retval = debug_target.to_follow_fork (follow_child); - can_immediately_follow_vfork = debug_target.to_can_follow_vfork_prior_to_exec (); + fprintf_unfiltered (gdb_stdlog, "target_follow_fork (%d) = %d\n", + follow_child, retval); - fprintf_unfiltered (gdb_stdlog, "target_can_follow_vfork_prior_to_exec () = %d\n", - can_immediately_follow_vfork); - - return can_immediately_follow_vfork; -} - -static void -debug_to_post_follow_vfork (int parent_pid, int followed_parent, int child_pid, - int followed_child) -{ - debug_target.to_post_follow_vfork (parent_pid, followed_parent, child_pid, followed_child); - - fprintf_unfiltered (gdb_stdlog, - "target_post_follow_vfork (%d, %d, %d, %d)\n", - parent_pid, followed_parent, child_pid, followed_child); + return retval; } static int @@ -2593,20 +2346,6 @@ debug_to_remove_exec_catchpoint (int pid) return retval; } -static int -debug_to_has_execd (int pid, char **execd_pathname) -{ - int has_execd; - - has_execd = debug_target.to_has_execd (pid, execd_pathname); - - fprintf_unfiltered (gdb_stdlog, "target_has_execd (%d, %s) = %d\n", - pid, (*execd_pathname ? *execd_pathname : ""), - has_execd); - - return has_execd; -} - static int debug_to_reported_exec_events_per_exec_call (void) { @@ -2621,36 +2360,6 @@ debug_to_reported_exec_events_per_exec_call (void) return reported_exec_events; } -static int -debug_to_has_syscall_event (int pid, enum target_waitkind *kind, - int *syscall_id) -{ - int has_syscall_event; - char *kind_spelling = "??"; - - has_syscall_event = debug_target.to_has_syscall_event (pid, kind, syscall_id); - if (has_syscall_event) - { - switch (*kind) - { - case TARGET_WAITKIND_SYSCALL_ENTRY: - kind_spelling = "SYSCALL_ENTRY"; - break; - case TARGET_WAITKIND_SYSCALL_RETURN: - kind_spelling = "SYSCALL_RETURN"; - break; - default: - break; - } - } - - fprintf_unfiltered (gdb_stdlog, - "target_has_syscall_event (%d, %s, %d) = %d\n", - pid, kind_spelling, *syscall_id, has_syscall_event); - - return has_syscall_event; -} - static int debug_to_has_exited (int pid, int wait_status, int *exit_status) { @@ -2685,22 +2394,23 @@ debug_to_can_run (void) } static void -debug_to_notice_signals (int pid) +debug_to_notice_signals (ptid_t ptid) { - debug_target.to_notice_signals (pid); + debug_target.to_notice_signals (ptid); - fprintf_unfiltered (gdb_stdlog, "target_notice_signals (%d)\n", pid); + fprintf_unfiltered (gdb_stdlog, "target_notice_signals (%d)\n", + PIDGET (ptid)); } static int -debug_to_thread_alive (int pid) +debug_to_thread_alive (ptid_t ptid) { int retval; - retval = debug_target.to_thread_alive (pid); + retval = debug_target.to_thread_alive (ptid); fprintf_unfiltered (gdb_stdlog, "target_thread_alive (%d) = %d\n", - pid, retval); + PIDGET (ptid), retval); return retval; } @@ -2721,18 +2431,6 @@ debug_to_stop (void) fprintf_unfiltered (gdb_stdlog, "target_stop ()\n"); } -static int -debug_to_query (int type, char *req, char *resp, int *siz) -{ - int retval; - - retval = debug_target.to_query (type, req, resp, siz); - - fprintf_unfiltered (gdb_stdlog, "target_query (%c, %s, %s, %d) = %d\n", type, req, resp, *siz, retval); - - return retval; -} - static void debug_to_rcmd (char *command, struct ui_file *outbuf) @@ -2774,19 +2472,6 @@ debug_to_pid_to_exec_file (int pid) return exec_file; } -static char * -debug_to_core_file_to_sym_file (char *core) -{ - char *sym_file; - - sym_file = debug_target.to_core_file_to_sym_file (core); - - fprintf_unfiltered (gdb_stdlog, "target_core_file_to_sym_file (%s) = %s\n", - core, sym_file); - - return sym_file; -} - static void setup_target_debug (void) { @@ -2796,23 +2481,30 @@ setup_target_debug (void) current_target.to_close = debug_to_close; current_target.to_attach = debug_to_attach; current_target.to_post_attach = debug_to_post_attach; - current_target.to_require_attach = debug_to_require_attach; current_target.to_detach = debug_to_detach; - current_target.to_require_detach = debug_to_require_detach; + current_target.to_disconnect = debug_to_disconnect; current_target.to_resume = debug_to_resume; current_target.to_wait = debug_to_wait; - current_target.to_post_wait = debug_to_post_wait; current_target.to_fetch_registers = debug_to_fetch_registers; current_target.to_store_registers = debug_to_store_registers; current_target.to_prepare_to_store = debug_to_prepare_to_store; - current_target.to_xfer_memory = debug_to_xfer_memory; + current_target.deprecated_xfer_memory = deprecated_debug_xfer_memory; current_target.to_files_info = debug_to_files_info; current_target.to_insert_breakpoint = debug_to_insert_breakpoint; current_target.to_remove_breakpoint = debug_to_remove_breakpoint; + current_target.to_can_use_hw_breakpoint = debug_to_can_use_hw_breakpoint; + current_target.to_insert_hw_breakpoint = debug_to_insert_hw_breakpoint; + current_target.to_remove_hw_breakpoint = debug_to_remove_hw_breakpoint; + current_target.to_insert_watchpoint = debug_to_insert_watchpoint; + current_target.to_remove_watchpoint = debug_to_remove_watchpoint; + current_target.to_stopped_by_watchpoint = debug_to_stopped_by_watchpoint; + current_target.to_stopped_data_address = debug_to_stopped_data_address; + current_target.to_region_size_ok_for_hw_watchpoint = debug_to_region_size_ok_for_hw_watchpoint; current_target.to_terminal_init = debug_to_terminal_init; current_target.to_terminal_inferior = debug_to_terminal_inferior; current_target.to_terminal_ours_for_output = debug_to_terminal_ours_for_output; current_target.to_terminal_ours = debug_to_terminal_ours; + current_target.to_terminal_save_ours = debug_to_terminal_save_ours; current_target.to_terminal_info = debug_to_terminal_info; current_target.to_kill = debug_to_kill; current_target.to_load = debug_to_load; @@ -2820,21 +2512,14 @@ setup_target_debug (void) current_target.to_create_inferior = debug_to_create_inferior; current_target.to_post_startup_inferior = debug_to_post_startup_inferior; current_target.to_acknowledge_created_inferior = debug_to_acknowledge_created_inferior; - current_target.to_clone_and_follow_inferior = debug_to_clone_and_follow_inferior; - current_target.to_post_follow_inferior_by_clone = debug_to_post_follow_inferior_by_clone; current_target.to_insert_fork_catchpoint = debug_to_insert_fork_catchpoint; current_target.to_remove_fork_catchpoint = debug_to_remove_fork_catchpoint; current_target.to_insert_vfork_catchpoint = debug_to_insert_vfork_catchpoint; current_target.to_remove_vfork_catchpoint = debug_to_remove_vfork_catchpoint; - current_target.to_has_forked = debug_to_has_forked; - current_target.to_has_vforked = debug_to_has_vforked; - current_target.to_can_follow_vfork_prior_to_exec = debug_to_can_follow_vfork_prior_to_exec; - current_target.to_post_follow_vfork = debug_to_post_follow_vfork; + current_target.to_follow_fork = debug_to_follow_fork; current_target.to_insert_exec_catchpoint = debug_to_insert_exec_catchpoint; current_target.to_remove_exec_catchpoint = debug_to_remove_exec_catchpoint; - current_target.to_has_execd = debug_to_has_execd; current_target.to_reported_exec_events_per_exec_call = debug_to_reported_exec_events_per_exec_call; - current_target.to_has_syscall_event = debug_to_has_syscall_event; current_target.to_has_exited = debug_to_has_exited; current_target.to_mourn_inferior = debug_to_mourn_inferior; current_target.to_can_run = debug_to_can_run; @@ -2842,12 +2527,10 @@ setup_target_debug (void) current_target.to_thread_alive = debug_to_thread_alive; current_target.to_find_new_threads = debug_to_find_new_threads; current_target.to_stop = debug_to_stop; - current_target.to_query = debug_to_query; current_target.to_rcmd = debug_to_rcmd; current_target.to_enable_exception_callback = debug_to_enable_exception_callback; current_target.to_get_current_exception_event = debug_to_get_current_exception_event; current_target.to_pid_to_exec_file = debug_to_pid_to_exec_file; - current_target.to_core_file_to_sym_file = debug_to_core_file_to_sym_file; } @@ -2881,17 +2564,28 @@ initialize_targets (void) add_info ("target", target_info, targ_desc); add_info ("files", target_info, targ_desc); - add_show_from_set ( - add_set_cmd ("target", class_maintenance, var_zinteger, - (char *) &targetdebug, - "Set target debugging.\n\ -When non-zero, target debugging is enabled.", &setdebuglist), - &showdebuglist); - + deprecated_add_show_from_set + (add_set_cmd ("target", class_maintenance, var_zinteger, + (char *) &targetdebug, + "Set target debugging.\n\ +When non-zero, target debugging is enabled. Higher numbers are more\n\ +verbose. Changes do not take effect until the next \"run\" or \"target\"\n\ +command.", &setdebuglist), + &showdebuglist); + + add_setshow_boolean_cmd ("trust-readonly-sections", class_support, + &trust_readonly, "\ +Set mode for reading from readonly sections.", "\ +Show mode for reading from readonly sections.", "\ +When this mode is on, memory reads from readonly sections (such as .text)\n\ +will be read from the object file instead of from the target. This will\n\ +result in significant performance improvement for remote targets.", "\ +Mode for reading from readonly sections is %s.", + NULL, NULL, + &setlist, &showlist); add_com ("monitor", class_obscure, do_monitor_command, "Send a command to the remote monitor (remote targets only)."); - if (!STREQ (signals[TARGET_SIGNAL_LAST].string, "TARGET_SIGNAL_MAGIC")) - abort (); + target_dcache = dcache_init (); }