debugger.h 17.1 KB
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432
/*
 * Debugger definitions
 *
 * Copyright 1995 Alexandre Julliard
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __WINE_DEBUGGER_H
#define __WINE_DEBUGGER_H

#include <assert.h>
#include <stdarg.h>

#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#define WIN32_LEAN_AND_MEAN
#include "windef.h"
#include "winbase.h"
#include "ntstatus.h"
#include "winver.h"
#include "dbghelp.h"
#include "cvconst.h"
#include "objbase.h"
#include "oaidl.h"

/* the debugger uses these exceptions for it's internal use */
#define	DEBUG_STATUS_OFFSET		0x80003000
#define	DEBUG_STATUS_INTERNAL_ERROR	(DEBUG_STATUS_OFFSET+0) /* something went wrong */
#define	DEBUG_STATUS_NO_SYMBOL		(DEBUG_STATUS_OFFSET+1) /* no symbol found in lookup */
#define	DEBUG_STATUS_DIV_BY_ZERO	(DEBUG_STATUS_OFFSET+2)
#define	DEBUG_STATUS_BAD_TYPE		(DEBUG_STATUS_OFFSET+3) /* no type found, when type was expected */
#define DEBUG_STATUS_NO_FIELD		(DEBUG_STATUS_OFFSET+4) /* when dereferencing a struct, the field was not found */
#define DEBUG_STATUS_ABORT              (DEBUG_STATUS_OFFSET+5) /* user aborted on going action */
#define DEBUG_STATUS_CANT_DEREF         (DEBUG_STATUS_OFFSET+6) /* either not deref:able, or index out of bounds */
#define DEBUG_STATUS_NOT_AN_INTEGER     (DEBUG_STATUS_OFFSET+7) /* requiring an integral value */

/*
 * Return values for symbol_get_function_line_status.  Used to determine
 * what to do when the 'step' command is given.
 */
enum dbg_line_status
{
    dbg_no_line_info,
    dbg_not_on_a_line_number,
    dbg_on_a_line_number,
    dbg_in_a_thunk,
};

enum dbg_internal_types
{
    dbg_itype_first             = 0xffffff00,
    dbg_itype_unsigned_int,
    dbg_itype_signed_int,
    dbg_itype_signed_char_int,
    dbg_itype_unsigned_char_int,
    dbg_itype_unsigned_short_int,
    dbg_itype_signed_short_int,
    dbg_itype_unsigned_long_int,
    dbg_itype_signed_long_int,
    dbg_itype_unsigned_longlong_int,
    dbg_itype_signed_longlong_int,
    dbg_itype_char,
    dbg_itype_wchar,
    dbg_itype_short_real, /* aka float */
    dbg_itype_real,       /* aka double */
    dbg_itype_long_real,  /* aka long double */
    dbg_itype_astring,
    dbg_itype_ustring,
    dbg_itype_none              = 0xffffffff
};

/* type description (in the following order):
 * - if 'id' is dbg_itype_none (whatever 'module' value), the type isn't known
 * - if 'module' is 0, it's an internal type (id is one of dbg_itype...)
 * - if 'module' is non 0, then 'id' is a type ID referring to module (loaded in
 *   dbghelp) which (linear) contains address 'module'.
 */
struct dbg_type
{
    unsigned long       id;
    DWORD               module;
};

struct dbg_lvalue       /* structure to hold left-values... */
{
    int			cookie;	/* DLV_??? */
/* DLV_TARGET references an address in debuggee's address space, whereas DLV_HOST
 * references the winedbg's address space
 */
#	define	DLV_TARGET	0xF00D
#	define	DLV_HOST	0x50DA
    ADDRESS             addr;
    struct dbg_type     type;
};

enum dbg_exec_mode
{
    dbg_exec_cont,       		/* Continue execution */
    dbg_exec_step_over_line,  		/* Stepping over a call to next source line */
    dbg_exec_step_into_line,  		/* Step to next source line, stepping in if needed */
    dbg_exec_step_over_insn,  		/* Stepping over a call */
    dbg_exec_step_into_insn,  		/* Single-stepping an instruction */
    dbg_exec_finish,		        /* Single-step until we exit current frame */
#if 0
    EXEC_STEP_OVER_TRAMPOLINE, 	/* Step over trampoline.  Requires that we dig the real
                                 * return value off the stack and set breakpoint there - 
                                 * not at the instr just after the call.
				 */
#endif
};

extern char *arg_command;

