Hacked unicode printing feature (x /u).
Made the type casts a bit more robust.
This commit is contained in:
parent
ca96de344b
commit
7bec5c16ab
|
@ -86,7 +86,7 @@ int yyerror(char *);
|
||||||
%nonassoc ':'
|
%nonassoc ':'
|
||||||
|
|
||||||
%type <expression> expr lval lvalue
|
%type <expression> expr lval lvalue
|
||||||
%type <type> type_cast type_expr
|
%type <type> type_expr
|
||||||
%type <value> expr_addr lval_addr
|
%type <value> expr_addr lval_addr
|
||||||
%type <integer> expr_value
|
%type <integer> expr_value
|
||||||
%type <string> pathname identifier
|
%type <string> pathname identifier
|
||||||
|
@ -266,11 +266,8 @@ noprocess_state:
|
||||||
| tNOPROCESS tSTRING tEOL { DEBUG_Printf(DBG_CHN_MESG, "No process loaded, cannot execute '%s'\n", $2); }
|
| tNOPROCESS tSTRING tEOL { DEBUG_Printf(DBG_CHN_MESG, "No process loaded, cannot execute '%s'\n", $2); }
|
||||||
;
|
;
|
||||||
|
|
||||||
type_cast: '(' type_expr ')' { $$ = $2; }
|
|
||||||
;
|
|
||||||
|
|
||||||
type_expr:
|
type_expr:
|
||||||
type_expr '*' { $$ = DEBUG_FindOrMakePointerType($1); }
|
type_expr '*' { $$ = $1 ? DEBUG_FindOrMakePointerType($1) : NULL; }
|
||||||
| tINT { $$ = DEBUG_GetBasicType(DT_BASIC_INT); }
|
| tINT { $$ = DEBUG_GetBasicType(DT_BASIC_INT); }
|
||||||
| tCHAR { $$ = DEBUG_GetBasicType(DT_BASIC_CHAR); }
|
| tCHAR { $$ = DEBUG_GetBasicType(DT_BASIC_CHAR); }
|
||||||
| tLONG tINT { $$ = DEBUG_GetBasicType(DT_BASIC_LONGINT); }
|
| tLONG tINT { $$ = DEBUG_GetBasicType(DT_BASIC_LONGINT); }
|
||||||
|
@ -344,7 +341,7 @@ expr:
|
||||||
| '(' expr ')' { $$ = $2; }
|
| '(' expr ')' { $$ = $2; }
|
||||||
| '*' expr %prec OP_DEREF { $$ = DEBUG_UnopExpr(EXP_OP_DEREF, $2); }
|
| '*' expr %prec OP_DEREF { $$ = DEBUG_UnopExpr(EXP_OP_DEREF, $2); }
|
||||||
| '&' expr %prec OP_DEREF { $$ = DEBUG_UnopExpr(EXP_OP_ADDR, $2); }
|
| '&' expr %prec OP_DEREF { $$ = DEBUG_UnopExpr(EXP_OP_ADDR, $2); }
|
||||||
| type_cast expr %prec OP_DEREF { $$ = DEBUG_TypeCastExpr($1, $2); }
|
| '(' type_expr ')' expr %prec OP_DEREF { $$ = DEBUG_TypeCastExpr($2, $4); }
|
||||||
;
|
;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -419,6 +419,8 @@ extern enum dbg_mode DEBUG_GetSelectorType( WORD sel );
|
||||||
extern void DEBUG_FixAddress( DBG_ADDR *address, DWORD def );
|
extern void DEBUG_FixAddress( DBG_ADDR *address, DWORD def );
|
||||||
extern int DEBUG_IsSelectorSystem( WORD sel );
|
extern int DEBUG_IsSelectorSystem( WORD sel );
|
||||||
#endif
|
#endif
|
||||||
|
extern int DEBUG_PrintStringA( int chnl, const DBG_ADDR* address, int len );
|
||||||
|
extern int DEBUG_PrintStringW( int chnl, const DBG_ADDR* address, int len );
|
||||||
|
|
||||||
/* debugger/module.c */
|
/* debugger/module.c */
|
||||||
extern int DEBUG_LoadEntryPoints( const char * prefix );
|
extern int DEBUG_LoadEntryPoints( const char * prefix );
|
||||||
|
@ -513,7 +515,8 @@ extern struct datatype * DEBUG_GetBasicType(enum debug_type_basic);
|
||||||
#define DBG_CHN_WARN 4
|
#define DBG_CHN_WARN 4
|
||||||
#define DBG_CHN_FIXME 8
|
#define DBG_CHN_FIXME 8
|
||||||
#define DBG_CHN_TRACE 16
|
#define DBG_CHN_TRACE 16
|
||||||
extern void DEBUG_Output(int chn, const char* buffer, int len);
|
extern void DEBUG_OutputA(int chn, const char* buffer, int len);
|
||||||
|
extern void DEBUG_OutputW(int chn, const WCHAR* buffer, int len);
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
extern int DEBUG_Printf(int chn, const char* format, ...) __attribute__((format (printf,2,3)));
|
extern int DEBUG_Printf(int chn, const char* format, ...) __attribute__((format (printf,2,3)));
|
||||||
#else
|
#else
|
||||||
|
|
|
@ -323,6 +323,11 @@ DBG_VALUE DEBUG_EvalExpr(struct expr * exp)
|
||||||
case EXPR_TYPE_CAST:
|
case EXPR_TYPE_CAST:
|
||||||
rtn = DEBUG_EvalExpr(exp->un.cast.expr);
|
rtn = DEBUG_EvalExpr(exp->un.cast.expr);
|
||||||
rtn.type = exp->un.cast.cast;
|
rtn.type = exp->un.cast.cast;
|
||||||
|
if (!rtn.type)
|
||||||
|
{
|
||||||
|
DEBUG_Printf(DBG_CHN_MESG, "Can't cast to unknown type\n");
|
||||||
|
RaiseException(DEBUG_STATUS_BAD_TYPE, 0, 0, NULL);
|
||||||
|
}
|
||||||
if (DEBUG_GetType(rtn.type) == DT_POINTER)
|
if (DEBUG_GetType(rtn.type) == DT_POINTER)
|
||||||
rtn.cookie = DV_TARGET;
|
rtn.cookie = DV_TARGET;
|
||||||
break;
|
break;
|
||||||
|
|
132
debugger/info.c
132
debugger/info.c
|
@ -36,97 +36,107 @@
|
||||||
*/
|
*/
|
||||||
void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format )
|
void DEBUG_PrintBasic( const DBG_VALUE* value, int count, char format )
|
||||||
{
|
{
|
||||||
char * default_format;
|
char * default_format;
|
||||||
long long int res;
|
long long int res;
|
||||||
|
|
||||||
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
assert(value->cookie == DV_TARGET || value->cookie == DV_HOST);
|
||||||
if( value->type == NULL )
|
if (value->type == NULL)
|
||||||
{
|
{
|
||||||
DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression\n");
|
DEBUG_Printf(DBG_CHN_MESG, "Unable to evaluate expression\n");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
default_format = NULL;
|
default_format = NULL;
|
||||||
res = DEBUG_GetExprValue(value, &default_format);
|
res = DEBUG_GetExprValue(value, &default_format);
|
||||||
|
|
||||||
switch(format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case 'x':
|
case 'x':
|
||||||
if (value->addr.seg)
|
if (value->addr.seg)
|
||||||
{
|
{
|
||||||
DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "0x%04lx", (long unsigned int) res );
|
DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "0x%04lx", (long unsigned int)res);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "0x%08lx", (long unsigned int) res );
|
DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "0x%08lx", (long unsigned int)res);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd':
|
case 'd':
|
||||||
DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%ld\n", (long int) res );
|
DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%ld\n", (long int)res);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%d = '%c'",
|
DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%d = '%c'",
|
||||||
(char)(res & 0xff), (char)(res & 0xff) );
|
(char)(res & 0xff), (char)(res & 0xff));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 'u':
|
||||||
|
{
|
||||||
|
WCHAR wch = (WCHAR)(res & 0xFFFF);
|
||||||
|
DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%d = '", (unsigned)(res & 0xffff));
|
||||||
|
DEBUG_OutputW(DBG_CHN_MESG, &wch, 1);
|
||||||
|
DEBUG_Printf(DBG_CHN_MESG, "'");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
case 's':
|
case 's':
|
||||||
case 'w':
|
case 'w':
|
||||||
case 'b':
|
case 'b':
|
||||||
DEBUG_Printf( DBG_CHN_MESG, "Format specifier '%c' is meaningless in 'print' command\n", format );
|
DEBUG_Printf(DBG_CHN_MESG, "Format specifier '%c' is meaningless in 'print' command\n", format);
|
||||||
case 0:
|
case 0:
|
||||||
if( default_format != NULL )
|
if (default_format != NULL)
|
||||||
{
|
{
|
||||||
if (strstr(default_format, "%S") != NULL)
|
if (strstr(default_format, "%S") != NULL)
|
||||||
{
|
{
|
||||||
char* ptr;
|
char* ptr;
|
||||||
int state = 0;
|
int state = 0;
|
||||||
|
|
||||||
/* FIXME: simplistic implementation for default_format being
|
/* FIXME: simplistic implementation for default_format being
|
||||||
* foo%Sbar => will print foo, then string then bar
|
* foo%Sbar => will print foo, then string then bar
|
||||||
*/
|
*/
|
||||||
for (ptr = default_format; *ptr; ptr++)
|
for (ptr = default_format; *ptr; ptr++)
|
||||||
{
|
{
|
||||||
if (*ptr == '%') state++;
|
if (*ptr == '%')
|
||||||
else if (state == 1)
|
{
|
||||||
|
state++;
|
||||||
|
}
|
||||||
|
else if (state == 1)
|
||||||
{
|
{
|
||||||
if (*ptr == 'S')
|
if (*ptr == 'S')
|
||||||
{
|
{
|
||||||
char ch;
|
DBG_ADDR addr;
|
||||||
char* str = (char*)(long)res;
|
|
||||||
|
addr.seg = 0;
|
||||||
for (; DEBUG_READ_MEM(str, &ch, 1) && ch; str++) {
|
addr.off = (long)res;
|
||||||
DEBUG_Output(DBG_CHN_MESG, &ch, 1);
|
DEBUG_nchar += DEBUG_PrintStringA(DBG_CHN_MESG, &addr, -1);
|
||||||
DEBUG_nchar++;
|
}
|
||||||
}
|
else
|
||||||
}
|
{
|
||||||
else
|
|
||||||
{
|
|
||||||
/* shouldn't happen */
|
/* shouldn't happen */
|
||||||
DEBUG_Printf(DBG_CHN_MESG, "%%%c", *ptr);
|
DEBUG_Printf(DBG_CHN_MESG, "%%%c", *ptr);
|
||||||
DEBUG_nchar += 2;
|
DEBUG_nchar += 2;
|
||||||
}
|
}
|
||||||
state = 0;
|
state = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_Output(DBG_CHN_MESG, ptr, 1);
|
DEBUG_OutputA(DBG_CHN_MESG, ptr, 1);
|
||||||
DEBUG_nchar++;
|
DEBUG_nchar++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (strcmp(default_format, "%B") == 0)
|
else if (strcmp(default_format, "%B") == 0)
|
||||||
{
|
{
|
||||||
DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, "%s", res ? "true" : "false");
|
DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "%s", res ? "true" : "false");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DEBUG_nchar += DEBUG_Printf( DBG_CHN_MESG, default_format, res );
|
DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, default_format, res);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -276,33 +276,15 @@ void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format )
|
||||||
|
|
||||||
switch(format)
|
switch(format)
|
||||||
{
|
{
|
||||||
case 'u': {
|
case 'u':
|
||||||
WCHAR wch;
|
if (count == 1) count = 256;
|
||||||
if (count == 1) count = 256;
|
DEBUG_nchar += DEBUG_PrintStringW(DBG_CHN_MESG, &value.addr, count);
|
||||||
while (count--)
|
DEBUG_Printf(DBG_CHN_MESG, "\n");
|
||||||
{
|
|
||||||
if (!DEBUG_READ_MEM_VERBOSE(pnt, &wch, sizeof(wch)) || !wch)
|
|
||||||
break;
|
|
||||||
pnt += sizeof(wch);
|
|
||||||
DEBUG_Printf(DBG_CHN_MESG, "%c", (char)wch);
|
|
||||||
}
|
|
||||||
DEBUG_Printf(DBG_CHN_MESG,"\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
case 's':
|
||||||
case 's': {
|
DEBUG_nchar += DEBUG_PrintStringA(DBG_CHN_MESG, &value.addr, count);
|
||||||
char ch;
|
DEBUG_Printf(DBG_CHN_MESG, "\n");
|
||||||
|
|
||||||
if (count == 1) count = 256;
|
|
||||||
while (count--)
|
|
||||||
{
|
|
||||||
if (!DEBUG_READ_MEM_VERBOSE(pnt, &ch, sizeof(ch)) || !ch)
|
|
||||||
break;
|
|
||||||
pnt++;
|
|
||||||
DEBUG_Output(DBG_CHN_MESG, &ch, 1);
|
|
||||||
}
|
|
||||||
DEBUG_Printf(DBG_CHN_MESG,"\n");
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
case 'i':
|
case 'i':
|
||||||
while (count-- && DEBUG_DisassembleInstruction( &value.addr ));
|
while (count-- && DEBUG_DisassembleInstruction( &value.addr ));
|
||||||
return;
|
return;
|
||||||
|
@ -330,3 +312,50 @@ void DEBUG_ExamineMemory( const DBG_VALUE *_value, int count, char format )
|
||||||
case 'b': DO_DUMP2(char, 16, " %02x", (_v) & 0xff);
|
case 'b': DO_DUMP2(char, 16, " %02x", (_v) & 0xff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************************************************
|
||||||
|
* DEBUG_PrintStringA
|
||||||
|
*
|
||||||
|
* Prints on channel chnl, the string starting at address in target
|
||||||
|
* address space. The string stops when either len chars (if <> -1)
|
||||||
|
* have been printed, or the '\0' char is printed
|
||||||
|
*/
|
||||||
|
int DEBUG_PrintStringA(int chnl, const DBG_ADDR* address, int len)
|
||||||
|
{
|
||||||
|
char* lin = (void*)DEBUG_ToLinear(address);
|
||||||
|
char ach[16+1];
|
||||||
|
int i, l;
|
||||||
|
|
||||||
|
if (len == -1) len = 32767; /* should be big enough */
|
||||||
|
|
||||||
|
/* so that the ach is always terminated */
|
||||||
|
ach[sizeof(ach) - 1] = '\0';
|
||||||
|
for (i = len; i >= 0; i -= sizeof(ach) - 1)
|
||||||
|
{
|
||||||
|
l = min(sizeof(ach) - 1, i);
|
||||||
|
DEBUG_READ_MEM_VERBOSE(lin, ach, l);
|
||||||
|
l = strlen(ach);
|
||||||
|
DEBUG_OutputA(chnl, ach, l);
|
||||||
|
lin += l;
|
||||||
|
if (l < sizeof(ach) - 1) break;
|
||||||
|
}
|
||||||
|
return len - i; /* number of actually written chars */
|
||||||
|
}
|
||||||
|
|
||||||
|
int DEBUG_PrintStringW(int chnl, const DBG_ADDR* address, int len)
|
||||||
|
{
|
||||||
|
char* lin = (void*)DEBUG_ToLinear(address);
|
||||||
|
WCHAR wch;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (len == -1) len = 32767; /* should be big enough */
|
||||||
|
while (len--)
|
||||||
|
{
|
||||||
|
if (!DEBUG_READ_MEM_VERBOSE(lin, &wch, sizeof(wch)) || !wch)
|
||||||
|
break;
|
||||||
|
lin += sizeof(wch);
|
||||||
|
DEBUG_OutputW(chnl, &wch, 1);
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
|
@ -875,7 +875,6 @@ DEBUG_Print( const DBG_VALUE *value, int count, char format, int level )
|
||||||
size = DEBUG_GetObjectSize(value->type->un.array.basictype);
|
size = DEBUG_GetObjectSize(value->type->un.array.basictype);
|
||||||
if( size == 1 )
|
if( size == 1 )
|
||||||
{
|
{
|
||||||
char ach[16];
|
|
||||||
int len, clen;
|
int len, clen;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -883,21 +882,17 @@ DEBUG_Print( const DBG_VALUE *value, int count, char format, int level )
|
||||||
*/
|
*/
|
||||||
pnt = (char *) value->addr.off;
|
pnt = (char *) value->addr.off;
|
||||||
len = value->type->un.array.end - value->type->un.array.start + 1;
|
len = value->type->un.array.end - value->type->un.array.start + 1;
|
||||||
clen = (DEBUG_nchar + len < DEBUG_maxchar)
|
clen = (DEBUG_nchar + len < DEBUG_maxchar)
|
||||||
? len : (DEBUG_maxchar - DEBUG_nchar);
|
? len : (DEBUG_maxchar - DEBUG_nchar);
|
||||||
|
|
||||||
DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "\"");
|
DEBUG_nchar += DEBUG_Printf(DBG_CHN_MESG, "\"");
|
||||||
switch (value->cookie)
|
switch (value->cookie)
|
||||||
{
|
{
|
||||||
case DV_TARGET:
|
case DV_TARGET:
|
||||||
for (i = clen; i > 0; i -= sizeof(ach))
|
clen = DEBUG_PrintStringA(DBG_CHN_MESG, &value->addr, clen);
|
||||||
{
|
|
||||||
DEBUG_READ_MEM(pnt, ach, min(sizeof(ach), i));
|
|
||||||
DEBUG_Output(DBG_CHN_MESG, ach, min(sizeof(ach), i));
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case DV_HOST:
|
case DV_HOST:
|
||||||
DEBUG_Output(DBG_CHN_MESG, pnt, clen);
|
DEBUG_OutputA(DBG_CHN_MESG, pnt, clen);
|
||||||
break;
|
break;
|
||||||
default: assert(0);
|
default: assert(0);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,7 +48,7 @@ static DBG_PROCESS* DEBUG_ProcessList = NULL;
|
||||||
static int automatic_mode;
|
static int automatic_mode;
|
||||||
DBG_INTVAR DEBUG_IntVars[DBG_IV_LAST];
|
DBG_INTVAR DEBUG_IntVars[DBG_IV_LAST];
|
||||||
|
|
||||||
void DEBUG_Output(int chn, const char* buffer, int len)
|
void DEBUG_OutputA(int chn, const char* buffer, int len)
|
||||||
{
|
{
|
||||||
if (DBG_IVAR(ConChannelMask) & chn)
|
if (DBG_IVAR(ConChannelMask) & chn)
|
||||||
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL);
|
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL);
|
||||||
|
@ -56,6 +56,16 @@ void DEBUG_Output(int chn, const char* buffer, int len)
|
||||||
fwrite(buffer, len, 1, stderr);
|
fwrite(buffer, len, 1, stderr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DEBUG_OutputW(int chn, const WCHAR* buffer, int len)
|
||||||
|
{
|
||||||
|
/* FIXME: this won't work is std output isn't attached to a console */
|
||||||
|
if (DBG_IVAR(ConChannelMask) & chn)
|
||||||
|
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), buffer, len, NULL, NULL);
|
||||||
|
/* simplistic Unicode to ANSI conversion */
|
||||||
|
if (DBG_IVAR(StdChannelMask) & chn)
|
||||||
|
while (len--) fputc((char)*buffer++, stderr);
|
||||||
|
}
|
||||||
|
|
||||||
int DEBUG_Printf(int chn, const char* format, ...)
|
int DEBUG_Printf(int chn, const char* format, ...)
|
||||||
{
|
{
|
||||||
static char buf[4*1024];
|
static char buf[4*1024];
|
||||||
|
@ -71,7 +81,7 @@ static char buf[4*1024];
|
||||||
buf[len] = 0;
|
buf[len] = 0;
|
||||||
buf[len - 1] = buf[len - 2] = buf[len - 3] = '.';
|
buf[len - 1] = buf[len - 2] = buf[len - 3] = '.';
|
||||||
}
|
}
|
||||||
DEBUG_Output(chn, buf, len);
|
DEBUG_OutputA(chn, buf, len);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue