be_cpu.h 6.67 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * 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
18
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19 20 21 22
 */

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,
23
                     be_xpoint_watch_write, be_xpoint_free=-1};
24

25 26
struct gdb_register
{
27
    const char *feature;
28
    const char *name;
29
    const char *type;
30 31
    size_t      offset;
    size_t      length;
32 33
};

34 35
struct backend_cpu
{
36 37
    const DWORD         machine;
    const DWORD         pointer_size;
38 39 40 41
    /* ------------------------------------------------------------------------------
     * address manipulation
     * ------------------------------------------------------------------------------ */
    /* Linearizes an address. Only CPUs with segmented address model need this.
42
     * Otherwise, implementation is straightforward (be_cpu_linearize will do)
43
     */
44 45
    void*               (*linearize)(HANDLE hThread, const ADDRESS64*);
    /* Fills in an ADDRESS64 structure from a segment & an offset. CPUs without
46
     * segment address model should use 0 as seg. Required method to fill
47
     * in an ADDRESS64 (except an linear one).
48 49
     * Non segmented CPU shall use be_cpu_build_addr
     */
50
    BOOL                (*build_addr)(HANDLE hThread, const dbg_ctx_t *ctx,
51
                                      ADDRESS64* addr, unsigned seg,
52
                                      DWORD64 offset);
53 54 55
    /* Retrieves in addr an address related to the context (program counter, stack
     * pointer, frame pointer)
     */
56
    BOOL                (*get_addr)(HANDLE hThread, const dbg_ctx_t *ctx,
57
                                    enum be_cpu_addr, ADDRESS64* addr);
58 59

    /* returns which kind of information a given register number refers to */
60
    BOOL                (*get_register_info)(int regno, enum be_cpu_addr* kind);
61

62 63 64 65
    /* -------------------------------------------------------------------------------
     * context manipulation 
     * ------------------------------------------------------------------------------- */
    /* Enables/disables CPU single step mode (depending on enable) */
66
    void                (*single_step)(dbg_ctx_t *ctx, BOOL enable);
67
    /* Dumps out the content of the context */
68
    void                (*print_context)(HANDLE hThread, const dbg_ctx_t *ctx, int all_regs);
69 70 71
    /* Prints information about segments. Non segmented CPU should leave this
     * function empty
     */
72
    void                (*print_segment_info)(HANDLE hThread, const dbg_ctx_t *ctx);
73 74 75
    /* all the CONTEXT's relative variables, bound to this CPU */
    const struct dbg_internal_var* context_vars;

76 77 78 79 80 81
    /* -------------------------------------------------------------------------------
     * code inspection 
     * -------------------------------------------------------------------------------*/
    /* Check whether the instruction at addr is an insn to step over
     * (like function call, interruption...)
     */
82
    BOOL                (*is_step_over_insn)(const void* addr);
83
    /* Check whether instruction at 'addr' is the return from a function call */
84
    BOOL                (*is_function_return)(const void* addr);
85 86 87
    /* Check whether instruction at 'addr' is the CPU break instruction. On i386, 
     * it's INT3 (0xCC)
     */
88
    BOOL                (*is_break_insn)(const void*);
89
    /* Check whether instruction at 'addr' is a function call */
90
    BOOL                (*is_function_call)(const void* insn, ADDRESS64* callee);
91
    /* Check whether instruction at 'addr' is a jump */
92
    BOOL                (*is_jump)(const void* insn, ADDRESS64* jumpee);
93
    /* Ask for disassembling one instruction. If display is true, assembly code
94 95
     * will be printed. In all cases, 'addr' is advanced at next instruction
     */
96
    void                (*disasm_one_insn)(ADDRESS64* addr, int display);
97 98 99 100
    /* -------------------------------------------------------------------------------
     * break points / watchpoints handling 
     * -------------------------------------------------------------------------------*/
    /* Inserts an Xpoint in the CPU context and/or debuggee address space */
101
    BOOL                (*insert_Xpoint)(HANDLE hProcess, const struct be_process_io* pio,
102
                                         dbg_ctx_t *ctx, enum be_xpoint_type type,
103
                                         void* addr, unsigned *val, unsigned size);
104
    /* Removes an Xpoint in the CPU context and/or debuggee address space */
105
    BOOL                (*remove_Xpoint)(HANDLE hProcess, const struct be_process_io* pio,
106
                                         dbg_ctx_t *ctx, enum be_xpoint_type type,
107
                                         void* addr, unsigned val, unsigned size);
108
    /* Checks whether a given watchpoint has been triggered */
109
    BOOL                (*is_watchpoint_set)(const dbg_ctx_t *ctx, unsigned idx);
110
    /* Clears the watchpoint indicator */
111
    void                (*clear_watchpoint)(dbg_ctx_t *ctx, unsigned idx);
112 113 114 115 116
    /* 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.
     */
117
    int                 (*adjust_pc_for_break)(dbg_ctx_t *ctx, BOOL way);
118 119 120
    /* -------------------------------------------------------------------------------
     * basic type read/write 
     * -------------------------------------------------------------------------------*/
121
    BOOL                (*get_context)(HANDLE thread, dbg_ctx_t *ctx);
122
    BOOL                (*set_context)(HANDLE thread, const dbg_ctx_t *ctx);
123 124 125

    const struct gdb_register *gdb_register_map;
    const size_t gdb_num_regs;
126 127 128
};

/* some handy functions for non segmented CPUs */
129
void*    be_cpu_linearize(HANDLE hThread, const ADDRESS64*);
130
BOOL be_cpu_build_addr(HANDLE hThread, const dbg_ctx_t *ctx, ADDRESS64* addr,
131
                       unsigned seg, DWORD64 offset);