wpasmfil.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 309 行

C
309
字号
/****************************************************************************
*
*                            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:  Profiler disassembly view routines.
*
****************************************************************************/


#include <stdio.h>
#include <string.h>
#include "walloca.h"

#include "common.h"
#include "aui.h"
#include "wpaui.h"
#include "dip.h"
#include "mad.h"
#include "sampinfo.h"
#include "wpasmfil.h"
#include "wpsrcfil.h"
#include "srcmgt.h"
#include "msg.h"


extern massgd_sample_addr *WPGetMassgdSampData(sio_data *curr_sio,clicks_t click_index);
extern void *ProfRealloc(void *p,size_t new_size);
extern void *ProfCAlloc(size_t size);
extern void ProfFree(void *ptr);
extern void ErrorMsg(char *msg,... );
extern int AddrCmp(address *addr1,address *addr2);
extern file_handle ExeOpen(char *name);
extern void ExeClose(file_handle fh);
extern void SetExeOffset( address );
extern void SetExeImage(image_info *image);
extern bint SetExeFile(file_handle fh,bint overlay);
extern void SetNumBytes(uint_16 num);
extern void CodeAdvance( address * );
extern void GetFullInstruct( address, char *buffer,int max);
extern char EndOfSegment(void );
extern void *FOpenSource( char *name, sm_mod_handle mod, sm_cue_file_id id );
extern void FDoneSource( void *hndl );
extern int FReadLine( void *hndl, int line, int off, char *buff, int size );

#define MAX_ASM_BUFF_LEN    256

extern wp_asmline * WPGetAsmLoc( wp_asmfile * wpasm_file, int row,
                                    int * group_loc, int * row_loc )
/******************************************************************/
{
    wp_asmline *    asm_line;
    int             asm_row;
    int             asm_group;

    asm_group = row / MAX_ASM_LINE_INDEX;
    asm_row = row - (asm_group * MAX_ASM_LINE_INDEX);
    if( asm_group != 0 && asm_row == 0 && asm_group > wpasm_file->asm_groups ) {
        wpasm_file->asm_data = ProfRealloc( wpasm_file->asm_data,
                                     sizeof(wp_asm_groups)*(asm_group+1) );
        wpasm_file->asm_data[asm_group].asm_lines
                 = ProfAlloc( MAX_ASM_LINE_SIZE );
        wpasm_file->asm_groups++;
    }
    *group_loc = asm_group;
    *row_loc = asm_row;
    asm_line = &wpasm_file->asm_data[asm_group].asm_lines[asm_row];
    return( asm_line );
}



extern wp_asmfile * WPAsmOpen( sio_data * curr_sio, int src_row, bint quiet )
/***************************************************************************/
{
    wp_asmfile *        wpasm_file;
    cue_handle *        ch;
    cue_handle *        ch2;
    mod_info *          curr_mod;
    file_info *         curr_file;
    massgd_sample_addr * samp_data;
    wp_asmline *        asm_line;
    mod_handle          mh;
    file_handle         fh;
    address             addr;
    cue_file_id         fid;
    search_result       cue_find;
    int                 rows;
    int                 asm_group;
    int                 asm_row;
    int                 file_index;
    int                 addr_cmp;
    clicks_t            addr_tick_index;

    quiet=quiet;
    ch = __alloca( DIPHandleSize( HK_CUE ) );
    ch2 = __alloca( DIPHandleSize( HK_CUE ) );
    curr_file = curr_sio->curr_file;
    curr_mod = curr_sio->curr_mod;
    if( curr_file->fid == 0 || LineCue( curr_mod->mh, curr_sio->curr_file->fid,
                                        src_row, 0, ch2 ) == SR_NONE ) {
        ch2 = NULL;
    }
    fh = ExeOpen( curr_sio->curr_image->name );
    if( fh == -1 ) {
        ErrorMsg( LIT( Exe_Not_Found ), curr_sio->curr_image->name );
        return( NULL );
    }
    wpasm_file = ProfCAlloc( sizeof(wp_asmfile) );
    curr_sio->asm_file = wpasm_file;
    wpasm_file->asm_buff = ProfAlloc( MAX_ASM_BUFF_LEN );
    wpasm_file->asm_buff_len = MAX_ASM_BUFF_LEN;
    SetNumBytes( 0 );
    SetExeFile( fh, B_FALSE );
    wpasm_file->fh = fh;
    addr = ModAddr( curr_mod->mh );
    SetExeOffset( addr );
    wpasm_file->max_time = 0;
    addr_tick_index = curr_mod->first_tick_index - 1;
    samp_data = WPGetMassgdSampData( curr_sio, addr_tick_index++ );
    wpasm_file->asm_data = ProfAlloc( sizeof(wp_asm_groups) );
    wpasm_file->asm_data[0].asm_lines = ProfAlloc( MAX_ASM_LINE_SIZE );
    wpasm_file->asm_groups = 0;
    rows = 0;
    for( ;; ) {
        mh = curr_mod->mh;
        if( EndOfSegment()
            || AddrMod( addr, &mh ) == SR_NONE || mh != curr_mod->mh ) break;
        cue_find = (AddrCue( curr_mod->mh, addr, ch ) == SR_EXACT);
        if( ch2 != NULL && CueCmp( ch, ch2 ) == 0 ) {
            wpasm_file->entry_line = rows;
            ch2 = NULL;
        }
        asm_line = WPGetAsmLoc( wpasm_file, rows, &asm_group, &asm_row );
        if( cue_find ) {
            asm_line->source_line = B_TRUE;
            asm_line->u.src.line = CueLine( ch );
            asm_line->u.src.src_file = NULL;
            if( !curr_file->unknown_file ) {
                fid = CueFileId( ch );
                file_index = 0;
                while( file_index < curr_mod->file_count ) {
                    curr_file = curr_mod->mod_file[file_index];
                    if( curr_file->fid == fid ) {
                        asm_line->u.src.src_file =
                                FOpenSource( curr_file->name, mh, fid );
                        break;
                    }
                    file_index++;
                }
            }
            rows++;
            asm_line = WPGetAsmLoc( wpasm_file, rows, &asm_group, &asm_row );
        }
        asm_line = &wpasm_file->asm_data[asm_group].asm_lines[asm_row];
        asm_line->source_line = B_FALSE;
        asm_line->u.asm_line.addr = addr;
        asm_line->u.asm_line.tick_count = 0;
        for( ;; ) {
            if( samp_data == NULL ) break;
            addr_cmp = AddrCmp( &addr, samp_data->raw );
            if( addr_cmp < 0 ) break;
            if( addr_cmp == 0 ) {
                asm_line->u.asm_line.tick_count = samp_data->hits;
                if( asm_line->u.asm_line.tick_count > wpasm_file->max_time ) {
                    wpasm_file->max_time = asm_line->u.asm_line.tick_count;
                }
            }
            samp_data = WPGetMassgdSampData( curr_sio, addr_tick_index++ );
        }
        rows++;
        CodeAdvance( &addr );
    }
    WPGetAsmLoc( wpasm_file, rows, &asm_group, &asm_row );
    wpasm_file->asm_data[asm_group].asm_lines =
            ProfRealloc( wpasm_file->asm_data[asm_group].asm_lines,
                         sizeof(wp_asmline)*(asm_row+1) );
    wpasm_file->asm_rows = rows;
    return( wpasm_file );
}



