/*
 *      Interactive disassembler (IDA).
 *      Copyright (c) 1990-2008 Hex-Rays
 *      ALL RIGHTS RESERVED.
 *
 */

#ifndef DBG_HPP
#define DBG_HPP

#include <idp.hpp>
#include <idd.hpp>
#include <kernwin.hpp>          // for callui() and ui_notification_t

#pragma pack(push, 4)

//
//      This file contains functions to control the debugging of a process.
//
// These functions are inlined for the kernel
// They are not inlined for the user-interfaces

//--------------------------------------------------------------------
//             D E B U G G E R   I N F O R M A T I O N
//--------------------------------------------------------------------

// The following structure contains information about the current debugger
// (NULL if no debugger was loaded) - see IDD.HPP for details about this structure.
//
// All functions defined in this structure should only be called by the kernel !!!

idaman debugger_t ida_export_data *dbg; // Current debugger - NULL if no debugger

#ifndef SWIG
//--------------------------------------------------------------------
//               D E B U G G E R   C A L L B A C K S
//--------------------------------------------------------------------
// A plugin can receive notifications of all major events in the
// debugger, by calling the hook_to_notification_point() function
// with HT_DBG as hook_type_t (see LOADER.HPP for details about
// installing and removing such callbacks).
//
//
// IDA generates two major different types of debugger notifications:
//
// - debugger event notification:
//     this notification monitors usual events occuring during the
//     execution of a process.
//     These event notifications are always generated for any process.
//     Some of these event notifications are interpreted by IDA
//     (high-level events), while others are directly generated by the
//     debugger module (low-level events).
//     Low-levels events always return a debug_event_t structure as argument
//     (see IDD.HPP for details about this structure).
//
// - debugger asynchronous function result notification:
//     such a notification occurs only when a debugger properly terminated
//     the execution of an asynchronous function (see "debugger functions"
//     in this file).
//
//
// How to control the process execution (after the execution of all notification
// handlers) from the notification handler?
//
// - to force the process to STOP:
//   call suspend_process().
//   In this case, the current debugger command will be aborted and no new
//   request will be started.
//
// - to force the process to CONTINUE:
//   call continue_process().
//   In this case, no new request will be started.
//
// - to start new debugger command(s):
//   call as many request_COMMAND() as needed, then call run_requests().
//   In this case, the current debugger command (if any) will be aborted.
//   (see "debugger functions" in this file for more details about requests)
//
// - else, the process execution will depend on the current debugger options or
//   object settings. Some examples:
//   * a new loaded library will stop the process depending on the associated debugger option.
//   * a breakpoint will stop the process depending on its properties.
//
//
// A plugin must not call asynchronous debugger functions from the notification handler!
// Use the REQUEST QUEUE mechanism instead (request_...()).
//
// If the plugin wants to access the process memory from a notification point,
// it should call invalidate_dbgmem_config() and/or invalidate_dbgmem_contents()
// functions. The invalidate_dbgmem_config() is really slow, so do not call it
// unless the process memory config have changed after the last time the process
// was suspended. The invalidate_dbgmem_contents() is fast and flushes the
// memory cache in the ida kernel. Without it, functions like get_byte() would
// return obsolete values!

enum dbg_notification_t
{
  dbg_null = 0,

  // debugger low-level event notifications (see IDD.HPP for details).

  dbg_process_start,   // Parameter:  const debug_event_t *event
                       //   This event notification is also an asynchronous
                       //   function result notification for start_process() !

  dbg_process_exit,    // Parameter:  const debug_event_t *event
                       //   This event notification is also an asynchronous
                       //   function result notification for exit_process() !

  dbg_process_attach,  // Parameter:  const debug_event_t *event
                       //   This event notification is also an asynchronous
                       //   function result notification for attach_process() !

  dbg_process_detach,  // Parameter:  const debug_event_t *event
                       //   This event notification is also an asynchronous
                       //   function result notification for detach_process() !

  dbg_thread_start,    // Parameter:  const debug_event_t *event

  dbg_thread_exit,     // Parameter:  const debug_event_t *event

  dbg_library_load,    // Parameter:  const debug_event_t *event

  dbg_library_unload,  // Parameter:  const debug_event_t *event

  dbg_information,     // Parameter:  const debug_event_t *event

  dbg_exception,       // Parameters: const debug_event_t *event
                       //             int                 *warn = -1
                       //             Return (in *warn):
                       //              -1 - to display an exception warning dialog
                       //                   if the process is suspended.
                       //               0 - to never display an exception warning dialog.
                       //               1 - to always display an exception warning dialog.

  // debugger high-level event notifications

  dbg_suspend_process, // The process is now suspended.
                       // Parameter: const debug_event_t *event
                       //   This event notification is also an asynchronous
                       //   function result notification for suspend_process() !

  dbg_bpt,             // A user defined breakpoint was reached.
                       // Parameters: thid_t tid
                       //             ea_t        bptea
                       //             int        *warn = -1
                       //             Return (in *warn):
                       //              -1 - to display a breakpoint warning dialog
                       //                   if the process is suspended.
                       //               0 - to never display a breakpoint warning dialog.
                       //               1 - to always display a breakpoint warning dialog.

  dbg_trace,           // A step occured (one instruction was executed). This event
                       // notification is only generated if step tracing is enabled.
                       // Parameters: thid_t tid
                       //             ea_t        ip
                       // Returns: 1-do not log this trace event; 0-log it

  dbg_request_error,   // An error occured during the processing of a request.
                       // Parameters: ui_notification_t  failed_command
                       //             dbg_notification_t failed_dbg_notification

  // debugger asynchronous function result notifications
  //   Please note some low-level event notifications also act as asynchronous
  //   function result notifications.

  dbg_step_into,       // Parameter: const debug_event_t *event

  dbg_step_over,       // Parameter: const debug_event_t *event

  dbg_run_to,          // Parameter: const debug_event_t *event

  dbg_step_until_ret,  // Parameter: const debug_event_t *event

  dbg_bpt_changed,     // Breakpoint has been changed
                       // Parameter: int bptev_code, bpt_t *bpt
                       // Breakpoint modification events
#define BPTEV_ADDED    0 // Breakpoint has been added
#define BPTEV_REMOVED  1 // Breakpoint has been removed
#define BPTEV_CHANGED  2 // Breakpoint has been modified

  dbg_last,            // The last debugger notification code
};

//--------------------------------------------------------------------
//               D E B U G G E R    F U N C T I O N S
//--------------------------------------------------------------------
// Debugger functions complete either SYNCHRONOUSLY or ASYNCHRONOUSLY:
//
// - SYNCHRONOUS FUNCTIONS execute the entire action before the function returns.
//
// - ASYNCHRONOUS FUNCTIONS return before the action has executed in its
//   entirety. They simply start the action, but the result of the action will
//   only be available later. For example, a run_to(address) function can
//   execute a lot of instructions before terminating.
//   Such functions provide a notification code to indicate the end of their
//   execution (see the 'Notification' keyword in the function documentation).
//   Install a callback using the hook_to_notification_point() function
//   (see LOADER.HPP) to be notified when the action is terminated.
//
//
// DEBUGGER COMMANDS are functions who influence the execution of the debugged
// process. They are available in 2 forms:
//
// - COMMAND(): in this mode, the command will be directly executed.
//   However, it is forbidden to use asynchronous commands in this mode from a
//   debugger notification handler (see "debugger callbacks" in this file).
//
// - request_COMMAND(): in this mode, a REQUEST to run the command will be
//   memorized at the end of the REQUEST QUEUE (see below). This is mandatory
//   to use this mode for asynchronous commands from a debugger notification
//   handler (see "debugger callbacks" in this file).
//
//
// The REQUEST QUEUE contains a list of planned debugger commands.
// These commands will be started only in the following cases:
//
// - the previous command terminated, and no call to suspend_process()
//   or continue_process() occured in the asynchronous function result
//   notification handler (if any).
//
// - run_requests() was called.
//   Please note that when called from a debugger notification handler the
//   queued requests will only be started after the execution of all
//   notification handlers.
//
// A request which fails to start (by returning 0) will generate a
// dbg_request_error notification.


// Execute requests until all requests are processed or an asynchronous
// function is called.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Return: false if not all requests could be processed
//         (indicates an asynchronous function was started)
// Note: If called from a notification handler, the execution of requests will
//       be postponed to the end of the execution of all notification handlers.

bool idaapi run_requests(void);


// Get the current running request.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Return: ui_null if no running request
ui_notification_t idaapi get_running_request(void);
inline bool is_request_running(void) { return get_running_request() != ui_null; }


// Get the notification associated (if any) with the current running request.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Return: dbg_null if no running request
dbg_notification_t idaapi get_running_notification(void);


// Clear the queue of waiting requests.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Note: If a request is currently running, this one isn't stopped.

void idaapi clear_requests_queue(void);

//--------------------------------------------------------------------
//                P R O C E S S   C O M M A N D S
//--------------------------------------------------------------------
// Use the following functions to manipulate the debugged process.

// Return the state of the currently debugged process.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Returns one of DSTATE_.. constants

int idaapi get_process_state(void);

#define DSTATE_SUSP             -1 // process is suspended and will not continue
#define DSTATE_NOTASK            0 // no process is currently debugged
#define DSTATE_RUN               1 // process is running


// Set new state for the debugged process.
// Notifies the IDA kernel about the change of the debugged process state.
// For example, a debugger module could call this function when it knows
// that the process is suspended for a short period of time.
// Some IDA API calls can be made only when the process is suspended.
// The process state is usually restored before returning control to the caller.
// You must know that it is ok to change the process state, doing it at arbitrary
// moments may crash the application or IDA.
// Type:         Synchronous function
// Notification: none (synchronous function)
//      newstate - new process state (one of DSTATE_.. constants)
//                 if DSTATE_NOTASK is passed then the state is not changed
//      p_thid   - ptr to new thread id. may be NULL or pointer to NO_THREAD.
//                 the pointed variable will contain the old thread id upon return
//      dbginv   - combination of DBGINV_.. bits
// Returns: old debugger state (one of DSTATE_.. constants)

int idaapi set_process_state(int newstate, thid_t *p_thid, int dbginv);

#define DBGINV_MEMORY   0x0001  // invalidate cached memory contents
#define DBGINV_MEMCFG   0x0002  // invalidate cached process segmentation
#define DBGINV_REGS     0x0004  // invalidate cached register values
#define DBGINV_ALL      0x7FFF  // invalidate everything
#define DBGINV_REDRAW   0x8000  // refresh the screen
#define DBGINV_NONE     0       // invalidate nothing


// Invalidate cached debugger information
// Type:         Synchronous function
// Notification: none (synchronous function)
//      dbginv   - combination of DBGINV_.. bits
// Returns: current debugger state (one of DSTATE_.. constants)

inline int idaapi invalidate_dbg_state(int dbginv)
{
  return set_process_state(DSTATE_NOTASK, NULL, dbginv);
}


// Start a process in the debugger
//     path    - path to the executable to start
//     args    - arguments to pass to process
//     sdir    - starting directory for the process
//   For all parameters, a NULL value indicates the debugger will take
//   the value from the defined Process Options.
// Type:         Asynchronous function - available as Request
// Notification: dbg_process_start
// Return:
//         -1 - impossible to create the process
//          0 - the starting of the process was cancelled by the user
//          1 - the process was properly started
// Note: You can also use the run_to() function to easily start the execution
//       of a process until a given address is reached.

int idaapi start_process(const char *path = NULL,
                         const char *args = NULL,
                         const char *sdir = NULL);
int idaapi request_start_process(const char *path = NULL,
                                 const char *args = NULL,
                                 const char *sdir = NULL);


