diff options
Diffstat (limited to 'gnu/usr.bin/gdb/kgdb/trgt.c')
-rw-r--r-- | gnu/usr.bin/gdb/kgdb/trgt.c | 161 |
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(); } |