#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/log2.h>
#include <linux/mm.h>
#include <linux/mman.h>
#include <linux/errno.h>
#include <linux/signal.h>
#include <linux/binfmts.h>
#include <linux/string.h>
#include <linux/file.h>
#include <linux/slab.h>
#include <linux/personality.h>
#include <linux/elfcore.h>
#include <linux/init.h>
#include <linux/highuid.h>
#include <linux/compiler.h>
#include <linux/highmem.h>
#include <linux/hugetlb.h>
#include <linux/pagemap.h>
#include <linux/vmalloc.h>
#include <linux/security.h>
#include <linux/random.h>
#include <linux/elf.h>
#include <linux/elf-randomize.h>
#include <linux/utsname.h>
#include <linux/coredump.h>
#include <linux/sched.h>
#include <linux/sched/coredump.h>
#include <linux/sched/task_stack.h>
#include <linux/sched/cputime.h>
#include <linux/sizes.h>
#include <linux/types.h>
#include <linux/cred.h>
#include <linux/dax.h>
#include <linux/uaccess.h>
#include <linux/rseq.h>
#include <asm/param.h>
#include <asm/page.h>
#ifndef ELF_COMPAT
#define ELF_COMPAT …
#endif
#ifndef user_long_t
#define user_long_t …
#endif
#ifndef user_siginfo_t
#define user_siginfo_t …
#endif
#ifndef elf_check_fdpic
#define elf_check_fdpic(ex) …
#endif
static int load_elf_binary(struct linux_binprm *bprm);
#ifdef CONFIG_USELIB
static int load_elf_library(struct file *);
#else
#define load_elf_library …
#endif
#ifdef CONFIG_ELF_CORE
static int elf_core_dump(struct coredump_params *cprm);
#else
#define elf_core_dump …
#endif
#if ELF_EXEC_PAGESIZE > PAGE_SIZE
#define ELF_MIN_ALIGN …
#else
#define ELF_MIN_ALIGN …
#endif
#ifndef ELF_CORE_EFLAGS
#define ELF_CORE_EFLAGS …
#endif
#define ELF_PAGESTART(_v) …
#define ELF_PAGEOFFSET(_v) …
#define ELF_PAGEALIGN(_v) …
static struct linux_binfmt elf_format = …;
#define BAD_ADDR(x) …
static int padzero(unsigned long address)
{ … }
#ifdef CONFIG_STACK_GROWSUP
#define STACK_ADD …
#define STACK_ROUND …
#define STACK_ALLOC …
#else
#define STACK_ADD(sp, items) …
#define STACK_ROUND(sp, items) …
#define STACK_ALLOC(sp, len) …
#endif
#ifndef ELF_BASE_PLATFORM
#define ELF_BASE_PLATFORM …
#endif
static int
create_elf_tables(struct linux_binprm *bprm, const struct elfhdr *exec,
unsigned long interp_load_addr,
unsigned long e_entry, unsigned long phdr_addr)
{ … }
static unsigned long elf_map(struct file *filep, unsigned long addr,
const struct elf_phdr *eppnt, int prot, int type,
unsigned long total_size)
{ … }
static unsigned long elf_load(struct file *filep, unsigned long addr,
const struct elf_phdr *eppnt, int prot, int type,
unsigned long total_size)
{ … }
static unsigned long total_mapping_size(const struct elf_phdr *phdr, int nr)
{ … }
static int elf_read(struct file *file, void *buf, size_t len, loff_t pos)
{ … }
static unsigned long maximum_alignment(struct elf_phdr *cmds, int nr)
{ … }
static struct elf_phdr *load_elf_phdrs(const struct elfhdr *elf_ex,
struct file *elf_file)
{ … }
#ifndef CONFIG_ARCH_BINFMT_ELF_STATE
struct arch_elf_state { … };
#define INIT_ARCH_ELF_STATE …
static inline int arch_elf_pt_proc(struct elfhdr *ehdr,
struct elf_phdr *phdr,
struct file *elf, bool is_interp,
struct arch_elf_state *state)
{ … }
static inline int arch_check_elf(struct elfhdr *ehdr, bool has_interp,
struct elfhdr *interp_ehdr,
struct arch_elf_state *state)
{ … }
#endif
static inline int make_prot(u32 p_flags, struct arch_elf_state *arch_state,
bool has_interp, bool is_interp)
{ … }
static unsigned long load_elf_interp(struct elfhdr *interp_elf_ex,
struct file *interpreter,
unsigned long no_base, struct elf_phdr *interp_elf_phdata,
struct arch_elf_state *arch_state)
{ … }
static int parse_elf_property(const char *data, size_t *off, size_t datasz,
struct arch_elf_state *arch,
bool have_prev_type, u32 *prev_type)
{ … }
#define NOTE_DATA_SZ …
#define GNU_PROPERTY_TYPE_0_NAME …
#define NOTE_NAME_SZ …
static int parse_elf_properties(struct file *f, const struct elf_phdr *phdr,
struct arch_elf_state *arch)
{ … }
static int load_elf_binary(struct linux_binprm *bprm)
{ … }
#ifdef CONFIG_USELIB
static int load_elf_library(struct file *file)
{ … }
#endif
#ifdef CONFIG_ELF_CORE
struct memelfnote
{ … };
static int notesize(struct memelfnote *en)
{ … }
static int writenote(struct memelfnote *men, struct coredump_params *cprm)
{ … }
static void fill_elf_header(struct elfhdr *elf, int segs,
u16 machine, u32 flags)
{ … }
static void fill_elf_note_phdr(struct elf_phdr *phdr, int sz, loff_t offset)
{ … }
static void fill_note(struct memelfnote *note, const char *name, int type,
unsigned int sz, void *data)
{ … }
static void fill_prstatus(struct elf_prstatus_common *prstatus,
struct task_struct *p, long signr)
{ … }
static int fill_psinfo(struct elf_prpsinfo *psinfo, struct task_struct *p,
struct mm_struct *mm)
{ … }
static void fill_auxv_note(struct memelfnote *note, struct mm_struct *mm)
{ … }
static void fill_siginfo_note(struct memelfnote *note, user_siginfo_t *csigdata,
const kernel_siginfo_t *siginfo)
{ … }
static int fill_files_note(struct memelfnote *note, struct coredump_params *cprm)
{ … }
#include <linux/regset.h>
struct elf_thread_core_info { … };
struct elf_note_info { … };
#ifdef CORE_DUMP_USE_REGSET
static void do_thread_regset_writeback(struct task_struct *task,
const struct user_regset *regset)
{ … }
#ifndef PRSTATUS_SIZE
#define PRSTATUS_SIZE …
#endif
#ifndef SET_PR_FPVALID
#define SET_PR_FPVALID(S) …
#endif
static int fill_thread_core_info(struct elf_thread_core_info *t,
const struct user_regset_view *view,
long signr, struct elf_note_info *info)
{ … }
#else
static int fill_thread_core_info(struct elf_thread_core_info *t,
const struct user_regset_view *view,
long signr, struct elf_note_info *info)
{
struct task_struct *p = t->task;
elf_fpregset_t *fpu;
fill_prstatus(&t->prstatus.common, p, signr);
elf_core_copy_task_regs(p, &t->prstatus.pr_reg);
fill_note(&t->notes[0], "CORE", NT_PRSTATUS, sizeof(t->prstatus),
&(t->prstatus));
info->size += notesize(&t->notes[0]);
fpu = kzalloc(sizeof(elf_fpregset_t), GFP_KERNEL);
if (!fpu || !elf_core_copy_task_fpregs(p, fpu)) {
kfree(fpu);
return 1;
}
t->prstatus.pr_fpvalid = 1;
fill_note(&t->notes[1], "CORE", NT_PRFPREG, sizeof(*fpu), fpu);
info->size += notesize(&t->notes[1]);
return 1;
}
#endif
static int fill_note_info(struct elfhdr *elf, int phdrs,
struct elf_note_info *info,
struct coredump_params *cprm)
{ … }
static int write_note_info(struct elf_note_info *info,
struct coredump_params *cprm)
{ … }
static void free_note_info(struct elf_note_info *info)
{ … }
static void fill_extnum_info(struct elfhdr *elf, struct elf_shdr *shdr4extnum,
elf_addr_t e_shoff, int segs)
{ … }
static int elf_core_dump(struct coredump_params *cprm)
{ … }
#endif
static int __init init_elf_binfmt(void)
{ … }
static void __exit exit_elf_binfmt(void)
{ … }
core_initcall(init_elf_binfmt);
module_exit(exit_elf_binfmt);
#ifdef CONFIG_BINFMT_ELF_KUNIT_TEST
#include "tests/binfmt_elf_kunit.c"
#endif