summaryrefslogtreecommitdiffstats
path: root/gnu
diff options
context:
space:
mode:
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/gdb/kgdb/kgdb.h16
-rw-r--r--gnu/usr.bin/gdb/kgdb/kld.c75
-rw-r--r--gnu/usr.bin/gdb/kgdb/kthr.c6
-rw-r--r--gnu/usr.bin/gdb/kgdb/main.c205
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt.c161
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_amd64.c5
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_arm.c5
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_i386.c34
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_ia64.c5
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_powerpc.c5
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_sparc64.c5
11 files changed, 338 insertions, 184 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.h b/gnu/usr.bin/gdb/kgdb/kgdb.h
index 0c324e6..b9a5df6 100644
--- a/gnu/usr.bin/gdb/kgdb/kgdb.h
+++ b/gnu/usr.bin/gdb/kgdb/kgdb.h
@@ -32,8 +32,6 @@
struct thread_info;
extern kvm_t *kvm;
-extern char *kernel;
-extern bfd *kern_bfd;
struct kthr {
struct kthr *next;
@@ -48,11 +46,14 @@ struct kthr {
extern struct kthr *curkthr;
-void kgdb_add_kld_cmd(char *, int);
-void kgdb_kld_init(void);
-void kgdb_target(void);
+void initialize_kld_target(void);
+void initialize_kgdb_target(void);
+void kgdb_dmesg(void);
+void kgdb_trgt_new_objfile(struct objfile *);
void kgdb_trgt_fetch_registers(int);
void kgdb_trgt_store_registers(int);
+void kld_init(void);
+void kld_new_objfile(struct objfile *);
frame_unwind_sniffer_ftype kgdb_trgt_trapframe_sniffer;
@@ -67,6 +68,9 @@ struct kthr *kgdb_thr_select(struct kthr *);
char *kgdb_thr_extra_thread_info(int);
uintptr_t kgdb_lookup(const char *sym);
-CORE_ADDR kgdb_parse(const char *exp);
+CORE_ADDR kgdb_parse_1(const char *, int);
+
+#define kgdb_parse(exp) kgdb_parse_1((exp), 0)
+#define kgdb_parse_quiet(exp) kgdb_parse_1((exp), 1)
#endif /* _KGDB_H_ */
diff --git a/gnu/usr.bin/gdb/kgdb/kld.c b/gnu/usr.bin/gdb/kgdb/kld.c
index 4a57692..76541cd 100644
--- a/gnu/usr.bin/gdb/kgdb/kld.c
+++ b/gnu/usr.bin/gdb/kgdb/kld.c
@@ -55,6 +55,8 @@ static CORE_ADDR off_address, off_filename, off_pathname, off_next;
/* KVA of 'linker_path' which corresponds to the kern.module_path sysctl .*/
static CORE_ADDR module_path_addr;
+static CORE_ADDR linker_files_addr;
+static CORE_ADDR kernel_file_addr;
static struct target_so_ops kld_so_ops;
@@ -70,7 +72,6 @@ kld_ok (char *path)
/*
* Look for a matching file checking for debug suffixes before the raw file:
- * - filename + ".symbols" (e.g. foo.ko.symbols)
* - filename + ".debug" (e.g. foo.ko.debug)
* - filename (e.g. foo.ko)
*/
@@ -112,11 +113,14 @@ find_kld_path (char *filename, char *path, size_t path_size)
char *kernel_dir, *module_dir, *cp;
int error;
- kernel_dir = dirname(kernel);
- if (kernel_dir != NULL) {
- snprintf(path, path_size, "%s/%s", kernel_dir, filename);
- if (check_kld_path(path, path_size))
- return (1);
+ if (exec_bfd) {
+ kernel_dir = dirname(bfd_get_filename(exec_bfd));
+ if (kernel_dir != NULL) {
+ snprintf(path, path_size, "%s/%s", kernel_dir,
+ filename);
+ if (check_kld_path(path, path_size))
+ return (1);
+ }
}
if (module_path_addr != 0) {
target_read_string(module_path_addr, &module_path, PATH_MAX,
@@ -160,11 +164,12 @@ find_kld_address (char *arg, CORE_ADDR *address)
char *filename;
int error;
- if (off_address == 0 || off_filename == 0 || off_next == 0)
+ if (linker_files_addr == 0 || off_address == 0 || off_filename == 0 ||
+ off_next == 0)
return (0);
filename = basename(arg);
- for (kld = kgdb_parse("linker_files.tqh_first"); kld != 0;
+ for (kld = read_pointer(linker_files_addr); kld != 0;
kld = read_pointer(kld + off_next)) {
/* Try to read this linker file's filename. */
target_read_string(read_pointer(kld + off_filename),
@@ -256,12 +261,15 @@ load_kld (char *path, CORE_ADDR base_addr, int from_tty)
do_cleanups(cleanup);
}
-void
+static void
kgdb_add_kld_cmd (char *arg, int from_tty)
{
char path[PATH_MAX];
CORE_ADDR base_addr;
+ if (!exec_bfd)
+ error("No kernel symbol file");
+
/* Try to open the raw path to handle absolute paths first. */
snprintf(path, sizeof(path), "%s", arg);
if (!check_kld_path(path, sizeof(path))) {
@@ -324,6 +332,10 @@ kld_current_sos (void)
char *path;
int error;
+ if (linker_files_addr == 0 || kernel_file_addr == 0 ||
+ off_address == 0 || off_filename == 0 || off_next == 0)
+ return (NULL);
+
head = NULL;
prev = &head;
@@ -331,8 +343,8 @@ kld_current_sos (void)
* Walk the list of linker files creating so_list entries for
* each non-kernel file.
*/
- kernel = kgdb_parse("linker_kernel_file");
- for (kld = kgdb_parse("linker_files.tqh_first"); kld != 0;
+ kernel = read_pointer(kernel_file_addr);
+ for (kld = read_pointer(linker_files_addr); kld != 0;
kld = read_pointer(kld + off_next)) {
/* Skip the main kernel file. */
if (kld == kernel)
@@ -429,6 +441,28 @@ kld_find_and_open_solib (char *solib, unsigned o_flags, char **temp_pathname)
return (fd);
}
+void
+kld_new_objfile (struct objfile *objfile)
+{
+
+ if (!have_partial_symbols())
+ return;
+
+ /*
+ * Compute offsets of relevant members in struct linker_file
+ * and the addresses of global variables. Don't warn about
+ * kernels that don't have 'pathname' in the linker_file
+ * struct since 6.x kernels don't have it.
+ */
+ off_address = kgdb_parse("&((struct linker_file *)0)->address");
+ off_filename = kgdb_parse("&((struct linker_file *)0)->filename");
+ off_pathname = kgdb_parse_quiet("&((struct linker_file *)0)->pathname");
+ off_next = kgdb_parse("&((struct linker_file *)0)->link.tqe_next");
+ module_path_addr = kgdb_parse("linker_path");
+ linker_files_addr = kgdb_parse("&linker_files.tqh_first");
+ kernel_file_addr = kgdb_parse("&linker_kernel_file");
+}
+
static int
load_klds_stub (void *arg)
{
@@ -438,19 +472,16 @@ load_klds_stub (void *arg)
}
void
-kgdb_kld_init (void)
+kld_init (void)
{
- struct cmd_list_element *c;
- /* Compute offsets of relevant members in struct linker_file. */
- off_address = kgdb_parse("&((struct linker_file *)0)->address");
- off_filename = kgdb_parse("&((struct linker_file *)0)->filename");
- off_pathname = kgdb_parse("&((struct linker_file *)0)->pathname");
- off_next = kgdb_parse("&((struct linker_file *)0)->link.tqe_next");
- if (off_address == 0 || off_filename == 0 || off_next == 0)
- return;
+ catch_errors(load_klds_stub, NULL, NULL, RETURN_MASK_ALL);
+}
- module_path_addr = kgdb_parse("linker_path");
+void
+initialize_kld_target(void)
+{
+ struct cmd_list_element *c;
kld_so_ops.relocate_section_addresses = kld_relocate_section_addresses;
kld_so_ops.free_so = kld_free_so;
@@ -464,8 +495,6 @@ kgdb_kld_init (void)
current_target_so_ops = &kld_so_ops;
- catch_errors(load_klds_stub, NULL, NULL, RETURN_MASK_ALL);
-
c = add_com("add-kld", class_files, kgdb_add_kld_cmd,
"Usage: add-kld FILE\n\
Load the symbols from the kernel loadable module FILE.");
diff --git a/gnu/usr.bin/gdb/kgdb/kthr.c b/gnu/usr.bin/gdb/kgdb/kthr.c
index 4c51c0e..7c76b80 100644
--- a/gnu/usr.bin/gdb/kgdb/kthr.c
+++ b/gnu/usr.bin/gdb/kgdb/kthr.c
@@ -78,6 +78,12 @@ kgdb_thr_init(void)
struct thread td;
struct kthr *kt;
uintptr_t addr, paddr;
+
+ while (first != NULL) {
+ kt = first;
+ first = kt->next;
+ free(kt);
+ }
addr = kgdb_lookup("_allproc");
if (addr == 0) {
diff --git a/gnu/usr.bin/gdb/kgdb/main.c b/gnu/usr.bin/gdb/kgdb/main.c
index 7762763..3d94406 100644
--- a/gnu/usr.bin/gdb/kgdb/main.c
+++ b/gnu/usr.bin/gdb/kgdb/main.c
@@ -37,7 +37,6 @@ __FBSDID("$FreeBSD$");
#include <sys/wait.h>
#include <errno.h>
#include <err.h>
-#include <fcntl.h>
#include <inttypes.h>
#include <kvm.h>
#include <limits.h>
@@ -55,42 +54,31 @@ __FBSDID("$FreeBSD$");
#include <interps.h>
#include <cli-out.h>
#include <main.h>
+#include <objfiles.h>
#include <target.h>
#include <top.h>
+#include <ui-file.h>
#include <bfd.h>
#include <gdbcore.h>
#include <wrapper.h>
-extern void (*init_ui_hook)(char *);
-
extern frame_unwind_sniffer_ftype *kgdb_sniffer_kluge;
-extern void symbol_file_add_main (char *args, int from_tty);
-
#include "kgdb.h"
-kvm_t *kvm;
-static char kvm_err[_POSIX2_LINE_MAX];
-
static int dumpnr;
static int quiet;
static int verbose;
static char crashdir[PATH_MAX];
-char *kernel;
+static char *kernel;
static char *remote;
static char *vmcore;
+static struct ui_file *parse_gdberr;
static void (*kgdb_new_objfile_chain)(struct objfile * objfile);
static void
-kgdb_atexit(void)
-{
- if (kvm != NULL)
- kvm_close(kvm);
-}
-
-static void
usage(void)
{
@@ -168,27 +156,42 @@ kernel_from_dumpnr(int nr)
static void
kgdb_new_objfile(struct objfile *objfile)
{
-#if 0
- printf("XXX: %s(%p)\n", __func__, objfile);
- if (objfile != NULL) {
- goto out;
- }
+ static int once = 1;
+
+ kld_new_objfile(objfile);
+ kgdb_trgt_new_objfile(objfile);
-out:
-#endif
if (kgdb_new_objfile_chain != NULL)
kgdb_new_objfile_chain(objfile);
+
+ if (once && objfile != NULL && objfile == symfile_objfile) {
+ /*
+ * The initial kernel has just been loaded. Start the
+ * remote target if we have one.
+ */
+ once = 0;
+ if (remote != NULL)
+ push_remote_target (remote, 0);
+ }
}
+/*
+ * Parse an expression and return its value. If 'quiet' is true, then
+ * any error messages from the parser are masked.
+ */
CORE_ADDR
-kgdb_parse(const char *exp)
+kgdb_parse_1(const char *exp, int quiet)
{
+ struct ui_file *old_stderr;
struct cleanup *old_chain;
struct expression *expr;
struct value *val;
char *s;
CORE_ADDR n;
+ old_stderr = gdb_stderr;
+ if (quiet)
+ gdb_stderr = parse_gdberr;
n = 0;
s = xstrdup(exp);
old_chain = make_cleanup(xfree, s);
@@ -198,45 +201,19 @@ kgdb_parse(const char *exp)
n = value_as_address(val);
}
do_cleanups(old_chain);
+ gdb_stderr = old_stderr;
return (n);
}
#define MSGBUF_SEQ_TO_POS(size, seq) ((seq) % (size))
-static void
-kgdb_init_target(void)
+void
+kgdb_dmesg(void)
{
CORE_ADDR bufp;
int size, rseq, wseq;
- int kern_desc;
char c;
- kern_desc = open(kernel, O_RDONLY);
- if (kern_desc == -1)
- errx(1, "couldn't open a kernel image");
-
- kern_bfd = bfd_fdopenr(kernel, gnutarget, kern_desc);
- if (kern_bfd == NULL) {
- close(kern_desc);
- errx(1, "\"%s\": can't open to probe ABI: %s.", kernel,
- bfd_errmsg (bfd_get_error ()));
- }
- bfd_set_cacheable(kern_bfd, 1);
-
- if (!bfd_check_format (kern_bfd, bfd_object)) {
- bfd_close(kern_bfd);
- errx(1, "\"%s\": not in executable format: %s", kernel,
- bfd_errmsg(bfd_get_error()));
- }
-
- set_gdbarch_from_file (kern_bfd);
-
- symbol_file_add_main (kernel, 0);
- if (remote)
- push_remote_target (remote, 0);
- else
- kgdb_target();
-
/*
* Display the unread portion of the message buffer. This gives the
* user a some initial data to work from.
@@ -266,37 +243,54 @@ kgdb_init_target(void)
}
static void
-kgdb_interp_command_loop(void *data)
+kgdb_init(char *argv0 __unused)
+{
+
+ parse_gdberr = mem_fileopen();
+ set_prompt("(kgdb) ");
+ initialize_kgdb_target();
+ initialize_kld_target();
+ kgdb_new_objfile_chain = target_new_objfile_hook;
+ target_new_objfile_hook = kgdb_new_objfile;
+}
+
+/*
+ * Remote targets can support any number of syntaxes and we want to
+ * support them all with one addition: we support specifying a device
+ * node for a serial device without the "/dev/" prefix.
+ *
+ * What we do is to stat(2) the existing remote target first. If that
+ * fails, we try it with "/dev/" prepended. If that succeeds we use
+ * the resulting path, otherwise we use the original target. If
+ * either stat(2) succeeds make sure the file is either a character
+ * device or a FIFO.
+ */
+static void
+verify_remote(void)
{
- static int once = 0;
+ char path[PATH_MAX];
+ struct stat st;
- if (!once) {
- once = 1;
- kgdb_init_target();
- print_stack_frame(get_selected_frame(),
- frame_relative_level(get_selected_frame()), 1);
+ if (stat(remote, &st) != 0) {
+ snprintf(path, sizeof(path), "/dev/%s", remote);
+ if (stat(path, &st) != 0)
+ return;
+ free(remote);
+ remote = strdup(path);
}
- command_loop();
+ if (!S_ISCHR(st.st_mode) && !S_ISFIFO(st.st_mode))
+ errx(1, "%s: not a special file, FIFO or socket", remote);
}
static void
-kgdb_init(char *argv0 __unused)
+add_arg(struct captured_main_args *args, char *arg)
{
- static struct interp_procs procs = {
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- kgdb_interp_command_loop
- };
- struct interp *kgdb;
- kgdb = interp_new("kgdb", NULL, cli_out_new(gdb_stdout), &procs);
- interp_add(kgdb);
- set_prompt("(kgdb) ");
- kgdb_new_objfile_chain = target_new_objfile_hook;
- target_new_objfile_hook = kgdb_new_objfile;
+ args->argc++;
+ args->argv = reallocf(args->argv, (args->argc + 1) * sizeof(char *));
+ if (args->argv == NULL)
+ err(1, "Out of memory building argument list");
+ args->argv[args->argc] = arg;
}
int
@@ -306,7 +300,7 @@ main(int argc, char *argv[])
struct stat st;
struct captured_main_args args;
char *s;
- int a, ch, writecore;
+ int a, ch;
dumpnr = -1;
@@ -331,7 +325,11 @@ main(int argc, char *argv[])
}
quiet = 0;
- writecore = 0;
+ memset (&args, 0, sizeof args);
+ args.use_windows = 0;
+ args.interpreter_p = INTERP_CONSOLE;
+ args.argv = malloc(sizeof(char *));
+ args.argv[0] = argv[0];
while ((ch = getopt(argc, argv, "ac:d:fn:qr:vw")) != -1) {
switch (ch) {
@@ -364,6 +362,7 @@ main(int argc, char *argv[])
break;
case 'q':
quiet = 1;
+ add_arg(&args, "-q");
break;
case 'r': /* use given device for remote session. */
if (remote != NULL) {
@@ -378,7 +377,7 @@ main(int argc, char *argv[])
verbose++;
break;
case 'w': /* core file is writeable. */
- writecore = 1;
+ add_arg(&args, "--write");
break;
case '?':
default:
@@ -411,21 +410,8 @@ main(int argc, char *argv[])
if (!S_ISREG(st.st_mode))
errx(1, "%s: not a regular file", path);
vmcore = strdup(path);
- } else if (remote != NULL && remote[0] != ':' && remote[0] != '|') {
- if (stat(remote, &st) != 0) {
- snprintf(path, sizeof(path), "/dev/%s", remote);
- if (stat(path, &st) != 0) {
- err(1, "%s", remote);
- /* NOTREACHED */
- }
- free(remote);
- remote = strdup(path);
- }
- if (!S_ISCHR(st.st_mode) && !S_ISFIFO(st.st_mode)) {
- errx(1, "%s: not a special file, FIFO or socket",
- remote);
- /* NOTREACHED */
- }
+ } else if (remote != NULL) {
+ verify_remote();
} else if (argc > optind) {
if (vmcore == NULL)
vmcore = strdup(argv[optind++]);
@@ -445,20 +431,12 @@ main(int argc, char *argv[])
warnx("kernel image: %s", kernel);
}
- /*
- * At this point we must either have a core file or have a kernel
- * with a remote target.
- */
+ /* A remote target requires an explicit kernel argument. */
if (remote != NULL && kernel == NULL) {
warnx("remote debugging requires a kernel");
usage();
/* NOTREACHED */
}
- if (vmcore == NULL && remote == NULL) {
- warnx("need a core file or a device for remote debugging");
- usage();
- /* NOTREACHED */
- }
/* If we don't have a kernel image yet, try to find one. */
if (kernel == NULL) {
@@ -470,27 +448,16 @@ main(int argc, char *argv[])
if (verbose)
warnx("kernel image: %s", kernel);
}
+ add_arg(&args, kernel);
- if (remote == NULL) {
- kvm = kvm_openfiles(kernel, vmcore, NULL,
- writecore ? O_RDWR : O_RDONLY, kvm_err);
- if (kvm == NULL)
- errx(1, kvm_err);
- atexit(kgdb_atexit);
- kgdb_thr_init();
- }
+ if (vmcore != NULL)
+ add_arg(&args, vmcore);
/* The libgdb code uses optind too. Reset it... */
optind = 0;
- memset (&args, 0, sizeof args);
- args.argv = argv;
- args.argc = 1 + quiet;
- if (quiet)
- argv[1] = "-q";
- argv[args.argc] = NULL;
- args.use_windows = 0;
- args.interpreter_p = "kgdb";
+ /* Terminate argv list. */
+ add_arg(&args, NULL);
init_ui_hook = kgdb_init;
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();
}
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
index 064d482..d37e9da 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
@@ -74,6 +74,11 @@ kgdb_trgt_store_registers(int regno __unused)
fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
}
+void
+kgdb_trgt_new_objfile(struct objfile *objfile)
+{
+}
+
struct kgdb_frame_cache {
CORE_ADDR pc;
CORE_ADDR sp;
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_arm.c b/gnu/usr.bin/gdb/kgdb/trgt_arm.c
index afdcbc6..e99d5b2 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_arm.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_arm.c
@@ -89,6 +89,11 @@ kgdb_trgt_store_registers(int regno __unused)
fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
}
+void
+kgdb_trgt_new_objfile(struct objfile *objfile)
+{
+}
+
#ifndef CROSS_DEBUGGER
struct kgdb_frame_cache {
CORE_ADDR fp;
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_i386.c b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
index 995f1a6..f0546ba 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_i386.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
@@ -41,12 +41,15 @@ __FBSDID("$FreeBSD$");
#include <target.h>
#include <gdbthread.h>
#include <inferior.h>
+#include <objfiles.h>
#include <regcache.h>
#include <frame-unwind.h>
#include <i386-tdep.h>
#include "kgdb.h"
+static int ofs_fix;
+
void
kgdb_trgt_fetch_registers(int regno __unused)
{
@@ -74,6 +77,23 @@ kgdb_trgt_store_registers(int regno __unused)
fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
}
+void
+kgdb_trgt_new_objfile(struct objfile *objfile)
+{
+
+ /*
+ * In revision 1.117 of i386/i386/exception.S trap handlers
+ * were changed to pass trapframes by reference rather than
+ * by value. Detect this by seeing if the first instruction
+ * at the 'calltrap' label is a "push %esp" which has the
+ * opcode 0x54.
+ */
+ if (kgdb_parse("((char *)calltrap)[0]") == 0x54)
+ ofs_fix = 4;
+ else
+ ofs_fix = 0;
+}
+
struct kgdb_tss_cache {
CORE_ADDR pc;
CORE_ADDR sp;
@@ -285,8 +305,6 @@ kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame,
char dummy_valuep[MAX_REGISTER_SIZE];
struct kgdb_frame_cache *cache;
int ofs, regsz;
- static int ofs_fix = 0;
- static int ofs_fixed = 0;
regsz = register_size(current_gdbarch, regnum);
@@ -298,18 +316,6 @@ kgdb_trgt_trapframe_prev_register(struct frame_info *next_frame,
*lvalp = not_lval;
*realnump = -1;
- if (!ofs_fixed) {
- /*
- * In revision 1.117 of i386/i386/exception.S trap handlers
- * were changed to pass trapframes by reference rather than
- * by value. Detect this by seeing if the first instruction
- * at the 'calltrap' label is a "push %esp" which has the
- * opcode 0x54.
- */
- if (kgdb_parse("((char *)calltrap)[0]") == 0x54)
- ofs_fix = 4;
- ofs_fixed = 1;
- }
ofs = (regnum >= I386_EAX_REGNUM && regnum <= I386_FS_REGNUM)
? kgdb_trgt_frame_offset[regnum] + ofs_fix : -1;
if (ofs == -1)
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
index 86d83fc..f9e0136 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
@@ -135,6 +135,11 @@ kgdb_trgt_store_registers(int regno __unused)
fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
}
+void
+kgdb_trgt_new_objfile(struct objfile *objfile)
+{
+}
+
struct kgdb_frame_cache {
CORE_ADDR bsp;
CORE_ADDR ip;
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c b/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c
index 5c0ffe7..95e6161 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c
@@ -83,6 +83,11 @@ kgdb_trgt_store_registers(int regno __unused)
fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
}
+void
+kgdb_trgt_new_objfile(struct objfile *objfile)
+{
+}
+
struct kgdb_frame_cache {
CORE_ADDR pc;
CORE_ADDR sp;
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c b/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
index 3e4a41a..736a499 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
@@ -73,6 +73,11 @@ kgdb_trgt_store_registers(int regno __unused)
fprintf_unfiltered(gdb_stderr, "XXX: %s\n", __func__);
}
+void
+kgdb_trgt_new_objfile(struct objfile *objfile)
+{
+}
+
struct kgdb_frame_cache {
CORE_ADDR pc;
CORE_ADDR sp;
OpenPOWER on IntegriCloud