// Suspend the process in the debugger.
// Type:         Synchronous function  (if in a notification handler)
//               Asynchronous function (everywhere else)
//               available as Request
// Notification: none                (if in a notification handler)
//               dbg_suspend_process (everywhere else)
// Note: The suspend_process() function can be called from a notification
//       handler to force the stopping of the process.
//       In this case, no notification will be generated.
//       When you suspend a process, the running command is always aborted.

bool idaapi suspend_process(void);
bool idaapi request_suspend_process(void);


// Continue the execution of the process in the debugger.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)
// Note: The continue_process() function can be called from a notification
//       handler to force the continuation of the process. In this case
//       the request queue will not be examined, IDA will simply resume
//       execution. Usually it makes sense to call request_continue_process()
//       followed by run_requests(), so that IDA will first start a queued
//       request (if any) and then resume the application.

bool idaapi continue_process(void);             // unconditional: ignores the queued requests
bool idaapi request_continue_process(void);     // requires explicit run_requests()


// Terminate the debugging of the current process.
// Type:         Asynchronous function - available as Request
// Notification: dbg_process_exit

bool idaapi exit_process(void);
bool idaapi request_exit_process(void);


// Take a snapshot of running processes and return their number.
// Type:         Synchronous function
// Notification: none (synchronous function)

int idaapi get_process_qty(void);


// Get information about a running process
//      n - number of process, is in range 0..get_process_qty()-1
// If process_info isn't NULL, it is filled with the information.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Return: NO_PROCESS if the process doesn't exist.
// Note: Always first call get_process_qty() to initialize the snapshot.

pid_t idaapi get_process_info(int n, process_info_t *process_info);
inline pid_t getn_process(int n) { return get_process_info(n, NULL); }


// Attach the debugger to a running process
//     process - PID of the process to attach to. If NO_PROCESS, a dialog box
//               will interactively ask the user for the process to attach to.
// Type:         Asynchronous function - available as Request
// Notification: dbg_process_attach
// Return:
//         -2 - impossible to find a compatible process
//         -1 - impossible to attach to the given process (process died, privilege
//              needed, not supported by the debugger plugin, ...)
//          0 - the user cancelled the attaching to the process
//          1 - the debugger properly attached to the process
// Note: This function shouldn't be called as a request if NO_PROCESS is used.

int idaapi attach_process(pid_t pid=NO_PROCESS, int event_id=-1);
int idaapi request_attach_process(pid_t pid, int event_id);


// Detach the debugger from the debugged process.
// Type:         Asynchronous function - available as Request
// Notification: dbg_process_detach

bool idaapi detach_process(void);
bool idaapi request_detach_process(void);


// Is the debugger busy?
// Some debuggers do not accept any commands while the debugged appplication
// is running. For such a debugger, it is unsafe to do anything with the
// database (even simple queries like get_byte may lead to undesired consequences).
// Returns: true if the debugged application is running under such a debugger

bool idaapi is_debugger_busy(void);


//--------------------------------------------------------------------
//                         T H R E A D S
//--------------------------------------------------------------------

// Get number of threads.
// Type:         Synchronous function
// Notification: none (synchronous function)
int idaapi get_thread_qty(void);


// Get the ID of a thread
//     n - number of thread, is in range 0..get_thread_qty()-1
// Type:         Synchronous function
// Notification: none (synchronous function)
// Return: NO_THREAD if the thread doesn't exist.

thid_t idaapi getn_thread(int n);


// Get current thread ID
// Type:         Synchronous function
// Notification: none (synchronous function)
thid_t idaapi get_current_thread(void);


// Select the given thread as the current debugged thread.
// All thread related execution functions will work on this thread.
//     tid - ID of the thread to select
// The process must be suspended to select a new thread.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)
// Return: false if the thread doesn't exist.

bool idaapi select_thread(thid_t tid);
bool idaapi request_select_thread(thid_t tid);

// Suspend thread
//     tid - thread id
// Suspending a thread may deadlock the whole application if the suspended
// was owning some synchronization objects.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)
// Return: -1:network error, 0-failed, 1-ok

int idaapi suspend_thread(thid_t tid);
int idaapi request_suspend_thread(thid_t tid);

// Resume thread
//     tid - thread id
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)
// Return: -1:network error, 0-failed, 1-ok

int idaapi resume_thread(thid_t tid);
int idaapi request_resume_thread(thid_t tid);

//--------------------------------------------------------------------
//                         M O D U L E S
//--------------------------------------------------------------------

// Functions to enumerate modules loaded into the process
//      modinfo - structure to receive the answer
// Return: false if there are no (more) modules
// Typical loop to enumerate modules would look like:
//   module_info_t minfo;
//   for ( bool ok=get_first_module(&minfo); ok; ok=get_next_module(&minfo) )
//     ...

bool idaapi get_first_module(module_info_t *modinfo);
bool idaapi get_next_module(module_info_t *modinfo);


//--------------------------------------------------------------------
//    E X E C U T I O N   F L O W   C O N T R O L   C O M M A N D S
//--------------------------------------------------------------------
// Use the following functions to run instructions in the debugged process.


// Execute one instruction in the current thread.
// Other threads are kept suspended.
// Type:         Asynchronous function - available as Request
// Notification: dbg_step_into

bool idaapi step_into(void);
bool idaapi request_step_into(void);


// Execute one instruction in the current thread,
// but without entering into functions
// Others threads keep suspended.
// Type:         Asynchronous function - available as Request
// Notification: dbg_step_over

bool idaapi step_over(void);
bool idaapi request_step_over(void);


// Execute the process until the given address is reached.
// If no process is active, a new process is started.
// Type:         Asynchronous function - available as Request
// Notification: dbg_run_to
//
// Technically, the debugger setups a temporary breakpoint at
// the given address, and continue (or start) the execution of
// the whole process.
// So, all threads continue their execution !

bool idaapi run_to(ea_t ea);
bool idaapi request_run_to(ea_t ea);


// Execute instructions in the current thread until
// a function return instruction is reached.
// Other threads are kept suspended.
// Type:         Asynchronous function - available as Request
// Notification: dbg_step_until_ret

bool idaapi step_until_ret(void);
bool idaapi request_step_until_ret(void);

//--------------------------------------------------------------------
//                       R E G I S T E R S
//--------------------------------------------------------------------
// The debugger structure defines a set of hardware registers in dbg->registers.
// IDA also recognizes register names for each defined bit in bit registers.
// You can use all these names to set or get a register value.
//
// For example, with the x86 Userland Win32 debugger you can use
// register names like:
//  - "EAX", ... "EBP", "ESP", "EFL": for classical integer registers
//  - "CS", "DS", ...               : for segment registers
//  - "ST0", "ST1", ...             : for FPU registers
//  - "CF", "PF", "AF", "ZF", ...   : for special bit values


// Read a register value from the current thread.
// Type:         Synchronous function
// Notification: none (synchronous function)

bool idaapi get_reg_val(const char *regname, regval_t *regval);

inline bool get_reg_val(const char *regname, uint64 *ival)
{
  regval_t regval;
  if ( !get_reg_val(regname, &regval) )
    return false;
  if ( regval.rvtype != RVT_INT )
    return false;
  if ( ival != NULL )
    *ival = regval.ival;
  return true;
}


// Write a register value to the current thread.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi set_reg_val(const char *regname, const regval_t *regval);
bool idaapi request_set_reg_val(const char *regname, const regval_t *regval);

inline bool set_reg_val(const char *regname, uint64 ival)
{
  regval_t regval;
  regval.ival = ival;
  return set_reg_val(regname, &regval);
}


// Does a register contain an integer value?
// Type:         Synchronous function
// Notification: none (synchronous function)

bool idaapi is_reg_integer(const char *regname);


// Does a register contain a floating point value?
// Type:         Synchronous function
// Notification: none (synchronous function)

bool idaapi is_reg_float(const char *regname);


// Does a register contain a value of a custom data type?
// Type:         Synchronous function
// Notification: none (synchronous function)

bool idaapi is_reg_custom(const char *regname);


#endif // SWIG

//--------------------------------------------------------------------
//                     B R E A K P O I N T S
//--------------------------------------------------------------------

// Helper functions
int idaapi set_bptloc_string(const char *s);
const char *idaapi get_bptloc_string(int i);

enum bpt_loctype_t
{
  BPLT_ABS,           // absolute address: ea
  BPLT_REL,           // relative address: module_path, offset
  BPLT_SYM,           // symbolic: symbol_name, offset
  BPLT_SRC,           // source level: filename, lineno
};

struct bpt_location_t
{
//private:
  ea_t info;
  int index;
  bpt_loctype_t loctype;
//public:
  bpt_loctype_t type(void) const { return loctype; }
  bool is_empty_path(void) const { return index == 0; } // rel & src
  const char *path(void) const { return get_bptloc_string(index); } // rel & src
  const char *symbol(void) const { return get_bptloc_string(index); } // sym
  int lineno(void) const { return int(info); } // src
  uval_t offset(void) const { return (uval_t)info; } // rel & sym
  ea_t ea(void) const { return info; } // abs

  bpt_location_t(void) : loctype(BPLT_ABS) {}
  void set_abs_bpt(ea_t a)
  {
    info = a;
    loctype = BPLT_ABS;
  }

  void set_src_bpt(const char *fn, int _lineno)
  {
    index   = set_bptloc_string(fn);
    info    = _lineno;
    loctype = BPLT_SRC;
  }

  void set_sym_bpt(const char *_symbol, uval_t _offset=0)
  {
    index   = set_bptloc_string(_symbol);
    info    = _offset;
    loctype = BPLT_SYM;
  }

  void set_rel_bpt(const char *mod, uval_t _offset)
  {
    index   = set_bptloc_string(mod);
    info    = _offset;
    loctype = BPLT_REL;
  }

  int compare(const bpt_location_t &r) const { return callui(ui_dbg_compare_bpt_locs, this, &r).i; }
  bool operator==(const bpt_location_t &r) const { return compare(r) == 0; }
  bool operator!=(const bpt_location_t &r) const { return compare(r) != 0; }
  bool operator< (const bpt_location_t &r) const { return compare(r) <  0; }
  bool operator> (const bpt_location_t &r) const { return compare(r) >  0; }
  bool operator<=(const bpt_location_t &r) const { return compare(r) <= 0; }
  bool operator>=(const bpt_location_t &r) const { return compare(r) >= 0; }

  // internal functions
  size_t print(char *buf, size_t bufsize) const;
};

// A breakpoint has the following characteristics:
struct bpt_t
{
  size_t cb;               // size of this structure
  qstring cndbody;         // Condition as entered by the user
  bpt_location_t loc;      // Location
  ea_t ea;                 // Address, if known. For BPLT_SRC, index into an internal data struct
  bpttype_t type;          // Breakpoint type
  int pass_count;          // Number of times the breakpoint is hit before stopping
                           // (default is 0: stop always)
  uint32 flags;
#define BPT_BRK        0x001 // suspend execution upon hit
#define BPT_TRACE      0x002 // add trace information upon hit
#define BPT_UPDMEM     0x004 // refresh the memory layout and contents before evaluating bpt condition
#define BPT_ENABLED    0x008 // enabled?
#define BPT_LOWCND     0x010 // condition is calculated at low level (on the server side)
#define BPT_TRACEON    0x020 // enable tracing when the breakpoint is reached
#define BPT_TRACE_INSN 0x040 //   instruction tracing
#define BPT_TRACE_FUNC 0x080 //   function tracing
#define BPT_TRACE_BBLK 0x100 //   basic block tracing
#define BPT_TRACE_TYPES (BPT_TRACE_INSN|BPT_TRACE_FUNC|BPT_TRACE_BBLK)
                             // if any of BPT_TRACE_TYPES bits are set but BPT_TRACEON is clear,
                             // then turn off tracing for the specified trace types

