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#7113 decode cache: Add analyzer library for decode_cache_t #7114

Open
wants to merge 47 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
fca712e
i#7113: Add library to cache information about decoded instructions
abhinav92003 Dec 9, 2024
abebffc
Docx improvement, and handle regdeps branch_target case.
abhinav92003 Dec 9, 2024
18f7028
Use instr_noalloc_t where possible.
abhinav92003 Dec 10, 2024
4487168
Remove redundant test.
abhinav92003 Dec 10, 2024
41595eb
move impl to cpp
abhinav92003 Dec 10, 2024
d2e94c7
Move impl to cpp
abhinav92003 Dec 10, 2024
f0f8a74
Cleanup and aarch64 mov fix.
abhinav92003 Dec 10, 2024
a1b1d63
Fix windows bug
abhinav92003 Dec 10, 2024
db8a3ad
Reviewer suggested changes
abhinav92003 Dec 10, 2024
1e810b5
Cleanup
abhinav92003 Dec 10, 2024
1fc4c04
Merge branch 'master' into i7113-decode-cache-lib
abhinav92003 Dec 14, 2024
bf76f70
Merge branch 'master' into i7113-decode-cache-lib
abhinav92003 Dec 15, 2024
45e062f
Add instr_decode_cache_t support to opcode_mix; add module_mapper_t s…
abhinav92003 Dec 15, 2024
5e28112
Drop instr_ from instr_decode_cache
abhinav92003 Dec 15, 2024
0a33a51
Handle missing use_module_mapper case
abhinav92003 Dec 15, 2024
29d10a3
Fix clang-format
abhinav92003 Dec 15, 2024
0e2df67
Make add_decode_info simpler and fix build error
abhinav92003 Dec 15, 2024
716a0ea
Cleanup
abhinav92003 Dec 15, 2024
fefe38b
Proactive destruction of module mapper
abhinav92003 Dec 16, 2024
2f0a708
Remove stale file
abhinav92003 Dec 16, 2024
84a2039
Move impl to cpp
abhinav92003 Dec 16, 2024
141e3c5
Fix when we use module mapper in opcode mix
abhinav92003 Dec 16, 2024
1092a21
Revert view deps
abhinav92003 Dec 16, 2024
b2ba91c
Use filetype instead of encoding_is_new
abhinav92003 Dec 16, 2024
d70e227
Cleanup
abhinav92003 Dec 16, 2024
d51d823
Add tmate to windows test
abhinav92003 Dec 16, 2024
0000c5b
Remove test filter
abhinav92003 Dec 16, 2024
3737ec5
Add missing standalone_init
abhinav92003 Dec 16, 2024
652bab0
Add tmate again
abhinav92003 Dec 16, 2024
1177304
Remove drmemtrace_static from test deps
abhinav92003 Dec 16, 2024
96efb50
Keep obj count tracking for tests
abhinav92003 Dec 16, 2024
31e1eab
Keep only one bool for use_module_mapper
abhinav92003 Dec 16, 2024
3702f29
Convert to doc comment
abhinav92003 Dec 16, 2024
d7a4d10
Add tmate... again
abhinav92003 Dec 16, 2024
57f34ad
Disable module mapper tests on Windows due to i#5960
abhinav92003 Dec 17, 2024
3f9cc4e
Remove tmate
abhinav92003 Dec 17, 2024
44971f6
Add TODO for some future items
abhinav92003 Dec 17, 2024
3042d6b
More apt function visibility
abhinav92003 Dec 17, 2024
2b301b5
Merge branch 'master' into i7113-decode-cache-lib
abhinav92003 Dec 19, 2024
4157f23
Reviewer suggested changes
abhinav92003 Dec 19, 2024
0f50370
Add clear_cache API for parallel_shard_exit
abhinav92003 Dec 19, 2024
8dc950c
Add optimization to avoid repeated module map lookups
abhinav92003 Dec 19, 2024
160e052
Remove common-case opt. Need add_decode_info for new encodings
abhinav92003 Dec 19, 2024
74da310
Optimize lookups into the cache
abhinav92003 Dec 19, 2024
6bcc33b
Skip re-decoding on invalid cached decode info. It's redundant.
abhinav92003 Dec 19, 2024
b24d79a
Cleanup
abhinav92003 Dec 22, 2024
e175cd9
Avoid DecodeInfo object construction when not needed.
abhinav92003 Dec 22, 2024
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
18 changes: 17 additions & 1 deletion clients/drcachesim/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,13 @@ add_exported_library(drmemtrace_view STATIC tools/view.cpp)
add_exported_library(drmemtrace_func_view STATIC tools/func_view.cpp)
add_exported_library(drmemtrace_invariant_checker STATIC tools/invariant_checker.cpp)
add_exported_library(drmemtrace_schedule_stats STATIC tools/schedule_stats.cpp)
add_exported_library(drmemtrace_instr_decode_cache STATIC
tools/instr_decode_cache.cpp)
add_exported_library(drmemtrace_schedule_file STATIC common/schedule_file.cpp)
add_exported_library(drmemtrace_mutex_dbg_owned STATIC common/mutex_dbg_owned.cpp)

