drloc.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 703 行 · 第 1/2 页
C
703 行
top[0] = stk2 - stk1;
break;
case DW_OP_mod:
top[0] = stk2 % stk1;
break;
case DW_OP_mul:
top[0] = stk2 * stk1;
break;
case DW_OP_neg:
top[0] = -stk1;
break;
case DW_OP_not:
top[0] = ~stk1;
break;
case DW_OP_or:
top[0] = stk2 | stk1;
break;
case DW_OP_plus:
top[0] = stk2 + stk1;
break;
case DW_OP_plus_uconst:
top[0] += op1;
break;
case DW_OP_shl:
top[0] = stk2 << stk1;
break;
case DW_OP_shr:
top[0] = stk2 >> stk1;
break;
case DW_OP_shra:
top[0] = (int_32) stk2 >> stk1;
break;
case DW_OP_xor:
top[0] = stk2 ^ stk1;
break;
case DW_OP_eq:
top[0] = (int_32)stk2 == (int_32)stk1;
break;
case DW_OP_ge:
top[0] = (int_32)stk2 >= (int_32)stk1;
break;
case DW_OP_gt:
top[0] = (int_32)stk2 > (int_32)stk1;
break;
case DW_OP_le:
top[0] = (int_32)stk2 <= (int_32)stk1;
break;
case DW_OP_lt:
top[0] = (int_32)stk2 < (int_32)stk1;
break;
case DW_OP_ne:
top[0] = (int_32)stk2 != (int_32)stk1;
break;
case DW_OP_bra:
stk1 = top[0];
Pop( top );
if( stk1 == 0 ) break; /* conditional fall thru */
case DW_OP_skip:
p += op1;
break;
case DW_OP_nop:
break;
case DW_OP_piece:
/* call got piece */
if( !callbck->ref( d, top[0], op1, kind ) ) {
return;
}
Pop( top );
kind = DR_LOC_ADDR;
break;
default:
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
}
}
while( !IsEmpty( top, stk_top) ) {
if( !callbck->ref( d, top[0], addr_size, kind ) ) {
return;
}
Pop( top );
kind = DR_LOC_ADDR;
}
return;
}
static dr_handle SearchLocList( uint_32 start, uint_32 context,
uint addr_size )
/*************************************************************/
// Search loc list for context return start of loc_expr block or NULL
{
uint_32 low;
uint_32 high;
int len;
dr_handle p;
p = DWRCurrNode->sections[DR_DEBUG_LOC].base;
if( p == NULL ){
DWREXCEPT( DREXCEP_BAD_DBG_INFO );
return( NULL );
}
p += start;
for( ;; ) {
low = ReadVWord( p, addr_size );
p+= addr_size;
high = ReadVWord( p, addr_size );
p+= addr_size;
if( low == high && low == 0 ) {
p = NULL;
break;
}
if( low <= context && context < high ) break;
len = DWRVMReadWord( p );
p+= sizeof(uint_16);
p += len;
}
return( p );
}
static int DWRLocExpr( dr_handle var,
dr_handle abbrev,
dr_handle info,
dr_loc_callbck *callbck,
void *d )
/***********************************************/
{
unsigned form;
uint_32 size;
char loc_buff[256];
char *expr;
int ret;
dr_handle loclist;
uint_32 context;
int addr_size;
addr_size = DWRGetAddrSize( DWRFindCompileUnit( info ) );
form = DWRVMReadULEB128( &abbrev );
ret = TRUE;
for( ;; ) {
switch( form ) {
case DW_FORM_block1:
size = DWRVMReadByte( info );
info += sizeof(unsigned_8);
goto end_loop;
case DW_FORM_block2:
size = DWRVMReadWord( info );
info += sizeof(unsigned_16);
goto end_loop;
case DW_FORM_block4:
size = DWRVMReadDWord( info );
info += sizeof(unsigned_32);
goto end_loop;
case DW_FORM_block:
size = DWRVMReadULEB128( &info );
goto end_loop;
case DW_FORM_indirect:
form = DWRVMReadULEB128( &info );
break;
case DW_FORM_ref_addr:
case DW_FORM_data4:
if( !callbck->live( d, &context ) ) {
ret = FALSE;
goto exit;
}
loclist = DWRVMReadDWord( info );
info = SearchLocList( loclist, context, addr_size );
if( info == NULL ) {
ret = FALSE;
goto exit;
}
form = DW_FORM_block2;
break;
case DW_FORM_data2: //TODO kludge
ret = DWRVMReadWord( info );
ret = callbck->ref( d, ret, addr_size, DR_LOC_ADDR );
goto exit;
default:
ret = FALSE;
goto exit;
}
} end_loop:;
if( size > sizeof( loc_buff ) ) {
expr = DWRALLOC( size );
} else if( size > 0 ) {
expr = loc_buff;
} else {
ret = FALSE;
goto exit;
}
ret = TRUE;
DWRVMRead( info, expr, size );
DoLocExpr( expr, size, addr_size, callbck, d, var );
if( size > sizeof( loc_buff ) ) {
DWRFREE( expr );
}
exit:
return( ret );
}
extern int DRLocBasedAT( dr_handle var,
dr_loc_callbck *callbck,
void *d )
/***********************************************/
{
dw_tagnum tag;
dw_atnum at;
dr_handle abbrev;
dr_handle sym = var;
int ret;
abbrev = DWRVMReadULEB128( &var );
abbrev = DWRLookupAbbrev( var, abbrev );
tag = DWRVMReadULEB128( &abbrev );
++abbrev; /* skip child flag */
switch( tag ) {
break;
case DW_TAG_member:
case DW_TAG_inheritance:
at = DW_AT_data_member_location;
break;
case DW_TAG_subprogram:
at = DW_AT_vtable_elem_location;
break;
default:
return( FALSE );
}
if( DWRScanForAttrib( &abbrev, &var, at ) != 0 ) {
ret = DWRLocExpr( sym, abbrev, var, callbck, d );
} else {
if( tag == DW_TAG_member ) {
// For members of a union, it is valid not to have any
// DW_AT_data_member_location attribute (we might want to check
// that we are in fact dealing with a union here). Just create
// a dummy location "+0".
uint_8 dummy_loc[] = { DW_OP_lit0, DW_OP_plus };
int addr_size;
addr_size = DWRGetAddrSize( DWRFindCompileUnit( var ) );
DoLocExpr( dummy_loc, sizeof(dummy_loc), addr_size, callbck, d, var );
ret = TRUE;
} else {
ret = FALSE;
}
}
return( ret );
}
extern int DRLocationAT( dr_handle var,
dr_loc_callbck *callbck,
void *d )
/***********************************************/
{
dw_tagnum tag;
dw_atnum at;
dr_handle abbrev;
dr_handle sym = var;
int ret;
abbrev = DWRVMReadULEB128( &var );
abbrev = DWRLookupAbbrev( var, abbrev );
tag = DWRVMReadULEB128( &abbrev );
++abbrev; /* skip child flag */
switch( tag ) {
case DW_TAG_common_block:
case DW_TAG_formal_parameter:
case DW_TAG_variable:
case DW_TAG_subprogram:
at = DW_AT_location;
break;
case DW_TAG_string_type:
at = DW_AT_string_length;
break;
default:
return( FALSE );
}
if( DWRScanForAttrib( &abbrev, &var, at ) != 0 ) {
ret = DWRLocExpr( sym, abbrev, var, callbck, d );
} else {
ret = FALSE;
}
return( ret );
}
extern int DRParmEntryAT( dr_handle var,
dr_loc_callbck *callbck,
void *d )
/***************************************************/
{
dw_tagnum tag;
dr_handle abbrev;
dr_handle sym = var;
int ret;
abbrev = DWRVMReadULEB128( &var );
abbrev = DWRLookupAbbrev( var, abbrev );
tag = DWRVMReadULEB128( &abbrev );
++abbrev; /* skip child flag */
if( DWRScanForAttrib( &abbrev, &var, DW_AT_WATCOM_parm_entry ) != 0 ) {
ret = DWRLocExpr( sym, abbrev, var, callbck, d );
} else {
ret = FALSE;
}
return( ret );
}
extern dr_handle DRStringLengthAT( dr_handle str )
/************************************************/
{
dr_handle abbrev;
abbrev = DWRGetAbbrev( &str );
if( DWRScanForAttrib( &abbrev, &str, DW_AT_string_length ) != 0 ) {
return( str );
} else {
return( NULL );
}
}
extern int DRRetAddrLocation( dr_handle var,
dr_loc_callbck *callbck,
void *d )
/****************************************************/
{
dr_handle abbrev;
dr_handle sym = var;
int ret;
abbrev = DWRGetAbbrev( &var );
if( DWRScanForAttrib( &abbrev, &var, DW_AT_return_addr ) != 0 ) {
ret = DWRLocExpr( sym, abbrev, var, callbck, d );
} else {
ret = FALSE;
}
return( ret );
}
extern int DRSegLocation( dr_handle var,
dr_loc_callbck *callbck,
void *d )
/************************************************/
{
dr_handle abbrev;
dr_handle sym = var;
int ret;
abbrev = DWRGetAbbrev( &var );
if( DWRScanForAttrib( &abbrev, &var, DW_AT_segment ) != 0 ) {
ret = DWRLocExpr( sym, abbrev, var, callbck, d );
} else {
ret = FALSE;
}
return( ret );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?