/*
 *      Interactive disassembler (IDA).
 *      Copyright (c) 1990-98 by Ilfak Guilfanov.
 *      ALL RIGHTS RESERVED.
 *                              E-mail: ig@estar.msk.su, ig@datarescue.com
 *                              FIDO:   2:5020/209
 *
 */

#ifndef _IDD_HPP
#define _IDD_HPP
#pragma pack(push, 1)           // IDA uses 1 byte alignments!

//
//      This file contains definition of the interface to IDD modules
//      The interface consists of structures describing the target
//      debugged processor and a debugging API.


//      Versions history:
// 1    24.10.02        Initial version

#define         IDD_INTERFACE_VERSION   1


//====================================================================
//
//                       Process and Threads
//

typedef int process_id_t;
typedef int thread_id_t;

#define PROCESS_NO_THREAD   0xFFFFFFFF // No Thread
                                       // in PROCESS_START this value
                                       // can be used to specify that
                                       // the main thread has not been created
                                       // It will be initializated later
                                       // by a THREAD_START event.

struct process_info_t
{
  process_id_t process_id;
  char name[MAXSTR];
};

//====================================================================
//
//                          Registers
//

typedef unsigned char register_class_t; // Each register is associated to
                                        // a register class.
                                        // example: "segment", "mmx", ...

struct register_info_t
{
  char *name;                         // Register full name
  ulong flags;                        // Register special features
#define REGISTER_READONLY 0x0001      //   the user can't modify the current value of this register
#define REGISTER_IP       0x0002      //   instruction pointer
#define REGISTER_SP       0x0004      //   stack pointer
#define REGISTER_FP       0x0008      //   frame pointer
#define REGISTER_ADDRESS  0x0010      // Register can contain an address
  register_class_t register_class;
  char dtyp;                          // Register size (dt_... constants)
  char* *bit_strings;                 // Strings corresponding to each bit of the register
                                      // (NULL = no bit, same name = multi-bits mask)
  int bit_strings_default;            // Mask of default bits
};

//====================================================================
//
//                           Memory
//

struct memory_info_t : public area_t
{
  uchar perm;                  // Memory area permissions (0-no information): see segment.hpp
  char name[MAXSTR];           // Memory area name
};

//====================================================================
//
//                         Debug events
//

enum event_id_t
{
  NO_EVENT       = 0x00000000, // Not an interesting event
  PROCESS_START  = 0x00000001, // New process started
  PROCESS_EXIT   = 0x00000002, // Process stopped
  THREAD_START   = 0x00000004, // New thread started
  THREAD_EXIT    = 0x00000008, // Thread stopped
  BREAKPOINT     = 0x00000010, // Breakpoint reached
  STEP           = 0x00000020, // One instruction executed
  EXCEPTION      = 0x00000040, // Exception
  LIBRARY_LOAD   = 0x00000080, // New library loaded
  LIBRARY_UNLOAD = 0x00000100, // Library unloaded
  INFORMATION    = 0x00000200, // User-defined information
                               // This event can be used to return empty information
                               // This will cause IDA to call get_debug_event()
                               // immediately once more
  SYSCALL        = 0x00000400, // Syscall (not used yet)
  WINMESSAGE     = 0x00000800, // Window message (not used yet)
/*
  SIGNAL,
  DEBUG_STRING
  ...
*/
};


// Those structures describe particular debug events

struct e_process_exit_t
{
  int code;
};

struct e_thread_exit_t
{
  int code;
};

struct e_breakpoint_t
{
  ea_t ea;              // Possible address referenced by hardware breakpoints
};

struct e_exception_t
{
  int code;
  bool continuable;     // Execution of the process can continue after this exception
  ea_t ea;              // Possible address referenced by the exception
  char message[MAXSTR]; // Exception message
};

struct e_library_load_t // event.ea contains the library base address. if unknown pass 0
{
  char name[MAXSTR];
  ea_t size;            // library size. if unknown pass 0
};

