Add branch trace information to struct thread_info.
[deliverable/binutils-gdb.git] / gdb / target.c
index 151209e246e3b1151d25638a21626a1ddc1d9736..524caec71223371cb710a12fd95429908315fdd3 100644 (file)
@@ -1,6 +1,6 @@
 /* Select target systems and architectures at runtime for GDB.
 
-   Copyright (C) 1990-2012 Free Software Foundation, Inc.
+   Copyright (C) 1990-2013 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
 
@@ -205,7 +205,7 @@ int may_stop = 1;
 
 /* Non-zero if we want to see trace of target level stuff.  */
 
-static int targetdebug = 0;
+static unsigned int targetdebug = 0;
 static void
 show_targetdebug (struct ui_file *file, int from_tty,
                  struct cmd_list_element *c, const char *value)
@@ -693,6 +693,7 @@ update_current_target (void)
       INHERIT (to_get_min_fast_tracepoint_insn_len, t);
       INHERIT (to_set_disconnected_tracing, t);
       INHERIT (to_set_circular_trace_buffer, t);
+      INHERIT (to_set_trace_buffer_size, t);
       INHERIT (to_set_trace_notes, t);
       INHERIT (to_get_tib_address, t);
       INHERIT (to_set_permissions, t);
@@ -703,6 +704,7 @@ update_current_target (void)
       INHERIT (to_can_use_agent, t);
       INHERIT (to_magic, t);
       INHERIT (to_supports_evaluation_of_breakpoint_conditions, t);
+      INHERIT (to_can_run_breakpoint_commands, t);
       /* Do not inherit to_memory_map.  */
       /* Do not inherit to_flash_erase.  */
       /* Do not inherit to_flash_done.  */
@@ -911,6 +913,9 @@ update_current_target (void)
   de_fault (to_set_circular_trace_buffer,
            (void (*) (int))
            target_ignore);
+  de_fault (to_set_trace_buffer_size,
+           (void (*) (LONGEST))
+           target_ignore);
   de_fault (to_set_trace_notes,
            (int (*) (char *, char *, char *))
            return_zero);
@@ -932,6 +937,9 @@ update_current_target (void)
   de_fault (to_supports_evaluation_of_breakpoint_conditions,
            (int (*) (void))
            return_zero);
+  de_fault (to_can_run_breakpoint_commands,
+           (int (*) (void))
+           return_zero);
   de_fault (to_use_agent,
            (int (*) (int))
            tcomplain);
