⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nlmacc.c

📁 开放源码的编译器open watcom 1.6.0版的源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/****************************************************************************
*
*                            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:  Low-level Netware implementation code for the debugger trap.
*
****************************************************************************/


#include "debugme.h"
#include <stddef.h>
#include <string.h>     /* may only call functions defined in nlmstrt.c */
#include <fcntl.h>
#include <stdio.h>
#include <nwtypes.h>

#include "miniproc.h"

#include "loader.h"
//#include "nlmheadr.h"
#if !defined ( _USE_NEW_KERNEL )
#include "nwsemaph.h"
#endif
#include "debugapi.h"

#undef TRUE
#undef FALSE

#include "dbg386.h"
#include "trpimp.h"
#include "trperr.h"
#include "packet.h"
#include "exenov.h"
#include "madregs.h"

#include "nlmport.h"
#include "nw3to4.h"

#include "x86cpu.h"
#include "misc7386.h"

#define NO_DREG     ((byte)-1)
#define NUM_DREG    4

#define FLG_T           0x0100UL

typedef LONG pPID;

#if defined ( _USE_NEW_KERNEL )
void *          kSemaphoreAlloc( const char *, long );
unsigned long   kSemaphoreExamineCount( void *sp );
int             kSemaphoreFree( void *sp );
int             kSemaphoreWait( void *sp );
int             kSemaphoreTimedWait( void *sp, unsigned long ms);
int             kSemaphoreSignal( void *sp );
int             kSemaphoreTry( void *sp );
int             kSemaphoreValidate( void *sp );
int             kGetSemaphoreInfo( void *sp, char *name, size_t nameMax,
                    unsigned long *count, int *waitingThreads, void *owner );

// R.E.
int             kSemaphoreSignalAll( void *sp );

#endif

struct      {
    dword   address;
    byte    type;
    byte    size;
} DR[ NUM_DREG ];

typedef struct msb {
        struct msb                      *next;
        struct LoadDefinitionStructure  *load;
        pPID                             os_id;
        dword                           dbg_id;
        dword                           xnum;
        dword                           errnum;
        trap_cpu_regs                   cpu;
        trap_fpu_regs                   fpu;
#if defined ( _USE_NEW_KERNEL )
        void *                          ksem;
        void *                          tksem;
#else
        dword                           sem;
#endif
        char                            *description;
        unsigned                        asleep:1;/* sleeping on our semaphore */
        unsigned                        frozen:1;/* allowed to execute? */
        unsigned                        in_start_proc:1;/* our helper thread! */
        unsigned                        clib_created:1;/* created by CLIB*/
        unsigned                        to_be_killed:1;/* condemned */
        int                             exception_number;
} msb;

typedef enum {
        NLM_NONE,
        NLM_PRELOADING,
        NLM_LOADING,
        NLM_IN_START_PROC,
        NLM_FORCED_INIT_FAILURE,
        NLM_LOADED,
} nlmstate;

typedef struct nlm_entry {
        struct nlm_entry                *next;
        struct LoadDefinitionStructure  ld;
        bool                            is_load;
} nlm_entry;

static unsigned_8                       RealNPXType;

nlmstate                                NLMState;
#define BUFF_SIZE                       256
char                                    CmdLine[BUFF_SIZE];
char                                    NLMName[14];
char                                    UtilBuff[BUFF_SIZE];
msb                                     *MSB;
msb                                     *MSBHead;
trap_cpu_regs                           HelperThreadRegs;
dword                                   ThreadId;
#if defined ( _USE_NEW_KERNEL )
void *                                  kDebugSem = NULL;
void *                                  kHelperSem = NULL;
#else
dword                                   DebugSem = 0;
dword                                   HelperSem = 0;
#endif
struct LoadDefinitionStructure         *DebuggerLoadedNLM = NULL;
nlm_entry                               *NLMList = NULL;
nlm_entry                               *LastNLMListEntry = NULL;
bool                                    FakeBreak;
bool                                    DebuggerRunning;
bool                                    ExpectingEvent;
bool                                    TrapInt1;
byte                                    SavedFirstByte;
dword                                   DebugProcess;
byte                                    DebugPriority;
byte                                    RunningPriority;

/* from MYPRELUD.C */
extern struct ResourceTagStructure      *AllocTag;
extern struct ResourceTagStructure      *SemaphoreTag;
extern struct ResourceTagStructure      *ProcessTag;
extern void                             ServMessage(char*);


/* from NLMIO.C */
extern int IOCreat( char *name );
extern int IOOpen( char *openname, int openmode );
extern int IOClose( int closehandle );
extern int IOWrite( int writehandle, char *buff, int buff_len );
extern int IOWriteConsole( char *buff, int buff_len );
extern int IOSeek( int seekhandle, int seekmode, long seekpos );
extern int IORead( int readhandle, char *buff, int len );
extern void StringToNLMPath( char *name, char *res );

