Update comment of linespec_lexer_lex_keyword.
[deliverable/binutils-gdb.git] / gdb / target.c
index 16151c498266642036fd10b07a75d1d263928a71..af94f48279abaa5291435537a918fd5fd7f4b035 100644 (file)
@@ -1,6 +1,6 @@
 /* Select target systems and architectures at runtime for GDB.
 
-   Copyright (C) 1990-2014 Free Software Foundation, Inc.
+   Copyright (C) 1990-2015 Free Software Foundation, Inc.
 
    Contributed by Cygnus Support.
 
@@ -20,8 +20,6 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include <errno.h>
-#include <string.h>
 #include "target.h"
 #include "target-dcache.h"
 #include "gdbcmd.h"
@@ -35,7 +33,6 @@
 #include <signal.h>
 #include "regcache.h"
 #include "gdbcore.h"
-#include "exceptions.h"
 #include "target-descriptions.h"
 #include "gdbthread.h"
 #include "solib.h"
@@ -108,9 +105,6 @@ static char *default_pid_to_str (struct target_ops *ops, ptid_t ptid);
 static enum exec_direction_kind default_execution_direction
     (struct target_ops *self);
 
-static CORE_ADDR default_target_decr_pc_after_break (struct target_ops *ops,
-                                                    struct gdbarch *gdbarch);
-
 static struct target_ops debug_target;
 
 #include "target-delegates.c"
@@ -119,13 +113,10 @@ static void init_dummy_target (void);
 
 static void update_current_target (void);
 
-/* Pointer to array of target architecture structures; the size of the
-   array; the current index into the array; the allocated size of the
-   array.  */
-struct target_ops **target_structs;
-unsigned target_struct_size;
-unsigned target_struct_allocsize;
-#define        DEFAULT_ALLOCSIZE       10
+/* Vector of existing target structures. */
+typedef struct target_ops *target_ops_p;
+DEF_VEC_P (target_ops_p);
+static VEC (target_ops_p) *target_structs;
 
 /* The initial current target, so that there is always a semi-valid
    current target.  */
