X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gdb%2Fcorefile.c;h=8a96d75db23e4b8a5989ae6fa1c8494194f7ac5d;hb=40c1a0073715c1e3f93afc83edac8396eb362a98;hp=c07447b20913a4b61f2b5e2f0b38e44b368b467a;hpb=0b30217134add051e159a192066a1e568ebd837f;p=deliverable%2Fbinutils-gdb.git
diff --git a/gdb/corefile.c b/gdb/corefile.c
index c07447b209..8a96d75db2 100644
--- a/gdb/corefile.c
+++ b/gdb/corefile.c
@@ -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,7 +18,7 @@
along with this program. If not, see . */
#include "defs.h"
-#include "gdb_string.h"
+#include
#include
#include
#include
@@ -31,9 +30,11 @@
#include "target.h"
#include "gdbcore.h"
#include "dis-asm.h"
-#include "gdb_stat.h"
+#include
#include "completer.h"
#include "exceptions.h"
+#include "observer.h"
+#include "cli/cli-utils.h"
/* Local function declarations. */
@@ -60,7 +61,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;
@@ -72,8 +73,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);
@@ -132,26 +132,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 +158,6 @@ reopen_exec_file (void)
bfd_cache_close_all ();
do_cleanups (cleanups);
-#endif
}
/* If we have both a core file and an exec file,
@@ -200,8 +182,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 +193,102 @@ Use the \"file\" or \"exec-file\" command."));
}
-/* 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 +371,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 +409,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 +431,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 +440,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 +498,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 +555,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"));