Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

i#6662 public traces: add instr_t operation_size API #7151

Merged
merged 7 commits into from
Dec 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion api/docs/release.dox
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,8 @@ changes:
- No compatibility changes yet.

Further non-compatibility-affecting changes include:
- No changes yet.
- Added instr_get_operation_size() and instr_set_operation_size() APIs for
#DR_ISA_REGDEPS #instr_t.

**************************************************
<hr>
Expand Down
16 changes: 16 additions & 0 deletions core/ir/instr_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -1995,6 +1995,22 @@ DR_API
instr_t *
instr_convert_short_meta_jmp_to_long(void *drcontext, instrlist_t *ilist, instr_t *instr);

DR_API
/**
* Returns the operation size of \p instr if it's a #DR_ISA_REGDEPS instruction, #OPSZ_NA
* otherwise.
*/
opnd_size_t
instr_get_operation_size(instr_t *instr);

DR_API
/**
* Sets the operation size of \p instr to \p operation_size only if instr is a
* #DR_ISA_REGDEPS instruction.
*/
void
instr_set_operation_size(instr_t *instr, opnd_size_t operation_size);

DR_API
/**
* Converts a real ISA (e.g., #DR_ISA_AMD64) instruction \p instr_real_isa into a
Expand Down
29 changes: 27 additions & 2 deletions core/ir/instr_shared.c
Original file line number Diff line number Diff line change
Expand Up @@ -2999,6 +2999,27 @@ instr_uses_fp_reg(instr_t *instr)
return false;
}

opnd_size_t
instr_get_operation_size(instr_t *instr)
{
/* Only DR_ISA_REGDEPS instructions can have an operation_size.
*/
if (instr_get_isa_mode(instr) == DR_ISA_REGDEPS)
return instr->operation_size;

return OPSZ_NA;
}

void
instr_set_operation_size(instr_t *instr, opnd_size_t operation_size)
{
CLIENT_ASSERT(instr_get_isa_mode(instr) != DR_ISA_REGDEPS,
"instr_set_operation_size: only DR_ISA_REGDEPS instructions can have "
"an operation_size");
instr->operation_size = operation_size;
return;
}

void
instr_convert_to_isa_regdeps(void *drcontext, instr_t *instr_real_isa,
instr_t *instr_regdeps_isa)
Expand Down Expand Up @@ -3097,10 +3118,14 @@ instr_convert_to_isa_regdeps(void *drcontext, instr_t *instr_real_isa,
instr_set_category(instr_regdeps_isa, instr_get_category(instr_real_isa));

/* Convert max_src_opnd_size_bytes from number of bytes to opnd_size_t (which holds
* OPSZ_ enum values).
* OPSZ_ enum values). If we have no operands, operation_size is OPSZ_0, same as a
* decoded DR_ISA_REGDEPS instruction.
*/
opnd_size_t max_opnd_size = opnd_size_from_bytes(max_src_opnd_size_bytes);
instr_regdeps_isa->operation_size = max_opnd_size;
if (num_dsts + num_srcs > 0)
instr_regdeps_isa->operation_size = max_opnd_size;
else
instr_regdeps_isa->operation_size = OPSZ_0;

/* Set the source and destination register operands for the converted instruction.
*/
Expand Down
12 changes: 12 additions & 0 deletions suite/tests/api/ir_regdeps.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,11 +108,23 @@ test_instr_encode_decode_disassemble_synthetic(void *dc, instr_t *instr,
byte *next_pc_decode = decode(dc, bytes, instr_synthetic_decoded);
ASSERT(next_pc_decode != NULL);
ASSERT(next_pc_encode == next_pc_decode);

/* Check instruction length.
*/
ASSERT((next_pc_encode - bytes) == instr_length(dc, instr_synthetic_decoded));
ASSERT(instr_length(dc, instr_synthetic_decoded) != 0);

/* Check for overflow.
*/
ASSERT((next_pc_encode - bytes) <= sizeof(bytes));
ASSERT((next_pc_decode - bytes) <= sizeof(bytes));

/* Check operation size.
*/
ASSERT(instr_get_operation_size(instr_synthetic_decoded) != OPSZ_NA);
ASSERT(instr_get_operation_size(instr_synthetic_decoded) ==
instr_get_operation_size(instr_synthetic_converted));

/* Disassemble regdeps synthetic encodings to buffer.
*/
char dbuf[512];
Expand Down
Loading