summaryrefslogtreecommitdiffstats
path: root/gnu/usr.bin
diff options
context:
space:
mode:
Diffstat (limited to 'gnu/usr.bin')
-rw-r--r--gnu/usr.bin/gdb/kgdb/Makefile2
-rw-r--r--gnu/usr.bin/gdb/kgdb/kgdb.h10
-rw-r--r--gnu/usr.bin/gdb/kgdb/kthr.c59
-rw-r--r--gnu/usr.bin/gdb/kgdb/main.c46
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt.c116
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_alpha.c2
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_amd64.c2
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_i386.c2
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_ia64.c2
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_sparc64.c2
10 files changed, 218 insertions, 25 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/Makefile b/gnu/usr.bin/gdb/kgdb/Makefile
index 404b960..d688bb6 100644
--- a/gnu/usr.bin/gdb/kgdb/Makefile
+++ b/gnu/usr.bin/gdb/kgdb/Makefile
@@ -1,7 +1,7 @@
# $FreeBSD$
PROG= kgdb${GDB_SUFFIX}
-SRCS= kthr.c main.c trgt.c trgt_${TARGET_ARCH}.c
+SRCS= main.c kthr.c trgt.c trgt_${MACHINE_ARCH}.c
WARNS?= 2
BULIBS= ${OBJ_BU}/libbfd/libbfd.a ${OBJ_BU}/libopcodes/libopcodes.a \
diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.h b/gnu/usr.bin/gdb/kgdb/kgdb.h
index eb38032..b545ebb 100644
--- a/gnu/usr.bin/gdb/kgdb/kgdb.h
+++ b/gnu/usr.bin/gdb/kgdb/kgdb.h
@@ -29,15 +29,19 @@
#ifndef _KGDB_H_
#define _KGDB_H_
+struct thread_info;
+
extern kvm_t *kvm;
extern int verbose;
struct kthr {
struct kthr *next;
+ uintptr_t paddr;
uintptr_t kaddr;
uintptr_t kstack;
uintptr_t pcb;
int tid;
+ int pid;
};
extern struct kthr *curkthr;
@@ -48,8 +52,12 @@ void kgdb_trgt_store_registers(int);
struct kthr *kgdb_thr_first(void);
struct kthr *kgdb_thr_init(void);
-struct kthr *kgdb_thr_lookup(int);
+struct kthr *kgdb_thr_lookup_tid(int);
+struct kthr *kgdb_thr_lookup_pid(int);
+struct kthr *kgdb_thr_lookup_paddr(uintptr_t);
+struct kthr *kgdb_thr_lookup_taddr(uintptr_t);
struct kthr *kgdb_thr_next(struct kthr *);
struct kthr *kgdb_thr_select(struct kthr *);
+char *kgdb_thr_extra_thread_info(int);
#endif /* _KGDB_H_ */
diff --git a/gnu/usr.bin/gdb/kgdb/kthr.c b/gnu/usr.bin/gdb/kgdb/kthr.c
index 25f8d49..505605d 100644
--- a/gnu/usr.bin/gdb/kgdb/kthr.c
+++ b/gnu/usr.bin/gdb/kgdb/kthr.c
@@ -37,6 +37,8 @@ __FBSDID("$FreeBSD$");
#include <stdio.h>
#include <stdlib.h>
+#include <defs.h>
+
#include "kgdb.h"
static uintptr_t dumppcb;
@@ -102,19 +104,21 @@ kgdb_thr_init(void)
(uintptr_t)td.td_pcb;
kt->kstack = td.td_kstack;
kt->tid = td.td_tid;
+ kt->pid = p.p_pid;
+ kt->paddr = paddr;
first = kt;
addr = (uintptr_t)TAILQ_NEXT(&td, td_plist);
}
paddr = (uintptr_t)LIST_NEXT(&p, p_list);
}
- curkthr = kgdb_thr_lookup(dumptid);
+ curkthr = kgdb_thr_lookup_tid(dumptid);
if (curkthr == NULL)
curkthr = first;
return (first);
}
struct kthr *
-kgdb_thr_lookup(int tid)
+kgdb_thr_lookup_tid(int tid)
{
struct kthr *kt;
@@ -125,6 +129,39 @@ kgdb_thr_lookup(int tid)
}
struct kthr *
+kgdb_thr_lookup_taddr(uintptr_t taddr)
+{
+ struct kthr *kt;
+
+ kt = first;
+ while (kt != NULL && kt->kaddr != taddr)
+ kt = kt->next;
+ return (kt);
+}
+
+struct kthr *
+kgdb_thr_lookup_pid(int pid)
+{
+ struct kthr *kt;
+
+ kt = first;
+ while (kt != NULL && kt->pid != pid)
+ kt = kt->next;
+ return (kt);
+}
+
+struct kthr *
+kgdb_thr_lookup_paddr(uintptr_t paddr)
+{
+ struct kthr *kt;
+
+ kt = first;
+ while (kt != NULL && kt->paddr != paddr)
+ kt = kt->next;
+ return (kt);
+}
+
+struct kthr *
kgdb_thr_next(struct kthr *kt)
{
return (kt->next);
@@ -139,3 +176,21 @@ kgdb_thr_select(struct kthr *kt)
curkthr = kt;
return (pcur);
}
+
+char *
+kgdb_thr_extra_thread_info(int tid)
+{
+ struct kthr *kt;
+ struct proc *p;
+ static char comm[MAXCOMLEN + 1];
+
+ kt = kgdb_thr_lookup_tid(tid);
+ if (kt == NULL)
+ return (NULL);
+ p = (struct proc *)kt->paddr;
+ if (kvm_read(kvm, (uintptr_t)&p->p_comm[0], &comm, sizeof(comm)) !=
+ sizeof(comm))
+ return (NULL);
+
+ return (comm);
+}
diff --git a/gnu/usr.bin/gdb/kgdb/main.c b/gnu/usr.bin/gdb/kgdb/main.c
index 54f6a3e..3ad158b 100644
--- a/gnu/usr.bin/gdb/kgdb/main.c
+++ b/gnu/usr.bin/gdb/kgdb/main.c
@@ -56,6 +56,8 @@ __FBSDID("$FreeBSD$");
#include <main.h>
#include <target.h>
#include <top.h>
+#include <bfd.h>
+#include <gdbcore.h>
extern void (*init_ui_hook)(char *);
@@ -166,18 +168,50 @@ out:
}
static void
+kgdb_init_target(void)
+{
+ bfd *kern_bfd;
+ int kern_desc;
+
+ 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);
+ bfd_close(kern_bfd);
+
+ symbol_file_add_main (kernel, 0);
+ if (remote)
+ push_remote_target (remote, 0);
+ else
+ kgdb_target();
+}
+
+static void
kgdb_interp_command_loop(void *data)
{
static int once = 0;
if (!once) {
once = 1;
- symbol_file_add_main (kernel, 0);
- if (remote)
- push_remote_target (remote, 0);
- else
- kgdb_target();
- print_stack_frame(get_current_frame(), -1, 0);
+ kgdb_init_target();
+ kgdb_target();
+ print_stack_frame (get_selected_frame (),
+ frame_relative_level (get_selected_frame ()), 1);
}
command_loop();
}
diff --git a/gnu/usr.bin/gdb/kgdb/trgt.c b/gnu/usr.bin/gdb/kgdb/trgt.c
index 5c889eb..93cac11 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt.c
@@ -27,22 +27,48 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
-#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/sysctl.h>
+#include <sys/user.h>
#include <kvm.h>
-#include "kgdb.h"
-
#include <defs.h>
+#include <command.h>
#include <gdbthread.h>
#include <inferior.h>
+#include <regcache.h>
#include <target.h>
+#include "kgdb.h"
+
static struct target_ops kgdb_trgt_ops;
+#define KERNOFF (kgdb_kernbase ())
+#define INKERNEL(x) ((x) >= KERNOFF)
+
+static CORE_ADDR
+kgdb_kernbase (void)
+{
+ static CORE_ADDR kernbase;
+ struct minimal_symbol *sym;
+
+ if (kernbase == 0)
+ {
+ sym = lookup_minimal_symbol ("kernbase", NULL, NULL);
+ if (sym == NULL) {
+ kernbase = KERNBASE;
+ } else {
+ kernbase = SYMBOL_VALUE_ADDRESS (sym);
+ }
+ }
+ return kernbase;
+}
+
static char *
-kgdb_trgt_extra_thread_info(struct thread_info *ti __unused)
+kgdb_trgt_extra_thread_info(struct thread_info *ti)
{
- return (NULL);
+ return (kgdb_thr_extra_thread_info(ptid_get_tid(ti->ptid)));
}
static void
@@ -53,16 +79,17 @@ kgdb_trgt_find_new_threads(void)
static char *
kgdb_trgt_pid_to_str(ptid_t ptid)
{
- static char buf[16];
+ static char buf[33];
- snprintf(buf, sizeof(buf), "TID %d", ptid_get_pid(ptid));
+ snprintf(buf, sizeof(buf), "PID %5d TID %5ld", ptid_get_pid(ptid),
+ ptid_get_tid(ptid));
return (buf);
}
static int
kgdb_trgt_thread_alive(ptid_t ptid)
{
- return (kgdb_thr_lookup(ptid_get_pid(ptid)) != NULL);
+ return (kgdb_thr_lookup_tid(ptid_get_tid(ptid)) != NULL);
}
static int
@@ -78,6 +105,71 @@ kgdb_trgt_xfer_memory(CORE_ADDR memaddr, char *myaddr, int len, int write,
return (kvm_write(kvm, memaddr, myaddr, len));
}
+static void
+kgdb_switch_to_thread(struct kthr *thr)
+{
+ if (thr->tid == ptid_get_tid(inferior_ptid))
+ return;
+
+ inferior_ptid = ptid_build(thr->pid, 0, thr->tid);
+ flush_cached_frames ();
+ registers_changed ();
+ stop_pc = read_pc ();
+ select_frame (get_current_frame ());
+}
+
+static void
+kgdb_set_proc_cmd (char *arg, int from_tty)
+{
+ CORE_ADDR addr;
+ struct kthr *thr;
+
+ if (!arg)
+ error_no_arg ("proc address for the new context");
+
+ if (kvm == NULL)
+ error ("no kernel core file");
+
+ addr = (CORE_ADDR) parse_and_eval_address (arg);
+
+ if (!INKERNEL (addr)) {
+ thr = kgdb_thr_lookup_pid((int)addr);
+ if (thr == NULL)
+ error ("invalid pid");
+ } else {
+ thr = kgdb_thr_lookup_paddr(addr);
+ if (thr == NULL)
+ error("invalid proc address");
+ }
+ kgdb_switch_to_thread(thr);
+}
+
+static void
+kgdb_set_tid_cmd (char *arg, int from_tty)
+{
+ CORE_ADDR addr;
+ struct kthr *thr;
+
+ if (!arg)
+ error_no_arg ("TID or thread address for the new context");
+
+ if (kvm == NULL)
+ error ("no kernel core file");
+
+ addr = (CORE_ADDR) parse_and_eval_address (arg);
+
+ if (!INKERNEL (addr)) {
+ thr = kgdb_thr_lookup_tid((int)addr);
+ if (thr == NULL)
+ error ("invalid TID");
+ } else {
+ thr = kgdb_thr_lookup_taddr(addr);
+ if (thr == NULL)
+ error("invalid thread address");
+ }
+ kgdb_switch_to_thread(thr);
+}
+
void
kgdb_target(void)
{
@@ -105,8 +197,12 @@ kgdb_target(void)
kt = kgdb_thr_first();
while (kt != NULL) {
- ti = add_thread(ptid_build(kt->tid, 0, 0));
+ ti = add_thread(ptid_build(kt->pid, 0, kt->tid));
kt = kgdb_thr_next(kt);
}
- inferior_ptid = ptid_build(curkthr->tid, 0, 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 process context");
}
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_alpha.c b/gnu/usr.bin/gdb/kgdb/trgt_alpha.c
index 891b0eb..336970b 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_alpha.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_alpha.c
@@ -47,7 +47,7 @@ kgdb_trgt_fetch_registers(int regno __unused)
struct kthr *kt;
struct pcb pcb;
- kt = kgdb_thr_lookup(ptid_get_pid(inferior_ptid));
+ kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
if (kt == NULL)
return;
if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) {
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
index e193969..0907d0d 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
@@ -47,7 +47,7 @@ kgdb_trgt_fetch_registers(int regno __unused)
struct kthr *kt;
struct pcb pcb;
- kt = kgdb_thr_lookup(ptid_get_pid(inferior_ptid));
+ kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
if (kt == NULL)
return;
if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) {
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_i386.c b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
index 36c1ed0..96dad51 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_i386.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
@@ -47,7 +47,7 @@ kgdb_trgt_fetch_registers(int regno __unused)
struct kthr *kt;
struct pcb pcb;
- kt = kgdb_thr_lookup(ptid_get_pid(inferior_ptid));
+ kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
if (kt == NULL)
return;
if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) {
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
index 15609af..bfceba4 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
@@ -49,7 +49,7 @@ kgdb_trgt_fetch_registers(int regno __unused)
struct pcb pcb;
uint64_t r;
- kt = kgdb_thr_lookup(ptid_get_pid(inferior_ptid));
+ kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
if (kt == NULL)
return;
if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) {
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c b/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
index 81f9a86..8be716e 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
@@ -49,7 +49,7 @@ kgdb_trgt_fetch_registers(int regno __unused)
struct pcb pcb;
uint64_t r;
- kt = kgdb_thr_lookup(ptid_get_pid(inferior_ptid));
+ kt = kgdb_thr_lookup_tid(ptid_get_tid(inferior_ptid));
if (kt == NULL)
return;
if (kvm_read(kvm, kt->pcb, &pcb, sizeof(pcb)) != sizeof(pcb)) {
OpenPOWER on IntegriCloud