  uint32 props;            // Internal properties
#define BKPT_BADBPT   0x01 // failed to write the bpt to the process memory (at least one location)
#define BKPT_LISTBPT  0x02 // include in bpt list (user-defined bpt)
#define BKPT_TRACE    0x04 // trace bpt; should not be deleted when the process gets suspended
#define BKPT_ACTIVE   0x08 // active?
#define BKPT_PARTIAL  0x10 // partially active? (some locations were not written yet)
#define BKPT_CNDREADY 0x20 // condition has been compiled
#define BKPT_FAKEPEND 0x40 // fake pending bpt: it is inactive but another
                           // bpt of the same type is active at the same address(es)
#define BKPT_PAGE     0x80 // written to the process as a page bpt. is available
                           // only after writing the bpt to the process.
#define BKPT_ELANG_MASK  0xF0000000u // index of the extlang (scripting language) of the condition
#define BKPT_ELANG_SHIFT 28

  int size;                // Size of the breakpoint (0 for software breakpoints)
  int cndidx;              // Internal number of the condition (<0-none)

  bpt_t(void) : cb(sizeof(*this)), ea(BADADDR), type(BPT_SOFT), pass_count(0),
                flags(BPT_BRK|BPT_ENABLED), props(0), size(0), cndidx(-1) {}

  bool is_hwbpt(void) const { return type != BPT_SOFT; }
  bool enabled(void) const { return (flags & BPT_ENABLED) != 0; }
  bool is_low_level(void) const { return (flags & BPT_LOWCND) != 0; }
  bool badbpt(void) const { return (props & BKPT_BADBPT) != 0; }
  bool listbpt(void) const { return (props & BKPT_LISTBPT) != 0; }
  bool is_compiled(void) const { return (props & BKPT_CNDREADY) != 0; }
  // written completely to process?
  bool is_active(void) const { return (props & (BKPT_PARTIAL|BKPT_ACTIVE)) == BKPT_ACTIVE; }
  // written partially to process?
  bool is_partially_active(void) const { return (props & BKPT_PARTIAL) != 0; }
  // not written to process at all?
  bool is_inactive(void) const { return (props & (BKPT_PARTIAL|BKPT_ACTIVE)) == 0; }
  bool is_page_bpt(void) const { return (props & BKPT_PAGE) != 0; }

  int get_size(void) const { return is_hwbpt() ? size : 1; }
  void set_abs_bpt(ea_t a) { loc.set_abs_bpt(a); ea = a; }
  void set_src_bpt(const char *fn, int lineno) { loc.set_src_bpt(fn, lineno); ea = BADADDR; }
  void set_sym_bpt(const char *sym, uval_t o) { loc.set_sym_bpt(sym, o); ea = BADADDR; }
  void set_rel_bpt(const char *mod, uval_t o) { loc.set_rel_bpt(mod, o); ea = BADADDR; }

  bool is_absbpt(void) const { return loc.type() == BPLT_ABS; }
  bool is_relbpt(void) const { return loc.type() == BPLT_REL; }
  bool is_symbpt(void) const { return loc.type() == BPLT_SYM; }
  bool is_srcbpt(void) const { return loc.type() == BPLT_SRC; }

  bool is_tracemodebpt(void) const { return (flags & BPT_TRACE_TYPES) != 0; }
  bool is_traceonbpt(void) const { return is_tracemodebpt() && (flags & BPT_TRACEON) != 0; }
  bool is_traceoffbpt(void) const { return is_tracemodebpt() && (flags & BPT_TRACEON) == 0; }

  bool set_trace_action(bool enable, int trace_types)
  {
    trace_types &= ~BPT_TRACE_TYPES;
    if ( trace_types == 0 )
      return false;
    flags |= trace_types;
    setflag(flags, BPT_TRACEON, enable);
    return true;
  }

  // get the scripting language name for the condition string
  const char *get_cnd_elang() const;

  // set the scripting language name for the condition string
  // returns false if too many languages were used
  bool set_cnd_elang(const char *name);

  // internal functions
  void set_cond(const char *cnd);
  bool eval_cond(ea_t ea, bool *fire, const char *bpt_type);
};

#ifndef SWIG
// Get number of breakpoints.
// Type:         Synchronous function
// Notification: none (synchronous function)

int idaapi get_bpt_qty(void);


// Get the characteristics of a breakpoint
//      n - number of breakpoint, is in range 0..get_bpt_qty()-1
// bpt is filled with the characteristics.
// Type:         Synchronous function
// Notification: none (synchronous function)

bool idaapi getn_bpt(int n, bpt_t *bpt);


// Get the characteristics of a breakpoint
//      address - any address in the breakpoint range
// If bpt isn't NULL, it is filled with the characteristics.
// Type:         Synchronous function
// Notification: none (synchronous function)

bool idaapi get_bpt(ea_t ea, bpt_t *bpt);
inline bool exist_bpt(ea_t ea) { return get_bpt(ea, NULL); }


// Add a new breakpoint in the debugged process
//     ea   - any address in the process memory space:
//            Depending on the architecture, hardware breakpoints
//            always be setup at random address. For example, on x86,
//            hardware breakpoints should be aligned depending on their size.
//            Moreover, on the x86 architecture, it is impossible to setup
//            more than 4 hardware breakpoints.
//     size - size of the breakpoint (irrelevant for software breakpoints):
//            As for the address, hardware breakpoints can't always be setup
//            with random size.
//     type - type of the breakpoint (BPT_SOFT for software breakpoint)
//            special case BPT_DEFAULT (BPT_SOFT|BPT_EXEC):
//            try to add instruction breakpoint of the appropriate type
//            as follows: software bpt if supported, hwbpt otherwise
// Only one breakpoint can exist at a given address.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi add_bpt(ea_t ea, asize_t size = 0, bpttype_t type = BPT_DEFAULT);
bool idaapi request_add_bpt(ea_t ea, asize_t size = 0, bpttype_t type = BPT_DEFAULT);


// Add a new breakpoint in the debugged process
//     bpt    -  Breakpoint to add. It describes the break condition,
//               type, flags, location (module relative, source breakpoint
//               or absolute) and other attributes.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi add_bpt(const bpt_t &bpt);
bool idaapi request_add_bpt(const bpt_t &bpt);


// Delete an existing breakpoint in the debugged process
//      ea - any address in the breakpoint range
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi del_bpt(ea_t ea);
bool idaapi request_del_bpt(ea_t ea);


// Delete an existing breakpoint in the debugged process
//      bptloc - Breakpoint location
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi del_bpt(const bpt_location_t &bptloc);
bool idaapi request_del_bpt(const bpt_location_t &bptloc);

// Update modifiable characteristics of an existing breakpoint.
// To update the breakpoint location, delete and add a new breakpoint.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Only the bpt condition, pass_cont, flags, and size can be modified.

bool idaapi update_bpt(const bpt_t *bpt);


// Find a breakpoint by location
//      bptloc - Breakpoint location
//      bpt    - bpt is filled if the breakpoint was found
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi find_bpt(const bpt_location_t &bptloc, bpt_t *bpt);


// Enable or disable an existing breakpoint.
// A disabled breakpoint isn't available anymore in the process.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi enable_bpt(ea_t ea, bool enable = true);
bool idaapi enable_bpt(const bpt_location_t &bptloc, bool enable = true);
inline bool disable_bpt(ea_t ea) { return enable_bpt(ea, false); }
inline bool disable_bpt(const bpt_location_t &bptloc) { return enable_bpt(bptloc, false); }
bool idaapi request_enable_bpt(ea_t ea, bool enable = true);
bool idaapi request_enable_bpt(const bpt_location_t &bptloc, bool enable = true);
inline bool request_disable_bpt(ea_t ea) { return request_enable_bpt(ea, false); }
inline bool request_disable_bpt(const bpt_location_t &bptloc) { return request_enable_bpt(bptloc, false); }



// Check the breakpoint at the specified address
// Return value: one of BPTCK_...

int idaapi check_bpt(ea_t ea);

#define BPTCK_NONE -1  // breakpoint does not exist
#define BPTCK_NO    0  // breakpoint is disabled
#define BPTCK_YES   1  // breakpoint is enabled
#define BPTCK_ACT   2  // breakpoint is active (written to the process)


// Visit all breakpoits
// To use this class, derive your own class from it and call for_all_bpts()
// it is forbidden to add/del bpts from the visit_bpt() function
// If bpts are nevetheless modified, the enumeration should be stopped
struct bpt_visitor_t
{
  int _for_all_bpts(int bvflags); // do not use this func
  area_t range;                 // if specified, restricts the address range
  const char *name;             // if specified, restricts bpts to the ones that match the given name
  bpt_visitor_t(void) : range(0, BADADDR), name(NULL) {}
  virtual int idaapi visit_bpt(const bpt_t *bpt) = 0;
  int idaapi for_all_bpts(int bvflags)
  {
    return callui(ui_dbg_for_all_bpts, this, bvflags).i;
  }
};

// Flags for for_all_bpts():
#define BVF_ABS             0x0001  // include absolute bpts
#define BVF_REL             0x0002  // include relative bpts
#define BVF_SYM             0x0004  // include symbolic bpts
#define BVF_SRC             0x0008  // include source bpts
#define BVF_ALL             0x000F  // include all bpt location types
#define BVF_STATE           0x0030  // bpt state mask:
#define   BVFS_ANY          0x0000  //   any state
#define   BVFS_INPROC       0x0010  //   written to process memory
#define   BVFS_PENDING      0x0020  //   pending
#define   BVFS_DISABLED     0x0030  //   disabled
                                    // it is forbidden to modify bpt states
                                    // from the visit_bpt() function if
                                    // BVF_STATE is not BFVS_ANY

//--------------------------------------------------------------------
//                    T R A C I N G   B U F F E R
//--------------------------------------------------------------------
// IDA memorizes various types of trace events in a circular buffer:
// instruction tracing, function call and return, breakpoint access ...


// Specify the new size of the circular buffer
//     size - if 0, buffer isn't circular and events are never removed.
// If the new size is smaller than the existing number of trace events,
// a corresponding number of trace events are removed.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Note: If you specify 0, all available memory can be quickly used !!!

bool idaapi set_trace_size(int size);


// Clear all events in the trace buffer
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

void idaapi clear_trace(void);
void idaapi request_clear_trace(void);

//--------------------------------------------------------------------
//                        S T E P    T R A C I N G
//--------------------------------------------------------------------
// To step trace, IDA activates the step-by-step feature of the processor,
// and generates a dbg_trace notification after each step in the current thread.
// Use this mechanism to implement your own custom tracing engine.
// This mechanism is currently only available for plugins !


// Get current state of step tracing.
// Type:         Synchronous function
// Notification: none (synchronous function)
bool idaapi is_step_trace_enabled(void);


// Enable or disable the step tracing
//    true - enable step tracing
//   false - disable step tracing
//      -1 - temporarly disable step tracing
//           (trace-over breakpoints are conserved:
//            these could reenable step tracing later)
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi enable_step_trace(int enable = true);
inline bool disable_step_trace(void) { return enable_step_trace(false); }
bool idaapi request_enable_step_trace(int enable = true);
inline bool request_disable_step_trace(void) { return request_enable_step_trace(false); }


// Get current step tracing options.
// Type:         Synchronous function
// Notification: none (synchronous function)

#define ST_OVER_DEBUG_SEG 0x01 // step tracing will be disabled when IP is in a debugger segment
#define ST_OVER_LIB_FUNC  0x02 // step tracing will be disabled when IP is in a library function
#define ST_ALREADY_LOGGED 0x04 // step tracing will be disabled when IP is already logged
#define ST_SKIP_LOOPS     0x08 // step tracing will try to skip loops already recorded
#define ST_DIFFERENTIAL   0x10 // tracing: log only new instructions
// mask of available options, to ensure compatibility with newer IDA versions
#define ST_OPTIONS_MASK    (ST_OVER_DEBUG_SEG|ST_OVER_LIB_FUNC|ST_ALREADY_LOGGED|ST_SKIP_LOOPS|ST_DIFFERENTIAL)
#define ST_OPTIONS_DEFAULT (ST_OVER_DEBUG_SEG|ST_OVER_LIB_FUNC)

