Introduce the GDB debugger backend for the new KDB framework. The

backend improves over the old GDB support in the following ways:
o  Unified implementation with minimal MD code.
o  A simple interface for devices to register themselves as debug
   ports, ala consoles.
o  Compression by using run-length encoding.
o  Implements GDB threading support.
This commit is contained in:
Marcel Moolenaar 2004-07-10 17:47:22 +00:00
parent f5eda2f1cb
commit 72d44f31a6
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=131899
14 changed files with 1515 additions and 0 deletions

View File

@ -0,0 +1,101 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/signal.h>
#include <machine/gdb_machdep.h>
#include <machine/pcb.h>
#include <machine/reg.h>
#include <gdb/gdb.h>
void *
gdb_cpu_getreg(int regnum, size_t *regsz)
{
*regsz = gdb_cpu_regsz(regnum);
switch (regnum) {
case 9: return (&kdb_thrctx->pcb_context[0]);
case 10: return (&kdb_thrctx->pcb_context[1]);
case 11: return (&kdb_thrctx->pcb_context[2]);
case 12: return (&kdb_thrctx->pcb_context[3]);
case 13: return (&kdb_thrctx->pcb_context[4]);
case 14: return (&kdb_thrctx->pcb_context[5]);
case 15: return (&kdb_thrctx->pcb_context[6]);
case 30: return (&kdb_thrctx->pcb_hw.apcb_ksp);
case 64: return (&kdb_thrctx->pcb_context[7]);
}
return (NULL);
}
void
gdb_cpu_setreg(int regnum, register_t val)
{
switch (regnum) {
}
}
int
gdb_cpu_signal(int entry, int code)
{
switch (entry) {
case ALPHA_KENTRY_INT:
case ALPHA_KENTRY_ARITH:
return (SIGILL); /* Can this happen? */
case ALPHA_KENTRY_MM:
switch (code) {
case ALPHA_MMCSR_INVALTRANS:
return (SIGSEGV);
case ALPHA_MMCSR_ACCESS:
case ALPHA_MMCSR_FOR:
case ALPHA_MMCSR_FOE:
case ALPHA_MMCSR_FOW:
return (SIGBUS);
}
case ALPHA_KENTRY_IF:
switch (code) {
case ALPHA_IF_CODE_BUGCHK:
case ALPHA_IF_CODE_BPT:
return (SIGTRAP);
case ALPHA_IF_CODE_GENTRAP:
case ALPHA_IF_CODE_FEN:
case ALPHA_IF_CODE_OPDEC:
return (SIGILL);
}
case ALPHA_KENTRY_UNA:
return (SIGSEGV);
case ALPHA_KENTRY_SYS:
return (SIGILL);
}
return (SIGILL);
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_GDB_MACHDEP_H_
#define _MACHINE_GDB_MACHDEP_H_
#define GDB_BUFSZ 600
#define GDB_NREGS 67
#define GDB_REG_PC 64
static __inline size_t
gdb_cpu_regsz(int regnum)
{
return (sizeof(long));
}
static __inline int
gdb_cpu_query(void)
{
return (0);
}
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, register_t);
int gdb_cpu_signal(int, int);
#endif /* !_MACHINE_GDB_MACHDEP_H_ */

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/signal.h>
#include <machine/frame.h>
#include <machine/gdb_machdep.h>
#include <machine/psl.h>
#include <machine/reg.h>
#include <machine/trap.h>
#include <gdb/gdb.h>
void *
gdb_cpu_getreg(int regnum, size_t *regsz)
{
struct trapframe *tf = kdb_frame;
*regsz = gdb_cpu_regsz(regnum);
switch (regnum) {
case 0: return (&tf->tf_rax);
case 1: return (&tf->tf_rbx);
case 2: return (&tf->tf_rcx);
case 3: return (&tf->tf_rdx);
case 4: return (&tf->tf_rsi);
case 5: return (&tf->tf_rdi);
case 6: return (&tf->tf_rbp);
case 7: return (&tf->tf_rsp);
case 8: return (&tf->tf_r8);
case 9: return (&tf->tf_r9);
case 10: return (&tf->tf_r10);
case 11: return (&tf->tf_r11);
case 12: return (&tf->tf_r12);
case 13: return (&tf->tf_r13);
case 14: return (&tf->tf_r14);
case 15: return (&tf->tf_r15);
case 16: return (&tf->tf_rip);
case 17: return (&tf->tf_rflags);
case 18: return (&tf->tf_cs);
case 19: return (&tf->tf_ss);
}
return (NULL);
}
void
gdb_cpu_setreg(int regnum, register_t val)
{
struct trapframe *tf = kdb_frame;
switch (regnum) {
case GDB_REG_PC: tf->tf_rip = val; break;
}
}

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_GDB_MACHDEP_H_
#define _MACHINE_GDB_MACHDEP_H_
#define GDB_BUFSZ 500
#define GDB_NREGS 56
#define GDB_REG_PC 18
static __inline size_t
gdb_cpu_regsz(int regnum)
{
return ((regnum > 16 && regnum < 24) ? 4 : 8);
}
static __inline int
gdb_cpu_signal(int type, int code __unused)
{
return (type);
}
static __inline int
gdb_cpu_query(void)
{
return (0);
}
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, register_t);
#endif /* !_MACHINE_GDB_MACHDEP_H_ */

