DynamoRIO
Basic Block Duplicator

Data Structures

struct  drbbdup_options_t
 
struct  drbbdup_stats_t
 

Macros

#define DRMGR_PRIORITY_APP2APP_NAME_DRBBDUP   "drbbdup_app2app"
 
#define DRMGR_PRIORITY_INSERT_NAME_DRBBDUP   "drbbdup_insert"
 
#define DRMGR_PRIORITY_RESTORE_NAME_DRBBDUP   "drbbdup_restore"
 

Typedefs

typedef uintptr_t(* drbbdup_set_up_bb_dups_t) (void *drbbdup_ctx, void *drcontext, void *tag, instrlist_t *bb, DR_PARAM_IN bool *enable_dups, DR_PARAM_IN bool *enable_dynamic_handling, void *user_data)
 
typedef bool(* drbbdup_allow_gen_t) (void *drcontext, void *tag, instrlist_t *ilist, uintptr_t new_case, bool *enable_dynamic_handling, void *user_data)
 
typedef void(* drbbdup_analyze_orig_t) (void *drcontext, void *tag, instrlist_t *bb, void *user_data, DR_PARAM_IN void **orig_analysis_data)
 
typedef void(* drbbdup_destroy_orig_analysis_t) (void *drcontext, void *user_data, void *orig_analysis_data)
 
typedef void(* drbbdup_analyze_case_t) (void *drcontext, void *tag, instrlist_t *bb, uintptr_t encoding, void *user_data, void *orig_analysis_data, DR_PARAM_IN void **case_analysis_data)
 
typedef dr_emit_flags_t(* drbbdup_analyze_case_ex_t) (void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating, uintptr_t encoding, void *user_data, void *orig_analysis_data, DR_PARAM_IN void **case_analysis_data)
 
typedef void(* drbbdup_destroy_case_analysis_t) (void *drcontext, uintptr_t encoding, void *user_data, void *orig_analysis_data, void *case_analysis_data)
 
typedef void(* drbbdup_insert_encode_t) (void *drcontext, void *tag, instrlist_t *bb, instr_t *where, void *user_data, void *orig_analysis_data)
 
typedef void(* drbbdup_instrument_instr_t) (void *drcontext, void *tag, instrlist_t *bb, instr_t *instr, instr_t *where, uintptr_t encoding, void *user_data, void *orig_analysis_data, void *case_analysis_data)
 
typedef dr_emit_flags_t(* drbbdup_instrument_instr_ex_t) (void *drcontext, void *tag, instrlist_t *bb, instr_t *instr, instr_t *where, bool for_trace, bool translating, uintptr_t encoding, void *user_data, void *orig_analysis_data, void *case_analysis_data)
 

Enumerations

enum  drbbdup_status_t {
  DRBBDUP_SUCCESS,
  DRBBDUP_ERROR_INVALID_PARAMETER,
  DRBBDUP_ERROR_INVALID_OPND,
  DRBBDUP_ERROR_CASE_ALREADY_REGISTERED,
  DRBBDUP_ERROR_CASE_LIMIT_REACHED,
  DRBBDUP_ERROR_ALREADY_INITIALISED,
  DRBBDUP_ERROR,
  DRBBDUP_ERROR_UNSET_FEATURE,
  DRBBDUP_ERROR_NOT_INITIALIZED
}
 
enum  {
  DRMGR_PRIORITY_APP2APP_DRBBDUP = 6500,
  DRMGR_PRIORITY_INSERT_DRBBDUP = -6500,
  DRMGR_PRIORITY_RESTORE_DRBBDUP = -99900
}
 

Functions

DR_EXPORT drbbdup_status_t drbbdup_init (drbbdup_options_t *ops_in)
 
DR_EXPORT drbbdup_status_t drbbdup_exit (void)
 
DR_EXPORT drbbdup_status_t drbbdup_register_case_encoding (void *drbbdup_ctx, uintptr_t encoding)
 
DR_EXPORT drbbdup_status_t drbbdup_is_first_instr (void *drcontext, instr_t *instr, DR_PARAM_OUT bool *is_start)
 
