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 + -
显示快捷键?