dbgwmem.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 1,074 行 · 第 1/3 页
C
1,074 行
/****************************************************************************
*
* 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: WHEN YOU FIGURE OUT WHAT THIS FILE DOES, PLEASE
* DESCRIBE IT HERE!
*
****************************************************************************/
#include <string.h>
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include "dbgdefn.h"
#include "dbgwind.h"
#include "dbgtoggl.h"
#include "dbgitem.h"
#include "dbgio.h"
#include "dbgreg.h"
#include "dbgerr.h"
#include "dbginfo.h"
#include "madcli.h"
#include "mad.h"
#include "ldsupp.h"
#include "memtypes.h"
extern char *StrCopy(char*,char*);
extern address AddrAddWrap(address,long);
extern unsigned ProgPeek(address ,void *,unsigned int );
extern char *CnvULongDec(unsigned long,char *);
extern char *CnvULong(unsigned long,char *);
extern char *StrAddr(address *,char * ,unsigned);
extern void SetDataDot( address );
extern bool DlgLongExpr( char *, long * );
extern unsigned NewCurrRadix(unsigned int );
extern bool DlgDataAddr( char *title, address *value );
extern bool DlgDataAddrFormat( char *, void *, void (*fmt)(void*,char*));
extern long AddrDiff( address a, address b );
extern unsigned ChangeMemUndoable( address addr, void *data, unsigned len );
extern bool DlgMadTypeExpr( char *title, item_mach *value, mad_type_handle th );
extern bool DlgString( char *title, char *buff );
extern char *DupStr( char *str );
extern int AddrComp(address,address);
extern void Warn( char *p );
extern bool BreakWrite( address addr, mad_type_handle, char *comment );
extern a_window *WndAsmInspect(address addr);
extern bool DlgScanGivenAddr( char *str, address *value );
extern void MemFiniTypes( mem_type_walk_data *data );
extern void MemInitTypes( mad_type_kind mas, mem_type_walk_data *data );
extern mad_type_handle GetMADTypeHandleDefaultAt( address a, mad_type_kind mtk );
extern char *Format( char *buff, char *fmt, ... );
extern char *AddrToString( address *a, mad_address_format af, char *p, unsigned );
extern unsigned ProgPeekWrap(address addr,char * buff,unsigned length );
extern machine_state *DbgRegs;
extern char *TxtBuff;
extern address NilAddr;
typedef gui_ord (MEMHEADER)(a_window *,int);
#define TITLE_SIZE 1
static mem_type_walk_data MemData;
static gui_menu_struct *MemTypeMenu = NULL;
static gui_menu_struct DummyMenu[1];
#include "menudef.h"
static gui_menu_struct MemMenu[] = {
#include "menumem.h"
};
#define PIECE_TYPE( x ) ( (x)-MENU_MEMORY_FIRST_TYPE )
static unsigned MemByteType;
static MEMHEADER MemHeader;
static MEMHEADER BinHeader;
static MEMHEADER *HeadTab[] =
{
MemHeader,
BinHeader
};
typedef struct mem_backout {
struct mem_backout *next;
address home;
address addr;
unsigned curr_offset;
unsigned total_size;
char *follow;
unsigned has_current : 1;
} mem_backout;
typedef struct mem_window {
union {
struct {
address addr; // this is the current top of window address
address home; // this is the first address looked at
void *contents;
int size;
char *follow;
mem_backout *backout;
} m;
struct {
handle filehndl;
long offset;
long size;
} f;
} u;
unsigned curr_offset;
unsigned items_per_line;
unsigned item_size;
unsigned item_width;
unsigned total_size;
int piece_type;
int last_type_popup;
gui_ord address_end;
long bp_offset;
long sp_offset;
wnd_row cursor_row;
int cursor_piece;
int shadow_piece;
mad_type_handle init_type; //MAD: what if active MAD changes?
unsigned file : 1;
unsigned stack : 1;
} mem_window;
#define WndMem( wnd ) ( (mem_window *)WndExtra( wnd ) )
static void MemValidAddr( address addr )
{
char ch;
if( _IsOff( SW_RUNNING_PROFILE ) ) {
if( ProgPeekWrap( addr, &ch, 1 ) != 1 ) {
Error( ERR_NONE, LIT( ERR_NO_READ_MEM ), addr );
}
}
}
static char *MemGetTitle( mem_window *mem )
{
char *p;
p = StrCopy( LIT( WindowMemory ), TxtBuff );
p = StrCopy( " (", p );
p = AddrToString( &mem->u.m.home, MAF_FULL, p, TXT_LEN - ( p - TxtBuff ) );
p = StrCopy( ")", p );
return( TxtBuff );
}
static unsigned MemCurrOffset( a_window *wnd )
{
wnd_row row;
int piece;
mem_window *mem = WndMem( wnd );
WndGetCurrent( wnd, &row, &piece );
if( row < 0 ) return( 0 );
--piece;
if( piece >= mem->items_per_line ) piece -= mem->items_per_line;
return( ( row * mem->items_per_line + piece ) * mem->item_size );
}
static gui_ord MemHeader( a_window *wnd, int piece )
{
address addr;
mem_window *mem = WndMem( wnd );
gui_ord len;
char buff[TXT_LEN];
if( mem->stack && piece > 0 ) return( -1 );
if( mem->file ) {
if( piece > 0 ) return( -1 );
CnvULong( MemCurrOffset( wnd ), TxtBuff );
return( 0 );
}
if( piece > 1 ) return( -1 );
addr = AddrAddWrap( mem->u.m.addr, MemCurrOffset( wnd ) );
AddrToString( &addr, MAF_FULL, buff, sizeof( buff ) );
switch( piece ) {
case 0:
StrCopy( buff, TxtBuff );
return( 0 );
case 1:
StrAddr( &addr, TxtBuff, TXT_LEN );
if( strcmp( buff, TxtBuff ) == 0 ) break;
len = WndExtentX( wnd, buff ) + 2*WndMidCharX( wnd );
return( len );
}
return( -1 );
}
static gui_ord BinHeader( a_window *wnd, int piece )
{
mem_window *mem = WndMem( wnd );
if( piece != 0 ) return( -1 );
CnvULongDec( mem->u.f.offset + MemCurrOffset( wnd ), TxtBuff );
return( 0 );
}
static void MemGetContents( a_window *wnd, bool make_dirty )
{
int size;
mem_window *mem = WndMem( wnd );
void *old;
int old_size;
old = mem->u.m.contents;
old_size = mem->u.m.size;
size = mem->items_per_line * mem->item_size * WndRows( wnd );
mem->u.m.contents = WndAlloc( size );
if( mem->u.m.contents == NULL ) {
mem->u.m.size = 0;
} else {
mem->u.m.size = ProgPeekWrap( mem->u.m.addr, mem->u.m.contents, size );
}
AddrToString( &mem->u.m.addr, MAF_OFFSET, TxtBuff, TXT_LEN );
mem->address_end = ( strlen( TxtBuff ) + 1 ) * WndMidCharX( wnd );
if( mem->stack ) {
mem->sp_offset = AddrDiff( Context.stack, mem->u.m.addr );
mem->bp_offset = AddrDiff( Context.frame, mem->u.m.addr );
}
if( make_dirty ) {
WndNoSelect( wnd );
if( mem->u.m.size != old_size ||
old == NULL ||
mem->u.m.contents == NULL ) {
WndRepaint( wnd );
} else {
for( size = 0; size < old_size; ++size ) {
if( ((char*)old)[size] != ((char*)mem->u.m.contents)[size] ) {
WndRowDirty( wnd, size / ( mem->items_per_line * mem->item_size ) );
}
}
}
}
WndFree( old );
}
static void MemSetStartAddr( a_window *wnd, address addr, bool new_home )
{
mem_window *mem = WndMem( wnd );
if( new_home ) mem->u.m.home = addr;
mem->u.m.addr = addr;
MemGetContents( wnd, FALSE );
}
static WNDREFRESH MemRefresh;
static void MemRefresh( a_window *wnd )
{
mem_window *mem = WndMem( wnd );
if( !mem->file ) {
MemGetContents( wnd, TRUE );
} else {
CnvULong( ULONG_MAX, TxtBuff );
mem->address_end = ( strlen( TxtBuff ) + 1 ) * WndMidCharX( wnd );
}
if( !WndHasCurrent( wnd ) ) WndFirstCurrent( wnd );
}
static void MemGetNewAddr( a_window *wnd )
{
address addr;
long offset;
mem_window *mem = WndMem( wnd );
unsigned old;
if( mem->file ) {
offset = mem->u.f.offset;
old = NewCurrRadix( 10 );
if( !DlgLongExpr( LIT( New_Offset ), &offset ) ) return;
NewCurrRadix( old );
if( offset > mem->u.f.size ) return;
mem->u.f.offset = offset;
} else {
addr = mem->u.m.home;
if( !DlgDataAddr( LIT( New_Addr ), &addr ) ) return;
MemValidAddr( addr );
MemSetStartAddr( wnd, addr, TRUE );
WndNoCurrent( wnd );
MemRefresh( wnd );
SetDataDot( addr );
}
WndSetTitle( wnd, MemGetTitle( mem ) );
WndZapped( wnd );
}
extern void MemSetLength( a_window *wnd, unsigned size )
{
WndMem( wnd )->total_size = size;
}
extern void MemSetFollow( a_window *wnd, char *follow )
{
mem_window *mem = WndMem( wnd );
WndFree( mem->u.m.follow );
mem->u.m.follow = follow;
}
static void MemSetType( a_window *wnd, unsigned idx )
{
mem_window *mem = WndMem( wnd );
mem->piece_type = idx;
if( mem->stack ) {
mem->items_per_line = 1;
} else {
mem->items_per_line = MemData.info[ mem->piece_type ].items_per_line;
}
mem->item_size = MemData.info[ mem->piece_type ].item_size;
mem->item_width = MemData.info[ mem->piece_type ].item_width;
}
static bool CanModify( a_window *wnd, int row, int piece )
{
piece = piece;
if( row < 0 ) return( FALSE );
if( WndMem( wnd )->file ) return( FALSE );
return( TRUE );
}
static void SetNewDataDot( a_window *wnd )
{
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?