void DoAPoints( stack_entry *stk, type_kind def ) { stack_flags was_imp_addr; addr_off off; LRValue( stk ); was_imp_addr = stk->flags & SF_IMP_ADDR; switch( stk->info.kind ) { case TK_BOOL: case TK_ENUM: case TK_CHAR: case TK_INTEGER: //NYI: 64 bit offsets off = U32FetchTrunc( stk->v.uint ); stk->v.addr = DefAddrSpaceForAddr( Context.execution ); stk->v.addr.mach.offset = off; stk->info.modifier = TM_NEAR; /* fall through */ case TK_POINTER: case TK_ADDRESS: if( stk->th != NULL ) { LocationCreate( &stk->v.loc, LT_ADDR, &stk->v.addr ); DIPTypeBase( stk->th, stk->th, stk->lc, &stk->v.loc ); ClassifyEntry( stk, &stk->info ); if( stk->info.kind == TK_VOID ) { Error( ERR_NONE, LIT_ENG( ERR_VOID_BASE ) ); } } else { if( def == TK_NONE ) def = TK_INTEGER; stk->info.kind = def; switch( def ) { case TK_INTEGER: stk->info.modifier = TM_UNSIGNED; stk->info.size = DefaultSize( DK_INT ); break; case TK_ADDRESS: ExprSetAddrInfo( stk, false ); break; } LocationCreate( &stk->v.loc, LT_ADDR, &stk->v.addr ); } stk->flags |= SF_LOCATION | was_imp_addr; break; default: Error( ERR_NONE, LIT_ENG( ERR_ILL_TYPE ) ); break; } stk->flags &= ~SF_CONST; }
static bool GetStrLen( imp_image_handle *ii, dr_handle dr_sym, location_context *lc, dr_typeinfo *ret ) { // Find value of scalar uint_32 seg; location_list src; location_list dst; imp_mod_handle im; union { long l; short s; char c; } val; unsigned idx_size; mod_info *modinfo; im = DwarfMod( ii, dr_sym ); if( im == IMH_NOMOD ) { return( FALSE ); } modinfo = IMH2MODI( ii, im ); if( modinfo->is_segment == FALSE ) { seg = SEG_DATA; // if flat hoke segment } else { EvalSeg( ii, dr_sym, &seg ); } if( EvalLocation( ii, lc, dr_sym, seg, &src ) != DS_OK ) { return( FALSE ); } idx_size = ret->size; if( idx_size == 0 ) { idx_size = modinfo->addr_size; } LocationCreate( &dst, LT_INTERNAL, &val ); if( DCAssignLocation( &dst, &src, idx_size ) != DS_OK ) { return( FALSE ); } switch( idx_size ) { case 1: ret->size = val.c; break; case 2: ret->size = val.s; break; case 4: ret->size = val.l; break; } return( TRUE ); }
dip_status ImpSymLocation( imp_image_handle *ii, imp_sym_handle *is, location_context *lc, location_list *ll, ji_ptr *obj_handle ) { address a; dip_status ds; location_list var; unsigned acc; unsigned cp_idx; unsigned_32 off; ji_ptr sig; switch( is->kind ) { case JS_METHOD: sig = 0; acc = GetU16( is->u.mb + offsetof( struct methodblock, fb.access ) ); if( acc & ACC_NATIVE ) return( DS_ERR | DS_BAD_LOCATION ); a = DefCodeAddr; a.mach.offset = GetPointer( is->u.mb + offsetof( struct methodblock, code ) ); LocationCreate( ll, LT_ADDR, &a ); break; case JS_FIELD: sig = GetPointer( is->u.fb + offsetof( struct fieldblock, signature ) ); acc = GetU16( is->u.fb + offsetof( struct fieldblock, access ) ); if( acc & ACC_STATIC ) { a = DefDataAddr; switch( GetU8( sig ) ) { case SIGNATURE_LONG: case SIGNATURE_DOUBLE: a.mach.offset = GetPointer( is->u.fb + offsetof( struct fieldblock, u.static_address ) ); break; default: a.mach.offset = is->u.fb + offsetof( struct fieldblock, u.static_value ); break; } LocationCreate( ll, LT_ADDR, &a ); } else {
void SymResolve( stack_entry *entry ) { item_mach tmp; sym_handle *sh; if( entry->flags & SF_SYM ) { sh = entry->v.sh; entry->flags &= ~SF_FORM_MASK; if( SymLocation( sh, entry->lc, &entry->v.loc ) == DS_OK ) { entry->flags |= SF_LOCATION; if( entry->v.loc.e[0].type == LT_ADDR ) { entry->flags |= SF_IMP_ADDR; } GetTrueEntry( entry ); } else { if( entry->info.kind == TK_STRING ) { _ChkAlloc( entry->v.string.allocated, entry->info.size, LIT( ERR_NO_MEMORY_FOR_EXPR ) ); LocationCreate( &entry->v.string.loc, LT_INTERNAL, entry->v.string.allocated ); if( SymValue( sh, entry->lc, entry->v.string.allocated ) != DS_OK ) { Error( ERR_NONE, LIT( ERR_NO_ACCESS ) ); } } else { if( SymValue( sh, entry->lc, &tmp ) != DS_OK ) { Error( ERR_NONE, LIT( ERR_NO_ACCESS ) ); } FromItem( &tmp, entry ); } } switch( entry->info.kind ) { case TK_CODE: case TK_ADDRESS: if( !(entry->flags & SF_LOCATION) ) { ExprSetAddrInfo( entry, FALSE ); /* This was here before, but that messes up things like 'do x=0:0' where 'x' is a newly created debugger variable. I can't think of any reason why you'd want to do this. If it turns out that there is a reason, talk to me. Brian. } else { LocationToAddr( entry ); */ } entry->th = NULL; break; } } }
bool PerformExplicitCall( address start, mad_string ctype, unsigned num_parms ) { bool ret; stack_entry *src; address stack; unsigned align; unsigned long amount; mad_type_info mti; stack = GetRegSP(); GetMADTypeDefaultAt( stack, MTK_INTEGER, &mti ); align = mti.b.bits / BITS_PER_BYTE; for( ; num_parms != 0; --num_parms ) { if( ExprSP->v.loc.e[0].type!=LT_ADDR && ExprSP->v.loc.e[0].u.p==NULL ) { /* push item */ src = StkEntry( 1 ); amount = (src->info.size + (align-1)) & -align; if( _IsOff( SW_STACK_GROWS_UP ) ) { stack.mach.offset -= amount; } LocationCreate( &ExprSP->v.loc, LT_ADDR, &stack ); if( _IsOn( SW_STACK_GROWS_UP ) ) { stack.mach.offset += amount; } ExprSP->info = src->info; ExprSP->flags |= SF_LOCATION; ExprSP->th = NULL; } SwapStack( 1 ); DoAssign(); PopEntry(); } AddrFix( &start ); SetRegSP( stack ); MADCallBuildFrame( ctype, start, start, &DbgRegs->mr, &DbgRegs->mr ); DbgTmpBrk.loc.addr = start; NullStatus( &DbgTmpBrk ); DbgTmpBrk.status.b.active = TRUE; ret = CallRoutine(); NullStatus( &DbgTmpBrk ); return( ret ); }
dip_status DoIndirection( imp_image_handle *ii, dip_type_info *ti, location_context *lc, location_list *ll ) { union { unsigned_8 u8; unsigned_16 u16; unsigned_32 u32; addr32_off ao32; addr48_off ao48; addr32_ptr ap32; addr48_ptr ap48; } tmp; location_list dst; dip_status ds; ii = ii; LocationCreate( &dst, LT_INTERNAL, &tmp ); ds = DCAssignLocation( &dst, ll, ti->size ); if( ds != DS_OK ) return( ds ); ds = DCItemLocation( lc, CI_DEF_ADDR_SPACE, ll ); if( ds != DS_OK ) return( ds ); if( ti->modifier == TM_NEAR ) { if( ti->size == sizeof( addr32_off ) ) { ll->e[0].u.addr.mach.offset = tmp.ao32; } else { ll->e[0].u.addr.mach.offset = tmp.ao48; } } else { if( ti->size == sizeof( addr32_ptr ) ) { ll->e[0].u.addr.mach.offset = tmp.ap32.offset; ll->e[0].u.addr.mach.segment = tmp.ap32.segment; } else { ll->e[0].u.addr.mach.offset = tmp.ap48.offset; ll->e[0].u.addr.mach.segment = tmp.ap48.segment; } } return( DS_OK ); }
static bool GetSymVal( imp_image_handle *ii, dr_handle dr_sym, location_context *lc, int_32 *ret ) { // Find value of scalar dr_handle dr_type; dr_typeinfo typeinfo[1]; imp_mod_handle im; uint_32 seg; location_list src; location_list dst; dr_type = DRGetTypeAT( dr_sym ); if( dr_type == DR_HANDLE_NUL ) { return( FALSE ); } DRGetTypeInfo( dr_type, typeinfo ); if( typeinfo->size > sizeof( *ret ) ) { return( FALSE ); } im = DwarfMod( ii, dr_sym ); if( im == IMH_NOMOD ) { return( FALSE ); } if( IMH2MODI( ii, im )->is_segment == FALSE ) { seg = SEG_DATA; // if flat hoke segment } else { EvalSeg( ii, dr_sym, &seg ); } if( EvalLocation( ii, lc, dr_sym, seg, &src ) != DS_OK ) { return( FALSE ); } LocationCreate( &dst, LT_INTERNAL, ret ); if( DCAssignLocation( &dst, &src, typeinfo->size ) != DS_OK ) { return( FALSE ); } return( TRUE ); }
dip_status FollowObject( ji_ptr sig, location_list *ll, ji_ptr *handle ) { location_list var; unsigned_32 off; dip_status ds; unsigned len; Classjava_lang_String str; /* follow the object pointer(s) */ if( sig == 0 ) return( DS_OK ); len = GetString( sig, NameBuff, sizeof( NameBuff ) ); if( len == 0 ) return( DS_ERR | DS_FAIL ); switch( NameBuff[0] ) { case SIGNATURE_CLASS: case SIGNATURE_ARRAY: LocationCreate( &var, LT_INTERNAL, &off ); ds = DCAssignLocation( &var, ll, sizeof( off ) ); if( ds != DS_OK ) return( ds ); ll->e[0].u.addr.mach.offset = GetPointer( off + offsetof( JHandle, obj ) ); *handle = off; break; default: *handle = 0; break; } if( NameBuff[0] == SIGNATURE_CLASS && memcmp( &NameBuff[1], JAVA_STRING_NAME, sizeof( JAVA_STRING_NAME ) - 1 ) == 0 ) { /* Got a string, get pointer to actual character storage */ *handle = ll->e[0].u.addr.mach.offset; ds = GetData( ll->e[0].u.addr.mach.offset, &str, sizeof( str ) ); if( ds != DS_OK ) return( ds ); ll->e[0].u.addr.mach.offset = GetPointer( (ji_ptr)str.value + offsetof( JHandle, obj ) ) + str.offset * sizeof( unicode ); } return( DS_OK ); }
void LRValue( stack_entry *entry ) { location_list ll; item_mach tmp; bool extend; mad_type_info mti; DIPHDL( type, th ); ExprResolve( entry ); if( entry->flags & SF_LOCATION ) { if( entry->info.kind == TK_FUNCTION || entry->info.kind == TK_CODE ) { /* rvalue of procedure is its address */ entry->v.addr = entry->v.loc.e[0].u.addr; ExprSetAddrInfo( entry, FALSE ); entry->info.kind = TK_ADDRESS; } else if( !AddressExpression( entry ) ) { extend = FALSE; switch( entry->info.kind ) { case TK_ARRAY: /* rvalue of array is its address */ entry->v.addr = entry->v.loc.e[0].u.addr; if( entry->th != NULL ) { /* change typing from "array of..." to "pointer to..." */ GetMADTypeDefaultAt( entry->v.addr, MTK_ADDRESS, &mti ); TypeBase( entry->th, th, NULL, NULL ); TypePointer( th, TM_FAR, mti.b.bits / BITS_PER_BYTE, entry->th ); TypeInfo( entry->th, entry->lc, &entry->info ); } else { ExprSetAddrInfo( entry, FALSE ); } break; case TK_STRING: _ChkAlloc( entry->v.string.allocated, entry->info.size, LIT( ERR_NO_MEMORY_FOR_EXPR ) ); LocationCreate( &ll, LT_INTERNAL, entry->v.string.allocated ); if( LocationAssign( &ll, &entry->v.loc, entry->info.size, FALSE ) != DS_OK ) { _Free( entry->v.string.allocated ); Error( ERR_NONE, LIT( ERR_NO_ACCESS ) ); } entry->v.string.loc = ll; break; case TK_BOOL: case TK_CHAR: case TK_ENUM: case TK_INTEGER: if( (entry->info.modifier & TM_MOD_MASK) == TM_SIGNED ) extend = TRUE; /* fall through */ default: LocationCreate( &ll, LT_INTERNAL, &tmp ); if( LocationAssign( &ll, &entry->v.loc, entry->info.size, extend ) != DS_OK ) { Error( ERR_NONE, LIT( ERR_NO_ACCESS ) ); } FromItem( &tmp, entry ); break; } } entry->flags &= ~(SF_LOCATION | SF_IMP_ADDR); } if( entry->info.kind == TK_POINTER && (entry->info.modifier & TM_MOD_MASK) == TM_NEAR ) { NearToFar( entry ); } }
/* * ConvertTo -- convert 'entry' to the given 'class'. * 'entry' should be an rvalue. */ void ConvertTo( stack_entry *entry, type_kind k, type_modifier m, unsigned s ) { conv_class from; char *dest; if( s == 0 && k == TK_INTEGER ) { s = DefaultSize( DK_INT ); } if( entry->info.kind == k && entry->info.modifier == m && entry->info.size == s ) return; from = ConvIdx( &entry->info ); switch( from ) { case U1: U32ToU64( U8FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case U2: U32ToU64( U16FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case U4: U32ToU64( U32FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I1: I32ToI64( I8FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I2: I32ToI64( I16FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case I4: I32ToI64( I32FetchTrunc( entry->v.uint ), &entry->v.uint ); break; case F4: DToLD( (float)LDToD( &entry->v.real ), &entry->v.real ); break; case F8: DToLD( (double)LDToD( &entry->v.real ), &entry->v.real ); break; case C8: DToLD( (float)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re ); DToLD( (float)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im ); break; case C16: DToLD( (double)LDToD( &entry->v.cmplx.re ), &entry->v.cmplx.re ); DToLD( (double)LDToD( &entry->v.cmplx.im ), &entry->v.cmplx.im ); break; case NP2: case FP4: entry->v.addr.mach.offset &= 0xffff; break; case STR: if( k != TK_STRING ) { Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) ); } if( s > entry->info.size ) { /* have to expand string */ _ChkAlloc( dest, s, LIT( ERR_NO_MEMORY_FOR_EXPR ) ); memcpy( dest, entry->v.string.loc.e[0].u.p, entry->info.size ); memset( &dest[entry->info.size], ' ', s - entry->info.size ); if( AllocatedString( entry ) ) { _Free( entry->v.string.allocated ); } entry->v.string.allocated = dest; LocationCreate( &entry->v.string.loc, LT_INTERNAL, dest ); } break; default: break; } entry->info.kind = k; entry->info.modifier = m; entry->info.size = s; if( !ConvFunc[ ConvIdx( &entry->info ) ]( entry, from ) ) { Error( ERR_NONE, LIT( ERR_TYPE_CONVERSION ) ); } entry->th = NULL; }
void ProcCall( void ) { mad_string ctype; int parm; const char *results; address start; const char *old; location_list ll; dig_type_info ti; dig_type_info *pti; char *p; const mad_reg_info **parm_reg; if( CurrToken == T_DIV ) { Scan(); ctype = ScanCall(); if( ctype == MAD_MSTR_NIL ) { Error( ERR_LOC, LIT_ENG( ERR_BAD_CALL_TYPE ) ); } } else { ctype = DefCallType; } CallExpr( &start ); if( _IsOff( SW_HAVE_SET_CALL ) ) { FiniCall(); p = TxtBuff; *p++ = '('; parm_reg = MADCallParmRegList( ctype, start ); for( parm = 0; parm_reg[parm] != NULL; ++parm ) { if( parm > 0 ) { *p++ = ','; } p = StrCopy( parm_reg[parm]->name, p ); } *p++ = ')'; StrCopy( MADCallReturnReg( ctype, start )->name, p ); old = ReScan( TxtBuff ); DoCallSet(); ReScan( old ); } parm = 0; results = DefReturn; if( CurrToken == T_LEFT_PAREN ) { Scan(); if( CurrToken != T_RIGHT_PAREN ) { for( ; ; ) { pti = &ti; if( CurrToken == T_DIV ) { Scan(); if( CurrToken == T_DIV ) { Scan(); /* on stack */ LocationCreate( &ll, LT_INTERNAL, NULL ); pti = NULL; } else { GetLocation( &ll, pti ); } } else { if( DefParms[parm] == NULL ) { /* on stack */ LocationCreate( &ll, LT_INTERNAL, NULL ); pti = NULL; } else { old = ReScan( DefParms[parm] ); GetLocation( &ll, pti ); ReScan( old ); } } PushLocation( &ll, pti ); NormalExpr(); SwapStack( 1 ); ++parm; if( CurrToken != T_COMMA ) break; Scan(); } } Recog( T_RIGHT_PAREN ); results = ScanPos(); if( CurrToken == T_DIV ) { Scan(); } else if( ScanEOC() ) { results = DefReturn; } else { /* syntax check */ ChkPrintList(); } } ReqEOC(); FreezeRegs(); if( PerformExplicitCall( start, ctype, parm ) && results != NULL ) { old = ReScan( results ); if( Spawn( CallResults ) == 0 ) { ReScan( old ); } } UnFreezeRegs(); FreePgmStack( false ); }