Fix xmethod Python so that it works with Python3.
[deliverable/binutils-gdb.git] / gdb / corefile.c
index c07447b20913a4b61f2b5e2f0b38e44b368b467a..1617392372d80cc752f590fcc6c978720a7917f2 100644 (file)
@@ -1,7 +1,6 @@
 /* Core dump and executable file functions above target vector, for GDB.
 
-   Copyright (C) 1986-1987, 1989, 1991-1994, 1996-2001, 2003, 2006-2012
-   Free Software Foundation, Inc.
+   Copyright (C) 1986-2014 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -19,8 +18,6 @@
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
-#include "gdb_string.h"
-#include <errno.h>
 #include <signal.h>
 #include <fcntl.h>
 #include "inferior.h"
 #include "target.h"
 #include "gdbcore.h"
 #include "dis-asm.h"
-#include "gdb_stat.h"
+#include <sys/stat.h>
 #include "completer.h"
 #include "exceptions.h"
+#include "observer.h"
+#include "cli/cli-utils.h"
 
 /* Local function declarations.  */
 
 extern void _initialize_core (void);
-static void call_extra_exec_file_hooks (char *filename);
 
 /* You can have any number of hooks for `exec_file_command' command to
    call.  If there's only one hook, it is set in exec_file_display
@@ -49,7 +47,7 @@ static void call_extra_exec_file_hooks (char *filename);
    only one hook could be set, and which called
    deprecated_exec_file_display_hook directly.  */
 
-typedef void (*hook_type) (char *);
+typedef void (*hook_type) (const char *);
 
 hook_type deprecated_exec_file_display_hook;   /* The original hook.  */
 static hook_type *exec_file_extra_hooks;       /* Array of additional
@@ -60,7 +58,7 @@ static int exec_file_hook_count = 0;          /* Size of array.  */
 
 bfd *core_bfd = NULL;
 
-/* corelow.c target (if included for this gdb target).  */
+/* corelow.c target.  It is never NULL after GDB initialization.  */
 
 struct target_ops *core_target;
 \f