extern void WPAsmClose( wp_asmfile * wpasm_file )
/***********************************************/
{
    wp_asmline *        asm_line;
    int                 row;
    int                 asm_group;
    int                 asm_row;

    if( wpasm_file != NULL ) {
        if( wpasm_file->asm_data != NULL ) {
            row = 0;
            while( row < wpasm_file->asm_rows ) {
                asm_line = WPGetAsmLoc( wpasm_file, row, &asm_group, &asm_row );
                if( asm_line->source_line ) {
                    FDoneSource( asm_line->u.src.src_file );
                }
                row++;
            }
            row = wpasm_file->asm_rows;
            asm_group = 0;
            for( ;; ) {
                ProfFree( wpasm_file->asm_data[asm_group++].asm_lines );
                row -= MAX_ASM_LINE_INDEX;
                if( row < 0 ) break;
            }
            ProfFree( wpasm_file->asm_data );
        }
        if( wpasm_file->asm_buff != NULL ) {
            ProfFree( wpasm_file->asm_buff );
        }
        if( wpasm_file->fh != NULL ) {
            ExeClose( wpasm_file->fh );
        }
        ProfFree( wpasm_file );
    }
}



extern char * WPAsmGetLine( a_window * wnd, int line )
/****************************************************/
{
    sio_data *      curr_sio;
    wp_asmfile *    wpasm_file;
    src_info *      src;
    wp_asmline *    asm_line;
    int             asm_group;
    int             asm_row;
    int             buff_len;

    curr_sio = WndExtra( wnd );
    wpasm_file = curr_sio->asm_file;
    if( line >= wpasm_file->asm_rows ) {
        return( NULL );
    }
    asm_line = WPGetAsmLoc( wpasm_file, line, &asm_group, &asm_row );
    if( asm_line->source_line ) {
        src = &asm_line->u.src;
        if( src->src_file == NULL ) {
            strcpy( wpasm_file->asm_buff, LIT( Unable_To_Open_Src ) );
        } else {
            for( ;; ) {
                buff_len = FReadLine( src->src_file, src->line, 0,
                                      wpasm_file->asm_buff,
                                      wpasm_file->asm_buff_len );
                if( buff_len != wpasm_file->asm_buff_len ) break;
                wpasm_file->asm_buff_len += 120;
                wpasm_file->asm_buff = ProfRealloc( wpasm_file->asm_buff,
                                                    wpasm_file->asm_buff_len );
            }
            if( buff_len < 0 ) {
                buff_len = 0;
            }
            wpasm_file->asm_buff[buff_len] = NULLCHAR;
        }
    } else {
        SetNumBytes( 0 );
        SetExeFile( wpasm_file->fh, B_FALSE );
        SetExeImage( curr_sio->curr_image );
        GetFullInstruct( asm_line->u.asm_line.addr, wpasm_file->asm_buff, wpasm_file->asm_buff_len-1 );
    }
    return( wpasm_file->asm_buff );
}



extern int WPAsmFindSrcLine( sio_data * curr_sio, int line )
/**********************************************************/
{
    wp_asmfile *    wpasm_file;
    wp_asmline *    asm_line;
    int             asm_group;
    int             asm_row;

    wpasm_file = curr_sio->asm_file;
    while( line >= 0 ) {
        asm_line = WPGetAsmLoc( wpasm_file, line, &asm_group, &asm_row );
        if( asm_line->source_line ) {
            return( asm_line->u.src.line );
        }
        line--;
    }
    return( 0 );
}

⌨️ 快捷键说明

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