1 #ifndef ROSE_BinaryAnalysis_InstructionCache_H
2 #define ROSE_BinaryAnalysis_InstructionCache_H
3 #include <featureTests.h>
4 #if defined(ROSE_ENABLE_BINARY_ANALYSIS) && __cplusplus >= 201103L
6 #include <unordered_map>
12 class InstructionCache;
14 class LockedInstruction;
15 class ManagedInstruction;
28 class ManagedInstruction {
33 InstructionCache *cache;
36 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
44 mutable size_t lastAccess;
59 friend class InstructionCache;
61 ManagedInstruction() =
delete;
62 ManagedInstruction(
const ManagedInstruction&) =
delete;
63 ManagedInstruction& operator=(
const ManagedInstruction&) =
delete;
65 ManagedInstruction(InstructionCache *cache, rose_addr_t va)
66 : cache{cache}, state{ABSENT}, u{.va = va} {
67 ASSERT_not_null(cache);
70 explicit ManagedInstruction(InstructionCache *cache)
71 : cache{cache}, state{PRESENT}, u{.ast =
nullptr} {
72 ASSERT_not_null(cache);
88 LockedInstruction operator->()
const;
91 friend class InstructionPtr;
97 LockedInstruction lock()
const;
102 LockedInstruction makePresentNS()
const;
111 void updateTimerNS()
const;
131 class LockedInstruction {
133 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
149 explicit LockedInstruction(
const InstructionPtr &insn);
154 LockedInstruction(
const LockedInstruction &other);
161 LockedInstruction& operator=(
const LockedInstruction &other);
166 ~LockedInstruction();
201 explicit operator bool()
const;
267 class InstructionPtr {
268 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
269 std::shared_ptr<ManagedInstruction> mi_;
276 InstructionPtr(
const InstructionPtr &other)
283 InstructionPtr& operator=(
const InstructionPtr &other);
301 LockedInstruction operator->()
const;
308 explicit operator bool()
const;
314 LockedInstruction lock()
const;
330 bool operator==(
const InstructionPtr &other)
const;
331 bool operator!=(
const InstructionPtr &other)
const;
332 bool operator<=(
const InstructionPtr &other)
const;
333 bool operator>=(
const InstructionPtr &other)
const;
334 bool operator<(
const InstructionPtr &other)
const;
335 bool operator>(
const InstructionPtr &other)
const;
336 bool operator==(std::nullptr_t)
const;
337 bool operator!=(std::nullptr_t)
const;
341 friend class InstructionCache;
344 static InstructionPtr instance(InstructionCache *cache, rose_addr_t va);
345 static InstructionPtr instance(InstructionCache *cache);
363 Exception(
const std::string &mesg)
364 :
Rose::Exception(mesg) {}
365 ~Exception() throw() {}
369 MemoryMap::Ptr memory_;
370 Disassembler *decoder_;
372 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
373 std::unordered_map<rose_addr_t, InstructionPtr> insns_;
375 InstructionCache(
const InstructionCache&) =
delete;
376 InstructionCache& operator=(
const InstructionCache&) =
delete;
384 InstructionCache(
const MemoryMap::Ptr &memory, Disassembler *decoder)
385 : memory_(memory), decoder_(decoder) {
386 ASSERT_not_null(memory);
387 ASSERT_not_null(decoder);
395 MemoryMap::Ptr memoryMap()
const {
402 Disassembler* decoder()
const {
414 InstructionPtr
get(rose_addr_t va);
419 LockedInstruction lock(rose_addr_t va);
427 friend class ManagedInstruction;
440 class InstructionGuard {
444 LockedInstruction lock;
448 explicit InstructionGuard(
const InstructionPtr &insn)
456 inline InstructionPtr&
457 InstructionPtr::operator=(
const InstructionPtr &other) {
458 SAWYER_THREAD_TRAITS::LockGuard2 lock(mutex_, other.mutex_);
463 inline LockedInstruction
464 InstructionPtr::operator->()
const {
465 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
466 ASSERT_not_null(mi_);
467 ManagedInstruction &mi = *mi_.get();
471 inline LockedInstruction
472 ManagedInstruction::operator->()
const {
476 inline LockedInstruction
477 ManagedInstruction::lock()
const {
478 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
480 return makePresentNS();
484 ManagedInstruction::updateTimerNS()
const {
485 static size_t nextTimer = 0;
486 lastAccess = ++nextTimer;
489 inline LockedInstruction
490 ManagedInstruction::makePresentNS()
const {
491 if (ABSENT == state) {
493 ASSERT_not_null(decoded);
497 return LockedInstruction{u.ast};
508 LockedInstruction::~LockedInstruction() {
514 LockedInstruction::operator->()
const {
515 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
516 ASSERT_not_null(insn);
521 InstructionPtr::operator bool()
const {
522 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
523 return mi_.get() ? !(*mi_).isNull() :
false;
527 ManagedInstruction::isNull()
const {
528 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
533 return u.ast ==
nullptr;
537 InstructionPtr::operator!=(
const std::nullptr_t)
const {
538 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
539 return mi_ && !(*mi_).isNull()?
true :
false;
Base class for machine instructions.
Main namespace for the ROSE library.
Base class for reference counted objects.
Base class for all ROSE exceptions.
void adjustCacheLockCount(int increment)
Property: Cache lock count.