15c48b108SAl Viro #include <linux/elf.h> 25c48b108SAl Viro #include <linux/coredump.h> 35c48b108SAl Viro #include <linux/fs.h> 45c48b108SAl Viro #include <linux/mm.h> 55c48b108SAl Viro 65c48b108SAl Viro #include <asm/elf.h> 75c48b108SAl Viro 85c48b108SAl Viro 95c48b108SAl Viro Elf32_Half elf_core_extra_phdrs(void) 105c48b108SAl Viro { 115c48b108SAl Viro return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; 125c48b108SAl Viro } 135c48b108SAl Viro 14*506f21c5SAl Viro int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset) 155c48b108SAl Viro { 165c48b108SAl Viro if ( vsyscall_ehdr ) { 175c48b108SAl Viro const struct elfhdr *const ehdrp = 185c48b108SAl Viro (struct elfhdr *) vsyscall_ehdr; 195c48b108SAl Viro const struct elf_phdr *const phdrp = 205c48b108SAl Viro (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); 215c48b108SAl Viro int i; 225c48b108SAl Viro Elf32_Off ofs = 0; 235c48b108SAl Viro 245c48b108SAl Viro for (i = 0; i < ehdrp->e_phnum; ++i) { 255c48b108SAl Viro struct elf_phdr phdr = phdrp[i]; 265c48b108SAl Viro 275c48b108SAl Viro if (phdr.p_type == PT_LOAD) { 285c48b108SAl Viro ofs = phdr.p_offset = offset; 295c48b108SAl Viro offset += phdr.p_filesz; 305c48b108SAl Viro } else { 315c48b108SAl Viro phdr.p_offset += ofs; 325c48b108SAl Viro } 335c48b108SAl Viro phdr.p_paddr = 0; /* match other core phdrs */ 34*506f21c5SAl Viro if (!dump_emit(cprm, &phdr, sizeof(phdr))) 355c48b108SAl Viro return 0; 365c48b108SAl Viro } 375c48b108SAl Viro } 385c48b108SAl Viro return 1; 395c48b108SAl Viro } 405c48b108SAl Viro 415c48b108SAl Viro int elf_core_write_extra_data(struct file *file, size_t *size, 425c48b108SAl Viro unsigned long limit) 435c48b108SAl Viro { 445c48b108SAl Viro if ( vsyscall_ehdr ) { 455c48b108SAl Viro const struct elfhdr *const ehdrp = 465c48b108SAl Viro (struct elfhdr *) vsyscall_ehdr; 475c48b108SAl Viro const struct elf_phdr *const phdrp = 485c48b108SAl Viro (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); 495c48b108SAl Viro int i; 505c48b108SAl Viro 515c48b108SAl Viro for (i = 0; i < ehdrp->e_phnum; ++i) { 525c48b108SAl Viro if (phdrp[i].p_type == PT_LOAD) { 535c48b108SAl Viro void *addr = (void *) phdrp[i].p_vaddr; 545c48b108SAl Viro size_t filesz = phdrp[i].p_filesz; 555c48b108SAl Viro 565c48b108SAl Viro *size += filesz; 575c48b108SAl Viro if (*size > limit 585c48b108SAl Viro || !dump_write(file, addr, filesz)) 595c48b108SAl Viro return 0; 605c48b108SAl Viro } 615c48b108SAl Viro } 625c48b108SAl Viro } 635c48b108SAl Viro return 1; 645c48b108SAl Viro } 655c48b108SAl Viro 665c48b108SAl Viro size_t elf_core_extra_data_size(void) 675c48b108SAl Viro { 685c48b108SAl Viro if ( vsyscall_ehdr ) { 695c48b108SAl Viro const struct elfhdr *const ehdrp = 705c48b108SAl Viro (struct elfhdr *)vsyscall_ehdr; 715c48b108SAl Viro const struct elf_phdr *const phdrp = 725c48b108SAl Viro (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); 735c48b108SAl Viro int i; 745c48b108SAl Viro 755c48b108SAl Viro for (i = 0; i < ehdrp->e_phnum; ++i) 765c48b108SAl Viro if (phdrp[i].p_type == PT_LOAD) 775c48b108SAl Viro return (size_t) phdrp[i].p_filesz; 785c48b108SAl Viro } 795c48b108SAl Viro return 0; 805c48b108SAl Viro } 81