X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Ftarget.c;h=5f7a2e729afd6751677878d62b40ba7d2f88eea0;hb=d62d0f5fc2156db337ac3cbbc3c05ca76565dbd3;hp=ed7ccdc9997cdb8c4dbc689f70e5ade86068db50;hpb=a96d9b2e9a79e6cc7a9da9b4e5bab6fcc35f1eb4;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/target.c b/gdb/target.c index ed7ccdc999..5f7a2e729a 100644 --- a/gdb/target.c +++ b/gdb/target.c @@ -1,7 +1,7 @@ /* Select target systems and architectures at runtime for GDB. Copyright (C) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, - 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. Contributed by Cygnus Support. @@ -46,8 +46,6 @@ static void target_info (char *, int); -static void kill_or_be_killed (int); - static void default_terminal_info (char *, int); static int default_watchpoint_addr_within_range (struct target_ops *, @@ -73,8 +71,6 @@ static void target_command (char *, int); static struct target_ops *find_default_run_target (char *); -static void nosupport_runtime (void); - static LONGEST default_xfer_partial (struct target_ops *ops, enum target_object object, const char *annex, gdb_byte *readbuf, @@ -481,8 +477,10 @@ void target_terminal_inferior (void) { /* A background resume (``run&'') should leave GDB in control of the - terminal. */ - if (target_is_async_p () && !sync_execution) + terminal. Use target_can_async_p, not target_is_async_p, since at + this point the target is not async yet. However, if sync_execution + is not set, we know it will become async prior to resume. */ + if (target_can_async_p () && !sync_execution) return; /* If GDB is resuming the inferior in the foreground, install @@ -517,49 +515,12 @@ nosymbol (char *name, CORE_ADDR *addrp) return 1; /* Symbol does not exist in target env */ } -static void -nosupport_runtime (void) -{ - if (ptid_equal (inferior_ptid, null_ptid)) - noprocess (); - else - error (_("No run-time support for this")); -} - - static void default_terminal_info (char *args, int from_tty) { printf_unfiltered (_("No saved terminal information.\n")); } -/* This is the default target_create_inferior and target_attach function. - If the current target is executing, it asks whether to kill it off. - If this function returns without calling error(), it has killed off - the target, and the operation should be attempted. */ - -static void -kill_or_be_killed (int from_tty) -{ - if (target_has_execution) - { - printf_unfiltered (_("You are already running a program:\n")); - target_files_info (); - if (query (_("Kill it? "))) - { - target_kill (); - if (target_has_execution) - error (_("Killing the program did not help.")); - return; - } - else - { - error (_("Program not killed.")); - } - } - tcomplain (); -} - /* A default implementation for the to_get_ada_task_ptid target method. This function builds the PTID by using both LWP and TID as part of @@ -674,6 +635,8 @@ update_current_target (void) INHERIT (to_async_mask, t); INHERIT (to_find_memory_regions, t); INHERIT (to_make_corefile_notes, t); + INHERIT (to_get_bookmark, t); + INHERIT (to_goto_bookmark, t); /* Do not inherit to_get_thread_local_address. */ INHERIT (to_can_execute_reverse, t); INHERIT (to_thread_architecture, t); @@ -681,6 +644,20 @@ update_current_target (void) INHERIT (to_get_ada_task_ptid, t); /* Do not inherit to_search_memory. */ INHERIT (to_supports_multi_process, t); + INHERIT (to_trace_init, t); + INHERIT (to_download_tracepoint, t); + INHERIT (to_download_trace_state_variable, t); + INHERIT (to_trace_set_readonly_regions, t); + INHERIT (to_trace_start, t); + INHERIT (to_get_trace_status, t); + INHERIT (to_trace_stop, t); + INHERIT (to_trace_find, t); + INHERIT (to_get_trace_state_variable_value, t); + INHERIT (to_save_trace_data, t); + INHERIT (to_upload_tracepoints, t); + INHERIT (to_upload_trace_state_variables, t); + INHERIT (to_get_raw_trace_data, t); + INHERIT (to_set_disconnected_tracing, t); INHERIT (to_magic, t); /* Do not inherit to_memory_map. */ /* Do not inherit to_flash_erase. */ @@ -829,6 +806,48 @@ update_current_target (void) de_fault (to_supports_multi_process, (int (*) (void)) return_zero); + de_fault (to_trace_init, + (void (*) (void)) + tcomplain); + de_fault (to_download_tracepoint, + (void (*) (struct breakpoint *)) + tcomplain); + de_fault (to_download_trace_state_variable, + (void (*) (struct trace_state_variable *)) + tcomplain); + de_fault (to_trace_set_readonly_regions, + (void (*) (void)) + tcomplain); + de_fault (to_trace_start, + (void (*) (void)) + tcomplain); + de_fault (to_get_trace_status, + (int (*) (struct trace_status *)) + return_minus_one); + de_fault (to_trace_stop, + (void (*) (void)) + tcomplain); + de_fault (to_trace_find, + (int (*) (enum trace_find_type, int, ULONGEST, ULONGEST, int *)) + return_zero); + de_fault (to_get_trace_state_variable_value, + (int (*) (int, LONGEST *)) + return_zero); + de_fault (to_save_trace_data, + (int (*) (char *)) + tcomplain); + de_fault (to_upload_tracepoints, + (int (*) (struct uploaded_tp **)) + return_zero); + de_fault (to_upload_trace_state_variables, + (int (*) (struct uploaded_tsv **)) + return_zero); + de_fault (to_get_raw_trace_data, + (LONGEST (*) (gdb_byte *, ULONGEST, LONGEST)) + tcomplain); + de_fault (to_set_disconnected_tracing, + (void (*) (int)) + tcomplain); #undef de_fault /* Finally, position the target-stack beneath the squashed @@ -1181,8 +1200,8 @@ target_section_by_addr (struct target_ops *target, CORE_ADDR addr) return NULL; } -/* Perform a partial memory transfer. The arguments and return - value are just as for target_xfer_partial. */ +/* Perform a partial memory transfer. + For docs see target.h, to_xfer_partial. */ static LONGEST memory_xfer_partial (struct target_ops *ops, enum target_object object, @@ -1267,7 +1286,10 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object, return -1; } - inf = find_inferior_pid (ptid_get_pid (inferior_ptid)); + if (!ptid_equal (inferior_ptid, null_ptid)) + inf = find_inferior_pid (ptid_get_pid (inferior_ptid)); + else + inf = NULL; if (inf != NULL && (region->attrib.cache @@ -1333,7 +1355,7 @@ memory_xfer_partial (struct target_ops *ops, enum target_object object, && stack_cache_enabled_p && object != TARGET_OBJECT_STACK_MEMORY) { - dcache_update (target_dcache, memaddr, (void *) writebuf, reg_len); + dcache_update (target_dcache, memaddr, (void *) writebuf, res); } /* If we still haven't got anything, return the last error. We @@ -1357,6 +1379,8 @@ make_show_memory_breakpoints_cleanup (int show) (void *) (uintptr_t) current); } +/* For docs see target.h, to_xfer_partial. */ + static LONGEST target_xfer_partial (struct target_ops *ops, enum target_object object, const char *annex, @@ -1471,6 +1495,11 @@ target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len) return EIO; } +/* Write LEN bytes from MYADDR to target memory at address MEMADDR. + Returns either 0 for success or an errno value if any error occurs. + If an error occurs, no guarantee is made about how much data got written. + Callers that can deal with partial writes should call target_write. */ + int target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len) { @@ -1634,11 +1663,7 @@ current_xfer_partial (struct target_ops *ops, enum target_object object, 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. */ +/* Target vector read/write partial wrapper functions. */ static LONGEST target_read_partial (struct target_ops *ops, @@ -1659,6 +1684,9 @@ target_write_partial (struct target_ops *ops, } /* Wrappers to perform the full transfer. */ + +/* For docs on target_read see target.h. */ + LONGEST target_read (struct target_ops *ops, enum target_object object, @@ -1747,7 +1775,6 @@ target_read_until_error (struct target_ops *ops, return len; } - /* An alternative to target_write with progress callbacks. */ LONGEST @@ -1783,6 +1810,8 @@ target_write_with_progress (struct target_ops *ops, return len; } +/* For docs on target_write see target.h. */ + LONGEST target_write (struct target_ops *ops, enum target_object object, @@ -2046,7 +2075,9 @@ target_detach (char *args, int from_tty) else /* If we're in breakpoints-always-inserted mode, have to remove them before detaching. */ - remove_breakpoints (); + remove_breakpoints_pid (PIDGET (inferior_ptid)); + + prepare_for_detach (); for (t = current_target.beneath; t != NULL; t = t->beneath) { @@ -2302,7 +2333,7 @@ simple_search_memory (struct target_ops *ops, if (search_space_len >= pattern_len) { unsigned keep_len = search_buf_size - chunk_size; - CORE_ADDR read_addr = start_addr + keep_len; + CORE_ADDR read_addr = start_addr + chunk_size + keep_len; int nr_to_read; /* Copy the trailing part of the previous iteration to the front @@ -2547,6 +2578,42 @@ target_get_osdata (const char *type) 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) +{ + 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)); + + if (inf == NULL || inf->aspace == NULL) + internal_error (__FILE__, __LINE__, "\ +Can't determine the current address space of thread %s\n", + target_pid_to_str (ptid)); + + return inf->aspace; +} + static int default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len) { @@ -2658,7 +2725,7 @@ generic_mourn_inferior (void) if (!ptid_equal (ptid, null_ptid)) { int pid = ptid_get_pid (ptid); - delete_inferior (pid); + exit_inferior (pid); } breakpoint_init_inferior (inf_exited); @@ -2712,20 +2779,37 @@ dummy_pid_to_str (struct target_ops *ops, ptid_t ptid) return normal_pid_to_str (ptid); } -/* Error-catcher for target_find_memory_regions */ -static int dummy_find_memory_regions (int (*ignore1) (), void *ignore2) +/* Error-catcher for target_find_memory_regions. */ +static int +dummy_find_memory_regions (int (*ignore1) (), void *ignore2) { - error (_("No target.")); + error (_("Command not implemented for this target.")); return 0; } -/* Error-catcher for target_make_corefile_notes */ -static char * dummy_make_corefile_notes (bfd *ignore1, int *ignore2) +/* Error-catcher for target_make_corefile_notes. */ +static char * +dummy_make_corefile_notes (bfd *ignore1, int *ignore2) +{ + error (_("Command not implemented for this target.")); + return NULL; +} + +/* Error-catcher for target_get_bookmark. */ +static gdb_byte * +dummy_get_bookmark (char *ignore1, int ignore2) { - error (_("No target.")); + tcomplain (); return NULL; } +/* Error-catcher for target_goto_bookmark. */ +static void +dummy_goto_bookmark (gdb_byte *ignore, int from_tty) +{ + tcomplain (); +} + /* Set up the handful of non-empty slots needed by the dummy target vector. */ @@ -2746,12 +2830,17 @@ init_dummy_target (void) 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_get_bookmark = dummy_get_bookmark; + dummy_target.to_goto_bookmark = dummy_goto_bookmark; dummy_target.to_xfer_partial = default_xfer_partial; dummy_target.to_has_all_memory = (int (*) (struct target_ops *)) return_zero; dummy_target.to_has_memory = (int (*) (struct target_ops *)) return_zero; dummy_target.to_has_stack = (int (*) (struct target_ops *)) return_zero; dummy_target.to_has_registers = (int (*) (struct target_ops *)) return_zero; dummy_target.to_has_execution = (int (*) (struct target_ops *)) return_zero; + dummy_target.to_stopped_by_watchpoint = return_zero; + dummy_target.to_stopped_data_address = + (int (*) (struct target_ops *, CORE_ADDR *)) return_zero; dummy_target.to_magic = OPS_MAGIC; } @@ -2955,6 +3044,26 @@ target_store_registers (struct regcache *regcache, int regno) noprocess (); } +int +target_core_of_thread (ptid_t ptid) +{ + struct target_ops *t; + + for (t = current_target.beneath; t != NULL; t = t->beneath) + { + if (t->to_core_of_thread != NULL) + { + int retval = t->to_core_of_thread (t, ptid); + if (targetdebug) + fprintf_unfiltered (gdb_stdlog, "target_core_of_thread (%d) = %d\n", + PIDGET (ptid), retval); + return retval; + } + } + + return -1; +} + static void debug_to_prepare_to_store (struct regcache *regcache) { @@ -3367,8 +3476,8 @@ debug_to_thread_architecture (struct target_ops *ops, ptid_t ptid) retval = debug_target.to_thread_architecture (ops, ptid); - fprintf_unfiltered (gdb_stdlog, "target_thread_architecture (%s) = %p [%s]\n", - target_pid_to_str (ptid), retval, + fprintf_unfiltered (gdb_stdlog, "target_thread_architecture (%s) = %s [%s]\n", + target_pid_to_str (ptid), host_address_to_string (retval), gdbarch_bfd_arch_info (retval)->printable_name); return retval; }