/* from NLMINTR.ASM */
extern void                     DoALongJumpTo( unsigned_32, unsigned_32, unsigned_32, unsigned_32, unsigned_32, unsigned_32, unsigned_32, unsigned_32, unsigned_32, unsigned_32 );
dword                           ReturnESP;
extern void                     Return( void );
extern int                      AdjustStack( dword old_esp, dword adjust );
extern word                     GetDS( void );
extern word                     GetCS( void );

/* from NLMCLIB.C */

extern struct LoadDefinitionStructure *GetNLMFromPID(pPID);
extern void                     BoobyTrapPID(pPID);
extern void                     UnBoobyTrapPID(pPID);
extern char                     *GetPIDName(pPID);
extern int                      ValidatePID(pPID);
extern void                     SetupPIDForACleanExit(pPID);
#if defined ( __NW40__ )
extern int                      ImportCLIBSymbols( void );
#endif

/* Must be CLIB! */
void  _exit( int __status );
#if defined ( __NW50__ )
void  NXVmExit( int status ) ;

int   get_app_type       ( void );

/* return flags for get_app_type()... */
#define LIBRARY_UNKNOWN      0x01  /* thread has default library context     */
#define LIBRARY_LIBC         0x02  /* thread has specific NKS/LibC context   */
#define LIBRARY_CLIB         0x04  /* thread has CLib context                */
#define LIBRARY_JAVA         0x08  /* thread belongs to Java Virtual Machine */

#endif


/* from SERVNAME.C */
extern char ServPref[];

typedef struct watch {
    addr48_ptr  addr;
    dword       value;
    dword       linear;
    short       dregs;
    short       len;
} watch;

#define MAX_WP  32
watch   WatchPoints[ MAX_WP ];
int     WatchCount;

/*
//  Code to release all waiters on a semaphore and delete it
*/
#if defined ( _USE_NEW_KERNEL )
int msb_KernelSemaphoreReleaseAll( msb * m )
{
    void *      ksem = m->ksem;
    m->ksem = NULL;
    m->tksem = ksem;

    return( kSemaphoreSignalAll( ksem ) );
}

int KernelSemaphoreReleaseAll( void * sp )
{
    kSemaphoreSignalAll( sp );
    return ( kSemaphoreFree( sp ) );
}

#endif

void NewNLMListEntry( struct LoadDefinitionStructure *ld )
{
    nlm_entry   *new;

    new = Alloc( sizeof( *new ), AllocTag );
    new->next = NLMList;
    new->ld = *ld;
    new->is_load = TRUE;
    NLMList = new;
//  _DBG_EVENT(( "NewNLMListEntry: %8x %s\r\n", ld, &(ld->LDFileName[1]) ));
}

void DeadNLMListEntry( struct LoadDefinitionStructure *ld )
{
    nlm_entry   *curr;

    for( curr = NLMList; curr != NULL; curr = curr->next ) {
        if( !curr->is_load )
            continue;
        if( curr->ld.LDCodeImageOffset != ld->LDCodeImageOffset )
            continue;
        curr->is_load = FALSE;
//      _DBG_EVENT(( "DeadNLMListEntry: %8x %s\r\n", ld, &(ld->LDFileName[1]) ));
        break;
    }
}

void FreeAnNLMListEntry( void )
{
    nlm_entry   *junk;

    junk = NLMList;
    NLMList = NLMList->next;
    Free( junk );
}

msb *LocateThread( pPID pid )
{
    msb         *m;

    m = MSBHead;
    _DBG_THREAD(( "Looking for  MSB for thread=%8x -- \r\n", pid ));
    while( m != NULL ) {
        if( m->os_id == pid ) {
            _DBG_THREAD(( "Found MSB=%8x TID=%d\r\n", m, m->dbg_id ));
            return( m );
        }
        m = m->next;
    }
    m = Alloc( sizeof( msb ), AllocTag );

    if( NULL == m ){
        _DBG_ERROR(( "LocateThread: Failed to allocate msb block\r\n" ));
        return NULL;
    }

    m->description = NULL;
    m->load = NULL;
    m->os_id = pid;
    m->dbg_id = ++ThreadId;
    m->asleep = FALSE;
    m->frozen = FALSE;
    m->in_start_proc = FALSE;
    m->clib_created = FALSE;
    m->to_be_killed = FALSE;
#if defined ( _USE_NEW_KERNEL )
    m->ksem = NULL;
    m->tksem = NULL;
#else
    m->sem = 0;
#endif
    m->next = MSBHead;
    //_DBG_THREAD(( "Allocating MSB=%8x TID=%d\r\n", m, m->dbg_id ));
    MSBHead = m;
    return( m );
}

void FreeThread( msb *m )
{
    msb **owner;
    msb *curr;

    _DBG_THREAD(( "Trying to free thread MSB=%8x -- \r\n", m ));
    owner = &MSBHead;
    for( ;; ) {
        curr = *owner;
        if( curr == NULL )
            return;
        if( curr == m ) {
            *owner = curr->next;
            _DBG_THREAD(( "Freed it\r\n" ));
#if defined ( _USE_NEW_KERNEL )
            if( m->ksem){
                kSemaphoreFree( m->ksem );
                m->ksem = NULL;
            }
#else
            if( m->sem )
                CDeAllocateSemaphore( m->sem );
#endif
            Free( m );
            _DBG_THREAD(( "\r\n" ));
            return;
        }
        owner = &(curr->next);
    }
}


