Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 4 Apr 2004 19:48:45 -0700 (PDT)
From:      Marcel Moolenaar <marcel@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 50373 for review
Message-ID:  <200404050248.i352mj1w011371@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=50373

Change 50373 by marcel@marcel_nfs on 2004/04/04 19:47:59

	Dump the register state of the kernel threads as NT_PRSTATUS
	notes so that we have the threads visible in gdb(1). We only
	need a kernel debugging mode in gdb(1) for virtual address
	translation.

Affected files ...

.. //depot/projects/gdb/sys/ia64/ia64/dump_machdep.c#2 edit

Differences ...

==== //depot/projects/gdb/sys/ia64/ia64/dump_machdep.c#2 (text+ko) ====

@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Marcel Moolenaar
+ * Copyright (c) 2002-2004 Marcel Moolenaar
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,8 @@
 #include <sys/cons.h>
 #include <sys/kernel.h>
 #include <sys/kerneldump.h>
+#include <sys/proc.h>
+#include <sys/procfs.h>
 #include <vm/vm.h>
 #include <vm/pmap.h>
 #include <machine/bootinfo.h>
@@ -52,8 +54,13 @@
 
 typedef int callback_t(EFI_MEMORY_DESCRIPTOR*, int, void*);
 
+extern int osreldate;
+
 static struct kerneldumpheader kdh;
 static off_t dumplo, fileofs;
+static char notenm[] = "FreeBSD";
+static size_t notesz;
+static int nthreads;
 
 /* Handle buffered writes. */
 static char buffer[DEV_BSIZE];
@@ -117,10 +124,88 @@
 
 	error = di->dumper(di->priv, buffer, 0, dumplo, DEV_BSIZE);
 	dumplo += DEV_BSIZE;
+	fragsz = 0;
 	return (error);
 }
 
 static int
