From 09cf52ea0f371e16d0c6d016b4f403b3a45a747c Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Tue, 4 Mar 2008 14:28:30 -0800 Subject: [PATCH] --- yaml --- r: 86781 b: refs/heads/master c: d31472b6d4f799a68d877f69b2f843eec5875472 h: refs/heads/master i: 86779: ea608679625c4879ad1b7935e171af30a8a4217a v: v3 --- [refs] | 2 +- trunk/fs/binfmt_elf.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 54d05625b523..2993da85a152 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 938a9204e0df070bfbaac71f6403cebed76763ad +refs/heads/master: d31472b6d4f799a68d877f69b2f843eec5875472 diff --git a/trunk/fs/binfmt_elf.c b/trunk/fs/binfmt_elf.c index 41a958a7585e..5e1a4fb5cacb 100644 --- a/trunk/fs/binfmt_elf.c +++ b/trunk/fs/binfmt_elf.c @@ -1424,6 +1424,18 @@ struct elf_note_info { int thread_notes; }; +/* + * When a regset has a writeback hook, we call it on each thread before + * dumping user memory. On register window machines, this makes sure the + * user memory backing the register data is up to date before we read it. + */ +static void do_thread_regset_writeback(struct task_struct *task, + const struct user_regset *regset) +{ + if (regset->writeback) + regset->writeback(task, regset, 1); +} + static int fill_thread_core_info(struct elf_thread_core_info *t, const struct user_regset_view *view, long signr, size_t *total) @@ -1445,6 +1457,8 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, sizeof(t->prstatus), &t->prstatus); *total += notesize(&t->notes[0]); + do_thread_regset_writeback(t->task, &view->regsets[0]); + /* * Each other regset might generate a note too. For each regset * that has no core_note_type or is inactive, we leave t->notes[i] @@ -1452,6 +1466,7 @@ static int fill_thread_core_info(struct elf_thread_core_info *t, */ for (i = 1; i < view->n; ++i) { const struct user_regset *regset = &view->regsets[i]; + do_thread_regset_writeback(t->task, regset); if (regset->core_note_type && (!regset->active || regset->active(t->task, regset))) { int ret;