summaryrefslogtreecommitdiffstats
path: root/gnu
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2013-02-17 02:15:19 +0000
committermarcel <marcel@FreeBSD.org>2013-02-17 02:15:19 +0000
commita57e06a00fbd4f164ab76d450ae9dd7f852d133a (patch)
treed0bc12f1f0bac581a236d8a6b3b200c69d7b4569 /gnu
parentf84b7c4c4093195c81005c6571f2a995bc7480df (diff)
downloadFreeBSD-src-a57e06a00fbd4f164ab76d450ae9dd7f852d133a.zip
FreeBSD-src-a57e06a00fbd4f164ab76d450ae9dd7f852d133a.tar.gz
In kthr.c, obtain the address of the PCB for threads that were running
on a core, when the core was stopped, by calling kgdb_trgt_core_pcb(). This has 2 advantages: 1. We don't need to include a machine-specific header anymore and as such kthr.c is truly machine independent. This allows the code to be used in a cross-debugger. 2. We don't need to lookup stoppcbs in generic code when it's an inherently target-spicific symbol. It does not exist for ia64. Implement kgdb_trgt_core_pcb() for all architectures, except ia64, by calling a common function called kgdb_trgt_stop_pcb(). This function differs from kgdb_trgt_core_pcb() in that it gets the size of the PCB structure as an argument and as such remains machine independent. On ia64 the PCB for stopped cores is in the PCPU structure itself. This for better scaling. The implementation of kgdb_trgt_core_pcb() for ia64 uses the cpuid_to_pcpu[] array to to obtain the address of the PCB structure.
Diffstat (limited to 'gnu')
-rw-r--r--gnu/usr.bin/gdb/kgdb/kgdb.h2
-rw-r--r--gnu/usr.bin/gdb/kgdb/kthr.c9
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt.c17
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_amd64.c6
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_arm.c6
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_i386.c6
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_ia64.c12
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_mips.c6
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_powerpc.c6
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_powerpc64.c6
-rw-r--r--gnu/usr.bin/gdb/kgdb/trgt_sparc64.c6
11 files changed, 75 insertions, 7 deletions
diff --git a/gnu/usr.bin/gdb/kgdb/kgdb.h b/gnu/usr.bin/gdb/kgdb/kgdb.h
index e828f56..1a32d8a 100644
--- a/gnu/usr.bin/gdb/kgdb/kgdb.h
+++ b/gnu/usr.bin/gdb/kgdb/kgdb.h
@@ -49,6 +49,8 @@ extern struct kthr *curkthr;
void initialize_kld_target(void);
void initialize_kgdb_target(void);
void kgdb_dmesg(void);
+CORE_ADDR kgdb_trgt_core_pcb(u_int);
+CORE_ADDR kgdb_trgt_stop_pcb(u_int, u_int);
void kgdb_trgt_new_objfile(struct objfile *);
void kgdb_trgt_fetch_registers(int);
void kgdb_trgt_store_registers(int);
diff --git a/gnu/usr.bin/gdb/kgdb/kthr.c b/gnu/usr.bin/gdb/kgdb/kthr.c
index b12d07c..713b93b 100644
--- a/gnu/usr.bin/gdb/kgdb/kthr.c
+++ b/gnu/usr.bin/gdb/kgdb/kthr.c
@@ -44,12 +44,10 @@ __FBSDID("$FreeBSD$");
#include <frame-unwind.h>
#include "kgdb.h"
-#include <machine/pcb.h>
static CORE_ADDR dumppcb;
static int dumptid;
-static CORE_ADDR stoppcbs;
static cpuset_t stopped_cpus;
static struct kthr *first;
@@ -98,10 +96,9 @@ kgdb_thr_add_procs(uintptr_t paddr)
kt->kaddr = addr;
if (td.td_tid == dumptid)
kt->pcb = dumppcb;
- else if (td.td_state == TDS_RUNNING && stoppcbs != 0 &&
+ else if (td.td_state == TDS_RUNNING &&
CPU_ISSET(td.td_oncpu, &stopped_cpus))
- kt->pcb = (uintptr_t)stoppcbs +
- sizeof(struct pcb) * td.td_oncpu;
+ kt->pcb = kgdb_trgt_core_pcb(td.td_oncpu);
else
kt->pcb = (uintptr_t)td.td_pcb;
kt->kstack = td.td_kstack;
@@ -152,8 +149,6 @@ kgdb_thr_init(void)
addr != 0)
kvm_read(kvm, addr, &stopped_cpus, cpusetsize);
- stoppcbs = kgdb_lookup("stoppcbs");
-
kgdb_thr_add_procs(paddr);
addr = kgdb_lookup("zombproc");
if (addr != 0) {
diff --git a/gnu/usr.bin/gdb/kgdb/trgt.c b/gnu/usr.bin/gdb/kgdb/trgt.c
index 14449b9..85065cc 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt.c
@@ -53,6 +53,8 @@ __FBSDID("$FreeBSD$");
#include "kgdb.h"
+static CORE_ADDR stoppcbs;
+
static void kgdb_core_cleanup(void *);
static char *vmcore;
@@ -352,3 +354,18 @@ initialize_kgdb_target(void)
add_com ("tid", class_obscure, kgdb_set_tid_cmd,
"Set current thread context");
}
+
+CORE_ADDR
+kgdb_trgt_stop_pcb(u_int cpuid, u_int pcbsz)
+{
+ static int once = 0;
+
+ if (stoppcbs == 0 && !once) {
+ once = 1;
+ stoppcbs = kgdb_lookup("stoppcbs");
+ }
+ if (stoppcbs == 0)
+ return 0;
+
+ return (stoppcbs + pcbsz * cpuid);
+}
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
index cdab775..cb13d71 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_amd64.c
@@ -44,6 +44,12 @@ __FBSDID("$FreeBSD$");
#include "kgdb.h"
+CORE_ADDR
+kgdb_trgt_core_pcb(u_int cpuid)
+{
+ return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb)));
+}
+
void
kgdb_trgt_fetch_registers(int regno __unused)
{
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_arm.c b/gnu/usr.bin/gdb/kgdb/trgt_arm.c
index f2e292e..ca18ae3 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_arm.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_arm.c
@@ -47,6 +47,12 @@ __FBSDID("$FreeBSD$");
#include "kgdb.h"
+CORE_ADDR
+kgdb_trgt_core_pcb(u_int cpuid)
+{
+ return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb)));
+}
+
void
kgdb_trgt_fetch_registers(int regno __unused)
{
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_i386.c b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
index aba8b65..02c9918 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_i386.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_i386.c
@@ -49,6 +49,12 @@ __FBSDID("$FreeBSD$");
static int ofs_fix;
+CORE_ADDR
+kgdb_trgt_core_pcb(u_int cpuid)
+{
+ return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb)));
+}
+
void
kgdb_trgt_fetch_registers(int regno __unused)
{
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
index 4efa6eb..6ba800b 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_ia64.c
@@ -52,6 +52,18 @@ __FBSDID("$FreeBSD$");
#include "kgdb.h"
+CORE_ADDR
+kgdb_trgt_core_pcb(u_int cpuid)
+{
+ CORE_ADDR addr;
+ char *expr;
+
+ asprintf(&expr, "&cpuid_to_pcpu[%d]->pc_md.pcb", cpuid);
+ addr = kgdb_parse(expr);
+ free(expr);
+ return (addr);
+}
+
void
kgdb_trgt_fetch_registers(int regno __unused)
{
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_mips.c b/gnu/usr.bin/gdb/kgdb/trgt_mips.c
index 423cacd..6ad2274 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_mips.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_mips.c
@@ -52,6 +52,12 @@ __FBSDID("$FreeBSD$");
#include "kgdb.h"
+CORE_ADDR
+kgdb_trgt_core_pcb(u_int cpuid)
+{
+ return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb)));
+}
+
void
kgdb_trgt_fetch_registers(int regno __unused)
{
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c b/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c
index a83c2d0..ef8d7f1 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_powerpc.c
@@ -49,6 +49,12 @@ __FBSDID("$FreeBSD$");
#include "kgdb.h"
+CORE_ADDR
+kgdb_trgt_core_pcb(u_int cpuid)
+{
+ return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb)));
+}
+
void
kgdb_trgt_fetch_registers(int regno __unused)
{
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_powerpc64.c b/gnu/usr.bin/gdb/kgdb/trgt_powerpc64.c
index d20a4d6..65f7ab5 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_powerpc64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_powerpc64.c
@@ -44,6 +44,12 @@ __FBSDID("$FreeBSD$");
#include "kgdb.h"
+CORE_ADDR
+kgdb_trgt_core_pcb(u_int cpuid)
+{
+ return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb)));
+}
+
void
kgdb_trgt_fetch_registers(int regno __unused)
{
diff --git a/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c b/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
index 8fece24..070194a 100644
--- a/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
+++ b/gnu/usr.bin/gdb/kgdb/trgt_sparc64.c
@@ -46,6 +46,12 @@ __FBSDID("$FreeBSD$");
#include "kgdb.h"
+CORE_ADDR
+kgdb_trgt_core_pcb(u_int cpuid)
+{
+ return (kgdb_trgt_stop_pcb(cpuid, sizeof(struct pcb)));
+}
+
void
kgdb_trgt_fetch_registers(int regno __unused)
{
OpenPOWER on IntegriCloud