void FreeInvalidThreads( void )
{
    msb **owner;
    msb *curr;

    owner = &MSBHead;
    for( ;; ) {
        curr = *owner;
        if( curr == NULL )
            return;
        if( !ValidatePID( curr->os_id ) ) {
            *owner = curr->next;    /* remove MSB from chain */
#if defined ( _USE_NEW_KERNEL )
            if( curr->ksem ){
                kSemaphoreFree( curr->ksem );
                curr->ksem = NULL;
            }
#else
            if( curr->sem )
                CDeAllocateSemaphore( curr->sem );
#endif
            //owner = &(curr->next);
            owner = &MSBHead;       /* start from the begiining again */
            Free( curr );           /* free MSB */
        } else {
            owner = &(curr->next);
        }
    }
}


void Suicide( void )
{
    CDestroyProcess( CGetMyProcessID() );
}


void TheBigSleep( void )
{
    while( TRUE ) {
        CSleepUntilInterrupt();
    }
}


void WakeDebugger( void )
{
    if( !DebuggerRunning ) {
        ClearDebugRegs();
        DebuggerRunning = TRUE;
#if defined ( _USE_NEW_KERNEL )
        kSemaphoreSignal( kDebugSem );
#else
        CVSemaphore( DebugSem );
#endif
    }
}


void SleepDebugger( void )
{
    DebuggerRunning = FALSE;
#if defined ( _USE_NEW_KERNEL )
    kSemaphoreWait( kDebugSem );
#else
    CPSemaphore( DebugSem );
#endif
    DebuggerRunning = TRUE;
}


#if 0
bool IsInOSCode( LONG eip )
{
    LoadedListHandle loadhandle;
    struct LoadDefinitionStructure *loaded;

    for( loadhandle = GetNextLoadedListEntry( 0 );
         loadhandle != 0; loadhandle = GetNextLoadedListEntry( loadhandle ) ) {
        loaded = ValidateModuleHandle( loadhandle );
        if( eip >= loaded->LDCodeImageOffset
         && eip <  loaded->LDCodeImageOffset + loaded->LDCodeImageLength ) {
            return( FALSE );
        }
    }
    if( DebuggerLoadedNLM ) { /* might not be on the LoadedList yet */
        if( eip >= DebuggerLoadedNLM->LDCodeImageOffset
         && eip <  DebuggerLoadedNLM->LDCodeImageOffset
                 + DebuggerLoadedNLM->LDCodeImageLength ) {
            return( FALSE );
        }
    }
    return( TRUE );
}


bool CheckIfBreakOKInOS( LONG eip )
{
    if( !IsInOSCode( eip ) )
        return( TRUE );
    ServMessage( TRP_NLM_cant_debug_os );
    return( FALSE );
}
#endif


unsigned_8 NPX( void )
{
    if( HAVE_EMU == 0 )
        return( RealNPXType );
#if defined ( __NW50__ ) || defined ( __NW40__ )
    return( X86_EMU );
#elif defined ( __NW30__ )
    {
        struct ExternalPublicDefinitionStructure    *epd;

        #define EMU_NAME        "__init_387_emulator"
        #define EMU_LEN         ( sizeof( EMU_NAME ) - 1 )

        for( epd = ExternalPublicList; epd != NULL; epd = epd->EPDLink ) {
            if( epd->EPDName[0] == EMU_LEN ) {
                if( memcmp( EMU_NAME, &epd->EPDName[1], EMU_LEN ) == 0 ) {
                    return( X86_EMU );
                }
            }
        }
        return( RealNPXType );
    }
#endif
}


#define SaveRegs( reg_struct ) \
    reg_struct.EAX = FieldEAX( frame ); \
    reg_struct.EBX = FieldEBX( frame ); \
    reg_struct.ECX = FieldECX( frame ); \
    reg_struct.EDX = FieldEDX( frame ); \
    reg_struct.ESI = FieldESI( frame ); \
    reg_struct.EDI = FieldEDI( frame ); \
    reg_struct.EBP = FieldEBP( frame ); \
    reg_struct.ESP = FieldESP( frame ); \
    reg_struct.EIP = FieldEIP( frame ); \
    reg_struct.EFL = FieldEFLAGS( frame ); \
    reg_struct.CS  = FieldCS( frame ); \
    reg_struct.DS  = FieldDS( frame ); \
    reg_struct.ES  = FieldES( frame ); \
    reg_struct.SS  = FieldDS( frame ); \
    reg_struct.FS  = FieldFS( frame ); \
    reg_struct.GS  = FieldGS( frame );

⌨️ 快捷键说明

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