PERFORCE change 102819 for review
Marcel Moolenaar
marcel at FreeBSD.org
Mon Jul 31 01:51:22 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=102819
Change 102819 by marcel at 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;
More information about the p4-projects
mailing list