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

📄 ptrace.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  arch/s390/kernel/ptrace.c * *  S390 version *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation *    Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), * *  Based on PowerPC version  *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * *  Derived from "arch/m68k/kernel/ptrace.c" *  Copyright (C) 1994 by Hamish Macdonald *  Taken from linux/kernel/ptrace.c and modified for M680x0. *  linux/kernel/ptrace.c is by Ross Biro 1/23/92, edited by Linus Torvalds * * Modified by Cort Dougan (cort@cs.nmt.edu)  * * * This file is subject to the terms and conditions of the GNU General * Public License.  See the file README.legal in the main directory of * this archive for more details. */#include <stddef.h>#include <linux/config.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/mm.h>#include <linux/smp.h>#include <linux/smp_lock.h>#include <linux/errno.h>#include <linux/ptrace.h>#include <linux/user.h>#include <asm/segment.h>#include <asm/page.h>#include <asm/pgtable.h>#include <asm/pgalloc.h>#include <asm/system.h>#include <asm/uaccess.h>#ifdef CONFIG_S390_SUPPORT#include "linux32.h"#else#define parent_31bit 0#endifvoid FixPerRegisters(struct task_struct *task){	struct pt_regs *regs = __KSTK_PTREGS(task);	per_struct *per_info=			(per_struct *)&task->thread.per_info;	per_info->control_regs.bits.em_instruction_fetch =	        per_info->single_step | per_info->instruction_fetch;		if (per_info->single_step) {		per_info->control_regs.bits.starting_addr=0;#ifdef CONFIG_S390_SUPPORT		if (current->thread.flags & S390_FLAG_31BIT) {			per_info->control_regs.bits.ending_addr=0x7fffffffUL;	        }		else #endif      		{		per_info->control_regs.bits.ending_addr=-1L;		}	} else {		per_info->control_regs.bits.starting_addr=		        per_info->starting_addr;		per_info->control_regs.bits.ending_addr=		        per_info->ending_addr;	}	/* if any of the control reg tracing bits are on 	   we switch on per in the psw */	if (per_info->control_regs.words.cr[0] & PER_EM_MASK)		regs->psw.mask |= PSW_PER_MASK;	else		regs->psw.mask &= ~PSW_PER_MASK;	if (per_info->control_regs.bits.storage_alt_space_ctl)		task->thread.user_seg |= USER_STD_MASK;	else		task->thread.user_seg &= ~USER_STD_MASK;}void set_single_step(struct task_struct *task){	per_struct *per_info= (per_struct *) &task->thread.per_info;			per_info->single_step = 1;  /* Single step */	FixPerRegisters (task);}void clear_single_step(struct task_struct *task){	per_struct *per_info= (per_struct *) &task->thread.per_info;	per_info->single_step = 0;	FixPerRegisters (task);}int ptrace_usercopy(addr_t realuseraddr, addr_t copyaddr, int len,                    int tofromuser, int writeuser, unsigned long mask){        unsigned long *realuserptr, *copyptr;	unsigned long tempuser;	int retval;        retval = 0;        realuserptr = (unsigned long *) realuseraddr;        copyptr = (unsigned long *) copyaddr;	if (writeuser && realuserptr == NULL)		return 0;	if (mask != -1L) {		tempuser = *realuserptr;		if (!writeuser) {			tempuser &= mask;			realuserptr = &tempuser;		}	}	if (tofromuser) {		if (writeuser) {			retval = copy_from_user(realuserptr, copyptr, len);		} else {			if (realuserptr == NULL)				retval = clear_user(copyptr, len);			else				retval = copy_to_user(copyptr,realuserptr,len);		}      		retval = retval ? -EFAULT : 0;	} else {		if (writeuser)			memcpy(realuserptr, copyptr, len);		else			memcpy(copyptr, realuserptr, len);	}	if (mask != -1L && writeuser)                *realuserptr = (*realuserptr & mask) | (tempuser & ~mask);	return retval;}#ifdef CONFIG_S390_SUPPORTtypedef struct{	__u32 cr[3];} per_cr_words32  __attribute__((packed));typedef struct{	__u16          perc_atmid;          /* 0x096 */	__u32          address;             /* 0x098 */	__u8           access_id;           /* 0x0a1 */} per_lowcore_words32  __attribute__((packed));typedef struct{	union {		per_cr_words32   words;	} control_regs  __attribute__((packed));	/*	 * Use these flags instead of setting em_instruction_fetch	 * directly they are used so that single stepping can be	 * switched on & off while not affecting other tracing	 */	unsigned  single_step       : 1;	unsigned  instruction_fetch : 1;	unsigned                    : 30;	/*	 * These addresses are copied into cr10 & cr11 if single	 * stepping is switched off	 */	__u32     starting_addr;	__u32     ending_addr;	union {		per_lowcore_words32 words;	} lowcore; } per_struct32 __attribute__((packed));struct user_regs_struct32{	_psw_t32 psw;	u32 gprs[NUM_GPRS];	u32 acrs[NUM_ACRS];	u32 orig_gpr2;	s390_fp_regs fp_regs;	/*	 * These per registers are in here so that gdb can modify them	 * itself as there is no "official" ptrace interface for hardware	 * watchpoints. This is the way intel does it.	 */	per_struct32 per_info;	u32  ieee_instruction_pointer; 	/* Used to give failing instruction back to user for ieee exceptions */};struct user32 {                                  /* We start with the registers, to mimic the way that "memory" is returned                                   from the ptrace(3,...) function.  */  struct user_regs_struct32 regs; /* Where the registers are actually stored */                                  /* The rest of this junk is to help gdb figure out what goes where */  u32 u_tsize;	                  /* Text segment size (pages). */  u32 u_dsize;	                  /* Data segment size (pages). */  u32 u_ssize;	                  /* Stack segment size (pages). */  u32 start_code;                 /* Starting virtual address of text. */  u32 start_stack;	          /* Starting virtual address of stack area.				   This is actually the bottom of the stack,				   the top of the stack is always found in the				   esp register.  */  s32 signal;     		  /* Signal that caused the core dump. */  u32 u_ar0;                      /* Used by gdb to help find the values for */				  /* the registers. */  u32 magic;		          /* To uniquely identify a core file */  char u_comm[32];		  /* User command that was responsible */};#define PT32_PSWMASK  0x0#define PT32_PSWADDR  0x04#define PT32_GPR0     0x08#define PT32_GPR15    0x44#define PT32_ACR0     0x48#define PT32_ACR15    0x84#define PT32_ORIGGPR2 0x88#define PT32_FPC      0x90#define PT32_FPR0_HI  0x98#define PT32_FPR15_LO 0x114#define PT32_CR_9     0x118#define PT32_CR_11    0x120#define PT32_IEEE_IP  0x13C#define PT32_LASTOFF  PT32_IEEE_IP#define PT32_ENDREGS  0x140-1#define U32OFFSETOF(member) offsetof(struct user32,regs.member)#define U64OFFSETOF(member) offsetof(struct user,regs.member)#define U6432DIFF(member) (U64OFFSETOF(member) - U32OFFSETOF(member))#define PT_SINGLE_STEP   (PT_CR_11+8)#define PT32_SINGLE_STEP (PT32_CR_11+4)#endif /* CONFIG_S390_SUPPORT */int copy_user(struct task_struct *task,saddr_t useraddr, addr_t copyaddr,              int len, int tofromuser, int writingtouser){	int copylen=0,copymax;	addr_t  realuseraddr;	saddr_t enduseraddr;	unsigned long mask;#ifdef CONFIG_S390_SUPPORT	int     parent_31bit=current->thread.flags & S390_FLAG_31BIT;	int     skip;#endif	enduseraddr=useraddr+len;	if ((useraddr<0||useraddr&3||enduseraddr&3)||#ifdef CONFIG_S390_SUPPORT	    (parent_31bit && enduseraddr > sizeof(struct user32)) ||#endif	    enduseraddr > sizeof(struct user))		return (-EIO);#ifdef CONFIG_S390_SUPPORT	if(parent_31bit)	{		if(useraddr != PT32_PSWMASK)		{			if (useraddr == PT32_PSWADDR)				useraddr = PT_PSWADDR+4;			else if(useraddr <= PT32_GPR15)				useraddr = ((useraddr-PT32_GPR0)*2) + PT_GPR0+4;			else if(useraddr <= PT32_ACR15)				useraddr += PT_ACR0-PT32_ACR0;			else if(useraddr == PT32_ORIGGPR2)				useraddr = PT_ORIGGPR2+4;			else if(useraddr <= PT32_FPR15_LO)				useraddr += PT_FPR0-PT32_FPR0_HI;			else if(useraddr <= PT32_CR_11)				useraddr = ((useraddr-PT32_CR_9)*2) + PT_CR_9+4;			else if(useraddr ==  PT32_SINGLE_STEP)				useraddr = PT_SINGLE_STEP; 			else if(useraddr <= U32OFFSETOF(per_info.ending_addr))					useraddr = (((useraddr-U32OFFSETOF(per_info.starting_addr)))*2) + 					U64OFFSETOF(per_info.starting_addr)+4;			else if( useraddr == U32OFFSETOF(per_info.lowcore.words.perc_atmid))				useraddr = U64OFFSETOF(per_info.lowcore.words.perc_atmid);			else if( useraddr == U32OFFSETOF(per_info.lowcore.words.address))				useraddr = U64OFFSETOF(per_info.lowcore.words.address)+4;			else if(useraddr == U32OFFSETOF(per_info.lowcore.words.access_id))				useraddr = U64OFFSETOF(per_info.lowcore.words.access_id);			else if(useraddr == PT32_IEEE_IP)				useraddr = PT_IEEE_IP+4;		}	}#endif /* CONFIG_S390_SUPPORT */	while(len>0)	{#ifdef CONFIG_S390_SUPPORT		skip=0;#endif		mask=PSW_ADDR_MASK;		if(useraddr<PT_FPC)		{			realuseraddr=((addr_t) __KSTK_PTREGS(task)) + useraddr;			if(useraddr<(PT_PSWMASK+8))			{				if(parent_31bit)				{					copymax=PT_PSWMASK+4;

⌨️ 快捷键说明

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