struct e_library_unload_t
{
  char name[MAXSTR];
};


struct e_information_t
{
  char message[MAXSTR];    // Information message. It will be displayed
                           // in the messages window if not empty
};

// This structure is used only when detailed information
//   on a debug event is needed.
struct debug_event_t
{
  event_id_t   event_id;   // Event code (used to decipher 'info' union)
  process_id_t process_id; // Process where the event occured
  thread_id_t  thread_id;  // Thread where the event occured
  ea_t ea;                 // Address where the event occured
  bool handled;            // Is event handled by the debugger
                           // (from the system's point of view)
  union
  {
    e_process_exit_t   e_process_exit;
    e_thread_exit_t    e_thread_exit;
    e_library_load_t   e_library_load;
    e_library_unload_t e_library_unload;
    e_breakpoint_t     e_breakpoint;
    e_exception_t      e_exception;
    e_information_t    e_information;
  } info;
};

// Hardware breakpoint types
typedef int hwbpt_t;
const hwbpt_t
  HWBPT_EXEC  = 0,              // Execute instruction
  HWBPT_WRITE = 1,              // Write access
  HWBPT_RDWR  = 3;              // Read/write access


// Exception information
struct exception_info_t
{
  int code;
  bool break_on;        // break on the exception
  bool handle;          // should be handled by the debugger?
  char *name;           // Exception standard name
  char *mesg;           // Long message used to display info about the exception
};

// Instruction operand information
struct idd_opinfo_t
{
  ea_t addr;            // operand address (BADADDR - no address)
  ulong value;          // operand value
  bool modified;        // the operand is modified (written) by the instruction
};

//====================================================================
//
//     This structure describes a debugger API module.
//     (functions needed to debug a process on a specific
//      operating system)
//

struct debugger_t
{
  int version;                        // Expected kernel version,
                                      //   should be IDD_INTERFACE_VERSION
  int id;                             // Debugger API module id
#define DEBUGGER_ID_X86_IA32_WIN32_USER              0 // Userland win32 processes (win32 debugging APIs)
// #define DEBUGGER_ID_X86_IA32_WIN32_KERNEL           // ?
// #define DEBUGGER_ID_X86_IA32_WIN32_USER_WINDBG      // Translate functions to Microsoft WinDBG commands
// #define DEBUGGER_ID_X86_IA32_WIN32_KERNEL_WINDBG    // "
// #define DEBUGGER_ID_X86_IA32_WIN32_USER_SOFTICE     // Forward functions to a SoftIce plugin ?
// #define DEBUGGER_ID_X86_IA32_WIN32_KERNEL_SOFTICE   // "
// #define DEBUGGER_ID_X86_IA32_LINUX_USER             // Userland linux processes (ptrace())
// #define DEBUGGER_ID_X86_IA32_LINUX_KERNEL           // ?
// #define DEBUGGER_ID_X86_IA32_BOCHS                  // Forward functions to Bochs emulator ?
// #define DEBUGGER_ID_JAVA
// ...

  ulong flags;                              // Debugger module special features

  char *name;                               // Debugger module full name (displayed in menus)

  char*           *register_classes;        // Array of register class names
  int             register_classes_default; // Mask of default printed register classes
  register_info_t *registers;               // Array of registers
  int             registers_size;           // Number of registers

  int             memory_page_size;         // Size of a memory page

  const uchar     *breakpoint_bytes;        // Array of bytes for a breakpoint instruction
  int             breakpoint_size;          // Size of this array

  const exception_info_t *exc_info;         // Array of standard exception information
  int exc_qty;                              // Size of this array

//
// The following functions manipulate processes.
//
  int (idaapi* process_get_list)(process_id_t *processes, int processes_size);   // Return a list of available processes
  int (idaapi* process_get_info)(process_id_t process_id, process_info_t *info); // Return informations about a process

