forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel…
…/git/jwessel/linux-2.6-kgdb * 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jwessel/linux-2.6-kgdb: debug_core,kdb: fix crash when arch does not have single step kgdb,x86: use macro HBP_NUM to replace magic number 4 kgdb,mips: remove unused kgdb_cpu_doing_single_step operations mm,kdb,kgdb: Add a debug reference for the kdb kmap usage KGDB: Remove set but unused newPC ftrace,kdb: Allow dumping a specific cpu's buffer with ftdump ftrace,kdb: Extend kdb to be able to dump the ftrace buffer kgdb,powerpc: Replace hardcoded offset by BREAK_INSTR_SIZE arm,kgdb: Add ability to trap into debugger on notify_die gdbstub: do not directly use dbg_reg_def[] in gdb_cmd_reg_set() gdbstub: Implement gdbserial 'p' and 'P' packets kgdb,arm: Individual register get/set for arm kgdb,mips: Individual register get/set for mips kgdb,x86: Individual register get/set for x86 kgdb,kdb: individual register set and and get API gdbstub: Optimize kgdb's "thread:" response for the gdb serial protocol kgdb: remove custom hex_to_bin()implementation
- Loading branch information
Showing
16 changed files
with
801 additions
and
316 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,57 +10,62 @@ | |
* Deepak Saxena <[email protected]> | ||
*/ | ||
#include <linux/irq.h> | ||
#include <linux/kdebug.h> | ||
#include <linux/kgdb.h> | ||
#include <asm/traps.h> | ||
|
||
/* Make a local copy of the registers passed into the handler (bletch) */ | ||
void pt_regs_to_gdb_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs) | ||
struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = | ||
{ | ||
int regno; | ||
|
||
/* Initialize all to zero. */ | ||
for (regno = 0; regno < GDB_MAX_REGS; regno++) | ||
gdb_regs[regno] = 0; | ||
{ "r0", 4, offsetof(struct pt_regs, ARM_r0)}, | ||
{ "r1", 4, offsetof(struct pt_regs, ARM_r1)}, | ||
{ "r2", 4, offsetof(struct pt_regs, ARM_r2)}, | ||
{ "r3", 4, offsetof(struct pt_regs, ARM_r3)}, | ||
{ "r4", 4, offsetof(struct pt_regs, ARM_r4)}, | ||
{ "r5", 4, offsetof(struct pt_regs, ARM_r5)}, | ||
{ "r6", 4, offsetof(struct pt_regs, ARM_r6)}, | ||
{ "r7", 4, offsetof(struct pt_regs, ARM_r7)}, | ||
{ "r8", 4, offsetof(struct pt_regs, ARM_r8)}, | ||
{ "r9", 4, offsetof(struct pt_regs, ARM_r9)}, | ||
{ "r10", 4, offsetof(struct pt_regs, ARM_r10)}, | ||
{ "fp", 4, offsetof(struct pt_regs, ARM_fp)}, | ||
{ "ip", 4, offsetof(struct pt_regs, ARM_ip)}, | ||
{ "sp", 4, offsetof(struct pt_regs, ARM_sp)}, | ||
{ "lr", 4, offsetof(struct pt_regs, ARM_lr)}, | ||
{ "pc", 4, offsetof(struct pt_regs, ARM_pc)}, | ||
{ "f0", 12, -1 }, | ||
{ "f1", 12, -1 }, | ||
{ "f2", 12, -1 }, | ||
{ "f3", 12, -1 }, | ||
{ "f4", 12, -1 }, | ||
{ "f5", 12, -1 }, | ||
{ "f6", 12, -1 }, | ||
{ "f7", 12, -1 }, | ||
{ "fps", 4, -1 }, | ||
{ "cpsr", 4, offsetof(struct pt_regs, ARM_cpsr)}, | ||
}; | ||
|
||
gdb_regs[_R0] = kernel_regs->ARM_r0; | ||
gdb_regs[_R1] = kernel_regs->ARM_r1; | ||
gdb_regs[_R2] = kernel_regs->ARM_r2; | ||
gdb_regs[_R3] = kernel_regs->ARM_r3; | ||
gdb_regs[_R4] = kernel_regs->ARM_r4; | ||
gdb_regs[_R5] = kernel_regs->ARM_r5; | ||
gdb_regs[_R6] = kernel_regs->ARM_r6; | ||
gdb_regs[_R7] = kernel_regs->ARM_r7; | ||
gdb_regs[_R8] = kernel_regs->ARM_r8; | ||
gdb_regs[_R9] = kernel_regs->ARM_r9; | ||
gdb_regs[_R10] = kernel_regs->ARM_r10; | ||
gdb_regs[_FP] = kernel_regs->ARM_fp; | ||
gdb_regs[_IP] = kernel_regs->ARM_ip; | ||
gdb_regs[_SPT] = kernel_regs->ARM_sp; | ||
gdb_regs[_LR] = kernel_regs->ARM_lr; | ||
gdb_regs[_PC] = kernel_regs->ARM_pc; | ||
gdb_regs[_CPSR] = kernel_regs->ARM_cpsr; | ||
char *dbg_get_reg(int regno, void *mem, struct pt_regs *regs) | ||
{ | ||
if (regno >= DBG_MAX_REG_NUM || regno < 0) | ||
return NULL; | ||
|
||
if (dbg_reg_def[regno].offset != -1) | ||
memcpy(mem, (void *)regs + dbg_reg_def[regno].offset, | ||
dbg_reg_def[regno].size); | ||
else | ||
memset(mem, 0, dbg_reg_def[regno].size); | ||
return dbg_reg_def[regno].name; | ||
} | ||
|
||
/* Copy local gdb registers back to kgdb regs, for later copy to kernel */ | ||
void gdb_regs_to_pt_regs(unsigned long *gdb_regs, struct pt_regs *kernel_regs) | ||
int dbg_set_reg(int regno, void *mem, struct pt_regs *regs) | ||
{ | ||
kernel_regs->ARM_r0 = gdb_regs[_R0]; | ||
kernel_regs->ARM_r1 = gdb_regs[_R1]; | ||
kernel_regs->ARM_r2 = gdb_regs[_R2]; | ||
kernel_regs->ARM_r3 = gdb_regs[_R3]; | ||
kernel_regs->ARM_r4 = gdb_regs[_R4]; | ||
kernel_regs->ARM_r5 = gdb_regs[_R5]; | ||
kernel_regs->ARM_r6 = gdb_regs[_R6]; | ||
kernel_regs->ARM_r7 = gdb_regs[_R7]; | ||
kernel_regs->ARM_r8 = gdb_regs[_R8]; | ||
kernel_regs->ARM_r9 = gdb_regs[_R9]; | ||
kernel_regs->ARM_r10 = gdb_regs[_R10]; | ||
kernel_regs->ARM_fp = gdb_regs[_FP]; | ||
kernel_regs->ARM_ip = gdb_regs[_IP]; | ||
kernel_regs->ARM_sp = gdb_regs[_SPT]; | ||
kernel_regs->ARM_lr = gdb_regs[_LR]; | ||
kernel_regs->ARM_pc = gdb_regs[_PC]; | ||
kernel_regs->ARM_cpsr = gdb_regs[_CPSR]; | ||
if (regno >= DBG_MAX_REG_NUM || regno < 0) | ||
return -EINVAL; | ||
|
||
if (dbg_reg_def[regno].offset != -1) | ||
memcpy((void *)regs + dbg_reg_def[regno].offset, mem, | ||
dbg_reg_def[regno].size); | ||
return 0; | ||
} | ||
|
||
void | ||
|
@@ -176,6 +181,33 @@ void kgdb_roundup_cpus(unsigned long flags) | |
local_irq_disable(); | ||
} | ||
|
||
static int __kgdb_notify(struct die_args *args, unsigned long cmd) | ||
{ | ||
struct pt_regs *regs = args->regs; | ||
|
||
if (kgdb_handle_exception(1, args->signr, cmd, regs)) | ||
return NOTIFY_DONE; | ||
return NOTIFY_STOP; | ||
} | ||
static int | ||
kgdb_notify(struct notifier_block *self, unsigned long cmd, void *ptr) | ||
{ | ||
unsigned long flags; | ||
int ret; | ||
|
||
local_irq_save(flags); | ||
ret = __kgdb_notify(ptr, cmd); | ||
local_irq_restore(flags); | ||
|
||
return ret; | ||
} | ||
|
||
static struct notifier_block kgdb_notifier = { | ||
.notifier_call = kgdb_notify, | ||
.priority = -INT_MAX, | ||
}; | ||
|
||
|
||
/** | ||
* kgdb_arch_init - Perform any architecture specific initalization. | ||
* | ||
|
@@ -184,6 +216,11 @@ void kgdb_roundup_cpus(unsigned long flags) | |
*/ | ||
int kgdb_arch_init(void) | ||
{ | ||
int ret = register_die_notifier(&kgdb_notifier); | ||
|
||
if (ret != 0) | ||
return ret; | ||
|
||
register_undef_hook(&kgdb_brkpt_hook); | ||
register_undef_hook(&kgdb_compiled_brkpt_hook); | ||
|
||
|
@@ -200,6 +237,7 @@ void kgdb_arch_exit(void) | |
{ | ||
unregister_undef_hook(&kgdb_brkpt_hook); | ||
unregister_undef_hook(&kgdb_compiled_brkpt_hook); | ||
unregister_die_notifier(&kgdb_notifier); | ||
} | ||
|
||
/* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.