dfsym.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,799 行 · 第 1/4 页
C
1,799 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: DWARF implementation of the DIP symbol handling interface.
*
****************************************************************************/
#include <string.h>
#include "dfdip.h"
#include "dfld.h"
#include "dfmod.h"
#include "dfmodinf.h"
#include "dfaddr.h"
#include "dfaddsym.h"
#include "dftype.h"
#include "dfloc.h"
#include "dfscope.h"
#include "dfhash.h"
#include "demangle.h"
#include "dfsym.h"
imp_mod_handle DIPENTRY DIPImpSymMod( imp_image_handle *ii, imp_sym_handle *is )
/*******************************************************************************/
{
/* Return the module that the implementation symbol handle comes from. */
imp_mod_handle im;
ii = ii;
im = IMX2IM( is->imx );
return( im );
}
unsigned DIPENTRY DIPImpSymName( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc,
symbol_name sn, char *buff, unsigned max )
/****************************************************************/
{
/*
SN_SOURCE:
The name of the symbol as it appears in the source code.
SN_OBJECT:
The name of the symbol as it appeared to the linker.
SN_DEMANGLED:
C++ names, with full typing (essentially it looks like
a function prototype). If the symbol is not a C++ symbol
(not mangled), return zero for the length.
SN_EXPRESSION:
Return whatever character string is necessary such that
when scanned in an expression, the symbol handle can
be reconstructed.
SS_BLOCK:
Not possible. Will never happen.
*/
char *name;
unsigned len, demangled_len;
lc = lc;
//TODO: what's lc for?
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
switch( sn ) {
case SN_SOURCE:
case SN_OBJECT:
len = DRGetNameBuff( is->sym, buff, max );
if( len == 0 ) {
DCStatus( DS_FAIL );
return( 0 );
}
--len;
if( max != 0 && len > max ) {
buff[max-1] = '\0';
}
break;
case SN_SCOPED:
len = DRGetScopedNameBuff( is->sym, buff, max );
if( len == 0 ) {
DCStatus( DS_FAIL );
return( 0 );
}
--len;
if( max != 0 && len > max ) {
buff[max-1] = '\0';
}
break;
case SN_DEMANGLED:
if( ii->mod_map[is->imx].lang == DR_LANG_CPLUSPLUS ) {
name = DRDecoratedName( is->sym, NULL );
if( name == NULL ) {
DCStatus( DS_FAIL );
return( 0 );
}
len = NameCopy(buff, name, max );
DCFree( name );
} else if( buff == NULL ) {
return( 0 );
} else {
len = DRGetNameBuff( is->sym, buff, max );
if( __is_mangled( buff, len ) ) {
demangled_len = __demangle_l( buff, len, NULL, 0 );
if( demangled_len > max ) {
demangled_len = max;
}
name = DCAlloc( demangled_len );
__demangle_l( buff, len, name, demangled_len );
strncpy( buff, name, max );
DCFree( name );
return( demangled_len );
} else {
return( 0 );
}
}
break;
case SN_EXPRESSION:
return( 0 );
}
return( len );
}
dip_status DIPENTRY DIPImpSymType( imp_image_handle *ii,
imp_sym_handle *is, imp_type_handle *it )
/***********************************************************/
{
/* Get the implementation type handle for the type of the given symbol. */
dip_status ret;
ret = DS_FAIL;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */
if( is->state == DF_NOT ) {
is->stype = DRGetTagType( is->sym );
}
switch( is->stype ) {
case DR_TAG_FUNCTION:
case DR_TAG_CLASS:
case DR_TAG_ENUM:
it->type = is->sym;
break;
default:
it->type = DRGetTypeAT( is->sym );
break;
}
ret = DS_OK;
it->imx = is->imx;
if( it->type != NULL ) {
it->state = DF_NOT;
} else {
it->state = DF_SET; // default the type
it->sub_array = FALSE;
it->typeinfo.kind = DR_TYPEK_DATA;
it->typeinfo.size = 0;
it->typeinfo.mclass = DR_MOD_NONE;
if( is->stype == DR_TAG_LABEL ) {
it->typeinfo.kind = DR_TYPEK_CODE;
}
}
return( ret );
}
struct mod_wlk {
imp_image_handle *ii;
seg_list *addr_sym;
im_idx imx;
address a;
dr_handle sym;
search_result ret;
};
static int AMod( dr_handle sym, void *_d, dr_search_context *cont )
/*****************************************************************/
{
//TODO: no segments, better TAG_label
struct mod_wlk *d = _d;
uint_32 offset;
uint_32 seg;
int ret;
addrsym_info info;
cont = cont;
ret = TRUE;
if( DRGetLowPc( sym, &offset) ) {
if( d->ii->mod_map[d->imx].is_segment == FALSE ) {
seg = SEG_FLAT; // if flat hoke segment
} else {
EvalSeg( d->ii, sym, &seg );
}
} else {
if( d->ii->mod_map[d->imx].is_segment == FALSE ) {
seg = SEG_FLAT; // if flat hoke segment
} else {
EvalSeg( d->ii, sym, &seg );
}
ret = EvalSymOffset( d->ii, sym, &offset );
}
info.map_offset = offset;
info.sym = sym;
info.map_seg = seg;
AddAddrSym( d->addr_sym, &info );
return( TRUE );
}
extern seg_list *DFLoadAddrSym( imp_image_handle *ii, im_idx imx )
/****************************************************************/
{
dr_handle cu_tag;
struct mod_wlk d;
seg_list *addr_sym;
addr_sym = ii->mod_map[imx].addr_sym;
if( addr_sym->head == NULL ) { /* no cache */
FiniAddrSym( addr_sym ); /* kill cache */
DRSetDebug( ii->dwarf->handle ); /* must do at each interface */
cu_tag = ii->mod_map[imx].cu_tag;
d.addr_sym = addr_sym;
d.ii = ii;
d.imx = imx;
d.ret = SR_NONE;
DRWalkModFunc( cu_tag, FALSE, AMod, &d ); /* load cache */
SortAddrSym( addr_sym );
}
return( addr_sym );
}
typedef struct {
dr_handle inh; /* member class handle */
char *name; /* member name */
dr_handle match; /* handle that matches */
} mem_func_wlk;
static int AMemFuncSym( void *_df, addrsym_info *info )
/*****************************************************/
{
mem_func_wlk *df = _df;
int cont;
char buff[256];
int len;
dr_handle contain;
cont = TRUE;
contain = DRGetContaining( info->sym );
if( contain != NULL ) {
contain = DRSkipTypeChain( contain ); /* PCH typedef link */
if( contain == df->inh ) {
len = DRGetNameBuff( info->sym, buff, sizeof( buff ) );
if( strcmp( buff, df->name ) == 0 ) {
cont = FALSE;
df->match = info->sym;
}
}
}
return( cont );
}
static dr_handle MemFuncLookUp( imp_image_handle *ii,
dr_handle sym,
dr_handle inh,
im_idx imx )
/***************************************************/
{
mem_func_wlk df;
char buff[256];
seg_list *addr_sym;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */
addr_sym = DFLoadAddrSym( ii, imx );
DRGetNameBuff( sym, buff, sizeof( buff ) );
df.name = buff;
df.inh = inh;
df.match = NULL;
WlkAddrSyms( addr_sym, &AMemFuncSym, &df );
return( df.match );
}
static addr_seg GetCodeSeg( imp_image_handle *ii )
/*************************************************/
{
addr_ptr mach;
mach.segment = SEG_CODE;
mach.offset = 0;
DCMapAddr( &mach, ii->dcmap );
return( mach.segment );
}
dip_status DIPENTRY DIPImpSymLocation( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc, location_list *ll )
/***************************************************************************/
{
/* Get the location of the given symbol. */
dip_status ret;
address base; /* base segment & offset */
uint_32 seg;
dr_handle sym;
base = NilAddr;
DRSetDebug( ii->dwarf->handle ); /* must do at each call into dwarf */
if( DRGetLowPc( is->sym, &base.mach.offset) ) {
if( ii->mod_map[is->imx].is_segment == FALSE ) {
seg = SEG_CODE; // if flat hoke segment
} else {
EvalSeg( ii, is->sym, &seg );
}
base.mach.segment = seg;
DCMapAddr( &base.mach, ii->dcmap );
LocationCreate( ll, LT_ADDR, &base );
ret = DS_OK;
} else {
switch( is->sclass ) {
case SYM_MEM:
case SYM_VIRTF:
{
dr_bitfield info;
int b_strt;
ret = SafeDCItemLocation( lc, CI_OBJECT, ll );
if( ret != DS_OK ) {
DCStatus( ret );
return( ret );
}
if( is->f.minfo.inh != NULL ) {
DFBaseAdjust( ii, is->f.minfo.root,
DRGetTypeAT( is->f.minfo.inh ),lc, &ll->e[0].u.addr );
}
ret = EvalLocAdj( ii, lc, is->sym, &ll->e[0].u.addr );
if( is->sclass == SYM_VIRTF ) {
ll->e[0].u.addr.mach.segment = GetCodeSeg( ii );
} else if( DRGetBitFieldInfo( is->sym, &info ) ) {
b_strt = 8 * info.byte_size.val.s -
(info.bit_offset.val.s + info.bit_size.val.s);
LocationAdd( ll, b_strt );
LocationTrunc( ll, info.bit_size.val.s );
}
break;
}
case SYM_MEMF:
if( is->f.minfo.inh == NULL ) {
sym = is->f.minfo.root;
} else {
sym = DRGetTypeAT( is->f.minfo.inh ); /* get inherited type */
}
sym = DRSkipTypeChain( sym ); /* PCH typedef link */
sym = MemFuncLookUp( ii, is->sym, sym, is->imx );
if( sym == NULL ) {
base = NilAddr; /* for now say it's NULL */
LocationCreate( ll, LT_ADDR, &base );
ret = DS_OK;
break;
} else {
is->sym = sym;
}
DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */
if( DRGetLowPc( is->sym, &base.mach.offset) ) {
if( ii->mod_map[is->imx].is_segment == FALSE ) {
seg = SEG_CODE; // if flat hoke segment
} else {
EvalSeg( ii, is->sym, &seg );
}
base.mach.segment = seg;
DCMapAddr( &base.mach, ii->dcmap );
LocationCreate( ll, LT_ADDR, &base );
ret = DS_OK;
}
break;
case SYM_MEMVAR:
case SYM_VAR:
if( ii->mod_map[is->imx].is_segment == FALSE ) {
if( DRIsFunc( is->sym ) ) {
seg = SEG_CODE; // if flat hoke segment
} else {
seg = SEG_DATA; // if flat hoke segment
}
} else {
EvalSeg( ii, is->sym, &seg );
}
ret = EvalLocation( ii, lc, is->sym, seg, ll );
break;
}
}
return( ret );
}
dip_status DIPENTRY DIPImpSymValue( imp_image_handle *ii,
imp_sym_handle *is, location_context *ic, void *buff )
/********************************************************************/
{
uint_32 value;
/* Copy the value of a constant symbol into 'buff'. You can get the
* size required by doing a SymType followed by a TypeInfo.
*/
ii = ii;
ic = ic;
if( is->sclass != SYM_ENUM ) {
return( DS_FAIL );
}
DRSetDebug( ii->dwarf->handle ); /* must do at each call into DWARF */
if( !DRConstValAT( is->sym, &value ) ) {
return( DS_FAIL );
}
switch( is->f.einfo.size ) {
case 1:
*(uint_8 *)buff = value;
break;
case 2:
*(uint_16 *)buff = value;
break;
case 4:
*(uint_32 *)buff = value;
break;
default:
return( DS_FAIL );
}
return( DS_OK );
}
dip_status DIPENTRY DIPImpSymInfo( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc, sym_info *si )
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?