dbgprog.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,649 行 · 第 1/4 页

C
1,649
字号
/****************************************************************************
*
*                            Open Watcom Project
*
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
*  ========================================================================
*
*    This file contains Original Code and/or Modifications of Original
*    Code as defined in and that are subject to the Sybase Open Watcom
*    Public License version 1.0 (the 'License'). You may not use this file
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
*    provided with the Original Code and Modifications, and is also
*    available at www.sybase.com/developer/opensource.
*
*    The Original Code and all software distributed under the License are
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
*    NON-INFRINGEMENT. Please see the License for the specific language
*    governing rights and limitations under the License.
*
*  ========================================================================
*
* Description:  Processing of the NEW command, program and symbol loading.
*
****************************************************************************/


#include <string.h>
#include <stdio.h>
#include "spawn.h"
#include "dbgdefn.h"
#include "dbglit.h"
#include "dbgio.h"
#include "dbgtoggl.h"
#include "dbgtoken.h"
#include "dbgerr.h"
#include "dbginfo.h"
#include "dbgmem.h"
#include "dbgbreak.h"
#include "dbghook.h"
#include "trpcore.h"
#include "dbgreg.h"
#include "mad.h"
#include "dui.h"
#include "tistrail.h"
#include <limits.h>


search_result           LineCue( mod_handle, cue_file_id,
                          unsigned long line, unsigned column, cue_handle *ch );
extern cue_file_id      CueFileId( cue_handle * );
extern unsigned         CueFile( cue_handle *ch, char *file, unsigned max );
extern unsigned long    CueLine( cue_handle *ch );
extern void             StdInNew( void );
extern void             StdOutNew( void );
extern void             Warn( char * );
extern unsigned int     ScanCmd( char * );
extern void             Scan( void );
extern bool             ScanItem( bool, char **, unsigned int * );
extern void             ReqEOC( void );
extern bool             KillProgOvlay( void );
extern void             ReportTask( task_status, unsigned );
extern void             BPsDeac( void );
extern void             BPsUnHit( void );
extern unsigned         DoLoad( char *, unsigned long * );
extern void             ClearMachState( void );
extern void             SetupMachState( void );
extern unsigned long    RemoteGetLibName( unsigned long, void *, unsigned );
extern unsigned         RemoteStringToFullName( bool, char *, char *, unsigned );
extern char             *GetCmdArg( int );
extern void             SetCmdArgStart( int, char * );
extern void             RemoteSplitCmd( char *, char **, char ** );
extern void             SymInfoMvHdl( handle, handle );
extern handle           PathOpen( char *, unsigned, char * );
extern handle           FullPathOpen( char *name, char *ext, char *result, unsigned max_result );
extern void             ChkExpr( void );
extern bool             ScanEOC( void );
extern char             *ReScan( char * );
extern unsigned         ReqExpr( void );
extern char             *ScanPos( void );
extern void             ReqMemAddr( memory_expr, address * );
extern void             SetNoSectSeg( void );
extern char             *Format( char *buff, char *fmt, ... );
extern void             TraceKill( void );
extern void             ActPoint( brk*, bool );
extern void             AddAliasInfo( unsigned, unsigned );
extern void             FreeAliasInfo( void );
extern void             CheckSegAlias( void );
extern char             *StrCopy( char *, char * );
extern void             SetCodeDot( address );
extern address          GetRegIP( void );
extern bool             DlgGivenAddr( char *title, address *value );
extern void             SetLastExe( char *name );
extern void             SetPointAddr( brk *bp, address addr );
extern void             RemoteMapAddr( addr_ptr *, addr_off *, addr_off *, unsigned long handle );
extern void             AddrSection( address *, unsigned );
extern void             VarFreeScopes( void );
extern void             VarUnMapScopes( image_entry * );
extern void             VarReMapScopes( image_entry * );
extern char             *DIPMsgText( dip_status );
extern address          GetRegSP( void );
extern bool             FindNullSym( mod_handle, address * );
extern bool             SetWDPresent( mod_handle );
extern void             RecordStart( void );
extern char             *GetCmdName( int index );
extern char             *GetCmdEntry( char *tab, int index, char *buff );
extern void             RecordEvent( char * );
extern bool             HookPendingPush( void );
extern char             *CheckForPowerBuilder( char * );
extern char             *DupStr( char * );
extern mod_handle       LookupImageName( char *start, unsigned len );
extern mod_handle       LookupModName( mod_handle search, char *start, unsigned len );
extern bool             GetBPSymAddr( brk *bp, address *addr );
extern void             DbgUpdate( update_list );
extern long             RemoteGetFileDate( char *name );
extern long             LocalGetFileDate( char *name );
extern bool             RemoteSetFileDate( char *name, long date );
extern unsigned         RemoteErase( char const * );
extern unsigned         MaxRemoteWriteSize( void );