DR_EXPORT drbbdup_status_t drbbdup_is_first_nonlabel_instr (void *drcontext, instr_t *instr, bool *is_nonlabel)
 
DR_EXPORT drbbdup_status_t drbbdup_is_last_instr (void *drcontext, instr_t *instr, DR_PARAM_OUT bool *is_last)
 
DR_EXPORT drbbdup_status_t drbbdup_get_stats (DR_PARAM_OUT drbbdup_stats_t *stats)
 

Detailed Description

Macro Definition Documentation

◆ DRMGR_PRIORITY_APP2APP_NAME_DRBBDUP

#define DRMGR_PRIORITY_APP2APP_NAME_DRBBDUP   "drbbdup_app2app"

Name of drbbdup app2app priority.

◆ DRMGR_PRIORITY_INSERT_NAME_DRBBDUP

#define DRMGR_PRIORITY_INSERT_NAME_DRBBDUP   "drbbdup_insert"

Name of drbbdup insert priority.

◆ DRMGR_PRIORITY_RESTORE_NAME_DRBBDUP

#define DRMGR_PRIORITY_RESTORE_NAME_DRBBDUP   "drbbdup_restore"

Name of drbbdup restore state priority.

Typedef Documentation

◆ drbbdup_allow_gen_t

typedef bool(* drbbdup_allow_gen_t) (void *drcontext, void *tag, instrlist_t *ilist, uintptr_t new_case, bool *enable_dynamic_handling, void *user_data)

When a unregistered case new_case is identified as a candidate for dynamic handling, such a call-back function is invoked to give the user the opportunity to go ahead or stop the generation of an additional basic block copy. The call-back should return true if generation should be done, and false otherwise. In addition, the call-back can also turn off dynamic handling for the considered basic block by setting enable_dynamic_handling to false.

◆ drbbdup_analyze_case_ex_t

typedef dr_emit_flags_t(* drbbdup_analyze_case_ex_t) (void *drcontext, void *tag, instrlist_t *bb, bool for_trace, bool translating, uintptr_t encoding, void *user_data, void *orig_analysis_data, DR_PARAM_IN void **case_analysis_data)

Identical to drbbdup_analyze_case_t except for two extra parameters, "for_trace" and "translating", and the return value. These all match the same parameters and return values used with drmgr_analysis_cb_t and dr_register_bb_event(). The returned flags will be merged in the same manner as for drmgr_analysis_cb_t.

◆ drbbdup_analyze_case_t

typedef void(* drbbdup_analyze_case_t) (void *drcontext, void *tag, instrlist_t *bb, uintptr_t encoding, void *user_data, void *orig_analysis_data, DR_PARAM_IN void **case_analysis_data)

Conducts an analysis on a basic block with respect to a case with encoding encoding. The result of the analysis needs to be stored in case_analysis_data.

The user data user_data is that supplied to drbbdup_init(). Analysis data orig_analysis_data that was conducted on the original bb is also provided.

The user can use thread allocation for storing the analysis result.

The analysis data is destroyed via a drbbdup_analyze_case_t function.

◆ drbbdup_analyze_orig_t

typedef void(* drbbdup_analyze_orig_t) (void *drcontext, void *tag, instrlist_t *bb, void *user_data, DR_PARAM_IN void **orig_analysis_data)

Conducts an analysis of the original basic block. The call-back is not called for each case, but once for the overall fragment. Therefore, computationally expensive analysis that only needs to be done once per fragment can be implemented by this call-back and made available to all cases of the basic block. The function should store the analysis result in orig_analysis_data. The user data user_data is that supplied to drbbdup_init().

It is not possible to insert note labels via this analysis call-back function. Any labels inserted will not persist. Such functionality is only possible via a drbbdup_analyze_case_t call-back.

The user can use thread allocation for storing the analysis result.

The analysis data is destroyed via a drbbdup_destroy_orig_analysis_t function.

Returns
whether successful or an error code on failure.

◆ drbbdup_destroy_case_analysis_t

