⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hppab-tdep.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Machine-dependent code which would otherwise be in inflow.c and core.c,   for GDB, the GNU debugger.  This code is for the HP PA-RISC cpu.   Copyright 1986, 1987, 1989, 1990, 1991, 1992 Free Software Foundation, Inc.   Contributed by the Center for Software Science at the   University of Utah (pa-gdb-bugs@cs.utah.edu).This file is part of GDB.This program is free software; you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation; either version 2 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */#include "defs.h"#include "frame.h"#include "inferior.h"#include "value.h"/* For argument passing to the inferior */#include "symtab.h"#ifdef USG#include <sys/types.h>#endif#include <sys/param.h>#include <sys/dir.h>#include <signal.h>#include <sys/ioctl.h>#ifdef COFF_ENCAPSULATE#include "a.out.encap.h"#else#include <a.out.h>#endif#ifndef N_SET_MAGIC#define N_SET_MAGIC(exec, val) ((exec).a_magic = (val))#endif/*#include <sys/user.h>		After a.out.h  */#include <sys/file.h>#include <sys/stat.h>#include <machine/psl.h>#ifdef KERNELDEBUG#include <sys/vmmac.h>#include <machine/machparam.h>#include <machine/vmparam.h>#include <machine/pde.h>#include <machine/cpu.h>#include <machine/iomod.h>#include <machine/pcb.h>#include <machine/rpb.h>#include <ctype.h>extern int kernel_debugging;extern CORE_ADDR startup_file_start;extern CORE_ADDR startup_file_end;#define	KERNOFF		((unsigned)KERNBASE)#define	INKERNEL(x)	((x) >= KERNOFF && (x) < KERNOFF + ctob(slr))static int ok_to_cache();static void set_kernel_boundaries();int devmem = 0;int vtophys_ready = 0;int kerneltype;#define	OS_BSD	1#define	OS_MACH	2#endif#include "gdbcore.h"#include "gdbcmd.h"extern int errno;/* Last modification time of executable file.   Also used in source.c to compare against mtime of a source file.  */extern int exec_mtime;/* Virtual addresses of bounds of the two areas of memory in the core file.  *//* extern CORE_ADDR data_start; */extern CORE_ADDR data_end;extern CORE_ADDR stack_start;extern CORE_ADDR stack_end;/* Virtual addresses of bounds of two areas of memory in the exec file.   Note that the data area in the exec file is used only when there is no core file.  */extern CORE_ADDR text_start;extern CORE_ADDR text_end;extern CORE_ADDR exec_data_start;extern CORE_ADDR exec_data_end;/* Address in executable file of start of text area data.  */extern int text_offset;/* Address in executable file of start of data area data.  */extern int exec_data_offset;/* Address in core file of start of data area data.  */extern int data_offset;/* Address in core file of start of stack area data.  */extern int stack_offset;struct header file_hdr;struct som_exec_auxhdr exec_hdr;#ifdef KERNELDEBUG/* * Kernel debugging routines. */static struct pcb pcb;static struct pde *pdir;static struct hte *htbl;static u_int npdir, nhtbl;static CORE_ADDRksym_lookup(name)	char *name;{	struct symbol *sym;	int i;	if ((i = lookup_misc_func(name)) < 0)		error("kernel symbol `%s' not found.", name);	return (misc_function_vector[i].address);}/* * (re-)set the variables that tell "inside_entry_file" where to end * a stack backtrace. */voidset_kernel_boundaries(){	switch (kerneltype) {	case OS_MACH:		startup_file_start = ksym_lookup("$syscall");		startup_file_end = ksym_lookup("trap");		break;	case OS_BSD:		startup_file_start = ksym_lookup("syscallinit");		startup_file_end = ksym_lookup("$syscallexit");		break;	}}/* * return true if 'len' bytes starting at 'addr' can be read out as * longwords and/or locally cached (this is mostly for memory mapped * i/o register access when debugging remote kernels). */static intok_to_cache(addr, len){	static CORE_ADDR ioptr;	if (! ioptr)		ioptr = ksym_lookup("ioptr");	if (addr >= ioptr && addr < SPA_HIGH)		return (0);	return (1);}staticphysrd(addr, dat, len)	u_int addr;	char *dat;{	if (lseek(corechan, addr, L_SET) == -1)		return (-1);	if (read(corechan, dat, len) != len)		return (-1);	return (0);}/* * When looking at kernel data space through /dev/mem or with a core file, do * virtual memory mapping. */static CORE_ADDRvtophys(space, addr)	unsigned space;	CORE_ADDR addr;{	struct pde *pptr;	u_int hindx, vpageno, ppageno;	CORE_ADDR phys = ~0;	if (!vtophys_ready) {		phys = addr;		/* XXX for kvread */	} else if (kerneltype == OS_BSD) {		/* make offset into a virtual page no */		vpageno = btop(addr);		/*		 *  Determine index into hash table, initialize pptr to this		 *  entry (since first word of pte & hte are same), and set		 *  physical page number for first entry in chain.		 */		hindx = pdirhash(space, addr) & (nhtbl-1);		pptr = (struct pde *) &htbl[hindx];		ppageno = pptr->pde_next;		while (1) {			if (pptr->pde_end)				break;			pptr = &pdir[ppageno];			/*			 *  If space id & virtual page number match, return			 *  "next PDIR entry of previous PDIR entry" as the			 *  physical page or'd with offset into page.			 */			if (pptr->pde_space == space &&			    pptr->pde_page == vpageno) {				phys = (CORE_ADDR) ((u_int)ptob(ppageno) |						    (addr & PGOFSET));				break;			}			ppageno = pptr->pde_next;		}	}#ifdef MACHKERNELDEBUG	else if (kerneltype == OS_MACH) {	  mach_vtophys(space, addr, &phys);	}#endif#if 0	printf("vtophys(%x.%x) -> %x\n", space, addr, phys);#endif	return (phys);}statickvread(addr)	CORE_ADDR addr;{	CORE_ADDR paddr;	paddr = vtophys(0, addr);	if (paddr != ~0)		if (physrd(paddr, (char *)&addr, sizeof(addr)) == 0)			return (addr);	return (~0);}static voidread_pcb(addr)     u_int addr;{	int i, off;	extern char registers[];	static int reg2pcb[] = {		/* RPB */		-1,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,		18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33,		45, 52, 51, 75, 74, 49, 53, 54, 55, 56, -1, 70, 66, 67, 68, 69,		71, 72, 73, 34, 42, 43, 44, 46, 47, 58, 59, 60, -1, -1, -1, -1,		-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,		-1, -1, -1, -1,		/* BSD */		-1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,		15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,		43, 64, 67, 68, 67, 47, 51, 52, 53, 54, -1, 35, 31, 32, 33, 34,		36, 37, 38, 39, 40, 41, 42, 44, 45, 56, 57, 58,102,103,104, -1,		70, 71, 72, 73, 74, 75, 76, 77, 78, 80, 82, 84, 86, 88, 90, 92,		94, 96, 98, 100,		/* Mach */		-1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13,		14, 15, 16, -1, -1, -1, -1, -1, -1, -1, -1, 17, -1, -1, 18, -1,		25, -1, -1, -1, -1, 30, -1, -1, -1, -1, -1, 20, -1, -1, -1, 19,		21, 22, 23, 24, 26, 27, -1, 28, 29, -1, -1, -1, -1, -1, -1, -1,		34, 35, 36, 37, 38, 39, 40, 41, -1, -1, -1, -1, -1, -1, -1, -1,		42, 44, 46, 48	};	static struct rpb *rpbaddr = (struct rpb *) 0;	static u_int rpbpcbaddr = 0;	if (!remote_debugging) {		/*		 * If we are debugging a post-mortem and this is the first		 * call of read_pcb, read the RPB.  Also assoicate the		 * thread/proc running at the time with the RPB.		 */		if (!devmem && rpbpcbaddr == 0) {			CORE_ADDR raddr = ksym_lookup("rpb");			int usepcb = 1;			if (raddr != ~0) {				rpbaddr = (struct rpb *) malloc(sizeof *rpbaddr);				if (!physrd(raddr, (char *)rpbaddr, sizeof *rpbaddr)) {					rpbpcbaddr = addr;					usepcb = 0;				}			}			if (usepcb) {				error("cannot read rpb, using pcb for registers\n");				if (rpbaddr)					free((char *)rpbaddr);				rpbpcbaddr = ~0;			}		}		if (physrd (addr, (char *)&pcb, sizeof pcb))			error ("cannot read pcb at %x.\n", addr);	} else {		if (remote_read_inferior_memory(addr, (char *)&pcb, sizeof pcb))			error ("cannot read pcb at %x.\n", addr);	}	if (kerneltype == OS_BSD) {		printf("p0br %lx p0lr %lx p1br %lx p1lr %lx\n",		       pcb.pcb_p0br, pcb.pcb_p0lr, pcb.pcb_p1br, pcb.pcb_p1lr);		off = NUM_REGS;	} else {		printf("pcb %lx psw %lx ksp %lx\n",		       addr, ((int *)&pcb)[31], ((int *)&pcb)[32]);		off = NUM_REGS * 2;	}	/*	 * get the register values out of the sys pcb and	 * store them where `read_register' will find them.	 */	bzero(registers, REGISTER_BYTES);	for (i = 0; i < NUM_REGS; ++i)		if (reg2pcb[i+off] != -1)			supply_register(i, &((int *)&pcb)[reg2pcb[i+off]]);	/*	 * If the RPB is valid for this thread/proc use the register values	 * contained there.	 */	if (addr == rpbpcbaddr) {		off = 0;		for (i = 0; i < NUM_REGS; ++i)			if (reg2pcb[i+off] != -1)				supply_register(i, &((int *)rpbaddr)[reg2pcb[i+off]]);	}}voidsetup_kernel_debugging(){	struct stat stb;	CORE_ADDR addr;	fstat(corechan, &stb);	devmem = 0;	if ((stb.st_mode & S_IFMT) == S_IFCHR && stb.st_rdev == makedev(2, 0))		devmem = 1;	/* XXX */	if (lookup_misc_func("Sysmap") < 0)		kerneltype = OS_MACH;	else		kerneltype = OS_BSD;	if (kerneltype == OS_BSD) {		int len, err = 0;		/*		 * Hash table and PDIR are equivalently mapped		 */		nhtbl = kvread(ksym_lookup("nhtbl"));		if (nhtbl != ~0) {			len = nhtbl * sizeof(*htbl);			htbl = (struct hte *) malloc(len);			if (htbl) {				addr = kvread(ksym_lookup("htbl"));				if (physrd(addr, (char *)htbl, len))					err++;			} else				err++;		} else			err++;		npdir = kvread(ksym_lookup("npdir"));		if (npdir != ~0) {			len = npdir * sizeof(*pdir);			pdir = (struct pde *) malloc(len);			if (pdir) {				addr = kvread(ksym_lookup("pdir"));				if (physrd(addr, (char *)pdir, len))					err++;			} else				err++;		} else			err++;		if (err) {			error("cannot read PDIR/HTBL");			return;		}		vtophys_ready = 1;		/*		 * pcb where "panic" saved registers in first thing in		 * current u-area.  The current u-area is pointed to by		 * "uptr".		 */		addr = kvread(ksym_lookup("uptr"));		if (addr == ~0) {			error("cannot read current u-area address");			return;		}		read_pcb(vtophys(0, addr));	/* XXX space */		if (!devmem) {			/* find stack frame */			CORE_ADDR panicstr;			char buf[256];			register char *cp;						panicstr = kvread(ksym_lookup("panicstr"));			if (panicstr == ~0)				return;			kernel_core_file_hook(panicstr, buf, sizeof(buf));			for (cp = buf; cp < &buf[sizeof(buf)] && *cp; cp++)				if (!isascii(*cp) || (!isprint(*cp) && !isspace(*cp)))					*cp = '?';			if (*cp)				*cp = '\0';			printf("panic: %s\n", buf);		}	}#ifdef MACHKERNELDEBUG	else {		int *thread;		/*		 * Set up address translation		 */		if (mach_vtophys_init() == 0) {			error("cannot initialize vtophys for Mach");			return;		}		vtophys_ready = 1;		/*		 * Locate active thread and read PCB		 * XXX MAJOR HACK		 *	- assumes uni-processor		 *	- assumes position of pcb to avoid mach includes		 */		thread = (int *)kvread(ksym_lookup("active_threads"));		addr = kvread(&thread[9]);		/* XXX: pcb addr */		read_pcb(vtophys(0, addr));	}#endif}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -