📄 coredump.c
字号:
/*@(#)coredump.c 4.2 Ultrix 11/9/90*//************************************************************************ * * * Copyright (c) 1986 by * * Digital Equipment Corporation, Maynard, MA * * All rights reserved. * * * * This software is furnished under a license and may be used and * * copied only in accordance with the terms of such license and * * with the inclusion of the above copyright notice. This * * software or any other copies thereof may not be provided or * * otherwise made available to any other person. No title to and * * ownership of the software is hereby transferred. * * * * This software is derived from software received from the * * University of California, Berkeley, and from Bell * * Laboratories. Use, duplication, or disclosure is subject to * * restrictions under license agreements with University of * * California and with AT&T. * * * * The information in this software is subject to change without * * notice and should not be construed as a commitment by Digital * * Equipment Corporation. * * * * Digital assumes no responsibility for the use or reliability * * of its software on equipment which is not supplied by Digital. * * * ************************************************************************//************************************************************************ * * * Modification History * * * * 004 - Added support for vectors. * * (L Miller, 18JAN90) * * * * 003 - Merged in 4.3 changes. * * (vjh, April 29, 1986) * * * * 002 - Added lookup for symbol 'cpudata' in getkerinfo(); * * this symbol used to be called 'masterpaddr', but was * * changed in the MP version. * * (Victoria Holt, April 16, 1986) * * * * 001 - Removed reference to u_exdata, as it no longer exists. * * (Greg Depp, April 8, 1986) * * * ************************************************************************//* * Copyright (c) 1983 Regents of the University of California. * All rights reserved. The Berkeley software License Agreement * specifies the terms and conditions for redistribution. */#ifndef lintstatic char sccsid[] = "@(#)coredump.c 5.1 (Berkeley) 5/31/85";#endif not lintstatic char rcsid[] = "$Header: coredump.c,v 1.5 84/12/26 10:38:56 linton Exp $";/* * Deal with the core dump anachronism. */#include "defs.h"#include "coredump.h"#include "machine.h"#include "object.h"#include "main.h"#include "process.h"#include <sys/types.h>#include <sys/stat.h>#include <sys/param.h>#include <sys/dir.h>#ifndef NOVECTORS#include <sys/acct.h>#endif /* NOVECTORS */#include <machine/psl.h>#include <machine/pte.h>#include <sys/user.h>#include <sys/vm.h>#include <machine/reg.h>#include <a.out.h>#ifndef public#define coredump_readin(m, r, s) coredump_xreadin(&(m), r, &(s))#include "machine.h"#endif#define MAXSTKADDR (USRSTACK) /* highest stack address *//* USRSTACK = (0x80000000 - ctob(UPAGES + FORKPAGES))*/ typedef struct { Address begin; Address end; Address seekaddr;} Map;private Map datamap, stkmap;private File objfile;private struct exec hdr;/* * Special variables for debugging the kernel. */private integer masterpcbb;private integer slr;private struct pte *sbr;private struct pcb pcb;private getpcb (){ fseek(corefile, masterpcbb & ~0x80000000, 0); get(corefile, pcb); pcb.pcb_p0lr &= ~AST_CLR; printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n", pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr ); setreg(0, pcb.pcb_r0); setreg(1, pcb.pcb_r1); setreg(2, pcb.pcb_r2); setreg(3, pcb.pcb_r3); setreg(4, pcb.pcb_r4); setreg(5, pcb.pcb_r5); setreg(6, pcb.pcb_r6); setreg(7, pcb.pcb_r7); setreg(8, pcb.pcb_r8); setreg(9, pcb.pcb_r9); setreg(10, pcb.pcb_r10); setreg(11, pcb.pcb_r11); setreg(ARGP, pcb.pcb_ap); setreg(FRP, pcb.pcb_fp); setreg(STKP, pcb.pcb_ksp); setreg(PROGCTR, pcb.pcb_pc);}public coredump_getkerinfo (){ Symbol s; s = lookup(identname("Sysmap", true)); if (s == nil) { panic("can't find 'Sysmap'"); } sbr = (struct pte *) (s->symvalue.offset); s = lookup(identname("Syssize", true)); if (s == nil) { panic("can't find 'Syssize'"); } slr = (integer) (s->symvalue.offset); printf("sbr %lx slr %lx\n", sbr, slr); s = lookup(identname("cpudata", true)); /* added for MP */ if (s == nil) { s = lookup(identname("masterpaddr", true)); if (s == nil) { panic("can't find 'cpudata' or 'masterpaddr'"); } } fseek( corefile, datamap.seekaddr + s->symvalue.offset&0x7fffffff - datamap.begin, 0 ); get(corefile, masterpcbb); masterpcbb = (masterpcbb&PG_PFNUM)*512; getpcb();}private copyregs (savreg, reg)Word savreg[], reg[];{ reg[0] = savreg[R0]; reg[1] = savreg[R1]; reg[2] = savreg[R2]; reg[3] = savreg[R3]; reg[4] = savreg[R4]; reg[5] = savreg[R5]; reg[6] = savreg[R6]; reg[7] = savreg[R7]; reg[8] = savreg[R8]; reg[9] = savreg[R9]; reg[10] = savreg[R10]; reg[11] = savreg[R11]; reg[ARGP] = savreg[AP]; reg[FRP] = savreg[FP]; reg[STKP] = savreg[SP]; reg[PROGCTR] = savreg[PC];}/* * Read the user area information from the core dump. */public coredump_xreadin(mask, reg, signo)int *mask;Word reg[];int *signo;{ register struct user *up; register Word *savreg; union { struct user u; char dummy[ctob(UPAGES)]; } ustruct; Symbol s; objfile = fopen(objname, "r"); if (objfile == nil) { fatal("can't read \"%s\"", objname); } get(objfile, hdr); if (vaddrs) { datamap.begin = 0; datamap.end = 0xffffffff; stkmap.begin = 0xffffffff; stkmap.end = 0xffffffff; } else { up = &(ustruct.u); fread(up, ctob(UPAGES), 1, corefile); savreg = (Word *) &(ustruct.dummy[ctob(UPAGES)]); *mask = savreg[PS]; copyregs(savreg, reg); *signo = up->u_arg[0]; datamap.seekaddr = ctob(UPAGES); stkmap.begin = MAXSTKADDR - ctob(up->u_ssize); stkmap.end = MAXSTKADDR; stkmap.seekaddr = datamap.seekaddr + ctob(up->u_dsize); switch (hdr.a_magic) { case OMAGIC: datamap.begin = 0; datamap.end = ctob(up->u_tsize) + ctob(up->u_dsize); break; case NMAGIC: case ZMAGIC: datamap.begin = (Address) ptob(btop(ctob(up->u_tsize) - 1) + 1); datamap.end = datamap.begin + ctob(up->u_dsize); break; default: fatal("bad magic number 0x%x", hdr.a_magic); }#ifndef NOVECTORS if(vectorcapable && up->u_acflag & AVP) { put_vregs(corefile); }#endif /* NOVECTORS */#ifdef UXMAG /* * Core dump not from this object file? */ if (hdr.a_magic != 0 and up->u_exdata.ux_mag != 0 and hdr.a_magic != up->u_exdata.ux_mag) { warning("core dump ignored"); coredump = false; fclose(corefile); fclose(objfile); start(nil, nil, nil); }#endif }}public coredump_close(){ fclose(objfile);}public coredump_readtext(buff, addr, nbytes)char *buff;Address addr;int nbytes;{ if (hdr.a_magic == OMAGIC or vaddrs) { coredump_readdata(buff, addr, nbytes); } else { fseek(objfile, N_TXTOFF(hdr) + addr, 0); fread(buff, nbytes, sizeof(Byte), objfile); }}/* * Map a virtual address to a physical address. */private Address vmap (addr)Address addr;{ Address r; integer v, n; struct pte pte; r = addr & ~0xc0000000; v = btop(r); switch (addr&0xc0000000) { case 0xc0000000: case 0x80000000: /* * In system space, so get system pte. * If it is valid or reclaimable then the physical address * is the combination of its page number and the page offset * of the original address. */ if (v >= slr) { error("address %x out of segment", addr); } r = ((long) (sbr + v)) & ~0x80000000; goto simple; case 0x40000000: /* * In p1 space, must not be in shadow region. */ if (v < pcb.pcb_p1lr) { error("address %x out of segment", addr); } r = (Address) (pcb.pcb_p1br + v); break; case 0x00000000: /* * In p0 space, must not be off end of region. */ if (v >= pcb.pcb_p0lr) { error("address %x out of segment", addr); } r = (Address) (pcb.pcb_p0br + v); break; default: /* do nothing */ break; } /* * For p0/p1 address, user-level page table should be in * kernel virtual memory. Do second-level indirect by recursing. */ if ((r & 0x80000000) == 0) { error("bad p0br or p1br in pcb"); } r = vmap(r);simple: /* * "r" is now the address of the pte of the page * we are interested in; get the pte and paste up the physical address. */ fseek(corefile, r, 0); n = fread(&pte, sizeof(pte), 1, corefile); if (n != 1) { error("page table botch (fread at %x returns %d)", r, n); } if (pte.pg_v == 0 and (pte.pg_fod != 0 or pte.pg_pfnum == 0)) { error("page no valid or reclamable"); } return (addr&PGOFSET) + ((Address) ptob(pte.pg_pfnum));}public coredump_readdata(buff, addr, nbytes)char *buff;Address addr;int nbytes;{ Address a; a = addr; if (a < datamap.begin) { if (hdr.a_magic == OMAGIC) { error("[data address 0x%x too low (lb = 0x%x)]", a, datamap.begin); } else { coredump_readtext(buff, a, nbytes); } } else if (a > stkmap.end) { error("data address 0x%x too high (ub = 0x%x)", a, stkmap.end); } else { if (vaddrs) { vreadfromfile(corefile, a, buff, nbytes); } else { readfromfile(corefile, a, buff, nbytes); } }}/* * Read a block of data from a memory image, mapping virtual addresses. * Have to watch out for page boundaries. */private vreadfromfile (corefile, v, buff, nbytes)File corefile;Address v;char *buff;integer nbytes;{ Address a; integer i, remainder, pagesize; char *bufp; a = v; pagesize = (integer) ptob(1); remainder = pagesize - (a mod pagesize); if (remainder >= nbytes) { readfromfile(corefile, vmap(a), buff, nbytes); } else { readfromfile(corefile, vmap(a), buff, remainder); a += remainder; i = nbytes - remainder; bufp = buff + remainder; while (i > pagesize) { readfromfile(corefile, vmap(a), bufp, pagesize); a += pagesize; bufp += pagesize; i -= pagesize; } readfromfile(corefile, vmap(a), bufp, i); }}private readfromfile (f, a, buff, nbytes)File f;Address a;char *buff;integer nbytes;{ integer fileaddr; static corefile_size = -1; if (a < stkmap.begin) { fileaddr = datamap.seekaddr + a - datamap.begin; } else { fileaddr = stkmap.seekaddr + a - stkmap.begin; } if(corefile_size == -1) { struct stat buf; if(fstat(fileno(f), &buf) == 0) corefile_size = buf.st_size; } if(fileaddr > corefile_size) { coredump = false; fclose(corefile); error("\nattempting to read pass EOF on corefile, closing corefile"); } fseek(f, fileaddr, 0); fread(buff, nbytes, sizeof(Byte), f);}public Word readvregfromfile (f, a)File f;Address a;{ integer fileaddr; static corefile_size = -1; Word buff; if(!coredump) return(0); fileaddr = a + stkmap.seekaddr + (stkmap.end - stkmap.begin); if(corefile_size == -1) { struct stat buf; if(fstat(fileno(f), &buf) == 0) corefile_size = buf.st_size; } if(fileaddr > corefile_size) { coredump = false; fclose(corefile); error("\nattempting to read pass EOF on corefile, closing corefile"); } fseek(f, fileaddr, 0); fread(&buff, 1, sizeof(Word), f); return(buff);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -