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