support.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,334 行 · 第 1/3 页
C
1,334 行
{
image_info *curr_image;
ovl_entry *overlay;
int count;
if( addr == 0 ) {
return;
}
addr->sect_id = 0;
count = 0;
for(;;) {
if( count >= CurrSIOData->image_count ) {
return;
}
curr_image = CurrSIOData->curr_image;
if( curr_image->ovl_count != 0 ) break;
count++;
}
overlay = curr_image->ovl_data;
count = 0;
while( count < curr_image->ovl_count ) {
if( addr->mach.segment == overlay[count].base_para ) {
addr->sect_id = count + 1;
break;
}
count++;
}
}
STATIC void ResolveOverlays( image_info *image )
/**********************************************/
{
int ovl_count;
int count;
int index;
int count2;
int index2;
int count3;
clicks_t curr_tick;
clicks_t map_tick;
ovl_entry *overlay;
remap_data *remap;
addr_seg *remap_segment;
thread_data *thd;
address *samp_data;
addr_seg base_segment;
addr_seg actual_segment;
base_segment = image->map_data[0].actual.mach.segment;
overlay = image->ovl_data;
ovl_count = image->ovl_count;
remap_segment = ProfCAlloc( ovl_count * sizeof(addr_seg) );
remap = CurrSIOData->remaps->next;
map_tick = remap->tick;
/* If we've got overlays, there's only one thread */
thd = CurrSIOData->samples;
curr_tick = thd->start_time;
count = RAW_BUCKET_IDX( thd->end_time - thd->start_time ) + 1;
for( index = 0; index < count; ++index ) {
samp_data = thd->raw_bucket[index];
count2 = MAX_RAW_BUCKET_INDEX;
if( (thd->end_time - curr_tick) < count2 ) {
count2 = thd->end_time - curr_tick;
}
for( index2 = 0; index2 < count2; ++index2 ) {
while( curr_tick == map_tick ) {
remap_segment[remap->section-1] = remap->segment;
if( remap == CurrSIOData->remaps ) {
map_tick = CurrSIOData->total_samples;
} else {
remap = remap->next;
map_tick = remap->tick;
}
}
actual_segment = samp_data[index2].mach.segment;
if( actual_segment != base_segment ) {
count3 = 0;
while( count3 < ovl_count ) {
if( actual_segment == remap_segment[count3] ) {
samp_data[index2].mach.segment
= overlay[count3].base_para;
samp_data[index2].sect_id = count3 + 1;
break;
}
count3++;
}
}
curr_tick++;
count3++;
}
}
ProfFree( remap_segment );
}
STATIC bint LoadOverlayInfo( void )
/*********************************/
{
image_info *image;
file_handle fh;
address map_addr;
addr_seg base_segment;
off_t fileoffset;
off_t filenameoffset;
ovltab_entry formal_entry;
ovltab_prolog prolog;
ovl_entry *entry;
ovl_entry *entry_ptr;
char *ovl_name;
char buffer[_MAX_PATH];
char buffer1[_MAX_PATH2];
char buffer2[_MAX_PATH2];
char buffer3[_MAX_PATH2];
char *drive;
char *dir;
char *name;
char *ext;
int count;
int len;
image = CurrSIOData->curr_image;
fh = ExeOpen( image->name );
if( fh == -1 ) {
ErrorMsg( LIT( Cannot_Process_Ovly ), image->name );
return( B_FALSE );
}
SetExeFile( fh, B_FALSE );
map_addr = image->overlay_table;
MapAddressToMap( &map_addr.mach );
fileoffset = TransformExeOffset( map_addr.mach.segment,
map_addr.mach.offset, ROOT_SECTION );
if( lseek( fh, fileoffset, SEEK_SET ) != fileoffset ) {
ErrorMsg( LIT( Cannot_Process_Ovly ), image->name );
return( B_FALSE );
}
if( read( fh, &prolog, sizeof(prolog) ) != sizeof(prolog) ) {
ErrorMsg( LIT( Cannot_Process_Ovly ), image->name );
return( B_FALSE );
}
if( prolog.major != OVL_MAJOR_VERSION
|| prolog.minor > OVL_MINOR_VERSION ) {
ErrorMsg( LIT( Incompat_Ver_Ovly ), image->name );
return( B_FALSE );
}
base_segment = image->map_data[0].actual.mach.segment;
count = 0;
entry_ptr = NULL;
for(;;) {
if( read( fh, &formal_entry, sizeof(formal_entry) )
!= sizeof(formal_entry) ) {
ErrorMsg( LIT( Cannot_Process_Ovly ), image->name );
return( B_FALSE );
}
if( formal_entry.flags_anc == OVLTAB_TERMINATOR ) break;
++count;
if( entry_ptr == NULL ) {
entry_ptr = ProfAlloc( count * sizeof(ovl_entry) );
} else {
entry_ptr = ProfRealloc( entry_ptr, count * sizeof(ovl_entry) );
}
entry = entry_ptr + count - 1;
/* make sure we are properly initialized in case of error */
image->ovl_count = count;
image->ovl_data = entry_ptr;
entry->fname = NULL;
entry->start_para = formal_entry.start_para;
/* add 1 to the segment to account for both */
/* segments being base zero values */
entry->base_para = entry->start_para + base_segment + 1;
entry->disk_addr = formal_entry.disk_addr;
if( formal_entry.fname & OVE_EXE_FILENAME ) {
ovl_name = image->name;
entry->separate_overlay = B_FALSE;
} else {
fileoffset = lseek( fh, 0, SEEK_CUR ); /* save current posn */
map_addr = image->overlay_table;
map_addr.mach.offset += formal_entry.fname;
MapAddressToMap( &map_addr.mach );
filenameoffset = TransformExeOffset( map_addr.mach.segment,
map_addr.mach.offset,
ROOT_SECTION );
if( lseek( fh, filenameoffset, SEEK_SET ) != filenameoffset ) {
ErrorMsg( LIT( Cannot_Process_Ovly ), image->name );
return( B_FALSE );
}
if( read( fh, buffer, _MAX_PATH ) != _MAX_PATH ) {
ErrorMsg( LIT( Cannot_Process_Ovly ), image->name );
return( B_FALSE );
}
/* find overlay file */
if( access( buffer, 0 ) != 0 ) {
strcpy( buffer3, buffer );
_searchenv( buffer3, "PATH", buffer );
if( buffer[0] == '\0' ) {
_splitpath2( image->name, buffer1, &drive, &dir, NULL, NULL );
_splitpath2( buffer3, buffer2, NULL, NULL, &name, &ext );
_makepath( buffer, drive, dir, name, ext );
}
}
ovl_name = buffer;
entry->separate_overlay = B_TRUE;
/* restore current posn */
if( lseek( fh, fileoffset, SEEK_SET ) != fileoffset ) {
ErrorMsg( LIT( Cannot_Process_Ovly ), image->name );
return( B_FALSE );
}
}
len = strlen( ovl_name ) + 1;
entry->fname = ProfAlloc( len );
memcpy( entry->fname, ovl_name, len );
}
ExeClose( fh );
return( B_TRUE );
}
extern bint LoadImageOverlays( void )
/***********************************/
{
image_info *curr_image;
int image_index;
/* assume 32-bit addresses until proven otherwise */
exeFlags.is_32_bit = TRUE;
image_index = 0;
while( image_index < CurrSIOData->image_count ) {
curr_image = CurrSIOData->curr_image;
if( curr_image->overlay_table.mach.segment != 0 ) {
CurrSIOData->curr_image = curr_image;
if( !LoadOverlayInfo() ) {
return( B_FALSE );
}
if( CurrSIOData->remaps != NULL ) {
ResolveOverlays( curr_image );
}
}
image_index++;
}
return( B_TRUE );
}
STATIC void AdvanceCurrentOffset( uint_32 advance )
/*************************************************/
{
addr_off old_offset;
exeFlags.end_of_segment = B_FALSE;
old_offset = currAddr.mach.offset;
MADAddrAdd( &currAddr, advance, MAF_OFFSET );
if( currAddr.mach.offset < old_offset ) {
exeFlags.end_of_segment = B_TRUE;
return;
}
if( exeFlags.segment_split ) {
if( currAddr.mach.offset > cacheHi ) {
MapSetExeOffset( currAddr );
}
}
}
STATIC void exeRewind( size_t offset )
/************************************/
{
if( offset > exeCurrent ) {
exeSeek( ( exePosition + exeCurrent ) - offset );
} else {
exeCurrent -= offset;
}
}
void SetNumBytes( uint_16 num )
/*****************************/
{
numBytes = num;
}
void CodeAdvance( address *addr )
/*******************************/
{
MADDisasm( MDData, addr, 0 );
SetExeOffset( *addr );
}
STATIC unsigned char exeGetChar( void )
/*************************************/
{
if( isHole ) {
return( 0 );
}
if( exeCurrent >= exeAmount ) {
exePosition += exeAmount;
lseek( exeFH, exePosition, SEEK_SET );
if( nbytes < BUFF_SIZE ) {
exeAmount = read( exeFH, exeBuff, nbytes );
} else {
exeAmount = read( exeFH, exeBuff, BUFF_SIZE );
}
if( exeAmount == 0 || exeAmount == (uint_16)-1 ) {
exeFlags.end_of_file = B_TRUE;
return( 0 );
}
exeCurrent = 0;
}
return( exeBuff[ exeCurrent++ ] );
}
unsigned FormatAddr( address a, char *buffer, unsigned max )
{
mad_type_info host;
mad_type_info mti;
unsigned_8 item[16];
MADTypeInfoForHost( MTK_ADDRESS, sizeof( address ), &host );
MADTypeInfo( MADTypeDefault( MTK_ADDRESS, MAF_FULL, NULL, &a ), &mti );
MADTypeConvert( &host, &a, &mti, item, 0 );
MADTypeToString( 16, &mti, item, &max, buffer );
return( max );
}
void GetFullInstruct( address a, char * buffer, int max )
/*******************************************************/
{
unsigned i;
char * tail;
address start;
unsigned ins_size;
mad_type_info host;
unsigned_8 item;
unsigned mad_max = max;
start = a;
MADDisasm( MDData, &a, 0 );
tail = &buffer[ FormatAddr( start, buffer, max ) ];
*tail++ = ' '; /* two spaces */
*tail++ = ' ';
if( 1 <= numBytes ) {
SetExeOffset( start );
ins_size = MADDisasmInsSize( MDData );
for( i = 0; i < ins_size || i < numBytes; i++ ) {
if( i < ins_size ) {
item = exeGetChar();
MADTypeInfoForHost( MTK_INTEGER, sizeof( item ), &host );
mad_max = 4;
MADTypeToString( 16, &host, &item, &mad_max, tail );
tail += mad_max;
} else if( i < numBytes ) {
*tail++ = ' '; /* two spaces */
*tail++ = ' ';
}
*tail++ = ' ';
}
*tail++ = ' '; /* two spaces */
*tail++ = ' ';
exeRewind( ins_size );
}
MADDisasmFormat( MDData, MDP_ALL, 16, max - (tail-buffer), tail );
}
/*
* Convert address to a symbol string. Return FALSE if this could not be done.
*/
bool CnvAddr( address addr, char *buff, unsigned max )
{
sym_handle * sym;
search_result sr;
int name_len;
sym = __alloca( DIPHandleSize( HK_SYM ) );
// MapAddressToActual( exeImage, &addr.mach );
sr = AddrSym( NO_MOD, addr, sym );
switch( sr ) {
case SR_EXACT:
//case SR_CLOSEST: /* add in if we have symbol+offset */
break;
default:
return( FALSE );
}
name_len = SymName( sym, NULL, SN_DEMANGLED, buff, max );
if( name_len == 0 ) {
SymName( sym, NULL, SN_SOURCE, buff, max );
}
return( TRUE );
}
bool IsX86BigAddr( address a )
{
return( exeFlags.is_32_bit );
}
bool IsX86RealAddr( address a )
{
switch( exeType ) {
case EXE_MZ:
case EXE_OVL:
return( B_TRUE );
}
return( B_FALSE );
}
int_16 GetDataByte( void )
/************************/
{
int_16 value;
value = exeGetChar();
AdvanceCurrentOffset( sizeof( int_8 ) );
return( (int_8)value );
}
char EndOfSegment( void )
/***********************/
{
if( exeFlags.end_of_segment ) {
return( B_TRUE );
}
if( exeFlags.end_of_file ) {
return( B_TRUE );
}
return( B_FALSE );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?