dipdump.c

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

C
1,069
字号
/****************************************************************************
*
*                            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:  Dumper and test program for DIPs.
*
****************************************************************************/


#include <string.h>
#include <stdio.h>
#include <stddef.h>
#include <stdarg.h>
#include <sys/stat.h>
#include <time.h>
#include <unistd.h>
#include "walloca.h"
#include "bool.h"
#include "dip.h"
#include "digcli.h"

/**
 * Options
 */
static struct {
    unsigned    do_cue_tests : 1;   /* Perform the various Cue tests. */
} Opts = { 1 };


/**
 * Prints an error message.
 *
 * @returns Appropriate exit code for an error.
 *
 * @param   pszFormat   The format string (passed to vfprintf).
 * @param   ...         Format arguments.
 */
static int ErrorMsg( const char *pszFormat, ... )
{
    va_list va;

    fprintf( stderr, "dipdump: error: " );
    va_start( va, pszFormat );
    vfprintf( stderr, pszFormat, va);
    va_end( va );
    return( 1 );
}

/**
 * Prints an informational message.
 *
 * @param   pszFormat   The format string (passed to vfprintf).
 * @param   ...         Format arguments.
 */
static void InfoMsg( const char *pszFormat, ... )
{
    va_list va;

    fprintf( stderr, "dipdump: info: " );
    va_start( va, pszFormat );
    vfprintf( stderr, pszFormat, va);
    va_end( va );
}

/**
 * Get type kind name.
 * @returns type kind name (readonly).
 * @param   kind        The type kind.
 */
static const char *GetTypeKind(type_kind kind)
{
    switch( kind ) {
    case TK_NONE:       return( "TK_NONE" );
    case TK_DATA:       return( "TK_DATA" );
    case TK_CODE:       return( "TK_CODE" );
    case TK_ADDRESS:    return( "TK_ADDRESS" );
    case TK_VOID:       return( "TK_VOID" );
    case TK_BOOL:       return( "TK_BOOL" );
    case TK_ENUM:       return( "TK_ENUM" );
    case TK_CHAR:       return( "TK_CHAR" );
    case TK_INTEGER:    return( "TK_INTEGER" );
    case TK_REAL:       return( "TK_REAL" );
    case TK_COMPLEX:    return( "TK_COMPLEX" );
    case TK_STRING:     return( "TK_STRING" );
    case TK_POINTER:    return( "TK_POINTER" );
    case TK_STRUCT:     return( "TK_STRUCT" );
    case TK_ARRAY:      return( "TK_ARRAY" );
    case TK_FUNCTION:   return( "TK_FUNCTION" );
    case TK_NAMESPACE:  return( "TK_NAMESPACE" );
    default:            return( "!unknown!" );
    }
}

/**
 * Get type modifier name.
 * @returns type modifier name (readonly).
 * @param   modifier    The type modifier.
 * @param   kind        The type kind (needed to understand the modifier).
 */
