Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

elf coredump: replace ELF_CORE_EXTRA_* macros by functions

elf_core_dump() and elf_fdpic_core_dump() use #ifdef and the corresponding
macro for hiding _multiline_ logics in functions. This patch removes
#ifdef and replaces ELF_CORE_EXTRA_* by corresponding functions. For
architectures not implemeonting ELF_CORE_EXTRA_*, we use weak functions in
order to reduce a range of modification.

This cleanup is for my next patches, but I think this cleanup itself is
worth doing regardless of my firnal purpose.

Signed-off-by: Daisuke HATAYAMA <d.hatayama@jp.fujitsu.com>
Cc: "Luck, Tony" <tony.luck@intel.com>
Cc: Jeff Dike <jdike@addtoit.com>
Cc: David Howells <dhowells@redhat.com>
Cc: Greg Ungerer <gerg@snapgear.com>
Cc: Roland McGrath <roland@redhat.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Ingo Molnar <mingo@elte.hu>
Cc: Alexander Viro <viro@zeniv.linux.org.uk>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Cc: <linux-arch@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Daisuke HATAYAMA and committed by
Linus Torvalds
1fcccbac 088e7af7

+191 -109
-48
arch/ia64/include/asm/elf.h
··· 219 219 NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR); \ 220 220 } while (0) 221 221 222 - 223 - /* 224 - * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out 225 - * extra segments containing the gate DSO contents. Dumping its 226 - * contents makes post-mortem fully interpretable later without matching up 227 - * the same kernel and hardware config to see what PC values meant. 228 - * Dumping its extra ELF program headers includes all the other information 229 - * a debugger needs to easily find how the gate DSO was being used. 230 - */ 231 - #define ELF_CORE_EXTRA_PHDRS (GATE_EHDR->e_phnum) 232 - #define ELF_CORE_WRITE_EXTRA_PHDRS \ 233 - do { \ 234 - const struct elf_phdr *const gate_phdrs = \ 235 - (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \ 236 - int i; \ 237 - Elf64_Off ofs = 0; \ 238 - for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \ 239 - struct elf_phdr phdr = gate_phdrs[i]; \ 240 - if (phdr.p_type == PT_LOAD) { \ 241 - phdr.p_memsz = PAGE_ALIGN(phdr.p_memsz); \ 242 - phdr.p_filesz = phdr.p_memsz; \ 243 - if (ofs == 0) { \ 244 - ofs = phdr.p_offset = offset; \ 245 - offset += phdr.p_filesz; \ 246 - } \ 247 - else \ 248 - phdr.p_offset = ofs; \ 249 - } \ 250 - else \ 251 - phdr.p_offset += ofs; \ 252 - phdr.p_paddr = 0; /* match other core phdrs */ \ 253 - DUMP_WRITE(&phdr, sizeof(phdr)); \ 254 - } \ 255 - } while (0) 256 - #define ELF_CORE_WRITE_EXTRA_DATA \ 257 - do { \ 258 - const struct elf_phdr *const gate_phdrs = \ 259 - (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); \ 260 - int i; \ 261 - for (i = 0; i < GATE_EHDR->e_phnum; ++i) { \ 262 - if (gate_phdrs[i].p_type == PT_LOAD) { \ 263 - DUMP_WRITE((void *) gate_phdrs[i].p_vaddr, \ 264 - PAGE_ALIGN(gate_phdrs[i].p_memsz)); \ 265 - break; \ 266 - } \ 267 - } \ 268 - } while (0) 269 - 270 222 /* 271 223 * format for entries in the Global Offset Table 272 224 */
+2
arch/ia64/kernel/Makefile
··· 45 45 obj-$(CONFIG_DMAR) += pci-dma.o 46 46 obj-$(CONFIG_SWIOTLB) += pci-swiotlb.o 47 47 48 + obj-$(CONFIG_BINFMT_ELF) += elfcore.o 49 + 48 50 # fp_emulate() expects f2-f5,f16-f31 to contain the user-level state. 49 51 CFLAGS_traps.o += -mfixed-range=f2-f5,f16-f31 50 52
+64
arch/ia64/kernel/elfcore.c
··· 1 + #include <linux/elf.h> 2 + #include <linux/coredump.h> 3 + #include <linux/fs.h> 4 + #include <linux/mm.h> 5 + 6 + #include <asm/elf.h> 7 + 8 + 9 + Elf64_Half elf_core_extra_phdrs(void) 10 + { 11 + return GATE_EHDR->e_phnum; 12 + } 13 + 14 + int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, 15 + unsigned long limit) 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 + *size += sizeof(phdr); 39 + if (*size > limit || !dump_write(file, &phdr, sizeof(phdr))) 40 + return 0; 41 + } 42 + return 1; 43 + } 44 + 45 + int elf_core_write_extra_data(struct file *file, size_t *size, 46 + unsigned long limit) 47 + { 48 + const struct elf_phdr *const gate_phdrs = 49 + (const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff); 50 + int i; 51 + 52 + for (i = 0; i < GATE_EHDR->e_phnum; ++i) { 53 + if (gate_phdrs[i].p_type == PT_LOAD) { 54 + void *addr = (void *)gate_phdrs[i].p_vaddr; 55 + size_t memsz = PAGE_ALIGN(gate_phdrs[i].p_memsz); 56 + 57 + *size += memsz; 58 + if (*size > limit || !dump_write(file, addr, memsz)) 59 + return 0; 60 + break; 61 + } 62 + } 63 + return 1; 64 + }
+2
arch/um/sys-i386/Makefile
··· 6 6 ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \ 7 7 sys_call_table.o tls.o 8 8 9 + obj-$(CONFIG_BINFMT_ELF) += elfcore.o 10 + 9 11 subarch-obj-y = lib/semaphore_32.o lib/string_32.o 10 12 subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o 11 13 subarch-obj-$(CONFIG_MODULES) += kernel/module.o
-43
arch/um/sys-i386/asm/elf.h
··· 116 116 } \ 117 117 } while (0) 118 118 119 - /* 120 - * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out 121 - * extra segments containing the vsyscall DSO contents. Dumping its 122 - * contents makes post-mortem fully interpretable later without matching up 123 - * the same kernel and hardware config to see what PC values meant. 124 - * Dumping its extra ELF program headers includes all the other information 125 - * a debugger needs to easily find how the vsyscall DSO was being used. 126 - */ 127 - #define ELF_CORE_EXTRA_PHDRS \ 128 - (vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0 ) 129 - 130 - #define ELF_CORE_WRITE_EXTRA_PHDRS \ 131 - if ( vsyscall_ehdr ) { \ 132 - const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \ 133 - const struct elf_phdr *const phdrp = \ 134 - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \ 135 - int i; \ 136 - Elf32_Off ofs = 0; \ 137 - for (i = 0; i < ehdrp->e_phnum; ++i) { \ 138 - struct elf_phdr phdr = phdrp[i]; \ 139 - if (phdr.p_type == PT_LOAD) { \ 140 - ofs = phdr.p_offset = offset; \ 141 - offset += phdr.p_filesz; \ 142 - } \ 143 - else \ 144 - phdr.p_offset += ofs; \ 145 - phdr.p_paddr = 0; /* match other core phdrs */ \ 146 - DUMP_WRITE(&phdr, sizeof(phdr)); \ 147 - } \ 148 - } 149 - #define ELF_CORE_WRITE_EXTRA_DATA \ 150 - if ( vsyscall_ehdr ) { \ 151 - const struct elfhdr *const ehdrp = (struct elfhdr *)vsyscall_ehdr; \ 152 - const struct elf_phdr *const phdrp = \ 153 - (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); \ 154 - int i; \ 155 - for (i = 0; i < ehdrp->e_phnum; ++i) { \ 156 - if (phdrp[i].p_type == PT_LOAD) \ 157 - DUMP_WRITE((void *) phdrp[i].p_vaddr, \ 158 - phdrp[i].p_filesz); \ 159 - } \ 160 - } 161 - 162 119 #endif
+67
arch/um/sys-i386/elfcore.c
··· 1 + #include <linux/elf.h> 2 + #include <linux/coredump.h> 3 + #include <linux/fs.h> 4 + #include <linux/mm.h> 5 + 6 + #include <asm/elf.h> 7 + 8 + 9 + Elf32_Half elf_core_extra_phdrs(void) 10 + { 11 + return vsyscall_ehdr ? (((struct elfhdr *)vsyscall_ehdr)->e_phnum) : 0; 12 + } 13 + 14 + int elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, 15 + unsigned long limit) 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 + *size += sizeof(phdr); 36 + if (*size > limit 37 + || !dump_write(file, &phdr, sizeof(phdr))) 38 + return 0; 39 + } 40 + } 41 + return 1; 42 + } 43 + 44 + int elf_core_write_extra_data(struct file *file, size_t *size, 45 + unsigned long limit) 46 + { 47 + if ( vsyscall_ehdr ) { 48 + const struct elfhdr *const ehdrp = 49 + (struct elfhdr *) vsyscall_ehdr; 50 + const struct elf_phdr *const phdrp = 51 + (const struct elf_phdr *) (vsyscall_ehdr + ehdrp->e_phoff); 52 + int i; 53 + 54 + for (i = 0; i < ehdrp->e_phnum; ++i) { 55 + if (phdrp[i].p_type == PT_LOAD) { 56 + void *addr = (void *) phdrp[i].p_vaddr; 57 + size_t filesz = phdrp[i].p_filesz; 58 + 59 + *size += filesz; 60 + if (*size > limit 61 + || !dump_write(file, addr, filesz)) 62 + return 0; 63 + } 64 + } 65 + } 66 + return 1; 67 + }
+5 -9
fs/binfmt_elf.c
··· 1878 1878 * Please check DEFAULT_MAX_MAP_COUNT definition when you modify here. 1879 1879 */ 1880 1880 segs = current->mm->map_count; 1881 - #ifdef ELF_CORE_EXTRA_PHDRS 1882 - segs += ELF_CORE_EXTRA_PHDRS; 1883 - #endif 1881 + segs += elf_core_extra_phdrs(); 1884 1882 1885 1883 gate_vma = get_gate_vma(current); 1886 1884 if (gate_vma != NULL) ··· 1956 1958 goto end_coredump; 1957 1959 } 1958 1960 1959 - #ifdef ELF_CORE_WRITE_EXTRA_PHDRS 1960 - ELF_CORE_WRITE_EXTRA_PHDRS; 1961 - #endif 1961 + if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit)) 1962 + goto end_coredump; 1962 1963 1963 1964 /* write out the notes section */ 1964 1965 if (!write_note_info(&info, cprm->file, &foffset)) ··· 1996 1999 } 1997 2000 } 1998 2001 1999 - #ifdef ELF_CORE_WRITE_EXTRA_DATA 2000 - ELF_CORE_WRITE_EXTRA_DATA; 2001 - #endif 2002 + if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit)) 2003 + goto end_coredump; 2002 2004 2003 2005 end_coredump: 2004 2006 set_fs(fs);
+5 -9
fs/binfmt_elf_fdpic.c
··· 1664 1664 elf_core_copy_regs(&prstatus->pr_reg, cprm->regs); 1665 1665 1666 1666 segs = current->mm->map_count; 1667 - #ifdef ELF_CORE_EXTRA_PHDRS 1668 - segs += ELF_CORE_EXTRA_PHDRS; 1669 - #endif 1667 + segs += elf_core_extra_phdrs(); 1670 1668 1671 1669 /* Set up header */ 1672 1670 fill_elf_fdpic_header(elf, segs + 1); /* including notes section */ ··· 1771 1773 goto end_coredump; 1772 1774 } 1773 1775 1774 - #ifdef ELF_CORE_WRITE_EXTRA_PHDRS 1775 - ELF_CORE_WRITE_EXTRA_PHDRS; 1776 - #endif 1776 + if (!elf_core_write_extra_phdrs(cprm->file, offset, &size, cprm->limit)) 1777 + goto end_coredump; 1777 1778 1778 1779 /* write out the notes section */ 1779 1780 for (i = 0; i < numnote; i++) ··· 1796 1799 mm_flags) < 0) 1797 1800 goto end_coredump; 1798 1801 1799 - #ifdef ELF_CORE_WRITE_EXTRA_DATA 1800 - ELF_CORE_WRITE_EXTRA_DATA; 1801 - #endif 1802 + if (!elf_core_write_extra_data(cprm->file, &size, cprm->limit)) 1803 + goto end_coredump; 1802 1804 1803 1805 if (cprm->file->f_pos != offset) { 1804 1806 /* Sanity check */
+2
fs/compat_binfmt_elf.c
··· 28 28 29 29 #undef elfhdr 30 30 #undef elf_phdr 31 + #undef elf_shdr 31 32 #undef elf_note 32 33 #undef elf_addr_t 33 34 #define elfhdr elf32_hdr 34 35 #define elf_phdr elf32_phdr 36 + #define elf_shdr elf32_shdr 35 37 #define elf_note elf32_note 36 38 #define elf_addr_t Elf32_Addr 37 39
+2
include/linux/elf.h
··· 396 396 #define elf_phdr elf32_phdr 397 397 #define elf_note elf32_note 398 398 #define elf_addr_t Elf32_Off 399 + #define Elf_Half Elf32_Half 399 400 400 401 #else 401 402 ··· 405 404 #define elf_phdr elf64_phdr 406 405 #define elf_note elf64_note 407 406 #define elf_addr_t Elf64_Off 407 + #define Elf_Half Elf64_Half 408 408 409 409 #endif 410 410
+16
include/linux/elfcore.h
··· 8 8 #include <linux/user.h> 9 9 #endif 10 10 #include <linux/ptrace.h> 11 + #include <linux/elf.h> 12 + #include <linux/fs.h> 11 13 12 14 struct elf_siginfo 13 15 { ··· 152 150 153 151 #endif /* __KERNEL__ */ 154 152 153 + /* 154 + * These functions parameterize elf_core_dump in fs/binfmt_elf.c to write out 155 + * extra segments containing the gate DSO contents. Dumping its 156 + * contents makes post-mortem fully interpretable later without matching up 157 + * the same kernel and hardware config to see what PC values meant. 158 + * Dumping its extra ELF program headers includes all the other information 159 + * a debugger needs to easily find how the gate DSO was being used. 160 + */ 161 + extern Elf_Half elf_core_extra_phdrs(void); 162 + extern int 163 + elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, 164 + unsigned long limit); 165 + extern int 166 + elf_core_write_extra_data(struct file *file, size_t *size, unsigned long limit); 155 167 156 168 #endif /* _LINUX_ELFCORE_H */
+3
kernel/Makefile
··· 91 91 obj-$(CONFIG_TASKSTATS) += taskstats.o tsacct.o 92 92 obj-$(CONFIG_TRACEPOINTS) += tracepoint.o 93 93 obj-$(CONFIG_LATENCYTOP) += latencytop.o 94 + obj-$(CONFIG_BINFMT_ELF) += elfcore.o 95 + obj-$(CONFIG_COMPAT_BINFMT_ELF) += elfcore.o 96 + obj-$(CONFIG_BINFMT_ELF_FDPIC) += elfcore.o 94 97 obj-$(CONFIG_FUNCTION_TRACER) += trace/ 95 98 obj-$(CONFIG_TRACING) += trace/ 96 99 obj-$(CONFIG_X86_DS) += trace/
+23
kernel/elfcore.c
··· 1 + #include <linux/elf.h> 2 + #include <linux/fs.h> 3 + #include <linux/mm.h> 4 + 5 + #include <asm/elf.h> 6 + 7 + 8 + Elf_Half __weak elf_core_extra_phdrs(void) 9 + { 10 + return 0; 11 + } 12 + 13 + int __weak elf_core_write_extra_phdrs(struct file *file, loff_t offset, size_t *size, 14 + unsigned long limit) 15 + { 16 + return 1; 17 + } 18 + 19 + int __weak elf_core_write_extra_data(struct file *file, size_t *size, 20 + unsigned long limit) 21 + { 22 + return 1; 23 + }