62
sys/gdb/gdb.h Normal file
View File

@ -0,0 +1,62 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _GDB_GDB_H_
#define _GDB_GDB_H_
typedef int gdb_checkc_f(void);
typedef int gdb_getc_f(void);
typedef void gdb_init_f(void);
typedef int gdb_probe_f(void);
typedef void gdb_putc_f(int);
typedef void gdb_term_f(void);
struct gdb_dbgport {
const char *gdb_name;
gdb_checkc_f *gdb_checkc;
gdb_getc_f *gdb_getc;
gdb_init_f *gdb_init;
gdb_probe_f *gdb_probe;
gdb_putc_f *gdb_putc;
gdb_term_f *gdb_term;
int gdb_active;
};
#define GDB_DBGPORT(name, probe, init, term, checkc, getc, putc) \
static struct gdb_dbgport name##_gdb_dbgport = { \
.gdb_name = #name, \
.gdb_checkc = checkc, \
.gdb_getc = getc, \
.gdb_init = init, \
.gdb_probe = probe, \
.gdb_putc = putc, \
.gdb_term = term \
}; \
DATA_SET(gdb_dbgport_set, name##_gdb_dbgport)
#endif /* !_GDB_GDB_H_ */

109
sys/gdb/gdb_int.h Normal file
View File

@ -0,0 +1,109 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _GDB_GDB_INT_H_
#define _GDB_GDB_INT_H_
extern struct gdb_dbgport *gdb_cur;
extern char *gdb_rxp;
extern size_t gdb_rxsz;
extern char *gdb_txp;
int gdb_rx_begin(void);
int gdb_rx_equal(const char *);
int gdb_rx_mem(unsigned char *, size_t);
int gdb_rx_varhex(uintmax_t *);
static __inline int
gdb_rx_char(void)
{
int c;
if (gdb_rxsz > 0) {
c = *gdb_rxp++;
gdb_rxsz--;
} else
c = -1;
return (c);
}
void gdb_tx_begin(char);
int gdb_tx_end(void);
int gdb_tx_mem(const unsigned char *, size_t);
void gdb_tx_reg(int);
static __inline void
gdb_tx_char(char c)
{
*gdb_txp++ = c;
}
static __inline int
gdb_tx_empty(void)
{
gdb_tx_begin('\0');
return (gdb_tx_end());
}
static __inline void
gdb_tx_hex(uintmax_t n, int sz)
{
gdb_txp += sprintf(gdb_txp, "%0*jx", sz, n);
}
static __inline int
gdb_tx_err(int err)
{
gdb_tx_begin('E');
gdb_tx_hex(err, 2);
return (gdb_tx_end());
}
static __inline int
gdb_tx_ok(void)
{
gdb_tx_begin('O');
gdb_tx_char('K');
return (gdb_tx_end());
}
static __inline void
gdb_tx_str(const char *s)
{
while (*s)
*gdb_txp++ = *s++;
}
static __inline void
gdb_tx_varhex(uintmax_t n)
{
gdb_txp += sprintf(gdb_txp, "%jx", n);
}
#endif /* !_GDB_GDB_INT_H_ */

261
sys/gdb/gdb_main.c Normal file
View File

@ -0,0 +1,261 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/pcpu.h>
#include <sys/proc.h>
#include <sys/reboot.h>
#include <machine/gdb_machdep.h>
#include <machine/kdb.h>
#include <gdb/gdb.h>
#include <gdb/gdb_int.h>
static dbbe_init_f gdb_init;
static dbbe_trap_f gdb_trap;
KDB_BACKEND(gdb, gdb_init, NULL, gdb_trap);
GDB_DBGPORT(null, NULL, NULL, NULL, NULL, NULL, NULL);
SET_DECLARE(gdb_dbgport_set, struct gdb_dbgport);
struct gdb_dbgport *gdb_cur = NULL;
static int
gdb_init(void)
{
struct gdb_dbgport *dp, **iter;
int cur_pri, pri;
gdb_cur = NULL;
cur_pri = -1;
SET_FOREACH(iter, gdb_dbgport_set) {
dp = *iter;
pri = (dp->gdb_probe != NULL) ? dp->gdb_probe() : -1;
dp->gdb_active = (pri >= 0) ? 0 : -1;
if (pri > cur_pri) {
cur_pri = pri;
gdb_cur = dp;
}
}
if (gdb_cur != NULL) {
printf("GDB: debug ports:");
SET_FOREACH(iter, gdb_dbgport_set) {
dp = *iter;
if (dp->gdb_active == 0)
printf(" %s", dp->gdb_name);
}
printf("\n");
} else
printf("GDB: no debug ports present\n");
if (gdb_cur != NULL) {
gdb_cur->gdb_init();
printf("GDB: current port: %s\n", gdb_cur->gdb_name);
}
if (gdb_cur != NULL)
cur_pri = (boothowto & RB_GDB) ? 2 : 0;
else
cur_pri = -1;
return (cur_pri);
}
static int
gdb_trap(int type, int code)
{
struct thread *thr_iter;
/*
* Send a T packet. We currently do not support watchpoints (the
* awatch, rwatch or watch elements).
*/
gdb_tx_begin('T');
gdb_tx_hex(gdb_cpu_signal(type, code), 2);
gdb_tx_varhex(GDB_REG_PC);
gdb_tx_char(':');
gdb_tx_reg(GDB_REG_PC);
gdb_tx_char(';');
gdb_tx_str("thread:");
gdb_tx_varhex((long)kdb_thread->td_tid);
gdb_tx_char(';');
gdb_tx_end(); /* XXX check error condition. */
thr_iter = NULL;
while (gdb_rx_begin() == 0) {
printf("GDB: got '%s'\n", gdb_rxp);
switch (gdb_rx_char()) {
case '?': /* Last signal. */
gdb_tx_begin('S');
gdb_tx_hex(gdb_cpu_signal(type, code), 2);
gdb_tx_end();
break;
case 'c': { /* Continue. */
uintmax_t addr;
if (!gdb_rx_varhex(&addr))
gdb_cpu_setreg(GDB_REG_PC, addr);
kdb_cpu_clear_singlestep();
return (1);
}
case 'C': { /* Continue with signal. */
uintmax_t addr, sig;
if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' &&
!gdb_rx_varhex(&addr))
gdb_cpu_setreg(GDB_REG_PC, addr);
kdb_cpu_clear_singlestep();
return (1);
}
case 'g': { /* Read registers. */
size_t r;
gdb_tx_begin(0);
for (r = 0; r < GDB_NREGS; r++)
gdb_tx_reg(r);
gdb_tx_end();
break;
}
case 'G': /* Write registers. */
gdb_tx_err(0);
break;
case 'H': { /* Set thread. */
intmax_t tid;
struct thread *thr;
gdb_rx_char();
gdb_rx_varhex(&tid);
if (tid > 0) {
thr = kdb_thr_lookup(tid);
if (thr == NULL) {
gdb_tx_err(ENOENT);
break;
}
kdb_thr_select(thr);
}
gdb_tx_ok();
break;
}
case 'k': /* Kill request. */
kdb_cpu_clear_singlestep();
return (1);
case 'm': { /* Read memory. */
uintmax_t addr, size;
if (gdb_rx_varhex(&addr) || gdb_rx_char() != ',' ||
gdb_rx_varhex(&size)) {
gdb_tx_err(EINVAL);
break;
}
gdb_tx_begin(0);
if (gdb_tx_mem((char *)(uintptr_t)addr, size))
gdb_tx_end();
else
gdb_tx_err(EIO);
break;
}
case 'M': { /* Write memory. */
uintmax_t addr, size;
if (gdb_rx_varhex(&addr) || gdb_rx_char() != ',' ||
gdb_rx_varhex(&size) || gdb_rx_char() != ':') {
gdb_tx_err(EINVAL);
break;
}
if (gdb_rx_mem((char *)(uintptr_t)addr, size) == 0)
gdb_tx_err(EIO);
else
gdb_tx_ok();
break;
}
case 'P': { /* Write register. */
uintmax_t reg, val;
if (gdb_rx_varhex(&reg) || gdb_rx_char() != '=' ||
gdb_rx_varhex(&val)) {
gdb_tx_err(EINVAL);
break;
}
gdb_cpu_setreg(reg, val);
gdb_tx_ok();
break;
}
case 'q': /* General query. */
if (gdb_rx_equal("fThreadInfo")) {
thr_iter = kdb_thr_first();
gdb_tx_begin('m');
gdb_tx_hex((long)thr_iter->td_tid, 8);
gdb_tx_end();
} else if (gdb_rx_equal("sThreadInfo")) {
if (thr_iter == NULL) {
gdb_tx_err(ENXIO);
break;
}
thr_iter = kdb_thr_next(thr_iter);
if (thr_iter != NULL) {
gdb_tx_begin('m');
gdb_tx_hex((long)thr_iter->td_tid, 8);
gdb_tx_end();
} else {
gdb_tx_begin('l');
gdb_tx_end();
}
} else if (!gdb_cpu_query())
gdb_tx_empty();
break;
case 's': { /* Step. */
uintmax_t addr;
if (!gdb_rx_varhex(&addr))
gdb_cpu_setreg(GDB_REG_PC, addr);
kdb_cpu_set_singlestep();
return (1);
}
case 'S': { /* Step with signal. */
uintmax_t addr, sig;
if (!gdb_rx_varhex(&sig) && gdb_rx_char() == ';' &&
!gdb_rx_varhex(&addr))
gdb_cpu_setreg(GDB_REG_PC, addr);
kdb_cpu_set_singlestep();
return (1);
}
case 'T': { /* Thread alive. */
intmax_t tid;
gdb_rx_varhex(&tid);
if (kdb_thr_lookup(tid) != NULL)
gdb_tx_ok();
else
gdb_tx_err(ENOENT);
break;
}
case -1:
/* Empty command. Treat as unknown command. */
/* FALLTHROUGH */
default:
/* Unknown command. Send empty response. */
gdb_tx_empty();
break;
}
}
return (0);
}

