Date: Mon, 31 Jul 2006 01:51:21 GMT From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 102819 for review Message-ID: <200607310151.k6V1pLHa045347@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=102819 Change 102819 by marcel@marcel_nfs on 2006/07/31 01:50:40 Bring over the preparatory changes from the core branch (depot user/marcel/core). The core branch is going to be retired. Future core file related work is going to happen on the gdb branch (depot projects/gdb). The preparatory changes include simplifying the dumping code so that it could be more easily extended for the next generation core file (Core/NG). Core/NG was triggered by discussions on the GDB mailing list when I attempted to contribute the support for FreeBSD/ia64. This attempt stalled due to lack of time and energy to also revamp the core file dumping. With ARM, MIPS & PowerPC standing in line for GDB support, it seems like a good idea to work towards an integrated branch onto which all GDB related work can happen. I expect that there will be enough overlap that seperate branches are more trouble than they are worth... Affected files ... .. //depot/projects/gdb/sys/kern/imgact_elf.c#15 edit Differences ... ==== //depot/projects/gdb/sys/kern/imgact_elf.c#15 (text+ko) ==== @@ -1,7 +1,8 @@ /*- - * Copyright (c) 2000 David O'Brien * Copyright (c) 1995-1996 Søren Schmidt * Copyright (c) 1996 Peter Wemm + * Copyright (c) 2000 David O'Brien + * Copyright (c) 2005 Marcel Moolenaar * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -886,8 +887,6 @@ static void cb_put_phdr(vm_map_entry_t, void *); static void cb_size_segment(vm_map_entry_t, void *); static void each_writable_segment(struct thread *, segment_callback, void *); -static int __elfN(corehdr)(struct thread *, struct vnode *, struct ucred *, - int, void *, size_t); static void __elfN(puthdr)(struct thread *, void *, size_t *, int); static void __elfN(putnote)(void *, size_t *, const char *, int, const void *, size_t); @@ -895,16 +894,15 @@ extern int osreldate; int -__elfN(coredump)(td, vp, limit) - struct thread *td; - struct vnode *vp; - off_t limit; +__elfN(coredump)(struct thread *td, struct vnode *vp, off_t limit) { + struct sseg_closure seginfo; struct ucred *cred = td->td_ucred; - int error = 0; - struct sseg_closure seginfo; + Elf_Phdr *php; void *hdr; - size_t hdrsize; + off_t offset; + size_t pre_hdrsz, post_hdrsz; + int error, idx; /* Size the program segments. */ seginfo.count = 0; @@ -916,41 +914,45 @@ * a dry run of generating it. Nothing is written, but the * size is calculated. */ - hdrsize = 0; - __elfN(puthdr)(td, (void *)NULL, &hdrsize, seginfo.count); + pre_hdrsz = 0; + __elfN(puthdr)(td, (void *)NULL, &pre_hdrsz, seginfo.count); - if (hdrsize + seginfo.size >= limit) + if (pre_hdrsz + seginfo.size >= limit) return (EFAULT); /* - * Allocate memory for building the header, fill it up, + * Allocate memory for building the headers, fill it up, * and write it out. */ - hdr = malloc(hdrsize, M_TEMP, M_WAITOK); - if (hdr == NULL) { + hdr = malloc(pre_hdrsz, M_TEMP, M_WAITOK | M_ZERO); + if (hdr == NULL) return (EINVAL); - } - error = __elfN(corehdr)(td, vp, cred, seginfo.count, hdr, hdrsize); + + post_hdrsz = 0; + __elfN(puthdr)(td, hdr, &post_hdrsz, seginfo.count); + + /* + * We allow that pre-sizing over-estimates. It is not acceptable + * that we overrun the buffer. + */ + KASSERT(pre_hdrsz >= post_hdrsz, + ("%s: pre_hdrsz < post_hdrsz", __func__)); + + /* Write it to the core file. */ + error = vn_rdwr_inchunks(UIO_WRITE, vp, hdr, post_hdrsz, (off_t)0, + UIO_SYSSPACE, IO_UNIT | IO_DIRECT, cred, NOCRED, NULL, td); /* Write the contents of all of the writable segments. */ - if (error == 0) { - Elf_Phdr *php; - off_t offset; - int i; - - php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1; - offset = hdrsize; - for (i = 0; i < seginfo.count; i++) { - error = vn_rdwr_inchunks(UIO_WRITE, vp, - (caddr_t)(uintptr_t)php->p_vaddr, - php->p_filesz, offset, UIO_USERSPACE, - IO_UNIT | IO_DIRECT, cred, NOCRED, NULL, - curthread); /* XXXKSE */ - if (error != 0) - break; - offset += php->p_filesz; - php++; - } + offset = post_hdrsz; + php = (Elf_Phdr *)((char *)hdr + sizeof(Elf_Ehdr)) + 1; + while (error == 0 && seginfo.count > 0) { + error = vn_rdwr_inchunks(UIO_WRITE, vp, + (caddr_t)(uintptr_t)php->p_vaddr, php->p_filesz, + offset, UIO_USERSPACE, IO_UNIT | IO_DIRECT, cred, + NOCRED, NULL, td); + offset += php->p_filesz; + php++; + seginfo.count--; } free(hdr, M_TEMP); @@ -962,9 +964,7 @@ * program header entry. */ static void -cb_put_phdr(entry, closure) - vm_map_entry_t entry; - void *closure; +cb_put_phdr(vm_map_entry_t entry, void *closure) { struct phdr_closure *phc = (struct phdr_closure *)closure; Elf_Phdr *phdr = phc->phdr; @@ -994,9 +994,7 @@ * the number of segments and their total size. */ static void -cb_size_segment(entry, closure) - vm_map_entry_t entry; - void *closure; +cb_size_segment(vm_map_entry_t entry, void *closure) { struct sseg_closure *ssc = (struct sseg_closure *)closure; @@ -1010,18 +1008,15 @@ * caller-supplied data. */ static void -each_writable_segment(td, func, closure) - struct thread *td; - segment_callback func; - void *closure; +each_writable_segment(struct thread *td, segment_callback func, void *closure) { struct proc *p = td->td_proc; vm_map_t map = &p->p_vmspace->vm_map; vm_map_entry_t entry; + vm_object_t obj; for (entry = map->header.next; entry != &map->header; - entry = entry->next) { - vm_object_t obj; + entry = entry->next) { /* * Don't dump inaccessible mappings, deal with legacy @@ -1065,32 +1060,6 @@ } } -/* - * Write the core file header to the file, including padding up to - * the page boundary. - */ -static int -__elfN(corehdr)(td, vp, cred, numsegs, hdr, hdrsize) - struct thread *td; - struct vnode *vp; - struct ucred *cred; - int numsegs; - size_t hdrsize; - void *hdr; -{ - size_t off; - - /* Fill in the header. */ - bzero(hdr, hdrsize); - off = 0; - __elfN(puthdr)(td, hdr, &off, numsegs); - - /* Write it to the core file. */ - return (vn_rdwr_inchunks(UIO_WRITE, vp, hdr, hdrsize, (off_t)0, - UIO_SYSSPACE, IO_UNIT | IO_DIRECT, cred, NOCRED, NULL, - td)); /* XXXKSE */ -} - #if defined(COMPAT_IA32) && __ELF_WORD_SIZE == 32 typedef struct prstatus32 elf_prstatus_t; typedef struct prpsinfo32 elf_prpsinfo_t;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200607310151.k6V1pLHa045347>