linux/fs/proc/kcore.c

// SPDX-License-Identifier: GPL-2.0
/*
 *	fs/proc/kcore.c kernel ELF core dumper
 *
 *	Modelled on fs/exec.c:aout_core_dump()
 *	Jeremy Fitzhardinge <[email protected]>
 *	ELF version written by David Howells <[email protected]>
 *	Modified and incorporated into 2.3.x by Tigran Aivazian <[email protected]>
 *	Support to dump vmalloc'd areas (ELF only), Tigran Aivazian <[email protected]>
 *	Safe accesses to vmalloc/direct-mapped discontiguous areas, Kanoj Sarcar <[email protected]>
 */

#include <linux/vmcore_info.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/kcore.h>
#include <linux/user.h>
#include <linux/capability.h>
#include <linux/elf.h>
#include <linux/elfcore.h>
#include <linux/vmalloc.h>
#include <linux/highmem.h>
#include <linux/printk.h>
#include <linux/memblock.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/uio.h>
#include <asm/io.h>
#include <linux/list.h>
#include <linux/ioport.h>
#include <linux/memory.h>
#include <linux/sched/task.h>
#include <linux/security.h>
#include <asm/sections.h>
#include "internal.h"

#define CORE_STR

#ifndef ELF_CORE_EFLAGS
#define ELF_CORE_EFLAGS
#endif

static struct proc_dir_entry *proc_root_kcore;


#ifndef kc_vaddr_to_offset
#define kc_vaddr_to_offset
#endif
#ifndef	kc_offset_to_vaddr
#define kc_offset_to_vaddr
#endif

static LIST_HEAD(kclist_head);
static DECLARE_RWSEM(kclist_lock);
static int kcore_need_update =;

/*
 * Returns > 0 for RAM pages, 0 for non-RAM pages, < 0 on error
 * Same as oldmem_pfn_is_ram in vmcore
 */
static int (*mem_pfn_is_ram)(unsigned long pfn);

int __init register_mem_pfn_is_ram(int (*fn)(unsigned long pfn))
{}

static int pfn_is_ram(unsigned long pfn)
{}

/* This doesn't grab kclist_lock, so it should only be used at init time. */
void __init kclist_add(struct kcore_list *new, void *addr, size_t size,
		       int type)
{}

static size_t get_kcore_size(int *nphdr, size_t *phdrs_len, size_t *notes_len,
			     size_t *data_offset)
{}

#ifdef CONFIG_HIGHMEM
/*
 * If no highmem, we can assume [0...max_low_pfn) continuous range of memory
 * because memory hole is not as big as !HIGHMEM case.
 * (HIGHMEM is special because part of memory is _invisible_ from the kernel.)
 */
static int kcore_ram_list(struct list_head *head)
{
	struct kcore_list *ent;

	ent = kmalloc(sizeof(*ent), GFP_KERNEL);
	if (!ent)
		return -ENOMEM;
	ent->addr = (unsigned long)__va(0);
	ent->size = max_low_pfn << PAGE_SHIFT;
	ent->type = KCORE_RAM;
	list_add(&ent->list, head);
	return 0;
}

#else /* !CONFIG_HIGHMEM */

#ifdef CONFIG_SPARSEMEM_VMEMMAP
/* calculate vmemmap's address from given system ram pfn and register it */
static int
get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
{}
#else
static int
get_sparsemem_vmemmap_info(struct kcore_list *ent, struct list_head *head)
{
	return 1;
}

#endif

static int
kclist_add_private(unsigned long pfn, unsigned long nr_pages, void *arg)
{}

static int kcore_ram_list(struct list_head *list)
{}
#endif /* CONFIG_HIGHMEM */

static int kcore_update_ram(void)
{}

static void append_kcore_note(char *notes, size_t *i, const char *name,
			      unsigned int type, const void *desc,
			      size_t descsz)
{}

static ssize_t read_kcore_iter(struct kiocb *iocb, struct iov_iter *iter)
{}

static int open_kcore(struct inode *inode, struct file *filp)
{}

static int release_kcore(struct inode *inode, struct file *file)
{}

static const struct proc_ops kcore_proc_ops =;

/* just remember that we have to update kcore */
static int __meminit kcore_callback(struct notifier_block *self,
				    unsigned long action, void *arg)
{}


static struct kcore_list kcore_vmalloc;

#ifdef CONFIG_ARCH_PROC_KCORE_TEXT
static struct kcore_list kcore_text;
/*
 * If defined, special segment is used for mapping kernel text instead of
 * direct-map area. We need to create special TEXT section.
 */
static void __init proc_kcore_text_init(void)
{}
#else
static void __init proc_kcore_text_init(void)
{
}
#endif

#if defined(CONFIG_MODULES) && defined(MODULES_VADDR)
/*
 * MODULES_VADDR has no intersection with VMALLOC_ADDR.
 */
static struct kcore_list kcore_modules;
static void __init add_modules_range(void)
{}
#else
static void __init add_modules_range(void)
{
}
#endif

static int __init proc_kcore_init(void)
{}
fs_initcall(proc_kcore_init);