📄 privateice.c
字号:
/****************************************************************************** * * Copyright (c) 2003 Gerhard W. Gruber * * PROJECT: pICE * $Source: /cvsroot/pice/pice/module/privateice.c,v $ * $Revision: 1.3 $ * $Date: 2004/02/17 23:07:37 $ * $Author: lightweave $ * $Name: $ * * $Log: privateice.c,v $ * Revision 1.3 2004/02/17 23:07:37 lightweave * * Improved the DEBUG facillity and replaced the configuration handler with a * new code which now can read MS Windows INI style files. See CHANGES.txt for * more details. * Also added a macro which prevents compiling for kernels before 2.4.19. * * Revision 1.2 2003/06/18 22:00:22 lightweave * DEBUG and DEBUG_SERIAL added * * *****************************************************************************/static char *ident = "$Header: /cvsroot/pice/pice/module/privateice.c,v 1.3 2004/02/17 23:07:37 lightweave Exp $";/*++Copyright (c) 1998-2001 Klaus P. GerlicherModule Name: privateice.cAbstract:Environment: LINUX 2.2.X/2.4.X Kernel mode onlyAuthor: Klaus P. GerlicherRevision History: 16-Jul-1998: created 15-Nov-2000: general cleanup of source files 19-Jan-2001: renamed to privateice.cCopyright notice: This file may be distributed under the terms of the GNU Public License.--*/////////////////////////////////////////////////////// INCLUDES////#include "remods.h"#include <linux/kernel.h>#include <linux/module.h>#include <asm/uaccess.h>#include <linux/fs.h>#include <linux/config.h>#include <linux/sched.h>#include <asm/unistd.h>#include <linux/string.h>#include "precomp.h"#include "serial.h" #include "debug.h"////////////////////////////////////////////////////// GLOBALS////// this is for the command line to insmod (pice="...")MODULE_AUTHOR("Klaus P. Gerlicher");MODULE_DESCRIPTION("Linux system level symbolic debugger");MODULE_LICENSE("GPL");BOOLEAN bDeviceAlreadyOpen = FALSE;int major_device_number;DEBUG_PERMISSION debug_permission;static char tempPICE[1024];typedef asmlinkage int (*PFNMKNOD)(const char * filename, int mode, dev_t dev);static PFNMKNOD pice_sys_mknod = NULL;typedef asmlinkage int (*PFNUNLINK)(const char * pathname);static PFNUNLINK pice_sys_unlink = NULL;#define PICE_HEAP_SIZE (0x400000) // heap size 4MB, adjust on as needed basisint RegisterDriver(void);void UnregisterDriver(void);////////////////////////////////////////////////////// FUNCTIONS//////*************************************************************************// init_module()////*************************************************************************int init_module(void){ int rc = 0; int err; printk(KERN_INFO "PICE ************ startup \n"); memset(&debug_permission, 0, sizeof(debug_permission)); debug_permission.Mode = DBG_NONE;#ifdef DEBUG_SERIAL // first we enable output of debug strings to COM port DebugSetupSerial(1,115200); debug_permission.Mode = DBG_SERIAL; debug_permission.Level = DBL_INFO; debug_permission.Permission[DBT_MAIN] = TRUE; debug_permission.Permission[DBT_FUNCTION] = TRUE; debug_permission.Permission[DBT_SYMBOLS] = TRUE; debug_permission.Permission[DBT_INIT] = TRUE; memset(debug_permission.Permission, TRUE, sizeof(debug_permission.Permission)); debug_permission.Permission[DBT_ADDRESS] = TRUE;#endif // DEBUG_SERIAL DPRINT(PICE_DEBUG, DBT_MAIN, DBL_INFO, "********* PrivateICE *********\n"); ENTER_FUNC(); DVPRINT(PICE_DEBUG, DBT_INIT, DBL_INFO, "Get kernel mm_struct\n"); // get kernel mm_struct my_init_mm = GetInitMm(); if(!my_init_mm) { DVPRINT(KERN_ERR, DBT_INIT, DBL_ERROR, "ABORT (initial memory map not found)\n"); goto Quit; } // first thing to do before calling anything except stuff in debug.c if(!PICE_HeapInit(PICE_HEAP_SIZE)) { DVPRINT(PICE_DEBUG, DBT_MAIN, DBL_INFO, "HeapInit failed\n"); rc = -ENOMEM; goto Quit; } // initialize debugger if(InitPICE()) { mm_segment_t oldfs; // tell system we're here if(RegisterDriver() < 0) { CleanUpPICE(); rc = -EFAULT; goto Quit; } pice_sys_mknod = (PFNMKNOD)sys_call_table[__NR_mknod]; pice_sys_unlink = (PFNUNLINK)sys_call_table[__NR_unlink]; if(!pice_sys_mknod || !pice_sys_unlink) { // tell system we're gone UnregisterDriver(); // cleanup CleanUpPICE(); rc = -EFAULT; goto Quit; } oldfs = get_fs(); set_fs(KERNEL_DS); pice_sys_unlink("/dev/pice0"); if(0 > (err = pice_sys_mknod("/dev/pice0",S_IFCHR|S_IRWXUGO,MKDEV(major_device_number,0))) ) { set_fs(oldfs); sprintf(tempPICE,"PICE: couldn't create device node (err = %u)\n",-err); Print(OUTPUT_WINDOW,tempPICE); // tell system we're gone UnregisterDriver(); // cleanup CleanUpPICE(); rc = -EFAULT; goto Quit; } set_fs(oldfs); DVPRINT(PICE_DEBUG, DBT_MAIN, DBL_INFO, "installed!\n"); } else { DVPRINT(PICE_DEBUG, DBT_MAIN, DBL_INFO, "InitPICE failed\n"); rc = -EFAULT; } LEAVE_FUNC();Quit: return(rc);}//*************************************************************************// pice_open()////*************************************************************************static int pice_open(struct inode *inode, struct file *file){ DPRINT(PICE_DEBUG, DBT_MAIN, DBL_INFO, "pice_open(%p)\n", file); /* We don't want to talk to two processes at the * same time */ if (bDeviceAlreadyOpen) return -EBUSY; bDeviceAlreadyOpen = TRUE; MOD_INC_USE_COUNT; return 0;}//*************************************************************************// pice_close()////*************************************************************************#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)static int pice_close(struct inode *inode, struct file *file)#elsestatic void pice_close(struct inode *inode, struct file *file)#endif{ DPRINT(PICE_DEBUG, DBT_MAIN, DBL_INFO, "device_release(%p,%p)\n", inode, file); /* We're now ready for our next caller */ bDeviceAlreadyOpen = FALSE; MOD_DEC_USE_COUNT; #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) return 0;#endif}//*************************************************************************// pice_ioctl()////*************************************************************************static int pice_ioctl(struct inode *inode,struct file *file,unsigned int ioctl_num,unsigned long ioctl_param){// char* pFilename = (char*) ioctl_param; if(_IOC_TYPE(ioctl_num) != PICE_IOCTL_MAGIC) return -EINVAL; if(!capable(CAP_SYS_ADMIN)) { Print(OUTPUT_WINDOW,"pICE: sorry, you must have superuser privileges\n"); return -EINVAL; } switch(ioctl_num) { case PICE_IOCTL_LOAD: break; case PICE_IOCTL_RELOAD: { if(!ReloadSymbols()) { PICE_sprintf(tempPICE,"pICE: not able to reload symbols\n"); Print(OUTPUT_WINDOW,tempPICE); } } break; case PICE_IOCTL_UNLOAD: UnloadSymbols(); break; case PICE_IOCTL_BREAK: { PICE_sprintf(tempPICE,"pICE: forcible break\n"); Print(OUTPUT_WINDOW,tempPICE); // simulate an initial break DebuggerHotkey(); } break; case PICE_IOCTL_STATUS: { PDEBUGGER_STATUS_BLOCK ustatus_block_p = (PDEBUGGER_STATUS_BLOCK)ioctl_param; DEBUGGER_STATUS_BLOCK kstatus_block; int err; err = verify_area(VERIFY_WRITE,ustatus_block_p ,sizeof(DEBUGGER_STATUS_BLOCK)); if(err) return err; kstatus_block.Test = 0x12345678; copy_to_user(ustatus_block_p, &kstatus_block, sizeof(DEBUGGER_STATUS_BLOCK) ); } break; default: return -EINVAL; } return 0;}/* This structure will hold the functions to be called * when a process does something to the device we * created. Since a pointer to this structure is kept in * the devices table, it can't be local to * init_module. NULL is for unimplemented functions. */struct file_operations pice_fops = { ioctl: pice_ioctl, open: pice_open, release: pice_close, /* all others are NULL -> default handler */ };//*************************************************************************// RegisterDriver()////*************************************************************************int RegisterDriver(void){ // register the driver major_device_number= register_chrdev(0,"pice",&pice_fops); return major_device_number;}//*************************************************************************// UnregisterDriver()////*************************************************************************void UnregisterDriver(void){ // unregister the driver unregister_chrdev(major_device_number,"pice");}//*************************************************************************// cleanup_module()////*************************************************************************void cleanup_module(void){ mm_segment_t oldfs; ENTER_FUNC(); DPRINT(PICE_DEBUG, DBT_MAIN, DBL_INFO, "cleanup_module()\n"); // remove symbolic link if(pice_sys_unlink) { oldfs = get_fs(); set_fs(KERNEL_DS); pice_sys_unlink("/dev/pice0"); set_fs(oldfs); } // remove all internal stuff CleanUpPICE(); // tell system we're gone UnregisterDriver(); // last thing to do PICE_HeapExit(); DPRINT(PICE_DEBUG, DBT_MAIN, DBL_INFO, "removed!\n"); LEAVE_FUNC();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -