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: Ingo Molnar <mingo@elte.hu> Signed-off-by: Frederic Weisbecker <fweisbec@gmail.com> Cc: "K. Prasad" <prasad@linux.vnet.ibm.com>
This commit is contained in:
parent
676c0dbe6e
commit
9f6b3c2c30
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <linux/user.h>
|
||||
#include <linux/elfcore.h>
|
||||
#include <asm/debugreg.h>
|
||||
|
||||
/*
|
||||
* 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)
|
|||
>> PAGE_SHIFT;
|
||||
dump->u_dsize -= dump->u_tsize;
|
||||
dump->u_ssize = 0;
|
||||
dump->u_debugreg[0] = current->thread.debugreg[0];
|
||||
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;
|
||||
aout_dump_debugregs(dump);
|
||||
|
||||
if (dump->start_stack < TASK_SIZE)
|
||||
dump->u_ssize = ((unsigned long)(TASK_SIZE - dump->start_stack))
|
||||
|
|
|
@ -89,6 +89,8 @@ static inline void hw_breakpoint_disable(void)
|
|||
set_debugreg(0UL, 3);
|
||||
}
|
||||
|
||||
extern void aout_dump_debugregs(struct user *dump);
|
||||
|
||||
#ifdef CONFIG_KVM
|
||||
extern void hw_breakpoint_restore(void);
|
||||
#endif
|
||||
|
|
|
@ -375,6 +375,41 @@ int arch_validate_hwbkpt_settings(struct perf_event *bp,
|
|||
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 = ¤t->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
|
||||
*/
|
||||
|
|
Loading…
Reference in a new issue