289
sys/gdb/gdb_packet.c Normal file
View File

@ -0,0 +1,289 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/ctype.h>
#include <sys/kdb.h>
#include <machine/gdb_machdep.h>
#include <gdb/gdb.h>
#include <gdb/gdb_int.h>
static char gdb_rxbuf[GDB_BUFSZ];
char *gdb_rxp = NULL;
size_t gdb_rxsz = 0;
static char gdb_txbuf[GDB_BUFSZ];
char *gdb_txp = NULL; /* Used in inline functions. */
#define C2N(c) (((c) < 'A') ? (c) - '0' : \
10 + (((c) < 'a') ? (c) - 'A' : (c) - 'a'))
#define N2C(n) (((n) < 10) ? (n) + '0' : (n) + 'a' - 10)
/*
* Functions to receive and extract from a packet.
*/
int
gdb_rx_begin(void)
{
int c, cksum;
gdb_rxp = NULL;
do {
/*
* Wait for the start character, ignore all others.
* XXX needs a timeout.
*/
while ((c = gdb_cur->gdb_getc()) != '$')
;
/* Read until a # or end of buffer is found. */
cksum = 0;
gdb_rxsz = 0;
while (gdb_rxsz < sizeof(gdb_rxbuf) - 1) {
c = gdb_cur->gdb_getc();
if (c == '#')
break;
gdb_rxbuf[gdb_rxsz++] = c;
cksum += c;
}
gdb_rxbuf[gdb_rxsz] = 0;
cksum &= 0xff;
/* Bail out on a buffer overflow. */
if (c != '#') {
gdb_cur->gdb_putc('-');
return (ENOSPC);
}
c = gdb_cur->gdb_getc();
cksum -= (C2N(c) << 4) & 0xf0;
c = gdb_cur->gdb_getc();
cksum -= C2N(c) & 0x0f;
gdb_cur->gdb_putc((cksum == 0) ? '+' : '-');
if (cksum != 0)
printf("GDB: packet `%s' has invalid checksum\n",
gdb_rxbuf);
} while (cksum != 0);
gdb_rxp = gdb_rxbuf;
return (0);
}
int
gdb_rx_equal(const char *str)
{
int len;
len = strlen(str);
if (len > gdb_rxsz || strncmp(str, gdb_rxp, len) != 0)
return (0);
gdb_rxp += len;
gdb_rxsz -= len;
return (1);
}
int
gdb_rx_mem(unsigned char *addr, size_t size)
{
void *prev;
jmp_buf jb;
int ret;
unsigned char c;
if (size * 2 != gdb_rxsz)
return (-1);
prev = kdb_jmpbuf(jb);
ret = setjmp(jb);
if (ret == 0) {
while (size-- > 0) {
c = (C2N(gdb_rxp[0]) << 4) & 0xf0;
c |= C2N(gdb_rxp[1]) & 0x0f;
*addr++ = c;
gdb_rxsz -= 2;
gdb_rxp += 2;
}
}
(void)kdb_jmpbuf(prev);
return ((ret == 0) ? 1 : 0);
}
int
gdb_rx_varhex(uintmax_t *vp)
{
uintmax_t v;
int c, neg;
c = gdb_rx_char();
neg = (c == '-') ? 1 : 0;
if (neg == 1)
c = gdb_rx_char();
if (!isxdigit(c)) {
gdb_rxp -= ((c == -1) ? 0 : 1) + neg;
gdb_rxsz += ((c == -1) ? 0 : 1) + neg;
return (-1);
}
v = 0;
do {
v <<= 4;
v += C2N(c);
c = gdb_rx_char();
} while (isxdigit(c));
if (c != -1) {
gdb_rxp--;
gdb_rxsz++;
}
*vp = (neg) ? -v : v;
return (0);
}
/*
* Function to build and send a package.
*/
void
gdb_tx_begin(char tp)
{
gdb_txp = gdb_txbuf;
if (tp != '\0')
gdb_tx_char(tp);
}
int
gdb_tx_end(void)
{
const char *p;
int runlen;
unsigned char c, cksum;
do {
gdb_cur->gdb_putc('$');
cksum = 0;
p = gdb_txbuf;
while (p < gdb_txp) {
/* Send a character and start run-length encoding. */
c = *p++;
gdb_cur->gdb_putc(c);
cksum += c;
runlen = 0;
/* Determine run-length and update checksum. */
while (p < gdb_txp && *p == c) {
runlen++;
p++;
}
/* Emit the run-length encoded string. */
while (runlen >= 97) {
gdb_cur->gdb_putc('*');
cksum += '*';
gdb_cur->gdb_putc(97+29);
cksum += 97+29;
runlen -= 97;
if (runlen > 0) {
gdb_cur->gdb_putc(c);
cksum += c;
runlen--;
}
}
if (runlen == 1) {
gdb_cur->gdb_putc(c);
cksum += c;
runlen--;
}
if (runlen == 0)
continue;
/* Don't emit '$', '#', '+' or '-'. */
if (runlen == 7) {
gdb_cur->gdb_putc(c);
cksum += c;
runlen--;
}
if (runlen == 6 || runlen == 14 || runlen == 16) {
gdb_cur->gdb_putc(c);
cksum += c;
runlen--;
}
gdb_cur->gdb_putc('*');
cksum += '*';
gdb_cur->gdb_putc(runlen+29);
cksum += runlen+29;
}
gdb_cur->gdb_putc('#');
c = cksum >> 4;
gdb_cur->gdb_putc(N2C(c));
c = cksum & 0x0f;
gdb_cur->gdb_putc(N2C(c));
c = gdb_cur->gdb_getc();
} while (c != '+');
return (0);
}
int
gdb_tx_mem(const unsigned char *addr, size_t size)
{
void *prev;
jmp_buf jb;
int ret;
prev = kdb_jmpbuf(jb);
ret = setjmp(jb);
if (ret == 0) {
while (size-- > 0) {
*gdb_txp++ = N2C(*addr >> 4);
*gdb_txp++ = N2C(*addr & 0x0f);
addr++;
}
}
(void)kdb_jmpbuf(prev);
return ((ret == 0) ? 1 : 0);
}
void
gdb_tx_reg(int regnum)
{
unsigned char *regp;
size_t regsz;
regp = gdb_cpu_getreg(regnum, &regsz);
if (regp == NULL) {
/* Register unavailable. */
while (regsz--) {
gdb_tx_char('x');
gdb_tx_char('x');
}
} else
gdb_tx_mem(regp, regsz);
}

View File

@ -0,0 +1,90 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/signal.h>
#include <machine/gdb_machdep.h>
#include <machine/pcb.h>
#include <machine/trap.h>
#include <gdb/gdb.h>
void *
gdb_cpu_getreg(int regnum, size_t *regsz)
{
*regsz = gdb_cpu_regsz(regnum);
switch (regnum) {
case 3: return (&kdb_thrctx->pcb_ebx);
case 4: return (&kdb_thrctx->pcb_esp);
case 5: return (&kdb_thrctx->pcb_ebp);
case 6: return (&kdb_thrctx->pcb_esi);
case 7: return (&kdb_thrctx->pcb_edi);
case 8: return (&kdb_thrctx->pcb_eip);
}
return (NULL);
}
void
gdb_cpu_setreg(int regnum, register_t val)
{
switch (regnum) {
case GDB_REG_PC: kdb_thrctx->pcb_eip = val; break;
}
}
int
gdb_cpu_signal(int type, int code)
{
switch (type & ~T_USER) {
case 0: return (SIGFPE); /* Divide by zero. */
case 1: return (SIGTRAP); /* Debug exception. */
case 3: return (SIGTRAP); /* Breakpoint. */
case 4: return (SIGURG); /* into instr. (overflow). */
case 5: return (SIGURG); /* bound instruction. */
case 6: return (SIGILL); /* Invalid opcode. */
case 7: return (SIGFPE); /* Coprocessor not present. */
case 8: return (SIGEMT); /* Double fault. */
case 9: return (SIGSEGV); /* Coprocessor segment overrun. */
case 10: return (SIGTRAP); /* Invalid TSS (also single-step). */
case 11: return (SIGSEGV); /* Segment not present. */
case 12: return (SIGSEGV); /* Stack exception. */
case 13: return (SIGSEGV); /* General protection. */
case 14: return (SIGSEGV); /* Page fault. */
case 16: return (SIGEMT); /* Coprocessor error. */
}
return (SIGEMT);
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_GDB_MACHDEP_H_
#define _MACHINE_GDB_MACHDEP_H_
#define GDB_BUFSZ 400
#define GDB_NREGS 14
#define GDB_REG_PC 8
static __inline size_t
gdb_cpu_regsz(int regnum __unused)
{
return (sizeof(int));
}
static __inline int
gdb_cpu_query(void)
{
return (0);
}
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, register_t);
int gdb_cpu_signal(int, int);
#endif /* !_MACHINE_GDB_MACHDEP_H_ */