  // Start an executable to debug
  // 1 - ok, 0 - failed, -1 - file not found
  int (idaapi* create_process)(const char *path, const char *args, const char *startdir);
  int (idaapi* attach_process)(process_id_t process_id);        // Attach to an existing running process
  int (idaapi* detach_process)();                               // Detach from the debugged process

  // Prepare to pause the process
  // This function will prepare to pause the process
  // Normally the next get_debug_event() will pause the process
  // If the process is sleeping then the pause will not occur
  // until the process wakes up. The interface should take care of
  // this situation.
  // If this function is absent, then it won't be possible to pause the program
  bool (idaapi* prepare_to_pause_process)();

  // Stop the process.
  bool (idaapi* exit_process)();

//-------------------------------------------
// The following functions manipulate events.
//
// Get a pending debug event and suspend the process
// returns: 1-got event, 0-no event, -1-error
// This function will be called regularly by IDA.
  int (idaapi* get_debug_event)(debug_event_t *event, bool ida_is_idle);

// Continue after handling the event
// 0-ok, 1-failed
  bool (idaapi* continue_after_event)(debug_event_t *event);

// The following function will be called by the kernel each time
// when it has stopped the debugger process for some reason,
// refreshed the database and the screen.
// The debugger module may add information to the database if it wants.
// The reason for introducing this function is that when an event line
// LOAD_DLL happens, the database does not reflect the memory state yet
// and therefore we can't add information about the dll into the database
// in the get_debug_event() function.
// Only when the kernel has adjusted the database we can do it.
// Example: for imported PE DLLs we will add the exported function
// names to the database.
// This function pointer may be absent, i.e. NULL.
  void (idaapi *stopped_at_debug_event)(debug_event_t *event);

//-------------------------------------------
// The following functions manipulate threads.
//
  bool (idaapi* thread_suspend) (thread_id_t thread_id); // Suspend a running thread
  bool (idaapi* thread_continue)(thread_id_t thread_id); // Resume a suspended thread
  bool (idaapi* thread_set_step)(thread_id_t thread_id); // Run one instruction in the thread

//
// The following functions manipulate registers.
//

  bool (idaapi* thread_read_registers) (thread_id_t thread_id, ulonglong *values); // Return current register values
  bool (idaapi* thread_write_registers)(thread_id_t thread_id, ulonglong *values); // Write register values

//
// The following functions manipulate bytes in memory.
//
  ea_t (idaapi* memory_get_area)(ea_t ea, memory_info_t *info);      // Get information on the memory area containing 'ea'
                                                                     //   Return: the address of the next memory chunk
                                                                     //           BADADDR if no more chunks
  int (idaapi* read_memory)(ea_t ea, void *buffer, int size);        // Returns number of read bytes
  int (idaapi* write_memory)(ea_t ea, const void *buffer, int size); // Returns number of written bytes

  // Calculate the address of the instruction which will be
  // executed after "step over". The kernel will put a breakpoint there.
  // If the step over is equal to step into or we can not calculate
  // the address, return BADADDR.
  ea_t (idaapi* calc_step_over)(thread_id_t thread_id);

//
// The following functions manipulate hardware breakpoints.
//

  bool (idaapi* acceptable_hwbpt)(hwbpt_t type, ea_t ea, int len);  // Is it possible to set breakpoint?
  bool (idaapi* add_hwbpt)(hwbpt_t type, ea_t ea, int len);      // Set a hardware breakpoint
  bool (idaapi* del_hwbpt)(ea_t ea);                             // Remove a hardware breakpoint

// Optional functions to improve the debugger

// Get information about an instruction operand
// true-ok, false-failure
  bool (idaapi *get_operand_info)(ea_t ea, int n,
                                  const ulonglong *regvalues,
                                  idd_opinfo_t *opinf);
  ea_t (idaapi *get_jump_target)(ea_t ea, const ulonglong *regvalues);
};


#ifdef __BORLANDC__
#if sizeof(debugger_t) % 4
#error "Size of debugger_t is incorrect"
#endif
#endif


#pragma pack(pop)
#endif // _IDD_HPP
