From: Denys Vlasenko <vda.linux@gmail.com>
To: linux-kernel@vger.kernel.org,
"Jonathan M. Foote" <jmfoote@cert.org>,
"H. J. Lu" <hjl.tools@gmail.com>, Ingo Molnar <mingo@elte.hu>,
"H. Peter Anvin" <hpa@zytor.com>, Andi Kleen <ak@linux.intel.com>
Cc: Oleg Nesterov <oleg@redhat.com>,
Denys Vlasenko <dvlasenk@redhat.com>,
Jan Kratochvil <jan.kratochvil@redhat.com>
Subject: [PATCH v2] Extend core dump note section to contain file names of mapped files
Date: Thu, 12 Jul 2012 21:42:02 +0200 [thread overview]
Message-ID: <201207122142.02137.vda.linux@googlemail.com> (raw)
This note has the following format:
long count -- how many files are mapped
long page_size -- units for file_ofs
array of [COUNT] elements of
long start
long end
long file_ofs
followed by COUNT filenames in ASCII: "FILE1" NUL "FILE2" NUL...
Compared to previous version, code is simplified
as suggested by Oleg Nesterov.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 1b52956..8e60c38 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1372,6 +1372,72 @@ static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
fill_note(note, "CORE", NT_AUXV, i * sizeof(elf_addr_t), auxv);
}
+#define MAX_FILE_NOTE_SIZE (4*1024*1024)
+
+static void fill_files_note(struct memelfnote *note)
+{
+ struct vm_area_struct *vma;
+ struct file *file;
+ unsigned count, word_count, size, remaining;
+ long *data;
+ long *start_end_ofs;
+ char *name;
+
+ count = 0;
+ for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
+ file = vma->vm_file;
+ if (!file)
+ continue;
+ count++;
+ }
+
+ size = count * 64;
+ word_count = 2 + 3 * count;
+ alloc:
+ if (size >= MAX_FILE_NOTE_SIZE) /* paranoia check */
+ goto err;
+ size = round_up(size, PAGE_SIZE);
+ data = vmalloc(size);
+ if (!data)
+ goto err;
+
+ start_end_ofs = data;
+ name = (void*)&start_end_ofs[word_count];
+ remaining = size - word_count * sizeof(long);
+
+ *start_end_ofs++ = count;
+ *start_end_ofs++ = PAGE_SIZE;
+ for (vma = current->mm->mmap; vma != NULL; vma = vma->vm_next) {
+ const char *filename;
+
+ file = vma->vm_file;
+ if (!file)
+ continue;
+ filename = d_path(&file->f_path, name, remaining);
+ if (IS_ERR(filename)) {
+ if (PTR_ERR(filename) == -ENAMETOOLONG) {
+ vfree(data);
+ size = size * 5 / 4;
+ goto alloc;
+ }
+ /* continue; - WRONG, we must have COUNT elements */
+ filename = "";
+ }
+ /* d_path() fills at the end, move it to front */
+ do
+ remaining--;
+ while ((*name++ = *filename++) != '\0');
+
+ *start_end_ofs++ = vma->vm_start;
+ *start_end_ofs++ = vma->vm_end;
+ *start_end_ofs++ = vma->vm_pgoff;
+ }
+
+ size = name - (char*)data;
+ fill_note(note, "CORE", NT_FILE, size, data);
+ err: ;
+}
+
#ifdef CORE_DUMP_USE_REGSET
#include <linux/regset.h>
@@ -1386,6 +1452,7 @@ struct elf_note_info {
struct elf_thread_core_info *thread;
struct memelfnote psinfo;
struct memelfnote auxv;
+ struct memelfnote files;
size_t size;
int thread_notes;
};
@@ -1562,6 +1629,9 @@ static int fill_note_info(struct elfhdr *elf, int phdrs,
fill_auxv_note(&info->auxv, current->mm);
info->size += notesize(&info->auxv);
+ fill_files_note(&info->files);
+ info->size += notesize(&info->files);
+
return 1;
}
@@ -1590,6 +1660,8 @@ static int write_note_info(struct elf_note_info *info,
return 0;
if (first && !writenote(&info->auxv, file, foffset))
return 0;
+ if (first && !writenote(&info->files, file, foffset))
+ return 0;
for (i = 1; i < info->thread_notes; ++i)
if (t->notes[i].data &&
@@ -1616,6 +1688,7 @@ static void free_note_info(struct elf_note_info *info)
kfree(t);
}
kfree(info->psinfo.data);
+ vfree(info->files.data);
}
#else
diff --git a/include/linux/elf.h b/include/linux/elf.h
index 999b4f5..5e6c08f 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -372,6 +372,7 @@ typedef struct elf64_shdr {
#define NT_PRPSINFO 3
#define NT_TASKSTRUCT 4
#define NT_AUXV 6
+#define NT_FILE 0x46494c45
#define NT_PRXFPREG 0x46e62b7f /* copied from gdb5.1/include/elf/common.h */
#define NT_PPC_VMX 0x100 /* PowerPC Altivec/VMX registers */
#define NT_PPC_SPE 0x101 /* PowerPC SPE/EVR registers */
next reply other threads:[~2012-07-12 19:42 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-07-12 19:42 Denys Vlasenko [this message]
2012-07-13 14:58 ` [PATCH v2] Extend core dump note section to contain file names of mapped files Oleg Nesterov
2012-07-13 15:56 ` Andi Kleen
2012-07-13 17:20 ` Oleg Nesterov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=201207122142.02137.vda.linux@googlemail.com \
--to=vda.linux@gmail.com \
--cc=ak@linux.intel.com \
--cc=dvlasenk@redhat.com \
--cc=hjl.tools@gmail.com \
--cc=hpa@zytor.com \
--cc=jan.kratochvil@redhat.com \
--cc=jmfoote@cert.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=oleg@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.