int tracer_copy_in( struct tracer *t, void *data, const void *uaddr, int length ) { int result; static int fast_read_success = 0; static int fast_read_failure = 0; static int fast_read_attempts = 100; UPTRINT_T iuaddr = (UPTRINT_T)uaddr; #if !defined(CCTOOLS_CPU_I386) if(!tracer_is_64bit(t)) iuaddr &= 0xffffffff; #endif if(fast_read_success>0 || fast_read_failure<fast_read_attempts) { result = full_pread64(t->memory_file,data,length,iuaddr); if(result>0) { fast_read_success++; return result; } else { fast_read_failure++; // fall through to slow method, print message on the last attempt. if(fast_read_success==0 && fast_read_failure>=fast_read_attempts) { debug(D_SYSCALL,"reading from /proc/X/mem failed, falling back to slow ptrace read"); } } } result = tracer_copy_in_slow(t,data,(void*)iuaddr,length); return result; }
int tracer_copy_in( struct tracer *t, void *data, const void *uaddr, int length ) { int result; static int has_fast_read = 1; UPTRINT_T iuaddr = (UPTRINT_T)uaddr; #if !defined(CCTOOLS_CPU_I386) if(!tracer_is_64bit(t)) iuaddr &= 0xffffffff; #endif if(has_fast_read) { result = full_pread64(t->memory_file,data,length,iuaddr); if( result<=0 && errno==EINVAL ) { has_fast_read = 0; debug(D_SYSCALL,"reading from /proc/X/mem failed, falling back to slow ptrace read"); } else { return result; } } result = tracer_copy_in_slow(t,data,(void*)iuaddr,length); return result; }
ssize_t tracer_copy_in( struct tracer *t, void *data, const void *uaddr, size_t length, int flags ) { if(length==0) return 0; #if !defined(CCTOOLS_CPU_I386) if(!tracer_is_64bit(t)) { uaddr = VOID_MATH(uaddr, & 0xffffffff); } #endif ssize_t rc = copy_in_fast(t,data,uaddr,length,flags); if (rc == -1 && errno == ENOSYS && !(flags & TRACER_O_FAST)) rc = tracer_copy_in_slow(t,data,uaddr,length,flags); assert(!(flags & TRACER_O_ATOMIC) || (rc == -1 || (size_t)rc == length)); return rc; }