target_link_libraries(drmemtrace_invariant_checker drdecode drmemtrace_schedule_file)
target_link_libraries(drmemtrace_invariant_checker drdecode drmemtrace_schedule_file
drmemtrace_instr_decode_cache)

configure_DynamoRIO_standalone(drmemtrace_opcode_mix)
configure_DynamoRIO_standalone(drmemtrace_view)
Expand Down Expand Up @@ -609,6 +612,7 @@ restore_nonclient_flags(drmemtrace_analyzer)
restore_nonclient_flags(drmemtrace_invariant_checker)
restore_nonclient_flags(drmemtrace_schedule_stats)
restore_nonclient_flags(drmemtrace_schedule_file)
restore_nonclient_flags(drmemtrace_instr_decode_cache)

# We need to pass /EHsc and we pull in libcmtd into drcachesim from a dep lib.
# Thus we need to override the /MT with /MTd.
Expand Down Expand Up @@ -682,6 +686,7 @@ add_win32_flags(drmemtrace_analyzer)
add_win32_flags(drmemtrace_invariant_checker)
add_win32_flags(drmemtrace_schedule_stats)
add_win32_flags(drmemtrace_schedule_file)
add_win32_flags(drmemtrace_instr_decode_cache)
add_win32_flags(directory_iterator)
add_win32_flags(test_helpers)
add_win32_flags(drmemtrace_mutex_dbg_owned)
Expand Down Expand Up @@ -940,6 +945,17 @@ if (BUILD_TESTS)
add_win32_flags(tool.drcacheoff.burst_aarch64_sys)
endif ()

add_executable(tool.drcachesim.instr_decode_cache_test
tests/instr_decode_cache_test.cpp)
configure_DynamoRIO_standalone(tool.drcachesim.instr_decode_cache_test)
add_win32_flags(tool.drcachesim.instr_decode_cache_test)
target_link_libraries(tool.drcachesim.instr_decode_cache_test
drmemtrace_static drmemtrace_instr_decode_cache test_helpers)
add_test(NAME tool.drcachesim.instr_decode_cache_test
COMMAND tool.drcachesim.instr_decode_cache_test)
set_tests_properties(tool.drcachesim.instr_decode_cache_test PROPERTIES
TIMEOUT ${test_seconds})

# XXX i#1997: dynamorio_static is not supported on Mac yet
# FIXME i#2949: gcc 7.3 fails to link certain configs
# TODO i#3544: Port tests to RISC-V 64
Expand Down
167 changes: 167 additions & 0 deletions clients/drcachesim/tests/instr_decode_cache_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/* **********************************************************
* Copyright (c) 2024 Google, LLC 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 Google, 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 GOOGLE, LLC 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.
*/

/* Tests for the instr_decode_cache_t library. */

#include <iostream>
#include <vector>

#include "../tools/instr_decode_cache.h"
#include "../common/memref.h"
#include "memref_gen.h"

