From owner-svn-src-all@FreeBSD.ORG Sat Dec 28 19:54:20 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 361D8B14; Sat, 28 Dec 2013 19:54:20 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 22076158B; Sat, 28 Dec 2013 19:54:20 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rBSJsJ3t029376; Sat, 28 Dec 2013 19:54:19 GMT (envelope-from marcel@svn.freebsd.org) Received: (from marcel@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id rBSJsJgI029375; Sat, 28 Dec 2013 19:54:19 GMT (envelope-from marcel@svn.freebsd.org) Message-Id: <201312281954.rBSJsJgI029375@svn.freebsd.org> From: Marcel Moolenaar Date: Sat, 28 Dec 2013 19:54:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r260009 - head/sys/ia64/ia64 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 28 Dec 2013 19:54:20 -0000 Author: marcel Date: Sat Dec 28 19:54:19 2013 New Revision: 260009 URL: http://svnweb.freebsd.org/changeset/base/260009 Log: Add a virt_foreach() that does the same as what phys_foreach() does and change virt_size(), virt_dumphdrs() and virt_dumpdata() into its callback functions. In virt_foreach() we iterate over all the virtual memory regions that we want in the minidump. For now, just start with the PBVM (= kernel text and data plus preloaded modules). The core file this produces can already be used to work out the libkvm changes that need to be made to support it. In parallel, we can flesh out the in-kernel bits to dump more of what we need in a minidump without changing the core file structure. Modified: head/sys/ia64/ia64/dump_machdep.c Modified: head/sys/ia64/ia64/dump_machdep.c ============================================================================== --- head/sys/ia64/ia64/dump_machdep.c Sat Dec 28 19:23:16 2013 (r260008) +++ head/sys/ia64/ia64/dump_machdep.c Sat Dec 28 19:54:19 2013 (r260009) @@ -219,27 +219,113 @@ phys_foreach(phys_callback_t cb, void *a * Virtual dump (aka minidump) support */ +typedef int virt_callback_t(vm_offset_t, vm_size_t, int, void*); + static int -virt_size(uint64_t *dumpsize) +virt_cb_size(vm_offset_t va, vm_size_t sz, int seqnr, void *arg) { + uint64_t *dumpsize = (uint64_t *)arg; + *dumpsize += sz; return (0); } static int -virt_dumphdrs(struct dumperinfo *di) +virt_cb_dumphdr(vm_offset_t va, vm_size_t sz, int seqnr, void *arg) { - - return (-ENOSYS); + struct dumperinfo *di = (struct dumperinfo *)arg; + Elf64_Phdr phdr; + int error; + + bzero(&phdr, sizeof(phdr)); + phdr.p_type = PT_LOAD; + phdr.p_flags = PF_R; /* XXX */ + phdr.p_offset = fileofs; + phdr.p_vaddr = va; + phdr.p_paddr = ~0UL; + phdr.p_filesz = sz; + phdr.p_memsz = sz; + phdr.p_align = PAGE_SIZE; + + error = buf_write(di, (char*)&phdr, sizeof(phdr)); + fileofs += phdr.p_filesz; + return (error); } static int -virt_dumpdata(struct dumperinfo *di) +virt_cb_dumpdata(vm_offset_t va, vm_size_t sz, int seqnr, void *arg) { + struct dumperinfo *di = (struct dumperinfo *)arg; + size_t counter, iosz; + int c, error, twiddle; + + error = 0; /* catch case in which pgs is 0 */ + counter = 0; /* Update twiddle every 16MB */ + twiddle = 0; + + printf(" chunk %d: %ld pages ", seqnr, atop(sz)); + + while (sz) { + iosz = (sz > DFLTPHYS) ? DFLTPHYS : sz; + counter += iosz; + if (counter >> 24) { + printf("%c\b", "|/-\\"[twiddle++ & 3]); + counter &= (1<<24) - 1; + } +#ifdef SW_WATCHDOG + wdog_kern_pat(WD_LASTVAL); +#endif + error = dump_write(di, (void*)va, 0, dumplo, iosz); + if (error) + break; + dumplo += iosz; + sz -= iosz; + va += iosz; + + /* Check for user abort. */ + c = cncheckc(); + if (c == 0x03) + return (ECANCELED); + if (c != -1) + printf("(CTRL-C to abort) "); + } + printf("... %s\n", (error) ? "fail" : "ok"); + return (error); +} - return (-ENOSYS); +static int +virt_foreach(virt_callback_t cb, void *arg) +{ + vm_offset_t va; + vm_size_t sz; + int error, seqnr; + + seqnr = 0; + while (1) { + switch (seqnr) { + case 0: + va = IA64_PBVM_BASE; + sz = round_page(bootinfo->bi_kernend) - va; + break; + default: + va = 0; + sz = 0; + break; + } + if (va == 0 && sz == 0) + break; + error = (*cb)(va, sz, seqnr, arg); + if (error) + return (-error); + seqnr++; + } + return (seqnr); } +/* + * main entry point. + */ + void dumpsys(struct dumperinfo *di) { @@ -274,7 +360,7 @@ dumpsys(struct dumperinfo *di) /* Calculate dump size. */ dumpsize = 0L; - status = (minidump) ? virt_size(&dumpsize) : + status = (minidump) ? virt_foreach(virt_cb_size, &dumpsize) : phys_foreach(phys_cb_size, &dumpsize); if (status < 0) { error = -status; @@ -311,7 +397,7 @@ dumpsys(struct dumperinfo *di) goto fail; /* Dump program headers */ - status = (minidump) ? virt_dumphdrs(di) : + status = (minidump) ? virt_foreach(virt_cb_dumphdr, di) : phys_foreach(phys_cb_dumphdr, di); if (status < 0) { error = -status; @@ -329,7 +415,7 @@ dumpsys(struct dumperinfo *di) dumplo += hdrgap; /* Dump memory chunks (updates dumplo) */ - status = (minidump) ? virt_dumpdata(di) : + status = (minidump) ? virt_foreach(virt_cb_dumpdata, di) : phys_foreach(phys_cb_dumpdata, di); if (status < 0) { error = -status;