static const char *GetTypeModifier(type_modifier modifier, type_kind kind)
{
    if( modifier == TM_NONE) {
        return( "TM_NONE" );
    }
    if( modifier == TM_NONE|TM_FLAG_DEREF) {
        return( "TM_NONE|TM_FLAG_DEREF" );
    }

    switch( kind ) {
    case TK_NONE:
    case TK_DATA:
    case TK_CODE:
    case TK_VOID:
    case TK_BOOL:
    case TK_ENUM:
    case TK_CHAR:
    case TK_STRUCT:
    case TK_ARRAY:
    case TK_FUNCTION:
    case TK_NAMESPACE:
    default:
        return( "!unknown modifier+kind!" );

    case TK_ADDRESS: //??
    case TK_POINTER:
        switch( modifier ) {
        case TM_NEAR:                       return( "TM_NEAR" );
        case TM_NEAR|TM_FLAG_DEREF:         return( "TM_NEAR|TM_FLAG_DEREF" );
        case TM_FAR:                        return( "TM_FAR" );
        case TM_FAR|TM_FLAG_DEREF:          return( "TM_FAR|TM_FLAG_DEREF" );
        case TM_HUGE:                       return( "TM_HUGE" );
        case TM_HUGE|TM_FLAG_DEREF:         return( "TM_HUGE|TM_FLAG_DEREF" );
        default:
            return( "!unknown pointer modifier!" );
        }

    case TK_INTEGER:
        switch( modifier ) {
        case TM_SIGNED:                     return( "TM_SIGNED" );
        case TM_SIGNED|TM_FLAG_DEREF:       return( "TM_SIGNED|TM_FLAG_DEREF" );
        case TM_UNSIGNED:                   return( "TM_UNSIGNED" );
        case TM_UNSIGNED|TM_FLAG_DEREF:     return( "TM_UNSIGNED|TM_FLAG_DEREF" );
        default:
            return( "!unknown integer modifier!" );
        }

    case TK_REAL:
    case TK_COMPLEX: //??
        switch( modifier ) {
        case TM_IEEE:                       return( "TM_IEEE" );
        case TM_IEEE|TM_FLAG_DEREF:         return( "TM_IEEE|TM_FLAG_DEREF" );
        case TM_VAX1:                       return( "TM_VAX1" );
        case TM_VAX1|TM_FLAG_DEREF:         return( "TM_VAX1|TM_FLAG_DEREF" );
        case TM_VAX2:                       return( "TM_VAX2" );
        case TM_VAX2|TM_FLAG_DEREF:         return( "TM_VAX2|TM_FLAG_DEREF" );
        default:
            return( "!unknown floating point modifier!" );
        }

    case TK_STRING:
        switch( modifier ) {
        case TM_ASCII:                      return( "TM_ASCII" );
        case TM_ASCII|TM_FLAG_DEREF:        return( "TM_ASCII|TM_FLAG_DEREF" );
        case TM_EBCIDIC:                    return( "TM_EBCIDIC" );
        case TM_EBCIDIC|TM_FLAG_DEREF:      return( "TM_EBCIDIC|TM_FLAG_DEREF" );
        case TM_UNICODE:                    return( "TM_UNICODE" );
        case TM_UNICODE|TM_FLAG_DEREF:      return( "TM_UNICODE|TM_FLAG_DEREF" );
        default:
            return( "!unknown string modifier!" );
        }
    }
}

/**
 * Get the tag name.
 * @returns tag name. (readonly)
 * @param   tag     The tag.
 */
static const char *GetTypeTag( symbol_type tag )
{
    switch( tag ) {
    case ST_NONE:       return( "ST_NONE" );
    case ST_OPERATOR:   return( "ST_OPERATOR" );
    case ST_DESTRUCTOR: return( "ST_DESTRUCTOR" );
    case ST_TYPE:       return( "ST_TYPE" );
    case ST_STRUCT_TAG: return( "ST_STRUCT_TAG" );
    case ST_CLASS_TAG:  return( "ST_CLASS_TAG" );
    case ST_UNION_TAG:  return( "ST_UNION_TAG" );
    case ST_ENUM_TAG:   return( "ST_ENUM_TAG" );
    case ST_NAMESPACE:  return( "ST_NAMESPACE" );
    default:
        return( "!unknown tag!" );
    }
}

/**
 * WalkSymList callback, the module pass.
 *
 * @returns WR_CONTINUE;
 * @param   info    Symbol walk info.
 * @param   sym     The Symbol.
 * @param   _idx    Pointer to the symbol index number.
 */
static walk_result Sym2Callback( sym_walk_info info, sym_handle *sym, void *_idx )
{
    int             *idx = (int *)_idx;
    char            buf[2048];
    int             len;
    dip_status      rc;
    location_list   ll = {0};
    sym_info        sinfo;
    int             i;

    /* index */
    printf( "%5d  ", ++*idx );

    /* symbol info */
    rc = SymInfo( sym, NULL, &sinfo );
    if( rc == DS_OK ) {
        switch( sinfo.kind ) {
        case SK_NONE:       printf( "NONE  " ); break;
        case SK_CODE:       printf( "CODE  " ); break;
        case SK_DATA:       printf( "DATA  " ); break;
        case SK_CONST:      printf( "CNST  " ); break;
        case SK_TYPE:       printf( "TYPE  " ); break;
        case SK_PROCEDURE:  printf( "PROC  " ); break;
        case SK_NAMESPACE:  printf( "NMSP  " ); break;
        default:            printf( "kind=%#x!  ", sinfo.kind ); break;
        }
    } else {
        printf( "rc=%#x  ", rc );
        memset( &sinfo, 0, sizeof( sinfo ) );
        sinfo.kind= SK_NONE;
    }

    /* location (i.e. address) */
    ll.num = MAX_LOC_ENTRIES;
    rc = SymLocation( sym, NULL, &ll );
    if( rc == DS_OK ) {
        if( ll.num > 0 ) {
            if( ll.e[0].type == LT_ADDR ) {
                printf( "%04x:%08lx  ", ll.e[0].u.addr.mach.segment, (long)ll.e[0].u.addr.mach.offset );
            } else {
                printf( "%p       ", ll.e[0].u.p ); /// what's this?
            }
        } else {
            printf( "               ");
        }
    } else if( sinfo.kind == SK_CONST ) {
        ll.num = 0;
        memset( buf, 0, sizeof( buf ) );
        rc = SymValue( sym, NULL, &buf[0] );
        if( rc == DS_OK ) {
            switch(sinfo.ret_modifier) {
            }
            printf( "               " );
        } else {
            printf( "SymValue rc=%#x ", rc );
        }
    } else if( sinfo.kind == SK_NONE || sinfo.kind == SK_TYPE
            || sinfo.kind == SK_NAMESPACE  ) {
        printf( "               " );
        ll.num = 0;
    } else {
        printf( "rc=%#x  ", rc );
        ll.num = 0;
    }

    /* info */
    switch( info ) {
        case SWI_SYMBOL:
            printf( "SYMBOL    " );
            break;
        case SWI_INHERIT_START:
            printf( "INH-STRT  " );
            break;
        case SWI_INHERIT_END:
            printf( "INH-END   " );
            break;
        default:
            printf( "%#d  ", info );
            break;
    }

    /* finally, the name. */
    /* try get the name */
    buf[0] = '\0';
    len = SymName( sym, NULL, SN_DEMANGLED, buf, sizeof( buf ) );
    if( !len ) {
        len = SymName( sym, NULL, SN_OBJECT, buf, sizeof( buf ) );
    }
    if( !len ) {
        len = SymName( sym, NULL, SN_SOURCE, buf, sizeof( buf ) );
    }
    if( len > 0 ) {
        printf( "%s\n", buf );
    } else {
        printf( "(len=%d)\n", len );
    }


    /* Get more stuff, mainly to test the APIs. */
    if( 1 ) {
        type_handle *type = alloca( DIPHandleSize( HK_TYPE ) );

        rc = SymType( sym, type );
        if( rc ) {
        }

#if 0
mod_handle      SymMod( sym_handle * );
unsigned        SymName( sym_handle *, location_context *, symbol_name, char *name, unsigned max );
dip_status      SymType( sym_handle *, type_handle * );
dip_status      SymValue( sym_handle *, location_context *, void * );
dip_status      SymInfo( sym_handle *, location_context *, sym_info * );
dip_status      SymParmLocation( sym_handle *, location_context *, location_list *, unsigned p );
dip_status      SymObjType( sym_handle *, type_handle *, type_info * );
dip_status      SymObjLocation( sym_handle *, location_context *, location_list * );
search_result   AddrSym( mod_handle, address, sym_handle * );
search_result   LookupSym( symbol_source, void *, lookup_item *, void * );
search_result   LookupSymEx( symbol_source, void *, lookup_item *, location_context *, void * );
search_result   AddrScope( mod_handle, address, scope_block * );
search_result   ScopeOuter( mod_handle, scope_block *, scope_block * );
int             SymCmp( sym_handle *, sym_handle * );
dip_status      SymAddRef( sym_handle * );
dip_status      SymRelease( sym_handle * );
dip_status      SymFreeAll();
#endif

    }


    /* more locations. */
    for( i = 1; i < ll.num; i++ ) {
        if( ll.e[0].type == LT_ADDR ) {

⌨️ 快捷键说明

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