int idaapi get_step_trace_options(void);


// Modify step tracing options.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

void idaapi set_step_trace_options(int options);
void idaapi request_set_step_trace_options(int options);

//--------------------------------------------------------------------
//               I N S T R U C T I O N S   T R A C I N G
//--------------------------------------------------------------------
// When instruction tracing is active, each executed instruction is stored
// in the tracing buffer.
// Internally, IDA uses step tracing to monitor register values after the
// execution of the instruction.


// Get current state of instructions tracing.
// Type:         Synchronous function
// Notification: none (synchronous function)
bool idaapi is_insn_trace_enabled(void);


// Enable or disable the instructions tracing
//    true - enable instructions tracing
//   false - disable instructions tracing
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi enable_insn_trace(bool enable = true);
inline bool disable_insn_trace(void) { return enable_insn_trace(false); }
bool idaapi request_enable_insn_trace(bool enable = true);
inline bool request_disable_insn_trace(void) { return request_enable_insn_trace(false); }


// Get current instruction tracing options.
// Type:         Synchronous function
// Notification: none (synchronous function)

#define IT_LOG_SAME_IP 0x01 // instruction tracing will log instructions whose IP doesn't change

int idaapi get_insn_trace_options(void);


// Modify instruction tracing options.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

void idaapi set_insn_trace_options(int options);
void idaapi request_set_insn_trace_options(int options);

//--------------------------------------------------------------------
//                 F U N C T I O N S   T R A C I N G
//--------------------------------------------------------------------
// Each call to a function or return from a function is stored
// in the tracing buffer.


// Get current state of functions tracing.
// Type:         Synchronous function
// Notification: none (synchronous function)
bool idaapi is_func_trace_enabled(void);


// Enable or disable the functions tracing
//    true - enable functions tracing
//   false - disable functions tracing
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi enable_func_trace(bool enable = true);
inline bool disable_func_trace(void) { return enable_func_trace(false); }
bool idaapi request_enable_func_trace(bool enable = true);
inline bool request_disable_func_trace(void) { return request_enable_func_trace(false); }


// Get current function tracing options.
// Type:         Synchronous function
// Notification: none (synchronous function)

#define FT_LOG_RET 0x01 // function tracing will log returning instructions

int idaapi get_func_trace_options(void);


// Modify function tracing options.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

void idaapi set_func_trace_options(int options);
void idaapi request_set_func_trace_options(int options);

//--------------------------------------------------------------------
//              B A S I C   B L O C K   T R A C I N G
//--------------------------------------------------------------------

// Modify basic block tracing options.
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

// Enable or disable the basic blocks tracing
//    true - enable basic blocks tracing
//   false - disable basic blocks tracing
// Type:         Synchronous function - available as Request
// Notification: none (synchronous function)

bool idaapi enable_bblk_trace(bool enable = true);
inline bool disable_bblk_trace(void) { return enable_bblk_trace(false); }
bool idaapi request_enable_bblk_trace(bool enable = true);
inline bool request_disable_bblk_trace(void) { return request_enable_bblk_trace(false); }

// Get current basic block tracing options.
// Type:         Synchronous function
// Notification: none (synchronous function)

int idaapi get_bblk_trace_options(void);

// Possible options are:
#define BT_LOG_INSTS 0x0001 // log all instructions in the current basic block


void idaapi set_bblk_trace_options(int options);
void idaapi request_set_bblk_trace_options(int options);


//--------------------------------------------------------------------
//                   T R A C I N G   E V E N T S
//--------------------------------------------------------------------
#endif // SWIG

// Trace event types:
enum tev_type_t
{
  tev_none = 0, // no event
  tev_insn,     // an instruction trace
  tev_call,     // a function call trace
  tev_ret,      // a function return trace
  tev_bpt,      // write, read/write, execution trace
  tev_mem,      // memory layout changed
  tev_event,    // debug event occurred
  tev_max,      // first unused event type
};

typedef qvector<debug_event_t> dbgevt_vec_t;

// Common information for all trace events:
struct tev_info_t
{
  tev_type_t   type;    // trace event type
  thid_t       tid;     // thread where the event was recorded
  ea_t         ea;      // address where the event occured
};
typedef qvector<tev_info_t> tevinfo_vec_t;

#ifndef SWIG
// Get number of trace events available in trace buffer.
// Type:         Synchronous function
// Notification: none (synchronous function)

int idaapi get_tev_qty(void);


// Get main information about a trace event.
//      n - number of trace event, is in range 0..get_bpt_qty()-1
//          0 represents the latest added trace event.
// Return the type of a trace event.
// Type:         Synchronous function
// Notification: none (synchronous function)

bool idaapi get_tev_info(int n, tev_info_t *tev_info);


// Read a register value from an instruction trace event.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Return: false if not an instruction event.
// Note: This is the value of the register before the execution of
//       the instruction.

bool idaapi get_insn_tev_reg_val(int n, const char *regname, regval_t *regval);

// required typedef for get_insn_tev_reg_mem
struct memreg_info_t
{
   ea_t ea;
   bytevec_t bytes;
};
DECLARE_TYPE_AS_MOVABLE(memreg_info_t);
typedef qvector<memreg_info_t> memreg_infos_t;

// Read the memory pointed by register values from an instruction
// trace event.
// Type:         Synchronous function
// Notification: none
// Return: false if not an instruction event or no memory is available
bool idaapi get_insn_tev_reg_mem(int n, memreg_infos_t *memmap);

inline bool get_insn_tev_reg_val(int n, const char *regname, uint64 *ival)
{
  regval_t regval;
  if ( !get_insn_tev_reg_val(n, regname, &regval) )
    return false;
  if ( regval.rvtype != RVT_INT )
    return false;
  if ( ival != NULL )
    *ival = regval.ival;
  return true;
}


// Read the resulting register value from an instruction trace event.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Return: false if not an instruction trace event or register wasn't modified.

bool idaapi get_insn_tev_reg_result(int n, const char *regname, regval_t *regval);

inline bool get_insn_tev_reg_result(int n, const char *regname, uint64 *ival)
{
  regval_t regval;
  if ( !get_insn_tev_reg_result(n, regname, &regval) )
    return false;
  if ( regval.rvtype != RVT_INT )
    return false;
  if ( ival != NULL )
    *ival = regval.ival;
  return true;
}


// Return the called function from a function call trace event.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Return: false if not a function call event.

ea_t idaapi get_call_tev_callee(int n);


// Return the return address from a function return trace event.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Return: false if not a function return event.

ea_t idaapi get_ret_tev_return(int n);


// Return the address associated to a read, read/write or execution trace event.
// Type:         Synchronous function
// Notification: none (synchronous function)
// Return: false if not a read, read/write or execution trace event.
// Note: Usually, a breakpoint is associated with a read, read/write or execution
//       trace event. However, the returned address could be any address in the
//       range of this breakpoint.
//       If the breakpoint was deleted after the trace event, the address no longer
//       corresponds to a valid breakpoint.

ea_t idaapi get_bpt_tev_ea(int n);


// Return the memory layout, if any, for the specified tev object
// Type:         Synchronous function
// Notification: None
// Return:       False if the tev_t object is not of type tev_mem, true otherwise,
//               with the new memory layout in "mi".

bool idaapi get_tev_memory_info(int n, meminfo_vec_t *mi);


// Return the corresponding debug event, if any, for the specified tev object
// Type:         Synchronous function
// Notification: None
// Return:       False if the tev_t object doesn't have any associated debug
//               event, true otherwise, with the debug event in "d".

bool idaapi get_tev_event(int n, debug_event_t *d);

// Return the base address of the current trace
// Type:         Synchronous function
// Notification: None
// Return:       the base address of the currently loaded trace

ea_t idaapi get_trace_base_address(void);

// Set the base address of the current trace
// Type:         Synchronous function
// Notification: None

void idaapi set_trace_base_address(ea_t ea);

// Add a thread to the current trace
// Type:         Synchronous function
// Notification: None

void idaapi dbg_add_thread(thid_t tid);

// Delete a thread from the current trace
// Type:         Synchronous function
// Notification: None

void idaapi dbg_del_thread(thid_t tid);

// Add a new trace element to the current trace
// Type:         Synchronous function
// Notification: None

void idaapi dbg_add_tev(tev_type_t type, thid_t tid, ea_t address);

// Structures used for dbg_add_many_tevs
struct tev_reg_value_t
{
  regval_t value;
  int reg_idx;

  tev_reg_value_t(int _reg_idx, uint64 _value) : reg_idx(_reg_idx)
  {
    value._set_int(_value);
  }
};
DECLARE_TYPE_AS_MOVABLE(tev_reg_value_t);
typedef qvector<tev_reg_value_t> tev_reg_values_t;

struct tev_info_reg_t
{
  tev_info_t info;
  tev_reg_values_t registers;
};
DECLARE_TYPE_AS_MOVABLE(tev_info_reg_t);
typedef qvector<tev_info_reg_t> tevinforeg_vec_t;


// Add many new trace elements to the current trace
// Type:         Synchronous function
// Notification: None
// Return:       False if the operation failed for any tev_info_t object,
//               true otherwise
bool idaapi dbg_add_many_tevs(tevinforeg_vec_t *new_tevs);

enum save_reg_values_t
{
  SAVE_ALL_VALUES = 0,
  SAVE_DIFF,
  SAVE_NONE
};

// Add a new instruction trace element to the current trace
// Type:         Synchronous function
// Notification: None
// Return:       False if the operation failed, true otherwise

bool idaapi dbg_add_insn_tev(thid_t tid, ea_t ea, save_reg_values_t save=SAVE_DIFF);

// Add a new breakpoint trace element to the current trace
// Type:         Synchronous function
// Notification: None
// Return:       False if the operation failed, true otherwise

bool idaapi dbg_add_bpt_tev(thid_t tid, ea_t ea, ea_t bp);

// Add a new call trace element to the current trace
// Type:         Synchronous function
// Notification: None

void idaapi dbg_add_call_tev(thid_t tid, ea_t caller, ea_t callee);

// Add a new return trace element to the current trace
// Type:         Synchronous function
// Notification: None

void idaapi dbg_add_ret_tev(thid_t tid, ea_t ret_insn, ea_t return_to);

// Add a new debug event to the current trace
// Type:         Synchronous function
// Notification: None

void idaapi dbg_add_debug_event(debug_event_t *event);

//---------------------------------------------------------------------------
//                    Trace management functions
//---------------------------------------------------------------------------

// Load a recorded trace file in the trace window
//
// If the call succeeds and 'buf' is not null, the description of the
// trace stored in the binary trace file will be returned in 'buf'
bool idaapi load_trace_file(const char *filename, char *buf, size_t bufsize);

// Save the current trace in the specified file
bool idaapi save_trace_file(const char *filename, const char *description);

// Is the specified file a valid trace file for the current database?
bool idaapi is_valid_trace_file(const char *filename);

// Change the description of the specified trace file
bool idaapi set_trace_file_desc(const char *filename, const char *description);

// Get the file header of the specified trace file
bool idaapi get_trace_file_desc(const char *filename, char *buf, size_t bufsize);

// Show the choose trace dialog
bool idaapi choose_trace_file(char *buf, size_t bufsize);

// Show difference between the current trace and the one from 'filename'
bool idaapi diff_trace_file(const char *filename);

// Show the trace callgraph
bool idaapi graph_trace(void);

