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 Elf64_Half elf_core_extra_phdrs(void) 11 { 12 return GATE_EHDR->e_phnum; 13 } 14 15 int elf_core_write_extra_phdrs(struct coredump_params *cprm, loff_t offset) 16 { 17 const struct elf_phdr *const gate_phdrs = 18 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); 19 int i; 20 Elf64_Off ofs = 0; 21 22 for (i = 0; i < GATE_EHDR->e_phnum; ++i) { 23 struct elf_phdr phdr = gate_phdrs[i]; 24 25 if (phdr.p_type == PT_LOAD) { 26 phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); 27 phdr.p_filesz = phdr.p_memsz; 28 if (ofs == 0) { 29 ofs = phdr.p_offset = offset; 30 offset += phdr.p_filesz; 31 } else { 32 phdr.p_offset = ofs; 33 } 34 } else { 35 phdr.p_offset += ofs; 36 } 37 phdr.p_paddr = 0; /* match other core phdrs */ 38 if (!dump_emit(cprm, &phdr, sizeof(phdr))) 39 return 0; 40 } 41 return 1; 42 } 43 44 int elf_core_write_extra_data(struct coredump_params *cprm) 45 { 46 const struct elf_phdr *const gate_phdrs = 47 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); 48 int i; 49 50 for (i = 0; i < GATE_EHDR->e_phnum; ++i) { 51 if (gate_phdrs[i].p_type == PT_LOAD) { 52 void *addr = (void *)gate_phdrs[i].p_vaddr; 53 size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz); 54 55 if (!dump_emit(cprm, addr, memsz)) 56 return 0; 57 break; 58 } 59 } 60 return 1; 61 } 62 63 size_t elf_core_extra_data_size(void) 64 { 65 const struct elf_phdr *const gate_phdrs = 66 (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); 67 int i; 68 size_t size = 0; 69 70 for (i = 0; i < GATE_EHDR->e_phnum; ++i) { 71 if (gate_phdrs[i].p_type == PT_LOAD) { 72 size += PAGE_ALIGN(gate_phdrs[i].p_memsz); 73 break; 74 } 75 } 76 return size; 77 } 78