wattype.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,874 行 · 第 1/4 页
C
1,874 行
return( DS_ERR|DS_BAD_LOCATION );
}
LocationAdd( ll, adj.e[0].u.addr.mach.offset * 8 );
new = new->prev;
}
ok = LoadType( ii, is->im, is->u.typ.t.entry );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
p = Type->start + is->u.typ.t.offset;
}
/* do field offset and bit field selection */
bit_start = 0;
bit_len = 0;
switch( p[1] ) {
case STRUCT_TYPE+ST_BIT_BYTE:
bit_start = p[3];
bit_len = p[4];
/* fall through */
case STRUCT_TYPE+ST_FIELD_BYTE:
offset = *(unsigned_8 *)(p+2);
break;
case STRUCT_TYPE+ST_BIT_WORD:
bit_start = p[4];
bit_len = p[5];
/* fall through */
case STRUCT_TYPE+ST_FIELD_WORD:
offset = *(unsigned_16 *)(p+2);
break;
case STRUCT_TYPE+ST_BIT_LONG:
bit_start = p[6];
bit_len = p[7];
/* fall through */
case STRUCT_TYPE+ST_FIELD_LONG:
offset = *(unsigned_32 *)(p+2);
break;
case STRUCT_TYPE+ST_FIELD_LOC:
case STRUCT_TYPE+ST_BIT_LOC:
if( info & (NEED_BASE|EMPTY_EXPR) ) PushBaseLocation( ll );
ok = EvalLocation( ii, lc, p + 3, ll );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
if( p[1] == STRUCT_TYPE+ST_BIT_LOC ) {
p = SkipLocation( p + 3 );
bit_start = p[0];
bit_len = p[1];
}
offset = 0;
}
PopLoad();
LocationAdd( ll, offset * 8 + bit_start );
LocationTrunc( ll, bit_len );
return( DS_OK );
}
dip_status SymHdl2MbrInfo( imp_image_handle *ii, imp_sym_handle *is,
sym_info *si, location_context *lc )
{
byte *p;
unsigned index;
dip_status ret;
unsigned attrib;
imp_type_handle tmp;
imp_sym_handle func_is;
byte kind;
location_list ll;
typeinfo typeld;
PushLoad( &typeld );
ret = LoadType( ii, is->im, is->u.typ.t.entry );
if( ret != DS_OK ) {
PopLoad();
return( ret );
}
p = Type->start + is->u.typ.t.offset;
switch( p[1] ) {
case STRUCT_TYPE+ST_FIELD_LOC:
case STRUCT_TYPE+ST_BIT_LOC:
attrib = p[2];
break;
default:
attrib = 0;
break;
}
p = BaseTypePtr( p );
GetIndex( p, &index );
ret = FindRawTypeHandle( ii, is->im, index, &tmp );
if( ret != DS_OK ) return( ret );
kind = GetRealTypeHandle( ii, &tmp ) & CLASS_MASK;
PopLoad();
switch( kind ) {
case PROC_TYPE:
si->kind = SK_PROCEDURE;
ret = SymHdl2MbrLoc( ii, is, lc, &ll );
if( ret == DS_OK ) {
func_is.im = is->im;
if( LookupLclAddr( ii, ll.e[0].u.addr, &func_is ) == SR_EXACT ) {
ret = SymHdl2LclInfo( ii, &func_is, si );
}
}
break;
default:
si->kind = SK_DATA;
break;
}
si->member = 1;
if( attrib & 0x01 ) si->compiler = 1;
if( attrib & 0x02 ) si->is_public = 1;
if( attrib & 0x04 ) si->is_protected = 1;
if( attrib & 0x08 ) si->is_private = 1;
return( ret );
}
dip_status DIPENTRY DIPImpTypeThunkAdjust( imp_image_handle *ii,
imp_type_handle *oit, imp_type_handle *mit,
location_context *lc, address *addr )
{
byte *p;
unsigned count;
struct anc_graph *pending, *new, *tmp;
imp_type_handle new_it;
unsigned index;
dip_status ok;
location_list adj;
typeinfo typeld;
if( oit->im != mit->im ) return( DS_FAIL );
PushLoad( &typeld );
ok = LoadType( ii, oit->im, oit->t.entry );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
p = Type->start + oit->t.offset;
pending = NULL;
count = *(unsigned_16 *)(p+2);
for( ;; ) {
if( count == 0 ) {
if( pending == NULL ) return( DS_FAIL );
ok = LoadType( ii, oit->im, pending->entry );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
count = pending->u.s.count;
p = Type->start + pending->u.s.off;
pending = pending->prev;
}
--count;
p = NEXT_TYPE( p );
if( p[1] == STRUCT_TYPE+ST_INHERIT ) {
new = __alloca( sizeof( *new ) );
new->entry = Type->entry;
new->u.s.off = p - Type->start;
new->u.s.count = count;
new->prev = pending;
pending = new;
p = SkipLocation( p + 2 );
GetIndex( p, &index );
ok = DoFindTypeHandle( ii, oit->im, index, &new_it );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
if( new_it.t.offset == mit->t.offset
&& new_it.t.entry == mit->t.entry ) break;
p = Type->start + new_it.t.offset;
count = *(unsigned_16 *)(p+2);
}
}
/* reverse the inheritance list */
new = NULL;
while( pending != NULL ) {
tmp = pending;
pending = tmp->prev;
tmp->prev = new;
new = tmp;
}
/* do the adjustors at each level */
while( new != NULL ) {
ok = LoadType( ii, oit->im, new->entry );
if( ok != DS_OK ) {
PopLoad();
return( ok );
}
p = new->u.s.off + Type->start;
ok = EvalLocation( ii, lc, p + 2, &adj );
if( !ok ) {
PopLoad();
return( ok );
}
if( adj.num != 1 || adj.e[0].type != LT_ADDR ) {
PopLoad();
DCStatus( DS_ERR|DS_BAD_LOCATION );
return( DS_ERR|DS_BAD_LOCATION );
}
addr->mach.offset += adj.e[0].u.addr.mach.offset;
new = new->prev;
}
PopLoad();
return( DS_OK );
}
search_result SearchMbr( imp_image_handle *ii, imp_type_handle *it,
lookup_item *li, void *d )
{
byte *p;
unsigned count;
search_result sr;
struct anc_graph *pending, *new;
imp_type_handle new_it;
unsigned index;
int (*comp)();
imp_sym_handle *is;
byte *name;
unsigned len;
typeinfo typeld;
PushLoad( &typeld );
if( LoadType( ii, it->im, it->t.entry ) != DS_OK ) {
PopLoad();
return( SR_NONE );
}
p = Type->start + it->t.offset;
if( (p[1] & CLASS_MASK) != STRUCT_TYPE ) {
PopLoad();
return( SR_NONE );
}
if( li->case_sensitive ) {
comp = memcmp;
} else {
comp = memicmp;
}
sr = SR_NONE;
pending = NULL;
count = *(unsigned_16 *)(p+2);
for( ;; ) {
if( count == 0 ) {
if( pending == NULL ) break;
if( LoadType( ii, it->im, pending->entry ) != DS_OK ) {
PopLoad();
return( WR_STOP );
}
count = pending->u.s.count;
p = Type->start + pending->u.s.off;
pending = pending->prev;
}
--count;
p = NEXT_TYPE( p );
if( p[1] == STRUCT_TYPE+ST_INHERIT ) {
new = __alloca( sizeof( *new ) );
new->entry = Type->entry;
new->u.s.off = p - Type->start;
new->u.s.count = count;
new->prev = pending;
pending = new;
p = SkipLocation( p + 2 );
GetIndex( p, &index );
if( DoFindTypeHandle( ii, it->im, index, &new_it ) != DS_OK ) {
PopLoad();
return( WR_STOP );
}
p = Type->start + new_it.t.offset;
count = *(unsigned_16 *)(p+2);
} else {
name = NamePtr( p );
len = *p - (name - p);
if( len==li->name.len && comp(name,li->name.start,len)==0 ) {
is = DCSymCreate( ii, d );
is->u.typ.t.offset = p - Type->start;
is->u.typ.t.entry = Type->entry;
is->name_off = name - p;
is->im = it->im;
is->u.typ.h = it->t;
is->type = SH_MBR;
sr = SR_EXACT;
}
}
}
PopLoad();
return( sr );
}
walk_result WalkTypeSymList( imp_image_handle *ii, imp_type_handle *it,
IMP_SYM_WKR *wk, imp_sym_handle *is, void *d )
{
byte *p;
unsigned count;
walk_result wr;
struct anc_graph *pending, *new;
imp_type_handle new_it;
unsigned index;
struct pending_entry *list, *new_entry, *used;
typeinfo typeld;
PushLoad( &typeld );
if( LoadType( ii, it->im, it->t.entry ) != DS_OK ) {
PopLoad();
return( WR_STOP );
}
is->im = it->im;
is->u.typ.h = it->t;
list = NULL;
used = NULL;
pending = NULL;
p = Type->start + it->t.offset;
switch( p[1] & CLASS_MASK ) {
case STRUCT_TYPE:
is->type = SH_MBR;
goto do_walk;
case ENUM_TYPE:
is->type = SH_CST;
do_walk:
count = *(unsigned_16 *)(p+2);
wr = WR_CONTINUE;
for( ;; ) {
while( count != 0 ) {
/* structure list is backwards -- reverse it */
p = NEXT_TYPE( p );
if( used == NULL ) {
new_entry = __alloca( sizeof( *new_entry ) );
} else {
new_entry = used;
used = used->prev;
}
new_entry->off = p - Type->start;
new_entry->prev = list;
list = new_entry;
--count;
}
if( list == NULL ) {
if( pending == NULL ) break;
wk( ii, SWI_INHERIT_END, NULL, d );
if( LoadType( ii, it->im, pending->entry ) != DS_OK ) {
PopLoad();
return( WR_STOP );
}
list = pending->u.todo;
pending = pending->prev;
}
p = list->off + Type->start;
if( p[1] == STRUCT_TYPE+ST_INHERIT ) {
if( wk( ii, SWI_INHERIT_START, NULL, d ) == WR_CONTINUE ) {
if( list->prev != NULL ) {
new = __alloca( sizeof( *new ) );
new->entry = Type->entry;
new->u.todo = list->prev;
new->prev = pending;
pending = new;
}
p = SkipLocation( p + 2 );
GetIndex( p, &index );
if( DoFindTypeHandle( ii, it->im, index, &new_it ) != DS_OK ) {
PopLoad();
return( WR_STOP );
}
list = NULL;
p = Type->start + new_it.t.offset;
count = *(unsigned_16 *)(p+2);
/* setting count will cause the list to be reversed */
continue;
}
} else {
is->u.typ.t.offset = p - Type->start;
is->u.typ.t.entry = Type->entry;
is->name_off = NamePtr( p ) - p;
wr = wk( ii, SWI_SYMBOL, is, d );
if( wr != WR_CONTINUE ) break;
}
new_entry = list->prev;
list->prev = used;
used = list;
list = new_entry;
}
break;
default:
wr = WR_STOP;
break;
}
PopLoad();
return( wr );
}
imp_mod_handle DIPENTRY DIPImpTypeMod( imp_image_handle *ii,
imp_type_handle *it )
{
ii = ii;
return( it->im );
}
void *FindSpecCueTable( imp_image_handle *ii, imp_mod_handle im, void **base )
{
typeinfo typeld;
byte *p;
unsigned entry;
unsigned long offset;
unsigned size;
PushLoad( &typeld );
if( LoadType( ii, im, 0 ) != DS_OK ) goto missing;
for( p = Type->start; p < Type->end; p = NEXT_TYPE( p ) ) {
if( p[1] == (NAME_TYPE+TYPE_CUE_TABLE) ) {
offset = *(unsigned_32 *)(p+2);
entry = 0;
for( ;; ) {
size = InfoSize( ii, im, DMND_TYPES, entry );
if( size == 0 ) goto missing;
if( size > offset ) break;
offset -= size;
++entry;
}
if( LoadType( ii, im, entry ) != DS_OK ) goto missing;
p = Type->start;
*base = p;
InfoSpecLock( p ); /* so that the PopLoad doesn't free it */
PopLoad();
return( p + (unsigned)offset );
}
}
missing:
*base = NULL;
PopLoad();
return( NULL );
}
int DIPENTRY DIPImpTypeCmp( imp_image_handle *ii, imp_type_handle *it1,
imp_type_handle *it2 )
{
ii = ii;
if( it1->im != it2->im ) return( it1->im - it2->im );
if( it1->t.entry != it2->t.entry ) return( it1->t.entry - it2->t.entry );
return( it1->t.offset - it2->t.offset );
}
unsigned DIPENTRY DIPImpTypeName( imp_image_handle *ii, imp_type_handle *it,
unsigned num, symbol_type *tag, char *buff, unsigned max )
{
//NYI: stub implementation
ii = ii; it = it; num = num; tag = tag; buff = buff; max = max;
return( 0 );
}
dip_status DIPENTRY DIPImpTypeAddRef( imp_image_handle *ii, imp_type_handle *it )
{
ii=ii;
it=it;
return(DS_OK);
}
dip_status DIPENTRY DIPImpTypeRelease( imp_image_handle *ii, imp_type_handle *it )
{
ii=ii;
it=it;
return(DS_OK);
}
dip_status DIPENTRY DIPImpTypeFreeAll( imp_image_handle *ii )
{
ii=ii;
return(DS_OK);
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?