dfsym.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,799 行 · 第 1/4 页
C
1,799 行
/**********************************************************************/
{
/* Get some generic information about a symbol. */
uint_32 num1;
uint_32 num2;
dr_ptr addr_class;
lc = lc;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */
if( is->state == DF_NOT ) {
DRSetDebug( ii->dwarf->handle ); /* must do at each interface */
is->stype = DRGetTagType( is->sym );
is->acc = DRGetAccess( is->sym );
is->isstatic = DRIsStatic( is->sym );
is->isartificial = DRIsArtificial( is->sym );
is->state = DF_SET;
}
switch( is->stype ) {
case DR_TAG_FUNCTION:
if( is->sclass == SYM_MEMF || is->sclass == SYM_VIRTF ) {
si->kind = SK_CODE; /* member functions */
} else {
si->kind = SK_PROCEDURE;
if( DRStartScopeAT( is->sym, &num1 ) ) {
si->prolog_size = num1;
} else {
si->prolog_size = 0;
}
if( !DRGetLowPc( is->sym, &num1 ) ) {
num1 = 0;
}
if( !DRGetHighPc( is->sym, &num2 ) ) {
num2 = num1;
}
si->rtn_size = num2 - num1;
si->num_parms = GetParmCount( ii, is->sym );
si->ret_size = 0;
si->ret_modifier = TM_NONE;
si->epilog_size = 0;
si->rtn_calloc = 0;
if( EvalOffset( ii, is->sym, &num1 ) )
si->ret_addr_offset = num1;
else
si->ret_addr_offset = ~0;
addr_class = DRGetAddrClass( is->sym );
switch( addr_class ) {
case DR_PTR_far32:
case DR_PTR_far16:
si->rtn_far = 1;
break;
default:
si->rtn_far = 0;
}
}
break;
case DR_TAG_CLASS:
case DR_TAG_ENUM:
case DR_TAG_TYPEDEF:
si->kind = SK_TYPE;
break;
case DR_TAG_VARIABLE:
si->kind = SK_DATA;
break;
case DR_TAG_LABEL:
si->kind = SK_CODE;
break;
case DR_TAG_NAMESPACE:
si->kind = SK_NAMESPACE;
break;
default:
si->kind = SK_NONE;
break;
}
si->is_private = 0;
si->is_protected = 0;
si->is_public = 0;
switch( is->acc ) {
case DR_ACCESS_PUBLIC:
si->is_public = 1;
break;
case DR_ACCESS_PROTECTED:
si->is_protected = 1;
break;
case DR_ACCESS_PRIVATE:
si->is_private = 1;
break;
}
si->compiler = is->isartificial;
if( is->isstatic ) {
si->global = 0;
} else {
si->global = 1;
}
switch( is->sclass ) {
case SYM_MEMVAR:
si->member = 1;
si->is_static = 1;
break;
case SYM_MEM:
case SYM_MEMF:
case SYM_VIRTF:
si->member = 1;
si->is_static = 0;
break;
default:
si->member = 0;
si->is_static = 0;
}
return( DS_OK );
}
static int ARet( dr_handle var, int index, void *_var_ptr )
/*********************************************************/
{
dr_handle *var_ptr = _var_ptr;
char name[sizeof( ".return" )];
int cont;
int len;
index = index;
cont = TRUE;
if( DRIsArtificial( var ) ) {
len = DRGetNameBuff( var, name, sizeof( ".return" ) );
if( len == sizeof( ".return" ) ) {
if( strcmp( name, ".return" ) == 0 ) {
*var_ptr = var;
cont = FALSE;
}
}
}
return( cont );
}
extern dr_handle GetRet( imp_image_handle *ii, dr_handle proc )
/**************************************************************/
{
/* Find handle of Watcom return symbol. */
dr_handle ret;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */
if( DRWalkBlock( proc, DR_SRCH_var, ARet, &ret ) ) {
ret = NULL;
}
return( ret );
}
dip_status DIPENTRY DIPImpSymParmLocation( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc,
location_list *ll, unsigned n )
/*******************************************************************/
{
/* Get information about where a routine's parameters/return value
* are located.
* If the 'n' parameter is zero, fill in the location list structure
* pointed at by 'll' with the information on the location of the
* function's return value. Otherwise fill it in with the location
* of the n'th parameter.
*/
//TODO: brian only wants regs for now
dr_handle parm;
dip_status ret;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */
ret = DS_FAIL;
if( n > 0 ) {
parm = GetParmN( ii, is->sym, n );
if( parm != NULL ) {
ret = EvalParmLocation( ii, lc, parm, ll );
}
} else if( n == 0 ) {
//TODO: get ret location
parm = GetRet( ii, is->sym );
if( parm != NULL ) {
ret = EvalRetLocation( ii, lc, parm, ll );
}
}
return( ret );
}
static int AThis( dr_handle var, int index, void *_var_ptr )
/**********************************************************/
{
dr_handle *var_ptr = _var_ptr;
char name[sizeof( "this" )];
int ret;
int len;
index = index;
ret = TRUE;
len = DRGetNameBuff( var, name, sizeof( "this" ) );
if( len == sizeof( "this" ) ) {
if( strcmp( name, "this" ) == 0 ) {
*var_ptr = var;
ret = FALSE;
}
}
return( ret );
}
static dr_handle GetThis( imp_image_handle *ii, dr_handle proc )
/***************************************************************/
{
/* Return handle of the this parmeter. */
dr_handle ret;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */
if( DRWalkBlock( proc, DR_SRCH_parm, AThis, &ret ) ) {
ret = NULL;
}
return( ret );
}
dip_status DIPENTRY DIPImpSymObjType( imp_image_handle *ii,
imp_sym_handle *is, imp_type_handle *it, type_info *ti )
/**************************************************************************/
{
/* Fill in the imp_type_handle with the type of the 'this' object
* for a C++ member function.
* If 'ti' is not NULL, fill in the type_info with the kind of 'this'
* pointer that the routine is expecting (near/far, 16/32). If the
* routine is a static member, set ti->kind to TK_NONE.
*/
dr_handle dr_this;
dr_handle dr_type;
dr_typeinfo typeinfo;
dip_status ret;
dr_this = GetThis( ii, is->sym );
if( dr_this != NULL ) {
DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */
dr_type = DRGetTypeAT( dr_this );
if( dr_type != NULL ) {
DRGetTypeInfo( dr_type, &typeinfo );
MapImpTypeInfo( &typeinfo, ti );
dr_type = DRSkipTypeChain( dr_type );
it->type = DRGetTypeAT( dr_type );
it->state = DF_NOT;
it->imx = is->imx;
ret = DS_OK;
} else {
ret = DS_FAIL;
}
} else {
ti->kind = TK_NONE;
ret = DS_FAIL;
}
return( ret );
}
dip_status DIPENTRY DIPImpSymObjLocation( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc,
location_list *ll )
/***********************************************************************/
{
/* Fill in the location list with the location of the '*this' object
* for a C++ member function. Return DS_FAIL if it's a static member
* function.
*/
dr_handle dr_this;
dr_handle dr_type;
dr_typeinfo typeinfo;
uint_32 seg;
address base; /* base segment & offset */
location_list tmp;
dip_status ret;
union{
addr32_off n16;
addr48_off n32;
addr32_ptr f16;
addr48_ptr f32;
} obj_ptr;
dr_this = GetThis( ii, is->sym );
if( dr_this != NULL ) {
if( ii->mod_map[is->imx].is_segment == FALSE ) {
seg = SEG_DATA; // if flat hoke segment
} else {
EvalSeg( ii, is->sym, &seg );
}
ret = EvalLocation( ii, lc, dr_this, seg, &tmp );
if( ret == DS_OK ) {
dr_type = DRGetTypeAT( dr_this );
if( dr_type != NULL ) {
DRGetTypeInfo( dr_type, &typeinfo );
LocationCreate( ll, LT_INTERNAL, &obj_ptr );
ret = DCAssignLocation( ll, &tmp, typeinfo.size );
if( ret == DS_OK ) {
base = NilAddr;
switch( typeinfo.modifier.ptr ) { /* set segment */
case DR_PTR_none:
case DR_PTR_near16:
case DR_PTR_near32:
ret = SafeDCItemLocation( lc, CI_DEF_ADDR_SPACE, ll );
base = ll->e[0].u.addr; /* set base */
break;
}
switch( typeinfo.modifier.ptr ) {
case DR_PTR_none:
if( typeinfo.size == 4 ) {
base.mach.offset = obj_ptr.n32;
} else {
base.mach.offset = obj_ptr.n16;
}
break;
case DR_PTR_near16:
base.mach.offset = obj_ptr.n16;
break;
case DR_PTR_near32:
base.mach.offset = obj_ptr.n32;
break;
case DR_PTR_far16:
base.mach.segment = obj_ptr.f16.segment;
base.mach.offset = obj_ptr.f16.offset;
break;
case DR_PTR_far32:
base.mach.segment = obj_ptr.f32.segment;
base.mach.offset = obj_ptr.f32.offset;
break;
case DR_PTR_huge16:
base.mach.segment = obj_ptr.f16.segment;
base.mach.offset = obj_ptr.f16.offset;
break;
}
}
LocationCreate( ll, LT_ADDR, &base );
}
}
} else {
ret = DS_FAIL;
}
return( ret );
}
search_result DIPENTRY DIPImpAddrSym( imp_image_handle *ii,
imp_mod_handle im, address a, imp_sym_handle *is )
/************************************************************************/
{
/* Search the given module for a symbol who's address is greater than
* or equal to 'addr'. If none is found return SR_NONE. If you find
* a symbol at that address exactly, fill in '*is' and return SR_EXACT.
* Otherwise, fill in '*is' and return SR_CLOSEST.
*/
im_idx imx;
addrsym_info info;
search_result ret;
seg_list *addr_sym;
if( im == 0 ) {
DCStatus( DS_FAIL );
return( SR_NONE );
}
imx = IM2IMX( im );
addr_sym = DFLoadAddrSym( ii, imx );
Real2Map( ii->addr_map, &a );
if( FindAddrSym( addr_sym, &a.mach, &info ) >= 0 ) {
is->sclass = SYM_VAR;
is->imx = imx;
is->sym = info.sym;
is->state = DF_NOT;
if( info.map_offset == a.mach.offset ) {
ret = SR_EXACT;
} else {
ret = SR_CLOSEST;
}
} else {
ret = SR_NONE;
}
return( ret );
}
/**********************************/
/* Walk inner and outer blocks */
/*********************************/
static int InBlk( dr_handle blk, int depth, void *_ctl )
/******************************************************/
{
scope_ctl *ctl = _ctl;
uint_32 lo;
uint_32 hi;
scope_node *new;
depth = depth;
lo = 0; //quick fix for labels
hi = 0;
DRGetLowPc( blk, &lo );
DRGetHighPc( blk, &hi );
new = AddScope( ctl->edge, lo, hi, blk );
if( ctl->root == NULL ) {
ctl->root = new;
}
ctl->edge = new;
return( TRUE );
}
static bool IsInScope( scope_ctl *ctl, address addr )
/****************************************************/
{
bool ret;
scope_node *root;
ret = FALSE;
root = ctl->root;
if( root != NULL ) {
if( ctl->base.mach.segment == addr.mach.segment ) {
if( root->start <= addr.mach.offset
&& addr.mach.offset < root->end ) {
ret = TRUE;
}
}
}
return( ret );
}
static search_result DFAddrScope( imp_image_handle *ii,
im_idx imx, address addr, scope_block *scope )
/************************************************************/
{
scope_ctl *ctl;
scope_node *node;
search_result ret;
ret = SR_NONE;
Real2Map( ii->addr_map, &addr );
ctl = &ii->scope;
if( !IsInScope( ctl, addr ) ) {
addrsym_info info;
seg_list *addr_sym;
addr_sym = DFLoadAddrSym( ii, imx );
if( FindAddrSym( addr_sym, &addr.mach, &info ) >= 0 ) {
DRSetDebug( ii->dwarf->handle ); /* must do at each interface */
if( DRIsFunc( info.sym ) ) {
FiniScope( ctl );
ctl->base = addr;
ctl->base.mach.offset = info.map_offset;
ctl->base.mach.segment = info.map_seg;
DRWalkScope( info.sym, InBlk, ctl );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?