cvsym.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,855 行 · 第 1/5 页
C
1,855 行
break;
case S_REGREL32:
disp = p->regrel32.f.offset;
ds = LocationOneReg( ii, p->regrel32.f.reg, lc, ll );
if( ds != DS_OK ) return( ds );
LocationCreate( &tmp_ll, LT_INTERNAL, &tmp.off48 );
ds = DCAssignLocation( ll, &tmp_ll, sizeof( addr48_off ) );
if( ds != DS_OK ) return( ds );
ds = DCItemLocation( lc, CI_DEF_ADDR_SPACE, ll );
if( ds != DS_OK ) return( ds );
ll->e[0].u.addr.mach.offset = tmp.off48 + disp;
break;
case S_LTHREAD32:
case S_GTHREAD32:
addr.mach.offset = p->lthread32.f.offset;
addr.mach.segment = p->lthread32.f.segment;
MapLogical( ii, &addr );
LocationCreate( ll, LT_ADDR, &addr );
break;
default:
Confused();
return( DS_FAIL );
}
return( DS_OK );
}
typedef struct {
cv_directory_entry *cde;
address start;
unsigned_32 len;
virt_mem scope;
virt_mem parent;
virt_mem end;
virt_mem next;
unsigned code;
} scope_info;
static dip_status ScopeFillIn( imp_image_handle *ii, virt_mem chk,
scope_info *scope, s_all **pp )
{
s_all *p;
p = VMBlock( ii, chk, sizeof( s_gproc32 ) );
if( pp != NULL ) *pp = p;
if( p == NULL ) return( DS_ERR|DS_FAIL );
scope->code = p->common.code;
scope->scope = chk;
scope->next = 0;
switch( p->common.code ) {
case S_LPROC16:
case S_GPROC16:
scope->start.mach.segment = p->lproc16.f.segment;
scope->start.mach.offset = p->lproc16.f.offset;
scope->len = p->lproc16.f.proc_length;
scope->parent = p->lproc16.f.pParent;
scope->end = p->lproc16.f.pEnd;
scope->next = p->lproc16.f.pNext;
break;
case S_THUNK16:
scope->start.mach.segment = p->thunk16.f.segment;
scope->start.mach.offset = p->thunk16.f.offset;
scope->len = p->thunk16.f.length;
scope->parent = p->thunk16.f.pParent;
scope->end = p->thunk16.f.pEnd;
scope->next = p->lproc16.f.pNext;
break;
case S_BLOCK16:
scope->start.mach.segment = p->block16.f.segment;
scope->start.mach.offset = p->block16.f.offset;
scope->len = p->block16.f.length;
scope->parent = p->block16.f.pParent;
scope->end = p->block16.f.pEnd;
break;
case S_WITH16:
scope->start.mach.segment = p->with16.f.segment;
scope->start.mach.offset = p->with16.f.offset;
scope->len = p->with16.f.length;
scope->parent = p->with16.f.pParent;
scope->end = p->with16.f.pEnd;
break;
case S_LPROC32:
case S_GPROC32:
scope->start.mach.segment = p->lproc32.f.segment;
scope->start.mach.offset = p->lproc32.f.offset;
scope->len = p->lproc32.f.proc_length;
scope->parent = p->lproc32.f.pParent;
scope->end = p->lproc32.f.pEnd;
scope->next = p->lproc16.f.pNext;
break;
case S_THUNK32:
scope->start.mach.segment = p->thunk32.f.segment;
scope->start.mach.offset = p->thunk32.f.offset;
scope->len = p->thunk32.f.length;
scope->parent = p->thunk32.f.pParent;
scope->end = p->thunk32.f.pEnd;
scope->next = p->lproc16.f.pNext;
break;
case S_BLOCK32:
scope->start.mach.segment = p->block32.f.segment;
scope->start.mach.offset = p->block32.f.offset;
scope->len = p->block32.f.length;
scope->parent = p->block32.f.pParent;
scope->end = p->block32.f.pEnd;
break;
case S_WITH32:
scope->start.mach.segment = p->with32.f.segment;
scope->start.mach.offset = p->with32.f.offset;
scope->len = p->with32.f.length;
scope->parent = p->with32.f.pParent;
scope->end = p->with32.f.pEnd;
break;
default:
return( DS_FAIL );
}
if( scope->parent != 0 ) scope->parent += scope->cde->lfo;
if( scope->next != 0 ) scope->next += scope->cde->lfo;
scope->end += scope->cde->lfo;
MapLogical( ii, &scope->start );
return( DS_OK );
}
static dip_status ScopeFindFirst( imp_image_handle *ii, imp_mod_handle im,
address addr, scope_info *scope )
{
virt_mem chk;
unsigned long len;
s_all *p;
scope_info new;
dip_status ds;
scope->cde = FindDirEntry( ii, im, sstAlignSym );
if( scope->cde == NULL ) return( DS_FAIL );
chk = scope->cde->lfo + sizeof( unsigned_32 );
len = scope->cde->cb - sizeof( unsigned_32 );
for( ;; ) {
if( len == 0 ) return( DS_FAIL );
p = VMBlock( ii, chk, sizeof( s_ssearch ) );
if( p == NULL ) return( DS_ERR|DS_FAIL );
if( p->common.code == S_SSEARCH ) {
scope->start.mach.segment = p->ssearch.f.segment;
scope->start.mach.offset = 0;
MapLogical( ii, &scope->start );
if( DCSameAddrSpace( scope->start, addr ) == DS_OK ) {
chk = p->ssearch.f.sym_off + scope->cde->lfo;
break;
}
}
chk += p->common.length + sizeof( p->common.length );
len -= p->common.length + sizeof( p->common.length );
}
/* found first scope block, now find correct offset */
for( ;; ) {
ds = ScopeFillIn( ii, chk, scope, NULL );
if( ds != DS_OK ) return( DS_ERR|ds );
if( addr.mach.offset >= scope->start.mach.offset
&& addr.mach.offset < (scope->start.mach.offset + scope->len) ) {
break;
}
if( scope->next == 0 ) return( DS_FAIL );
chk = scope->next;
}
/* found enclosing scope block, now find smallest one */
chk = scope->scope;
new.cde = scope->cde;
for( ;; ) {
ds = ScopeFillIn( ii, chk, &new, NULL );
if( ds & DS_ERR ) return( ds );
if( ds == DS_OK ) {
/* new scope */
if( !(addr.mach.offset >= new.start.mach.offset
&& addr.mach.offset < (new.start.mach.offset + new.len)) ) {
/* out of range */
chk = new.end;
} else if( !(new.start.mach.offset >= scope->start.mach.offset
&& (new.start.mach.offset+new.len) <= (scope->start.mach.offset+scope->len)) ) {
/* not smaller */
chk = new.end;
} else {
/* inner scope */
*scope = new;
}
} else if( p->common.code == S_END ) {
/* all done */
return( DS_OK );
}
p = VMBlock( ii, chk, sizeof( p->common ) );
if( p == NULL ) return( DS_ERR|DS_FAIL );
chk += p->common.length + sizeof( p->common.length );
}
}
static dip_status ScopeFindNext( imp_image_handle *ii, scope_info *scope )
{
if( scope->parent == 0 ) return( DS_FAIL );
return( ScopeFillIn( ii, scope->parent, scope, NULL ) );
}
static walk_result ScopeOneSymbol( imp_image_handle *ii, cv_directory_entry *cde,
scope_info *scope, IMP_SYM_WKR *wk, void *d,
virt_mem *currp )
{
scope_info new;
dip_status ds;
walk_result wr;
imp_sym_handle is;
s_all *p;
virt_mem curr;
curr = *currp;
new.cde = cde;
ds = ScopeFillIn( ii, curr, &new, &p );
if( ds & DS_ERR ) return( WR_FAIL );
if( ds == DS_OK ) {
*currp = new.end;
p = VMBlock( ii, *currp, sizeof( p->common ) );
if( p == NULL ) return( WR_FAIL );
}
*currp += p->common.length + sizeof( p->common.length );
switch( new.code ) {
case S_COMPILE:
case S_SSEARCH:
case S_END:
case S_SKIP:
case S_OBJNAME:
case S_ENDARG:
case S_RETURN:
case S_CEXMODEL16:
case S_VFTPATH16:
case S_THUNK16:
case S_BLOCK16:
case S_WITH16:
case S_CEXMODEL32:
case S_VFTPATH32:
case S_THUNK32:
case S_BLOCK32:
case S_WITH32:
/* not interested in these */
break;
case S_ENTRYTHIS:
curr += sizeof( s_common );
/* fall through */
default:
if( ds == DS_OK && scope != NULL ) {
/*
starting a new scope and not doing file scope
symbols -- skip scope start symbol
*/
break;
}
is.im = cde->iMod;
if( SymFillIn( ii, &is, curr ) != DS_OK ) return( WR_FAIL );
wr = wk( ii, SWI_SYMBOL, &is, d );
if( wr != WR_CONTINUE ) return( wr );
break;
}
return( WR_CONTINUE );
}
static walk_result ScopeWalkOne( imp_image_handle *ii, scope_info *scope,
IMP_SYM_WKR *wk, void *d )
{
walk_result wr;
s_all *p;
virt_mem curr;
curr = scope->scope;
p = VMBlock( ii, curr, sizeof( p->common ) );
if( p == NULL ) return( WR_FAIL );
/* skip over first scope start symbol */
curr += p->common.length + sizeof( p->common.length );
for( ;; ) {
p = VMBlock( ii, curr, sizeof( p->common ) );
if( p == NULL ) return( WR_FAIL );
if( p->common.code == S_END ) return( WR_CONTINUE );
wr = ScopeOneSymbol( ii, scope->cde, scope, wk, d, &curr );
if( wr != WR_CONTINUE ) return( wr );
}
}
static walk_result ScopeWalkClass( imp_image_handle *ii, scope_info *scope,
IMP_SYM_WKR *wk, void *d )
{
dip_status ds;
imp_type_handle it;
s_all *p;
imp_sym_handle is;
p = VMBlock( ii, scope->scope, sizeof( *p ) );
if( p == NULL ) return( WR_FAIL );
ds = TypeIndexFillIn( ii, SymTypeIdx( ii, p ), &it );
if( ds & DS_ERR ) return( WR_FAIL );
if( ds != DS_OK ) return( WR_CONTINUE );
ds = TypeMemberFuncInfo( ii, &it, &it, NULL, NULL );
if( ds & DS_ERR ) return( WR_FAIL );
if( ds != DS_OK ) return( WR_CONTINUE );
return( TypeSymWalkList( ii, &it, wk, &is, d ) );
}
static walk_result ScopeWalkAll( imp_image_handle *ii, imp_mod_handle im,
address addr, IMP_SYM_WKR *wk, void *d )
{
dip_status ds;
walk_result wr;
scope_info scope;
ds = ScopeFindFirst( ii, im, addr, &scope );
if( ds & DS_ERR ) return( WR_FAIL );
if( ds != DS_OK ) return( WR_CONTINUE );
for( ;; ) {
wr = ScopeWalkOne( ii, &scope, wk, d );
if( wr != WR_CONTINUE ) return( wr );
switch( scope.code ) {
case S_LPROC16:
case S_GPROC16:
case S_LPROC32:
case S_GPROC32:
wr = ScopeWalkClass( ii, &scope, wk, d );
if( wr != WR_CONTINUE ) return( wr );
break;
}
ds = ScopeFindNext( ii, &scope );
if( ds & DS_ERR ) return( WR_FAIL );
if( ds != DS_OK ) return( WR_CONTINUE );
}
}
static walk_result ScopeWalkFile( imp_image_handle *ii, imp_mod_handle im,
IMP_SYM_WKR *wk, void *d )
{
cv_directory_entry *cde;
virt_mem curr;
virt_mem end;
walk_result wr;
cde = FindDirEntry( ii, im, sstAlignSym );
if( cde == NULL ) return( WR_CONTINUE );
curr = cde->lfo;
end = curr + cde->cb;
curr += sizeof( unsigned_32 );
for( ;; ) {
if( curr >= end ) return( WR_CONTINUE );
wr = ScopeOneSymbol( ii, cde, NULL, wk, d, &curr );
if( wr != WR_CONTINUE ) return( wr );
}
}
static search_result TableSearchForAddr( imp_image_handle *ii,
address a, imp_sym_handle *is, addr_off *best_off, unsigned tbl_type )
{
cv_directory_entry *cde;
cv_sst_global_pub_header *hdr;
unsigned num_segs;
void *p;
unsigned i;
address chk;
virt_mem hash_base;
virt_mem base;
unsigned long offset_count;
unsigned long count;
addr_off new_off;
struct {
virt_mem base;
addr_off off;
} curr, best;
cde = FindDirEntry( ii, MH_GBL, tbl_type );
if( cde == NULL ) return( SR_NONE );
hdr = VMBlock( ii, cde->lfo, sizeof( *hdr ) );
if( hdr == NULL ) return( SR_FAIL );
switch( hdr->addrhash ) {
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?