svn commit: r260009 - head/sys/ia64/ia64

Marcel Moolenaar marcel at FreeBSD.org
Sat Dec 28 19:54:20 UTC 2013


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;


More information about the svn-src-head mailing list