/*
 * 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);
    /* 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, 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, 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, long long int*);
    /* 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);
