VOID BeforeLock( THREADID threadid ) { // OutFile << "Thread " << threadid << " is about to lock" << endl; thread_data_t* tdata = get_tls(threadid); clock_gettime(CLOCK_MONOTONIC, &tdata->mstart); }
VOID MemWrite(THREADID tid, ADDRINT ea, ADDRINT eip ) { IMG imgR; string retName = "ANON", rR = "unknown"; thread_data_t *tdata = get_tls(tid); list<ADDRINT>::const_iterator sp_iter; for (sp_iter = tdata->data_sp.begin(); sp_iter != tdata->data_sp.end(); sp_iter++) { if ( *sp_iter == ea ) break; } if ( sp_iter != tdata->data_sp.end() ) { PIN_LockClient(); imgR = IMG_FindByAddress((ADDRINT)eip); PIN_UnlockClient(); if ( IMG_Valid(imgR) ) { retName = IMG_Name(imgR); } rR = RTN_FindNameByAddress((ADDRINT)eip); OutFile[tid] << tid << hex << "return address overwrite!!! " << ea << " " << eip << " " << retName << " " << rR << endl; } }
char * _gpg_w32ce_strerror (int err) { struct tls_space_s *tls = get_tls (); wchar_t tmpbuf[STRBUFFER_SIZE]; int n; if (err == -1) err = _gpg_w32ce_get_errno (); /* Note: On a German HTC Touch Pro2 device I also tried LOCALE_USER_DEFAULT and LOCALE_SYSTEM_DEFAULT - both returned English messages. */ if (FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), tmpbuf, STRBUFFER_SIZE -1, NULL)) { n = WideCharToMultiByte (CP_UTF8, 0, tmpbuf, -1, tls->strerror_buffer, sizeof tls->strerror_buffer -1, NULL, NULL); } else n = -1; if (n < 0) snprintf (tls->strerror_buffer, sizeof tls->strerror_buffer -1, "[w32err=%d]", err); return tls->strerror_buffer; }
char * _gpg_w32ce_strerror (int err) { struct tls_space_s *tls = get_tls (); wchar_t tmpbuf[STRBUFFER_SIZE]; int n; if (err == -1) err = _gpg_w32ce_get_errno (); if (FormatMessageW (FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), tmpbuf, STRBUFFER_SIZE -1, NULL)) { n = WideCharToMultiByte (CP_UTF8, 0, tmpbuf, -1, tls->strerror_buffer, sizeof tls->strerror_buffer -1, NULL, NULL); } else n = -1; if (n < 0) snprintf (tls->strerror_buffer, sizeof tls->strerror_buffer -1, "[w32err=%d]", err); return tls->strerror_buffer; }
VOID PTHREAD_afterJoin(THREADID tid) { #ifdef PTHREADS_DEBUG thread_state_t* tstate = get_tls(tid); cerr << "[" << tstate->tid << "]" << " After pthread_join(XXX)" << endl; #endif PTHREAD_stopIgnore(tid); }
/* ========================================================================== */ VOID ILDJIT_startLoop_after(THREADID tid, ADDRINT ip) { // This is for when there are serial loops within an executing parallel loop. if (simulating_parallel_loop) { thread_state_t* tstate = get_tls(tid); lk_lock(&tstate->lock, tid + 1); tstate->ignore = false; lk_unlock(&tstate->lock); } }
VOID PTHREAD_stopIgnore(THREADID tid) { if (ExecMode != EXECUTION_MODE_SIMULATE) return; thread_state_t* tstate = get_tls(tid); lk_lock(&tstate->lock, tid + 1); tstate->ignore = false; lk_unlock(&tstate->lock); }
VOID ILDJIT_startLoop(THREADID tid, ADDRINT ip, ADDRINT loop) { // This is for when there are serial loops within an executing parallel loop. if (simulating_parallel_loop) { thread_state_t* tstate = get_tls(tid); lk_lock(&tstate->lock, tid + 1); tstate->ignore = true; lk_unlock(&tstate->lock); } string loop_string = (string)(char*) loop; // Increment invocation counter for this loop if (invocation_counts.count(loop_string) == 0) { invocation_counts[loop_string] = 0; } else { invocation_counts[loop_string]++; } if (KnobWarmLLC.Value()) { if ((!reached_warm_invocation) && (warm_loop == loop_string) && (invocation_counts[loop_string] == warm_loop_invocation)) { assert(invocation_counts[loop_string] == warm_loop_invocation); cerr << "Called warmLoop() for the warm invocation!:" << loop_string << endl; reached_warm_invocation = true; cerr << "Detected that we need to warm!:" << loop_string << endl; cerr << "FastWarm runtime:"; printElapsedTime(); cerr << "Do late!" << endl; doLateILDJITInstrumentation(); cerr << "Done late!" << endl; } } if ((!reached_start_invocation) && (start_loop == loop_string) && (invocation_counts[loop_string] == start_loop_invocation)) { assert(invocation_counts[loop_string] == start_loop_invocation); cerr << "Called startLoop() for the start invocation!:" << loop_string << endl; reached_start_invocation = true; if (start_loop_iteration == (UINT32)-1) { cerr << "Detected that we need to start the next parallel loop!:" << loop_string << endl; reached_start_iteration = true; } } if ((!reached_end_invocation) && (end_loop == loop_string) && (invocation_counts[loop_string] == end_loop_invocation)) { assert(invocation_counts[loop_string] == end_loop_invocation); cerr << "Called startLoop() for the end invocation!:" << (CHAR*)loop << endl; reached_end_invocation = true; if (end_loop_iteration == (UINT32)-1) { cerr << "Detected that we need to end the next parallel loop!:" << loop_string << endl; reached_end_iteration = true; } } }
// Print a memory write record VOID RecordMemWrite(VOID * ip, VOID * addr, THREADID threadid) { PIN_GetLock(&lock, 0); bool dl1hit = dl1cache->AccessSingleLine((ADDRINT)addr, CACHE_BASE::ACCESS_TYPE_STORE); bool dl3hit = dl3cache->AccessSingleLine((ADDRINT)addr, CACHE_BASE::ACCESS_TYPE_STORE); PIN_ReleaseLock(&lock); thread_data *td = get_tls(threadid); td->record_mem_write(ip, addr, dl1hit || dl3hit); }
VOID AfterLock( THREADID threadid ) { // OutFile << "Thread " << threadid << " is after lock" << endl; thread_data_t* tdata = get_tls(threadid); struct timespec mend; clock_gettime(CLOCK_MONOTONIC, &mend); tdata->mcount++; tdata->mtime += (BILLION * (mend.tv_sec - tdata->mstart.tv_sec) + mend.tv_nsec - tdata->mstart.tv_nsec) - clock_avg_t; }
VOID all_instr_full_count_always(THREADID threadid){ thread_data_t* tdata = get_tls(threadid); tdata->total_ins_count++; /*if(total_ins_count % PROGRESS_THRESHOLD == 0){ * FILE* f = fopen("mica_progress.txt","w"); * fprintf(f,"%lld*10^7 instructions analyzed\n", (long long)total_ins_count/PROGRESS_THRESHOLD); * fclose(f); * }*/ }
// Print a memory write record VOID RecordMemWrite(VOID * ip, VOID * addr, THREADID tid) { MLOG* mlog = get_tls(tid); int _sincelast = mlog->_icount - mlog->_icount_lastmem - 1; mlog->_icount_lastmem = mlog->_icount; fprintf(mlog->_ofile,"s %p %p %u\n", ip, addr, _sincelast); //sincelast=0; //fclose(trace); }
static int arm32_get_tp(struct thread *td, void *args) { #if __ARM_ARCH >= 6 td->td_retval[0] = (register_t)get_tls(); #else td->td_retval[0] = *(register_t *)ARM_TP_ADDRESS; #endif return (0); }
VOID Call(THREADID tid, ADDRINT sp, ADDRINT target, ADDRINT eip, ADDRINT nxtIns ) { thread_data_t *tdata = get_tls(tid); PIN_GetLock(&lock, tid+1); tdata->data_sp.push_front(sp); // Pushing SP register tdata->data_ret.push_front(nxtIns); // Pushing return address for the call ins tdata->tuplist.push_front(boost::tuple<ADDRINT, ADDRINT>(eip, nxtIns)); depth++; PIN_ReleaseLock(&lock); }
// This function is called when the application exits VOID Fini(INT32 code, VOID *v) { // Write to a file since cout and cerr maybe closed by the application OutFile << "Total number of threads = " << numThreads << endl; for (INT32 t=0; t<numThreads; t++) { thread_data_t* tdata = get_tls(t); OutFile << "Count[" << decstr(t) << "]= " << tdata->_count << endl; } OutFile.close(); }
static ClientShadowThread* GetShadowThread() { ClientShadowThread* thread = get_tls(); if(thread == NULL) { safe_assert(pipe_ != NULL); THREADID tid = get_next_threadid(); MYLOG(1) << "CLIENT: Creating new ClientShadowThread: " << tid; thread = new ClientShadowThread(tid, pipe_); thread->OnStart(); } return thread; }
VOID Call(THREADID tid, ADDRINT sp, ADDRINT target, ADDRINT eip, ADDRINT nxtIns ) { thread_data_t *tdata = get_tls(tid); PIN_GetLock(&lock, tid+1); tdata->data_sp.push_front(sp); // Pushing SP register tdata->data_ret.push_front(nxtIns); // Pushing return address for the call ins tdata->tuplist.push_front(boost::tuple<ADDRINT, ADDRINT>(eip, nxtIns)); depth++; PIN_ReleaseLock(&lock); if ( eip == 12 ) // cout << hex << (nxtIns - eip ) << " : " << nxtIns << " : " << eip << endl; cout << hex << tdata->tuplist.begin()->get<0>() << " " <<tdata->tuplist.begin()->get<1>() << endl; }
VOID RecordMemRead(VOID * ip, VOID * addr, THREADID tid) { MLOG* mlog = get_tls(tid); int _sincelast = mlog->_icount - mlog->_icount_lastmem - 1; mlog->_icount_lastmem = mlog->_icount; //mlog->_total+=mlog->_icount - mlog->_icount_lastmem; //assert (mlog->_total==mlog->_icount); fprintf(mlog->_ofile,"l %p %p %u\n", ip, addr, _sincelast); //sincelast=0; // fclose(trace); }
static int arm32_get_tp(struct thread *td, void *args) { if (td != curthread) td->td_retval[0] = td->td_md.md_tp; else #ifndef ARM_TP_ADDRESS td->td_retval[0] = (register_t)get_tls(); #else td->td_retval[0] = *(register_t *)ARM_TP_ADDRESS; #endif return (0); }
/* * Finish a fork operation, with process p2 nearly set up. * Copy and update the pcb, set up the stack so that the child * ready to run and return to user mode. */ void cpu_fork(register struct thread *td1, register struct proc *p2, struct thread *td2, int flags) { struct pcb *pcb2; struct trapframe *tf; struct switchframe *sf; struct mdproc *mdp2; if ((flags & RFPROC) == 0) return; pcb2 = (struct pcb *)(td2->td_kstack + td2->td_kstack_pages * PAGE_SIZE) - 1; #ifdef __XSCALE__ #ifndef CPU_XSCALE_CORE3 pmap_use_minicache(td2->td_kstack, td2->td_kstack_pages * PAGE_SIZE); #endif #endif td2->td_pcb = pcb2; bcopy(td1->td_pcb, pcb2, sizeof(*pcb2)); mdp2 = &p2->p_md; bcopy(&td1->td_proc->p_md, mdp2, sizeof(*mdp2)); pcb2->un_32.pcb32_sp = td2->td_kstack + USPACE_SVC_STACK_TOP - sizeof(*pcb2); pcb2->pcb_vfpcpu = -1; pcb2->pcb_vfpstate.fpscr = VFPSCR_DN | VFPSCR_FZ; pmap_activate(td2); td2->td_frame = tf = (struct trapframe *)STACKALIGN( pcb2->un_32.pcb32_sp - sizeof(struct trapframe)); *tf = *td1->td_frame; sf = (struct switchframe *)tf - 1; sf->sf_r4 = (u_int)fork_return; sf->sf_r5 = (u_int)td2; sf->sf_pc = (u_int)fork_trampoline; tf->tf_spsr &= ~PSR_C_bit; tf->tf_r0 = 0; tf->tf_r1 = 0; pcb2->un_32.pcb32_sp = (u_int)sf; KASSERT((pcb2->un_32.pcb32_sp & 7) == 0, ("cpu_fork: Incorrect stack alignment")); /* Setup to release spin count in fork_exit(). */ td2->td_md.md_spinlock_count = 1; td2->td_md.md_saved_cspr = 0; #ifdef ARM_TP_ADDRESS td2->td_md.md_tp = *(register_t *)ARM_TP_ADDRESS; #else td2->td_md.md_tp = (register_t) get_tls(); #endif }
VOID PTHREAD_beforeJoin(THREADID tid, ADDRINT arg) { pid_t internal_pid = pid_from_pthread_t(static_cast<pthread_t>(arg)); #ifdef PTHREADS_DEBUG thread_state_t* tstate = get_tls(tid); cerr << "[" << tstate->tid << "]" << " pthread_join(" << internal_pid << ")" << endl; cerr.flush(); #endif /* Make sure we parsed the pid correctly, i.e. we're trying to join a thread * which we've already seen. This could fail on a different platform / if the * field order in struct pthread changes. */ ASSERTX(global_to_local_tid.count(internal_pid) > 0); AddBlockedHandshake(tid, internal_pid); }
VOID Fini(INT32 code, VOID *v) { // Write to a file since cout and cerr maybe closed by the application clock_gettime(CLOCK_MONOTONIC, &end); uint64_t total_elapsed = BILLION * (end.tv_sec - start.tv_sec) + end.tv_nsec - start.tv_nsec; //OutFile << "Total elapsed time: " << total_elapsed << endl; uint64_t m_elapsed; OutFile << setw(7) << "Thread " << setw(15) << "% of runtime " << setw(21) << "% waiting for a lock" << endl; for (INT32 t = 0; t < numThreads; t++) { thread_data_t* tdata = get_tls(t); m_elapsed = BILLION * (tdata->tend.tv_sec - tdata->tstart.tv_sec) + tdata->tend.tv_nsec - tdata->tstart.tv_nsec; /* OutFile << "Thread : " << t << " elapsed time: " << m_elapsed << " (" << setprecision(2) << ((double) m_elapsed / (double)total_elapsed) * 100.00 << "%)" \ << " lock time: " << tdata->mtime << " (" << setprecision(2) << ((double)tdata->mtime / (double)m_elapsed) * 100.00 << "%)" << endl; */ OutFile << setw(6) << t << setw(15) << setprecision(2) << ((double) m_elapsed / (double)total_elapsed) * 100.00 << setw(22) << setprecision(2) << ((double)tdata->mtime / (double)m_elapsed) * 100.00 <<endl; } OutFile.close(); }
/* ========================================================================== */ VOID ILDJIT_endParallelLoop(THREADID tid, ADDRINT loop, ADDRINT numIterations) { #ifdef ILDJIT_DEBUG cerr << tid << ": Pausing simulation!" << endl; #endif if (ExecMode == EXECUTION_MODE_SIMULATE) { if (reached_end_invocation) { cerr << tid << ": Shutting down early!" << endl; shutdownSimulation(); } PauseSimulation(); cerr << tid << ": Paused simulation!" << endl; first_invocation = false; list<THREADID>::iterator it; ATOMIC_ITERATE(thread_list, it, thread_list_lock) { thread_state_t* tstate = get_tls(*it); lk_lock(&tstate->lock, tid + 1); tstate->ignore = true; tstate->pop_loop_state(); lk_unlock(&tstate->lock); } CHAR* loop_name = (CHAR*)loop; UINT32 iterCount = loop_state->simmed_iteration_count - 1; cerr << "Ending loop: " << loop_name << " NumIterations:" << iterCount << endl; simulating_parallel_loop = false; *ss_prev = *ss_curr; assert(loop_states.size() > 0); loop_states.pop(); if (loop_states.size() > 0) { loop_state = &(loop_states.top()); } }
/* ========================================================================== */ VOID SyscallExit(THREADID threadIndex, CONTEXT* ictxt, SYSCALL_STANDARD std, VOID* v) { lk_lock(&syscall_lock, threadIndex + 1); ADDRINT retval = PIN_GetSyscallReturn(ictxt, std); ipc_message_t msg; thread_state_t* tstate = get_tls(threadIndex); #ifdef SYSCALL_DEBUG stringstream log; log << tstate->tid << ": "; #endif switch (tstate->last_syscall_number) { case __NR_brk: #ifdef SYSCALL_DEBUG log << "Ret syscall brk(" << dec << tstate->last_syscall_number << ") addr: 0x" << hex << retval << dec << endl; #endif if (tstate->last_syscall_arg1 != 0) msg.UpdateBrk(asid, tstate->last_syscall_arg1, true); /* Seemingly libc code calls sbrk(0) to get the initial value of the sbrk. * We intercept that and send result to zesto, so that we can correclty deal * with virtual memory. */ else msg.UpdateBrk(asid, retval, false); SendIPCMessage(msg); break; case __NR_munmap: #ifdef SYSCALL_DEBUG log << "Ret syscall munmap(" << dec << tstate->last_syscall_number << ") addr: 0x" << hex << tstate->last_syscall_arg1 << " length: " << tstate->last_syscall_arg2 << dec << endl; #endif if (retval != (ADDRINT)-1) { msg.Munmap(asid, tstate->last_syscall_arg1, tstate->last_syscall_arg2, false); SendIPCMessage(msg); } break; case __NR_mmap: // oldmap #ifdef SYSCALL_DEBUG log << "Ret syscall oldmmap(" << dec << tstate->last_syscall_number << ") addr: 0x" << hex << retval << " length: " << tstate->last_syscall_arg1 << dec << endl; #endif if (retval != (ADDRINT)-1) { msg.Mmap(asid, retval, tstate->last_syscall_arg1, false); SendIPCMessage(msg); } break; #ifndef _LP64 case __NR_mmap2: // ia32-only #ifdef SYSCALL_DEBUG log << "Ret syscall mmap2(" << dec << tstate->last_syscall_number << ") addr: 0x" << hex << retval << " length: " << tstate->last_syscall_arg1 << dec << endl; #endif if (retval != (ADDRINT)-1) { msg.Mmap(asid, retval, tstate->last_syscall_arg1, false); SendIPCMessage(msg); } break; #endif // _LP64 case __NR_mremap: #ifdef SYSCALL_DEBUG log << "Ret syscall mremap(" << dec << tstate->last_syscall_number << ") " << hex << " old_addr: 0x" << tstate->last_syscall_arg1 << " old_length: " << tstate->last_syscall_arg2 << " new address: 0x" << retval << " new_length: " << tstate->last_syscall_arg3 << dec << endl; #endif if (retval != (ADDRINT)-1) { msg.Munmap(asid, tstate->last_syscall_arg1, tstate->last_syscall_arg2, false); SendIPCMessage(msg); msg.Mmap(asid, retval, tstate->last_syscall_arg3, false); SendIPCMessage(msg); } break; case __NR_mprotect: if (retval != (ADDRINT)-1) { if ((tstate->last_syscall_arg3 & PROT_READ) == 0) msg.Munmap(asid, tstate->last_syscall_arg1, tstate->last_syscall_arg2, false); else msg.Mmap(asid, tstate->last_syscall_arg1, tstate->last_syscall_arg2, false); SendIPCMessage(msg); } break; /* Present ourself as if we have num_cores cores */ /* case __NR_sysconf: #ifdef SYSCALL_DEBUG log << "Syscall sysconf (" << dec << syscall_num << ") ret" << endl; #endif if (tstate->last_syscall_arg1 == _SC_NPROCESSORS_ONLN) if ((INT32)retval != - 1) { PIN_SetContextReg(ictxt, REG_EAX, num_cores); PIN_ExecuteAt(ictxt); } break;*/ case __NR_gettimeofday: AfterGettimeofday(threadIndex, retval); #ifdef SYSCALL_DEBUG { timeval* tv = (struct timeval*)tstate->last_syscall_arg1; log << "Ret syscall gettimeofday(" << dec << tstate->last_syscall_number << ") old: " << retval << ", tv_sec: " << tv->tv_sec << ", tv_usec: " << tv->tv_usec << endl; } #endif break; case __NR_futex: { #ifdef SYSCALL_DEBUG log << "Ret syscall futex(" << hex << tstate->last_syscall_arg1 << dec << "," << tstate->last_syscall_arg2 << ")" << endl; #endif } break; default: break; } #ifdef SYSCALL_DEBUG cerr << log.str(); #endif tstate->last_syscall_number = 0; lk_unlock(&syscall_lock); }
/* ========================================================================== */ VOID SyscallEntry(THREADID threadIndex, CONTEXT* ictxt, SYSCALL_STANDARD std, VOID* v) { /* Kill speculative feeder before reaching a syscall. * This guarantees speculative processes don't have side effects. */ if (speculation_mode) { FinishSpeculation(get_tls(threadIndex)); return; } lk_lock(&syscall_lock, threadIndex + 1); ADDRINT syscall_num = PIN_GetSyscallNumber(ictxt, std); ADDRINT arg1 = PIN_GetSyscallArgument(ictxt, std, 0); ADDRINT arg2; ADDRINT arg3; mmap_arg_struct mmap_arg; thread_state_t* tstate = get_tls(threadIndex); tstate->last_syscall_number = syscall_num; #ifdef SYSCALL_DEBUG stringstream log; log << tstate->tid << ": "; #endif switch (syscall_num) { case __NR_brk: #ifdef SYSCALL_DEBUG log << "Syscall brk(" << dec << syscall_num << ") addr: 0x" << hex << arg1 << dec << endl; #endif tstate->last_syscall_arg1 = arg1; break; case __NR_munmap: arg2 = PIN_GetSyscallArgument(ictxt, std, 1); #ifdef SYSCALL_DEBUG log << "Syscall munmap(" << dec << syscall_num << ") addr: 0x" << hex << arg1 << " length: " << arg2 << dec << endl; #endif tstate->last_syscall_arg1 = arg1; tstate->last_syscall_arg2 = arg2; break; case __NR_mmap: // oldmmap #ifndef _LP64 memcpy(&mmap_arg, (void*)arg1, sizeof(mmap_arg_struct)); #else mmap_arg.addr = arg1; mmap_arg.len = PIN_GetSyscallArgument(ictxt, std, 1); #endif tstate->last_syscall_arg1 = mmap_arg.len; #ifdef SYSCALL_DEBUG log << "Syscall oldmmap(" << dec << syscall_num << ") addr: 0x" << hex << mmap_arg.addr << " length: " << mmap_arg.len << dec << endl; #endif break; #ifndef _LP64 case __NR_mmap2: // ia32-only arg2 = PIN_GetSyscallArgument(ictxt, std, 1); #ifdef SYSCALL_DEBUG log << "Syscall mmap2(" << dec << syscall_num << ") addr: 0x" << hex << arg1 << " length: " << arg2 << dec << endl; #endif tstate->last_syscall_arg1 = arg2; break; #endif // _LP64 case __NR_mremap: arg2 = PIN_GetSyscallArgument(ictxt, std, 1); arg3 = PIN_GetSyscallArgument(ictxt, std, 2); #ifdef SYSCALL_DEBUG log << "Syscall mremap(" << dec << syscall_num << ") old_addr: 0x" << hex << arg1 << " old_length: " << arg2 << " new_length: " << arg3 << dec << endl; #endif tstate->last_syscall_arg1 = arg1; tstate->last_syscall_arg2 = arg2; tstate->last_syscall_arg3 = arg3; break; case __NR_gettimeofday: #ifdef SYSCALL_DEBUG log << "Syscall gettimeofday(" << dec << syscall_num << ")" << endl; #endif tstate->last_syscall_arg1 = arg1; BeforeGettimeofday(threadIndex, arg1); break; case __NR_mprotect: arg2 = PIN_GetSyscallArgument(ictxt, std, 1); arg3 = PIN_GetSyscallArgument(ictxt, std, 2); #ifdef SYSCALL_DEBUG log << "Syscall mprotect(" << dec << syscall_num << ") addr: " << hex << arg1 << dec << " length: " << arg2 << " prot: " << hex << arg3 << dec << endl; #endif tstate->last_syscall_arg1 = arg1; tstate->last_syscall_arg2 = arg2; tstate->last_syscall_arg3 = arg3; break; case __NR_futex: { { std::lock_guard<XIOSIM_LOCK> l(tstate->lock); if (tstate->ignore) break; } arg2 = PIN_GetSyscallArgument(ictxt, std, 1); tstate->last_syscall_arg1 = arg1; tstate->last_syscall_arg2 = arg2; #ifdef SYSCALL_DEBUG log << "Syscall futex(" << hex << arg1 << dec << ", " << arg2 << ")" << endl; #endif int futex_op = FUTEX_CMD_MASK & arg2; if (futex_op == FUTEX_WAIT || futex_op == FUTEX_WAIT_BITSET) { AddGiveUpHandshake(threadIndex, false, true); } } break; case __NR_epoll_wait: case __NR_epoll_pwait: #ifdef SYSCALL_DEBUG log << "Syscall epoll_wait(*)" << endl; #endif AddGiveUpHandshake(threadIndex, false, true); break; case __NR_poll: case __NR_ppoll: #ifdef SYSCALL_DEBUG log << "Syscall poll(*)" << endl; #endif AddGiveUpHandshake(threadIndex, false, true); break; case __NR_select: case __NR_pselect6: #ifdef SYSCALL_DEBUG log << "Syscall select(*)" << endl; #endif AddGiveUpHandshake(threadIndex, false, true); break; case __NR_nanosleep: #ifdef SYSCALL_DEBUG log << "Syscall nanosleep(*)" << endl; #endif AddGiveUpHandshake(threadIndex, false, true); break; case __NR_pause: #ifdef SYSCALL_DEBUG log << "Syscall pause(*)" << endl; #endif AddGiveUpHandshake(threadIndex, false, true); break; #ifdef SYSCALL_DEBUG case __NR_open: log << "Syscall open (" << dec << syscall_num << ") path: " << (char*)arg1 << endl; break; #endif #ifdef SYSCALL_DEBUG case __NR_exit: log << "Syscall exit (" << dec << syscall_num << ") code: " << arg1 << endl; break; #endif case __NR_sched_setaffinity: { arg2 = PIN_GetSyscallArgument(ictxt, std, 1); arg3 = PIN_GetSyscallArgument(ictxt, std, 2); #ifdef SYSCALL_DEBUG log << "Syscall sched_setaffinity(" << arg1 << ", " << arg2 << ")"; #endif size_t mask_size = (size_t) arg2; cpu_set_t* mask = (cpu_set_t*) arg3; if (CPU_COUNT(mask) > 1) { #ifdef SYSCALL_DEBUG log << endl; #endif cerr << "We don't virtualize sched_setaffinity with a mask > 1." << endl; break; } int coreID = xiosim::INVALID_CORE; for (size_t i = 0; i < mask_size; i++) { if (CPU_ISSET(i, mask)) { coreID = static_cast<int>(i); break; } } #ifdef SYSCALL_DEBUG log << " cpu " << coreID << endl; #endif AddAffinityHandshake(threadIndex, coreID); } break; /* case __NR_sysconf: #ifdef SYSCALL_DEBUG log << "Syscall sysconf (" << dec << syscall_num << ") arg: " << arg1 << endl; #endif tstate->last_syscall_arg1 = arg1; break; */ default: #ifdef SYSCALL_DEBUG log << "Syscall " << dec << syscall_num << endl; #endif break; } #ifdef SYSCALL_DEBUG cerr << log.str(); #endif lk_unlock(&syscall_lock); }
// This function is called before every block VOID PIN_FAST_ANALYSIS_CALL docount(UINT32 c, THREADID threadid) { thread_data_t* tdata = get_tls(threadid); tdata->_count += c; }
VOID Ret(THREADID tid, ADDRINT sp, ADDRINT target, ADDRINT eip, UINT32 push ) { PIN_GetLock(&lock, tid+1); unsigned int dep = 0, i = 0; IMG imgR, imgT; string retName = "ANON", targetName = "ANON", rR = "unknown", tR = "unknown"; thread_data_t *tdata = get_tls(tid); list<ADDRINT>::iterator sp_iter;// = (*tdata).find(sp); list<ADDRINT>::iterator ret_iter;// = (*tdata).find(sp); tulist::iterator tup_iter;// = (*tdata).find(sp); /******************* Uncomment this code to check ONLY for landing pad violations. START HERE ************/ /* i = 0; for ( tup_iter = tdata->tuplist.begin(); tup_iter != tdata->tuplist.end(); tup_iter++ ) { ++i; if ( target == (tup_iter->get<1>()) ) { RetFile << tid << " Ret Addr Relocated " << hex << target << " " << tup_iter->get<0>() << " " << std::dec << i << endl; ++gotoCount; // Keeps track of no of times ret addr was relocated but landing pad are correct tdata->tuplist.erase( tup_iter ); break; } } if ( tup_iter != tdata->tuplist.end() ) { PIN_ReleaseLock(&lock); return; } else { // Landing Pad Violation // Getting the names of Image and rtn will make this really SLOW. Comment this before the File IO to make it faster PIN_LockClient(); imgR = IMG_FindByAddress((ADDRINT)eip); imgT = IMG_FindByAddress((ADDRINT)target); PIN_UnlockClient(); if ( IMG_Valid(imgR) ) { retName = IMG_Name(imgR); } if ( IMG_Valid(imgT) ) { targetName = IMG_Name(imgT); } rR = RTN_FindNameByAddress((ADDRINT)eip); tR = RTN_FindNameByAddress((ADDRINT)target); // This checks if the LP violation source or target is in Linker. // These are not Violation as Linker takes and passes control many times without // a call or ret. if ( LD_PATH == targetName || LD_PATH == retName ) goto overRide; OutFile[tid] << tid << hex << "Landing Pad Violation -1 " << sp << " " << target << " " << eip << " "<<targetName << " " << retName << " " << tR << " " << rR << endl; overRide: PIN_ReleaseLock(&lock); return; } */ /********* TO CHECK ONLY FOR LANDING PAD VIOLATIONS - END HERE *********************************/ /**** No need to comment the below code when checking only for LP violation as this function would return before reaching here *****/ /* Check if stack pointer value i.e. return address location is present */ for (sp_iter = tdata->data_sp.begin(); sp_iter != tdata->data_sp.end(); sp_iter++) { ++dep; if ( *sp_iter == sp ) break; } --dep; if (push) { OutFile[tid] << std::dec << tid << "PUSH FOUND" << endl; tdata->data_sp.erase(tdata->data_sp.begin()); PIN_ReleaseLock(&lock); return; } if (sp_iter == tdata->data_sp.end()) { /* This is the case where Ret Address is relocated to some other location on stack e.g Libffi does this to make ffi call portable accross ABIs */ i = 0; for ( tup_iter = tdata->tuplist.begin(); tup_iter != tdata->tuplist.end(); tup_iter++ ) { ++i; if ( target == (tup_iter->get<1>() ) ) { RetFile << tid << " Ret Addr Relocated " << hex << target << " " << tup_iter->get<0>() << ":" << (target - 2) << ":" << (target - tup_iter->get<0>() ) << " " << std::dec << i << endl; ++gotoCount; tdata->tuplist.erase( tup_iter ); break; } } if ( tup_iter != tdata->tuplist.end() ) { PIN_ReleaseLock(&lock); return; } PIN_LockClient(); imgR = IMG_FindByAddress((ADDRINT)eip); imgT = IMG_FindByAddress((ADDRINT)target); PIN_UnlockClient(); if ( IMG_Valid(imgR) ) { retName = IMG_Name(imgR); } if ( IMG_Valid(imgT) ) { targetName = IMG_Name(imgT); } rR = RTN_FindNameByAddress((ADDRINT)eip); tR = RTN_FindNameByAddress((ADDRINT)target); OutFile[tid] << tid << hex << "Landing Pad Violation -2 " << sp << " " << *(tdata->data_sp.begin()) << " " << target << " " << tup_iter->get<0>() << " " << eip << " "<<targetName << " " << retName << " " << tR << " " << rR << endl; PIN_ReleaseLock(&lock); return; } if ( sp_iter != tdata->data_sp.begin() ) OutFile[tid] << tid << hex <<"ret address not in the beginning!! " << target <<" "<< eip << " " << sp << " " << *(tdata->data_sp.begin()) << " " << dec << dep<< endl; depth -= dep; tdata->data_sp.erase( tdata->data_sp.begin(), sp_iter); tdata->data_sp.erase(sp_iter); PIN_ReleaseLock(&lock); }
VOID ThreadFini(THREADID threadid, const CONTEXT *ctxt, INT32 code, VOID *v) { thread_data_t* tdata = get_tls(threadid); clock_gettime(CLOCK_MONOTONIC, &tdata->tend); }
// This function is called before every instruction is executed //VOID docount() { icount++; } VOID docount(THREADID tid) { MLOG* mlog = get_tls(tid); mlog->_icount++; }
static CURL* get_curl(TrgClient *tc, guint http_class) { TrgClientPrivate *priv = tc->priv; TrgPrefs *prefs = trg_client_get_prefs(tc); trg_tls *tls = get_tls(tc); CURL *curl = tls->curl; g_mutex_lock(&priv->configMutex); if (priv->configSerial > tls->serial || http_class != priv->http_class) { gchar *proxy; curl_easy_reset(curl); curl_easy_setopt(curl, CURLOPT_USERAGENT, PACKAGE_NAME); curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &http_receive_callback); #ifdef DEBUG if (g_getenv("TRG_CURL_VERBOSE") != NULL) curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); #endif if (http_class == HTTP_CLASS_TRANSMISSION) { curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *) tc); curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, &header_callback); curl_easy_setopt(curl, CURLOPT_PASSWORD, trg_client_get_password(tc)); curl_easy_setopt(curl, CURLOPT_USERNAME, trg_client_get_username(tc)); curl_easy_setopt(curl, CURLOPT_URL, trg_client_get_url(tc)); } #ifndef CURL_NO_SSL if (trg_client_get_ssl(tc) && !trg_client_get_ssl_validate(tc)) { curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0); curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0); } #endif proxy = trg_client_get_proxy(tc); if (proxy) { curl_easy_setopt(curl, CURLOPT_PROXYTYPE, CURLPROXY_HTTP); curl_easy_setopt(curl, CURLOPT_PROXY, proxy); } tls->serial = priv->configSerial; priv->http_class = http_class; } if (http_class == HTTP_CLASS_TRANSMISSION) curl_easy_setopt(curl, CURLOPT_URL, trg_client_get_url(tc)); curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long) trg_prefs_get_int(prefs, TRG_PREFS_KEY_TIMEOUT, TRG_PREFS_CONNECTION)); g_mutex_unlock(&priv->configMutex); /* Headers are set on each use, then freed, so make sure invalid headers aren't still around. */ curl_easy_setopt(curl, CURLOPT_HTTPHEADER, NULL); return curl; }