177
sys/ia64/ia64/gdb_machdep.c Normal file
View File

@ -0,0 +1,177 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/signal.h>
#include <machine/gdb_machdep.h>
#include <machine/md_var.h>
#include <machine/pcb.h>
#include <machine/reg.h>
#include <gdb/gdb.h>
#include <gdb/gdb_int.h>
void *
gdb_cpu_getreg(int regnum, size_t *regsz)
{
static uint64_t synth;
uint64_t cfm;
*regsz = gdb_cpu_regsz(regnum);
switch (regnum) {
/* Registers 0-127: general registers. */
case 1: return (&kdb_thrctx->pcb_special.gp);
case 4: return (&kdb_thrctx->pcb_preserved.gr4);
case 5: return (&kdb_thrctx->pcb_preserved.gr5);
case 6: return (&kdb_thrctx->pcb_preserved.gr6);
case 7: return (&kdb_thrctx->pcb_preserved.gr7);
case 12: return (&kdb_thrctx->pcb_special.sp);
case 13: return (&kdb_thrctx->pcb_special.tp);
/* Registers 128-255: floating-point registers. */
case 130: return (&kdb_thrctx->pcb_preserved_fp.fr2);
case 131: return (&kdb_thrctx->pcb_preserved_fp.fr3);
case 132: return (&kdb_thrctx->pcb_preserved_fp.fr4);
case 133: return (&kdb_thrctx->pcb_preserved_fp.fr5);
case 144: return (&kdb_thrctx->pcb_preserved_fp.fr16);
case 145: return (&kdb_thrctx->pcb_preserved_fp.fr17);
case 146: return (&kdb_thrctx->pcb_preserved_fp.fr18);
case 147: return (&kdb_thrctx->pcb_preserved_fp.fr19);
case 148: return (&kdb_thrctx->pcb_preserved_fp.fr20);
case 149: return (&kdb_thrctx->pcb_preserved_fp.fr21);
case 150: return (&kdb_thrctx->pcb_preserved_fp.fr22);
case 151: return (&kdb_thrctx->pcb_preserved_fp.fr23);
case 152: return (&kdb_thrctx->pcb_preserved_fp.fr24);
case 153: return (&kdb_thrctx->pcb_preserved_fp.fr25);
case 154: return (&kdb_thrctx->pcb_preserved_fp.fr26);
case 155: return (&kdb_thrctx->pcb_preserved_fp.fr27);
case 156: return (&kdb_thrctx->pcb_preserved_fp.fr28);
case 157: return (&kdb_thrctx->pcb_preserved_fp.fr29);
case 158: return (&kdb_thrctx->pcb_preserved_fp.fr30);
case 159: return (&kdb_thrctx->pcb_preserved_fp.fr31);
/* Registers 320-327: branch registers. */
case 320:
if (kdb_thrctx->pcb_special.__spare == ~0UL)
return (&kdb_thrctx->pcb_special.rp);
break;
case 321: return (&kdb_thrctx->pcb_preserved.br1);
case 322: return (&kdb_thrctx->pcb_preserved.br2);
case 323: return (&kdb_thrctx->pcb_preserved.br3);
case 324: return (&kdb_thrctx->pcb_preserved.br4);
case 325: return (&kdb_thrctx->pcb_preserved.br5);
/* Registers 328-333: misc. other registers. */
case 330: return (&kdb_thrctx->pcb_special.pr);
case 331:
if (kdb_thrctx->pcb_special.__spare == ~0UL) {
synth = kdb_thrctx->pcb_special.iip;
synth += (kdb_thrctx->pcb_special.psr >> 41) & 3;
return (&synth);
}
return (&kdb_thrctx->pcb_special.rp);
case 333:
if (kdb_thrctx->pcb_special.__spare == ~0UL)
return (&kdb_thrctx->pcb_special.cfm);
return (&kdb_thrctx->pcb_special.pfs);
/* Registers 334-461: application registers. */
case 350: return (&kdb_thrctx->pcb_special.rsc);
case 351: /* bsp */
case 352: /* bspstore. */
synth = kdb_thrctx->pcb_special.bspstore;
if (kdb_thrctx->pcb_special.__spare == ~0UL) {
synth += kdb_thrctx->pcb_special.ndirty;
} else {
cfm = kdb_thrctx->pcb_special.pfs;
synth = ia64_bsp_adjust(synth,
IA64_CFM_SOF(cfm) - IA64_CFM_SOL(cfm));
}
return (&synth);
case 353: return (&kdb_thrctx->pcb_special.rnat);
case 370: return (&kdb_thrctx->pcb_special.unat);
case 374: return (&kdb_thrctx->pcb_special.fpsr);
case 398:
if (kdb_thrctx->pcb_special.__spare == ~0UL)
return (&kdb_thrctx->pcb_special.pfs);
break;
case 399: return (&kdb_thrctx->pcb_preserved.lc);
}
return (NULL);
}
void
gdb_cpu_setreg(int regnum, register_t val)
{
switch (regnum) {
case GDB_REG_PC: break;
}
}
int
gdb_cpu_query(void)
{
#if 0
uint64_t bspstore, *kstack;
#endif
uintmax_t slot;
if (!gdb_rx_equal("Part:dirty:read::"))
return (0);
if (gdb_rx_varhex(&slot) < 0) {
gdb_tx_err(EINVAL);
return (-1);
}
gdb_tx_err(EINVAL);
return (-1);
#if 0
/* slot is unsigned. No need to test for negative values. */
if (slot >= (kdb_frame->tf_special.ndirty >> 3)) {
return (-1);
}
/*
* If the trapframe describes a kernel entry, bspstore holds
* the address of the user backing store. Calculate the right
* kernel stack address. See also ptrace_machdep().
*/
bspstore = kdb_frame->tf_special.bspstore;
kstack = (bspstore >= IA64_RR_BASE(5)) ? (uint64_t*)bspstore :
(uint64_t*)(kdb_thread->td_kstack + (bspstore & 0x1ffUL));
gdb_tx_begin('\0');
gdb_tx_mem((void*)(kstack + slot), 8);
gdb_tx_end();
return (1);
#endif
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_GDB_MACHDEP_H_
#define _MACHINE_GDB_MACHDEP_H_
#define GDB_NREGS 462
#define GDB_REG_PC 331
#define GDB_BUFSZ (GDB_NREGS*16+128*16)
static __inline size_t
gdb_cpu_regsz(int regnum)
{
return ((regnum >= 128 && regnum < 256) ? 16 : 8);
}
static __inline int
gdb_cpu_signal(int vector, int dummy __unused)
{
/* Add 100 so GDB won't translate the vector into signal names. */
return (vector + 100);
}
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, register_t);
int gdb_cpu_query(void);
#endif /* !_MACHINE_GDB_MACHDEP_H_ */

