void CVBlkBeg( dbg_block *blk, offset lc ) /*******************************************/ { block_patch *bpatch; dbg_patch *dpatch; cv_out out[1]; offset start; cg_sym_handle sym; cs_block *ptr; byte *nm; bpatch = CGAlloc( sizeof( block_patch ) ); blk->patches = bpatch; NewBuff( out, CVSyms ); ptr = StartSym( out, SG_BLOCK ); ptr->pParent = 0; ptr->pEnd = 0; ptr->length = 0; ptr->offset = 0; ptr->segment = 0; nm = out->ptr; /* mark name */ CVPutNullStr( out ); EndSym( out ); dpatch = &blk->patches->patch; BuffPatchSet( CVSyms, dpatch ); BuffWrite( out, &ptr->offset ); sym = AskForLblSym( CurrProc->label ); start = lc - CurrProc->targ.debug->blk->start; SymReloc( CVSyms, sym, start ); BuffSkip( out, nm ); /* skip addr */ buffEnd( out ); DumpLocals( blk->locals ); }
extern void GenObject( void ) /*******************************/ { block *blk; block *next_blk; instruction *ins; source_line_number last_line; block_num targets; block_num i; segment_id old; label_handle lbl; unsigned align; fe_attr attr; old = SetOP( AskCodeSeg() ); InitZeroPage(); last_line = 0; attr = FEAttr( AskForLblSym( CurrProc->label ) ); for( blk = HeadBlock; blk != NULL; blk = next_blk ) { if( blk->label != CurrProc->label && blk->label != NULL ) { last_line = DumpLineNum( blk->ins.hd.line_num, last_line, TRUE ); if( ( blk->class & ITERATIONS_KNOWN ) && blk->iterations >= 10 ) { align = DepthAlign( DEEP_LOOP_ALIGN ); } else { align = DepthAlign( blk->depth ); } CodeLabel( blk->label, align ); if( ( blk->edge[ 0 ].flags & BLOCK_LABEL_DIES ) != 0 && BlocksUnTrimmed ) { TellCondemnedLabel( blk->label ); } }
void CVProEnd( dbg_rtn *rtn, offset lc ) /*****************************************/ { cg_sym_handle sym; dbg_type tipe; fe_attr attr; const char *name; cs_gproc *ptr; sg_index kind; cv_out out[1]; /* unused parameters */ (void)lc; sym = AskForLblSym( CurrProc->label ); attr = FEAttr( sym ); if( attr & FE_GLOBAL ){ kind = SG_GPROC; }else{ kind = SG_LPROC; } NewBuff( out, CVSyms ); ptr = StartSym( out, kind ); ptr->pParent = 0; ptr->pEnd = 0; ptr->pNext = 0; ptr->proc_length = 0; ptr->debug_start = rtn->pro_size; ptr->debug_end = 0; ptr->offset = 0; ptr->segment = 0; tipe = FEDbgType( sym ); ptr->proctype = tipe; ptr->flags.s = 0; #if _TARGET & ( _TARG_IAPX86 | _TARG_80386 ) if( *(call_class *)FindAuxInfoSym( sym, CALL_CLASS ) & FAR_CALL ) { ptr->flags.f.far_ret = true; } #endif if( rtn->obj_type != DBG_NIL_TYPE ) { name = FEAuxInfo( sym, CLASS_APPENDED_NAME ); } else { name = FEName( sym ); } CVPutStr( out, name ); EndSym( out ); BuffPatchSet( CVSyms, RtnPatch ); BuffWrite( out, &ptr->offset ); SymReloc( CVSyms, sym, 0 ); BuffSkip( out, &ptr->proctype ); buffEnd( out ); DBLocFini( rtn->reeturn ); DBLocFini( rtn->obj_loc ); if( rtn->parms != NULL ){ DumpParms( rtn->parms, &rtn->rtn_blk->locals ); } DumpLocals( rtn->rtn_blk->locals ); }
extern type_class_def CallState( aux_handle aux, type_def *tipe, call_state *state ) /*******************************************************************/ { type_class_def class; uint i; hw_reg_set parms[20]; hw_reg_set *parm_src; hw_reg_set *parm_dst; hw_reg_set *pregs; call_class cclass; call_class *pcclass; risc_byte_seq *code; bool have_aux_code = FALSE; state->unalterable = FixedRegs(); if( FEAttr( AskForLblSym( CurrProc->label ) ) & FE_VARARGS ) { HW_TurnOn( state->unalterable, VarargsHomePtr() ); } // For code bursts only, query the #pragma aux instead of using // hardcoded calling convention. If it ever turns out that we need // to support more than a single calling convention, this will need // to change to work more like x86 if( !AskIfRTLabel( CurrProc->label ) ) { code = FEAuxInfo( aux, CALL_BYTES ); if( code != NULL ) { have_aux_code = TRUE; } } pregs = FEAuxInfo( aux, SAVE_REGS ); HW_CAsgn( state->modify, HW_FULL ); if( have_aux_code ) { HW_TurnOff( state->modify, *pregs ); } else { HW_TurnOff( state->modify, SavedRegs() ); } HW_CTurnOff( state->modify, HW_UNUSED ); state->used = state->modify; /* anything not saved is used */ state->attr = 0; pcclass = FEAuxInfo( aux, CALL_CLASS ); cclass = *pcclass; if( cclass & SETJMP_KLUGE ) { state->attr |= ROUTINE_IS_SETJMP; } if( cclass & SUICIDAL ) { state->attr |= ROUTINE_NEVER_RETURNS; } if( cclass & NO_MEMORY_CHANGED ) { state->attr |= ROUTINE_MODIFIES_NO_MEMORY; } if( cclass & NO_MEMORY_READ ) { state->attr |= ROUTINE_READS_NO_MEMORY; } i = 0; if( have_aux_code ) { parm_src = FEAuxInfo( aux, PARM_REGS ); } else { parm_src = ParmRegs(); } parm_dst = &parms[0]; for( ;; ) { *parm_dst = *parm_src; if( HW_CEqual( *parm_dst, HW_EMPTY ) ) break; if( HW_Ovlap( *parm_dst, state->unalterable ) ) { FEMessage( MSG_BAD_SAVE, aux ); } HW_CTurnOff( *parm_dst, HW_UNUSED ); parm_dst++; parm_src++; i++; } i++; state->parm.table = CGAlloc( i * sizeof( hw_reg_set ) ); Copy( parms, state->parm.table, i * sizeof( hw_reg_set ) ); HW_CAsgn( state->parm.used, HW_EMPTY ); state->parm.curr_entry = state->parm.table; state->parm.offset = 0; class = ReturnClass( tipe, state->attr ); UpdateReturn( state, tipe, class, aux ); return( class ); }