dbgwass.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,095 行 · 第 1/3 页
C
1,095 行
/****************************************************************************
*
* 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: Processing of pop-up menu for assembly view.
*
****************************************************************************/
#include <string.h>
#include "dbgdefn.h"
#include "dbgreg.h"
#include "dbgio.h"
#include "dbgwind.h"
#include "dbgadget.h"
#include "dbginfo.h"
#include "dbgtoken.h"
#include "dbgerr.h"
#include "dbgmem.h"
#include "dbgtoggl.h"
#include "dbgitem.h"
#include "dbgbreak.h"
#include "mad.h"
extern cue_file_id CueFileId( cue_handle * );
extern unsigned CueFile( cue_handle *ch, char *file, unsigned max );
extern unsigned long CueLine( cue_handle *ch );
extern bool WndEvalInspectExpr( char *item, bool pop );
extern void WndInspectExprSP( char *item );
extern int AddrComp(address ,address );
extern void InitCache(address,unsigned);
extern void FiniCache(void);
extern bool DlgBreak(address);
extern void GoToAddr( address addr );
extern void WndFuncInspect( mod_handle mod );
extern a_window *WndAsmInspect( address addr );
extern bool DlgCodeAddr( char *title, address *value );
extern void ToggleBreak(address);
extern void SetCodeDot(address);
extern address GetCodeDot(void);
extern bool HasLineInfo(address);
extern brk *FindBreak(address);
extern unsigned NewCurrRadix(unsigned int );
extern bool SrcMoveDot( a_window *, address );
extern void SrcJoinAsm( a_window *, a_window * );
extern void SrcFreeAsm( a_window * );
extern void SrcNewAsmNotify( a_window *, mod_handle, bool track );
extern a_window *SrcWndFind( a_window*src, address addr,bool track );
extern void SkipToAddr( address );
extern char *StrAddr(address *,char *,unsigned);
extern void FileBreakGadget( a_window *,wnd_line_piece *line, bool curr, brk *bp );
extern a_window *DoWndAsmOpen( address addr, bool track );
extern unsigned ProgPeek(address ,void *,unsigned int );
extern bool DlgModName( char *title, mod_handle *mod );
extern void WndVarInspect( char * );
extern char *StrCopy(char*src,char*dst);
extern void SetUnderLine( a_window*, wnd_line_piece *);
extern void PushAddr( address );
extern void BreakOnExprSP( char *comment );
extern char *AddrToString( address *, mad_address_format, char *, unsigned );
extern void ReportMADFailure( mad_status );
extern void *OpenSrcFile(cue_handle * );
extern int FReadLine(void *,int ,int ,char *,int );
extern void FDoneSource(void *);
extern char *Format(char *,char *,... );
extern void StepIntoFunction( char * );
extern void BreakOnSelected( char *item );
extern void GoHome(void);
extern address ModFirstAddr( mod_handle mod );
extern gui_menu_struct *WndAppendToggles( mad_toggle_strings const *toggles, unsigned *pnum_toggles,
gui_menu_struct *old, unsigned num_old, int id );
extern void WndDeleteToggles( gui_menu_struct *popup, unsigned num_old, unsigned num_toggles );
extern char *StrAddr( address *addr, char *p, unsigned max );
extern char *ModImageName( mod_handle handle );
extern mad_type_handle GetMADTypeHandleDefaultAt( address a, mad_type_kind mtk );
extern bool InsMemRef( mad_disasm_data *dd );
extern void DbgUpdate( update_list );
extern machine_state *DbgRegs;
extern char *TxtBuff;
extern address NilAddr;
extern debug_level ActiveWindowLevel;
extern unsigned char CurrRadix;
#include "menudef.h"
static gui_menu_struct AsmShowMenu[] = {
#define pick( a,b,c,d,e,f,g ) MENU_ITEM( a, b )
#include "masmshow.h"
};
static gui_menu_struct AsmMenu[] = {
#include "menuasm.h"
};
enum {
PIECE_BREAK,
PIECE_ADDRESS,
PIECE_CURRENT = PIECE_ADDRESS,
PIECE_BRANCH_INDICATOR,
PIECE_OPCODE,
PIECE_OPERANDS,
PIECE_MEMREF
};
#define AVG_INS_SIZE 7
#define TITLE_SIZE 1
typedef struct {
address addr;
unsigned line;
} asm_addr;
typedef struct {
asm_addr *ins;
int ins_size;
address active;
address dotaddr;
address cache_addr;
mad_disasm_data *cache_dd;
unsigned ddsize;
gui_ord ins_end;
gui_ord address_end;
gui_ord last_width;
a_window *src;
mod_handle mod;
struct {
mod_handle mod;
cue_file_id file_id;
} src_list;
void *viewhndl;
unsigned num_toggles;
gui_menu_struct *popup;
mad_type_handle def_addr;
unsigned addr_len;
unsigned track : 1;
unsigned toggled_break : 1;
unsigned source : 1;
unsigned hex : 1;
} asm_window;
#define WndAsm( wnd ) ( (asm_window *)WndExtra( wnd ) )
static bool ExactCueAt( asm_window *asm, address addr, cue_handle *ch )
{
if( !asm->source ) return( FALSE );
if( DeAliasAddrCue( NO_MOD, addr, ch ) == SR_NONE ) return( FALSE );
if( AddrComp( CueAddr( ch ), addr ) ) return( FALSE );
return( TRUE );
}
static void AsmResize( a_window *wnd );
static void AsmSetFirst( a_window *wnd, address addr, bool use_first_source )
{
int row,rows;
asm_window *asm = WndAsm( wnd );
char chr;
mad_disasm_data *dd;
unsigned addr_len;
DIPHDL( cue, ch );
_AllocA( dd, asm->ddsize );
if( IS_NIL_ADDR( addr ) || ProgPeek( addr, &chr, 1 ) != 1 ) {
addr = NilAddr;
}
asm->ins[ 0 ].addr = addr;
asm->ins[ 0 ].line = 0;
addr_len = AddrToString( &addr, MAF_OFFSET, TxtBuff, TXT_LEN ) - TxtBuff;
if( addr_len != asm->addr_len ) {
asm->addr_len = addr_len;
AsmResize( wnd ); // recusively calls this routine!
WndZapped( wnd );
return;
}
rows = WndRows( wnd );
for( row = 0; row < rows; ++row ) {
asm->ins[ row ].addr = addr;
if( IS_NIL_ADDR( addr ) ) continue;
if( ExactCueAt( asm, addr, ch ) ) {
if( row != 0 || use_first_source ) {
asm->ins[ row ].addr = addr;
asm->ins[ row ].line = CueLine( ch );
++row;
if( row >= rows ) break;
}
}
asm->ins[ row ].addr = addr;
asm->ins[ row ].line = 0;
if( MADDisasm( dd, &addr, 0 ) != MS_OK ) {
addr = NilAddr;
}
}
}
static void CalcAddrLen( a_window *wnd, address addr )
{
asm_window *asm = WndAsm( wnd );
unsigned old;
old = NewCurrRadix( asm->hex ? 16 : 10 );
AddrToString( &addr, MAF_OFFSET, TxtBuff, TXT_LEN );
asm->address_end = MaxGadgetLength;
asm->address_end += ( strlen( TxtBuff ) + 1 ) * WndMidCharX( wnd );
NewCurrRadix( old );
}
static void AsmResize( a_window *wnd )
{
asm_window *asm = WndAsm( wnd );
asm_addr *new_ins;
address first;
int size;
size = WndRows( wnd );
if( size <= 0 ) size = 1;
first = asm->ins[ 0 ].addr;
new_ins = WndAlloc( size*sizeof( *new_ins ) );
memset( new_ins, 0, size*sizeof( *new_ins ) );
if( new_ins == NULL ) {
WndClose( wnd );
WndNoMemory();
}
WndFree( asm->ins );
asm->ins = new_ins;
asm->ins_size = size;
AsmSetFirst( wnd, first, asm->ins[ 0 ].line != 0 );
CalcAddrLen( wnd, first );
if( asm->last_width != WndWidth( wnd ) ) {
WndZapped( wnd );
}
asm->last_width = WndWidth( wnd );
WndFixedThumb( wnd );
}
static int AsmAddrRow( a_window *wnd, address ip )
{
int row;
asm_window *asm = WndAsm( wnd );
for( row = 0; row < WndRows( wnd ); ++row ) {
if( asm->ins[ row ].line != 0 ) continue;
if( AddrComp( asm->ins[ row ].addr, ip ) == 0 ) break;
}
return( row );
}
extern void AsmJoinSrc( a_window *wnd, a_window *src )
{
WndAsm( wnd )->src = src;
}
extern void AsmNewSrcNotify( a_window *src, mod_handle mod, bool track )
{
asm_window *asm;
a_window *wnd;
for( wnd = WndNext( NULL ); wnd != NULL; wnd = WndNext( wnd ) ) {
if( WndClass( wnd ) != WND_ASSEMBLY ) continue;
asm = WndAsm( wnd );
if( track != asm->track ) continue;
if( mod != asm->mod ) continue;
if( asm->src != NULL ) continue;
SrcJoinAsm( src, wnd );
AsmJoinSrc( wnd, src );
break;
}
}
static void AsmSetTitle( a_window *wnd )
{
char *p;
char *image_name;
asm_window *asm = WndAsm( wnd );
p = StrCopy( ": ", StrCopy( LIT( WindowAssembly ), TxtBuff ) );
p += ModName( asm->mod, p, TXT_LEN );
image_name = ModImageName( asm->mod );
if( image_name[0] != '\0' ) {
p = StrCopy( "(", StrCopy( " ", p ) );
p = StrCopy( ")", StrCopy( SkipPathInfo( image_name, OP_REMOTE ), p ) );
}
WndSetTitle( wnd, TxtBuff );
}
static void AsmSetDotAddr( a_window *wnd, address addr )
{
mod_handle mod;
asm_window *asm = WndAsm( wnd );
if( AddrComp( asm->dotaddr, addr ) != 0 ) {
WndRowDirty( wnd, -TITLE_SIZE );
asm->dotaddr = addr;
DeAliasAddrMod( addr, &mod );
if( mod != asm->mod ) {
DbgUpdate( UP_OPEN_CHANGE );
asm->mod = mod;
AsmSetTitle( wnd );
}
if( IS_NIL_ADDR( addr ) ) return;
if( wnd == WndFindActive() ) {
SrcMoveDot( asm->src, addr );
SetCodeDot( addr );
}
}
}
extern void AsmMoveDot( a_window *wnd, address addr )
{
int row;
asm_window *asm;
DIPHDL( cue, ch1 );
DIPHDL( cue, ch2 );
if( wnd == NULL ) return;
asm = WndAsm( wnd );
if( DeAliasAddrCue( asm->mod, addr, ch1 ) != SR_NONE &&
DeAliasAddrCue( asm->mod, asm->dotaddr, ch2 ) != SR_NONE ) {
if( CueMod( ch1 ) == CueMod( ch2 ) &&
CueFileId( ch1 ) == CueFileId( ch2 ) &&
CueLine( ch1 ) == CueLine( ch2 ) ) {
return;
}
}
WndNoSelect( wnd );
row = AsmAddrRow( wnd, addr );
if( row == WndRows( wnd ) ) {
AsmSetFirst( wnd, addr, TRUE );
row = AsmAddrRow( wnd, addr );
WndDirtyCurr( wnd );
WndNewCurrent( wnd, row, PIECE_CURRENT );
WndRepaint( wnd );
row = 0;
} else {
WndDirtyCurr( wnd );
WndNewCurrent( wnd, row, PIECE_CURRENT );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?