extern void             InsertRing( char_ring **owner, char *start, unsigned len );
extern void             DeleteRing( char_ring **owner, char *start, unsigned len );
extern void             FreeRing( char_ring *p );
extern char_ring        **RingEnd( char_ring **owner );

extern void             WndSetCmdPmt(char *,char *,unsigned int ,void (*)());
static bool             CopyToRemote( char *local, char *remote, bool strip, void *cookie );
char                    *RealFName( char *name, open_access *loc );

extern void             DUIImageLoaded( image_entry*, bool, bool, bool* );
extern void             FClearOpenSourceCache( void );

extern tokens           CurrToken;
extern char             *TxtBuff;
extern system_config    SysConfig;
extern brk              UserTmpBrk;
extern brk              *BrkList;
extern mod_handle       CodeAddrMod;
extern mod_handle       ContextMod;
extern image_entry      *DbgImageList;
extern dip_status       DIPStatus;
extern machine_state    *DbgRegs;
extern bool             DownLoadTask;

static char             *SymFileName;
static char             *TaskCmd;
static process_info     *CurrProcess; //NYI: multiple processes

char_ring               *LocalDebugInfo;

#define SYM_FILE_IND ':'

bool InitCmd( void )
{
    unsigned    argc;
    char        *curr;
    char        *ptr;
    char        *end;
    char        *parm;
    char        *last;
    unsigned    total;
    char        *start;

    curr = GetCmdArg( 0 );
    if( curr != NULL ) {
        while( *curr == ' ' || *curr == '\t' ) ++curr;
        if( *curr == SYM_FILE_IND ) {
            ++curr;
            while( *curr == ' ' || *curr == '\t' ) ++curr;
            start = curr;
            while( *curr != ' ' && *curr != '\t' && *curr != '\0' ) ++curr;
            _Alloc( parm, curr - start + 1 );
            if( parm == NULL ) return( FALSE );
            SymFileName = parm;
            while( start < curr ) {
                *parm++ = *start++;
            }
            *parm = NULLCHAR;
            while( *curr == ' ' || *curr == '\t' ) ++curr;
            argc = 0;
            if( *curr == NULLCHAR ) {
                curr = GetCmdArg( ++argc );
            }
            SetCmdArgStart( argc, curr );
        }
    }
    argc = 0;
    total = 0;
    for( ;; ) {
        curr = GetCmdArg( argc );
        if( curr == NULL ) break;
        while( *curr != NULLCHAR ) {
            ++total;
            ++curr;
        }
        ++total;
        ++argc;
    }
    _Alloc( TaskCmd, total + 2 );
    if( TaskCmd == NULL ) return( FALSE );
    ptr = TaskCmd;
    argc = 0;
    for( ;; ) {
        curr = GetCmdArg( argc );
        if( curr == NULL ) break;
        while( *curr != NULLCHAR ) {
            *ptr = *curr++;
            if( *ptr == ARG_TERMINATE ) *ptr = ' ';
            ++ptr;
        }
        *ptr++ = NULLCHAR;
        ++argc;
    }
    *ptr = ARG_TERMINATE;
    last = ptr;
    RemoteSplitCmd( TaskCmd, &end, &parm );
    for( ptr = TaskCmd; ptr < end; ++ptr ) {
        if( *ptr == NULLCHAR ) *ptr = ' ';
    }
    memmove( ptr + 1, parm, last - parm + 1 );
    *ptr = NULLCHAR;
    ptr = TaskCmd;
    // If the program name was quoted, strip off the quotes
    if( *ptr == '\"' ) {
        memmove( ptr, ptr + 1, end - ptr );
        *( end - 2 ) = NULLCHAR;
    }
    return( TRUE );
}

void FindLocalDebugInfo( char *name )
{
    char    *buff, *symname, *fname;
    char    *ext;
    int     len = strlen( name );
    handle  local;

    _AllocA( buff, len + 1 + 4 + 2 );
    _AllocA( fname, len + 1 );
    _AllocA( symname, len + 1 + 4 );
    strcpy( buff, "@l" );
    // If a .sym file is present, use it in preference to the .exe
    StrCopy( name, fname );
    ext = ExtPointer( fname, OP_LOCAL );
    if( *ext != NULLCHAR )
        *ext = NULLCHAR;
    local = FullPathOpen( fname, "sym", symname, len + 4 );
    if( local != NIL_HANDLE ) {
        strcat( buff, symname );
        FileClose( local );
    } else {
        strcat( buff, name );
    }
    InsertRing( RingEnd( &LocalDebugInfo ), buff, len + 4 + 2 );
}