// Set highlight trace parameters.
void idaapi set_highlight_trace_options(
    bool highlight,
    bgcolor_t color,
    bgcolor_t diff);

// Set/get platform name of current trace
void idaapi set_trace_platform(const char *platform);
const char *idaapi get_trace_platform();

#endif // SWIG

//---------------------------------------------------------------------------
//      High level functions (usable from scripts)
//--------------------------------------------------------------------
// Wait for the next debugger event
// See also get_process_state() to get info about the current state
// of the debugged application

// debugger event codes:
enum dbg_event_code_t
{
  DEC_NOTASK  = -2,  // process does not exist
  DEC_ERROR   = -1,  // error
  DEC_TIMEOUT = 0,   // timeout
};
// If the retured value > 0, then it is the event id (see idd.hpp, event_id_t)

dbg_event_code_t idaapi wait_for_next_event(int wfne, int timeout_in_secs);
                           // wfne flag is combination of the following:
#define WFNE_ANY    0x0001 // return the first event (even if it doesn't suspend the process)
#define WFNE_SUSP   0x0002 // wait until the process gets suspended
#define WFNE_SILENT 0x0004 // 1: be slient, 0:display modal boxes if necessary
#define WFNE_CONT   0x0008 // continue from the suspended state
#define WFNE_NOWAIT 0x0010 // do not wait for any event, immediately return DEC_TIMEOUT
                           // (to be used with WFNE_CONT)
#define WFNE_USEC   0x0020 // timeout is specified in microseconds
                           // (minimum non-zero timeout is 40000us)


// Get the current debugger event

const debug_event_t *idaapi get_debug_event(void);


// Set debugger options
// Replaces debugger options with the specifiction combination of DOPT_..
// Returns the old debugger options

uint idaapi set_debugger_options(uint options);

#define DOPT_SEGM_MSGS    0x00000001 // log debugger segments modifications
#define DOPT_START_BPT    0x00000002 // break on process start
#define DOPT_THREAD_MSGS  0x00000004 // log thread starts/exits
#define DOPT_THREAD_BPT   0x00000008 // break on thread start/exit
#define DOPT_BPT_MSGS     0x00000010 // log breakpoints
//#define DOPT_BINS_BPT     0x00000020 // break on breakpoint instruction
#define DOPT_LIB_MSGS     0x00000040 // log library loads/unloads
#define DOPT_LIB_BPT      0x00000080 // break on library load/unload
#define DOPT_INFO_MSGS    0x00000100 // log debugging info events
#define DOPT_INFO_BPT     0x00000200 // break on debugging information
#define DOPT_REAL_MEMORY  0x00000400 // do not hide breakpoint instructions
#define DOPT_REDO_STACK   0x00000800 // reconstruct the stack
#define DOPT_ENTRY_BPT    0x00001000 // break on program entry point
#define DOPT_EXCDLG       0x00006000 // exception dialogs:
#  define EXCDLG_NEVER    0x00000000 // never display exception dialogs
#  define EXCDLG_UNKNOWN  0x00002000 // display for unknown exceptions
#  define EXCDLG_ALWAYS   0x00006000 // always display
#define DOPT_LOAD_DINFO   0x00008000 // automatically load debug files (pdb)
#define DOPT_END_BPT      0x00010000 // evaluate event condition on process end
#define DOPT_TEMP_HWBPT   0x00020000 // when possible use hardware bpts for temp bpts

// Set remote debugging options
// Should be used before starting the debugger.
//      host - If host is empty, then IDA will use local debugger.
//             If host is NULL then the host will not be set
//      pass - If pass is NULL then the password will not be set
//      port - If port is -1 then the default port number will be used

void idaapi set_remote_debugger(const char *host, const char *pass, int port=-1);


// Get process options.
// Any of the arguments may be NULL

void idaapi get_process_options(qstring *path, qstring *args, qstring *sdir,
                                qstring *host, qstring *pass, int *port);


// Set process options.
// Any of the arguments may be NULL, which means 'do not modify'

void idaapi set_process_options(const char *path, const char *args, const char *sdir,
                                const char *host, const char *pass, int port);


// Retrieve the exception information
// You may freely modify the returned vector and add/edit/delete exceptions
// You must call store_exceptions() after any modifications
// Note: exceptions with code zero, multiple exception codes or names are prohibited
excvec_t *idaapi retrieve_exceptions(void);

// Update the exception information stored in the debugger module by
// invoking its dbg->set_exception_info callback
bool idaapi store_exceptions(void);


// Convenience function: define new exception code
//      code - exception code (can not be 0)
//      name - exception name (can not be empty or NULL)
//      desc - exception description (maybe NULL)
//      flags - combination of EXC_... flags
// returns: failure message or NULL
// you must call store_exceptions() if this function succeeds

const char *idaapi define_exception(uint code, const char *name, const char *desc, int flags);


//--------------------------------------------------------------------
// Is set_dbg_options() present in debugger_t?
inline bool have_set_options(const debugger_t *_dbg)
{
  return _dbg != NULL && _dbg->version >= 10 && _dbg->set_dbg_options != NULL;
}


//--------------------------------------------------------------------
// Convenience function to set debugger specific options. It checks if the debugger
// is present and the function is present and calls it.
inline const char *idaapi set_dbg_options(
        debugger_t *_dbg,
        const char *keyword,
        int pri,
        int value_type,
        const void *value)
{
  const char *code = IDPOPT_BADKEY;
  if ( have_set_options(_dbg) )
  {
    if ( _dbg->version < 17 )
    {
      typedef const char *idaapi old_setopts_t(const char *keyword,
                                            int value_type, const void *value);
      old_setopts_t *old_setopt = *(old_setopts_t**)&_dbg->set_dbg_options;
      code = old_setopt(keyword, value_type, value);
    }
    else
    {
      code = _dbg->set_dbg_options(keyword, pri, value_type, value);
    }
  }
  return code;
}

inline const char *idaapi set_dbg_options(
        const char *keyword,
        int pri,
        int value_type,
        const void *value)
{
  return set_dbg_options(dbg, keyword, pri, value_type, value);
}

inline const char *idaapi set_dbg_default_options(
        const char *keyword,
        int value_type,
        const void *value)
{
  return set_dbg_options(keyword, IDPOPT_PRI_DEFAULT, value_type, value);
}
inline const char *idaapi set_int_dbg_options(
        const char *keyword,
        int32 value)
{
  sval_t sv = value;
  return set_dbg_default_options(keyword, IDPOPT_NUM, &sv);
}


//---------------------------------------------------------------------------
//      S O U R C E  I N F O R M A T I O N  P R O V I D E R S
//---------------------------------------------------------------------------
// These providers supply information about the source files and lines
// to the source level debugger.
//
// NOTE: objects described below must be freed using the release() methods.
//       do not use the 'delete' operator!
//       (gcc & vc use different vtable layout for virtual destructors)
//
// Currently this interface is not frozen and may change.
// We will freeze it once we settle down things.

class srcinfo_provider_t;

#define ENABLE_SRCDBG // not ready yet
#ifdef ENABLE_SRCDBG
class idc_value_t;
class areaset_t;
class source_item_t;
class argloc_t;

// source item iterator
typedef qrefcnt_t<source_item_t> source_item_ptr;
typedef qiterator<source_item_ptr> _source_item_iterator;
typedef qrefcnt_t<_source_item_iterator> source_item_iterator;

//--------------------------------------------------------------------------
// Execution context. Currently not defined in detail. Will probably
// hold information about the execution context, like:
//      - thread id
//      - current register values
//      - stack frame address

class eval_ctx_t
{
  int size_cb;
public:
  eval_ctx_t(ea_t _ea) : size_cb(sizeof(*this)), ea(_ea) {}
  ea_t ea;
};


#ifndef __UI__
namespace Forms { class TForm; }
#endif

//--------------------------------------------------------------------------
// Source file.
class source_file_t : public qrefcnt_obj_t
{
public:
  // call this function to free source_file_t
  virtual void idaapi release() = 0;

  // get source info provider
  // there is no need to free or release it after using
  virtual srcinfo_provider_t *idaapi get_provider(void) const = 0;

  // get path to the source file (or a symbolic name)
  //   errbuf - pointer to buffer for the error message
  virtual const char *idaapi get_path(qstring *errbuf) = 0;

  // open window with source code (optional function)
  //   strvec - out: pointer to source text. the text should not be destroyed until the form is closed
  //   pview  - out: pointer to view that displays the source text (subview of TForm)
  //   x,y    - in: cursor coordinates
  virtual TForm *open_srcview(strvec_t **strvec, TCustomControl **pview, int lnnum, int colnum) = 0;

  // read entire file (colored lines)
  //   buf    - pointer to output buffer
  //   errbuf - pointer to buffer for the error message
  virtual bool idaapi read_file(strvec_t *buf, qstring *errbuf) = 0;
};

// source file iterator
typedef qrefcnt_t<source_file_t> source_file_ptr;
typedef qiterator<source_file_ptr> _source_file_iterator;
typedef qrefcnt_t<_source_file_iterator> source_file_iterator;

//--------------------------------------------------------------------------
// Kind of a source item.
// Source items are organized into trees. Each tree starts with a MODULE.
// Each MODULE consists of FUNC and STTVAR global items.
// Each FUNC consists of STMTs (statements).
// Each STMT contains some EXPRs (expressions).
enum src_item_kind_t
{
  SRCIT_NONE,       // unknown
  SRCIT_MODULE,     // module
  SRCIT_FUNC,       // function
  SRCIT_STMT,       // a statement (if/while/for...)
  SRCIT_EXPR,       // an expression (a+b*c)
  SRCIT_STKVAR,     // deprecated
  SRCIT_REGVAR,     // deprecated
  SRCIT_RRLVAR,     // deprecated
  SRCIT_STTVAR,     // static variable/code
  SRCIT_LOCVAR      // a stack, register, or register-relative local variable or parameter
};

//--------------------------------------------------------------------------
// Source item.
class source_item_t : public qrefcnt_obj_t
{
public:
  // call this function to free source_item_t
  virtual void idaapi release() = 0;

  // get source files of the item
  virtual source_file_iterator idaapi get_source_files() = 0;

  // get name of the item
  virtual bool idaapi get_name(qstring *buf) const = 0;

  // get line number of the item
  virtual int idaapi get_lnnum() const = 0;

  // get ending line number
  // the returned line number is the next
  // line after the expression
  virtual int idaapi get_end_lnnum() const = 0;

  // get column number of the item
  // if unknown, return -1
  virtual int idaapi get_colnum() const = 0;

  // get ending column number
  // the returned column number is the next
  // column after the expression
  // if unknown, return -1
  virtual int idaapi get_end_colnum() const = 0;

  // get starting address of the item
  virtual ea_t idaapi get_ea() const = 0;

  // get size of the item in bytes
  // if the item is fragmented, return size
  // of the main fragment
  // if unknown, return 0.
  // On error, return (asize_t) -1.
  virtual asize_t idaapi get_size() const = 0;

  // get item boundaries as a set of areas
  // this function will be used to determine what breakpoints to set for
  // stepping into/stepping over the item.
  virtual bool idaapi get_item_bounds(areaset_t *set) const = 0;

  // get parent of the item
  //   max_kind - maximal source item kind we are interested in
  //              for example, if max_kinds==SRC_STMT, we are not interested
  //              in expressions, only in the enclosing statement or function
  virtual source_item_ptr idaapi get_parent(src_item_kind_t max_kind) const = 0;

  // create an iterator to enumerate all children of the item
  virtual source_item_iterator idaapi create_children_iterator() = 0;

  // calculate a string to display as a hint
  //    ctx - execution context. NULL means missing context.
  //    hint - output buffer for the hint (may by multiline & with colors)
  //    nlines - number of important lines in the hint
  virtual bool idaapi get_hint(
        const eval_ctx_t *ctx,
        qstring *hint,
        int *nlines) const = 0;

