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