winedbg: Implement float fetching for x86-64 debugger.
[wine] / programs / winedbg / be_cpu.h
1 /*
2  * Debugger CPU backend definitions
3  *
4  * Copyright 2004 Eric Pouech
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * 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 enum be_cpu_addr {be_cpu_addr_pc, be_cpu_addr_stack, be_cpu_addr_frame};
22 enum be_xpoint_type {be_xpoint_break, be_xpoint_watch_exec, be_xpoint_watch_read,
23                      be_xpoint_watch_write};
24 struct backend_cpu
25 {
26     DWORD               machine;
27     /* ------------------------------------------------------------------------------
28      * address manipulation
29      * ------------------------------------------------------------------------------ */
30     /* Linearizes an address. Only CPUs with segmented address model need this.
31      * Otherwise, implementation is straightforward (be_cpu_linearize will do)
32      */
33     void*               (*linearize)(HANDLE hThread, const ADDRESS64*);
34     /* Fills in an ADDRESS64 structure from a segment & an offset. CPUs without
35      * segment address model should use 0 as seg. Required method to fill
36      * in an ADDRESS64 (except an linear one).
37      * Non segmented CPU shall use be_cpu_build_addr
38      */
39     unsigned            (*build_addr)(HANDLE hThread, const CONTEXT* ctx, 
40                                       ADDRESS64* addr, unsigned seg,
41                                       unsigned long offset);
42     /* Retrieves in addr an address related to the context (program counter, stack
43      * pointer, frame pointer)
44      */
45     unsigned            (*get_addr)(HANDLE hThread, const CONTEXT* ctx, 
46                                     enum be_cpu_addr, ADDRESS64* addr);
47
48     /* returns which kind of information a given register number refers to */
49     unsigned            (*get_register_info)(int regno, enum be_cpu_addr* kind);
50
51     /* -------------------------------------------------------------------------------
52      * context manipulation 
53      * ------------------------------------------------------------------------------- */
54     /* Enables/disables CPU single step mode (depending on enable) */
55     void                (*single_step)(CONTEXT* ctx, unsigned enable);
56     /* Dumps out the content of the context */
57     void                (*print_context)(HANDLE hThread, const CONTEXT* ctx, int all_regs);
58     /* Prints information about segments. Non segmented CPU should leave this
59      * function empty
60      */
61     void                (*print_segment_info)(HANDLE hThread, const CONTEXT* ctx);
62     /* Do the initialization so that the debugger has internal variables linked
63      * to the context's registers
64      */
65     const struct dbg_internal_var*
66                         (*init_registers)(CONTEXT* ctx);
67     /* -------------------------------------------------------------------------------
68      * code inspection 
69      * -------------------------------------------------------------------------------*/
70     /* Check whether the instruction at addr is an insn to step over
71      * (like function call, interruption...)
72      */
73     unsigned            (*is_step_over_insn)(const void* addr);
74     /* Check whether instruction at 'addr' is the return from a function call */
75     unsigned            (*is_function_return)(const void* addr);
76     /* Check whether instruction at 'addr' is the CPU break instruction. On i386, 
77      * it's INT3 (0xCC)
78      */
79     unsigned            (*is_break_insn)(const void*);
80     /* Check whether instruction at 'addr' is a function call */
81     unsigned            (*is_function_call)(const void* insn, ADDRESS64* callee);
82     /* Ask for disassembling one instruction. If display is true, assembly code
83      * will be printed. In all cases, 'addr' is advanced at next instruction
84      */
85     void                (*disasm_one_insn)(ADDRESS64* addr, int display);
86     /* -------------------------------------------------------------------------------
87      * break points / watchpoints handling 
88      * -------------------------------------------------------------------------------*/
89     /* Inserts an Xpoint in the CPU context and/or debuggee address space */
90     unsigned            (*insert_Xpoint)(HANDLE hProcess, const struct be_process_io* pio,
91                                          CONTEXT* ctx, enum be_xpoint_type type,
92                                          void* addr, unsigned long* val, unsigned size);
93     /* Removes an Xpoint in the CPU context and/or debuggee address space */
94     unsigned            (*remove_Xpoint)(HANDLE hProcess, const struct be_process_io* pio,
95                                          CONTEXT* ctx, enum be_xpoint_type type,
96                                          void* addr, unsigned long val, unsigned size);
97     /* Checks whether a given watchpoint has been triggered */
98     unsigned            (*is_watchpoint_set)(const CONTEXT* ctx, unsigned idx);
99     /* Clears the watchpoint indicator */
100     void                (*clear_watchpoint)(CONTEXT* ctx, unsigned idx);
101     /* After a break instruction is executed, in the corresponding exception handler,
102      * some CPUs report the address of the insn after the break insn, some others 
103      * report the address of the break insn itself.
104      * This function lets adjust the context PC to reflect this behavior.
105      */
106     int                 (*adjust_pc_for_break)(CONTEXT* ctx, BOOL way);
107     /* -------------------------------------------------------------------------------
108      * basic type read/write 
109      * -------------------------------------------------------------------------------*/
110     /* Reads an integer from memory and stores it inside a long long int */
111     int                 (*fetch_integer)(const struct dbg_lvalue* lvalue, unsigned size, unsigned is_signed, LONGLONG*);
112     /* Reads a real from memory and stores it inside a long double */
113     int                 (*fetch_float)(const struct dbg_lvalue* lvalue, unsigned size, long double*);
114 };
115
116 extern struct backend_cpu*      be_cpu;
117
118 /* some handy functions for non segmented CPUs */
119 void*    be_cpu_linearize(HANDLE hThread, const ADDRESS64*);
120 unsigned be_cpu_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* addr, 
121                            unsigned seg, unsigned long offset);