struct dbg_breakpoint
{
    ADDRESS             addr;
    unsigned long       enabled : 1,
                        xpoint_type : 2,
                        refcount : 13,
                        skipcount : 16;
    DWORD               info;
    struct              /* only used for watchpoints */
    {
        BYTE		len : 2;
        DWORD		oldval;
    } w;
    struct expr*        condition;
};

/* Wine extension; Windows doesn't have a name for this code.  This is an
   undocumented exception understood by MS VC debugger, allowing the program
   to name a particular thread.  Search google.com or deja.com for "0x406d1388"
   for more info. */
#define EXCEPTION_NAME_THREAD               0x406D1388

/* Helper structure */
typedef struct tagTHREADNAME_INFO
{
   DWORD   dwType;     /* Must be 0x1000 */
   LPCTSTR szName;     /* Pointer to name - limited to 9 bytes (8 characters + terminator) */
   DWORD   dwThreadID; /* Thread ID (-1 = caller thread) */
   DWORD   dwFlags;    /* Reserved for future use.  Must be zero. */
} THREADNAME_INFO;

struct dbg_thread
{
    struct dbg_process* 	process;
    HANDLE			handle;
    DWORD			tid;
    void*			teb;
    enum dbg_exec_mode          exec_mode;      /* mode the thread is run (step/run...) */
    int			        exec_count;     /* count of mode operations */
    ADDRESS_MODE	        addr_mode;      /* mode */
    struct dbg_breakpoint	step_over_bp;
    char                        name[9];
    struct dbg_thread*   	next;
    struct dbg_thread*   	prev;
    BOOL                        in_exception;   /* TRUE if thread stopped with an exception */
    EXCEPTION_RECORD            excpt_record;   /* only valid when in_exception is TRUE */
};

struct dbg_delayed_bp
{
    BOOL                        is_symbol;
    union
    {
        struct
        {
            int				lineno;
            char*			name;
        } symbol;
        ADDRESS                 addr;
    } u;
};

#define MAX_BREAKPOINTS 100
struct dbg_process
{
    HANDLE			handle;
    DWORD			pid;
    struct be_process_io*       process_io;
    const char*			imageName;
    struct dbg_thread*  	threads;
    unsigned			continue_on_first_exception;
    struct dbg_breakpoint       bp[MAX_BREAKPOINTS];
    unsigned                    next_bp;
    struct dbg_delayed_bp*      delayed_bp;
    int				num_delayed_bp;
    struct dbg_process* 	next;
    struct dbg_process* 	prev;
};

/* describes the way the debugger interacts with a given process */
struct be_process_io
{
    BOOL        (WINAPI *read)(HANDLE, const void*, void*, DWORD, DWORD*);
    BOOL        (WINAPI *write)(HANDLE, void*, const void*, DWORD, DWORD*);
};

extern	struct dbg_process*	dbg_curr_process;
extern	DWORD		        dbg_curr_pid;
extern	struct dbg_thread*	dbg_curr_thread;
extern	DWORD		        dbg_curr_tid;
extern  CONTEXT 	        dbg_context;
extern  BOOL                    dbg_interactiveP;
extern  int                     dbg_curr_frame;

struct dbg_internal_var
{
    DWORD		        val;
    const char*		        name;
    LPDWORD		        pval;
    unsigned long               typeid; /* always internal type */
};

enum sym_get_lval {sglv_found, sglv_unknown, sglv_aborted};

enum type_expr_e
{
    type_expr_type_id,
    type_expr_udt_class,
    type_expr_udt_struct,
    type_expr_udt_union,
    type_expr_enumeration
};

struct type_expr_t
{ 
    enum type_expr_e    type;
    unsigned            deref_count;
    union
    {
        struct dbg_type type;
        const char*     name;
    } u;
};

  /* break.c */
extern void             break_set_xpoints(BOOL set);
extern BOOL             break_add_break(const ADDRESS* addr, BOOL verbose);
extern BOOL             break_add_break_from_lvalue(const struct dbg_lvalue* value);
extern void             break_add_break_from_id(const char* name, int lineno);
extern void             break_add_break_from_lineno(int lineno);
extern void             break_add_watch_from_lvalue(const struct dbg_lvalue* lvalue);
extern void             break_add_watch_from_id(const char* name);
extern void             break_check_delayed_bp(void);
extern void             break_delete_xpoint(int num);
extern void             break_delete_xpoints_from_module(unsigned long base);
extern void             break_enable_xpoint(int num, BOOL enable);
extern void             break_info(void);
extern BOOL             break_should_continue(ADDRESS* addr, DWORD code, int* count, BOOL* is_break);
extern void             break_suspend_execution(void);
extern void             break_restart_execution(int count);
extern int              break_add_condition(int bpnum, struct expr* exp);

  /* dbg.y */
