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 <Rose/BinaryAnalysis/Disassembler/BasicTypes.h>
9 #include <unordered_map>
12 namespace BinaryAnalysis {
25 class ManagedInstruction {
30 InstructionCache *cache;
33 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
41 mutable size_t lastAccess;
56 friend class InstructionCache;
58 ManagedInstruction() =
delete;
59 ManagedInstruction(
const ManagedInstruction&) =
delete;
60 ManagedInstruction& operator=(
const ManagedInstruction&) =
delete;
62 ManagedInstruction(InstructionCache *cache, rose_addr_t va)
63 : cache{cache}, state{ABSENT}, u{.va = va} {
64 ASSERT_not_null(cache);
67 explicit ManagedInstruction(InstructionCache *cache)
68 : cache{cache}, state{PRESENT}, u{.ast =
nullptr} {
69 ASSERT_not_null(cache);
85 LockedInstruction operator->()
const;
88 friend class InstructionPtr;
94 LockedInstruction lock()
const;
99 LockedInstruction makePresentNS()
const;
108 void updateTimerNS()
const;
128 class LockedInstruction {
130 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
146 explicit LockedInstruction(
const InstructionPtr &insn);
151 LockedInstruction(
const LockedInstruction &other);
158 LockedInstruction& operator=(
const LockedInstruction &other);
163 ~LockedInstruction();
198 explicit operator bool()
const;
264 class InstructionPtr {
265 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
266 std::shared_ptr<ManagedInstruction> mi_;
273 InstructionPtr(
const InstructionPtr &other)
280 InstructionPtr& operator=(
const InstructionPtr &other);
298 LockedInstruction operator->()
const;
305 explicit operator bool()
const;
311 LockedInstruction lock()
const;
327 bool operator==(
const InstructionPtr &other)
const;
328 bool operator!=(
const InstructionPtr &other)
const;
329 bool operator<=(
const InstructionPtr &other)
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==(std::nullptr_t)
const;
334 bool operator!=(std::nullptr_t)
const;
338 friend class InstructionCache;
341 static InstructionPtr instance(InstructionCache *cache, rose_addr_t va);
342 static InstructionPtr instance(InstructionCache *cache);
360 Exception(
const std::string &mesg)
361 :
Rose::Exception(mesg) {}
362 ~Exception() throw() {}
369 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
370 std::unordered_map<rose_addr_t, InstructionPtr> insns_;
372 InstructionCache(
const InstructionCache&) =
delete;
373 InstructionCache& operator=(
const InstructionCache&) =
delete;
382 : memory_(memory), decoder_(decoder) {
383 ASSERT_not_null(memory);
384 ASSERT_not_null(decoder);
411 InstructionPtr
get(rose_addr_t va);
416 LockedInstruction lock(rose_addr_t va);
424 friend class ManagedInstruction;
437 class InstructionGuard {
441 LockedInstruction lock;
445 explicit InstructionGuard(
const InstructionPtr &insn)
453 inline InstructionPtr&
454 InstructionPtr::operator=(
const InstructionPtr &other) {
455 SAWYER_THREAD_TRAITS::LockGuard2 lock(mutex_, other.mutex_);
460 inline LockedInstruction
461 InstructionPtr::operator->()
const {
462 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
463 ASSERT_not_null(mi_);
464 ManagedInstruction &mi = *mi_.get();
468 inline LockedInstruction
469 ManagedInstruction::operator->()
const {
473 inline LockedInstruction
474 ManagedInstruction::lock()
const {
475 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
477 return makePresentNS();
481 ManagedInstruction::updateTimerNS()
const {
482 static size_t nextTimer = 0;
483 lastAccess = ++nextTimer;
486 inline LockedInstruction
487 ManagedInstruction::makePresentNS()
const {
488 if (ABSENT == state) {
490 ASSERT_not_null(decoded);
494 return LockedInstruction{u.ast};
505 LockedInstruction::~LockedInstruction() {
511 LockedInstruction::operator->()
const {
512 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
513 ASSERT_not_null(insn);
518 InstructionPtr::operator bool()
const {
519 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
520 return mi_.get() ? !(*mi_).isNull() :
false;
524 ManagedInstruction::isNull()
const {
525 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
530 return u.ast ==
nullptr;
534 InstructionPtr::operator!=(
const std::nullptr_t)
const {
535 SAWYER_THREAD_TRAITS::LockGuard lock(mutex_);
536 return mi_ && !(*mi_).isNull()?
true :
false;
Base class for machine instructions.
Main namespace for the ROSE library.
MemoryMapPtr Ptr
Reference counting pointer.
Base class for reference counted objects.
Sawyer::SharedPointer< Base > BasePtr
Reference counted pointer for disassemblers.
Base class for all ROSE exceptions.
void adjustCacheLockCount(int increment)
Property: Cache lock count.