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