+note_size(uint64_t *sz)
+{
+	struct proc *p;
+	struct thread *t;
+
+	nthreads = 0;
+	LIST_FOREACH(p, &allproc, p_list) {
+		FOREACH_THREAD_IN_PROC(p, t) {
+			nthreads++;
+		}
+	}
+	notesz = sizeof(Elf_Note) + sizeof(notenm) + sizeof(prstatus_t);
+	notesz *= nthreads;
+	*sz = MD_ALIGN(notesz);
+	return (1);
+}
+
+static int
+note_hdr(struct dumperinfo *di)
+{
+	Elf64_Phdr phdr;
+	int error;
+
+	bzero(&phdr, sizeof(phdr));
+	phdr.p_type = PT_NOTE;
+	phdr.p_offset = fileofs;
+	phdr.p_filesz = notesz;
+
+	error = buf_write(di, (char*)&phdr, sizeof(phdr));
+	fileofs += MD_ALIGN(notesz);
+	return (error);
+}
+
+static int
+note_data(struct dumperinfo *di)
+{
+	prstatus_t pr;
+	Elf_Note note;
+	struct proc *p;
+	struct thread *t;
+	int error;
+
+	note.n_namesz = sizeof(notenm);
+	note.n_descsz = sizeof(pr);
+	note.n_type = NT_PRSTATUS;
+	error = 0;
+	LIST_FOREACH(p, &allproc, p_list) {
+		FOREACH_THREAD_IN_PROC(p, t) {
+			error = buf_write(di, (char*)&note, sizeof(note));
+			if (error)
+				return (error);
+			error = buf_write(di, notenm, sizeof(notenm));
+			if (error)
+				return (error);
+			pr.pr_version = PRSTATUS_VERSION;
+			pr.pr_statussz = sizeof(prstatus_t);
+			pr.pr_gregsetsz = sizeof(gregset_t);
+			pr.pr_fpregsetsz = sizeof(fpregset_t);
+			pr.pr_osreldate = osreldate;
+			pr.pr_cursig = 0;
+			pr.pr_pid = t->td_tid;
+			if (t->td_last_frame != NULL)
+				t->td_frame = t->td_last_frame;
+			fill_regs(t, &pr.pr_reg);
+			error = buf_write(di, (char*)&pr, sizeof(pr));
+			if (error)
+				return (error);
+		}
+	}
+	error = buf_flush(di);
+	if (error)
+		return (error);
+	dumplo += MD_ALIGN(notesz) - DEV_ALIGN(notesz);
+	return (0);
+}
+
+static int
 cb_dumpdata(EFI_MEMORY_DESCRIPTOR *mdp, int seqnr, void *arg)
 {
 	struct dumperinfo *di = (struct dumperinfo*)arg;
@@ -135,7 +220,7 @@
 	pgs = mdp->NumberOfPages;
 	pa = IA64_PHYS_TO_RR7(mdp->PhysicalStart);
 
-	printf("  chunk %d: %ld pages ", seqnr, (long)pgs);
+	printf("  chunk %d: %ld pages ", seqnr + 1, (long)pgs);
 
 	while (pgs) {
 		sz = (pgs > (DFLTPHYS >> EFI_PAGE_SHIFT))
@@ -239,7 +324,7 @@
 	ehdr.e_ident[EI_DATA] = ELFDATA2MSB;
 #endif
 	ehdr.e_ident[EI_VERSION] = EV_CURRENT;
-	ehdr.e_ident[EI_OSABI] = ELFOSABI_STANDALONE;	/* XXX big picture? */
+	ehdr.e_ident[EI_OSABI] = ELFOSABI_FREEBSD;
 	ehdr.e_type = ET_CORE;
 	ehdr.e_machine = EM_IA_64;
 	ehdr.e_phoff = sizeof(ehdr);
@@ -249,8 +334,8 @@
 	ehdr.e_shentsize = sizeof(Elf64_Shdr);
 
 	/* Calculate dump size. */
-	dumpsize = 0L;
-	ehdr.e_phnum = foreach_chunk(cb_size, &dumpsize);
+	ehdr.e_phnum = note_size(&dumpsize);
+	ehdr.e_phnum += foreach_chunk(cb_size, &dumpsize);
 	hdrsz = ehdr.e_phoff + ehdr.e_phnum * ehdr.e_phentsize;
 	fileofs = MD_ALIGN(hdrsz);
 	dumpsize += fileofs;
@@ -266,8 +351,8 @@
 
 	mkdumpheader(&kdh, KERNELDUMP_IA64_VERSION, dumpsize, di->blocksize);
 
-	printf("Dumping %llu MB (%d chunks)\n", (long long)dumpsize >> 20,
-	    ehdr.e_phnum);
+	printf("Dumping %llu MB (%d memory chunks; %d threads)\n",
+	    (long long)dumpsize >> 20, ehdr.e_phnum - 1, nthreads);
 
 	/* Dump leader */
 	error = di->dumper(di->priv, &kdh, 0, dumplo, sizeof(kdh));
@@ -280,6 +365,10 @@
 	if (error)
 		goto fail;
 
+	/* Dump note header. */
+	error = note_hdr(di);
+	if (error < 0)
+		goto fail;
 	/* Dump program headers */
 	error = foreach_chunk(cb_dumphdr, di);
 	if (error < 0)
@@ -288,13 +377,17 @@
 
 	/*
 	 * All headers are written using blocked I/O, so we know the
-	 * current offset is (still) block aligned. Skip the alignement
+	 * current offset is (still) block aligned. Skip the alignment
 	 * in the file to have the segment contents aligned at page
 	 * boundary. We cannot use MD_ALIGN on dumplo, because we don't
 	 * care and may very well be unaligned within the dump device.
 	 */
 	dumplo += hdrgap;
 
+	/* Dump note segment. */
+	error = note_data(di);
+	if (error < 0)
+		goto fail;
 	/* Dump memory chunks (updates dumplo) */
 	error = foreach_chunk(cb_dumpdata, di);
 	if (error < 0)



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200404050248.i352mj1w011371>