void FMessageRpcClient::HandleMessage(const FMessageRpcProgress& Message, const TSharedRef<IMessageContext, ESPMode::ThreadSafe>& Context) { TSharedPtr<IMessageRpcCall> Call = FindCall(Context); if (Call.IsValid()) { Call->UpdateProgress(Message.Completion, FText::FromString(Message.StatusText)); } }
static ERL_NIF_TERM Respond(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) { TRACE("Respond\n"); int id; if(enif_get_int(env, argv[0], &id)) { ErlCall *erlCall = FindCall(id); if(erlCall) { enif_mutex_lock(erlCall->mutex); erlCall->result = argv[1]; erlCall->complete = 1; enif_cond_broadcast(erlCall->cond); enif_mutex_unlock(erlCall->mutex); return enif_make_atom(env, "ok"); } else { return enif_make_badarg(env); } } else { return enif_make_badarg(env); } }
static int HeuristicTraceBack( address *p_prev_sp, address *start, address *execution, address *frame, address *stack ) { mad_disasm_data dd; int word_size; long sp_adjust; long bp_adjust; long saved_bp_loc = 0; long bp_to_ra_offset = 0; // int found_inc_bp; int found_mov_bp_sp; int found_push_bp; char *jmplabel; address return_addr_location; address bp_value; address sp_value; address saved_return_location; int found_call; int i; InitCache( *start, 100 ); sp_value = *stack; bp_value = *frame; DbgAddr = *execution; DisAsm( &dd ); if( dd.ins.type == DI_X86_retf || dd.ins.type == DI_X86_retf2 ) { *execution = GetFarAddr( &sp_value ); found_call = 1; } else if( dd.ins.type == DI_X86_ret || dd.ins.type == DI_X86_ret2 ) { execution->mach.offset = GetAnOffset( &sp_value ); found_call = 1; } else { // Check for ADD SP,n right after current ip and adjust SP if its there // because it must be popping parms if( dd.ins.type == DI_X86_add3 && ConstOp( dd.ins.op[OP_2] ) && IsSPReg( dd.ins.op[OP_1] ) ){ sp_value.mach.offset += dd.ins.op[ OP_2 ].value.s._32[I64LO32]; } // Run through code from the known symbol until and collect prolog info word_size = Is32BitSegment ? 4 : 2; sp_adjust = 0; bp_adjust = 0; // found_inc_bp = 0; found_mov_bp_sp = 0; found_push_bp = 0; DbgAddr = *start; while( DbgAddr.mach.offset != execution->mach.offset ) { DisAsm( &dd ); switch( dd.ins.type ) { case DI_INVALID: return( 0 ); case DI_X86_call3: jmplabel = ToSegStr( dd.ins.op[ OP_1 ].value.s._32[I64LO32], dd.ins.op[ OP_1 ].extra, 0 ); if( IdentifyFunc( jmplabel, &sp_adjust ) ) continue; break; case DI_X86_call: jmplabel = JmpLabel( dd.ins.op[ OP_1 ].value.s._32[I64LO32], 0 ); if( IdentifyFunc( jmplabel, &sp_adjust ) ) continue; break; case DI_X86_enter: sp_adjust -= word_size; // push bp found_push_bp = 1; bp_to_ra_offset = sp_adjust; // mov bp,sp found_mov_bp_sp = 1; saved_bp_loc = 0; // 0[bp] sp_adjust -= dd.ins.op[ OP_1 ].value.s._32[I64LO32]; // sub sp,n break; case DI_X86_inc2: if( IsBPReg( dd.ins.op[ OP_1 ] ) ) { // found_inc_bp = 1; continue; } break; case DI_X86_mov: if( IsBPReg( dd.ins.op[ OP_1 ] ) && IsSPReg( dd.ins.op[ OP_2 ] ) ) { found_mov_bp_sp = 1; bp_to_ra_offset = sp_adjust; saved_bp_loc -= sp_adjust; } continue; case DI_X86_nop: continue; case DI_X86_pop: case DI_X86_pop2: case DI_X86_pop3d: case DI_X86_pop3e: case DI_X86_pop3s: case DI_X86_pop4f: case DI_X86_pop4g: sp_adjust += word_size; continue; case DI_X86_push: case DI_X86_push2: case DI_X86_push3: case DI_X86_push4f: case DI_X86_push4g: case DI_X86_push5: sp_adjust -= word_size; if( IsBPReg( dd.ins.op[ OP_1 ] ) ) { saved_bp_loc = sp_adjust; found_push_bp = 1; } continue; case DI_X86_sub: dd.ins.op[ OP_2 ].value.s._32[I64LO32] = -dd.ins.op[ OP_2 ].value.s._32[I64LO32]; /* fall through */ case DI_X86_add: if( !ConstOp( dd.ins.op[ OP_2 ] ) ) break; if( IsSPReg( dd.ins.op[ OP_1 ] ) ) { sp_adjust += dd.ins.op[ OP_2 ].value.s._32[I64LO32]; continue; } else if( IsBPReg( dd.ins.op[ OP_1 ] ) ) { bp_adjust += dd.ins.op[ OP_2 ].value.s._32[I64LO32]; continue; } break; default: break; } break; } // find the address of the return address (return_addr_location) if( found_mov_bp_sp ) { return_addr_location = bp_value; return_addr_location.mach.offset -= bp_adjust; GetBPFromStack( &return_addr_location, &bp_value ); return_addr_location.mach.offset -= bp_to_ra_offset; } else { if( found_push_bp ) { return_addr_location = sp_value; return_addr_location.mach.offset += saved_bp_loc - sp_adjust; GetBPFromStack( &return_addr_location, &bp_value ); } return_addr_location = sp_value; return_addr_location.mach.offset -= sp_adjust; } found_call = 0; if( found_mov_bp_sp ) { found_call = FindCall( execution, &return_addr_location ); if( !found_call ) { return_addr_location = sp_value; return_addr_location.mach.offset -= sp_adjust; } } if( !found_call ) { saved_return_location = return_addr_location; // limit the search to 512*word_size (W2K can cause us to search 4Gb!) for( i = 0; return_addr_location.mach.offset >= p_prev_sp->mach.offset && i < 512; ++i ) { found_call = FindCall( execution, &return_addr_location ); if( found_call ) break; return_addr_location.mach.offset -= word_size; } if( !found_call ) { return_addr_location = saved_return_location; for( i = 0; i < 10; ++i ) { return_addr_location.mach.offset += word_size; found_call = FindCall( execution, &return_addr_location ); if( found_call ) { break; } } } } } *stack = DbgAddr; *frame = bp_value; return( found_call ); }
unsigned OptSize1 (CodeSeg* S) /* Do size optimization by calling special subroutines that preload registers. * This routine does not work standalone, it needs a following register load * removal pass. */ { CodeEntry* E; unsigned Changes = 0; unsigned I; /* Are we optimizing for size */ int OptForSize = (S->CodeSizeFactor < 100); /* Walk over the entries */ I = 0; while (I < CS_GetEntryCount (S)) { const CallDesc* D; /* Get next entry */ E = CS_GetEntry (S, I); /* Check if it's a subroutine call */ if (E->OPC == OP65_JSR && (D = FindCall (E->Arg)) != 0) { /* Get input register info for this insn */ const RegContents* In = &E->RI->In; /* FindCall finds the first entry that matches our function name. * The names are listed in "best match" order, so search for the * first one, that fulfills our conditions. */ while (1) { /* Check the registers and allow slower code only if * optimizing for size. */ if ((OptForSize || (D->Flags & F_SLOWER) == 0) && RegMatch (D->Regs.RegA, In->RegA) && RegMatch (D->Regs.RegX, In->RegX) && RegMatch (D->Regs.RegY, In->RegY) && RegMatch (D->Regs.SRegLo, In->SRegLo) && RegMatch (D->Regs.SRegHi, In->SRegHi)) { /* Ok, match for all conditions */ CodeEntry* X; X = NewCodeEntry (E->OPC, E->AM, D->ShortFunc, 0, E->LI); CS_InsertEntry (S, X, I+1); CS_DelEntry (S, I); /* Remember that we had changes */ ++Changes; /* Done */ break; } /* Next table entry, bail out if next entry not valid */ if (++D >= CallTable + CALL_COUNT || strcmp (D->LongFunc, E->Arg) != 0) { /* End of table or entries reached */ break; } } } /* Next entry */ ++I; } /* Return the number of changes made */ return Changes; }