@@ -1124,7 +1132,7 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
     }
 
   if (target != NULL
-      && gdbarch_fetch_tls_load_module_address_p (target_gdbarch))
+      && gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
     {
       ptid_t ptid = inferior_ptid;
       volatile struct gdb_exception ex;
@@ -1134,7 +1142,7 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
          CORE_ADDR lm_addr;
          
          /* Fetch the load module address for this objfile.  */
-         lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch,
+         lm_addr = gdbarch_fetch_tls_load_module_address (target_gdbarch (),
                                                           objfile);
          /* If it's 0, throw the appropriate exception.  */
          if (lm_addr == 0)
@@ -1216,7 +1224,7 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
 int
 target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop)
 {
-  int tlen, origlen, offset, i;
+  int tlen, offset, i;
   gdb_byte buf[4];
   int errcode = 0;
   char *buffer;
@@ -1231,8 +1239,6 @@ target_read_string (CORE_ADDR memaddr, char **string, int len, int *errnop)
   buffer = xmalloc (buffer_allocated);
   bufptr = buffer;
 
-  origlen = len;
-
   while (len > 0)
     {
       tlen = MIN (len, 4 - (memaddr & 3));
@@ -1756,7 +1762,7 @@ target_xfer_partial (struct target_ops *ops,
    it makes no progress, and then return how much was transferred).  */
 
 int
-target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
   /* Dispatch to the topmost target, not the flattened current_target.
      Memory accesses check target->to_has_(all_)memory, and the
@@ -1772,7 +1778,7 @@ target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
    the target's stack.  This may trigger different cache behavior.  */
 
 int
-target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
   /* Dispatch to the topmost target, not the flattened current_target.
      Memory accesses check target->to_has_(all_)memory, and the
@@ -1791,7 +1797,7 @@ target_read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
    Callers that can deal with partial writes should call target_write.  */
 
 int
-target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
+target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 {
   /* Dispatch to the topmost target, not the flattened current_target.
      Memory accesses check target->to_has_(all_)memory, and the
@@ -1810,7 +1816,7 @@ target_write_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
    should call target_write.  */
 
 int
-target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, int len)
+target_write_raw_memory (CORE_ADDR memaddr, const gdb_byte *myaddr, ssize_t len)
 {
   /* Dispatch to the topmost target, not the flattened current_target.
      Memory accesses check target->to_has_(all_)memory, and the
@@ -2357,10 +2363,11 @@ char *
 target_read_stralloc (struct target_ops *ops, enum target_object object,
                      const char *annex)
 {
-  gdb_byte *buffer;
+  char *buffer;
   LONGEST i, transferred;
 
-  transferred = target_read_alloc_1 (ops, object, annex, &buffer, 1);
+  transferred = target_read_alloc_1 (ops, object, annex,
+                                    (gdb_byte **) &buffer, 1);
 
   if (transferred < 0)
     return NULL;
@@ -2380,7 +2387,7 @@ target_read_stralloc (struct target_ops *ops, enum target_object object,
        break;
       }
 
-  return (char *) buffer;
+  return buffer;
 }
 
 /* Memory transfer methods.  */
@@ -2493,7 +2500,7 @@ target_pre_inferior (int from_tty)
   /* In some OSs, the shared library list is the same/global/shared
      across inferiors.  If code is shared between processes, so are
      memory regions and features.  */
-  if (!gdbarch_has_global_solist (target_gdbarch))
+  if (!gdbarch_has_global_solist (target_gdbarch ()))
     {
       no_shared_libraries (NULL, from_tty);
 
@@ -2562,7 +2569,7 @@ target_detach (char *args, int from_tty)
 {
   struct target_ops* t;
   
-  if (gdbarch_has_global_breakpoints (target_gdbarch))
+  if (gdbarch_has_global_breakpoints (target_gdbarch ()))
     /* Don't remove global breakpoints here.  They're removed on
        disconnection from the target.  */
     ;
@@ -2625,13 +2632,17 @@ target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
          if (targetdebug)
            {
              char *status_string;
+             char *options_string;
 
              status_string = target_waitstatus_to_string (status);
+             options_string = target_options_to_string (options);
              fprintf_unfiltered (gdb_stdlog,
-                                 "target_wait (%d, status) = %d,   %s\n",
-                                 PIDGET (ptid), PIDGET (retval),
-                                 status_string);
+                                 "target_wait (%d, status, options={%s})"
+                                 " = %d,   %s\n",
+                                 PIDGET (ptid), options_string,
+                                 PIDGET (retval), status_string);
              xfree (status_string);
+             xfree (options_string);
            }
 
          return retval;
@@ -2866,8 +2877,9 @@ simple_search_memory (struct target_ops *ops,
   if (target_read (ops, TARGET_OBJECT_MEMORY, NULL,
                   search_buf, start_addr, search_buf_size) != search_buf_size)
     {
-      warning (_("Unable to access target memory at %s, halting search."),
-              hex_string (start_addr));
+      warning (_("Unable to access %s bytes of target "
+                "memory at %s, halting search."),
+              pulongest (search_buf_size), hex_string (start_addr));
       do_cleanups (old_cleanups);
       return -1;
     }
@@ -2920,8 +2932,9 @@ simple_search_memory (struct target_ops *ops,
                           search_buf + keep_len, read_addr,
                           nr_to_read) != nr_to_read)
            {
-             warning (_("Unable to access target "
+             warning (_("Unable to access %s bytes of target "
                         "memory at %s, halting search."),
+                      plongest (nr_to_read),
                       hex_string (read_addr));
              do_cleanups (old_cleanups);
              return -1;
@@ -3134,7 +3147,7 @@ target_supports_non_stop (void)
 
 /* Implement the "info proc" command.  */
 
-void
+int
 target_info_proc (char *args, enum info_proc_what what)
 {
   struct target_ops *t;
@@ -3157,11 +3170,11 @@ target_info_proc (char *args, enum info_proc_what what)
            fprintf_unfiltered (gdb_stdlog,
                                "target_info_proc (\"%s\", %d)\n", args, what);
 
-         return;
+         return 1;
        }
     }
 
-  error (_("Not supported on this target."));
+  return 0;
 }
 
 static int
@@ -3514,10 +3527,11 @@ target_fileio_read_alloc (const char *filename, gdb_byte **buf_p)
 char *
 target_fileio_read_stralloc (const char *filename)
 {
-  gdb_byte *buffer;
+  char *buffer;
   LONGEST i, transferred;
 
-  transferred = target_fileio_read_alloc_1 (filename, &buffer, 1);
+  transferred = target_fileio_read_alloc_1 (filename,
+                                           (gdb_byte **) &buffer, 1);
 
   if (transferred < 0)
     return NULL;
@@ -3537,14 +3551,14 @@ target_fileio_read_stralloc (const char *filename)
        break;
       }
 
-  return (char *) buffer;
+  return buffer;
 }
 
 
 static int
 default_region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
 {
-  return (len <= gdbarch_ptr_bit (target_gdbarch) / TARGET_CHAR_BIT);
+  return (len <= gdbarch_ptr_bit (target_gdbarch ()) / TARGET_CHAR_BIT);
 }
 
 static int
@@ -3558,7 +3572,7 @@ default_watchpoint_addr_within_range (struct target_ops *target,
 static struct gdbarch *
 default_thread_architecture (struct target_ops *ops, ptid_t ptid)
 {
-  return target_gdbarch;
+  return target_gdbarch ();
 }
 
 static int
@@ -3864,6 +3878,8 @@ target_waitstatus_to_string (const struct target_waitstatus *ws)
       return xstrprintf ("%svforked", kind_str);
     case TARGET_WAITKIND_EXECD:
       return xstrprintf ("%sexecd", kind_str);
+    case TARGET_WAITKIND_VFORK_DONE:
+      return xstrprintf ("%svfork-done", kind_str);
     case TARGET_WAITKIND_SYSCALL_ENTRY:
       return xstrprintf ("%sentered syscall", kind_str);
     case TARGET_WAITKIND_SYSCALL_RETURN:
@@ -3881,6 +3897,54 @@ target_waitstatus_to_string (const struct target_waitstatus *ws)
     }
 }
 
+/* Concatenate ELEM to LIST, a comma separate list, and return the
+   result.  The LIST incoming argument is released.  */
+
+static char *
+str_comma_list_concat_elem (char *list, const char *elem)
+{
+  if (list == NULL)
+    return xstrdup (elem);
+  else
+    return reconcat (list, list, ", ", elem, (char *) NULL);
+}
+
+/* Helper for target_options_to_string.  If OPT is present in
+   TARGET_OPTIONS, append the OPT_STR (string version of OPT) in RET.
+   Returns the new resulting string.  OPT is removed from
+   TARGET_OPTIONS.  */
+
+static char *
+do_option (int *target_options, char *ret,
+          int opt, char *opt_str)
+{
+  if ((*target_options & opt) != 0)
+    {
+      ret = str_comma_list_concat_elem (ret, opt_str);
+      *target_options &= ~opt;
+    }
+
+  return ret;
+}
+
+char *
+target_options_to_string (int target_options)
+{
+  char *ret = NULL;
+
+#define DO_TARG_OPTION(OPT) \
+  ret = do_option (&target_options, ret, OPT, #OPT)
+
+  DO_TARG_OPTION (TARGET_WNOHANG);
+
+  if (target_options != 0)
+    ret = str_comma_list_concat_elem (ret, "unknown???");
+
+  if (ret == NULL)
+    ret = xstrdup ("");
+  return ret;
+}
+
 static void
 debug_print_register (const char * func,
                      struct regcache *regcache, int regno)
@@ -3899,7 +3963,7 @@ debug_print_register (const char * func,
     {
       enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
       int i, size = register_size (gdbarch, regno);
-      unsigned char buf[MAX_REGISTER_SIZE];
+      gdb_byte buf[MAX_REGISTER_SIZE];
 
       regcache_raw_collect (regcache, regno, buf);
       fprintf_unfiltered (gdb_stdlog, " = ");
@@ -3995,7 +4059,7 @@ target_verify_memory (const gdb_byte *data, CORE_ADDR memaddr, ULONGEST size)
          if (targetdebug)
            fprintf_unfiltered (gdb_stdlog,
                                "target_verify_memory (%s, %s) = %d\n",
-                               paddress (target_gdbarch, memaddr),
+                               paddress (target_gdbarch (), memaddr),
                                pulongest (size),
                                retval);
          return retval;
@@ -4089,6 +4153,79 @@ target_ranged_break_num_registers (void)
   return -1;
 }
 
+/* See target.h.  */
+
+int
+target_supports_btrace (void)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_supports_btrace != NULL)
+      return t->to_supports_btrace ();
+
+  return 0;
+}
+
+/* See target.h.  */
+
+struct btrace_target_info *
+target_enable_btrace (ptid_t ptid)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_enable_btrace != NULL)
+      return t->to_enable_btrace (ptid);
+
+  tcomplain ();
+  return NULL;
+}
+
+/* See target.h.  */
+
+void
+target_disable_btrace (struct btrace_target_info *btinfo)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_disable_btrace != NULL)
+      return t->to_disable_btrace (btinfo);
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+void
+target_teardown_btrace (struct btrace_target_info *btinfo)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_teardown_btrace != NULL)
+      return t->to_teardown_btrace (btinfo);
+
+  tcomplain ();
+}
+
+/* See target.h.  */
+
+VEC (btrace_block_s) *
+target_read_btrace (struct btrace_target_info *btinfo,
+                   enum btrace_read_type type)
+{
+  struct target_ops *t;
+
+  for (t = current_target.beneath; t != NULL; t = t->beneath)
+    if (t->to_read_btrace != NULL)
+      return t->to_read_btrace (btinfo, type);
+
+  tcomplain ();
+  return NULL;
+}
+
 static void
 debug_to_prepare_to_store (struct regcache *regcache)
 {
@@ -4109,7 +4246,7 @@ deprecated_debug_xfer_memory (CORE_ADDR memaddr, bfd_byte *myaddr, int len,
 
   fprintf_unfiltered (gdb_stdlog,
                      "target_xfer_memory (%s, xxx, %d, %s, xxx) = %d",
-                     paddress (target_gdbarch, memaddr), len,
+                     paddress (target_gdbarch (), memaddr), len,
                      write ? "write" : "read", retval);
 
   if (retval > 0)
@@ -4718,15 +4855,15 @@ initialize_targets (void)
   add_info ("target", target_info, targ_desc);
   add_info ("files", target_info, targ_desc);
 
-  add_setshow_zinteger_cmd ("target", class_maintenance, &targetdebug, _("\
+  add_setshow_zuinteger_cmd ("target", class_maintenance, &targetdebug, _("\
 Set target debugging."), _("\
 Show target debugging."), _("\
 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."),
-                           NULL,
-                           show_targetdebug,
-                           &setdebuglist, &showdebuglist);
+                            NULL,
+                            show_targetdebug,
+                            &setdebuglist, &showdebuglist);
 
   add_setshow_boolean_cmd ("trust-readonly-sections", class_support,
                           &trust_readonly, _("\
This page took 0.03067 seconds and 4 git commands to generate.