Commit 9f6b3c2c authored by Frederic Weisbecker's avatar Frederic Weisbecker

hw-breakpoints: Fix broken a.out format dump

Fix the broken a.out format dump. For now we only dump the ptrace
breakpoints.

TODO: Dump every perf breakpoints for the current thread, not only
ptrace based ones.
Reported-by: default avatarIngo Molnar <mingo@elte.hu>
Signed-off-by: default avatarFrederic Weisbecker <fweisbec@gmail.com>
Cc: "K. Prasad" <prasad@linux.vnet.ibm.com>
parent 676c0dbe
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
#include <linux/user.h> #include <linux/user.h>
#include <linux/elfcore.h> #include <linux/elfcore.h>
#include <asm/debugreg.h>
/* /*
* fill in the user structure for an a.out core dump * fill in the user structure for an a.out core dump
...@@ -32,14 +33,7 @@ static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump) ...@@ -32,14 +33,7 @@ static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
>> PAGE_SHIFT; >> PAGE_SHIFT;
dump->u_dsize -= dump->u_tsize; dump->u_dsize -= dump->u_tsize;
dump->u_ssize = 0; dump->u_ssize = 0;
dump->u_debugreg[0] = current->thread.debugreg[0]; aout_dump_debugregs(dump);
dump->u_debugreg[1] = current->thread.debugreg[1];
dump->u_debugreg[2] = current->thread.debugreg[2];
dump->u_debugreg[3] = current->thread.debugreg[3];
dump->u_debugreg[4] = 0;
dump->u_debugreg[5] = 0;
dump->u_debugreg[6] = current->thread.debugreg6;
dump->u_debugreg[7] = current->thread.debugreg7;
if (dump->start_stack < TASK_SIZE) if (dump->start_stack < TASK_SIZE)
dump->u_ssize = ((unsigned long)(TASK_SIZE - dump->start_stack)) dump->u_ssize = ((unsigned long)(TASK_SIZE - dump->start_stack))
......
...@@ -89,6 +89,8 @@ static inline void hw_breakpoint_disable(void) ...@@ -89,6 +89,8 @@ static inline void hw_breakpoint_disable(void)
set_debugreg(0UL, 3); set_debugreg(0UL, 3);
} }
extern void aout_dump_debugregs(struct user *dump);
#ifdef CONFIG_KVM #ifdef CONFIG_KVM
extern void hw_breakpoint_restore(void); extern void hw_breakpoint_restore(void);
#endif #endif
......
...@@ -375,6 +375,41 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp, ...@@ -375,6 +375,41 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
return 0; return 0;
} }
/*
* Dump the debug register contents to the user.
* We can't dump our per cpu values because it
* may contain cpu wide breakpoint, something that
* doesn't belong to the current task.
*
* TODO: include non-ptrace user breakpoints (perf)
*/
void aout_dump_debugregs(struct user *dump)
{
int i;
int dr7 = 0;
struct perf_event *bp;
struct arch_hw_breakpoint *info;
struct thread_struct *thread = &current->thread;
for (i = 0; i < HBP_NUM; i++) {
bp = thread->ptrace_bps[i];
if (bp && !bp->attr.disabled) {
dump->u_debugreg[i] = bp->attr.bp_addr;
info = counter_arch_bp(bp);
dr7 |= encode_dr7(i, info->len, info->type);
} else {
dump->u_debugreg[i] = 0;
}
}
dump->u_debugreg[4] = 0;
dump->u_debugreg[5] = 0;
dump->u_debugreg[6] = current->thread.debugreg6;
dump->u_debugreg[7] = dr7;
}
/* /*
* Release the user breakpoints used by ptrace * Release the user breakpoints used by ptrace
*/ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment