15 #include <linux/capability.h>
16 #include <linux/elf.h>
17 #include <linux/elfcore.h>
22 #include <linux/slab.h>
23 #include <asm/uaccess.h>
25 #include <linux/list.h>
28 #include <asm/sections.h>
30 #define CORE_STR "CORE"
32 #ifndef ELF_CORE_EFLAGS
33 #define ELF_CORE_EFLAGS 0
39 #ifndef kc_vaddr_to_offset
40 #define kc_vaddr_to_offset(v) ((v) - PAGE_OFFSET)
42 #ifndef kc_offset_to_vaddr
43 #define kc_offset_to_vaddr(o) ((o) + PAGE_OFFSET)
57 static int kcore_need_update = 1;
62 new->addr = (
unsigned long)addr;
71 static size_t get_kcore_size(
int *nphdr,
size_t *elf_buflen)
85 *elf_buflen =
sizeof(
struct elfhdr) +
86 (*nphdr + 2)*
sizeof(
struct elf_phdr) +
93 return size + *elf_buflen;
116 if (kcore_need_update) {
120 list_move(&pos->
list, &garbage);
122 list_splice_tail(list, &kclist_head);
124 list_splice(list, &garbage);
125 kcore_need_update = 0;
126 proc_root_kcore->
size = get_kcore_size(&nphdr, &size);
129 free_kclist_ents(&garbage);
133 #ifdef CONFIG_HIGHMEM
139 static int kcore_update_ram(
void)
152 __kcore_update_ram(&
head);
158 #ifdef CONFIG_SPARSEMEM_VMEMMAP
202 kclist_add_private(
unsigned long pfn,
unsigned long nr_pages,
void *
arg)
214 if (ent->
addr < (
unsigned long)
__va(0))
232 if (!get_sparsemem_vmemmap_info(ent, head)) {
243 static int kcore_update_ram(
void)
246 unsigned long end_pfn;
253 unsigned long node_end;
254 node_end =
NODE_DATA(nid)->node_start_pfn +
256 if (end_pfn < node_end)
262 free_kclist_ents(&head);
265 __kcore_update_ram(&head);
289 static char *storenote(
struct memelfnote *men,
char *bufp)
293 #define DUMP_WRITE(addr,nr) do { memcpy(bufp,addr,nr); bufp += nr; } while(0)
296 en.n_descsz = men->
datasz;
297 en.n_type = men->
type;
303 bufp = (
char*)
roundup((
unsigned long)bufp,4);
305 bufp = (
char*)
roundup((
unsigned long)bufp,4);
316 static void elf_kcore_store_hdr(
char *bufp,
int nphdr,
int dataoff)
327 elf = (
struct elfhdr *) bufp;
328 bufp +=
sizeof(
struct elfhdr);
329 offset +=
sizeof(
struct elfhdr);
340 elf->e_phoff =
sizeof(
struct elfhdr);
343 elf->e_ehsize =
sizeof(
struct elfhdr);
344 elf->e_phentsize=
sizeof(
struct elf_phdr);
345 elf->e_phnum = nphdr;
374 phdr->p_filesz = phdr->p_memsz = m->
size;
388 notes[0].data = &prstatus;
392 nhdr->p_filesz = notesize(¬es[0]);
393 bufp = storenote(¬es[0], bufp);
399 notes[1].data = &prpsinfo;
402 prpsinfo.pr_state = 0;
403 prpsinfo.pr_sname =
'R';
404 prpsinfo.pr_zomb = 0;
406 strcpy(prpsinfo.pr_fname,
"vmlinux");
409 nhdr->p_filesz += notesize(¬es[1]);
410 bufp = storenote(¬es[1], bufp);
418 nhdr->p_filesz += notesize(¬es[2]);
419 bufp = storenote(¬es[2], bufp);
437 size = get_kcore_size(&nphdr, &elf_buflen);
439 if (buflen == 0 || *fpos >= size) {
445 if (buflen > size - *fpos)
446 buflen = size - *fpos;
449 if (*fpos < elf_buflen) {
452 tsz = elf_buflen - *fpos;
460 elf_kcore_store_hdr(elf_buf, nphdr, elf_buflen);
496 if (&m->
list == &kclist_head) {
505 vread(elf_buf, (
char *)start, tsz);
545 static int open_kcore(
struct inode *
inode,
struct file *filp)
549 if (kcore_need_update)
551 if (i_size_read(inode) != proc_root_kcore->
size) {
553 i_size_write(inode, proc_root_kcore->
size);
566 #ifdef CONFIG_MEMORY_HOTPLUG
569 unsigned long action,
void *arg)
575 kcore_need_update = 1;
585 #ifdef CONFIG_ARCH_PROC_KCORE_TEXT
591 static void __init proc_kcore_text_init(
void)
596 static void __init proc_kcore_text_init(
void)
601 #if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
606 static void __init add_modules_range(
void)
612 static void __init add_modules_range(
void)
617 static int __init proc_kcore_init(
void)
619 proc_root_kcore = proc_create(
"kcore",
S_IRUSR,
NULL,
620 &proc_kcore_operations);
621 if (!proc_root_kcore) {
626 proc_kcore_text_init();