@@ -381,20 +372,7 @@ add_target_with_completer (struct target_ops *t,
 
   complete_target_initialization (t);
 
-  if (!target_structs)
-    {
-      target_struct_allocsize = DEFAULT_ALLOCSIZE;
-      target_structs = (struct target_ops **) xmalloc
-       (target_struct_allocsize * sizeof (*target_structs));
-    }
-  if (target_struct_size >= target_struct_allocsize)
-    {
-      target_struct_allocsize *= 2;
-      target_structs = (struct target_ops **)
-       xrealloc ((char *) target_structs,
-                 target_struct_allocsize * sizeof (*target_structs));
-    }
-  target_structs[target_struct_size++] = t;
+  VEC_safe_push (target_ops_p, target_structs, t);
 
   if (targetlist == NULL)
     add_prefix_cmd ("target", class_run, target_command, _("\
@@ -451,6 +429,43 @@ target_load (const char *arg, int from_tty)
   (*current_target.to_load) (&current_target, arg, from_tty);
 }
 
+/* Possible terminal states.  */
+
+enum terminal_state
+  {
+    /* The inferior's terminal settings are in effect.  */
+    terminal_is_inferior = 0,
+
+    /* Some of our terminal settings are in effect, enough to get
+       proper output.  */
+    terminal_is_ours_for_output = 1,
+
+    /* Our terminal settings are in effect, for output and input.  */
+    terminal_is_ours = 2
+  };
+
+static enum terminal_state terminal_state;
+
+/* See target.h.  */
+
+void
+target_terminal_init (void)
+{
+  (*current_target.to_terminal_init) (&current_target);
+
+  terminal_state = terminal_is_ours;
+}
+
+/* See target.h.  */
+
+int
+target_terminal_is_inferior (void)
+{
+  return (terminal_state == terminal_is_inferior);
+}
+
+/* See target.h.  */
+
 void
 target_terminal_inferior (void)
 {
@@ -461,9 +476,36 @@ target_terminal_inferior (void)
   if (target_can_async_p () && !sync_execution)
     return;
 
+  if (terminal_state == terminal_is_inferior)
+    return;
+
   /* If GDB is resuming the inferior in the foreground, install
      inferior's terminal modes.  */
   (*current_target.to_terminal_inferior) (&current_target);
+  terminal_state = terminal_is_inferior;
+}
+
+/* See target.h.  */
+
+void
+target_terminal_ours (void)
+{
+  if (terminal_state == terminal_is_ours)
+    return;
+
+  (*current_target.to_terminal_ours) (&current_target);
+  terminal_state = terminal_is_ours;
+}
+
+/* See target.h.  */
+
+void
+target_terminal_ours_for_output (void)
+{
+  if (terminal_state != terminal_is_inferior)
+    return;
+  (*current_target.to_terminal_ours_for_output) (&current_target);
+  terminal_state = terminal_is_ours_for_output;
 }
 
 /* See target.h.  */
@@ -483,6 +525,40 @@ target_supports_terminal_ours (void)
   return 0;
 }
 
+/* Restore the terminal to its previous state (helper for
+   make_cleanup_restore_target_terminal). */
+
+static void
+cleanup_restore_target_terminal (void *arg)
+{
+  enum terminal_state *previous_state = arg;
+
+  switch (*previous_state)
+    {
+    case terminal_is_ours:
+      target_terminal_ours ();
+      break;
+    case terminal_is_ours_for_output:
+      target_terminal_ours_for_output ();
+      break;
+    case terminal_is_inferior:
+      target_terminal_inferior ();
+      break;
+    }
+}
+
+/* See target.h. */
+
+struct cleanup *
+make_cleanup_restore_target_terminal (void)
+{
+  enum terminal_state *ts = xmalloc (sizeof (*ts));
+
+  *ts = terminal_state;
+
+  return make_cleanup_dtor (cleanup_restore_target_terminal, ts, xfree);
+}
+
 static void
 tcomplain (void)
 {
@@ -738,9 +814,8 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
   if (gdbarch_fetch_tls_load_module_address_p (target_gdbarch ()))
     {
       ptid_t ptid = inferior_ptid;
-      volatile struct gdb_exception ex;
 
-      TRY_CATCH (ex, RETURN_MASK_ALL)
+      TRY
        {
          CORE_ADDR lm_addr;
          
@@ -753,7 +828,7 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
        }
       /* If an error occurred, print TLS related messages here.  Otherwise,
          throw the error to some higher catcher.  */
-      if (ex.reason < 0)
+      CATCH (ex, RETURN_MASK_ALL)
        {
          int objfile_is_library = (objfile->flags & OBJF_SHARED);
 
@@ -802,6 +877,7 @@ target_translate_tls_address (struct objfile *objfile, CORE_ADDR offset)
              break;
            }
        }
+      END_CATCH
     }
   /* It wouldn't be wrong here to try a gdbarch method, too; finding
      TLS is an ABI-specific thing.  But we don't do that yet.  */
@@ -927,6 +1003,59 @@ target_section_by_addr (struct target_ops *target, CORE_ADDR addr)
   return NULL;
 }
 
+
+/* Helper for the memory xfer routines.  Checks the attributes of the
+   memory region of MEMADDR against the read or write being attempted.
+   If the access is permitted returns true, otherwise returns false.
+   REGION_P is an optional output parameter.  If not-NULL, it is
+   filled with a pointer to the memory region of MEMADDR.  REG_LEN
+   returns LEN trimmed to the end of the region.  This is how much the
+   caller can continue requesting, if the access is permitted.  A
+   single xfer request must not straddle memory region boundaries.  */
+
+static int
+memory_xfer_check_region (gdb_byte *readbuf, const gdb_byte *writebuf,
+                         ULONGEST memaddr, ULONGEST len, ULONGEST *reg_len,
+                         struct mem_region **region_p)
+{
+  struct mem_region *region;
+
+  region = lookup_mem_region (memaddr);
+
+  if (region_p != NULL)
+    *region_p = region;
+
+  switch (region->attrib.mode)
+    {
+    case MEM_RO:
+      if (writebuf != NULL)
+       return 0;
+      break;
+
+    case MEM_WO:
+      if (readbuf != NULL)
+       return 0;
+      break;
+
+    case MEM_FLASH:
+      /* We only support writing to flash during "load" for now.  */
+      if (writebuf != NULL)
+       error (_("Writing to flash memory forbidden in this context"));
+      break;
+
+    case MEM_NONE:
+      return 0;
+    }
+
+  /* region->hi == 0 means there's no upper bound.  */
+  if (memaddr + len < region->hi || region->hi == 0)
+    *reg_len = len;
+  else
+    *reg_len = region->hi - memaddr;
+
+  return 1;
+}
+
 /* Read memory from more than one valid target.  A core file, for
    instance, could have some of memory but delegate other bits to
    the target below it.  So, we must manually try all targets.  */
