There are several methods to get register values for active tasks such as note
information and exception frames on kernel stacks. This is the preparation
patch to support such features abstracting them as the feature collecting
active registers.
Signed-off-by: HATAYAMA Daisuke <d.hatayama(a)jp.fujitsu.com>
---
src/libgcore/gcore_x86.c | 41 ++++++++++++++++++++---------------------
1 files changed, 20 insertions(+), 21 deletions(-)
diff --git a/src/libgcore/gcore_x86.c b/src/libgcore/gcore_x86.c
index 781ee38..377df6d 100644
--- a/src/libgcore/gcore_x86.c
+++ b/src/libgcore/gcore_x86.c
@@ -1354,30 +1354,29 @@ static ulong gcore_x86_64_get_cpu__pda_oldrsp(int cpu)
return oldrsp;
}
+static int get_active_regs(struct task_context *target,
+ struct user_regs_struct *regs)
+{
+ if (get_netdump_arch() != EM_NONE) {
+ struct user_regs_struct *note = get_regs_from_elf_notes(target);
+ memcpy(regs, note, sizeof(struct user_regs_struct));
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
static int genregs_get(struct task_context *target,
const struct user_regset *regset,
unsigned int size, void *buf)
{
struct user_regs_struct *regs = (struct user_regs_struct *)buf;
- struct user_regs_struct note_regs;
+ struct user_regs_struct active_regs;
const int active = is_task_active(target->task);
- /*
- * vmcore generated by kdump contains NT_PRSTATUS including
- * general register values for active tasks.
- */
- if (active && KDUMP_DUMPFILE()) {
- struct user_regs_struct *note_regs_p;
-
- note_regs_p = get_regs_from_elf_notes(target);
- memcpy(¬e_regs, note_regs_p, sizeof(struct user_regs_struct));
-
- /*
- * If the task was in kernel-mode at the kernel crash, note
- * information is not what we would like.
- */
- if (user_mode(¬e_regs)) {
- memcpy(regs, ¬e_regs, sizeof(struct user_regs_struct));
+ if (active && get_active_regs(target, &active_regs)) {
+ if (user_mode(&active_regs)) {
+ memcpy(regs, &active_regs, sizeof(*regs));
return 0;
}
}
@@ -1415,7 +1414,7 @@ static int genregs_get(struct task_context *target,
* entire registers are saved for special system calls.
*/
if (!gxt->is_special_syscall(nr_syscall))
- restore_rest(target->task, (struct pt_regs *)regs, ¬e_regs);
+ restore_rest(target->task, (struct pt_regs *)regs, &active_regs);
/*
* See FIXUP_TOP_OF_STACK in arch/x86/kernel/entry_64.S.
@@ -1437,7 +1436,7 @@ static int genregs_get(struct task_context *target,
/* Exceptions and NMI */
else if (vector < 20) {
restore_rest(target->task, (struct pt_regs *)regs,
- ¬e_regs);
+ &active_regs);
restore_segment_registers(target->task, regs);
}
@@ -1454,14 +1453,14 @@ static int genregs_get(struct task_context *target,
if (!gxt->is_special_ia32_syscall(nr_syscall))
restore_rest(target->task,
(struct pt_regs *)regs,
- ¬e_regs);
+ &active_regs);
restore_segment_registers(target->task, regs);
}
/* Muskable Interrupts */
else if (vector < 256) {
restore_rest(target->task, (struct pt_regs *)regs,
- ¬e_regs);
+ &active_regs);
restore_segment_registers(target->task, regs);
}
--
1.7.4