  // evaluate item value (meaningful only for expression items)
  //    ctx - execution context. NULL means missing context.
  //    res - buffer for the result (or exception if evaluation failed)
  //    errbuf - buffer for the error message
  virtual bool idaapi evaluate(
        const eval_ctx_t *ctx,
        idc_value_t *res,
        qstring *errbuf) const = 0;

  // The following functions can be used to extract the item information
  // in order to modify it. For example, if the user wants to modify a variable
  // we will find what exactly needs to be modified.

  // Deprecated. See #get_item_kind(eval_ctx_t *ctx).
  virtual src_item_kind_t idaapi get_item_kind() const { return SRCIT_NONE; }
  bool is_stmt()   const { return get_item_kind() == SRCIT_STMT; }
  bool is_module() const { return get_item_kind() == SRCIT_MODULE; }
  bool is_func()   const { return get_item_kind() == SRCIT_FUNC; }
  bool is_expr()   const { return get_item_kind() >= SRCIT_EXPR; }
  bool is_var()    const { return get_item_kind() >= SRCIT_STKVAR; }
  bool is_stkvar() const { return get_item_kind() == SRCIT_STKVAR; }
  bool is_regvar() const { return get_item_kind() == SRCIT_REGVAR; }
  bool is_rrlvar() const { return get_item_kind() == SRCIT_RRLVAR; }
  bool is_sttvar() const { return get_item_kind() == SRCIT_STTVAR; }

  // Deprecated. See #get_location.
  virtual bool idaapi get_stkvar_info(char *, size_t, uval_t *, ea_t) const { return false; }
  // Deprecated. See #get_location.
  virtual bool idaapi get_regvar_info(char *, size_t) const { return false; }
  // Deprecated. See #get_location.
  virtual bool idaapi get_rrlvar_info(char *, size_t, uval_t *) const { return false; }

  // Deprecated. See get_expr_tinfo
  virtual bool idaapi get_expr_type(qtype *, qtype *) const { return false; }

  // get source info provider
  // The instance shouldn't be freed or released after using
  virtual srcinfo_provider_t *idaapi get_provider(void) const = 0;

  // Do these two items have the same source?
  // Conforming implementations should behave as follows:
  //  return false when the source of the underlying data
  //               differs between the two items.
  //  return true when either the source of the underlying
  //              data is the same for the two items, or
  //              when such information is not available.
  //
  // E.g., A DWARF implementation of source_item_t will
  // return true if the two items are backed by DIEs
  // that have the same file offset.
  virtual bool idaapi equals(const source_item_t *other) const = 0;

  // WARNING: Do ***NOT*** name this 'get_item_kind()'. Counting on
  // polymorphism to tell methods apart is not something
  // that works with VisualStudio: It'll put this 'get_item_kind(const eval_ctx_t *)'
  // right alongside the 'get_item_kind()' in the VTable, thereby offset'ing all other
  // virtual methods, causing the Hex-Rays source-level debugging to
  // fail miserably.
  // Thank you for such a wonderful time, VS.
  virtual src_item_kind_t idaapi get_kind(const eval_ctx_t * /*ctx*/) const { return SRCIT_NONE; }
  bool is_stmt(const eval_ctx_t *ctx)   const { return get_kind(ctx) == SRCIT_STMT; }
  bool is_module(const eval_ctx_t *ctx) const { return get_kind(ctx) == SRCIT_MODULE; }
  bool is_func(const eval_ctx_t *ctx)   const { return get_kind(ctx) == SRCIT_FUNC; }
  bool is_expr(const eval_ctx_t *ctx)   const { return get_kind(ctx) >= SRCIT_EXPR; }
  bool is_locvar(const eval_ctx_t *ctx) const { return get_kind(ctx) >= SRCIT_LOCVAR; }
  bool is_sttvar(const eval_ctx_t *ctx) const { return get_kind(ctx) == SRCIT_STTVAR; }

  // Get the location for this source item.
  virtual bool idaapi get_location(argloc_t * /*out*/, const eval_ctx_t * /*ctx*/) const { return false; }
  // Get expression type
  virtual bool idaapi get_expr_tinfo(tinfo_t *tif) const = 0;
};

#define SRCDBG_PROV_VERSION 3

//--------------------------------------------------------------------------
class srcinfo_provider_t
{
public:
  // size of this class
  size_t cb;

  // various flags
  int flags;
#define SPF_DECOMPILER    0x0001        // is a decompiler?
#define SPF_ENABLED       0x0002        // enabled by the user
                                        // (this bit is managed by ida)
#define SPF_ACTIVE        0x0004        // is willing to work with the current idb
                                        // (this bit is managed by ida)
#define SPF_VERSION_MASK  0xFF000000    // Version mask, in the flags.
                                        // No other flag should have a bit rank > 23.

  // internal (unique) name of srcinfo provider
  const char *name;

  // external (displayable) name of srcinfo provider
  const char *display_name;

  srcinfo_provider_t(const char *_name, const char *_display_name, int _flags=0)
    : cb(sizeof(*this)), flags(_flags), name(_name), display_name(_display_name)
  {
    flags |= SRCDBG_PROV_VERSION << 24;
  }

  bool is_decompiler(void) const { return (flags & SPF_DECOMPILER) != 0; }
  bool is_enabled(void) const { return (flags & SPF_ENABLED) != 0; }
  bool is_active(void) const { return (flags & SPF_ACTIVE) != 0; }

  uint8 get_version() const { return (flags >> 24) & 0xFF; }

  // enable or disable the provider
  // if the provider fails to initialize, it returns false, otherwise true
  virtual bool idaapi enable_provider(bool enable) = 0;

  // configure srcinfo provider
  // see the description of set_options_t (idp.hpp)
  virtual const char *idaapi set_options(
        const char *keyword,
        int value_type,
        const void *value) = 0;

  // inform the provider that a module got loaded.
  // the provider is not required to read the module information immediately;
  // it may postpone it until really required.
  virtual void idaapi add_module(const char *path, ea_t base, asize_t size) = 0;

  // inform the provider that a module got unloaded.
  virtual void idaapi del_module(ea_t base) = 0;

  // inform the provider that we will request for information now.
  // this function must be called before calling all functions below.
  // probably it will be called when the process gets suspended.
  virtual void idaapi get_ready(void) = 0;

  // ask the provider if the source information has changed
  // and the screen should be refreshed. UI will call this function
  // periodically (when idle). if it returns a flag value other than SPCH_NONE,
  // then the source information must be refreshed.
  virtual int idaapi get_change_flags(void) = 0;
#define SPCH_NONE  0x0000       // nothing has changed
#define SPCH_FILES 0x0001       // source files have changed
#define SPCH_ITEMS 0x0002       // source items have changed
#define SPCH_LINES 0x0004       // source line numbers have changed

  // locate source item by address
  // the kernel will inquire all registered providers and use the best reply.
  //    ea    - linear address
  //    size  - size of the item
  //    level - the desired item level:
  //            SRCIT_STMT   - a statement
  //            SRCIT_EXPR   - an expression
  //            SRCIT_FUNC   - a global code item
  //            SRCIT_xxxVAR - a global data item (the exact type is not checked)
  //    may_decompile - meaningful only for the decompiler. if set to false
  //            and the function at 'ea' has not been decompiled yet, fail.
  virtual source_item_iterator idaapi find_source_items(
        ea_t ea,
        asize_t size,
        src_item_kind_t level,
        bool may_decompile) = 0;

  // locate source item by a position in a source file
  // if colnum == 0, return the statement that starts at the specified line
  // if lnnum == 0, return information about all lines (colnum is ignored in this case)
  virtual source_item_iterator idaapi find_source_items(source_file_t *sf, int lnnum, int colnum=0) = 0;

  // create iterators to enumerate files
  //   filename - name of the source file to enumerate
  virtual source_file_iterator idaapi create_file_iterator(const char *filename=NULL) = 0;
  // create iterators to enumerate items
  virtual source_item_iterator idaapi create_item_iterator(const source_file_t *sf) = 0;
};


//--------------------------------------------------------------------------
// Register a source information provider.
// Source information providers will call this function to register themselves
// with IDA kernel.
// Returns false: a service provider with this name already exists.

bool idaapi register_srcinfo_provider(srcinfo_provider_t *sp);


// Unregister a source information provider.
// Returns false: no such provider.

bool idaapi unregister_srcinfo_provider(srcinfo_provider_t *sp);


#ifndef __UI__
class source_view_t;
inline source_view_t *create_source_viewer(
        TWinControl *parent,
        TCustomControl *custview,
        source_file_ptr sf,
        strvec_t *lines,
        int lnnum,
        int colnum,
        int flags)
{
  return (source_view_t *)callui(ui_new_source_viewer, parent, custview, &sf,
                                 lines, lnnum, colnum, flags).vptr;
}
#endif
#endif // ENABLE_SRCDBG

//--------------------------------------------------------------------------
// Get one byte of the debugged process memory
//      ea - linear address
//      x  - pointer to byte value
// returns: true-success, false-address inaccessible or debugger not running

idaman bool ida_export get_dbg_byte(ea_t ea, uint32 *x);


// Change one byte of the debugged process memory
//      ea - linear address
//      x  - byte value
// returns: true-the process memory has been modified

idaman bool ida_export put_dbg_byte(ea_t ea, uint32 x);


//--------------------------------------------------------------------------
//      D E B U G G E R  M E M O R Y  F U N C T I O N S  F O R  U I
//--------------------------------------------------------------------------

// Set the memory information source for IDA kernel
// This function allows the kernel to use information coming from somewhere
// else than the database (from the debugger, for example)
//   dbg_get_memory_config - returns current memory configuration
//                           in the dynamic memory allocated by qalloc()
//                           The kernel will qfree() is automatically
//                           n - number of area_t elements in the answer
//                           If dbg_get_memory_config == NULL, then the debugged
//                           process memory is not used
//   memory_read           - read bytes from the debugged process memory
//   memory_write          - write bytes to the debugged process memory
//                           (don't forget to call invalidate_dbgmem_contents() from it)

idaman void ida_export set_dbgmem_source(
        area_t *(idaapi*dbg_get_memory_config)(int *n),
        int (idaapi*memory_read) (ea_t ea, void *buffer, int size),
        int (idaapi*memory_write)(ea_t ea, const void *buffer, int size));

// Invalidate the debugged process memory configuration
// Call this function if the debugged process might have changed its memory
// layout (allocated more memory, for example)

idaman void ida_export invalidate_dbgmem_config(void);


// Invalidate the debugged process memory contents
// Call this function each time the process has been stopped or the process
// memory is modified
// if ea == BADADDR, then the whole memory contents will be invalidated

idaman void ida_export invalidate_dbgmem_contents(ea_t ea, asize_t size);


// Is the debugger currently running?

idaman bool ida_export is_debugger_on(void);


// Is the address mapped to debugger memory?

idaman bool ida_export is_debugger_memory(ea_t ea);


//--------------------------------------------------------------------------
// internal structure, do not use. use exported appcall() function
struct appcall_info_t
{
  int options;
  int nargs;
  ea_t func_ea;
  thid_t tid;
  const struct func_type_data_t *fti;
  const struct regobjs_t *regargs;
  struct relobj_t *stkargs;
  struct regobjs_t *retregs;
  qstring errbuf;
  debug_event_t event;
};

// internal function, do not use.
idaman void ida_export inform_idc_about_debthread(qthread_t dt);

// internal kernel functions to lock the debugger memory configuration updates
void lock_dbgmem_config(void);
void unlock_dbgmem_config(void);
bool is_dbgmem_valid(void);

//--------------------------------------------------------------------------
#ifndef __UI__         // Not for the UI

// Convenience functions offered by the user interface

