PERFORCE change 50373 for review
Marcel Moolenaar
marcel at FreeBSD.org
Sun Apr 4 19:48:46 PDT 2004
http://perforce.freebsd.org/chv.cgi?CH=50373
Change 50373 by marcel at 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*)¬e, 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)
More information about the p4-projects
mailing list