cvtype.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 2,020 行 · 第 1/5 页
C
2,020 行
list->len = len;
wr = wk( ii, SWI_SYMBOL, list, p, d );
if( wr != WR_CONTINUE ) return( wr );
list->curr += len;
}
}
}
static void TypePrimitiveInfo( unsigned idx, type_info *ti )
{
static const unsigned_8 RealSizes[] = { 4, 8, 10, 16, 6 };
cv_primitive prim;
prim.s = idx;
switch( prim.f.mode ) {
case CV_DIRECT:
switch( prim.f.type ) {
case CV_SPECIAL:
switch( prim.f.size ) {
case 0x1:
ti->kind = TK_ADDRESS;
ti->size = sizeof( addr48_ptr );
break;
case 0x2:
ti->size = sizeof( addr_seg );
ti->kind = TK_DATA;
break;
case 0x3:
ti->size = 0;
ti->kind = TK_VOID;
break;
case 0x4:
ti->size = 8;
ti->kind = TK_DATA;
break;
case 0x5:
case 0x6:
/* Basic string: what size? */
ti->size = 0;
ti->kind = TK_STRING;
break;
}
break;
case CV_SIGNED:
ti->modifier = TM_SIGNED;
ti->kind = TK_INTEGER;
ti->size = 1 << prim.f.size;
if( ti->size == 1 ) ti->kind = TK_CHAR;
break;
case CV_UNSIGNED:
ti->modifier = TM_UNSIGNED;
ti->kind = TK_INTEGER;
ti->size = 1 << prim.f.size;
if( ti->size == 1 ) ti->kind = TK_CHAR;
break;
case CV_BOOL:
ti->kind = TK_BOOL;
ti->size = 1 << prim.f.size;
break;
case CV_REAL:
ti->kind = TK_REAL;
ti->size = RealSizes[ prim.f.size ];
break;
case CV_COMPLEX:
ti->kind = TK_COMPLEX;
ti->size = 2 * RealSizes[ prim.f.size ];
break;
case CV_SPECIAL2:
ti->kind = TK_DATA;
ti->size = 1;
break;
case CV_REALLYINT:
switch( prim.f.size ) {
case 0x0:
ti->kind = TK_CHAR;
ti->size = 1;
break;
case 0x1:
ti->kind = TK_CHAR;
ti->size = 2;
break;
case 0x2:
ti->modifier = TM_SIGNED;
ti->size = 2;
ti->kind = TK_INTEGER;
break;
case 0x3:
ti->modifier = TM_UNSIGNED;
ti->size = 2;
ti->kind = TK_INTEGER;
break;
case 0x4:
ti->modifier = TM_SIGNED;
ti->size = 4;
ti->kind = TK_INTEGER;
break;
case 0x5:
ti->modifier = TM_UNSIGNED;
ti->size = 4;
ti->kind = TK_INTEGER;
break;
case 0x6:
ti->modifier = TM_SIGNED;
ti->size = 8;
ti->kind = TK_INTEGER;
break;
case 0x7:
ti->modifier = TM_UNSIGNED;
ti->size = 8;
ti->kind = TK_INTEGER;
break;
}
break;
case 0x0f:
/* my own invention: T_CODE_LBL*, T_DATA_LBL* */
ti->kind = (prim.s & 0x08) ? TK_DATA : TK_CODE;
ti->size = 1 << prim.f.size;
break;
}
break;
case CV_NEARP:
ti->size = sizeof( addr32_off );
ti->modifier = TM_NEAR;
ti->kind = TK_POINTER;
break;
case CV_FARP:
ti->size = sizeof( addr32_ptr );
ti->modifier = TM_FAR;
ti->kind = TK_POINTER;
break;
case CV_HUGEP:
ti->size = sizeof( addr32_ptr );
ti->modifier = TM_HUGE;
ti->kind = TK_POINTER;
break;
case CV_NEAR32P:
ti->size = sizeof( addr48_off );
ti->modifier = TM_NEAR;
ti->kind = TK_POINTER;
break;
case CV_FAR32P:
ti->size = sizeof( addr48_ptr );
ti->modifier = TM_FAR;
ti->kind = TK_POINTER;
break;
case CV_NEAR64P:
ti->size = 8;
ti->modifier = TM_NEAR;
ti->kind = TK_POINTER;
break;
}
}
typedef struct {
cv_fldattr attr;
unsigned_16 type;
unsigned_32 vtab_off; /* optional: only if virtual function */
} method_info;
static method_info *GetMethodInfo( imp_image_handle *ii, unsigned ml_idx,
unsigned mf_idx )
{
virt_mem mlist;
method_info *p;
mlist = TypeIndexVM( ii, ml_idx );
if( mlist == 0 ) return( NULL );
mlist += sizeof( unsigned_16 ) * 2;
for( ;; ) {
p = VMBlock( ii, mlist, sizeof( *p ) );
if( p == NULL ) return( NULL );
if( mf_idx == 0 ) return( p );
mlist += sizeof( method_info );
switch( p->attr.f.mprop ) {
case CV_INTROVIRT:
case CV_PUREINTROVIRT:
break;
default:
mlist -= sizeof( p->vtab_off );
break;
}
--mf_idx;
}
}
static dip_status GetVirtBaseDisp( imp_image_handle *ii, virt_mem adj,
location_context *lc, location_list ll, unsigned long *disp )
{
lf_all *p;
void *ptr;
numeric_leaf val;
unsigned elt_type;
unsigned idx;
imp_type_handle vbp;
dip_status ds;
type_info ti;
union {
unsigned_8 u8;
unsigned_16 u16;
unsigned_32 u32;
} tmp;
location_list dst;
p = VMBlock( ii, adj, sizeof( *p ) + sizeof( unsigned_32 ) * 4 );
if( p == NULL ) return( DS_ERR|DS_FAIL );
ptr = GetNumLeaf( &p->vbclass + 1, &val );
LocationAdd( &ll, val.int_val * 8 );
GetNumLeaf( ptr, &val );
idx = val.int_val;
ds = TypeIndexFillIn( ii, p->vbclass.f.vtype, &vbp );
if( ds != DS_OK ) return( ds );
ds = ImpTypeInfo( ii, &vbp, lc, &ti );
if( ds != DS_OK ) return( ds );
if( ti.kind != TK_POINTER ) {
Confused();
}
p = VMBlock( ii, vbp.handle, sizeof( *p ) );
if( p == NULL ) return( DS_ERR|DS_FAIL );
if( p->pointer.f.type >= CV_FIRST_USER_TYPE ) {
ds = TypeIndexFillIn( ii, p->pointer.f.type, &vbp );
if( ds != DS_OK ) return( ds );
p = VMBlock( ii, vbp.handle, sizeof( *p ) );
if( p == NULL ) return( DS_ERR|DS_FAIL );
if( p->common.code != LF_ARRAY || p->array.f.elemtype >= CV_FIRST_USER_TYPE ) {
Confused();
}
elt_type = p->array.f.elemtype;
} else {
elt_type = p->pointer.f.type;
}
ds = DoIndirection( ii, &ti, lc, &ll );
TypePrimitiveInfo( elt_type, &ti );
ll.e[0].u.addr.mach.offset += ti.size * idx;
LocationCreate( &dst, LT_INTERNAL, &tmp );
ds = DCAssignLocation( &dst, &ll, ti.size );
if( ds != DS_OK ) return( ds );
switch( ti.size ) {
case 1:
*disp = tmp.u8;
break;
case 2:
*disp = tmp.u16;
break;
case 4:
*disp = tmp.u32;
break;
default:
Confused();
return( DS_ERR|DS_FAIL );
}
return( DS_OK );
}
struct vtab_data {
unsigned ptr_idx;
unsigned long disp;
};
static walk_result FindVTab( imp_image_handle *ii, sym_walk_info swi,
pending_type_list *list, lf_all *p, void *d )
{
struct vtab_data *vd = d;
ii = ii; list = list;
switch( swi ) {
case SWI_INHERIT_START:
case SWI_INHERIT_END:
return( WR_STOP );
}
/* SWI_SYMBOL: */
switch( p->common.code ) {
case LF_VFUNCTAB:
vd->disp = 0;
vd->ptr_idx = p->vfunctab.f.type;
return( WR_STOP );
case LF_VFUNCOFF:
vd->disp = p->vfuncoff.f.offset;
vd->ptr_idx = p->vfuncoff.f.type;
return( WR_STOP );
}
return( WR_CONTINUE );
}
static dip_status VFuncLocation( imp_image_handle *ii, imp_sym_handle *is,
unsigned_32 vfunc_off, location_context *lc, location_list *ll )
{
lf_all *p;
virt_mem base;
struct vtab_data data;
imp_type_handle it;
type_info ti;
unsigned_8 *vfsp;
unsigned vfshape;
addr_off save;
dip_status ds;
p = VMBlock( ii, is->containing_type, sizeof( *p ) );
if( p == NULL ) return( DS_ERR|DS_FAIL );
base = TypeIndexVM( ii, p->class_.f.field );
if( base == 0 ) return( DS_ERR|DS_FAIL );
switch( TypeListWalk( ii, base, is->containing_type, FindVTab, &data ) ) {
case WR_STOP:
break;
default:
return( DS_ERR|DS_FAIL );
}
ds = TypeIndexFillIn( ii, data.ptr_idx, &it );
if( ds != DS_OK ) return( ds );
ds = ImpTypeInfo( ii, &it, lc, &ti );
if( ds != DS_OK ) return( ds );
ds = DCItemLocation( lc, CI_OBJECT, ll );
if( ds != DS_OK ) return( ds );
LocationAdd( ll, data.disp * 8 );
ds = DoIndirection( ii, &ti, lc, ll );
if( ds != DS_OK ) return( ds );
LocationAdd( ll, vfunc_off * 8 );
ds = ImpTypeBase( ii, &it, &it );
if( ds != DS_OK ) return( ds );
vfsp = VMBlock( ii, it.handle + sizeof(unsigned_16)*2 + is->mfunc_idx/2,
sizeof( *vfsp ) );
if( vfsp == NULL ) return( DS_ERR|DS_FAIL );
if( (is->mfunc_idx % 2) != 0 ) {
vfshape = *vfsp >> 4;
} else {
vfshape = *vfsp & 0x0f;
}
switch( vfshape ) {
case CV_VTNEAR:
ti.modifier = TM_NEAR;
ti.size = sizeof( addr32_off );
break;
case CV_VTFAR:
ti.modifier = TM_FAR;
ti.size = sizeof( addr32_ptr );
break;
case CV_VTNEAR32:
ti.modifier = TM_NEAR;
ti.size = sizeof( addr48_off );
break;
case CV_VTFAR32:
ti.modifier = TM_FAR;
ti.size = sizeof( addr48_ptr );
break;
default:
Confused();
return( DS_ERR|DS_FAIL );
}
ds = DoIndirection( ii, &ti, lc, ll );
if( ds != DS_OK ) return( ds );
switch( vfshape ) {
case CV_VTNEAR:
case CV_VTNEAR32:
/* since it's a code item, the default addr space is CI_EXECUTION */
save = ll->e[0].u.addr.mach.offset;
ds = DCItemLocation( lc, CI_EXECUTION, ll );
if( ds != DS_OK ) return( ds );
ll->e[0].u.addr.mach.offset = save;
}
return( DS_OK );
}
static dip_status MatchSymLocation( imp_image_handle *ii, imp_sym_handle *is,
unsigned idx, location_context *lc, location_list *ll )
{
char *name;
unsigned len;
char *buff;
char *start;
imp_sym_handle real;
dip_status ds;
/*
Have to lookup "<scope>::<name>" with given type index to get
address. Ugh :-(.
*/
ds = TypeVMGetName( ii, is->handle, &name, &len, NULL );
if( ds != DS_OK ) return( ds );
/* name can't be longer than 256 because of CV format */
buff = __alloca( len + (SCOPE_TOKEN_LEN + 256) );
start = &buff[SCOPE_TOKEN_LEN+256];
buff = &start[len];
memcpy( start, name, len );
start -= SCOPE_TOKEN_LEN;
memcpy( start, SCOPE_TOKEN, SCOPE_TOKEN_LEN );
ds = TypeVMGetName( ii, is->containing_type, &name, &len, NULL );
if( ds != DS_OK ) return( ds );
start -= len;
memcpy( start, name, len );
ds = SymFindMatchingSym( ii, start, buff-start, idx, &real );
if( ds != DS_OK ) return( ds );
return( ImpSymLocation( ii, &real, lc, ll ) );
}
dip_status TypeSymGetAddr( imp_image_handle *ii, imp_sym_handle *is,
location_context *lc, location_list *ll )
{
lf_all *p;
numeric_leaf val;
dip_status ds;
unsigned idx;
imp_type_handle base;
unsigned long disp;
method_info *minfo;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?