summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin/gdb/kgdb/trgt.c
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin/gdb/kgdb/trgt.c')
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt.c161
1 files changed, 139 insertions, 22 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/trgt.c b/gnu/usr.bin/gdb/kgdb/trgt.c
index a312767..9898f6b 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt.c
@@ -32,22 +32,32 @@ __FBSDID("$FreeBSD$");
#include <sys/sysctl.h>
#include <sys/user.h>
#include <err.h>
+#include <fcntl.h>
#include <kvm.h>
#include <defs.h>
+#include <readline/readline.h>
+#include <readline/tilde.h>
#include <command.h>
#include <exec.h>
#include <frame-unwind.h>
+#include <gdbcore.h>
#include <gdbthread.h>
#include <inferior.h>
+#include <language.h>
#include <regcache.h>
+#include <solib.h>
#include <target.h>
#include "kgdb.h"
+static void kgdb_core_cleanup(void *);
+
+static char *vmcore;
static struct target_ops kgdb_trgt_ops;
-bfd *kern_bfd;
+kvm_t *kvm;
+static char kvm_err[_POSIX2_LINE_MAX];
#define KERNOFF (kgdb_kernbase ())
#define INKERNEL(x) ((x) >= KERNOFF)
@@ -69,6 +79,111 @@ kgdb_kernbase (void)
return kernbase;
}
+static void
+kgdb_trgt_open(char *filename, int from_tty)
+{
+ struct cleanup *old_chain;
+ struct thread_info *ti;
+ struct kthr *kt;
+ kvm_t *nkvm;
+ char *temp;
+ int ontop;
+
+ target_preopen (from_tty);
+ if (!filename)
+ error ("No vmcore file specified.");
+ if (!exec_bfd)
+ error ("Can't open a vmcore without a kernel");
+
+ filename = tilde_expand (filename);
+ if (filename[0] != '/') {
+ temp = concat (current_directory, "/", filename, NULL);
+ xfree(filename);
+ filename = temp;
+ }
+
+ old_chain = make_cleanup (xfree, filename);
+
+ nkvm = kvm_openfiles(bfd_get_filename(exec_bfd), filename, NULL,
+ write_files ? O_RDWR : O_RDONLY, kvm_err);
+ if (nkvm == NULL)
+ error ("Failed to open vmcore: %s", kvm_err);
+
+ /* Don't free the filename now and close any previous vmcore. */
+ discard_cleanups(old_chain);
+ unpush_target(&kgdb_trgt_ops);
+
+ kvm = nkvm;
+ vmcore = filename;
+ old_chain = make_cleanup(kgdb_core_cleanup, NULL);
+
+ ontop = !push_target (&kgdb_trgt_ops);
+ discard_cleanups (old_chain);
+
+ kgdb_dmesg();
+
+ init_thread_list();
+ kt = kgdb_thr_init();
+ while (kt != NULL) {
+ ti = add_thread(ptid_build(kt->pid, 0, kt->tid));
+ kt = kgdb_thr_next(kt);
+ }
+ if (curkthr != 0)
+ inferior_ptid = ptid_build(curkthr->pid, 0, curkthr->tid);
+
+ if (ontop) {
+ /* XXX: fetch registers? */
+ kld_init();
+ flush_cached_frames();
+ select_frame (get_current_frame());
+ print_stack_frame(get_selected_frame(),
+ frame_relative_level(get_selected_frame()), 1);
+ } else
+ warning(
+ "you won't be able to access this vmcore until you terminate\n\
+your %s; do ``info files''", target_longname);
+}
+
+static void
+kgdb_trgt_close(int quitting)
+{
+
+ if (kvm != NULL) {
+ inferior_ptid = null_ptid;
+ CLEAR_SOLIB();
+ if (kvm_close(kvm) != 0)
+ warning("cannot close \"%s\": %s", vmcore,
+ kvm_geterr(kvm));
+ kvm = NULL;
+ xfree(vmcore);
+ vmcore = NULL;
+ if (kgdb_trgt_ops.to_sections) {
+ xfree(kgdb_trgt_ops.to_sections);
+ kgdb_trgt_ops.to_sections = NULL;
+ kgdb_trgt_ops.to_sections_end = NULL;
+ }
+ }
+}
+
+static void
+kgdb_core_cleanup(void *arg)
+{
+
+ kgdb_trgt_close(0);
+}
+
+static void
+kgdb_trgt_detach(char *args, int from_tty)
+{
+
+ if (args)
+ error ("Too many arguments");
+ unpush_target(&kgdb_trgt_ops);
+ reinit_frame_cache();
+ if (from_tty)
+ printf_filtered("No vmcore file now.\n");
+}
+
static char *
kgdb_trgt_extra_thread_info(struct thread_info *ti)
{
@@ -86,7 +201,9 @@ static void
kgdb_trgt_files_info(struct target_ops *target)
{
- print_section_info(target, kern_bfd);
+ printf_filtered ("\t`%s', ", vmcore);
+ wrap_here (" ");
+ printf_filtered ("file type %s.\n", "FreeBSD kernel vmcore");
}
static void
@@ -135,6 +252,13 @@ kgdb_trgt_xfer_memory(CORE_ADDR memaddr, char *myaddr, int len, int write,
return (tb->to_xfer_memory(memaddr, myaddr, len, write, attrib, tb));
}
+static int
+kgdb_trgt_ignore_breakpoints(CORE_ADDR addr, char *contents)
+{
+
+ return 0;
+}
+
static void
kgdb_switch_to_thread(struct kthr *thr)
{
@@ -200,21 +324,26 @@ kgdb_set_tid_cmd (char *arg, int from_tty)
kgdb_switch_to_thread(thr);
}
+int fbsdcoreops_suppress_target = 1;
+
void
-kgdb_target(void)
+initialize_kgdb_target(void)
{
- struct kthr *kt;
- struct thread_info *ti;
kgdb_trgt_ops.to_magic = OPS_MAGIC;
kgdb_trgt_ops.to_shortname = "kernel";
- kgdb_trgt_ops.to_longname = "kernel core files";
- kgdb_trgt_ops.to_doc = "Kernel core files.";
- kgdb_trgt_ops.to_stratum = thread_stratum;
+ kgdb_trgt_ops.to_longname = "kernel core dump file";
+ kgdb_trgt_ops.to_doc =
+ "Use a vmcore file as a target. Specify the filename of the vmcore file.";
+ kgdb_trgt_ops.to_stratum = core_stratum;
kgdb_trgt_ops.to_has_memory = 1;
kgdb_trgt_ops.to_has_registers = 1;
kgdb_trgt_ops.to_has_stack = 1;
+ kgdb_trgt_ops.to_open = kgdb_trgt_open;
+ kgdb_trgt_ops.to_close = kgdb_trgt_close;
+ kgdb_trgt_ops.to_attach = find_default_attach;
+ kgdb_trgt_ops.to_detach = kgdb_trgt_detach;
kgdb_trgt_ops.to_extra_thread_info = kgdb_trgt_extra_thread_info;
kgdb_trgt_ops.to_fetch_registers = kgdb_trgt_fetch_registers;
kgdb_trgt_ops.to_files_info = kgdb_trgt_files_info;
@@ -223,25 +352,13 @@ kgdb_target(void)
kgdb_trgt_ops.to_store_registers = kgdb_trgt_store_registers;
kgdb_trgt_ops.to_thread_alive = kgdb_trgt_thread_alive;
kgdb_trgt_ops.to_xfer_memory = kgdb_trgt_xfer_memory;
-
- if (build_section_table(kern_bfd, &kgdb_trgt_ops.to_sections,
- &kgdb_trgt_ops.to_sections_end) != 0)
- errx(1, "\"%s\": can't find the file sections: %s",
- kernel, bfd_errmsg(bfd_get_error()));
+ kgdb_trgt_ops.to_insert_breakpoint = kgdb_trgt_ignore_breakpoints;
+ kgdb_trgt_ops.to_remove_breakpoint = kgdb_trgt_ignore_breakpoints;
add_target(&kgdb_trgt_ops);
- push_target(&kgdb_trgt_ops);
- kt = kgdb_thr_first();
- while (kt != NULL) {
- ti = add_thread(ptid_build(kt->pid, 0, kt->tid));
- kt = kgdb_thr_next(kt);
- }
- if (curkthr != 0)
- inferior_ptid = ptid_build(curkthr->pid, 0, curkthr->tid);
add_com ("proc", class_obscure, kgdb_set_proc_cmd,
"Set current process context");
add_com ("tid", class_obscure, kgdb_set_tid_cmd,
"Set current thread context");
- kgdb_kld_init();
}
OpenPOWER on IntegriCloud