typedef void(* drbbdup_destroy_case_analysis_t) (void *drcontext, uintptr_t encoding, void *user_data, void *orig_analysis_data, void *case_analysis_data)

Destroys analysis data case_analysis_data for the case with encoding encoding.

The function is not invoked by drbbdup if case_analysis_data was set to NULL by the drbbdup_analyze_case_t function.

The user data user_data is that supplied to drbbdup_init(). Analysis data orig_analysis_data that was conducted on the original bb is also provided.

Note
The user should not destroy orig_analysis_data.

◆ drbbdup_destroy_orig_analysis_t

typedef void(* drbbdup_destroy_orig_analysis_t) (void *drcontext, void *user_data, void *orig_analysis_data)

Destroys analysis data orig_analysis_data.

The function is not invoked by drbbdup if orig_analysis_data was set to NULL by the the drbbdup_analyze_orig_t function.

◆ drbbdup_insert_encode_t

typedef void(* drbbdup_insert_encode_t) (void *drcontext, void *tag, instrlist_t *bb, instr_t *where, void *user_data, void *orig_analysis_data)

Inserts code responsible for encoding the current runtime case at point of entry to the dispatcher. The function should store the resulting pointer-sized encoding to memory that is directly accessible via the reference operand passed to drbbdup_init().

The user data user_data is that supplied to drbbdup_init(). Analysis data orig_analysis_data, which was conducted on the original bb, is also provided.

Note
This call-back is optional and if set to NULL when initializing drbbdup, the runtime case encoding is just loaded. The memory storing the runtime case encoding is not modified by drbbdup.

◆ drbbdup_instrument_instr_ex_t

typedef dr_emit_flags_t(* drbbdup_instrument_instr_ex_t) (void *drcontext, void *tag, instrlist_t *bb, instr_t *instr, instr_t *where, bool for_trace, bool translating, uintptr_t encoding, void *user_data, void *orig_analysis_data, void *case_analysis_data)

Identical to drbbdup_instrument_instr_t except for two extra parameters, "for_trace" and "translating", and the return value. These all match the same parameters and return values used with drmgr_insertion_cb_t and dr_register_bb_event(). The returned flags will be merged in the same manner as for drmgr_insertion_cb_t.

◆ drbbdup_instrument_instr_t

typedef void(* drbbdup_instrument_instr_t) (void *drcontext, void *tag, instrlist_t *bb, instr_t *instr, instr_t *where, uintptr_t encoding, void *user_data, void *orig_analysis_data, void *case_analysis_data)

A user-defined call-back function that is invoked to instrument an instruction instr. The inserted code must be placed at where.

Instrumentation must be driven according to the passed case encoding encoding.

The user data user_data is that supplied to drbbdup_init(). Analysis data orig_analysis_data and case_analysis_data are also provided.

◆ drbbdup_set_up_bb_dups_t

typedef uintptr_t(* drbbdup_set_up_bb_dups_t) (void *drbbdup_ctx, void *drcontext, void *tag, instrlist_t *bb, DR_PARAM_IN bool *enable_dups, DR_PARAM_IN bool *enable_dynamic_handling, void *user_data)

Set up initial information related to managing copies of a new basic block bb. A pointer-sized value indicating the default case encoding is returned. The boolean value written to enable_dups specifies whether code duplication should be done for this particular basic block. If false, the basic block is always executed under the default case and no duplications are made. The flag enable_dynamic_handling specifies whether additional copies should be dynamically generated to handle new case encodings identified during runtime. This option entails flushing but can lead to more efficient instrumentation depending on the user's application of drbbdup. The user data user_data is that supplied to drbbdup_init().

Use drbbdup_register_case_value(), passing drbbdup_ctx, to register other case encodings.

Returns
the default case encoding.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Priorities of drmgr instrumentation passes used by drbbdup. Users can perform app2app manipulations prior to duplication by ordering such changes before DRMGR_PRIORITY_APP2APP_DRBBDUP.

Enumerator
DRMGR_PRIORITY_APP2APP_DRBBDUP 

Priority of drbbdup's app2app stage.

DRMGR_PRIORITY_INSERT_DRBBDUP 

Priority of drbbdup's insert stage.

