|
-------
ÉϴκÃÏñÓÐ0D0A¸ñʽÎÊÌâ.
-------
¸½¼þÊÇÕû¸öÐ޸ĺóµÄgdbserver,°üÀ¨uclinux2.4.17kernel ptrace.c
±¾À´Ð޸ıȽÏÉÙ,²»Ïë°ÑÕû¸ö¶«Î÷·ÅÉÏÀ´.
²»¹ý,ÓÐЩÅóÓÑÒª,»¹ÊDz»Ì«·½±ã,¾Í·ÅÔÚÕâÀïÁË.
0)È«²¿ÐÞ¸ÄÎÒÒѾ´«¸øchyyuu,²»¹ýĿǰֻÓб¾È˵IJâÊÔ
1)gdbserver:
Ç°ÃæÎÒдµÄ¾ÍÊǶÔgdbserver±¾ÉíµÄÈ«²¿ÐÞ¸Ä.
2)uclinux kernel2.4.17:
a.µ«ÊÇuclinux2.4.17 for at91(ÎÒ²âÊԵİ汾)ȱʡÔËÐеÄflat³ÌÐòÊÇÔÚUSER26ModeÏÂ,
²»ÊÇUSER32Mode.ÕâÑù,gdbserver/skyeye(client)µÄµ¥²½ÔËÐоͻá³öÎÊÌâ.
ÎÒÐÞ¸ÄÁËarch/armnommu/kernel/ptrace.c,ÒÔÖ§³ÖÕâÖÖÇé¿ö.
b.uclinuxµÄptraceûÓжÔÄÚ´æ¶Áд×öÏÞÖÆ,ºÜÈÝÒ׸㵽½ø³ÌÍâÄÚ´æ
//added by telpro
#define REG_SP 13
int in_arm26_mode(struct task_struct *child)
{
long psr;
psr = get_stack_long(child, REG_PSR) ;
return ((psr & 0x1f) <= 3);
}
#define FIXPC(child, x) \
do { \
if(in_arm26_mode(child)) x = x & 0x0ffffffc; \
}while(0)
//do as arch/armnommu/kernel/process.c
//a dirty version, FIXME...telpro
int is_addr_access( struct task_struct *child,
unsigned long addr )
{
unsigned long sp;
if ( addr >= child->mm->start_code &&
addr < child->mm->end_code )
return 1;
if ( addr >= child->mm->start_data &&
addr < child->mm->brk )
return 1;
sp = get_stack_long(child, REG_SP) ;
//actually <sp is r/w also.
if ( addr >= sp &&
addr < child->mm->start_stack )
return 1;
return 0;
}
int ptrace_set_bpt(struct task_struct *child)
{
struct pt_regs *regs;
unsigned long pc, insn;
int res;
regs = get_user_regs(child);
pc = instruction_pointer(regs);
//26bit , added by telpro
FIXPC(child, pc);
res = read_tsk_long(child, pc, &insn);
if (!res) {
struct debug_info *dbg = &child->thread.debug;
unsigned long alt;
dbg->nsaved = 0;
alt = get_branch_address(child, pc, insn);
if (alt) {
FIXPC(child, alt); //added by telpro
res = add_breakpoint_arm(child, dbg, alt);
}
.........
}
static int do_ptrace(int request, struct task_struct *child, long addr, long data)
ÖмÓÈë
case PTRACE_PEEKTEXT:
case PTRACE_PEEKDATA:
/*added by telpro*/
if (!is_addr_access(child, addr) ) {
ret = -EIO;
break;
}
ret = read_tsk_long(child, addr, &tmp);
....
case PTRACE_POKETEXT:
case PTRACE_POKEDATA:
/*added by telpro*/
if (!is_addr_access(child, addr) ) {
ret = -EIO;
break;
}
ret = write_tsk_long(child, addr, data);
break;
.......
case PTRACE_PEEKUSR:
ret = -EIO;
if ((addr & 3) || addr < 0 || addr >= sizeof(struct user))
break;
tmp = 0; /* Default return condition */
if (addr < sizeof(struct pt_regs)) {
tmp = get_stack_long(child, (int)addr >> 2);
//added by telpro, for at91
if(addr == 14*4 || addr == 15*4 ) {
FIXPC(child, tmp);
}
} else if (addr == 49*4) {
tmp = child->mm->start_code;
} else if (addr == 50*4) {
tmp = child->mm->start_data;
} else if (addr == 51*4) {
.....
3)ÒÑÖªÎÊÌâ
a.ÏÖÔÚ¶ÔUSER26MOdeµÄÓ¦ÓóÌÐò²»ÊÇÖ§³ÖµÃºÜºÃ,
r14,r15Êǰ´ÕÕUSER32ModeÏÔʾµÄ½á¹û.
ÕâÊDz»¶ÔµÄ.
ÍêÕûµÄ½â¾öÐèÒªÐÞ¸Äclient¶ËÈí¼þ,Ò²¾ÍÊÇskyeyeÓëgdbserverÅäºÏµÄ²¿·Ö.
²»¹ý,USER26×ܸоõÊÇÒ»ÖÖÌÔÌģʽ,xscaleÕâЩÒѾ²»Ö§³ÖËüÁË.
Òò´Ë,Ò²²»Ï뻨´óÁ¦ÆøÈ¥½â¾ö.
b.Thumbģʽ²»Ö§³Ö
¸½¼þ: ÄúËùÔÚµÄÓû§×éÎÞ·¨ÏÂÔØ»ò²é¿´¸½¼þ
|