2004-06-04 02:59:16 +02:00
|
|
|
/*
|
|
|
|
* Debugger CPU backend definitions
|
|
|
|
*
|
|
|
|
* Copyright 2004 Eric Pouech
|
|
|
|
*
|
|
|
|
* 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
|
2006-05-18 14:49:52 +02:00
|
|
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
2004-06-04 02:59:16 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
enum be_cpu_addr {be_cpu_addr_pc, be_cpu_addr_stack, be_cpu_addr_frame};
|
|
|
|
enum be_xpoint_type {be_xpoint_break, be_xpoint_watch_exec, be_xpoint_watch_read,
|
2018-02-02 13:11:26 +01:00
|
|
|
be_xpoint_watch_write, be_xpoint_free=-1};
|
2018-06-13 02:01:50 +02:00
|
|
|
|
2018-06-13 23:34:01 +02:00
|
|
|
struct gdb_register
|
|
|
|
{
|
2020-04-03 15:35:47 +02:00
|
|
|
const char *feature;
|
2020-04-03 15:35:48 +02:00
|
|
|
const char *name;
|
2020-04-03 15:35:49 +02:00
|
|
|
const char *type;
|
2020-04-03 15:35:51 +02:00
|
|
|
size_t offset;
|
|
|
|
size_t length;
|
2018-06-13 23:34:01 +02:00
|
|
|
};
|
|
|
|
|
2004-06-04 02:59:16 +02:00
|
|
|
struct backend_cpu
|
|
|
|
{
|
2010-04-12 21:18:18 +02:00
|
|
|
const DWORD machine;
|
|
|
|
const DWORD pointer_size;
|
2004-06-04 02:59:16 +02:00
|
|
|
/* ------------------------------------------------------------------------------
|
|
|
|
* address manipulation
|
|
|
|
* ------------------------------------------------------------------------------ */
|
|
|
|
/* Linearizes an address. Only CPUs with segmented address model need this.
|
2008-04-07 13:01:02 +02:00
|
|
|
* Otherwise, implementation is straightforward (be_cpu_linearize will do)
|
2004-06-04 02:59:16 +02:00
|
|
|
*/
|
2006-07-26 11:57:27 +02:00
|
|
|
void* (*linearize)(HANDLE hThread, const ADDRESS64*);
|
|
|
|
/* Fills in an ADDRESS64 structure from a segment & an offset. CPUs without
|
2004-06-04 02:59:16 +02:00
|
|
|
* segment address model should use 0 as seg. Required method to fill
|
2006-07-26 11:57:27 +02:00
|
|
|
* in an ADDRESS64 (except an linear one).
|
2004-06-04 02:59:16 +02:00
|
|
|
* Non segmented CPU shall use be_cpu_build_addr
|
|
|
|
*/
|
2018-06-13 00:53:18 +02:00
|
|
|
BOOL (*build_addr)(HANDLE hThread, const dbg_ctx_t *ctx,
|
2006-07-26 11:57:27 +02:00
|
|
|
ADDRESS64* addr, unsigned seg,
|
2021-10-04 14:16:23 +02:00
|
|
|
DWORD64 offset);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* Retrieves in addr an address related to the context (program counter, stack
|
|
|
|
* pointer, frame pointer)
|
|
|
|
*/
|
2018-06-13 00:53:18 +02:00
|
|
|
BOOL (*get_addr)(HANDLE hThread, const dbg_ctx_t *ctx,
|
2006-07-26 11:57:27 +02:00
|
|
|
enum be_cpu_addr, ADDRESS64* addr);
|
2006-12-02 17:43:08 +01:00
|
|
|
|
|
|
|
/* returns which kind of information a given register number refers to */
|
2013-11-14 03:53:02 +01:00
|
|
|
BOOL (*get_register_info)(int regno, enum be_cpu_addr* kind);
|
2006-12-02 17:43:08 +01:00
|
|
|
|
2004-06-04 02:59:16 +02:00
|
|
|
/* -------------------------------------------------------------------------------
|
|
|
|
* context manipulation
|
|
|
|
* ------------------------------------------------------------------------------- */
|
|
|
|
/* Enables/disables CPU single step mode (depending on enable) */
|
2018-06-13 00:53:18 +02:00
|
|
|
void (*single_step)(dbg_ctx_t *ctx, BOOL enable);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* Dumps out the content of the context */
|
2018-06-13 00:53:18 +02:00
|
|
|
void (*print_context)(HANDLE hThread, const dbg_ctx_t *ctx, int all_regs);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* Prints information about segments. Non segmented CPU should leave this
|
|
|
|
* function empty
|
|
|
|
*/
|
2018-06-13 00:53:18 +02:00
|
|
|
void (*print_segment_info)(HANDLE hThread, const dbg_ctx_t *ctx);
|
2010-03-27 09:08:20 +01:00
|
|
|
/* all the CONTEXT's relative variables, bound to this CPU */
|
|
|
|
const struct dbg_internal_var* context_vars;
|
|
|
|
|
2004-06-04 02:59:16 +02:00
|
|
|
/* -------------------------------------------------------------------------------
|
|
|
|
* code inspection
|
|
|
|
* -------------------------------------------------------------------------------*/
|
|
|
|
/* Check whether the instruction at addr is an insn to step over
|
|
|
|
* (like function call, interruption...)
|
|
|
|
*/
|
2013-11-14 03:53:02 +01:00
|
|
|
BOOL (*is_step_over_insn)(const void* addr);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* Check whether instruction at 'addr' is the return from a function call */
|
2013-11-14 03:53:02 +01:00
|
|
|
BOOL (*is_function_return)(const void* addr);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* Check whether instruction at 'addr' is the CPU break instruction. On i386,
|
|
|
|
* it's INT3 (0xCC)
|
|
|
|
*/
|
2013-11-14 03:53:02 +01:00
|
|
|
BOOL (*is_break_insn)(const void*);
|
2008-04-07 13:01:02 +02:00
|
|
|
/* Check whether instruction at 'addr' is a function call */
|
2013-11-14 03:53:02 +01:00
|
|
|
BOOL (*is_function_call)(const void* insn, ADDRESS64* callee);
|
2011-01-08 14:08:56 +01:00
|
|
|
/* Check whether instruction at 'addr' is a jump */
|
2013-11-14 03:53:02 +01:00
|
|
|
BOOL (*is_jump)(const void* insn, ADDRESS64* jumpee);
|
2008-04-07 13:01:02 +02:00
|
|
|
/* Ask for disassembling one instruction. If display is true, assembly code
|
2004-06-04 02:59:16 +02:00
|
|
|
* will be printed. In all cases, 'addr' is advanced at next instruction
|
|
|
|
*/
|
2006-07-26 11:57:27 +02:00
|
|
|
void (*disasm_one_insn)(ADDRESS64* addr, int display);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* -------------------------------------------------------------------------------
|
|
|
|
* break points / watchpoints handling
|
|
|
|
* -------------------------------------------------------------------------------*/
|
|
|
|
/* Inserts an Xpoint in the CPU context and/or debuggee address space */
|
2013-11-14 03:53:02 +01:00
|
|
|
BOOL (*insert_Xpoint)(HANDLE hProcess, const struct be_process_io* pio,
|
2018-06-13 00:53:18 +02:00
|
|
|
dbg_ctx_t *ctx, enum be_xpoint_type type,
|
2021-10-04 14:16:23 +02:00
|
|
|
void* addr, unsigned *val, unsigned size);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* Removes an Xpoint in the CPU context and/or debuggee address space */
|
2013-11-14 03:53:02 +01:00
|
|
|
BOOL (*remove_Xpoint)(HANDLE hProcess, const struct be_process_io* pio,
|
2018-06-13 00:53:18 +02:00
|
|
|
dbg_ctx_t *ctx, enum be_xpoint_type type,
|
2021-10-04 14:16:23 +02:00
|
|
|
void* addr, unsigned val, unsigned size);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* Checks whether a given watchpoint has been triggered */
|
2018-06-13 00:53:18 +02:00
|
|
|
BOOL (*is_watchpoint_set)(const dbg_ctx_t *ctx, unsigned idx);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* Clears the watchpoint indicator */
|
2018-06-13 00:53:18 +02:00
|
|
|
void (*clear_watchpoint)(dbg_ctx_t *ctx, unsigned idx);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* After a break instruction is executed, in the corresponding exception handler,
|
|
|
|
* some CPUs report the address of the insn after the break insn, some others
|
|
|
|
* report the address of the break insn itself.
|
|
|
|
* This function lets adjust the context PC to reflect this behavior.
|
|
|
|
*/
|
2018-06-13 00:53:18 +02:00
|
|
|
int (*adjust_pc_for_break)(dbg_ctx_t *ctx, BOOL way);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* -------------------------------------------------------------------------------
|
|
|
|
* basic type read/write
|
|
|
|
* -------------------------------------------------------------------------------*/
|
|
|
|
/* Reads an integer from memory and stores it inside a long long int */
|
2013-11-14 03:53:02 +01:00
|
|
|
BOOL (*fetch_integer)(const struct dbg_lvalue* lvalue, unsigned size, BOOL is_signed, LONGLONG*);
|
2004-06-04 02:59:16 +02:00
|
|
|
/* Reads a real from memory and stores it inside a long double */
|
2021-10-04 15:00:20 +02:00
|
|
|
BOOL (*fetch_float)(const struct dbg_lvalue* lvalue, unsigned size, double*);
|
2012-04-04 22:30:38 +02:00
|
|
|
/* Writes an integer to memory */
|
2013-11-14 03:53:02 +01:00
|
|
|
BOOL (*store_integer)(const struct dbg_lvalue* lvalue, unsigned size, BOOL is_signed, LONGLONG);
|
2018-06-13 02:01:50 +02:00
|
|
|
|
|
|
|
BOOL (*get_context)(HANDLE thread, dbg_ctx_t *ctx);
|
2018-06-13 00:53:20 +02:00
|
|
|
BOOL (*set_context)(HANDLE thread, const dbg_ctx_t *ctx);
|
2018-06-13 23:34:01 +02:00
|
|
|
|
|
|
|
const struct gdb_register *gdb_register_map;
|
|
|
|
const size_t gdb_num_regs;
|
2004-06-04 02:59:16 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
/* some handy functions for non segmented CPUs */
|
2006-07-26 11:57:27 +02:00
|
|
|
void* be_cpu_linearize(HANDLE hThread, const ADDRESS64*);
|
2018-06-13 00:53:18 +02:00
|
|
|
BOOL be_cpu_build_addr(HANDLE hThread, const dbg_ctx_t *ctx, ADDRESS64* addr,
|
2021-10-04 14:16:23 +02:00
|
|
|
unsigned seg, DWORD64 offset);
|