dbgprog.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,649 行 · 第 1/4 页
C
1,649 行
if( image != NULL ) {
if( DeAliasAddrMod( bp->loc.addr, &himage ) == SR_NONE ) return;
if( image != ImageEntry( himage ) ) return;
}
if( bp->image_name == NULL || bp->mod_name == NULL ) {
bp->status.b.unmapped = UnMapAddress( &bp->loc, image );
} else {
bp->status.b.unmapped = TRUE;
}
}
void UnMapPoints( image_entry *image )
{
brk *bp;
for( bp = BrkList; bp != NULL; bp = bp->next ) {
UnMapOnePoint( bp, image );
}
if( UserTmpBrk.status.b.has_address ) {
UnMapOnePoint( &UserTmpBrk, image );
}
}
void FreeImage( image_entry *image )
{
image_entry **owner;
image_entry *curr;
map_entry *head;
map_entry *next;
owner = &DbgImageList;
for( ;; ) {
curr = *owner;
if( curr == NULL ) return;
if( curr == image ) break;
owner = &curr->link;
}
if( curr == ImageEntry( ContextMod ) ) {
ContextMod = NO_MOD;
}
if( curr == ImageEntry( CodeAddrMod ) ) {
CodeAddrMod = NO_MOD;
}
VarUnMapScopes( curr );
UnMapPoints( curr );
*owner = curr->link;
for( head = curr->map_list; head != NULL; head = next ) {
next = head->link;
_Free( head );
}
_Free( curr->sym_name );
_Free( curr );
}
static image_entry *DoCreateImage( char *exe, char *sym )
{
image_entry *image;
image_entry **owner;
unsigned len;
len = (exe==NULL) ? 0 : strlen( exe );
_ChkAlloc( image, sizeof( *image ) + len, LIT( ERR_NO_MEMORY_FOR_DEBUG ) );
if( image == NULL ) return( NULL );
memset( image, 0, sizeof( *image ) );
if( len != 0 ) memcpy( image->image_name, exe, len + 1 );
if( sym != NULL ) {
_Alloc( image->sym_name, strlen( sym ) + 1 );
if( image->sym_name == NULL ) {
_Free( image );
Error( ERR_NONE, LIT( ERR_NO_MEMORY_FOR_DEBUG ) );
return( NULL );
}
strcpy( image->sym_name, sym );
}
image->mapper = MapAddrSystem;
for( owner = &DbgImageList; *owner != NULL; owner = &(*owner)->link )
{}
*owner = image;
return( image );
}
char *GetLastImageName( void )
{
image_entry *image;
for( image = DbgImageList; image->link != NULL; image = image->link ) ;
return( image->image_name );
}
static image_entry *CreateImage( char *exe, char *sym )
{
image_entry *image;
bool local;
char *curr_name;
char *curr_ext;
char curr_extchar;
char *this_name;
char *this_ext;
char this_extchar;
char_ring *curr;
open_access ind;
if( exe != NULL && sym == NULL ) {
local = FALSE;
this_name = SkipPathInfo( exe, OP_REMOTE );
this_ext = ExtPointer( exe, OP_REMOTE );
this_extchar = *this_ext;
*this_ext = '\0';
for( curr = LocalDebugInfo; curr != NULL; curr = curr->next ) {
curr_name = SkipPathInfo( curr->name, OP_LOCAL );
curr_name = RealFName( curr_name, &ind );
if( curr_name[0] == '@' && curr_name[1] == 'l' ) curr_name += 2;
curr_ext = ExtPointer( curr->name, OP_LOCAL );
curr_extchar = *curr_ext;
*curr_ext = '\0';
local = stricmp( this_name, curr_name ) == 0;
*curr_ext = curr_extchar;
if( local ) {
sym = curr->name;
break;
}
}
*this_ext = this_extchar;
}
_SwitchOn( SW_ERROR_RETURNS );
image = DoCreateImage( exe, sym );
_SwitchOff( SW_ERROR_RETURNS );
return( image );
}
static bool CheckLoadDebugInfo( image_entry *image, handle h,
unsigned start, unsigned end )
{
char buff[TXT_LEN];
char *name;
unsigned prio;
char *endstr;
prio = start;
for( ;; ) {
prio = DIPPriority( prio );
if( prio == 0 ) return( FALSE );
if( prio > end ) return( FALSE );
DIPStatus = DS_OK;
image->dip_handle = DIPLoadInfo( h, sizeof( image_entry * ), prio );
if( image->dip_handle != NO_MOD ) break;
if( DIPStatus & DS_ERR ) {
name = image->sym_name;
if( name == NULL ) name = image->image_name;
endstr = Format( buff, LIT( Sym_Info_Load_Failed ), name );
*endstr++ = ' ';
StrCopy( DIPMsgText( DIPStatus ), endstr );
Warn( buff );
return( FALSE );
}
}
*(image_entry **)ImageExtra( image->dip_handle ) = image;
return( TRUE );
}
/*
* ProcSymInfo -- initialize symbolic information
*
* Note: This function should try to open files locally first, for two
* reasons:
* 1) If a local file is open as remote, then local caching may interfere with
* file operations (notably seeks with DIO_SEEK_CUR)
* 2) Remote access goes through extra layer of indirection; this overhead
* is completely unnecessary for local debugging.
*/
static bool ProcSymInfo( image_entry *image )
{
handle h;
unsigned last;
char buff[TXT_LEN];
char *sym_name;
char *nopath;
unsigned len;
image->deferred_symbols = FALSE;
if( _IsOff( SW_LOAD_SYMS ) ) return( NO_MOD );
if( image->sym_name != NULL ) {
last = DP_MAX;
h = PathOpen( image->sym_name, strlen( image->sym_name ), "sym" );
if( h == NIL_HANDLE ) {
nopath = SkipPathInfo( image->sym_name, OP_REMOTE );
h = PathOpen( nopath, strlen( nopath ), "sym" );
if( h == NIL_HANDLE ) {
/* try the sym file without an added extension */
h = FileOpen( image->sym_name, OP_READ );
}
}
} else {
last = DP_EXPORTS-1;
h = FileOpen( image->image_name, OP_READ );
if( h == NIL_HANDLE ) {
h = FileOpen( image->image_name, OP_READ | OP_REMOTE );
}
}
if( h != NIL_HANDLE ) {
if( CheckLoadDebugInfo( image, h, DP_MIN, last ) ) {
return( TRUE );
}
FileClose( h );
}
if( image->sym_name != NULL ) return( FALSE );
_AllocA( sym_name, strlen( image->image_name ) + 1 );
strcpy( sym_name, image->image_name );
*ExtPointer( sym_name, OP_REMOTE ) = '\0';
len = MakeFileName( buff, sym_name, "sym", OP_REMOTE );
_Alloc( image->sym_name, len + 1 );
if( image->sym_name != NULL ) {
memcpy( image->sym_name, buff, len + 1 );
h = FileOpen( image->sym_name, OP_READ );
if( h == NIL_HANDLE ) {
h = FileOpen( image->sym_name, OP_READ | OP_REMOTE );
}
if( h == NIL_HANDLE ) {
h = PathOpen( image->sym_name, strlen( image->sym_name ), "" );
}
if( h != NIL_HANDLE ) {
if( CheckLoadDebugInfo( image, h, DP_MIN, DP_MAX ) ) {
return( TRUE );
}
FileClose( h );
}
_Free( image->sym_name );
}
image->sym_name = NULL;
if( _IsOff( SW_NO_EXPORT_SYMS ) ) {
if( _IsOn( SW_DEFER_SYM_LOAD ) ) {
image->deferred_symbols = TRUE;
} else {
h = FileOpen( image->image_name, OP_READ | OP_REMOTE );
if( h != NIL_HANDLE ) {
if( CheckLoadDebugInfo( image, h, DP_EXPORTS-1, DP_MAX ) ) {
return( TRUE );
}
FileClose( h );
}
}
}
return( FALSE );
}
void UnLoadSymInfo( image_entry *image, bool nofree )
{
if( image->dip_handle != NO_MOD ) {
image->nofree = nofree;
DIPUnloadInfo( image->dip_handle );
if( nofree ) {
image->dip_handle = NO_MOD;
image->nofree = FALSE;
}
DbgUpdate( UP_SYMBOLS_LOST );
FClearOpenSourceCache();
}
}
bool ReLoadSymInfo( image_entry *image )
{
if( ProcSymInfo( image ) ) {
DIPMapInfo( image->dip_handle, image );
DbgUpdate( UP_SYMBOLS_ADDED );
return( TRUE );
}
return( FALSE );
}
remap_return ReMapImageAddress( mappable_addr *loc, image_entry *image )
{
map_entry *map;
if( loc->image_name == NULL ) {
return( REMAP_WRONG_IMAGE );
}
if( strcmp( image->image_name, loc->image_name ) != 0 ) {
return( REMAP_WRONG_IMAGE );
}
for( map = image->map_list; map != NULL; map = map->link ) {
if( map->map_addr.segment == loc->addr.mach.segment ) {
loc->addr.mach.segment = map->real_addr.segment;
loc->addr.mach.offset = loc->addr.mach.offset + map->real_addr.offset;
AddrSection( &loc->addr, OVL_MAP_CURR );
DbgFree( loc->image_name );
loc->image_name = NULL;
return( REMAP_REMAPPED );
}
}
return( REMAP_ERROR );
}
bool ReMapAddress( mappable_addr *loc )
{
image_entry *image;
for( image = DbgImageList; image != NULL; image = image->link ) {
if( ReMapImageAddress( loc, image ) == REMAP_REMAPPED ) return( TRUE );
}
return( FALSE );
}
static remap_return ReMapOnePoint( brk *bp, image_entry *image )
{
mod_handle himage,mod;
bool ok;
address addr;
DIPHDL( cue, ch );
DIPHDL( cue, ch2 );
remap_return rc = REMAP_REMAPPED;
if( !bp->status.b.unmapped ) return( REMAP_WRONG_IMAGE );
if( bp->image_name == NULL || bp->mod_name == NULL ) {
if( image == NULL ) {
if( ReMapAddress( &bp->loc ) ) {
rc = REMAP_REMAPPED;
} else {
rc = REMAP_ERROR;
}
} else {
rc = ReMapImageAddress( &bp->loc, image );
}
} else {
himage = LookupImageName( bp->image_name, strlen( bp->image_name ) );
if( himage == NO_MOD ) return( REMAP_ERROR );
mod = LookupModName( himage, bp->mod_name, strlen( bp->mod_name ) );
if( mod == NO_MOD ) return( REMAP_ERROR );
ok = GetBPSymAddr( bp, &addr );
if( !ok ) return( REMAP_ERROR );
if( bp->cue_diff != 0 ) {
if( DeAliasAddrCue( mod, addr, ch ) != SR_EXACT ) return( REMAP_ERROR );
if( LineCue( mod, CueFileId( ch ), CueLine( ch ) + bp->cue_diff,
0, ch2 ) != SR_EXACT ) return( REMAP_ERROR );
addr = CueAddr( ch2 );
}
if( bp->addr_diff != 0 ) {
addr.mach.offset += bp->addr_diff;
}
bp->loc.addr = addr;
rc = REMAP_REMAPPED;
}
if( rc == REMAP_REMAPPED ) {
bp->status.b.unmapped = FALSE;
}
SetPointAddr( bp, bp->loc.addr );
if( bp->status.b.activate_on_remap ) {
ActPoint( bp, TRUE );
}
return( rc );
}
void ReMapPoints( image_entry *image )
{
brk *bp;
for( bp = BrkList; bp != NULL; bp = bp->next ) {
switch( ReMapOnePoint( bp, image ) ) {
case REMAP_ERROR:
ActPoint( bp, FALSE );
bp->status.b.activate_on_remap = TRUE;
break;
case REMAP_REMAPPED:
bp->countdown = bp->initial_countdown;
bp->total_hits = 0;
}
}
if( UserTmpBrk.status.b.has_address ) {
switch( ReMapOnePoint( &UserTmpBrk, image ) ) {
case REMAP_ERROR:
// nobody cares about this warning!! Warn( LIT( WARN_Unable_To_Remap_Tmp ) );
UserTmpBrk.status.b.active = FALSE;
break;
}
}
}
static void InitImageInfo( image_entry *image )
{
if( !FindNullSym( image->dip_handle, &image->def_addr_space ) ) {
image->def_addr_space = GetRegSP();
image->def_addr_space.mach.offset = 0;
}
SetWDPresent( image->dip_handle );
VarReMapScopes( image );
ReMapPoints( image );
}
bool LoadDeferredSymbols( void )
{
image_entry *image;
bool rc = FALSE;
bool defer;
defer = _IsOn( SW_DEFER_SYM_LOAD );
_SwitchOff( SW_DEFER_SYM_LOAD );
for( image = DbgImageList; image != NULL; image = image->link ) {
if( image->deferred_symbols ) {
if( ReLoadSymInfo( image ) ) {
InitImageInfo( image );
image->deferred_symbols = FALSE;
rc = TRUE;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?