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