debugger.c

/*
    File:       debugger.c
 
    Contains:   This is a small snippet of code that can be used to to detect if
                macsbug is installed or not. NOTE:  This code is intended to only
                work with version 6.2 of macsbug.  You should refer to your Low Level
                Debugger's manual for more information on how they install
                themselves.
    
                This code is based on information obtained from the MacsBug
                Reference. The basic assumptions are that macsbug will install itself
                in the following manner:
        
                If you are running with a Memory Manager that only works in 24 bit
                mode, then the high -order byte of MacJmp is a flags byte that
                contains the following information:
    
                Bit Meaning
                --- --------------------------------------
                7   -   Set if debugger is running
                6   -   Set if debugger can handle system errors
                5   -   Set if debugger is installed
                4   -   Set if debugger can support discipline utility
    
                The lower 3 bytes are used to store the address of the debugger's
                entry point.
    
                If you are running with a Memory Manager that works in 32-bit mode,
                the flags byte is moved to address 0xBFF and the long word at MacJmp
                becomes a full 32-bit address that points to the debugger's entry
                point..
    
                Symantec has a comment in the Think Reference 2.0.1 which states:
    
                "ADDENDUM:  The above information seems to be incorrect in the
                reference manual. I have found through testing etc. that in both
                modes, the Flag Byte appears at location 0xBFF.  The code reflects
                these findings."
            
                This is because they confused running in 24 bit mode, running in 32
                bit mode, and the _ability_ to run in 32 bit mode.  It is the latter
                ability which you must test to determine the location of the debugger
                flags.
 
    Written by:     
 
    Copyright:  Copyright © 1999 by Apple Computer, Inc., All Rights Reserved.
 
                You may incorporate this Apple sample source code into your program(s) without
                restriction. This Apple sample source code has been provided "AS IS" and the
                responsibility for its operation is yours. You are not permitted to redistribute
                this Apple sample source code as "Apple sample source code" after having made
                changes. If you're going to re-distribute the source, we require that you make
                it clear in the source that the code was descended from Apple sample source
                code, but that you've made changes.
 
    Change History (most recent first):
                8/12/1999   Karl Groethe    Updated for Metrowerks Codewarror Pro 2.1
                
 
*/ 
#define TEST    // if you want a standalone procedure, undefine TEST
 
#include <Memory.h>
#include <Gestalt.h>
#include <LowMem.h>
 
/* stuff that should be defined in C, but isn't (it's in Private.a) */
#define MacJmp          (Ptr *)  0x120      /* MACSBUG jumptable [pointer] */
#define MacJmpByte      (char *) 0x120      /* MACSBUG flags in 24 bit mode [byte] */
#define MacJmpFlag      (char *) 0xBFF      /* MacsBug flag [byte] */
 
enum dTypes {
    noDebugger,
    macsbug,
    tmon,
    other
};
 
typedef enum dTypes debuggerTypes;
 
/* stuff for use in this code */
#define DebuggerInstalled   5
Boolean
GetDebuggerInfo(debuggerTypes *kind, short *signature);
/*
** GetDebuggerInfo
** as documented in the "Macsbug Reference & Debugging Guide", page 412
** if we have a 32 bit capable Memory Manager, debugger flags are at $BFF
** if we have a 24 bit capable Memory Manager, debugger flags are at $120
** Ptr at $120 
**
** Note that the documentation is slightly obscure--you check if the machine
** is capable of 32-bit mode, _not_ if you are running in 32 bit mode.
**/
Boolean
GetDebuggerInfo(debuggerTypes *kind, short *signature)
{
    short   debugFlags;
    Ptr     debugEntry;
    short   **debugWorld;
    Ptr     ROMBaseWorld;
    long    addressingMode;
    
    /* initialize defaults, assuming no debugger present */
    *kind = noDebugger;
    *signature = '  ';
 
    Gestalt(gestaltAddressingModeAttr, &addressingMode);
    if (addressingMode & (1 << gestalt32BitCapable))
        debugFlags = *MacJmpFlag;
    else
        debugFlags = *MacJmpByte;
 
    if ( debugFlags & (1 << DebuggerInstalled) ) {
 
        /* we've got a debugger. what is it? */
        debugEntry = StripAddress(*MacJmp);
        ROMBaseWorld = StripAddress((Ptr)*(long *)LMGetROMBase());
 
        if (debugEntry < ROMBaseWorld) {    /* not ROM based debugger */
 
            debugWorld = (short **)StripAddress(debugEntry - sizeof(Ptr));
            *signature = **debugWorld;
            switch (*signature) {
                case 'MT':
                    *kind = macsbug;
                    break;
                case 'WH':
                    *kind = tmon;
                    break;
                default:
                    *kind = other;
                    break;
            }
        }
        return true;
    }
    return false;
}
 
#ifdef TEST
 
#include <stdio.h>
 
void main()
{
    debuggerTypes   k;
    union {
        short   sigShort;
        char    sigChar[2];
    } s;
    char    *dbgTypes[] = {"no debugger", "Macsbug", "TMON", "other debugger"};
    printf("Test of debugger info\n");
    
    if (GetDebuggerInfo(&k, &s.sigShort))
        printf("Debugger type is %s and debugger signature is %c%c",
            dbgTypes[k], s.sigChar[0], s.sigChar[1]);
    else
        printf("Didn't find a debugger.\n");
}
 
#endif