namespace dynamorio {
namespace drmemtrace {

class test_decode_info_t : public decode_info_base_t {
public:
void
set_decode_info(void *dcontext,
const dynamorio::drmemtrace::_memref_instr_t &memref_instr,
instr_t *instr) override
{
is_nop = instr_is_nop(instr);
is_ret = instr_is_return(instr);
}
bool is_nop = false;
bool is_ret = false;
};

std::string
check_decode_caching_without_instr()
{
static constexpr addr_t BASE_ADDR = 0x123450;
static constexpr addr_t TID_A = 1;
instr_t *nop = XINST_CREATE_nop(GLOBAL_DCONTEXT);
instr_t *ret = XINST_CREATE_return(GLOBAL_DCONTEXT);
instrlist_t *ilist = instrlist_create(GLOBAL_DCONTEXT);
instrlist_append(ilist, nop);
instrlist_append(ilist, ret);
std::vector<memref_with_IR_t> memref_setup = {
{ gen_instr(TID_A), nop },
{ gen_instr(TID_A), ret },
{ gen_instr(TID_A), nop },
};
auto memrefs = add_encodings_to_memrefs(ilist, memref_setup, BASE_ADDR);
// Set up the second nop memref to reuse the same encoding as the first nop.
memrefs[2].instr.encoding_is_new = false;

instr_decode_cache_t<test_decode_info_t> decode_cache(
GLOBAL_DCONTEXT,
/*persist_decoded_instrs=*/false);
if (decode_cache.get_decode_info(reinterpret_cast<app_pc>(memrefs[0].instr.addr)) !=
nullptr) {
return "Unexpected decode info for never-seen pc";
}
decode_cache.add_decode_info(memrefs[0].instr);
test_decode_info_t *decode_info_nop =
decode_cache.get_decode_info(reinterpret_cast<app_pc>(memrefs[0].instr.addr));
if (decode_info_nop == nullptr || !decode_info_nop->is_nop) {
return "Unexpected decode info for nop instr";
}
decode_cache.add_decode_info(memrefs[1].instr);
test_decode_info_t *decode_info_ret =
decode_cache.get_decode_info(reinterpret_cast<app_pc>(memrefs[1].instr.addr));
if (decode_info_ret == nullptr || !decode_info_ret->is_ret) {
return "Unexpected decode info for ret instr";
}
decode_cache.add_decode_info(memrefs[2].instr);
test_decode_info_t *decode_info_nop_2 =
decode_cache.get_decode_info(reinterpret_cast<app_pc>(memrefs[2].instr.addr));
if (decode_info_nop_2 != decode_info_nop) {
return "Did not see same decode info instance for second instance of nop";
}

instrlist_clear_and_destroy(GLOBAL_DCONTEXT, ilist);
std::cerr << "check_decode_caching_without_instr passed\n";
return "";
}

std::string
check_instr_decode_caching()
{
static constexpr addr_t BASE_ADDR = 0x123450;
static constexpr addr_t TID_A = 1;
instr_t *nop = XINST_CREATE_nop(GLOBAL_DCONTEXT);
instr_t *ret = XINST_CREATE_return(GLOBAL_DCONTEXT);
instrlist_t *ilist = instrlist_create(GLOBAL_DCONTEXT);
instrlist_append(ilist, nop);
instrlist_append(ilist, ret);
std::vector<memref_with_IR_t> memref_setup = {
{ gen_instr(TID_A), nop },
{ gen_instr(TID_A), ret },
{ gen_instr(TID_A), nop },
};
auto memrefs = add_encodings_to_memrefs(ilist, memref_setup, BASE_ADDR);
// Set up the second nop memref to reuse the same encoding as the first nop.
memrefs[2].instr.encoding_is_new = false;
abhinav92003 marked this conversation as resolved.
Show resolved Hide resolved

instr_decode_cache_t<instr_decode_info_t> decode_cache(
GLOBAL_DCONTEXT,
/*persist_decoded_instr=*/true);
for (const memref_t &memref : memrefs) {
decode_cache.add_decode_info(memref.instr);
derekbruening marked this conversation as resolved.
Show resolved Hide resolved
}

instr_decode_info_t *decode_info_nop =
decode_cache.get_decode_info(reinterpret_cast<app_pc>(memrefs[0].instr.addr));
if (decode_info_nop == nullptr || !instr_is_nop(decode_info_nop->instr_)) {
return "Unexpected decode info for nop instr";
}
instr_decode_info_t *decode_info_ret =
decode_cache.get_decode_info(reinterpret_cast<app_pc>(memrefs[1].instr.addr));
if (decode_info_ret == nullptr || !instr_is_return(decode_info_ret->instr_)) {
return "Unexpected decode info for ret instr";
}
instrlist_clear_and_destroy(GLOBAL_DCONTEXT, ilist);
std::cerr << "check_instr_decode_info passed\n";
return "";
}

int
test_main(int argc, const char *argv[])
{
std::string err = check_decode_caching_without_instr();
if (err != "") {
std::cerr << err << "\n";
exit(1);
}
err = check_instr_decode_caching();
if (err != "") {
std::cerr << err << "\n";
exit(1);
}
return 0;
}

} // namespace drmemtrace
} // namespace dynamorio
2 changes: 1 addition & 1 deletion clients/drcachesim/tests/invariant_checker_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ class checker_no_abort_t : public invariant_checker_t {
parallel_shard_exit(keyval.second.get());
}
}
per_shard_t global;
per_shard_t global(drcontext_);
check_schedule_data(&global);
return true;
}
Expand Down
55 changes: 55 additions & 0 deletions clients/drcachesim/tools/instr_decode_cache.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/* **********************************************************
abhinav92003 marked this conversation as resolved.
Show resolved Hide resolved
* Copyright (c) 2024 Google, 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 Google, 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.
*/

#include "instr_decode_cache.h"

namespace dynamorio {
namespace drmemtrace {

instr_decode_info_t::~instr_decode_info_t()
{
if (instr_ != nullptr) {
instr_destroy(dcontext_, instr_);
}
}

void
instr_decode_info_t::set_decode_info(
void *dcontext, const dynamorio::drmemtrace::_memref_instr_t &memref_instr,
instr_t *instr)
{
dcontext_ = dcontext;
instr_ = instr;
}

} // namespace drmemtrace
} // namespace dynamorio
Loading
Loading