diff --git a/clients/drcachesim/tracer/physaddr.cpp b/clients/drcachesim/tracer/physaddr.cpp index 4747adf0256..1d27f260431 100644 --- a/clients/drcachesim/tracer/physaddr.cpp +++ b/clients/drcachesim/tracer/physaddr.cpp @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2015-2020 Google, Inc. All rights reserved. + * Copyright (c) 2015-2022 Google, Inc. All rights reserved. * **********************************************************/ /* @@ -73,18 +73,29 @@ physaddr_t::physaddr_t() // No destructor needed either: ifstream closes when destroyed. } +physaddr_t::~physaddr_t() +{ + hashtable_delete(&v2p_); +} + bool physaddr_t::init() { #ifdef LINUX - std::ostringstream oss; - std::string pagemap = - dynamic_cast(oss << "/proc/" << getpid() << "/pagemap") - .str(); + // Some threads may not do much, so start out small. + constexpr int V2P_INITIAL_BITS = 9; + hashtable_init_ex(&v2p_, V2P_INITIAL_BITS, HASH_INTPTR, /*strdup=*/false, + /*synch=*/false, nullptr, nullptr, nullptr); + + // We avoid std::ostringstream to avoid malloc use for static linking. + constexpr int MAX_PAGEMAP_FNAME = 64; + char fname[MAX_PAGEMAP_FNAME]; + dr_snprintf(fname, sizeof(fname), "/proc/%d/pagemap", getpid()); + fname[MAX_PAGEMAP_FNAME - 1] = '\0'; // We can't read pagemap with any buffered i/o, like ifstream, as we'll // get EINVAL on any non-8-aligned size, and ifstream at least likes to // read buffers of non-aligned sizes. - fd_ = open(pagemap.c_str(), O_RDONLY); + fd_ = open(fname, O_RDONLY); // Accessing /proc/pid/pagemap requires privileges on some distributions, // such as Fedora with recent kernels. We have no choice but to fail there. return (fd_ != -1); @@ -105,7 +116,7 @@ physaddr_t::virtual2physical(addr_t virt) // Flush the cache and re-sync with the kernel use_cache = false; last_vpage_ = PAGE_INVALID; - v2p_.clear(); + hashtable_clear(&v2p_); count_ = 0; } if (use_cache) { @@ -115,10 +126,14 @@ physaddr_t::virtual2physical(addr_t virt) return last_ppage_ + PAGE_OFFS(virt); // XXX i#1703: add (debug-build-only) internal stats here and // on cache_t::request() fastpath. - std::unordered_map::iterator exists = v2p_.find(vpage); - if (exists != v2p_.end()) { + void *lookup = hashtable_lookup(&v2p_, reinterpret_cast(vpage)); + if (lookup != nullptr) { + addr_t ppage = reinterpret_cast(lookup); + // Restore a 0 payload. + if (ppage == 1) + ppage = 0; last_vpage_ = vpage; - last_ppage_ = exists->second; + last_ppage_ = ppage; return last_ppage_ + PAGE_OFFS(virt); } } @@ -142,7 +157,9 @@ physaddr_t::virtual2physical(addr_t virt) std::cerr << "virtual " << virt << " => physical " << (last_ppage_ + PAGE_OFFS(virt)) << std::endl; } - v2p_[vpage] = last_ppage_; + // Store 0 as 1 since 0 means no entry. + hashtable_add(&v2p_, reinterpret_cast(vpage), + reinterpret_cast(last_ppage_ == 0 ? 1 : last_ppage_)); last_vpage_ = vpage; return last_ppage_ + PAGE_OFFS(virt); #else diff --git a/clients/drcachesim/tracer/physaddr.h b/clients/drcachesim/tracer/physaddr.h index 48e5ff9f98d..61c1524aed3 100644 --- a/clients/drcachesim/tracer/physaddr.h +++ b/clients/drcachesim/tracer/physaddr.h @@ -1,5 +1,5 @@ /* ********************************************************** - * Copyright (c) 2015-2020 Google, Inc. All rights reserved. + * Copyright (c) 2015-2022 Google, Inc. All rights reserved. * **********************************************************/ /* @@ -38,11 +38,14 @@ #include #include +#include "dr_api.h" +#include "hashtable.h" #include "../common/trace_entry.h" class physaddr_t { public: physaddr_t(); + ~physaddr_t(); bool init(); addr_t @@ -54,7 +57,9 @@ class physaddr_t { addr_t last_vpage_; addr_t last_ppage_; int fd_; - std::unordered_map v2p_; + // We would use std::unordered_map, but that is not compatible with + // statically linking drmemtrace into an app. + hashtable_t v2p_; unsigned int count_; #endif }; diff --git a/clients/drcachesim/tracer/tracer.cpp b/clients/drcachesim/tracer/tracer.cpp index 393136571d9..a0bcf15b368 100644 --- a/clients/drcachesim/tracer/tracer.cpp +++ b/clients/drcachesim/tracer/tracer.cpp @@ -3116,14 +3116,6 @@ drmemtrace_client_main(client_id_t id, int argc, const char *argv[]) have_phys = physaddr.init(); if (!have_phys) NOTIFY(0, "Unable to open pagemap: using virtual addresses.\n"); - /* Unfortunately the use of std::unordered_map in physaddr_t calls malloc - * and thus we cannot support it for static linking, so we override the - * DR_DISALLOW_UNSAFE_STATIC declaration. - */ - dr_allow_unsafe_static_behavior(); -#ifdef DRMEMTRACE_STATIC - NOTIFY(0, "-use_physical is unsafe with statically linked clients\n"); -#endif } #ifdef HAS_SNAPPY if (op_offline.get_value() && snappy_enabled()) {