From a0bbf6fb69083099e9569af2629194342d006cf2 Mon Sep 17 00:00:00 2001 From: edeiana Date: Wed, 6 Mar 2024 03:38:24 -0800 Subject: [PATCH] Added initial implementation of synthetic encoding/decoding. --- core/CMakeLists.txt | 2 +- core/ir/synthetic/decode.c | 93 ++++++++++++++++++++++++++++++++++++++ core/ir/synthetic/decode.h | 9 ++++ core/ir/synthetic/encode.c | 43 +++++++++++++++++- 4 files changed, 145 insertions(+), 2 deletions(-) create mode 100644 core/ir/synthetic/decode.c create mode 100644 core/ir/synthetic/decode.h diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 29dabbf5f92..bbaade9812a 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -280,6 +280,7 @@ set(DECODER_SRCS ir/encode_shared.c ir/${ARCH_NAME}/encode.c ir/synthetic/encode.c + ir/synthetic/decode.c ir/disassemble_shared.c ir/${ARCH_NAME}/disassemble.c ir/ir_utils_shared.c @@ -1213,7 +1214,6 @@ DR_export_header(${CMAKE_CURRENT_SOURCE_DIR}/ir/arm/opcode_api.h dr_ir_opcodes_a DR_export_header(${CMAKE_CURRENT_SOURCE_DIR}/ir/instr_create_shared_api.h dr_ir_macros.h) DR_export_header(${CMAKE_CURRENT_SOURCE_DIR}/ir/x86/instr_create_api.h dr_ir_macros_x86.h) DR_export_header(${CMAKE_CURRENT_SOURCE_DIR}/ir/arm/instr_create_api.h dr_ir_macros_arm.h) -DR_export_header(${CMAKE_CURRENT_SOURCE_DIR}/ir/synthetic/encode.h dr_ir_encode_synthetic.h) DR_export_header(${CMAKE_CURRENT_SOURCE_DIR}/ir/aarch64/instr_create_api.h dr_ir_macros_aarch64.h) DR_export_header(${CMAKE_CURRENT_SOURCE_DIR}/lib/dr_ir_utils.h dr_ir_utils.h) diff --git a/core/ir/synthetic/decode.c b/core/ir/synthetic/decode.c new file mode 100644 index 00000000000..d7d83d61384 --- /dev/null +++ b/core/ir/synthetic/decode.c @@ -0,0 +1,93 @@ +/* ********************************************************** + * Copyright (c) 2011-2024 Google, Inc. All rights reserved. + * Copyright (c) 2001-2010 VMware, Inc. All rights reserved. + * **********************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of VMware, Inc. nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ +/* Copyright (c) 2003-2007 Determina Corp. */ +/* Copyright (c) 2001-2003 Massachusetts Institute of Technology */ +/* Copyright (c) 2001 Hewlett-Packard Company */ + +/* decode.c -- a decoder for DR synthetic IR */ + +#include "encode.h" +#include "decode.h" + +#include "../globals.h" +#include "instr_api.h" + +#define CATEGORY_BITS 22 +#define FLAGS_BITS 2 +#define NUM_OPND_BITS 4 + +void +decode_from_synth(dcontext_t *dcontext, byte *encoded_instr, instr_t *instr) +{ + uint encoding = 0; + uint shift = 0; + + /* + * Copy encoded_instr in a uint for easy retrieving of values. + */ + memcpy(&encoding, encoded_instr, sizeof(uint)); + + /* + * Decode synthetic opcode as instruction category. + */ + uint category_mask = (1U << CATEGORY_BITS) - 1; + uint category = encoding & category_mask; + instr_set_category(instr, category); + shift += CATEGORY_BITS; + + /* + * Decode flags. + */ + // Commented to avoid unused variable error. + // uint flags_mask = ((1U << FLAGS_BITS) - 1) << shift; + // uint flags = encoding & flags_mask; + // TOFIX: set all arithmetic flags of instr_t? + shift += FLAGS_BITS; + + /* + * Decode number of source operands. + */ + uint num_srcs_mask = ((1U << NUM_OPND_BITS) - 1) << shift; + uint num_srcs = encoding & num_srcs_mask; + shift += NUM_OPND_BITS; + + /* + * Decode number of destination operands. + */ + uint num_dsts_mask = ((1U << NUM_OPND_BITS) - 1) << shift; + uint num_dsts = encoding & num_dsts_mask; + + instr_set_num_opnds(dcontext, instr, num_dsts, num_srcs); + + return; +} diff --git a/core/ir/synthetic/decode.h b/core/ir/synthetic/decode.h new file mode 100644 index 00000000000..163cb3142b6 --- /dev/null +++ b/core/ir/synthetic/decode.h @@ -0,0 +1,9 @@ +#ifndef _SYNTHETIC_DECODE_H_ +#define _SYNTHETIC_DECODE_H_ 1 + +#include "../globals.h" + +void +decode_from_synth(dcontext_t *dcontext, byte *encoded_instr, instr_t *instr); + +#endif /* _SYNTHETIC_DECODE_H_ */ diff --git a/core/ir/synthetic/encode.c b/core/ir/synthetic/encode.c index 0c49a199249..29536b5e7cf 100644 --- a/core/ir/synthetic/encode.c +++ b/core/ir/synthetic/encode.c @@ -40,11 +40,52 @@ #include "../globals.h" +#define CATEGORY_BITS 22 +#define FLAGS_BITS 2 +#define NUM_OPND_BITS 4 + void encode_to_synth(dcontext_t *dcontext, instr_t *instr, byte *encoded_instr) { + uint encoding = 0; + uint shift = 0; + + /* + * Encode category as synthetic opcode. + */ uint category = instr_get_category(instr); - memcpy(encoded_instr, &category, sizeof(uint)); + encoding |= category; + shift += CATEGORY_BITS; + + /* + * Encode flags. + */ + // TOFIX: this is probably not the right way to look at arithmetic flags of an instr_t + uint flags = (uint)instr_arith_flags_valid(instr); + encoding |= (flags << shift); + shift += FLAGS_BITS; + + /* + * Encode number of source operands. + */ + uint num_srcs = (uint)instr_num_srcs(instr); + encoding |= (num_srcs << shift); + shift += NUM_OPND_BITS; + + /* + * Encode number of destination operands. + */ + uint num_dsts = (uint)instr_num_dsts(instr); + encoding |= (num_dsts << shift); + + /* + * TODO: Encode registers. + */ + + /* + * Copy result to output encoded_instr. + */ + memcpy(encoded_instr, &encoding, sizeof(uint)); return; }