inline bool idaapi run_requests(void)                                                         { return callui(ui_dbg_run_requests).cnd; }
inline ui_notification_t idaapi get_running_request(void)                                     { return (ui_notification_t)callui(ui_dbg_get_running_request).i; }
inline dbg_notification_t idaapi get_running_notification(void)                               { return (dbg_notification_t)callui(ui_dbg_get_running_notification).i; }
inline void idaapi clear_requests_queue(void)                                                 { callui(ui_dbg_clear_requests_queue); }
inline int idaapi get_process_state(void)                                                     { return callui(ui_dbg_get_process_state).i; }
inline int idaapi start_process(const char *path, const char *args, const char *sdir)         { return callui(ui_dbg_start_process, path, args, sdir).i; }
inline int idaapi request_start_process(const char *path, const char *args, const char *sdir) { return callui(ui_dbg_request_start_process, path, args, sdir).i; }
inline bool idaapi suspend_process(void)                                                      { return callui(ui_dbg_suspend_process).cnd; }
inline bool idaapi request_suspend_process(void)                                              { return callui(ui_dbg_request_suspend_process).cnd; }
inline bool idaapi continue_process(void)                                                     { return callui(ui_dbg_continue_process).cnd; }
inline bool idaapi request_continue_process(void)                                             { return callui(ui_dbg_request_continue_process).cnd; }
inline bool idaapi exit_process(void)                                                         { return callui(ui_dbg_exit_process).cnd; }
inline bool idaapi request_exit_process(void)                                                 { return callui(ui_dbg_request_exit_process).cnd; }
inline int idaapi get_process_qty(void)                                                       { return callui(ui_dbg_get_process_qty).i; }
inline pid_t idaapi get_process_info(int n, process_info_t *process_info)                     { return (pid_t)callui(ui_dbg_get_process_info, n, process_info).i; }
inline int idaapi attach_process(pid_t pid, int event_id)                                     { return callui(ui_dbg_attach_process, pid, event_id).i; }
inline int idaapi request_attach_process(pid_t pid, int event_id)                             { return callui(ui_dbg_request_attach_process, pid, event_id).i; }
inline bool idaapi detach_process(void)                                                       { return callui(ui_dbg_detach_process).cnd; }
inline bool idaapi request_detach_process(void)                                               { return callui(ui_dbg_request_detach_process).cnd; }
inline int idaapi get_thread_qty(void)                                                        { return callui(ui_dbg_get_thread_qty).i; }
inline thid_t idaapi getn_thread(int n)                                                       { return (thid_t)callui(ui_dbg_getn_thread, n).i; }
inline bool idaapi select_thread(thid_t tid)                                                  { return callui(ui_dbg_select_thread, tid).cnd; }
inline bool idaapi request_select_thread(thid_t tid)                                          { return callui(ui_dbg_request_select_thread, tid).cnd; }
inline bool idaapi step_into(void)                                                            { return callui(ui_dbg_step_into).cnd; }
inline bool idaapi request_step_into(void)                                                    { return callui(ui_dbg_request_step_into).cnd; }
inline bool idaapi step_over(void)                                                            { return callui(ui_dbg_step_over).cnd; }
inline bool idaapi request_step_over(void)                                                    { return callui(ui_dbg_request_step_over).cnd; }
inline bool idaapi run_to(ea_t ea)                                                            { return callui(ui_dbg_run_to, ea).cnd; }
inline bool idaapi request_run_to(ea_t ea)                                                    { return callui(ui_dbg_request_run_to, ea).cnd; }
inline bool idaapi step_until_ret(void)                                                       { return callui(ui_dbg_step_until_ret).cnd; }
inline bool idaapi request_step_until_ret(void)                                               { return callui(ui_dbg_request_step_until_ret).cnd; }
inline bool idaapi get_reg_val(const char *regname, regval_t *regval)                         { return callui(ui_dbg_get_reg_val, regname, regval).cnd; }
inline bool idaapi set_reg_val(const char *regname, const regval_t *regval)                   { return callui(ui_dbg_set_reg_val, regname, regval).cnd; }
inline bool idaapi request_set_reg_val(const char *regname, const regval_t *regval)           { return callui(ui_dbg_request_set_reg_val, regname, regval).cnd; }
inline int idaapi get_bpt_qty(void)                                                           { return callui(ui_dbg_get_bpt_qty).i; }
inline bool idaapi getn_bpt(int n, bpt_t *bpt)                                                { return callui(ui_dbg_getn_bpt, n, bpt).cnd; }
inline bool idaapi get_bpt(ea_t ea, bpt_t *bpt)                                               { return callui(ui_dbg_get_bpt, ea, bpt).cnd; }
inline bool idaapi find_bpt(const bpt_location_t &bptloc, bpt_t *bpt)                         { return callui(ui_dbg_find_bpt, &bptloc, bpt).cnd; }
inline bool idaapi add_bpt(ea_t ea, asize_t size, bpttype_t type)                             { return callui(ui_dbg_add_oldbpt, ea, size, type).cnd; }
inline bool idaapi add_bpt(const bpt_t &bpt)                                                  { return callui(ui_dbg_add_bpt, &bpt).cnd; }
inline bool idaapi request_add_bpt(ea_t ea, asize_t size, bpttype_t type)                     { return callui(ui_dbg_request_add_oldbpt, ea, size, type).cnd; }
inline bool idaapi request_add_bpt(const bpt_t &bpt)                                          { return callui(ui_dbg_request_add_bpt, &bpt).cnd; }
inline bool idaapi del_bpt(ea_t ea)                                                           { return callui(ui_dbg_del_oldbpt, ea).cnd; }
inline bool idaapi del_bpt(const bpt_location_t &bptloc)                                      { return callui(ui_dbg_del_bpt, &bptloc).cnd; }
inline bool idaapi request_del_bpt(ea_t ea)                                                   { return callui(ui_dbg_request_del_oldbpt, ea).cnd; }
inline bool idaapi request_del_bpt(const bpt_location_t &bptloc)                              { return callui(ui_dbg_request_del_bpt, &bptloc).cnd; }
inline bool idaapi update_bpt(const bpt_t *bpt)                                               { return callui(ui_dbg_update_bpt, bpt).cnd; }
inline bool idaapi enable_bpt(ea_t ea, bool enable)                                           { return callui(ui_dbg_enable_oldbpt, ea, enable).cnd; }
inline bool idaapi enable_bpt(const bpt_location_t &bptloc, bool enable)                      { return callui(ui_dbg_enable_bpt, &bptloc, enable).cnd; }
inline bool idaapi request_enable_bpt(ea_t ea, bool enable)                                   { return callui(ui_dbg_request_enable_oldbpt, ea, enable).cnd; }
inline bool idaapi request_enable_bpt(const bpt_location_t &bptloc, bool enable)              { return callui(ui_dbg_request_enable_bpt, &bptloc, enable).cnd; }
inline bool idaapi set_trace_size(int size)                                                   { return callui(ui_dbg_set_trace_size, size).cnd; }
inline void idaapi clear_trace(void)                                                          { callui(ui_dbg_clear_trace); }
inline void idaapi request_clear_trace(void)                                                  { callui(ui_dbg_request_clear_trace); }
inline bool idaapi is_step_trace_enabled(void)                                                { return callui(ui_dbg_is_step_trace_enabled).cnd; }
inline bool idaapi enable_step_trace(int enable)                                              { return callui(ui_dbg_enable_step_trace, enable).cnd; }
inline bool idaapi request_enable_step_trace(int enable)                                      { return callui(ui_dbg_request_enable_step_trace, enable).cnd; }
inline int idaapi get_step_trace_options(void)                                                { return callui(ui_dbg_get_step_trace_options).i; }
inline void idaapi set_step_trace_options(int options)                                        { callui(ui_dbg_set_step_trace_options, options); }
inline void idaapi request_set_step_trace_options(int options)                                { callui(ui_dbg_request_set_step_trace_options, options); }
inline bool idaapi is_insn_trace_enabled(void)                                                { return callui(ui_dbg_is_insn_trace_enabled).cnd; }
inline bool idaapi enable_insn_trace(bool enable)                                             { return callui(ui_dbg_enable_insn_trace, enable).cnd; }
inline bool idaapi request_enable_insn_trace(bool enable)                                     { return callui(ui_dbg_request_enable_insn_trace, enable).cnd; }
inline int idaapi get_insn_trace_options(void)                                                { return callui(ui_dbg_get_insn_trace_options).i; }
inline void idaapi set_insn_trace_options(int options)                                        { callui(ui_dbg_set_insn_trace_options, options); }
inline void idaapi request_set_insn_trace_options(int options)                                { callui(ui_dbg_request_set_insn_trace_options, options); }
inline bool idaapi is_func_trace_enabled(void)                                                { return callui(ui_dbg_is_func_trace_enabled).cnd; }
inline bool idaapi enable_func_trace(bool enable)                                             { return callui(ui_dbg_enable_func_trace, enable).cnd; }
inline bool idaapi request_enable_func_trace(bool enable)                                     { return callui(ui_dbg_request_enable_func_trace, enable).cnd; }
inline int idaapi get_func_trace_options(void)                                                { return callui(ui_dbg_get_func_trace_options).i; }
inline void idaapi set_func_trace_options(int options)                                        { callui(ui_dbg_set_func_trace_options, options); }
inline void idaapi request_set_func_trace_options(int options)                                { callui(ui_dbg_request_set_func_trace_options, options); }
inline void idaapi set_highlight_trace_options(bool highlight, bgcolor_t color, bgcolor_t diff)
      { callui(ui_dbg_set_highlight_trace_options, highlight, color, diff); }
