1b2441318SGreg Kroah-Hartman // SPDX-License-Identifier: GPL-2.0 25c48b108SAl Viro #include <linux/elf.h> 3*9ffc6724STiwei Bie #include <linux/elfcore.h> 45c48b108SAl Viro #include <linux/coredump.h> 55c48b108SAl Viro #include <linux/fs.h> 65c48b108SAl Viro #include <linux/mm.h> 75c48b108SAl Viro 85c48b108SAl Viro #include <asm/elf.h> 95c48b108SAl Viro 105c48b108SAl Viro 1119e183b5SCatalin Marinas Elf32_Half elf_core_extra_phdrs(struct coredump_params *cprm) 125c48b108SAl Viro { 135c48b108SAl Viro return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; 145c48b108SAl Viro } 155c48b108SAl Viro 16506f21c5SAl Viro int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset) 175c48b108SAl Viro { 185c48b108SAl Viro if ( vsyscall_ehdr ) { 195c48b108SAl Viro const struct elfhdr *const ehdrp = 205c48b108SAl Viro (struct elfhdr *) vsyscall_ehdr; 215c48b108SAl Viro const struct elf_phdr *const phdrp = 225c48b108SAl Viro (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); 235c48b108SAl Viro int i; 245c48b108SAl Viro Elf32_Off ofs = 0; 255c48b108SAl Viro 265c48b108SAl Viro for (i = 0; i < ehdrp->e_phnum; ++i) { 275c48b108SAl Viro struct elf_phdr phdr = phdrp[i]; 285c48b108SAl Viro 295c48b108SAl Viro if (phdr.p_type == PT_LOAD) { 305c48b108SAl Viro ofs = phdr.p_offset = offset; 315c48b108SAl Viro offset += phdr.p_filesz; 325c48b108SAl Viro } else { 335c48b108SAl Viro phdr.p_offset += ofs; 345c48b108SAl Viro } 355c48b108SAl Viro phdr.p_paddr = 0; /* match other core phdrs */ 36506f21c5SAl Viro if (!dump_emit(cprm, &phdr, sizeof(phdr))) 375c48b108SAl Viro return 0; 385c48b108SAl Viro } 395c48b108SAl Viro } 405c48b108SAl Viro return 1; 415c48b108SAl Viro } 425c48b108SAl Viro 43aa3e7eafSAl Viro int elf_core_write_extra_data(struct coredump_params *cprm) 445c48b108SAl Viro { 455c48b108SAl Viro if ( vsyscall_ehdr ) { 465c48b108SAl Viro const struct elfhdr *const ehdrp = 475c48b108SAl Viro (struct elfhdr *) vsyscall_ehdr; 485c48b108SAl Viro const struct elf_phdr *const phdrp = 495c48b108SAl Viro (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); 505c48b108SAl Viro int i; 515c48b108SAl Viro 525c48b108SAl Viro for (i = 0; i < ehdrp->e_phnum; ++i) { 535c48b108SAl Viro if (phdrp[i].p_type == PT_LOAD) { 545c48b108SAl Viro void *addr = (void *) phdrp[i].p_vaddr; 555c48b108SAl Viro size_t filesz = phdrp[i].p_filesz; 56aa3e7eafSAl Viro if (!dump_emit(cprm, addr, filesz)) 575c48b108SAl Viro return 0; 585c48b108SAl Viro } 595c48b108SAl Viro } 605c48b108SAl Viro } 615c48b108SAl Viro return 1; 625c48b108SAl Viro } 635c48b108SAl Viro 6419e183b5SCatalin Marinas size_t elf_core_extra_data_size(struct coredump_params *cprm) 655c48b108SAl Viro { 665c48b108SAl Viro if ( vsyscall_ehdr ) { 675c48b108SAl Viro const struct elfhdr *const ehdrp = 685c48b108SAl Viro (struct elfhdr *)vsyscall_ehdr; 695c48b108SAl Viro const struct elf_phdr *const phdrp = 705c48b108SAl Viro (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); 715c48b108SAl Viro int i; 725c48b108SAl Viro 735c48b108SAl Viro for (i = 0; i < ehdrp->e_phnum; ++i) 745c48b108SAl Viro if (phdrp[i].p_type == PT_LOAD) 755c48b108SAl Viro return (size_t) phdrp[i].p_filesz; 765c48b108SAl Viro } 775c48b108SAl Viro return 0; 785c48b108SAl Viro } 79