/*
 * 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
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

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,
                     be_xpoint_watch_write};
struct backend_cpu
{
    DWORD               machine;
    /* ------------------------------------------------------------------------------
     * address manipulation
     * ------------------------------------------------------------------------------ */
    /* Linearizes an address. Only CPUs with segmented address model need this.
     * Otherwise, implementation is straightforward (be_cpu_linearize will do)
     */
    void*               (*linearize)(HANDLE hThread, const ADDRESS64*);
    /* Fills in an ADDRESS64 structure from a segment & an offset. CPUs without
     * segment address model should use 0 as seg. Required method to fill
     * in an ADDRESS64 (except an linear one).
     * Non segmented CPU shall use be_cpu_build_addr
     */
    unsigned            (*build_addr)(HANDLE hThread, const CONTEXT* ctx, 
                                      ADDRESS64* addr, unsigned seg,
                                      unsigned long offset);
    /* Retrieves in addr an address related to the context (program counter, stack
     * pointer, frame pointer)
     */
    unsigned            (*get_addr)(HANDLE hThread, const CONTEXT* ctx, 
                                    enum be_cpu_addr, ADDRESS64* addr);

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

    /* -------------------------------------------------------------------------------
     * context manipulation 
     * ------------------------------------------------------------------------------- */
    /* Enables/disables CPU single step mode (depending on enable) */
    void                (*single_step)(CONTEXT* ctx, unsigned enable);
    /* Dumps out the content of the context */
    void                (*print_context)(HANDLE hThread, const CONTEXT* ctx, int all_regs);
    /* Prints information about segments. Non segmented CPU should leave this
     * function empty
     */
    void                (*print_segment_info)(HANDLE hThread, const CONTEXT* ctx);
    /* Do the initialization so that the debugger has internal variables linked
     * to the context's registers
     */
    const struct dbg_internal_var*
                        (*init_registers)(CONTEXT* ctx);
    /* -------------------------------------------------------------------------------
     * code inspection 
     * -------------------------------------------------------------------------------*/
    /* Check whether the instruction at addr is an insn to step over
     * (like function call, interruption...)
     */
    unsigned            (*is_step_over_insn)(const void* addr);
    /* Check whether instruction at 'addr' is the return from a function call */
    unsigned            (*is_function_return)(const void* addr);
    /* Check whether instruction at 'addr' is the CPU break instruction. On i386, 
     * it's INT3 (0xCC)
     */
    unsigned            (*is_break_insn)(const void*);
    /* Check whether instruction at 'addr' is a function call */
    unsigned            (*is_function_call)(const void* insn, ADDRESS64* callee);
    /* Ask for disassembling one instruction. If display is true, assembly code
     * will be printed. In all cases, 'addr' is advanced at next instruction
     */
    void                (*disasm_one_insn)(ADDRESS64* addr, int display);
    /* -------------------------------------------------------------------------------
     * break points / watchpoints handling 
     * -------------------------------------------------------------------------------*/
    /* Inserts an Xpoint in the CPU context and/or debuggee address space */
    unsigned            (*insert_Xpoint)(HANDLE hProcess, const struct be_process_io* pio,
                                         CONTEXT* ctx, enum be_xpoint_type type,
                                         void* addr, unsigned long* val, unsigned size);
    /* Removes an Xpoint in the CPU context and/or debuggee address space */
    unsigned            (*remove_Xpoint)(HANDLE hProcess, const struct be_process_io* pio,
                                         CONTEXT* ctx, enum be_xpoint_type type,
                                         void* addr, unsigned long val, unsigned size);
    /* Checks whether a given watchpoint has been triggered */
    unsigned            (*is_watchpoint_set)(const CONTEXT* ctx, unsigned idx);
    /* Clears the watchpoint indicator */
    void                (*clear_watchpoint)(CONTEXT* ctx, unsigned idx);
    /* 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.
     */
    int                 (*adjust_pc_for_break)(CONTEXT* ctx, BOOL way);
    /* -------------------------------------------------------------------------------
     * basic type read/write 
     * -------------------------------------------------------------------------------*/
    /* Reads an integer from memory and stores it inside a long long int */
    int                 (*fetch_integer)(const struct dbg_lvalue* lvalue, unsigned size, unsigned is_signed, LONGLONG*);
    /* Reads a real from memory and stores it inside a long double */
    int                 (*fetch_float)(const struct dbg_lvalue* lvalue, unsigned size, long double*);
};

extern struct backend_cpu*      be_cpu;

/* some handy functions for non segmented CPUs */
void*    be_cpu_linearize(HANDLE hThread, const ADDRESS64*);
unsigned be_cpu_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS64* addr, 
                           unsigned seg, unsigned long offset);