@@ -72,8 +70,7 @@ core_file_command (char *filename, int from_tty)
 {
   dont_repeat ();              /* Either way, seems bogus.  */
 
-  if (core_target == NULL)
-    error (_("GDB can't read core files on this machine."));
+  gdb_assert (core_target != NULL);
 
   if (!filename)
     (core_target->to_detach) (core_target, filename, from_tty);
@@ -87,7 +84,7 @@ core_file_command (char *filename, int from_tty)
    functions.  */
 
 static void
-call_extra_exec_file_hooks (char *filename)
+call_extra_exec_file_hooks (const char *filename)
 {
   int i;
 
@@ -99,7 +96,7 @@ call_extra_exec_file_hooks (char *filename)
    This is called from the x-window display code.  */
 
 void
-specify_exec_file_hook (void (*hook) (char *))
+specify_exec_file_hook (void (*hook) (const char *))
 {
   hook_type *new_array;
 
@@ -132,26 +129,9 @@ specify_exec_file_hook (void (*hook) (char *))
     deprecated_exec_file_display_hook = hook;
 }
 
-/* The exec file must be closed before running an inferior.
-   If it is needed again after the inferior dies, it must
-   be reopened.  */
-
-void
-close_exec_file (void)
-{
-#if 0                          /* FIXME */
-  if (exec_bfd)
-    bfd_tempclose (exec_bfd);
-#endif
-}
-
 void
 reopen_exec_file (void)
 {
-#if 0                          /* FIXME */
-  if (exec_bfd)
-    bfd_reopen (exec_bfd);
-#else
   char *filename;
   int res;
   struct stat st;
@@ -175,7 +155,6 @@ reopen_exec_file (void)
     bfd_cache_close_all ();
 
   do_cleanups (cleanups);
-#endif
 }
 \f
 /* If we have both a core file and an exec file,
@@ -200,8 +179,8 @@ validate_files (void)
 char *
 get_exec_file (int err)
 {
-  if (exec_bfd)
-    return bfd_get_filename (exec_bfd);
+  if (exec_filename)
+    return exec_filename;
   if (!err)
     return NULL;
 
@@ -211,44 +190,102 @@ Use the \"file\" or \"exec-file\" command."));
 }
 \f
 
-/* Report a memory error by throwing a MEMORY_ERROR error.  */
+char *
+memory_error_message (enum target_xfer_status err,
+                     struct gdbarch *gdbarch, CORE_ADDR memaddr)
+{
+  switch (err)
+    {
+    case TARGET_XFER_E_IO:
+      /* Actually, address between memaddr and memaddr + len was out of
+        bounds.  */
+      return xstrprintf (_("Cannot access memory at address %s"),
+                        paddress (gdbarch, memaddr));
+    case TARGET_XFER_UNAVAILABLE:
+      return xstrprintf (_("Memory at address %s unavailable."),
+                        paddress (gdbarch, memaddr));
+    default:
+      internal_error (__FILE__, __LINE__,
+                     "unhandled target_xfer_status: %s (%s)",
+                     target_xfer_status_to_string (err),
+                     plongest (err));
+    }
+}
+
+/* Report a memory error by throwing a suitable exception.  */
 
 void
-memory_error (int status, CORE_ADDR memaddr)
+memory_error (enum target_xfer_status err, CORE_ADDR memaddr)
 {
-  if (status == EIO)
-    /* Actually, address between memaddr and memaddr + len was out of
-       bounds.  */
-    throw_error (MEMORY_ERROR,
-                _("Cannot access memory at address %s"),
-                paddress (target_gdbarch, memaddr));
-  else
-    throw_error (MEMORY_ERROR,
-                _("Error accessing memory address %s: %s."),
-                paddress (target_gdbarch, memaddr),
-                safe_strerror (status));
+  char *str;
+  enum errors exception = GDB_NO_ERROR;
+
+  /* Build error string.  */
+  str = memory_error_message (err, target_gdbarch (), memaddr);
+  make_cleanup (xfree, str);
+
+  /* Choose the right error to throw.  */
+  switch (err)
+    {
+    case TARGET_XFER_E_IO:
+      exception = MEMORY_ERROR;
+      break;
+    case TARGET_XFER_UNAVAILABLE:
+      exception = NOT_AVAILABLE_ERROR;
+      break;
+    }
+
+  /* Throw it.  */
+  throw_error (exception, ("%s"), str);
 }
 
 /* Same as target_read_memory, but report an error if can't read.  */
 
 void
-read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+read_memory (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
+{
+  ULONGEST xfered = 0;
+
+  while (xfered < len)
+    {
+      enum target_xfer_status status;
+      ULONGEST xfered_len;
+
+      status = target_xfer_partial (current_target.beneath,
+                                   TARGET_OBJECT_MEMORY, NULL,
+                                   myaddr + xfered, NULL,
+                                   memaddr + xfered, len - xfered,
+                                   &xfered_len);
+
+      if (status != TARGET_XFER_OK)
+       memory_error (status == TARGET_XFER_EOF ? TARGET_XFER_E_IO : status,
+                     memaddr + xfered);
+
+      xfered += xfered_len;
+      QUIT;
+    }
+}
+
+/* Same as target_read_stack, but report an error if can't read.  */
+
+void
+read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
   int status;
 
-  status = target_read_memory (memaddr, myaddr, len);
+  status = target_read_stack (memaddr, myaddr, len);
   if (status != 0)
     memory_error (status, memaddr);
 }
 
-/* Same as target_read_stack, but report an error if can't read.  */
+/* Same as target_read_code, but report an error if can't read.  */
 
 void
-read_stack (CORE_ADDR memaddr, gdb_byte *myaddr, int len)
+read_code (CORE_ADDR memaddr, gdb_byte *myaddr, ssize_t len)
 {
   int status;
 
-  status = target_read_stack (memaddr, myaddr, len);
+  status = target_read_code (memaddr, myaddr, len);
   if (status != 0)
     memory_error (status, memaddr);
 }
@@ -331,6 +368,26 @@ read_memory_unsigned_integer (CORE_ADDR memaddr, int len,
   return extract_unsigned_integer (buf, len, byte_order);
 }
 
+LONGEST
+read_code_integer (CORE_ADDR memaddr, int len,
+                  enum bfd_endian byte_order)
+{
+  gdb_byte buf[sizeof (LONGEST)];
+
+  read_code (memaddr, buf, len);
+  return extract_signed_integer (buf, len, byte_order);
+}
+
+ULONGEST
+read_code_unsigned_integer (CORE_ADDR memaddr, int len,
+                           enum bfd_endian byte_order)
+{
+  gdb_byte buf[sizeof (ULONGEST)];
+
+  read_code (memaddr, buf, len);
+  return extract_unsigned_integer (buf, len, byte_order);
+}
+
 void
 read_memory_string (CORE_ADDR memaddr, char *buffer, int max_len)
 {
@@ -349,7 +406,7 @@ read_memory_string (CORE_ADDR memaddr, char *buffer, int max_len)
       cnt = max_len - (cp - buffer);
       if (cnt > 8)
        cnt = 8;
-      read_memory (memaddr + (int) (cp - buffer), cp, cnt);
+      read_memory (memaddr + (int) (cp - buffer), (gdb_byte *) cp, cnt);
       for (i = 0; i < cnt && *cp; i++, cp++)
        ;                       /* null body */
 
@@ -371,7 +428,7 @@ read_memory_typed_address (CORE_ADDR addr, struct type *type)
    write.  */
 void
 write_memory (CORE_ADDR memaddr, 
-             const bfd_byte *myaddr, int len)
+             const bfd_byte *myaddr, ssize_t len)
 {
   int status;
 
@@ -380,6 +437,16 @@ write_memory (CORE_ADDR memaddr,
     memory_error (status, memaddr);
 }
 
+/* Same as write_memory, but notify 'memory_changed' observers.  */
+
+void
+write_memory_with_notification (CORE_ADDR memaddr, const bfd_byte *myaddr,
+                               ssize_t len)
+{
+  write_memory (memaddr, myaddr, len);
+  observer_notify_memory_changed (current_inferior (), memaddr, len, myaddr);
+}
+
 /* Store VALUE at ADDR in the inferior as a LEN-byte unsigned
    integer.  */
 void
@@ -428,12 +495,41 @@ static void
 set_gnutarget_command (char *ignore, int from_tty,
                       struct cmd_list_element *c)
 {
+  char *gend = gnutarget_string + strlen (gnutarget_string);
+
+  gend = remove_trailing_whitespace (gnutarget_string, gend);
+  *gend = '\0';
+
   if (strcmp (gnutarget_string, "auto") == 0)
     gnutarget = NULL;
   else
     gnutarget = gnutarget_string;
 }
 
+/* A completion function for "set gnutarget".  */
+
+static VEC (char_ptr) *
+complete_set_gnutarget (struct cmd_list_element *cmd,
+                       const char *text, const char *word)
+{
+  static const char **bfd_targets;
+
+  if (bfd_targets == NULL)
+    {
+      int last;
+
+      bfd_targets = bfd_target_list ();
+      for (last = 0; bfd_targets[last] != NULL; ++last)
+       ;
+
+      bfd_targets = xrealloc (bfd_targets, (last + 2) * sizeof (const char **));
+      bfd_targets[last] = "auto";
+      bfd_targets[last + 1] = NULL;
+    }
+
+  return complete_on_enum (bfd_targets, text, word);
+}
+
 /* Set the gnutarget.  */
 void
 set_gnutarget (char *newtarget)
@@ -456,14 +552,17 @@ No arg means have no core file.  This command has been superseded by the\n\
   set_cmd_completer (c, filename_completer);
 
   
-  add_setshow_string_noescape_cmd ("gnutarget", class_files,
-                                  &gnutarget_string, _("\
+  c = add_setshow_string_noescape_cmd ("gnutarget", class_files,
+                                      &gnutarget_string, _("\
 Set the current BFD target."), _("\
 Show the current BFD target."), _("\
 Use `set gnutarget auto' to specify automatic detection."),
-                                  set_gnutarget_command,
-                                  show_gnutarget_string,
-                                  &setlist, &showlist);
+                                      set_gnutarget_command,
+                                      show_gnutarget_string,
+                                      &setlist, &showlist);
+  set_cmd_completer (c, complete_set_gnutarget);
+
+  add_alias_cmd ("g", "gnutarget", class_files, 1, &setlist);
 
   if (getenv ("GNUTARGET"))
     set_gnutarget (getenv ("GNUTARGET"));
This page took 0.041719 seconds and 4 git commands to generate.