extern void             parser(const char*);
extern int              input_read_line(const char* pfx, char* buffer, int size);
extern int              input_fetch_entire_line(const char* pfx, char** line, size_t* alloc, BOOL check_nl);

  /* debug.l */
extern void             lexeme_flush(void);
extern char*            lexeme_alloc(const char*);
extern char*            lexeme_alloc_size(int);

  /* display.c */
extern int              display_print(void);
extern int              display_add(struct expr* exp, int count, char format);
extern int              display_delete(int displaynum);
extern int              display_info(void);
extern int              display_enable(int displaynum, int enable);

  /* expr.c */
extern void             expr_free_all(void);
extern struct expr*     expr_alloc_internal_var(const char* name);
extern struct expr*     expr_alloc_symbol(const char* name);
extern struct expr*     expr_alloc_sconstant(int val);
extern struct expr*     expr_alloc_uconstant(unsigned val);
extern struct expr*     expr_alloc_string(const char* str);
extern struct expr*     expr_alloc_binary_op(int oper, struct expr*, struct expr*);
extern struct expr*     expr_alloc_unary_op(int oper, struct expr*);
extern struct expr*     expr_alloc_pstruct(struct expr*, const char* element);
extern struct expr*     expr_alloc_struct(struct expr*, const char* element);
extern struct expr*     expr_alloc_func_call(const char*, int nargs, ...);
extern struct expr*     expr_alloc_typecast(struct type_expr_t*, struct expr*);
extern struct dbg_lvalue expr_eval(struct expr*);
extern struct expr*     expr_clone(const struct expr* exp, unsigned* local_binding);
extern int              expr_free(struct expr* exp);
extern int              expr_print(const struct expr* exp);

  /* info.c */
extern void             print_help(void);
extern void             info_help(void);
extern void             info_win32_module(DWORD mod);
extern void             info_win32_class(HWND hWnd, const char* clsName);
extern void             info_win32_window(HWND hWnd, BOOL detailed);
extern void             info_win32_processes(void);
extern void             info_win32_threads(void);
extern void             info_win32_exceptions(DWORD tid);
extern void             info_win32_virtual(DWORD pid);
extern void             info_win32_segments(DWORD start, int length);
extern void             info_wine_dbg_channel(BOOL add, const char* chnl, const char* name);

  /* memory.c */
extern BOOL             memory_read_value(const struct dbg_lvalue* lvalue, DWORD size, void* result);
extern BOOL             memory_write_value(const struct dbg_lvalue* val, DWORD size, void* value);
extern void             memory_examine(const struct dbg_lvalue *lvalue, int count, char format);
extern void*            memory_to_linear_addr(const ADDRESS* address);
extern BOOL             memory_get_current_pc(ADDRESS* address);
extern BOOL             memory_get_current_stack(ADDRESS* address);
extern BOOL             memory_get_current_frame(ADDRESS* address);
extern BOOL             memory_get_string(struct dbg_process* pcs, void* addr, BOOL in_debuggee, BOOL unicode, char* buffer, int size);
extern BOOL             memory_get_string_indirect(struct dbg_process* pcs, void* addr, BOOL unicode, char* buffer, int size);
extern void             memory_disassemble(const struct dbg_lvalue*, const struct dbg_lvalue*, int instruction_count);
extern BOOL             memory_disasm_one_insn(ADDRESS* addr);
extern void             print_bare_address(const ADDRESS* addr);
extern void             print_address(const ADDRESS* addr, BOOLEAN with_line);
extern void             print_addr_and_args(const ADDRESS* pc, const ADDRESS* frame);
extern void             print_basic(const struct dbg_lvalue* value, int count, char format);

  /* source.c */
extern void             source_list(IMAGEHLP_LINE* src1, IMAGEHLP_LINE* src2, int delta);
extern void             source_list_from_addr(const ADDRESS* addr, int nlines);
extern void             source_show_path(void);
extern void             source_add_path(const char* path);
extern void             source_nuke_path(void);

  /* stack.c */
extern void             stack_info(void);
extern void             stack_backtrace(DWORD threadID, BOOL noisy);
extern int              stack_set_frame(int newframe);
extern BOOL             stack_get_frame(SYMBOL_INFO* sym, IMAGEHLP_STACK_FRAME* ihsf);

  /* symbol.c */
