1 // SPDX-License-Identifier: GPL-2.0 2 #include <linux/elf.h> 3 #include <linux/elfcore.h> 4 #include <linux/coredump.h> 5 #include <linux/fs.h> 6 #include <linux/mm.h> 7 8 #include <asm/elf.h> 9 10 11 Elf32_Half elf_core_extra_phdrs(struct coredump_params *cprm) 12 { 13 return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; 14 } 15 16 int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset) 17 { 18 if ( vsyscall_ehdr ) { 19 const struct elfhdr *const ehdrp = 20 (struct elfhdr *) vsyscall_ehdr; 21 const struct elf_phdr *const phdrp = 22 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); 23 int i; 24 Elf32_Off ofs = 0; 25 26 for (i = 0; i < ehdrp->e_phnum; ++i) { 27 struct elf_phdr phdr = phdrp[i]; 28 29 if (phdr.p_type == PT_LOAD) { 30 ofs = phdr.p_offset = offset; 31 offset += phdr.p_filesz; 32 } else { 33 phdr.p_offset += ofs; 34 } 35 phdr.p_paddr = 0; /* match other core phdrs */ 36 if (!dump_emit(cprm, &phdr, sizeof(phdr))) 37 return 0; 38 } 39 } 40 return 1; 41 } 42 43 int elf_core_write_extra_data(struct coredump_params *cprm) 44 { 45 if ( vsyscall_ehdr ) { 46 const struct elfhdr *const ehdrp = 47 (struct elfhdr *) vsyscall_ehdr; 48 const struct elf_phdr *const phdrp = 49 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); 50 int i; 51 52 for (i = 0; i < ehdrp->e_phnum; ++i) { 53 if (phdrp[i].p_type == PT_LOAD) { 54 void *addr = (void *) phdrp[i].p_vaddr; 55 size_t filesz = phdrp[i].p_filesz; 56 if (!dump_emit(cprm, addr, filesz)) 57 return 0; 58 } 59 } 60 } 61 return 1; 62 } 63 64 size_t elf_core_extra_data_size(struct coredump_params *cprm) 65 { 66 if ( vsyscall_ehdr ) { 67 const struct elfhdr *const ehdrp = 68 (struct elfhdr *)vsyscall_ehdr; 69 const struct elf_phdr *const phdrp = 70 (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); 71 int i; 72 73 for (i = 0; i < ehdrp->e_phnum; ++i) 74 if (phdrp[i].p_type == PT_LOAD) 75 return (size_t) phdrp[i].p_filesz; 76 } 77 return 0; 78 } 79