xref: /linux/arch/x86/um/elfcore.c (revision 506f21c556c747bb07b893f146220ec45cda381b)
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