Functions to create and manipulate lists of instructions. More...
Functions | |
instrlist_t * | instrlist_create (void *drcontext) |
void | instrlist_init (instrlist_t *ilist) |
void | instrlist_destroy (void *drcontext, instrlist_t *ilist) |
void | instrlist_clear (void *drcontext, instrlist_t *ilist) |
void | instrlist_clear_and_destroy (void *drcontext, instrlist_t *ilist) |
void | instrlist_set_translation_target (instrlist_t *ilist, app_pc pc) |
app_pc | instrlist_get_translation_target (instrlist_t *ilist) |
void | instrlist_set_auto_predicate (instrlist_t *ilist, dr_pred_type_t pred) |
dr_pred_type_t | instrlist_get_auto_predicate (instrlist_t *ilist) |
instr_t * | instrlist_first (instrlist_t *ilist) |
instr_t * | instrlist_first_app (instrlist_t *ilist) |
instr_t * | instrlist_last (instrlist_t *ilist) |
instr_t * | instrlist_last_app (instrlist_t *ilist) |
void | instrlist_append (instrlist_t *ilist, instr_t *instr) |
void | instrlist_prepend (instrlist_t *ilist, instr_t *instr) |
instrlist_t * | instrlist_clone (void *drcontext, instrlist_t *old) |
void | instrlist_preinsert (instrlist_t *ilist, instr_t *where, instr_t *instr) |
void | instrlist_postinsert (instrlist_t *ilist, instr_t *where, instr_t *instr) |
instr_t * | instrlist_replace (instrlist_t *ilist, instr_t *oldinst, instr_t *newinst) |
void | instrlist_remove (instrlist_t *ilist, instr_t *instr) |
bool | instrlist_set_fall_through_target (instrlist_t *bb, app_pc tgt) |
bool | instrlist_set_return_target (instrlist_t *bb, app_pc tgt) |
byte * | instrlist_encode (void *drcontext, instrlist_t *ilist, byte *pc, bool has_instr_jmp_targets) |
byte * | instrlist_encode_to_copy (void *drcontext, instrlist_t *ilist, byte *copy_pc, byte *final_pc, byte *max_pc, bool has_instr_jmp_targets) |
void | instrlist_disassemble (void *drcontext, app_pc tag, instrlist_t *ilist, file_t outfile) |
Functions to create and manipulate lists of instructions.
void instrlist_append | ( | instrlist_t * | ilist, |
instr_t * | instr | ||
) |
Adds instr
to the end of ilist
.
void instrlist_clear | ( | void * | drcontext, |
instrlist_t * | ilist | ||
) |
Frees the instructions in ilist
.
void instrlist_clear_and_destroy | ( | void * | drcontext, |
instrlist_t * | ilist | ||
) |
Destroys the instructions in ilist
and destroys the instrlist_t object itself.
instrlist_t* instrlist_clone | ( | void * | drcontext, |
instrlist_t * | old | ||
) |
Allocates a new instrlist_t and for each instr_t in old
allocates a new instr_t using instr_clone to produce a complete copy of old
. Each operand that is opnd_is_instr() has its target updated to point to the corresponding instr_t in the new instrlist_t (this routine assumes that all such targets are contained within old
, and may fault otherwise).
instrlist_t* instrlist_create | ( | void * | drcontext | ) |
Returns an initialized instrlist_t allocated on the thread-local heap.
void instrlist_destroy | ( | void * | drcontext, |
instrlist_t * | ilist | ||
) |
Deallocates the thread-local heap storage for ilist
.
void instrlist_disassemble | ( | void * | drcontext, |
app_pc | tag, | ||
instrlist_t * | ilist, | ||
file_t | outfile | ||
) |
Prints each instruction in ilist
in sequence to outfile
. The default is to use DR's custom syntax (see disassemble_set_syntax()) with additional information. The first column contains the offset in bytes from the start of the list. Next, each instruction is labeled according to its type, which will typically either be L3
for an unchanged application instruction or m4
for a tool instruction (the names come from "Level 3" and "meta Level 4", IR details which are no longer exposed to tools). Tool instructions have their IR heap addresses included (indicated with a leading @ character) to make instruction jump targets easier to identify. The final two columns contain the raw bytes and the actual instruction disassembly.
Below is an example where many tool instructions have been inserted around 3 application instructions, which can be identified by the L3
in the 2nd column. The label instructions are referred to by branch and store instructions, as can be seen by searching for the addresses of the labels.
byte* instrlist_encode | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
byte * | pc, | ||
bool | has_instr_jmp_targets | ||
) |
Encodes each instruction in ilist
in turn in contiguous memory starting at pc
. Returns the pc after all of the encodings, or NULL if any one of the encodings failed. Uses the x86/x64 mode stored in each instr, not the mode of the current thread. In order for instr_t operands to be encoded properly, has_instr_jmp_targets
must be true. If has_instr_jmp_targets
is true, the note field of each instr_t in ilist will be overwritten, and if any instr_t targets are not in ilist
, they must have their note fields set with their offsets relative to pc. x86 instructions can occupy up to 17 bytes each, so the caller should ensure the target location has enough room to avoid overflow.
byte* instrlist_encode_to_copy | ( | void * | drcontext, |
instrlist_t * | ilist, | ||
byte * | copy_pc, | ||
byte * | final_pc, | ||
byte * | max_pc, | ||
bool | has_instr_jmp_targets | ||
) |
Encodes each instruction in ilist
in turn in contiguous memory starting copy_pc
in preparation for copying to final_pc
. Any pc-relative instruction is encoded as though the instruction list were located at final_pc
. This allows for direct copying of the encoded bytes to final_pc
without re-relativization.
Returns the pc after all of the encodings, or NULL if any one of the encodings failed.
Uses the x86/x64 mode stored in each instr, not the mode of the current thread.
In order for instr_t operands to be encoded properly, has_instr_jmp_targets
must be true. If has_instr_jmp_targets
is true, the note field of each instr_t in ilist will be overwritten, and if any instr_t targets are not in ilist
, they must have their note fields set with their offsets relative to pc.
If max_pc
is non-NULL, computes the total size required to encode the instruction list before performing any encoding. If the whole list will not fit starting at copy_pc
without exceeding max_pc
, returns NULL without encoding anything. Otherwise encodes as normal. Note that x86 instructions can occupy up to 17 bytes each, so if max_pc
is NULL, the caller should ensure the target location has enough room to avoid overflow.
instr_t* instrlist_first_app | ( | instrlist_t * | ilist | ) |
Returns the first application (non-meta) instruction in the instruction list ilist
.
dr_pred_type_t instrlist_get_auto_predicate | ( | instrlist_t * | ilist | ) |
Returns the predicate for ilist
.
app_pc instrlist_get_translation_target | ( | instrlist_t * | ilist | ) |
Returns the translation target, or NULL if none is set.
void instrlist_init | ( | instrlist_t * | ilist | ) |
Initializes ilist
.
instr_t* instrlist_last_app | ( | instrlist_t * | ilist | ) |
Returns the last application (non-meta) instruction in the instruction list ilist
.
Inserts instr
into ilist
after where
.
Inserts instr
into ilist
prior to where
.
void instrlist_prepend | ( | instrlist_t * | ilist, |
instr_t * | instr | ||
) |
Adds instr
to the front of ilist
.
void instrlist_remove | ( | instrlist_t * | ilist, |
instr_t * | instr | ||
) |
Removes (does not destroy) instr
from ilist
.
Replaces oldinst
with newinst
in ilist
(does not destroy oldinst
).
void instrlist_set_auto_predicate | ( | instrlist_t * | ilist, |
dr_pred_type_t | pred | ||
) |
All future instructions inserted into ilist
will be predicated with pred
. This is a convenience routine to make it easy to have emitted code from internal DR components predicated.
dr_insert_clean_call()
handle auto predication gracefully and are thus safe for use with auto predication. bool instrlist_set_fall_through_target | ( | instrlist_t * | bb, |
app_pc | tgt | ||
) |
Specifies the fall-through target of a basic block if its last instruction is a conditional branch instruction. It can only be called in basic block building event callbacks when the for_trace
parameter is false, and has NO EFFECT in other cases.
bool instrlist_set_return_target | ( | instrlist_t * | bb, |
app_pc | tgt | ||
) |
Specifies the return target of a basic block if its last instruction is a call instruction. It can only be called in basic block building event callbacks when the for_trace
parameter is false, and has NO EFFECT in other cases.
void instrlist_set_translation_target | ( | instrlist_t * | ilist, |
app_pc | pc | ||
) |
All future instructions inserted into ilist
that do not have raw bits will have instr_set_translation() called with pc
as the target. This is a convenience routine to make it easy to have the same code generate non-translation and translation instructions, and it does not try to enforce that all instructions have translations (e.g., some could be inserted via instr_set_next()).