View File

@ -0,0 +1,57 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* $FreeBSD$
*/
#ifndef _MACHINE_GDB_MACHDEP_H_
#define _MACHINE_GDB_MACHDEP_H_
#define GDB_BUFSZ 600
#define GDB_NREGS 86
#define GDB_REG_PC 80
static __inline size_t
gdb_cpu_regsz(int regnum)
{
return ((regnum >= 32 && regnum < 64) ? sizeof(float) : sizeof(long));
}
static __inline int
gdb_cpu_query(void)
{
return (0);
}
static __inline int
gdb_cpu_signal(int vector, int _)
{
return (vector);
}
void *gdb_cpu_getreg(int, size_t *);
void gdb_cpu_setreg(int, register_t);
#endif /* !_MACHINE_GDB_MACHDEP_H_ */

View File

@ -0,0 +1,70 @@
/*
* Copyright (c) 2004 Marcel Moolenaar
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kdb.h>
#include <sys/kernel.h>
#include <sys/signal.h>
#include <machine/asm.h>
#include <machine/gdb_machdep.h>
#include <machine/pcb.h>
#include <machine/reg.h>
#include <gdb/gdb.h>
void *
gdb_cpu_getreg(int regnum, size_t *regsz)
{
static uint64_t synth;
*regsz = gdb_cpu_regsz(regnum);
switch (regnum) {
/* 0-7: g0-g7 */
/* 8-15: o0-o7 */
case 14:
synth = kdb_thrctx->pcb_sp - CCFSZ;
return (&synth);
/* 16-23: l0-l7 */
/* 24-31: i0-i7 */
case 30: return (&kdb_thrctx->pcb_sp);
/* 32-63: f0-f31 */
/* 64-79: f32-f62 (16 double FP) */
case 80: return (&kdb_thrctx->pcb_pc);
}
return (NULL);
}
void
gdb_cpu_setreg(int regnum, register_t val)
{
switch (regnum) {
}
}