inline bool idaapi is_bblk_trace_enabled(void)                                                { return callui(ui_dbg_is_bblk_trace_enabled).cnd; }
inline bool idaapi enable_bblk_trace(bool enable)                                             { return callui(ui_dbg_enable_bblk_trace, enable).cnd; }
inline bool idaapi request_enable_bblk_trace(bool enable)                                     { return callui(ui_dbg_request_enable_bblk_trace, enable).cnd; }
inline int idaapi get_bblk_trace_options(void)                                                { return callui(ui_dbg_get_bblk_trace_options).i; }
inline void idaapi set_bblk_trace_options(int options)                                        { callui(ui_dbg_set_bblk_trace_options, options); }
inline void idaapi request_set_bblk_trace_options(int options)                                { callui(ui_dbg_request_set_bblk_trace_options, options); }
inline int idaapi get_tev_qty(void)                                                           { return callui(ui_dbg_get_tev_qty).i; }
inline bool idaapi get_tev_info(int n, tev_info_t *tev_info)                                  { return callui(ui_dbg_get_tev_info, n, tev_info).cnd; }
inline bool idaapi get_insn_tev_reg_val(int n, const char *regname, regval_t *regval)         { return callui(ui_dbg_get_insn_tev_reg_val, n, regname, regval).cnd; }
inline bool idaapi get_insn_tev_reg_mem(int n, memreg_infos_t *memmap)                        { return callui(ui_dbg_get_insn_tev_reg_mem, n, memmap).cnd; }
inline bool idaapi get_insn_tev_reg_result(int n, const char *regname, regval_t *regval)      { return callui(ui_dbg_get_insn_tev_reg_result, n, regname, regval).cnd; }
inline ea_t idaapi get_call_tev_callee(int n)                                                 { ea_t ea; callui(ui_dbg_get_call_tev_callee, n, &ea); return ea; }
inline ea_t idaapi get_ret_tev_return(int n)                                                  { ea_t ea; callui(ui_dbg_get_ret_tev_return, n, &ea); return ea; }
inline ea_t idaapi get_bpt_tev_ea(int n)                                                      { ea_t ea; callui(ui_dbg_get_bpt_tev_ea, n, &ea); return ea; }
inline bool idaapi get_tev_memory_info(int n, meminfo_vec_t *mi)                              { return callui(ui_dbg_get_tev_memory_info, n, mi).cnd; }
inline bool idaapi get_tev_event(int n, debug_event_t *d)                                     { return callui(ui_dbg_get_tev_event, n, d).cnd; }
inline ea_t idaapi get_tev_ea(int n)                                                          { ea_t ea; callui(ui_dbg_get_tev_ea, n, &ea); return ea; }
inline int  idaapi get_tev_type(int n)                                                        { return callui(ui_dbg_get_tev_type, n).i; }
inline int  idaapi get_tev_tid(int n)                                                         { return callui(ui_dbg_get_tev_tid, n).i; }
inline ea_t idaapi get_tev_reg_val(int n, const char *regname)                                { ea_t ea; callui(ui_dbg_get_tev_reg_val, n, regname, &ea); return ea; }
inline int  idaapi get_tev_reg_mem_qty(int n)                                                 { return callui(ui_dbg_get_tev_reg_mem_qty, n).i; }
inline ea_t idaapi get_tev_reg_mem_ea(int n, int idx)                                         { ea_t ea; callui(ui_dbg_get_tev_reg_mem_ea, n, idx, &ea); return ea; }
inline ea_t idaapi get_trace_base_address(void)                                               { ea_t ea; callui(ui_dbg_get_trace_base_address, &ea); return ea; }
inline bool idaapi load_trace_file(const char *filename, char *buf, size_t bufsize)           { return callui(ui_dbg_load_trace_file, filename, buf, bufsize).cnd; }
inline bool idaapi save_trace_file(const char *filename, const char *description)             { return callui(ui_dbg_save_trace_file, filename, description).cnd; }
inline bool idaapi is_valid_trace_file(const char *filename)                                  { return callui(ui_dbg_is_valid_trace_file, filename).cnd; }
inline bool idaapi set_trace_file_desc(const char *filename, const char *description)         { return callui(ui_dbg_set_trace_file_desc, filename, description).cnd; }
inline bool idaapi get_trace_file_desc(const char *filename, char *buf, size_t bufsize)       { return callui(ui_dbg_get_trace_file_desc, filename, buf, bufsize).cnd; }
inline bool idaapi choose_trace_file(char *buf, size_t bufsize)                               { return callui(ui_dbg_choose_trace_file, buf, bufsize).cnd; }
inline bool idaapi diff_trace_file(const char *filename)                                      { return callui(ui_dbg_diff_trace_file, filename).cnd; }
inline void idaapi set_trace_platform(const char *platform)
      { callui(ui_dbg_set_trace_platform, platform); }
inline const char *idaapi get_trace_platform()
      { return callui(ui_dbg_get_trace_platform).cptr; }
inline bool idaapi graph_trace(void)                                                          { return callui(ui_dbg_graph_trace).cnd; }

inline void idaapi set_trace_base_address(ea_t ea)                                            { callui(ui_dbg_set_trace_base_address, ea); }

inline void idaapi dbg_add_thread(thid_t tid)                                                 { callui(ui_dbg_add_thread, tid); }
inline void idaapi dbg_del_thread(thid_t tid)                                                 { callui(ui_dbg_del_thread, tid); }
inline void idaapi dbg_add_tev(tev_type_t type, thid_t tid, ea_t address)                     { callui(ui_dbg_add_tev, type, tid, address); }
inline bool idaapi dbg_add_many_tevs(tevinforeg_vec_t *new_tevs)                              { return callui(ui_dbg_add_many_tevs, new_tevs).cnd; }
inline bool idaapi dbg_add_insn_tev(thid_t tid, ea_t ea, save_reg_values_t save)              { return callui(ui_dbg_add_insn_tev, tid, ea, save).cnd; }
inline bool idaapi dbg_add_bpt_tev(thid_t tid, ea_t ea, ea_t bp)                              { return callui(ui_dbg_add_bpt_tev, tid, ea, bp).cnd; }
inline void idaapi dbg_add_call_tev(thid_t tid, ea_t caller, ea_t callee)                     { callui(ui_dbg_add_call_tev, tid, caller, callee); }
inline void idaapi dbg_add_ret_tev(thid_t tid, ea_t ret_insn, ea_t return_to)                 { callui(ui_dbg_add_ret_tev, tid, ret_insn, return_to); }
inline void idaapi dbg_add_debug_event(debug_event_t *event)                                  { callui(ui_dbg_add_debug_event, event); }

inline bool idaapi is_reg_integer(const char *regname)                                        { return callui(ui_dbg_get_reg_value_type, regname).i-2 == RVT_INT; }
inline bool idaapi is_reg_float(const char *regname)                                          { return callui(ui_dbg_get_reg_value_type, regname).i-2 == RVT_FLOAT; }
inline bool idaapi is_reg_custom(const char *regname)                                         { return callui(ui_dbg_get_reg_value_type, regname).i >= 2; }
inline bool idaapi get_first_module(module_info_t *modinfo)                                   { return callui(ui_dbg_get_first_module, modinfo).cnd; }
inline bool idaapi get_next_module(module_info_t *modinfo)                                    { return callui(ui_dbg_get_next_module, modinfo).cnd; }
inline void idaapi bring_debugger_to_front(void)                                              { callui(ui_dbg_bring_to_front); }
inline thid_t idaapi get_current_thread(void)                                                 { return callui(ui_dbg_get_current_thread).i; }
inline dbg_event_code_t idaapi wait_for_next_event(int wfne, int timeout)                     { return dbg_event_code_t(callui(ui_dbg_wait_for_next_event, wfne, timeout).i); }
inline const debug_event_t *idaapi get_debug_event(void)                                      { return (const debug_event_t *)callui(ui_dbg_get_debug_event).vptr; }
inline const char *idaapi get_debugger_event_cond(void)                                       { return callui(ui_dbg_get_event_cond).cptr; }
inline void idaapi set_debugger_event_cond(const char *cond)                                  { callui(ui_dbg_set_event_cond, cond); }
inline uint idaapi set_debugger_options(uint options)                                         { return callui(ui_dbg_set_debugger_options, options).i; }
inline void idaapi set_remote_debugger(const char *host, const char *pass, int port)          { callui(ui_dbg_set_remote_debugger, host, pass, port); }
inline bool idaapi load_debugger(const char *dbgname, bool use_remote)                        { return callui(ui_dbg_load_debugger, dbgname, use_remote).cnd; }
inline excvec_t *idaapi retrieve_exceptions(void)                                             { return (excvec_t *)callui(ui_dbg_retrieve_exceptions).vptr; }
inline bool idaapi store_exceptions(void)                                                     { return callui(ui_dbg_store_exceptions).cnd; }
inline const char *idaapi define_exception(uint code, const char *name, const char *desc, int flags) { return callui(ui_dbg_define_exception, code, name, desc, flags).cptr; }
inline int idaapi suspend_thread(thid_t tid)                                                  { return callui(ui_dbg_suspend_thread, tid).i; }
inline int idaapi request_suspend_thread(thid_t tid)                                          { return callui(ui_dbg_request_suspend_thread, tid).i; }
inline int idaapi resume_thread(thid_t tid)                                                   { return callui(ui_dbg_resume_thread, tid).i; }
inline int idaapi request_resume_thread(thid_t tid)                                           { return callui(ui_dbg_request_resume_thread, tid).i; }
inline void idaapi get_process_options(qstring *path, qstring *args, qstring *sdir, qstring *host, qstring *pass, int *port) { callui(ui_dbg_get_process_options, path, args, sdir, host, pass, port); }
inline void idaapi set_process_options(const char *path, const char *args, const char *sdir, const char *host, const char *pass, int port) { callui(ui_dbg_set_process_options, path, args, sdir, host, pass, port); }
inline int idaapi check_bpt(ea_t ea)                                                          { return callui(ui_dbg_check_bpt, ea).i; }
inline int idaapi set_process_state(int newstate, thid_t *p_thid, int dbginv)                 { return callui(ui_dbg_set_process_state, newstate, p_thid, dbginv).i; }
inline void idaapi get_manual_regions(meminfo_vec_t *areas)                                   { callui(ui_dbg_get_manual_regions, areas); }
inline void idaapi set_manual_regions(const meminfo_vec_t *areas)                             { callui(ui_dbg_set_manual_regions, areas); }
inline void idaapi edit_manual_regions()                                                      { callui(ui_dbg_edit_manual_regions); }
inline void idaapi enable_manual_regions(bool enable)                                         { callui(ui_dbg_enable_manual_regions, enable); }
inline bool idaapi is_debugger_busy(void)                                                     { return callui(ui_dbg_is_busy).cnd; }
inline int  idaapi hide_all_bpts(void)                                                        { return callui(ui_dbg_hide_all_bpts).i; }
inline bool idaapi register_srcinfo_provider(srcinfo_provider_t *sp)                          { return callui(ui_dbg_register_provider, sp).cnd; }
inline bool idaapi unregister_srcinfo_provider(srcinfo_provider_t *sp)                        { return callui(ui_dbg_unregister_provider, sp).cnd; }
inline int  idaapi handle_debug_event(const debug_event_t *ev, int rqflags)                   { return callui(ui_dbg_handle_debug_event, ev, rqflags).i; }
inline bool idaapi add_virt_module(const module_info_t *mod)                                  { return callui(ui_dbg_add_vmod, mod).cnd; }
inline bool idaapi del_virt_module(const ea_t base)                                           { return callui(ui_dbg_del_vmod, base).cnd; }
inline int  idaapi set_bptloc_string(const char *s)                                           { return callui(ui_dbg_set_bptloc_string, s).i; }
inline const char *idaapi get_bptloc_string(int i)                                            { return callui(ui_dbg_get_bptloc_string, i).cptr; }
inline ea_t idaapi internal_appcall(appcall_info_t *a)                                        { callui(ui_dbg_internal_appcall, a); return a->func_ea; }
inline int  idaapi internal_cleanup_appcall(thid_t tid)                                       { return callui(ui_dbg_internal_cleanup_appcall, tid).i; }
inline int  idaapi internal_get_sreg_base(thid_t tid, int sreg_value, ea_t *answer)           { return callui(ui_dbg_internal_get_sreg_base, tid, sreg_value, answer).i; }
inline int  idaapi internal_ioctl(int fn, const void *buf, size_t size, void **poutbuf, ssize_t *poutsize) { return callui(ui_dbg_internal_ioctl, fn, buf, size, poutbuf, poutsize).i; }
inline ssize_t idaapi read_dbg_memory(ea_t ea, void *buffer, size_t size)                     { return callui(ui_dbg_read_memory, ea, buffer, size).ssize; }
inline ssize_t idaapi write_dbg_memory(ea_t ea, const void *buffer, size_t size)              { return callui(ui_dbg_write_memory, ea, buffer, size).ssize; }
inline int idaapi get_reg_vals(thid_t tid, int clsmask, regval_t *values)                     { return callui(ui_dbg_read_registers, tid, clsmask, values).i; }
inline int idaapi set_reg_val(thid_t tid, int regidx, const regval_t *value)                  { return callui(ui_dbg_write_register, tid, regidx, value).i; }
inline int idaapi get_dbg_memory_info(meminfo_vec_t *areas)                                   { return callui(ui_dbg_get_memory_info, areas).i; }
inline void idaapi move_bpt_to_grp(bpt_t &bpt, const char *grp_name)                          { callui(ui_dbg_move_bpt_to_grp, &bpt, grp_name); }
inline const char *bpt_t::get_cnd_elang() const                                               { return (const char *)(callui(ui_dbg_internal_get_elang, this).cptr); }
inline bool bpt_t::set_cnd_elang(const char *name)                                            { return callui(ui_dbg_internal_set_elang, this, name).cnd; }
#endif

#pragma pack(pop)
#endif