DRMGR_PRIORITY_RESTORE_DRBBDUP 

Priority of drbbdup's restore state event.

◆ drbbdup_status_t

Success code for each drbbdup operation.

Enumerator
DRBBDUP_SUCCESS 

Operation succeeded.

DRBBDUP_ERROR_INVALID_PARAMETER 

Operation failed: invalid parameter.

DRBBDUP_ERROR_INVALID_OPND 

Operation failed: invalid case opnd.

DRBBDUP_ERROR_CASE_ALREADY_REGISTERED 

Operation failed: already registered.

DRBBDUP_ERROR_CASE_LIMIT_REACHED 

Operation failed: case limit reached.

DRBBDUP_ERROR_ALREADY_INITIALISED 

DRBBDUP can only be initialised once. This is a fatal error.

DRBBDUP_ERROR 

Operation failed.

DRBBDUP_ERROR_UNSET_FEATURE 

Operation failed: feature not set.

DRBBDUP_ERROR_NOT_INITIALIZED 

Operation failed: not initialized.

Function Documentation

◆ drbbdup_exit()

DR_EXPORT drbbdup_status_t drbbdup_exit ( void  )

Cleans up the drbbdup extension.

Returns
whether successful or an error code on failure.

◆ drbbdup_get_stats()

DR_EXPORT drbbdup_status_t drbbdup_get_stats ( DR_PARAM_OUT drbbdup_stats_t stats)

Returns various statistics regarding drbbdup. In particular, the routine populates stats with current values.

Note that the invocation of this routine is only successful if statistics gathering is set via drbbdup_options_t when initializing drbbdup.

Internally, a lock is used while gathering the statistics.

◆ drbbdup_init()

DR_EXPORT drbbdup_status_t drbbdup_init ( drbbdup_options_t ops_in)

Initialises the drbbdup extension. Must be called before use of any other routines.

It cannot be called multiple times as duplication management is specific to a single use-case where only one default case encoding is associated with each basic block.

The ops_in parameter is a set of options which dictate how drbbdup manages basic block copies.

Returns
whether successful or an error code on failure.

◆ drbbdup_is_first_instr()

DR_EXPORT drbbdup_status_t drbbdup_is_first_instr ( void *  drcontext,
instr_t instr,
DR_PARAM_OUT bool *  is_start 
)

Indicates whether the instruction instr is the first instruction of the currently considered basic block copy. The result is returned in is_start.

Must be called via a drbbdup_instrument_instr_t call-back function.

Returns
whether successful or an error code on failure.
Note
when using drbbdup, do not rely on drmgr_is_first_instr().

◆ drbbdup_is_first_nonlabel_instr()

DR_EXPORT drbbdup_status_t drbbdup_is_first_nonlabel_instr ( void *  drcontext,
instr_t instr,
bool *  is_nonlabel 
)

Indicates whether the instruction instr is the first non label instruction of the currently considered basic block copy. The result is returned in is_nonlabel.

Must be called via a drbbdup_instrument_instr_t call-back function.

Returns
whether successful or an error code on failure.
Note
when using drbbdup, do not rely on drmgr_is_first_nonlabel_instr().

◆ drbbdup_is_last_instr()

DR_EXPORT drbbdup_status_t drbbdup_is_last_instr ( void *  drcontext,
instr_t instr,
DR_PARAM_OUT bool *  is_last 
)

Indicates whether the instruction instr is the last instruction of the currently considered basic block copy. The result is returned in is_last.

Must be called via a drbbdup_instrument_instr_t call-back function.

Returns
whether successful or an error code on failure.
Note
when using drbbdup, do not rely on drmgr_is_last_instr().

◆ drbbdup_register_case_encoding()

DR_EXPORT drbbdup_status_t drbbdup_register_case_encoding ( void *  drbbdup_ctx,
uintptr_t  encoding 
)

Registers a non-default case encoding encoding. The function should only be called by a drbbdup_set_up_bb_dups_t call-back function which provides drbbdup_ctx.

The same encoding cannot be registered more than once.

Returns
whether successful or an error code on failure.