Release 970120
Sun Jan 19 11:46:48 1997 Alexandre Julliard <julliard@lrc.epfl.ch>
* [loader/module.c]
Fixed LoadModule() to always call the DLL initialization code.
* [windows/event.c]
Moved all the keyboard stuff to windows/keyboard.c
* [tools/build.c]
Fixed Win32 register functions.
Sat Jan 18 22:24:41 1997 David Makepeace <D.Makepeace@mailbox.uq.oz.au>
* [tools/makedep.c]
Fixed bug which causes SEGV on Solaris x86.
Fri Jan 17 18:32:27 1997 Frans van Dorsselaer <dorssel@rulhmpc49.LeidenUniv.nl>
* [controls/edit.c]
Implemented WM_UNDO, WM_CONTEXTMENU (temporary using WM_RBUTTONUP),
WM_COMMAND, WM_INITPOPUPMENU, WM_SYSKEYDOWN.
Fixed EM_SETSEL and some minor bugs (features).
Hence: fully functional undo and a win95 menu with the right mouse
button.
* [include/resources.h] [resources/TODO] [resources/sysres_??.rc]
Added a context menu for the edit control.
Translations, please ...
Fri Jan 17 08:29:52 1997 David Faure <david.faure@ifhamy.insa-lyon.fr>
* [windows/event.c]
Move EVENT_ToAscii to windows/keyboard.c (where name ToAscii)
Fixed Keypad keys 0-9 and . in EVENT_event_to_vkey.
Added 3-state handling of toggle keys (CapsLock, NumLock) in order
to make them work with any X server.
Toggle keys now generate WM_KEYDOWN and WM_KEYUP on each pressing.
* [include/keyboard.h]
Totally replaced the file (formerly containing the vkcase definitions)
by the declaration of 'extern' variables contained by event.c and used
by keyboard.c
* [windows/keyboard.c]
Started to rewrite VkKeyScan and MapVirtualKey, to make them use the
table keyc2vkey or X functions only.
ToAscii : added keypad 0-9 and . special case.
Changed toggle keys active mask from 0x80 to 0x1.
* [misc/keyboard.c]
File deleted. Contents moved to windows/keyboard.c.
* [misc/main.c]
Added putenv XKB_DISABLE to disable XKB extension (which, when
present, causes AltGr to change keyboard group instead of being a
modifier).
Tue Jan 14 22:56:43 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
* [windows/event.c]
Do not assume NumLockMask is Mod2Mask, but compute it by scanning
output of XGetModifierMapping for XK_Num_Lock.
Tue Jan 14 15:49:49 1997 Marcus Meissner <msmeissn@cip.informatik.uni-erlangen.de>
* [loader/pe_*.c] [include/peexe.h] [include/resource32.h]
[debugger/*.c]
General clean up.
Changed defines/structures to match Windows NT SDK.
* [loader/main.c]
Don't crash on empty command-line.
* [windows/winpos.c]
winpos.c made win32 clean.
* [misc/ntdll.c]
Some string conversion additions.
* [files/file.c]
GetFileAttributes/GetTempFileName fixed.
* [misc/ver.c]
VerInstallFile implemented.
Mon Jan 13 15:03:11 1997 Philippe De Muyter <phdm@info.ucl.ac.be>
* [tools/build.c]: Use PREFIX also in stabs messages.
Mon Jan 13 10:40:33 1997 John Harvey <john@division.co.uk>
* [graphics/win16drv/*] [include/win16drv.h]
Many fixes and some new features.
* [graphics/x11drv/font.c] [graphics/x11drv/init.c]
[include/x11drv.h] [objects/font.c]
GetTextMetrics() moved to graphics driver.
* [if1632/gdi.spec] [misc/fontengine.c] [misc/Makefile.in]
New dummy EngineEnumerateFont, EngineRealizeFont functions.
* [include/windows.h]
TEXTFORM16 and FONTINFO16 structure definitions moved here from
include/win16drv.h
diff --git a/debugger/README b/debugger/README
index 02cad9b..412b7e8 100644
--- a/debugger/README
+++ b/debugger/README
@@ -1,8 +1,7 @@
- This is the core of the Wine debugger. Many pieces have been
-shamelessly stolen - the reverse assember was stolen from Mach more or
-less intact. It turns out that there are two variables that are set
-differently if you are reverse assembling 16 bit code, and on the
-whole it seems to work.
+ This is the core of the Wine debugger. The reverse assember
+was stolen from Mach more or less intact. It turns out that there are
+two variables that are set differently if you are reverse assembling
+16 bit code, and on the whole it seems to work.
NEWS:
@@ -63,6 +62,16 @@
automatic display expressions. An example is at the end of this file. The
syntax and usage should be identical to that of gdb.
+ 8) Type casts can be made from within the debugger, but they currently
+don't work with typedef'ed types. They only work with builtin types and
+named structures unions, etc. The problem is that internally we don't always
+record the typedefed names of structures, so we have no guarantee that we
+would know what each type is. This can be fixed, of course - it just takes
+more memory. Note that in some cases, typedefed structures could be cast
+using '(struct typedfname)' instead of '(typedfname)'. Technically this
+isn't quite correct, but if and when the rest of this stuff gets fixed,
+this would need to get corrected too.
+
NOTES:
If it weren't for the fact that gdb doesn't grok the Win32 debug
@@ -73,16 +82,6 @@
LIMITATIONS AND DIFFERENCES FROM GDB:
- You cannot use type casts in expressions that you give to the
-debugger. The hardest part about adding support for this is fixing
-the parser/lexer to know when it is handling a type cast, and when it
-is handling any other type of parenthesized expression. With lexer
-states, it may be possible to keep track of what we would expect at
-any given moment, but it would be tedious to go through and make sure
-that the state is set up correctly for all of the different operators
-and characters that we accept, and I am not yet convinced that this would
-even work.
-
You cannot set a breakpoint by file and line number as you can
with gdb. Adding support for this wouldn't be all that tough, I guess, but
it would be a nuisance. You can set a breakpoint given a function and
@@ -348,11 +347,6 @@
You can use the set command to set more or less anything. Note
however that you cannot use enumerated types on the RHS of the expression.
- Finally, type casts are not yet supported in the expression
-handling. There is sufficient information stored internally to be
-able to handle this - the main challenge is that the parser would
-need to be fixed to correctly parse the type cast.
-
*******************************************************************
diff --git a/debugger/TODO b/debugger/TODO
index 3544b12..c527b922 100644
--- a/debugger/TODO
+++ b/debugger/TODO
@@ -3,10 +3,9 @@
possible to me right now. In no particular order. If someone else
wants to dig in, feel free.
-1) Some kind of watchpoint capability. Pretty easy once we have a
- single step capability, but we end up running the program
- really slowly one instruction at a time. Use hardware debug
- registers for this???
+1) Some kind of watchpoint capability. Pretty easy, but we end up
+ running the program really slowly one instruction at a time.
+ Use hardware debug registers for this (much harder)???
2) Some kind of .wdbinit file.
@@ -31,14 +30,6 @@
8) Some of the newer displays are still a little bit sparse on information.
Make these more like gdb.
-9) Don't bother to disassemble an instruction when we stop at a breakpoint
- and if we have a valid source line we are displaying.
-
-10) Add support for '/i', etc in display command. Make sure 'display/i $eip'
- does the correct thing, and then skip automatic disassembly completely.
-
-11) Limit amount of information displayed with print command.
-
-12) Make sure operator precedence works OK.
+9) Make sure operator precedence works OK.
****************
diff --git a/debugger/break.c b/debugger/break.c
index 5cf164f..d84427d 100644
--- a/debugger/break.c
+++ b/debugger/break.c
@@ -252,6 +252,13 @@
fprintf( stderr, "Invalid breakpoint number %d\n", num );
return;
}
+
+ if( breakpoints[num].condition != NULL )
+ {
+ DEBUG_FreeExpr(breakpoints[num].condition);
+ breakpoints[num].condition = NULL;
+ }
+
breakpoints[num].enabled = FALSE;
breakpoints[num].in_use = FALSE;
breakpoints[num].skipcount = 0;
diff --git a/debugger/dbg.y b/debugger/dbg.y
index 8db0885..f79a3ff 100644
--- a/debugger/dbg.y
+++ b/debugger/dbg.y
@@ -41,6 +41,7 @@
int integer;
struct list_id listing;
struct expr * expression;
+ struct datatype * type;
}
%token tCONT tSTEP tLIST tNEXT tQUIT tHELP tBACKTRACE tINFO tWALK tUP tDOWN
@@ -48,12 +49,15 @@
%token tCLASS tMODULE tSTACK tSEGMENTS tREGS tWND tQUEUE tLOCAL
%token tEOL tSTRING
%token tFRAME tSHARE tCOND tDISPLAY tUNDISPLAY
-%token tSTEPI tNEXTI tFINISH tSHOW tDIR
+%token tSTEPI tNEXTI tFINISH tSHOW tDIR
%token <string> tPATH
%token <string> tIDENTIFIER tSTRING
%token <integer> tNUM tFORMAT
%token <reg> tREG
+%token tCHAR tSHORT tINT tLONG tFLOAT tDOUBLE tUNSIGNED tSIGNED
+%token tSTRUCT tUNION tENUM
+
/* %left ',' */
/* %left '=' OP_OR_EQUAL OP_XOR_EQUAL OP_AND_EQUAL OP_SHL_EQUAL \
OP_SHR_EQUAL OP_PLUS_EQUAL OP_MINUS_EQUAL \
@@ -66,14 +70,15 @@
%left '&'
%left OP_EQ OP_NE
%left '<' '>' OP_LE OP_GE
-%left OP_SHL OP_SHR OP_DRF
+%left OP_SHL OP_SHR
%left '+' '-'
%left '*' '/' '%'
%left OP_SIGN '!' '~' OP_DEREF /* OP_INC OP_DEC OP_ADDR */
-%left '.' '['
+%left '.' '[' OP_DRF
%nonassoc ':'
-%type <expression> expr lval lvalue
+%type <expression> expr lval lvalue
+%type <type> type_cast type_expr
%type <address> expr_addr lval_addr
%type <integer> expr_value
%type <string> pathname
@@ -129,7 +134,9 @@
| tSHOW tDIR tEOL { DEBUG_ShowDir(); }
| tDIR pathname tEOL { DEBUG_AddPath( $2 ); }
| tDIR tEOL { DEBUG_NukePath(); }
- | tDISPLAY expr tEOL { DEBUG_AddDisplay($2); }
+ | tDISPLAY tEOL { DEBUG_InfoDisplay(); }
+ | tDISPLAY expr tEOL { DEBUG_AddDisplay($2, 1, 0); }
+ | tDISPLAY tFORMAT expr tEOL { DEBUG_AddDisplay($3, $2 >> 8, $2 & 0xff); }
| tDELETE tDISPLAY tNUM tEOL { DEBUG_DelDisplay( $3 ); }
| tDELETE tDISPLAY tEOL { DEBUG_DelDisplay( -1 ); }
| tUNDISPLAY tNUM tEOL { DEBUG_DelDisplay( $2 ); }
@@ -257,6 +264,30 @@
| tWALK tWND tEOL { WIN_WalkWindows( 0, 0 ); }
| tWALK tWND tNUM tEOL { WIN_WalkWindows( $3, 0 ); }
+
+type_cast:
+ '(' type_expr ')' { $$ = $2; }
+
+type_expr:
+ type_expr '*' { $$ = DEBUG_FindOrMakePointerType($1); }
+ | tINT { $$ = DEBUG_TypeCast(BASIC, "int"); }
+ | tCHAR { $$ = DEBUG_TypeCast(BASIC, "char"); }
+ | tLONG tINT { $$ = DEBUG_TypeCast(BASIC, "long int"); }
+ | tUNSIGNED tINT { $$ = DEBUG_TypeCast(BASIC, "unsigned int"); }
+ | tLONG tUNSIGNED tINT { $$ = DEBUG_TypeCast(BASIC, "long unsigned int"); }
+ | tLONG tLONG tINT { $$ = DEBUG_TypeCast(BASIC, "long long int"); }
+ | tLONG tLONG tUNSIGNED tINT { $$ = DEBUG_TypeCast(BASIC, "long long unsigned int"); }
+ | tSHORT tINT { $$ = DEBUG_TypeCast(BASIC, "short int"); }
+ | tSHORT tUNSIGNED tINT { $$ = DEBUG_TypeCast(BASIC, "short unsigned int"); }
+ | tSIGNED tCHAR { $$ = DEBUG_TypeCast(BASIC, "signed char"); }
+ | tUNSIGNED tCHAR { $$ = DEBUG_TypeCast(BASIC, "unsigned char"); }
+ | tFLOAT { $$ = DEBUG_TypeCast(BASIC, "float"); }
+ | tDOUBLE { $$ = DEBUG_TypeCast(BASIC, "double"); }
+ | tLONG tDOUBLE { $$ = DEBUG_TypeCast(BASIC, "long double"); }
+ | tSTRUCT tIDENTIFIER { $$ = DEBUG_TypeCast(STRUCT, $2); }
+ | tUNION tIDENTIFIER { $$ = DEBUG_TypeCast(STRUCT, $2); }
+ | tENUM tIDENTIFIER { $$ = DEBUG_TypeCast(ENUM, $2); }
+
expr_addr:
expr { $$ = DEBUG_EvalExpr($1) }
@@ -310,6 +341,7 @@
| '(' expr ')' { $$ = $2; }
| '*' expr %prec OP_DEREF { $$ = DEBUG_UnopExpr(EXP_OP_DEREF, $2); }
| '&' expr %prec OP_DEREF { $$ = DEBUG_UnopExpr(EXP_OP_ADDR, $2); }
+ | type_cast expr %prec OP_DEREF { $$ = DEBUG_TypeCastExpr($1, $2); }
/*
* The lvalue rule builds an expression tree. This is a limited form
@@ -460,15 +492,18 @@
DEBUG_SilentBackTrace();
}
- /* Show where we crashed */
- curr_frame = 0;
- DEBUG_PrintAddress( &addr, dbg_mode, TRUE );
- fprintf(stderr,": ");
- if (DBG_CHECK_READ_PTR( &addr, 1 ))
- {
- DEBUG_Disasm( &addr, TRUE );
- fprintf(stderr,"\n");
- }
+ if( signal != SIGTRAP )
+ {
+ /* Show where we crashed */
+ curr_frame = 0;
+ DEBUG_PrintAddress( &addr, dbg_mode, TRUE );
+ fprintf(stderr,": ");
+ if (DBG_CHECK_READ_PTR( &addr, 1 ))
+ {
+ DEBUG_Disasm( &addr, TRUE );
+ fprintf(stderr,"\n");
+ }
+ }
ret_ok = 0;
do
diff --git a/debugger/dbgmain.c b/debugger/dbgmain.c
index 9d3fb8c..7c1992b 100644
--- a/debugger/dbgmain.c
+++ b/debugger/dbgmain.c
@@ -6,15 +6,16 @@
#include <signal.h>
#include <ldt.h>
-#include <windows.h>
-#include <toolhelp.h>
-#include <module.h>
-#include <debugger.h>
-#include <class.h>
+#include "windows.h"
+#include "toolhelp.h"
+#include "module.h"
+#include "debugger.h"
+#include "class.h"
#include <X11/Xlib.h>
#include "debugger.h"
#include "peexe.h"
+#include "pe_image.h"
ldt_copy_entry ldt_copy[LDT_SIZE];
unsigned char ldt_flags_copy[LDT_SIZE];
@@ -171,7 +172,7 @@
int dbg_size;
struct PE_Debug_dir * dbgdir;
struct pe_data * pe;
- struct pe_segment_table * sectp;
+ LPIMAGE_SECTION_HEADER sectp;
int nsect;
short int dbg_index;
char loaded;
@@ -190,7 +191,7 @@
struct deferred_debug_info deefer;
struct PE_Debug_dir dinfo;
struct CodeViewDebug cdebug;
- struct pe_segment_table sects[10];
+ IMAGE_SECTION_HEADER sects[10];
memset(&deefer, 0, sizeof(deefer));
memset(&dinfo, 0, sizeof(dinfo));
@@ -201,7 +202,7 @@
dinfo.timestamp = 812932395;
cdebug.cv_timestamp = 833392137 /* 841951397 */;
deefer.dbgdir = &dinfo;
- deefer.sectp = §s;
+ deefer.sectp = sects;
deefer.nsect = 10;
DEBUG_InitTypes();
diff --git a/debugger/debug.l b/debugger/debug.l
index 5f6cce2..d33b4c0 100644
--- a/debugger/debug.l
+++ b/debugger/debug.l
@@ -113,7 +113,7 @@
<INITIAL>list|lis|li|l { BEGIN(PATH_EXPECTED); return tLIST; }
<INITIAL>enable|enabl|enab|ena { BEGIN(NOCMD); return tENABLE;}
<INITIAL>disable|disabl|disab|disa|dis { BEGIN(NOCMD); return tDISABLE; }
-<INITIAL,INFO_CMD,DEL_CMD>display|displa|displ|disp { BEGIN(NOCMD); return tDISPLAY; }
+<INITIAL,INFO_CMD,DEL_CMD>display|displa|displ|disp { BEGIN(FORMAT_EXPECTED); return tDISPLAY; }
<INITIAL>undisplay|undispla|undispl|undisp|undis|undi|und { BEGIN(NOCMD); return tUNDISPLAY; }
<INITIAL>delete|delet|dele|del { BEGIN(DEL_CMD); return tDELETE; }
<INITIAL>quit|qui|qu|q { BEGIN(NOCMD); return tQUIT; }
@@ -155,11 +155,22 @@
<INITIAL,SHOW_CMD>directories|directorie|directori|director|directo|direct|direc|direc|dir {
BEGIN(PATH_EXPECTED); return tDIR; }
+char { return tCHAR; }
+short { return tSHORT; }
+int { return tINT; }
+long { return tLONG; }
+float { return tFLOAT; }
+double { return tDOUBLE; }
+unsigned { return tUNSIGNED; }
+signed { return tSIGNED; }
+struct { return tSTRUCT; }
+union { return tUNION; }
+enum { return tENUM; }
+
{IDENTIFIER} { yylval.string = make_symbol(yytext); return tIDENTIFIER; }
<PATH_EXPECTED>{PATHNAME} { yylval.string = make_symbol(yytext); return tPATH; }
-
[ \t]+ /* Eat up whitespace */
. { if (syntax_error == 0)
diff --git a/debugger/display.c b/debugger/display.c
index b170026..fd7e8c6 100644
--- a/debugger/display.c
+++ b/debugger/display.c
@@ -20,10 +20,18 @@
#include <stdarg.h>
#define MAX_DISPLAY 25
-static struct expr * displaypoints[MAX_DISPLAY];
+
+struct display
+{
+ struct expr * exp;
+ int count;
+ char format;
+};
+
+static struct display displaypoints[MAX_DISPLAY];
int
-DEBUG_AddDisplay(struct expr * exp)
+DEBUG_AddDisplay(struct expr * exp, int count, char format)
{
int i;
@@ -32,9 +40,11 @@
*/
for(i=0; i < MAX_DISPLAY; i++ )
{
- if( displaypoints[i] == NULL )
+ if( displaypoints[i].exp == NULL )
{
- displaypoints[i] = DEBUG_CloneExpr(exp);
+ displaypoints[i].exp = DEBUG_CloneExpr(exp);
+ displaypoints[i].count = count;
+ displaypoints[i].format = format;
break;
}
}
@@ -52,10 +62,10 @@
*/
for(i=0; i < MAX_DISPLAY; i++ )
{
- if( displaypoints[i] != NULL )
+ if( displaypoints[i].exp != NULL )
{
fprintf(stderr, "%d : ", i+1);
- DEBUG_DisplayExpr(displaypoints[i]);
+ DEBUG_DisplayExpr(displaypoints[i].exp);
fprintf(stderr, "\n");
}
}
@@ -74,22 +84,33 @@
*/
for(i=0; i < MAX_DISPLAY; i++ )
{
- if( displaypoints[i] != NULL )
+ if( displaypoints[i].exp != NULL )
{
- addr = DEBUG_EvalExpr(displaypoints[i]);
+ addr = DEBUG_EvalExpr(displaypoints[i].exp);
if( addr.type == NULL )
{
fprintf(stderr, "Unable to evaluate expression ");
- DEBUG_DisplayExpr(displaypoints[i]);
+ DEBUG_DisplayExpr(displaypoints[i].exp);
fprintf(stderr, "\nDisabling...\n");
DEBUG_DelDisplay(i);
}
else
{
fprintf(stderr, "%d : ", i + 1);
- DEBUG_DisplayExpr(displaypoints[i]);
+ DEBUG_DisplayExpr(displaypoints[i].exp);
fprintf(stderr, " = ");
- DEBUG_Print( &addr, 1, 0, 0);
+ if( displaypoints[i].format == 'i' )
+ {
+ DEBUG_ExamineMemory( &addr,
+ displaypoints[i].count,
+ displaypoints[i].format);
+ }
+ else
+ {
+ DEBUG_Print( &addr,
+ displaypoints[i].count,
+ displaypoints[i].format, 0);
+ }
}
}
}
@@ -111,17 +132,17 @@
{
for(i=0; i < MAX_DISPLAY; i++ )
{
- if( displaypoints[i] != NULL )
+ if( displaypoints[i].exp != NULL )
{
- DEBUG_FreeExpr(displaypoints[i]);
- displaypoints[i] = NULL;
+ DEBUG_FreeExpr(displaypoints[i].exp);
+ displaypoints[i].exp = NULL;
}
}
}
- else if( displaypoints[displaynum - 1] != NULL )
+ else if( displaypoints[displaynum - 1].exp != NULL )
{
- DEBUG_FreeExpr(displaypoints[displaynum - 1]);
- displaypoints[displaynum - 1] = NULL;
+ DEBUG_FreeExpr(displaypoints[displaynum - 1].exp);
+ displaypoints[displaynum - 1].exp = NULL;
}
return TRUE;
}
diff --git a/debugger/expr.c b/debugger/expr.c
index 4bf78ef..6ef8d37 100644
--- a/debugger/expr.c
+++ b/debugger/expr.c
@@ -70,6 +70,12 @@
struct
{
+ struct datatype * cast;
+ struct expr * expr;
+ } cast;
+
+ struct
+ {
struct expr * exp1;
const char * element_name;
int result;
@@ -103,6 +109,7 @@
#define EXPR_TYPE_ARRAY 8
#define EXPR_TYPE_CALL 9
#define EXPR_TYPE_STRING 10
+#define EXPR_TYPE_CAST 11
static char expr_list[4096];
static int next_expr_free = 0;
@@ -132,6 +139,18 @@
next_expr_free = 0;
}
+struct expr *
+DEBUG_TypeCastExpr(struct datatype * dt, struct expr * exp)
+{
+ struct expr * ex;
+
+ ex = DEBUG_GetFreeExpr();
+
+ ex->type = EXPR_TYPE_CAST;
+ ex->un.cast.cast = dt;
+ ex->un.cast.expr = exp;
+ return ex;
+}
struct expr *
DEBUG_RegisterExpr(enum debug_regs regno)
@@ -294,6 +313,10 @@
switch(exp->type)
{
+ case EXPR_TYPE_CAST:
+ rtn = DEBUG_EvalExpr(exp->un.cast.expr);
+ rtn.type = exp->un.cast.cast;
+ break;
case EXPR_TYPE_STRING:
rtn.type = DEBUG_TypeString;
rtn.off = (unsigned int) &exp->un.string.str;
@@ -620,6 +643,13 @@
switch(exp->type)
{
+ case EXPR_TYPE_CAST:
+ fprintf(stderr, "((");
+ DEBUG_PrintTypeCast(exp->un.cast.cast);
+ fprintf(stderr, ")");
+ DEBUG_DisplayExpr(exp->un.cast.expr);
+ fprintf(stderr, ")");
+ break;
case EXPR_TYPE_REGISTER:
DEBUG_PrintRegister(exp->un.rgister.reg);
break;
@@ -780,6 +810,9 @@
switch(exp->type)
{
+ case EXPR_TYPE_CAST:
+ rtn->un.cast.expr = DEBUG_CloneExpr(exp->un.cast.expr);
+ break;
case EXPR_TYPE_REGISTER:
case EXPR_TYPE_US_CONST:
case EXPR_TYPE_CONST:
@@ -834,6 +867,9 @@
switch(exp->type)
{
+ case EXPR_TYPE_CAST:
+ DEBUG_FreeExpr(exp->un.cast.expr);
+ break;
case EXPR_TYPE_REGISTER:
case EXPR_TYPE_US_CONST:
case EXPR_TYPE_CONST:
diff --git a/debugger/hash.c b/debugger/hash.c
index 2684ea0..20f3e64 100644
--- a/debugger/hash.c
+++ b/debugger/hash.c
@@ -18,6 +18,9 @@
#include "xmalloc.h"
#define NR_NAME_HASH 16384
+#ifndef PATH_MAX
+#define PATH_MAX _MAX_PATH
+#endif
static char * reg_name[] =
{
diff --git a/debugger/info.c b/debugger/info.c
index 6c5f4de..dd5b76a 100644
--- a/debugger/info.c
+++ b/debugger/info.c
@@ -17,10 +17,10 @@
*/
void DEBUG_PrintBasic( const DBG_ADDR *addr, int count, char format )
{
- char * default_format;
+ char * default_format;
long long int value;
- if( addr->type == NULL )
+ if( addr->type == NULL )
{
fprintf(stderr, "Unable to evaluate expression\n");
return;
@@ -32,16 +32,22 @@
switch(format)
{
case 'x':
- if (addr->seg) fprintf( stderr, "0x%04lx", (long unsigned int) value );
- else fprintf( stderr, "0x%08lx", (long unsigned int) value );
+ if (addr->seg)
+ {
+ DEBUG_nchar += fprintf( stderr, "0x%04lx", (long unsigned int) value );
+ }
+ else
+ {
+ DEBUG_nchar += fprintf( stderr, "0x%08lx", (long unsigned int) value );
+ }
break;
case 'd':
- fprintf( stderr, "%ld\n", (long int) value );
+ DEBUG_nchar += fprintf( stderr, "%ld\n", (long int) value );
break;
case 'c':
- fprintf( stderr, "%d = '%c'",
+ DEBUG_nchar += fprintf( stderr, "%d = '%c'",
(char)(value & 0xff), (char)(value & 0xff) );
break;
@@ -53,11 +59,10 @@
case 0:
if( default_format != NULL )
{
- fprintf( stderr, default_format, value );
+ DEBUG_nchar += fprintf( stderr, default_format, value );
}
break;
}
-
}
diff --git a/debugger/msc.c b/debugger/msc.c
index 1c1817b..90bf0fd 100644
--- a/debugger/msc.c
+++ b/debugger/msc.c
@@ -512,9 +512,9 @@
char * module_name;
char * dbg_info;
int dbg_size;
- struct PE_Debug_dir * dbgdir;
+ LPIMAGE_DEBUG_DIRECTORY dbgdir;
struct pe_data * pe;
- struct pe_segment_table * sectp;
+ LPIMAGE_SECTION_HEADER sectp;
int nsect;
short int dbg_index;
char loaded;
@@ -747,17 +747,24 @@
}
memset(symname, 0, sizeof(symname));
memcpy(symname, type->structure.name, type->structure.namelen);
- typeptr = DEBUG_NewDataType(STRUCT, symname);
+ if( strcmp(symname, "__unnamed") == 0 )
+ {
+ typeptr = DEBUG_NewDataType(STRUCT, NULL);
+ }
+ else
+ {
+ typeptr = DEBUG_NewDataType(STRUCT, symname);
+ }
cv_defined_types[curr_type - 0x1000] = typeptr;
/*
* Now copy the relevant bits from the fieldlist that we specified.
*/
subtype = DEBUG_GetCVType(type->structure.fieldlist);
- DEBUG_SetStructSize(typeptr, type->structure.structlen);
if( subtype != NULL )
{
+ DEBUG_SetStructSize(typeptr, type->structure.structlen);
DEBUG_CopyFieldlist(typeptr, subtype);
}
break;
@@ -773,17 +780,26 @@
}
memset(symname, 0, sizeof(symname));
memcpy(symname, type->t_union.name, type->t_union.namelen);
- typeptr = DEBUG_NewDataType(STRUCT, symname);
+
+ if( strcmp(symname, "__unnamed") == 0 )
+ {
+ typeptr = DEBUG_NewDataType(STRUCT, NULL);
+ }
+ else
+ {
+ typeptr = DEBUG_NewDataType(STRUCT, symname);
+ }
+
cv_defined_types[curr_type - 0x1000] = typeptr;
/*
* Now copy the relevant bits from the fieldlist that we specified.
*/
subtype = DEBUG_GetCVType(type->t_union.field);
- DEBUG_SetStructSize(typeptr, type->t_union.un_len);
if( subtype != NULL )
{
+ DEBUG_SetStructSize(typeptr, type->t_union.un_len);
DEBUG_CopyFieldlist(typeptr, subtype);
}
break;
@@ -874,14 +890,14 @@
int has_codeview = FALSE;
int rtn = FALSE;
int orig_size;
- struct PE_Debug_dir * dbgptr;
+ LPIMAGE_DEBUG_DIRECTORY dbgptr;
struct deferred_debug_info * deefer;
orig_size = size;
- dbgptr = (struct PE_Debug_dir *) (load_addr + v_addr);
+ dbgptr = (LPIMAGE_DEBUG_DIRECTORY) (load_addr + v_addr);
for(; size > 0; size -= sizeof(*dbgptr), dbgptr++ )
{
- switch(dbgptr->type)
+ switch(dbgptr->Type)
{
case IMAGE_DEBUG_TYPE_CODEVIEW:
case IMAGE_DEBUG_TYPE_MISC:
@@ -891,10 +907,10 @@
}
size = orig_size;
- dbgptr = (struct PE_Debug_dir *) (load_addr + v_addr);
+ dbgptr = (LPIMAGE_DEBUG_DIRECTORY) (load_addr + v_addr);
for(; size > 0; size -= sizeof(*dbgptr), dbgptr++ )
{
- switch(dbgptr->type)
+ switch(dbgptr->Type)
{
case IMAGE_DEBUG_TYPE_COFF:
/*
@@ -921,8 +937,8 @@
* means that this entry points to a .DBG file. Otherwise,
* it just points to itself, and we can ignore this.
*/
- if( (dbgptr->type == IMAGE_DEBUG_TYPE_MISC)
- && (pe->pe_header->coff.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) == 0 )
+ if( (dbgptr->Type == IMAGE_DEBUG_TYPE_MISC)
+ && (pe->pe_header->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) == 0 )
{
break;
}
@@ -938,9 +954,9 @@
* upon the type, but this is always enough so we are able
* to proceed if we know what we need to do next.
*/
- deefer->dbg_size = dbgptr->dbgsize;
- deefer->dbg_info = (char *) xmalloc(dbgptr->dbgsize);
- lseek(fd, dbgptr->dbgoff, SEEK_SET);
+ deefer->dbg_size = dbgptr->SizeOfData;
+ deefer->dbg_info = (char *) xmalloc(dbgptr->SizeOfData);
+ lseek(fd, dbgptr->PointerToRawData, SEEK_SET);
read(fd, deefer->dbg_info, deefer->dbg_size);
deefer->load_addr = (char *) load_addr;
@@ -951,7 +967,7 @@
deefer->module_name = xstrdup(DEBUG_curr_module);
deefer->sectp = pe->pe_seg;
- deefer->nsect = pe->pe_header->coff.NumberOfSections;
+ deefer->nsect = pe->pe_header->FileHeader.NumberOfSections;
dbglist = deefer;
break;
@@ -1538,7 +1554,7 @@
DBG_ADDR new_addr;
int nsect;
union any_size ptr;
- struct pe_segment_table * sectp;
+ IMAGE_SECTION_HEADER * sectp;
union codeview_symbol * sym;
char symname[PATH_MAX];
struct name_hash * thunk_sym = NULL;
@@ -1601,7 +1617,7 @@
new_addr.seg = 0;
new_addr.type = DEBUG_GetCVType(sym->data.symtype);
new_addr.off = (unsigned int) deefer->load_addr +
- sectp[sym->data.seg - 1].Virtual_Address +
+ sectp[sym->data.seg - 1].VirtualAddress +
sym->data.offset;
DEBUG_AddSymbol( symname, &new_addr, NULL, SYM_WIN32 | SYM_DATA );
break;
@@ -1615,7 +1631,7 @@
new_addr.seg = 0;
new_addr.type = NULL;
new_addr.off = (unsigned int) deefer->load_addr +
- sectp[sym->thunk.segment - 1].Virtual_Address +
+ sectp[sym->thunk.segment - 1].VirtualAddress +
sym->thunk.offset;
thunk_sym = DEBUG_AddSymbol( symname, &new_addr, NULL,
SYM_WIN32 | SYM_FUNC);
@@ -1630,7 +1646,7 @@
new_addr.seg = 0;
new_addr.type = DEBUG_GetCVType(sym->proc.proctype);
new_addr.off = (unsigned int) deefer->load_addr +
- sectp[sym->proc.segment - 1].Virtual_Address +
+ sectp[sym->proc.segment - 1].VirtualAddress +
sym->proc.offset;
/*
* See if we can find a segment that this goes with. If so,
@@ -1640,10 +1656,10 @@
for(i=0; linetab[i].linetab != NULL; i++)
{
if( ((unsigned int) deefer->load_addr
- + sectp[linetab[i].segno - 1].Virtual_Address
+ + sectp[linetab[i].segno - 1].VirtualAddress
+ linetab[i].start <= new_addr.off)
&& ((unsigned int) deefer->load_addr
- + sectp[linetab[i].segno - 1].Virtual_Address
+ + sectp[linetab[i].segno - 1].VirtualAddress
+ linetab[i].end > new_addr.off) )
{
break;
@@ -2119,8 +2135,8 @@
int j;
struct codeview_linetab_hdr * linetab;
int nsect;
- struct PE_DBG_FileHeader * pdbg = NULL;
- struct pe_segment_table * sectp;
+ LPIMAGE_SEPARATE_DEBUG_HEADER pdbg = NULL;
+ IMAGE_SECTION_HEADER * sectp;
struct stat statbuf;
int status;
@@ -2148,9 +2164,9 @@
addr = mmap(0, statbuf.st_size, PROT_READ,
MAP_PRIVATE, fd, 0);
- pdbg = (struct PE_DBG_FileHeader *) addr;
+ pdbg = (LPIMAGE_SEPARATE_DEBUG_HEADER) addr;
- if( pdbg->TimeDateStamp != deefer->dbgdir->timestamp )
+ if( pdbg->TimeDateStamp != deefer->dbgdir->TimeDateStamp )
{
fprintf(stderr, "Warning - %s has incorrect internal timestamp\n",
filename);
@@ -2160,10 +2176,10 @@
fprintf(stderr, "Processing symbols from %s...\n", filename);
dbghdr = (struct PE_Debug_dir *) ( addr + sizeof(*pdbg)
- + pdbg->NumberOfSections * sizeof(struct pe_segment_table)
+ + pdbg->NumberOfSections * sizeof(IMAGE_SECTION_HEADER)
+ pdbg->ExportedNamesSize);
- sectp = (struct pe_segment_table *) ((char *) pdbg + sizeof(*pdbg));
+ sectp = (LPIMAGE_SECTION_HEADER) ((char *) pdbg + sizeof(*pdbg));
nsect = pdbg->NumberOfSections;
for( i=0; i < pdbg->DebugDirectorySize / sizeof(*pdbg); i++, dbghdr++ )
@@ -2300,7 +2316,7 @@
last_proc = deefer->dbg_index;
}
- switch(deefer->dbgdir->type)
+ switch(deefer->dbgdir->Type)
{
case IMAGE_DEBUG_TYPE_COFF:
/*
diff --git a/debugger/registers.c b/debugger/registers.c
index 7c68f6a..5ed74dd 100644
--- a/debugger/registers.c
+++ b/debugger/registers.c
@@ -188,7 +188,7 @@
#ifdef GS_sig
GS_sig(sigcontext) = GS_reg(&DEBUG_context);
#else
- __asm__("movw %w0,%%gs"::"r" (FS_reg(&DEBUG_context)));
+ __asm__("movw %w0,%%gs"::"r" (GS_reg(&DEBUG_context)));
#endif
}
diff --git a/debugger/source.c b/debugger/source.c
index d80d386..4ece937 100644
--- a/debugger/source.c
+++ b/debugger/source.c
@@ -93,7 +93,7 @@
}
static
-void
+int
DEBUG_DisplaySource(char * sourcefile, int start, int end)
{
char * addr;
@@ -103,6 +103,7 @@
struct open_filelist * ol;
int nlines;
char * pnt;
+ int rtn;
struct searchlist * sl;
struct stat statbuf;
int status;
@@ -217,7 +218,7 @@
ol->linelist = NULL;
ofiles = ol;
fprintf(stderr,"Unable to open file %s\n", tmppath);
- return;
+ return FALSE;
}
}
}
@@ -239,13 +240,13 @@
fd = open(tmppath, O_RDONLY);
if( fd == -1 )
{
- return;
+ return FALSE;
}
addr = mmap(0, statbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
if( addr == (char *) -1 )
{
- return;
+ return FALSE;
}
/*
@@ -285,19 +286,20 @@
fd = open(ol->real_path, O_RDONLY);
if( fd == -1 )
{
- return;
+ return FALSE;
}
addr = mmap(0, ol->size, PROT_READ, MAP_PRIVATE, fd, 0);
if( addr == (char *) -1 )
{
- return;
+ return FALSE;
}
}
/*
* All we need to do is to display the source lines here.
*/
+ rtn = FALSE;
for(i=start - 1; i <= end - 1; i++)
{
if( i < 0 || i >= ol->nlines - 1)
@@ -305,6 +307,7 @@
continue;
}
+ rtn = TRUE;
memset(&buffer, 0, sizeof(buffer));
if( ol->linelist[i+1] != ol->linelist[i] )
{
@@ -317,6 +320,8 @@
munmap(addr, ol->size);
close(fd);
+ return rtn;
+
}
void
@@ -324,6 +329,7 @@
int delta)
{
int end;
+ int rtn;
int start;
char * sourcefile;
@@ -406,7 +412,7 @@
/*
* Now call this function to do the dirty work.
*/
- DEBUG_DisplaySource(sourcefile, start, end);
+ rtn = DEBUG_DisplaySource(sourcefile, start, end);
if( sourcefile != (char *) &DEBUG_current_sourcefile )
{
diff --git a/debugger/stabs.c b/debugger/stabs.c
index 0c1ddf1..a52c467 100644
--- a/debugger/stabs.c
+++ b/debugger/stabs.c
@@ -75,6 +75,44 @@
unsigned long n_value;
};
+/*
+ * This is used to keep track of known datatypes so that we don't redefine
+ * them over and over again. It sucks up lots of memory otherwise.
+ */
+struct known_typedef
+{
+ struct known_typedef * next;
+ char * name;
+ int ndefs;
+ struct datatype * types[0];
+};
+
+#define NR_STAB_HASH 521
+
+struct known_typedef * ktd_head[NR_STAB_HASH];
+
+static unsigned int stab_hash( const char * name )
+{
+ unsigned int hash = 0;
+ unsigned int tmp;
+ const char * p;
+
+ p = name;
+
+ while (*p)
+ {
+ hash = (hash << 4) + *p++;
+
+ if( (tmp = (hash & 0xf0000000)) )
+ {
+ hash ^= tmp >> 24;
+ }
+ hash &= ~tmp;
+ }
+ return hash % NR_STAB_HASH;
+}
+
+
static void stab_strcpy(char * dest, const char * source)
{
/*
@@ -89,6 +127,179 @@
*dest++ = '\0';
}
+#define MAX_TD_NESTING 128
+
+static
+int
+DEBUG_RegisterTypedef(const char * name, struct datatype ** types, int ndef)
+{
+ int hash;
+ struct known_typedef * ktd;
+
+ if( ndef == 1 )
+ {
+ return TRUE;
+ }
+
+ ktd = (struct known_typedef *) malloc(sizeof(struct known_typedef)
+ + ndef * sizeof(struct datatype *));
+
+ hash = stab_hash(name);
+
+ ktd->name = xstrdup(name);
+ ktd->ndefs = ndef;
+ memcpy(&ktd->types[0], types, ndef * sizeof(struct datatype *));
+ ktd->next = ktd_head[hash];
+ ktd_head[hash] = ktd;
+
+ return TRUE;
+}
+
+static
+int
+DEBUG_HandlePreviousTypedef(const char * name, const char * stab)
+{
+ int count;
+ enum debug_type expect;
+ int hash;
+ struct known_typedef * ktd;
+ char * ptr;
+ char * tc;
+ int typenum;
+
+ hash = stab_hash(name);
+
+ for(ktd = ktd_head[hash]; ktd; ktd = ktd->next)
+ {
+ if( (ktd->name[0] == name[0])
+ && (strcmp(name, ktd->name) == 0) )
+ {
+ break;
+ }
+ }
+
+ /*
+ * Didn't find it. This must be a new one.
+ */
+ if( ktd == NULL )
+ {
+ return FALSE;
+ }
+
+ /*
+ * Examine the stab to make sure it has the same number of definitions.
+ */
+ count = 0;
+ for(ptr = strchr(stab, '='); ptr; ptr = strchr(ptr+1, '='))
+ {
+ if( count >= ktd->ndefs )
+ {
+ return FALSE;
+ }
+
+ /*
+ * Make sure the types of all of the objects is consistent with
+ * what we have already parsed.
+ */
+ switch(ptr[1])
+ {
+ case '*':
+ expect = POINTER;
+ break;
+ case 's':
+ case 'u':
+ expect = STRUCT;
+ break;
+ case 'a':
+ expect = ARRAY;
+ break;
+ case '1':
+ case 'r':
+ expect = BASIC;
+ break;
+ case 'x':
+ expect = STRUCT;
+ break;
+ case 'e':
+ expect = ENUM;
+ break;
+ case 'f':
+ expect = FUNC;
+ break;
+ default:
+ fprintf(stderr, "Unknown type.\n");
+ return FALSE;
+ }
+ if( expect != DEBUG_GetType(ktd->types[count]) )
+ {
+ return FALSE;
+ }
+ count++;
+ }
+
+ if( ktd->ndefs != count )
+ {
+ return FALSE;
+ }
+
+ /*
+ * OK, this one is safe. Go through, dig out all of the type numbers,
+ * and substitute the appropriate things.
+ */
+ count = 0;
+ for(ptr = strchr(stab, '='); ptr; ptr = strchr(ptr+1, '='))
+ {
+ /*
+ * Back up until we get to a non-numeric character. This is the type
+ * number.
+ */
+ tc = ptr - 1;
+ while( *tc >= '0' && *tc <= '9' )
+ {
+ tc--;
+ }
+
+ typenum = atol(tc + 1);
+ if( num_stab_types <= typenum )
+ {
+ num_stab_types = typenum + 32;
+ stab_types = (struct datatype **) xrealloc(stab_types,
+ num_stab_types * sizeof(struct datatype *));
+ if( stab_types == NULL )
+ {
+ return FALSE;
+ }
+ }
+
+ stab_types[typenum] = ktd->types[count++];
+ }
+
+ return TRUE;
+}
+
+static int DEBUG_FreeRegisteredTypedefs()
+{
+ int count;
+ int j;
+ struct known_typedef * ktd;
+ struct known_typedef * next;
+
+ count = 0;
+ for(j=0; j < NR_STAB_HASH; j++ )
+ {
+ for(ktd = ktd_head[j]; ktd; ktd = next)
+ {
+ count++;
+ next = ktd->next;
+ free(ktd->name);
+ free(ktd);
+ }
+ ktd_head[j] = NULL;
+ }
+
+ return TRUE;
+
+}
static
int
@@ -96,21 +307,33 @@
{
int arrmax;
int arrmin;
- char * c;
+ char * c;
struct datatype * curr_type;
struct datatype * datatype;
+ struct datatype * curr_types[MAX_TD_NESTING];
char element_name[1024];
+ int ntypes = 0;
int offset;
+ const char * orig_typename;
int rtn = FALSE;
int size;
char * tc;
char * tc2;
int typenum;
- /*
- * Go from back to front. First we go through and figure out what type numbers
- * we need, and register those types. Then we go in and fill the details.
+ orig_typename = typename;
+
+ if( DEBUG_HandlePreviousTypedef(typename, ptr) == TRUE )
+ {
+ return TRUE;
+ }
+
+ /*
+ * Go from back to front. First we go through and figure out what
+ * type numbers we need, and register those types. Then we go in
+ * and fill the details.
*/
+
for( c = strchr(ptr, '='); c != NULL; c = strchr(c + 1, '=') )
{
/*
@@ -134,31 +357,47 @@
}
}
+ if( ntypes >= MAX_TD_NESTING )
+ {
+ /*
+ * If this ever happens, just bump the counter.
+ */
+ fprintf(stderr, "Typedef nesting overflow\n");
+ return FALSE;
+ }
+
switch(c[1])
{
case '*':
stab_types[typenum] = DEBUG_NewDataType(POINTER, NULL);
+ curr_types[ntypes++] = stab_types[typenum];
break;
case 's':
case 'u':
stab_types[typenum] = DEBUG_NewDataType(STRUCT, typename);
+ curr_types[ntypes++] = stab_types[typenum];
break;
case 'a':
stab_types[typenum] = DEBUG_NewDataType(ARRAY, NULL);
+ curr_types[ntypes++] = stab_types[typenum];
break;
case '1':
case 'r':
stab_types[typenum] = DEBUG_NewDataType(BASIC, typename);
+ curr_types[ntypes++] = stab_types[typenum];
break;
case 'x':
stab_strcpy(element_name, c + 3);
stab_types[typenum] = DEBUG_NewDataType(STRUCT, element_name);
+ curr_types[ntypes++] = stab_types[typenum];
break;
case 'e':
stab_types[typenum] = DEBUG_NewDataType(ENUM, NULL);
+ curr_types[ntypes++] = stab_types[typenum];
break;
case 'f':
stab_types[typenum] = DEBUG_NewDataType(FUNC, NULL);
+ curr_types[ntypes++] = stab_types[typenum];
break;
default:
fprintf(stderr, "Unknown type.\n");
@@ -166,154 +405,184 @@
typename = NULL;
}
- /*
- * OK, now take a second sweep through. Now we will be digging out the definitions
- * of the various components, and storing them in the skeletons that we have already
- * allocated. We take a right-to left search as this is much easier to parse.
- */
- for( c = strrchr(ptr, '='); c != NULL; c = strrchr(ptr, '=') )
- {
/*
- * Back up until we get to a non-numeric character. This is the type
- * number.
- */
- tc = c - 1;
- while( *tc >= '0' && *tc <= '9' )
- {
- tc--;
- }
- typenum = atol(tc + 1);
- curr_type = stab_types[typenum];
+ * Now register the type so that if we encounter it again, we will know
+ * what to do.
+ */
+ DEBUG_RegisterTypedef(orig_typename, curr_types, ntypes);
- switch(c[1])
- {
- case 'x':
- tc = c + 3;
- while( *tc != ':' )
- {
- tc ++;
- }
- tc++;
- if( *tc == '\0' )
- {
- *c = '\0';
- }
- else
- {
- strcpy(c, tc);
- }
+ /*
+ * OK, now take a second sweep through. Now we will be digging
+ * out the definitions of the various components, and storing
+ * them in the skeletons that we have already allocated. We take
+ * a right-to left search as this is much easier to parse.
+ */
+ for( c = strrchr(ptr, '='); c != NULL; c = strrchr(ptr, '=') )
+ {
+ /*
+ * Back up until we get to a non-numeric character. This is the type
+ * number.
+ */
+ tc = c - 1;
+ while( *tc >= '0' && *tc <= '9' )
+ {
+ tc--;
+ }
+ typenum = atol(tc + 1);
+ curr_type = stab_types[typenum];
+
+ switch(c[1])
+ {
+ case 'x':
+ tc = c + 3;
+ while( *tc != ':' )
+ {
+ tc ++;
+ }
+ tc++;
+ if( *tc == '\0' )
+ {
+ *c = '\0';
+ }
+ else
+ {
+ strcpy(c, tc);
+ }
+
+ break;
+ case '*':
+ case 'f':
+ tc = c + 2;
+ datatype = stab_types[strtol(tc, &tc, 10)];
+ DEBUG_SetPointerType(curr_type, datatype);
+ if( *tc == '\0' )
+ {
+ *c = '\0';
+ }
+ else
+ {
+ strcpy(c, tc);
+ }
+ break;
+ case '1':
+ case 'r':
+ /*
+ * We have already handled these above.
+ */
+ *c = '\0';
+ break;
+ case 'a':
+ tc = c + 5;
+ arrmin = strtol(tc, &tc, 10);
+ tc++;
+ arrmax = strtol(tc, &tc, 10);
+ tc++;
+ datatype = stab_types[strtol(tc, &tc, 10)];
+ if( *tc == '\0' )
+ {
+ *c = '\0';
+ }
+ else
+ {
+ strcpy(c, tc);
+ }
+
+ DEBUG_SetArrayParams(curr_type, arrmin, arrmax, datatype);
+ break;
+ case 's':
+ case 'u':
+ tc = c + 2;
+ if( DEBUG_SetStructSize(curr_type, strtol(tc, &tc, 10)) == FALSE )
+ {
+ /*
+ * We have already filled out this structure. Nothing to do,
+ * so just skip forward to the end of the definition.
+ */
+ while( tc[0] != ';' && tc[1] != ';' )
+ {
+ tc++;
+ }
+
+ tc += 2;
+
+ if( *tc == '\0' )
+ {
+ *c = '\0';
+ }
+ else
+ {
+ strcpy(c, tc + 1);
+ }
+ continue;
+ }
- break;
- case '*':
- case 'f':
- tc = c + 2;
- datatype = stab_types[strtol(tc, &tc, 10)];
- DEBUG_SetPointerType(curr_type, datatype);
- if( *tc == '\0' )
- {
- *c = '\0';
- }
- else
- {
- strcpy(c, tc);
- }
- break;
- case '1':
- case 'r':
- /*
- * We have already handled these above.
- */
- *c = '\0';
- break;
- case 'a':
- tc = c + 5;
- arrmin = strtol(tc, &tc, 10);
- tc++;
- arrmax = strtol(tc, &tc, 10);
- tc++;
- datatype = stab_types[strtol(tc, &tc, 10)];
- if( *tc == '\0' )
- {
- *c = '\0';
- }
- else
- {
- strcpy(c, tc);
- }
-
- DEBUG_SetArrayParams(curr_type, arrmin, arrmax, datatype);
- break;
- case 's':
- case 'u':
- tc = c + 2;
- DEBUG_SetStructSize(curr_type, strtol(tc, &tc, 10));
- /*
- * Now parse the individual elements of the structure/union.
- */
- while(*tc != ';')
- {
- tc2 = element_name;
- while(*tc != ':')
- {
- *tc2++ = *tc++;
- }
- tc++;
- *tc2++ = '\0';
- datatype = stab_types[strtol(tc, &tc, 10)];
- tc++;
- offset = strtol(tc, &tc, 10);
- tc++;
- size = strtol(tc, &tc, 10);
- tc++;
- DEBUG_AddStructElement(curr_type, element_name, datatype, offset, size);
- }
- if( *tc == '\0' )
- {
- *c = '\0';
- }
- else
- {
- strcpy(c, tc + 1);
- }
- break;
- case 'e':
- tc = c + 2;
- /*
- * Now parse the individual elements of the structure/union.
- */
- while(*tc != ';')
- {
- tc2 = element_name;
- while(*tc != ':')
- {
- *tc2++ = *tc++;
- }
- tc++;
- *tc2++ = '\0';
- offset = strtol(tc, &tc, 10);
- tc++;
- DEBUG_AddStructElement(curr_type, element_name, NULL, offset, 0);
- }
- if( *tc == '\0' )
- {
- *c = '\0';
- }
- else
- {
- strcpy(c, tc + 1);
- }
- break;
- default:
- fprintf(stderr, "Unknown type.\n");
- break;
- }
- }
-
- rtn = TRUE;
-
+ /*
+ * Now parse the individual elements of the structure/union.
+ */
+ while(*tc != ';')
+ {
+ tc2 = element_name;
+ while(*tc != ':')
+ {
+ *tc2++ = *tc++;
+ }
+ tc++;
+ *tc2++ = '\0';
+ datatype = stab_types[strtol(tc, &tc, 10)];
+ tc++;
+ offset = strtol(tc, &tc, 10);
+ tc++;
+ size = strtol(tc, &tc, 10);
+ tc++;
+ DEBUG_AddStructElement(curr_type, element_name, datatype, offset, size);
+ }
+ if( *tc == '\0' )
+ {
+ *c = '\0';
+ }
+ else
+ {
+ strcpy(c, tc + 1);
+ }
+ break;
+ case 'e':
+ tc = c + 2;
+ /*
+ * Now parse the individual elements of the structure/union.
+ */
+ while(*tc != ';')
+ {
+ tc2 = element_name;
+ while(*tc != ':')
+ {
+ *tc2++ = *tc++;
+ }
+ tc++;
+ *tc2++ = '\0';
+ offset = strtol(tc, &tc, 10);
+ tc++;
+ DEBUG_AddStructElement(curr_type, element_name, NULL, offset, 0);
+ }
+ if( *tc == '\0' )
+ {
+ *c = '\0';
+ }
+ else
+ {
+ strcpy(c, tc + 1);
+ }
+ break;
+ default:
+ fprintf(stderr, "Unknown type.\n");
+ break;
+ }
+ }
+
+ rtn = TRUE;
+
leave:
-
- return rtn;
+
+ return rtn;
}
@@ -676,6 +945,9 @@
num_stab_types = 0;
}
+
+ DEBUG_FreeRegisteredTypedefs();
+
return TRUE;
}
diff --git a/debugger/types.c b/debugger/types.c
index 581d096..0b26d50 100644
--- a/debugger/types.c
+++ b/debugger/types.c
@@ -11,8 +11,11 @@
#include <stdlib.h>
#include <assert.h>
+#ifndef __EMX__
#include <sys/mman.h>
+#endif
#include <fcntl.h>
+#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <strings.h>
@@ -28,6 +31,9 @@
#define NR_TYPE_HASH 521
+int DEBUG_nchar;
+static int DEBUG_maxchar = 1024;
+
struct en_values
{
struct en_values* next;
@@ -177,6 +183,32 @@
return dt;
}
+static
+struct datatype *
+DEBUG_LookupDataType(enum debug_type xtype, int hash, const char * typename)
+{
+ struct datatype * dt = NULL;
+
+ if( typename != NULL )
+ {
+ for( dt = type_hash_table[hash]; dt; dt = dt->next )
+ {
+ if( xtype != dt->type || dt->name == NULL
+ || dt->name[0] != typename[0])
+ {
+ continue;
+ }
+
+ if( strcmp(dt->name, typename) == 0 )
+ {
+ return dt;
+ }
+ }
+ }
+
+ return dt;
+}
+
struct datatype *
DEBUG_NewDataType(enum debug_type xtype, const char * typename)
{
@@ -195,22 +227,7 @@
hash = type_hash(typename);
}
- if( typename != NULL )
- {
- for( dt = type_hash_table[hash]; dt; dt = dt->next )
- {
- if( xtype != dt->type || dt->name == NULL
- || dt->name[0] != typename[0])
- {
- continue;
- }
-
- if( strcmp(dt->name, typename) == 0 )
- {
- return dt;
- }
- }
- }
+ dt = DEBUG_LookupDataType(xtype, hash, typename);
if( dt == NULL )
{
@@ -347,6 +364,11 @@
switch(addr->type->type)
{
case BASIC:
+ if (!DBG_CHECK_READ_PTR( addr, addr->type->un.basic.basic_size))
+ {
+ return 0;
+ }
+
memcpy(&rtn, (char *) addr->off, addr->type->un.basic.basic_size);
if( (addr->type->un.basic.b_signed)
&& ((addr->type->un.basic.basic_size & 3) != 0)
@@ -495,6 +517,12 @@
DEBUG_SetStructSize(struct datatype * dt, int size)
{
assert(dt->type == STRUCT);
+
+ if( dt->un.structure.members != NULL )
+ {
+ return FALSE;
+ }
+
dt->un.structure.size = size;
dt->un.structure.members = NULL;
@@ -710,7 +738,8 @@
*
* Implementation of the 'print' command.
*/
-void DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level )
+void
+DEBUG_Print( const DBG_ADDR *addr, int count, char format, int level )
{
DBG_ADDR addr1;
int i;
@@ -728,9 +757,20 @@
if( addr->type == NULL )
{
fprintf(stderr, "Unable to evaluate expression\n");
- return;
+ goto leave;
}
+ if( level == 0 )
+ {
+ DEBUG_nchar = 0;
+ }
+
+ if( DEBUG_nchar > DEBUG_maxchar )
+ {
+ fprintf(stderr, "...");
+ goto leave;
+ }
+
if( format == 'i' || format == 's' || format == 'w' || format == 'b' )
{
fprintf( stderr, "Format specifier '%c' is meaningless in 'print' command\n", format );
@@ -746,20 +786,25 @@
DEBUG_PrintBasic(addr, 1, format);
break;
case STRUCT:
- fprintf(stderr, "{");
+ DEBUG_nchar += fprintf(stderr, "{");
for(m = addr->type->un.structure.members; m; m = m->next)
{
addr1 = *addr;
DEBUG_FindStructElement(&addr1, m->name,
(int *) &value);
- fprintf(stderr, "%s=", m->name);
+ DEBUG_nchar += fprintf(stderr, "%s=", m->name);
DEBUG_Print(&addr1, 1, format, level + 1);
if( m->next != NULL )
{
- fprintf(stderr, ", ");
+ DEBUG_nchar += fprintf(stderr, ", ");
+ }
+ if( DEBUG_nchar > DEBUG_maxchar )
+ {
+ fprintf(stderr, "...}");
+ goto leave;
}
}
- fprintf(stderr, "}");
+ DEBUG_nchar += fprintf(stderr, "}");
break;
case ARRAY:
/*
@@ -772,28 +817,39 @@
* Special handling for character arrays.
*/
pnt = (char *) addr->off;
- fprintf(stderr, "\"");
+ DEBUG_nchar += fprintf(stderr, "\"");
for( i=addr->type->un.array.start; i < addr->type->un.array.end; i++ )
{
fputc(*pnt++, stderr);
+ DEBUG_nchar++;
+ if( DEBUG_nchar > DEBUG_maxchar )
+ {
+ fprintf(stderr, "...\"");
+ goto leave;
+ }
}
- fprintf(stderr, "\"");
+ DEBUG_nchar += fprintf(stderr, "\"");
break;
}
addr1 = *addr;
addr1.type = addr->type->un.array.basictype;
- fprintf(stderr, "{");
+ DEBUG_nchar += fprintf(stderr, "{");
for( i=addr->type->un.array.start; i <= addr->type->un.array.end; i++ )
{
DEBUG_Print(&addr1, 1, format, level + 1);
addr1.off += size;
if( i == addr->type->un.array.end )
{
- fprintf(stderr, "}");
+ DEBUG_nchar += fprintf(stderr, "}");
}
else
{
- fprintf(stderr, ", ");
+ DEBUG_nchar += fprintf(stderr, ", ");
+ }
+ if( DEBUG_nchar > DEBUG_maxchar )
+ {
+ fprintf(stderr, "...}");
+ goto leave;
}
}
break;
@@ -802,8 +858,157 @@
break;
}
+leave:
+
if( level == 0 )
{
- fprintf(stderr, "\n");
+ DEBUG_nchar += fprintf(stderr, "\n");
}
+ return;
}
+
+int
+DEBUG_DumpTypes()
+{
+ struct datatype * dt = NULL;
+ struct member * m;
+ int hash;
+ int nm;
+ char * name;
+ char * member_name;
+
+ for(hash = 0; hash < NR_TYPE_HASH + 1; hash++)
+ {
+ for( dt = type_hash_table[hash]; dt; dt = dt->next )
+ {
+ name = "none";
+ if( dt->name != NULL )
+ {
+ name = dt->name;
+ }
+ switch(dt->type)
+ {
+ case BASIC:
+ fprintf(stderr, "0x%p - BASIC(%s)\n",
+ dt, name);
+ break;
+ case POINTER:
+ fprintf(stderr, "0x%p - POINTER(%s)(%p)\n",
+ dt, name, dt->un.pointer.pointsto);
+ break;
+ case STRUCT:
+ member_name = "none";
+ nm = 0;
+ if( dt->un.structure.members != NULL
+ && dt->un.structure.members->name != NULL )
+ {
+ member_name = dt->un.structure.members->name;
+ for( m = dt->un.structure.members; m; m = m->next)
+ {
+ nm++;
+ }
+ }
+ fprintf(stderr, "0x%p - STRUCT(%s) %d %d %s\n", dt, name,
+ dt->un.structure.size, nm, member_name);
+ break;
+ case ARRAY:
+ fprintf(stderr, "0x%p - ARRAY(%s)(%p)\n",
+ dt, name, dt->un.array.basictype);
+ break;
+ case ENUM:
+ fprintf(stderr, "0x%p - ENUM(%s)\n",
+ dt, name);
+ break;
+ case BITFIELD:
+ fprintf(stderr, "0x%p - BITFIELD(%s)\n", dt, name);
+ break;
+ case FUNC:
+ fprintf(stderr, "0x%p - FUNC(%s)(%p)\n",
+ dt, name, dt->un.funct.rettype);
+ break;
+ case CONST:
+ case TYPEDEF:
+ fprintf(stderr, "What???\n");
+ break;
+ }
+ }
+ }
+ return TRUE;
+}
+
+
+enum debug_type DEBUG_GetType(struct datatype * dt)
+{
+ return dt->type;
+}
+
+struct datatype *
+DEBUG_TypeCast(enum debug_type type, const char * name)
+{
+ int hash;
+ struct datatype * rtn;
+
+ /*
+ * The last bucket is special, and is used to hold typeless names.
+ */
+ if( name == NULL )
+ {
+ hash = NR_TYPE_HASH;
+ }
+ else
+ {
+ hash = type_hash(name);
+ }
+
+ rtn = DEBUG_LookupDataType(type, hash, name);
+
+ return rtn;
+
+}
+
+int
+DEBUG_PrintTypeCast(struct datatype * dt)
+{
+ char * name;
+
+ name = "none";
+ if( dt->name != NULL )
+ {
+ name = dt->name;
+ }
+
+ switch(dt->type)
+ {
+ case BASIC:
+ fprintf(stderr, "%s", name);
+ break;
+ case POINTER:
+ DEBUG_PrintTypeCast(dt->un.pointer.pointsto);
+ fprintf(stderr, "*");
+ break;
+ case STRUCT:
+ fprintf(stderr, "struct %s", name);
+ break;
+ case ARRAY:
+ fprintf(stderr, "%s[]", name);
+ break;
+ case ENUM:
+ fprintf(stderr, "enum %s", name);
+ break;
+ case BITFIELD:
+ fprintf(stderr, "unsigned %s", name);
+ break;
+ case FUNC:
+ DEBUG_PrintTypeCast(dt->un.funct.rettype);
+ fprintf(stderr, "(*%s)()", name);
+ break;
+ case CONST:
+ case TYPEDEF:
+ fprintf(stderr, "What???\n");
+ break;
+ }
+
+ return TRUE;
+}
+
+