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