@@ -988,7 +1117,7 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
                       ULONGEST len, ULONGEST *xfered_len)
 {
   enum target_xfer_status res;
-  int reg_len;
+  ULONGEST reg_len;
   struct mem_region *region;
   struct inferior *inf;
 
@@ -1035,37 +1164,13 @@ memory_xfer_partial_1 (struct target_ops *ops, enum target_object object,
     }
 
   /* Try GDB's internal data cache.  */
-  region = lookup_mem_region (memaddr);
-  /* region->hi == 0 means there's no upper bound.  */
-  if (memaddr + len < region->hi || region->hi == 0)
-    reg_len = len;
-  else
-    reg_len = region->hi - memaddr;
-
-  switch (region->attrib.mode)
-    {
-    case MEM_RO:
-      if (writebuf != NULL)
-       return TARGET_XFER_E_IO;
-      break;
 
-    case MEM_WO:
-      if (readbuf != NULL)
-       return TARGET_XFER_E_IO;
-      break;
-
-    case MEM_FLASH:
-      /* We only support writing to flash during "load" for now.  */
-      if (writebuf != NULL)
-       error (_("Writing to flash memory forbidden in this context"));
-      break;
-
-    case MEM_NONE:
-      return TARGET_XFER_E_IO;
-    }
+  if (!memory_xfer_check_region (readbuf, writebuf, memaddr, len, &reg_len,
+                                &region))
+    return TARGET_XFER_E_IO;
 
   if (!ptid_equal (inferior_ptid, null_ptid))
-    inf = find_inferior_pid (ptid_get_pid (inferior_ptid));
+    inf = find_inferior_ptid (inferior_ptid);
   else
     inf = NULL;
 
@@ -1202,6 +1307,16 @@ target_xfer_partial (struct target_ops *ops,
                                  writebuf, offset, len, xfered_len);
   else if (object == TARGET_OBJECT_RAW_MEMORY)
     {
+      /* Skip/avoid accessing the target if the memory region
+        attributes block the access.  Check this here instead of in
+        raw_memory_xfer_partial as otherwise we'd end up checking
+        this twice in the case of the memory_xfer_partial path is
+        taken; once before checking the dcache, and another in the
+        tail call to raw_memory_xfer_partial.  */
+      if (!memory_xfer_check_region (readbuf, writebuf, offset, len, &len,
+                                    NULL))
+       return TARGET_XFER_E_IO;
+
       /* Request the normal memory object from other layers.  */
       retval = raw_memory_xfer_partial (ops, readbuf, writebuf, offset, len,
                                        xfered_len);
@@ -1287,6 +1402,22 @@ target_read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
     return TARGET_XFER_E_IO;
 }
 
+/* See target/target.h.  */
+
+int
+target_read_uint32 (CORE_ADDR memaddr, uint32_t *result)
+{
+  gdb_byte buf[4];
+  int r;
+
+  r = target_read_memory (memaddr, buf, sizeof buf);
+  if (r != 0)
+    return r;
+  *result = extract_unsigned_integer (buf, sizeof buf,
+                                     gdbarch_byte_order (target_gdbarch ()));
+  return 0;
+}
+
 /* Like target_read_memory, but specify explicitly that this is a read
    from the target's raw memory.  That is, this read bypasses the
    dcache, breakpoint shadowing, etc.  */
@@ -2365,15 +2496,15 @@ find_default_run_target (char *do_mesg)
 
   if (auto_connect_native_target)
     {
-      struct target_ops **t;
+      struct target_ops *t;
       int count = 0;
+      int i;
 
-      for (t = target_structs; t < target_structs + target_struct_size;
-          ++t)
+      for (i = 0; VEC_iterate (target_ops_p, target_structs, i, t); ++i)
        {
-         if ((*t)->to_can_run != delegate_can_run && target_can_run (*t))
+         if (t->to_can_run != delegate_can_run && target_can_run (t))
            {
-             runable = *t;
+             runable = t;
              ++count;
            }
        }
@@ -2515,7 +2646,7 @@ default_thread_address_space (struct target_ops *self, ptid_t ptid)
   struct inferior *inf;
 
   /* Fall-back to the "main" address space of the inferior.  */
-  inf = find_inferior_pid (ptid_get_pid (ptid));
+  inf = find_inferior_ptid (ptid);
 
   if (inf == NULL || inf->aspace == NULL)
     internal_error (__FILE__, __LINE__,
@@ -3012,9 +3143,9 @@ target_thread_alive (ptid_t ptid)
 }
 
 void
-target_find_new_threads (void)
+target_update_thread_list (void)
 {
-  current_target.to_find_new_threads (&current_target);
+  current_target.to_update_thread_list (&current_target);
 }
 
 void
@@ -3029,6 +3160,31 @@ target_stop (ptid_t ptid)
   (*current_target.to_stop) (&current_target, ptid);
 }
 
+/* See target/target.h.  */
+
+void
+target_stop_and_wait (ptid_t ptid)
+{
+  struct target_waitstatus status;
+  int was_non_stop = non_stop;
+
+  non_stop = 1;
+  target_stop (ptid);
+
+  memset (&status, 0, sizeof (status));
+  target_wait (ptid, &status, 0);
+
+  non_stop = was_non_stop;
+}
+
+/* See target/target.h.  */
+
+void
+target_continue_no_signal (ptid_t ptid)
+{
+  target_resume (ptid, 0, GDB_SIGNAL_0);
+}
+
 /* Concatenate ELEM to LIST, a comma separate list, and return the
    result.  The LIST incoming argument is released.  */
 
@@ -3230,10 +3386,18 @@ target_ranged_break_num_registers (void)
 
 /* See target.h.  */
 
+int
+target_supports_btrace (enum btrace_format format)
+{
+  return current_target.to_supports_btrace (&current_target, format);
+}
+
+/* See target.h.  */
+
 struct btrace_target_info *
-target_enable_btrace (ptid_t ptid)
+target_enable_btrace (ptid_t ptid, const struct btrace_config *conf)
 {
-  return current_target.to_enable_btrace (&current_target, ptid);
+  return current_target.to_enable_btrace (&current_target, ptid, conf);
 }
 
 /* See target.h.  */
@@ -3255,7 +3419,7 @@ target_teardown_btrace (struct btrace_target_info *btinfo)
 /* See target.h.  */
 
 enum btrace_error
-target_read_btrace (VEC (btrace_block_s) **btrace,
+target_read_btrace (struct btrace_data *btrace,
                    struct btrace_target_info *btinfo,
                    enum btrace_read_type type)
 {
@@ -3264,6 +3428,14 @@ target_read_btrace (VEC (btrace_block_s) **btrace,
 
 /* See target.h.  */
 
+const struct btrace_config *
+target_btrace_conf (const struct btrace_target_info *btinfo)
+{
+  return current_target.to_btrace_conf (&current_target, btinfo);
+}
+
+/* See target.h.  */
+
 void
 target_stop_recording (void)
 {
@@ -3397,23 +3569,6 @@ target_get_tailcall_unwinder (void)
   return current_target.to_get_tailcall_unwinder (&current_target);
 }
 
-/* Default implementation of to_decr_pc_after_break.  */
-
-static CORE_ADDR
-default_target_decr_pc_after_break (struct target_ops *ops,
-                                   struct gdbarch *gdbarch)
-{
-  return gdbarch_decr_pc_after_break (gdbarch);
-}
-
-/* See target.h.  */
-
-CORE_ADDR
-target_decr_pc_after_break (struct gdbarch *gdbarch)
-{
-  return current_target.to_decr_pc_after_break (&current_target, gdbarch);
-}
-
 /* See target.h.  */
 
 void
This page took 0.035183 seconds and 4 git commands to generate.