static void DoDownLoadCode( void )
/********************************/
{
    handle local;

    if( !DownLoadTask ) return;
    local = FullPathOpen( TaskCmd, "exe", TxtBuff, TXT_LEN );
    if( local == NIL_HANDLE ) {
        Error( ERR_NONE, LIT( ERR_FILE_NOT_OPEN ), TaskCmd );
    }
    FileClose( local );
    FindLocalDebugInfo( TxtBuff );
    CopyToRemote( TxtBuff, SkipPathInfo( TxtBuff, OP_LOCAL ), TRUE, NULL );
}


bool DownLoadCode( void )
/***********************/
{
    return( Spawn( DoDownLoadCode ) == 0 );
}

void FiniCmd()
{
    _Free( TaskCmd );
}

void InitLocalInfo()
{
    LocalDebugInfo = NULL;
}

void FiniLocalInfo( void )
{
    FreeRing( LocalDebugInfo );
    LocalDebugInfo = NULL;
}

image_entry *ImagePrimary( void )
{
    return( DbgImageList );
}

image_entry *ImageEntry( mod_handle mh )
{
    image_entry         **image_ptr;

    image_ptr = ImageExtra( mh );
    return( (image_ptr == NULL) ? NULL : *image_ptr );
}

address DefAddrSpaceForMod( mod_handle mh )
{
    image_entry *image;
    address     def_addr;

    image = ImageEntry( mh );
    if( image == NULL ) image = ImagePrimary();
    if( image != NULL ) {
        return( image->def_addr_space );
    }
    def_addr = GetRegSP();
    def_addr.mach.offset = 0;
    return( def_addr );
}

address DefAddrSpaceForAddr( address addr )
{
    mod_handle  mod;

    if( DeAliasAddrMod( addr, &mod ) == SR_NONE ) mod = NO_MOD;
    return( DefAddrSpaceForMod( mod ) );
}

OVL_EXTERN void MapAddrSystem( image_entry *image, addr_ptr *addr,
                        addr_off *lo_bound, addr_off *hi_bound )
{
    RemoteMapAddr( addr, lo_bound, hi_bound, image->system_handle );
}

static bool InMapEntry( map_entry *curr, addr_ptr *addr )
{
    if( addr->segment != curr->map_addr.segment ) return( FALSE );
    if( addr->offset < curr->map_valid_lo ) return( FALSE );
    if( addr->offset > curr->map_valid_hi ) return( FALSE );
    return( TRUE );
}

void MapAddrForImage( image_entry *image, addr_ptr *addr )
{
    map_entry           **owner;
    map_entry           *curr;
    addr_ptr            map_addr;
    addr_off            lo_bound;
    addr_off            hi_bound;

    owner = &image->map_list;
    for( ;; ) {
        curr = *owner;
        if( curr == NULL ) break;
        if( curr->pre_map || InMapEntry( curr, addr ) ) {
            curr->map_addr = *addr;
            curr->pre_map = FALSE;
            addr->segment = curr->real_addr.segment;
            addr->offset += curr->real_addr.offset;
            return;
        }
        owner = &curr->link;
    }
    map_addr = *addr;
    image->mapper( image, addr, &lo_bound, &hi_bound );
    _Alloc( curr, sizeof( *curr ) );
    if( curr != NULL ) {
        curr->link = NULL;
        *owner = curr;
        curr->map_valid_lo = lo_bound;
        curr->map_valid_hi = hi_bound;
        curr->map_addr = map_addr;
        curr->map_addr.offset = 0;
        curr->real_addr = *addr;
        curr->real_addr.offset -= map_addr.offset;
        curr->pre_map = FALSE;
    }
}


bool UnMapAddress( mappable_addr *loc, image_entry *image )
{
    map_entry           *map;
    mod_handle          himage;

    if( image == NULL ) {
        if( DeAliasAddrMod( loc->addr, &himage ) == SR_NONE ) return( FALSE );
        image = ImageEntry( himage );
    }
    if( image == NULL ) return( FALSE );
    DbgFree( loc->image_name );
    loc->image_name = DupStr( image->image_name );
    for( map = image->map_list; map != NULL; map = map->link ) {
        if( map->real_addr.segment == loc->addr.mach.segment ) {
            loc->addr.mach.segment = map->map_addr.segment;
            loc->addr.mach.offset = loc->addr.mach.offset - map->real_addr.offset;
            return( TRUE );
        }
    }
    return( FALSE );
}


static void UnMapOnePoint( brk *bp, image_entry *image )
{
    mod_handle          himage;
    if( bp->status.b.unmapped ) return;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?