dumpwv.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 990 行 · 第 1/2 页
C
990 行
/****************************************************************************
*
* 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: Watcom debug format dump routines.
*
****************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <setjmp.h>
#include "walloca.h"
#include "wdglb.h"
#include "dumpwv.h"
#include "wdfunc.h"
static int currSect;
static char *sdh_msg[] = {
"4 Module info offset = ",
"4 Global info offset = ",
"4 Address info offset = ",
"4 Section size = ",
NULL
};
/*
* print_info_title - print out a title for an info section
*/
static void print_info_title( char *title )
/*****************************************/
{
char buff[80];
char sec;
strcpy( buff, title );
strcat( buff, " Info (section " );
strcat( buff, itoa( currSect, &sec, 10 ) );
strcat( buff, ")" );
Banner( buff );
} /* print_info_title */
/*
* get_len_prefix_string - make a length-prefixed string a 0 terminated string
*/
static void get_len_prefix_string( char *res, char *str )
/*******************************************************/
{
{
int i; // WTF?!
i = 1;
}
memcpy( res, &str[1], str[0] );
res[ str[0] ] = 0;
} /* get_len_prefix_string */
/*
* dump_line_numbers - dump line number info
*/
static void dump_line_numbers( mod_info *mi )
/*******************************************/
{
int i,j;
unsigned_32 *offs;
int cnt;
v3_line_segment *li;
unsigned_32 coff;
unsigned_16 size;
cnt = mi->di[DMND_LINES].u.entries;
if( cnt == 0 ) {
return;
}
Wdputslc( "\n" );
Wdputslc( " *** Line Numbers ***\n" );
Wdputslc( " ====================\n" );
offs = alloca( (cnt+1) * sizeof( unsigned_32 ) );
if( offs == NULL ) {
Wdputslc( "Error! Not enough stack.\n" );
longjmp( Se_env, 1 );
}
Wlseek( Curr_sectoff + mi->di[DMND_LINES].info_off );
Wread( offs, (cnt+1) * sizeof( unsigned_32 ) );
Wdputs( " " );
Putdec( cnt );
Wdputslc( " offset entries:\n" );
for( i = 0; i <= cnt; i++ ) {
Wdputs( " offset " );
Putdec( i );
Wdputs( " = " );
Puthex( offs[i], 8 );
Wdputslc( "H\n" );
}
for( i = 0; i < cnt; i++ ) {
Wlseek( Curr_sectoff + offs[i] );
Wread( Wbuff, sizeof( v3_line_segment ) );
li = (v3_line_segment *) Wbuff;
coff = 0;
while( 1 ) {
size = (li->num-1)* sizeof( line_info );
Wread( Wbuff + sizeof( v3_line_segment ), size );
Wdputslc( " -------------------------------------\n" );
Wdputs( " Data " );
Putdec( i );
Wdputs( ": offset " );
Puthex( offs[i], 8 );
Wdputs( "H, addr info off = " );
Puthex( li->segment, 8 );
Wdputs( "H, num = " );
Putdec( li->num );
Wdputslc( "\n" );
for( j = 0; j < li->num; j++ ) {
Wdputs( " number =" );
Putdecl( li->line[j].line_number, 5 );
Wdputs( ", code offset = " );
Puthex( li->line[j].code_offset, 8 );
Wdputslc( "H\n" );
}
coff += sizeof( v3_line_segment ) + size;
if( coff >= (offs[i+1] - offs[i]) ) {
break;
}
Wread( Wbuff, sizeof( v3_line_segment ) );
}
}
} /* dump_line_numbers */
/*
* Get_type_index - get a type index
*/
char *Get_type_index( char *ptr, unsigned_16 *index )
/***************************************************/
{
unsigned_16 idx;
if( *ptr & 0x80 ) {
idx = 0x7f & *ptr;
idx *= 256;
idx += *(ptr+1);
*index = idx;
return( ptr+2 );
} else {
*index = *ptr;
return( ptr+1 );
}
} /* Get_type_index */
/*
* Get_local_name - get a name from a local variable data structure
*/
void Get_local_name( char *name, char *data, char *start )
/********************************************************/
{
int len;
len = start[0] - (data - start);
memcpy( name, data, len );
name[len] = 0;
} /* Get_local_name */
/*
* dump_block - dump local block record
*/
static void dump_block( char *buff, bool is32 )
/*********************************************/
{
block_386 *blk386;
block *blk;
if( is32 ) {
blk386 = (block_386 *) buff;
Wdputs( " start off = " );
Puthex( blk386->start_offset, 8 );
Wdputs( ", code size = " );
Puthex( blk386->code_size, 8 );
Wdputs( ", parent off = " );
Puthex( blk386->parent_block_offset, 4 );
Wdputslc( "\n" );
} else {
blk = (block *) buff;
Wdputs( " start off = " );
Puthex( blk->start_offset, 4 );
Wdputs( ", code size = " );
Puthex( blk->code_size, 4 );
Wdputs( ", parent off = " );
Puthex( blk->parent_block_offset, 4 );
Wdputslc( "\n" );
}
} /* dump_block */
static char *regLocStrs[] =
{
"AL",
"AH",
"BL",
"BH",
"CL",
"CH",
"DL",
"DH",
"AX",
"BX",
"CX",
"DX",
"SI",
"DI",
"BP",
"SP",
"CS",
"SS",
"DS",
"ES",
"ST0",
"ST1",
"ST2",
"ST3",
"ST4",
"ST5",
"ST6",
"ST7",
"EAX",
"EBX",
"ECX",
"EDX",
"ESI",
"EDI",
"EBP",
"ESP",
"FS",
"GS"
};
/*
* dump_single_location_entry - dump a single location expression entry
*/
static char *dump_single_location_entry( char *buff )
/***************************************************/
{
char type;
addr32_ptr *p32;
addr48_ptr *p48;
int i;
int num;
type = *buff;
buff++;
switch( type ) {
case 0:
Wdputslc( "<none>\n" );
break;
case BP_OFFSET_BYTE:
Wdputs( "BP_OFFSET_BYTE( " );
Puthex( *buff, 2 );
Wdputslc( " )\n" );
buff++;
break;
case BP_OFFSET_WORD:
Wdputs( "BP_OFFSET_WORD( " );
Puthex( *buff, 4 );
Wdputslc( " )\n" );
buff += sizeof( unsigned_16 );
break;
case BP_OFFSET_DWORD:
Wdputs( "BP_OFFSET_DWORD( " );
Puthex( *buff, 8 );
Wdputslc( " )\n" );
buff += sizeof( unsigned_32 );
break;
case CONST_ADDR286:
p32 = (addr32_ptr *) buff;
buff += sizeof( addr32_ptr );
Wdputs( "CONST_ADDR286( " );
Puthex( p32->segment, 4 );
Wdputc( ':' );
Puthex( p32->offset, 4 );
Wdputslc( " )\n" );
break;
case CONST_ADDR386:
p48 = (addr48_ptr *) buff;
buff += sizeof( addr48_ptr );
Wdputs( "CONST_ADDR386( " );
Puthex( p48->segment, 4 );
Wdputc( ':' );
Puthex( p48->offset, 8 );
Wdputslc( " )\n" );
break;
case CONST_INT_1:
Wdputs( "CONST_INT_1( " );
Puthex( *buff, 2 );
Wdputslc( " )\n" );
buff++;
break;
case CONST_INT_2:
Wdputs( "CONST_INT_2( " );
Puthex( *buff, 4 );
Wdputslc( " )\n" );
buff += sizeof( unsigned_16 );
break;
case CONST_INT_4:
Wdputs( "CONST_INT_4( " );
Puthex( *buff, 8 );
Wdputslc( " )\n" );
buff += sizeof( unsigned_32 );
break;
case IND_REG_CALLOC_NEAR:
Wdputs( "IND_REG_CALLOC_NEAR( " );
Wdputs( regLocStrs[ *buff ] );
Wdputslc( " )\n" );
buff++;
break;
case IND_REG_CALLOC_FAR:
Wdputs( "IND_REG_CALLOC_FAR( " );
Wdputs( regLocStrs[ *buff ] );
Wdputc( ':' );
Wdputs( regLocStrs[ *(buff+1) ] );
Wdputslc( " )\n" );
buff += 2;
break;
case IND_REG_RALLOC_NEAR:
Wdputs( "IND_REG_RALLOC_NEAR( " );
Wdputs( regLocStrs[ *buff ] );
Wdputslc( " )\n" );
buff++;
break;
case IND_REG_RALLOC_FAR:
Wdputs( "IND_REG_RALLOC_FAR( " );
Wdputs( regLocStrs[ *buff ] );
Wdputc( ':' );
Wdputs( regLocStrs[ *(buff+1) ] );
Wdputslc( " )\n" );
buff += 2;
break;
case OPERATOR_IND_2:
Wdputslc( "OPERATOR_IND_2\n" );
break;
case OPERATOR_IND_4:
Wdputslc( "OPERATOR_IND_4\n" );
break;
case OPERATOR_IND_ADDR286:
Wdputslc( "OPERATOR_IND_ADDR286\n" );
break;
case OPERATOR_IND_ADDR386:
Wdputslc( "OPERATOR_IND_ADDR386\n" );
break;
case OPERATOR_ZEB:
Wdputslc( "OPERATOR_ZEB\n" );
break;
case OPERATOR_ZEW:
Wdputslc( "OPERATOR_ZEW\n" );
break;
case OPERATOR_MK_FP:
Wdputslc( "OPERATOR_MK_FP\n" );
break;
case OPERATOR_POP:
Wdputslc( "OPERATOR_POP\n" );
break;
case OPERATOR_XCHG:
Wdputs( "OPERATOR_XCHG: " );
Puthex( *buff, 2 );
Wdputslc( "\n" );
buff++;
break;
case OPERATOR_ADD:
Wdputslc( "OPERATOR_ADD\n" );
break;
case OPERATOR_DUP:
Wdputslc( "OPERATOR_DUP\n" );
break;
case OPERATOR_NOP:
Wdputslc( "OPERATOR_NOP\n" );
break;
default:
if( type & 0x30 ) {
num = (type & 0x0f)+1;
Wdputs( "MULTI_REG(" );
Putdec( num );
Wdputs( "): " );
for( i=0;i<num;i++ ) {
Wdputs( regLocStrs[ *buff ] );
if( i != num-1 ) {
Wdputs( ", " );
} else {
Wdputslc( "\n" );
}
buff++;
}
} else if( type & 0x40 ) {
Wdputs( "REG: " );
Wdputs( regLocStrs[ type & 0x0f ] );
Wdputslc( "\n" );
} else {
Wdputslc( "**** UNKNOWN LOCATION EXPRESSION!! ****\n" );
}
break;
}
return( buff );
} /* dump_single_location_entry */
/*
* Dump_location_expression - dump out a location expression
*/
char *Dump_location_expression( char *buff, char *spacing )
/*********************************************************/
{
int multi;
char *end;
if( *buff & 0x80 ) {
end = buff + (*buff & 0x7f);
buff++;
multi = 1;
} else {
end = buff + 1;
multi = 0;
}
while( buff < end ) {
switch( multi ) {
case 1:
multi = 2;
Wdputslc( "\n" );
/* fall through */
case 2:
Wdputslc( spacing );
break;
}
buff = dump_single_location_entry( buff );
}
return( buff );
} /* Dump_location_expression */
/*
* dump_rtn - dump a near or far routine defn
*/
static void dump_rtn( char *buff )
/********************************/
{
int pro,epi;
unsigned_16 ret_off;
char *ptr;
int num_parms;
unsigned_16 index;
char name[256];
int i;
dump_block( buff, FALSE );
ptr = buff + sizeof( block );
pro = *ptr++;
epi = *ptr++;
Wdputs( " prologue size = " );
Putdec( pro );
Wdputs( ", epilogue size = " );
Putdec( epi );
Wdputslc( "\n" );
ret_off = *(unsigned_16 *) ptr;
ptr += sizeof( unsigned_16 );
Wdputs( " return address offset (from bp) = " );
Puthex( ret_off, 4 );
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?