/*
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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
{
    /* ------------------------------------------------------------------------------
     * address manipulation
     * ------------------------------------------------------------------------------ */
    /* Linearizes an address. Only CPUs with segmented address model need this.
     * Otherwise, implementation is straigthforward (be_cpu_linearize will do)
     */
    void*               (*linearize)(HANDLE hThread, const ADDRESS*);
    /* Fills in an ADDRESS structure from a segment & an offset. CPUs without
     * segment address model should use 0 as seg. Required method to fill
     * in an ADDRESS (except an linear one).
     * Non segmented CPU shall use be_cpu_build_addr
     */
    unsigned            (*build_addr)(HANDLE hThread, const CONTEXT* ctx, 
                                      ADDRESS* 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, ADDRESS* addr);
    /* -------------------------------------------------------------------------------
     * 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 instruciton at 'addr' is a function call */
    unsigned            (*is_function_call)(const void* insn, ADDRESS* callee);
    /* Ask for dissasembling one instruction. If display is true, assembly code
     * will be printed. In all cases, 'addr' is advanced at next instruction
     */
    void                (*disasm_one_insn)(ADDRESS* 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 ADDRESS*);
unsigned be_cpu_build_addr(HANDLE hThread, const CONTEXT* ctx, ADDRESS* addr, 
                           unsigned seg, unsigned long offset);
