hllsym.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,855 行 · 第 1/5 页
C
1,855 行
static unsigned ImpSymName( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc,
symbol_name sn, char *buff, unsigned max )
{
char *name;
unsigned len;
location_list ll;
dip_status ds;
imp_sym_handle global;
addr_off dummy_off;
search_result sr;
switch( sn ) {
case SN_EXPRESSION:
return( 0 );
case SN_OBJECT:
case SN_DEMANGLED:
ds = ImpSymLocation( ii, is, lc, &ll );
if( ds != DS_OK ) break;
if( ll.num != 1 ) break;
if( ll.e[0].type != LT_ADDR ) break;
dummy_off = 0;
sr = TableSearchForAddr( ii, ll.e[0].u.addr, &global,
&dummy_off, sstGlobalPub );
if( sr != SR_EXACT ) break;
if( SymGetName( ii, &global, &name, &len, NULL ) != DS_OK ) break;
if( sn == SN_OBJECT ) {
return( NameCopy( buff, name, max, len ) );
}
if( !__is_mangled( name, len ) ) return( 0 );
return( __demangle_l( name, len, buff, max ) );
}
if( sn == SN_DEMANGLED ) return( 0 );
/* SN_SOURCE: */
if( SymGetName( ii, is, &name, &len, NULL ) != DS_OK ) return( 0 );
return( NameCopy( buff, name, max, len ) );
}
unsigned DIPENTRY DIPImpSymName( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc,
symbol_name sn, char *buff, unsigned max )
{
return( ImpSymName( ii, is, lc, sn, buff, max ) );
}
dip_status ImpSymType( imp_image_handle *ii, imp_sym_handle *is, imp_type_handle *it )
{
s_all *p;
if( is->containing_type != 0 ) {
return( TypeSymGetType( ii, is, it ) );
}
p = VMBlock( ii, is->handle, is->len );
if( p == NULL ) return( DS_FAIL );
return( TypeIndexFillIn( ii, SymTypeIdx( ii, p ), it ) );
}
dip_status DIPENTRY DIPImpSymType( imp_image_handle *ii,
imp_sym_handle *is, imp_type_handle *it )
{
return( ImpSymType( ii, is, it ) );
}
dip_status DIPENTRY DIPImpSymLocation( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc, location_list *ll )
{
return( ImpSymLocation( ii, is, lc, ll ) );
}
dip_status ImpSymValue( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc, void *buff )
{
s_all *p;
numeric_leaf val;
dip_status ds;
imp_type_handle it;
type_info ti;
if( is->containing_type != 0 ) {
return( TypeSymGetValue( ii, is, lc, buff ) );
}
p = VMBlock( ii, is->handle, is->len );
if( p == NULL ) return( DS_FAIL );
switch( p->common.code ) {
case S_CONSTANT:
GetNumLeaf( (unsigned_8 *)p + sizeof( s_constant ), &val );
memcpy( buff, val.valp, val.size );
ds = TypeIndexFillIn( ii, SymTypeIdx( ii, p ), &it );
if( ds != DS_OK ) return( ds );
ds = ImpTypeInfo( ii, &it, lc, &ti );
if( ds != DS_OK ) return( ds );
memset( (unsigned_8 *)buff + val.size, 0, ti.size - val.size );
return( DS_OK );
}
return( DS_FAIL );
}
dip_status DIPENTRY DIPImpSymValue( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc, void *buff )
{
return( ImpSymValue( ii, is, lc, buff ) );
}
dip_status DIPENTRY DIPImpSymInfo( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc, sym_info *si )
{
s_all *p;
memset( si, 0, sizeof( *si ) );
if( is->containing_type != 0 ) {
return( TypeSymGetInfo( ii, is, lc, si ) );
}
p = VMBlock( ii, is->handle, is->len );
if( p == NULL ) return( DS_FAIL );
switch( p->common.code ) {
case S_PUB16:
if( SegIsExecutable( ii, p->pub16.f.segment ) == DS_OK ) {
si->kind = SK_CODE;
} else {
si->kind = SK_DATA;
}
si->global = 1;
break;
case S_PUB32:
if( SegIsExecutable( ii, p->pub32.f.segment ) == DS_OK ) {
si->kind = SK_CODE;
} else {
si->kind = SK_DATA;
}
si->global = 1;
break;
case S_GDATA16:
case S_GDATA32:
case S_GTHREAD32:
si->global = 1;
/* fall through */
case S_REGISTER:
case S_MANYREG:
case S_BPREL16:
case S_LDATA16:
case S_REGREL16:
case S_LDATA32:
case S_BPREL32:
case S_REGREL32:
case S_LTHREAD32:
si->kind = SK_DATA;
break;
case S_CONSTANT:
si->kind = SK_CONST;
break;
case S_UDT:
case S_COBOLUDT:
si->kind = SK_TYPE;
break;
case S_GPROC16:
si->global = 1;
/* fall through */
case S_LPROC16:
si->kind = SK_PROCEDURE;
si->rtn_far = p->lproc16.f.flags.f.far_ret;
si->ret_addr_offset = sizeof( unsigned_16 );
si->prolog_size = p->lproc16.f.debug_start;
si->epilog_size = p->lproc16.f.proc_length - p->lproc16.f.debug_end;
si->rtn_size = p->lproc16.f.proc_length;
//NYI: fill in si->rtn_calloc
//NYI: fill in si->rtn_modifier
//NYI: fill in si->ret_size
//NYI: fill in si->num_parms
break;
case S_GPROC32:
si->global = 1;
/* fall through */
case S_LPROC32:
si->kind = SK_PROCEDURE;
si->rtn_far = p->lproc32.f.flags.f.far_ret;
if( ii->mad == MAD_AXP ) {
si->ret_addr_offset = 0;
} else {
si->ret_addr_offset = sizeof( unsigned_32 );
}
si->prolog_size = p->lproc32.f.debug_start;
si->epilog_size = p->lproc32.f.proc_length - p->lproc32.f.debug_end;
si->rtn_size = p->lproc32.f.proc_length;
//NYI: fill in si->rtn_calloc
//NYI: fill in si->rtn_modifier
//NYI: fill in si->ret_size
//NYI: fill in si->num_parms
break;
case S_LABEL16:
case S_LABEL32:
si->kind = SK_CODE;
break;
default:
Confused();
return( DS_FAIL );
}
return( DS_OK );
}
static const unsigned_8 DXAXList[] = { CV_X86_DX, CV_X86_AX };
static const unsigned_8 DXEAXList[] = { CV_X86_DX, CV_X86_EAX };
static const unsigned_8 ST1ST0List[] = { CV_X86_ST1, CV_X86_ST0 };
dip_status DIPENTRY DIPImpSymParmLocation( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc,
location_list *ll, unsigned n )
{
s_all *p;
unsigned type;
int is32;
unsigned parm_count;
cv_calls call;
dip_status ds;
unsigned_8 *reg_list;
imp_type_handle it;
type_info ti;
p = VMBlock( ii, is->handle, is->len );
switch( p->common.code ) {
case S_LPROC16:
case S_GPROC16:
is32 = 0;
type = p->lproc16.f.proctype;
break;
case S_LPROC32:
case S_GPROC32:
is32 = 1;
type = p->lproc32.f.proctype;
break;
default:
return( DS_ERR|DS_FAIL );
}
ds = TypeCallInfo( ii, type, &call, &parm_count );
if( ds != DS_OK ) return( ds );
if( n > parm_count ) return( DS_NO_PARM );
if( n == 0 ) {
/* return value */
p = VMRecord( ii, is->handle + is->len );
if( p == NULL ) return( DS_ERR|DS_FAIL );
/* WARNING: assuming that S_RETURN directly follows func defn */
if( p->common.code == S_RETURN ) {
switch( p->return_.f.style ) {
case CVRET_VOID:
return( DS_NO_PARM );
case CVRET_DIRECT:
reg_list = (unsigned_8 *)(&p->return_ + 1);
return( LocationManyReg( ii, reg_list[0], ®_list[1], lc, ll ) );
case CVRET_CALLOC_NEAR:
case CVRET_CALLOC_FAR:
case CVRET_RALLOC_NEAR:
case CVRET_RALLOC_FAR:
//NYI: have to handle these suckers
NYI();
break;
}
return( DS_ERR|DS_BAD_LOCATION );
}
/* find out about return type */
ds = TypeIndexFillIn( ii, type, &it );
if( ds != DS_OK ) return( ds );
ds = ImpTypeBase( ii, &it, &it );
if( ds != DS_OK ) return( ds );
ds = ImpTypeInfo( ii, &it, lc, &ti );
if( ds != DS_OK ) return( ds );
switch( ti.kind ) {
case TK_VOID:
return( DS_BAD_LOCATION );
case TK_BOOL:
case TK_ENUM:
case TK_CHAR:
case TK_INTEGER:
case TK_POINTER:
switch( ii->mad ) {
case MAD_X86:
switch( ti.size ) {
case 1:
return( LocationOneReg( ii, CV_X86_AL, lc, ll ) );
case 2:
return( LocationOneReg( ii, CV_X86_AX, lc, ll ) );
case 4:
if( is32 ) {
return( LocationOneReg( ii, CV_X86_EAX, lc, ll ) );
} else {
return( LocationManyReg( ii, sizeof( DXAXList ), DXAXList, lc, ll ) );
}
case 6:
return( LocationManyReg( ii, sizeof( DXEAXList ), DXEAXList, lc, ll ) );
}
break;
case MAD_AXP:
return( LocationOneReg( ii, CV_AXP_r0, lc, ll ) );
}
return( DS_ERR|DS_FAIL );
case TK_REAL:
switch( ii->mad ) {
case MAD_X86:
return( LocationOneReg( ii, CV_X86_ST0, lc, ll ) );
case MAD_AXP:
return( LocationOneReg( ii, CV_AXP_f0, lc, ll ) );
}
return( DS_ERR|DS_FAIL );
case TK_COMPLEX:
switch( ii->mad ) {
case MAD_X86:
return( LocationManyReg( ii, sizeof( ST1ST0List ), ST1ST0List, lc, ll ) );
}
return( DS_ERR|DS_FAIL );
case TK_STRUCT:
case TK_ARRAY:
//NYI: have to handle these suckers
NYI();
break;
}
return( DS_ERR|DS_FAIL );
}
switch( call ) {
case CV_NEARC:
case CV_FARC:
/* all on stack */
return( DS_NO_PARM );
case CV_NEARPASCAL:
case CV_FARPASCAL:
case CV_NEARFASTCALL:
case CV_FARFASTCALL:
case CV_NEARSTDCALL:
case CV_FARSTDCALL:
case CV_NEARSYSCALL:
case CV_FARSYSCALL:
case CV_THISCALL:
case CV_MIPS:
case CV_AXP:
case CV_GENERIC:
//NYI: have to handle all of these suckers
NYI();
break;
}
return( DS_ERR|DS_NO_PARM );
}
dip_status DIPENTRY DIPImpSymObjType( imp_image_handle *ii,
imp_sym_handle *is, imp_type_handle *it, type_info *ti )
{
dip_status ds;
imp_type_handle func_it;
imp_type_handle this_it;
ds = ImpSymType( ii, is, &func_it );
if( ds != DS_OK ) return( ds );
ds = TypeMemberFuncInfo( ii, &func_it, it, &this_it, NULL );
if( ds != DS_OK ) return( ds );
if( ti != NULL ) {
ds = ImpTypeInfo( ii, &this_it, NULL, ti );
if( ds != DS_OK ) return( ds );
}
return( DS_OK );
}
dip_status DIPENTRY DIPImpSymObjLocation( imp_image_handle *ii,
imp_sym_handle *is, location_context *lc,
location_list *ll )
{
char *name;
unsigned len;
dip_status ds;
virt_mem check;
virt_mem next;
s_all *p;
imp_sym_handle parm;
imp_type_handle it;
type_info ti;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?