extern enum sym_get_lval symbol_get_lvalue(const char* name, const int lineno, struct dbg_lvalue* addr, BOOL bp_disp);
extern void             symbol_read_symtable(const char* filename, unsigned long offset);
extern enum dbg_line_status symbol_get_function_line_status(const ADDRESS* addr);
extern BOOL             symbol_get_line(const char* filename, const char* func, IMAGEHLP_LINE* ret);
extern void             symbol_info(const char* str);
extern int              symbol_info_locals(void);
extern BOOL             symbol_is_local(const char* name);

  /* tgt_minidump.c */
extern void             minidump_write(const char*, const EXCEPTION_RECORD*);

  /* types.c */
extern void             print_value(const struct dbg_lvalue* addr, char format, int level);
extern int              types_print_type(const struct dbg_type*, BOOL details);
extern int              print_types(void);
extern long int         types_extract_as_integer(const struct dbg_lvalue*);
extern BOOL             types_deref(const struct dbg_lvalue* value, struct dbg_lvalue* result);
extern BOOL             types_udt_find_element(struct dbg_lvalue* value, const char* name, long int* tmpbuf);
extern BOOL             types_array_index(const struct dbg_lvalue* value, int index, struct dbg_lvalue* result);
extern BOOL             types_get_info(const struct dbg_type*, IMAGEHLP_SYMBOL_TYPE_INFO, void*);
extern struct dbg_type  types_find_pointer(const struct dbg_type* type);
extern struct dbg_type  types_find_type(unsigned long linear, const char* name, enum SymTagEnum tag);

  /* winedbg.c */
extern void	        dbg_outputA(const char* buffer, int len);
extern void	        dbg_outputW(const WCHAR* buffer, int len);
#ifdef __GNUC__
extern int	        dbg_printf(const char* format, ...) __attribute__((format (printf,1,2)));
#else
extern int	        dbg_printf(const char* format, ...);
#endif
extern const struct dbg_internal_var* dbg_get_internal_var(const char*);
extern BOOL             dbg_attach_debuggee(DWORD pid, BOOL cofe, BOOL wfe);
extern BOOL             dbg_detach_debuggee(void);
extern BOOL             dbg_interrupt_debuggee(void);
extern void             dbg_run_debuggee(const char* args);
extern struct dbg_process* dbg_add_process(DWORD pid, HANDLE h);
extern void             dbg_set_process_name(struct dbg_process* p, const char* name);
extern struct dbg_process* dbg_get_process(DWORD pid);
extern void             dbg_del_process(struct dbg_process* p);
struct dbg_thread*	dbg_add_thread(struct dbg_process* p, DWORD tid, HANDLE h, void* teb);
extern struct dbg_thread* dbg_get_thread(struct dbg_process* p, DWORD tid);
extern void             dbg_del_thread(struct dbg_thread* t);
extern void             dbg_wait_next_exception(DWORD cont, int count, int mode);
extern BOOL             dbg_get_debuggee_info(HANDLE hProcess, IMAGEHLP_MODULE* imh_mod);

/* gdbproxy.c */
extern BOOL             gdb_remote(unsigned int);

static inline BOOL dbg_read_memory(const void* addr, void* buffer, size_t len)
{
    DWORD rlen;
    return ReadProcessMemory(dbg_curr_process->handle, addr, buffer, len, &rlen) && len == rlen;
}

static inline BOOL dbg_write_memory(void* addr, const void* buffer, size_t len)
{
    DWORD wlen;
    return WriteProcessMemory(dbg_curr_process->handle, addr, buffer, len, &wlen) && len == wlen;
}

static inline void* dbg_heap_realloc(void* buffer, size_t size)
{
    return (buffer) ? HeapReAlloc(GetProcessHeap(), 0, buffer, size) :
        HeapAlloc(GetProcessHeap(), 0, size);
}

extern struct dbg_internal_var          dbg_internal_vars[];
extern const struct dbg_internal_var*   dbg_context_vars;

#define  DBG_IVARNAME(_var)	dbg_internal_var_##_var
#define  DBG_IVARSTRUCT(_var)	dbg_internal_vars[DBG_IVARNAME(_var)]
#define  DBG_IVAR(_var)		(*(DBG_IVARSTRUCT(_var).pval))
#define  INTERNAL_VAR(_var,_val,_ref,itype) DBG_IVARNAME(_var),
enum debug_int_var
{
#include "intvar.h"
   DBG_IV_LAST
};
#undef   INTERNAL_VAR

/* include CPU dependent bits */
#include "be_cpu.h"

#endif  /* __WINE_DEBUGGER_H */