adding interval matching to memory-access listeners

git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1454 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
hsc
2012-07-16 18:21:03 +00:00
parent 1a339c1814
commit b245327b7e
3 changed files with 38 additions and 29 deletions

View File

@ -34,13 +34,15 @@ bool TroubleListener::addWatchNumber(unsigned troubleNumber)
return true; return true;
} }
bool MemAccessListener::isMatching(address_t addr, accessType_t accesstype) const bool MemAccessListener::isMatching(address_t addr, size_t width, accessType_t accesstype) const
{ {
if (!(m_WatchType & accesstype)) if (!(m_WatchType & accesstype)) {
return false; return false;
else if (m_WatchAddr != addr && } else if (m_WatchAddr != ANY_ADDR
m_WatchAddr != ANY_ADDR) && (m_WatchAddr >= addr + width
|| m_WatchAddr + m_WatchWidth <= addr)) {
return false; return false;
}
return true; return true;
} }

View File

@ -244,8 +244,6 @@ public:
/** /**
* \class MemAccessListener * \class MemAccessListener
* Observes memory read/write accesses. * Observes memory read/write accesses.
* FIXME? currently >8-bit accesses only match if their lowest address is being watched
* (e.g., a 32-bit write to 0x4 also accesses 0x7, but this cannot be matched)
*/ */
class MemAccessListener : virtual public BaseListener { class MemAccessListener : virtual public BaseListener {
public: public:
@ -256,14 +254,16 @@ public:
MEM_READWRITE = 0x3 MEM_READWRITE = 0x3
}; };
private: private:
//! Specific guest system address to watch, or ANY_ADDR. //! Specific physical guest system address to watch, or ANY_ADDR.
address_t m_WatchAddr; address_t m_WatchAddr;
//! Width of the memory area being watched (# bytes).
size_t m_WatchWidth;
/** /**
* Memory access type we want to watch * Memory access type we want to watch
* (MEM_READ || MEM_WRITE || MEM_READWRITE). * (MEM_READ || MEM_WRITE || MEM_READWRITE).
*/ */
accessType_t m_WatchType; accessType_t m_WatchType;
//! Specific guest system address that actually triggered the listener. //! Specific physical guest system address that actually triggered the listener.
address_t m_TriggerAddr; address_t m_TriggerAddr;
//! Width of the memory access (# bytes). //! Width of the memory access (# bytes).
size_t m_TriggerWidth; size_t m_TriggerWidth;
@ -273,64 +273,71 @@ private:
accessType_t m_AccessType; accessType_t m_AccessType;
public: public:
MemAccessListener(accessType_t watchtype = MEM_READWRITE) MemAccessListener(accessType_t watchtype = MEM_READWRITE)
: m_WatchAddr(ANY_ADDR), m_WatchType(watchtype), : m_WatchAddr(ANY_ADDR), m_WatchWidth(1), m_WatchType(watchtype),
m_TriggerAddr(ANY_ADDR), m_TriggerIP(ANY_ADDR), m_TriggerAddr(ANY_ADDR), m_TriggerIP(ANY_ADDR),
m_AccessType(MEM_UNKNOWN) { } m_AccessType(MEM_UNKNOWN) { }
MemAccessListener(address_t addr, MemAccessListener(address_t addr,
accessType_t watchtype = MEM_READWRITE) accessType_t watchtype = MEM_READWRITE)
: m_WatchAddr(addr), m_WatchType(watchtype), : m_WatchAddr(addr), m_WatchWidth(1), m_WatchType(watchtype),
m_TriggerAddr(ANY_ADDR), m_TriggerIP(ANY_ADDR), m_TriggerAddr(ANY_ADDR), m_TriggerIP(ANY_ADDR),
m_AccessType(MEM_UNKNOWN) { } m_AccessType(MEM_UNKNOWN) { }
/** /**
* Returns the memory address to be observed. * Returns the physical memory address to be observed.
*/ */
address_t getWatchAddress() const { return m_WatchAddr; } address_t getWatchAddress() const { return m_WatchAddr; }
/** /**
* Sets the memory address to be observed. (Wildcard: ANY_ADDR) * Sets the physical memory address to be observed. (Wildcard: ANY_ADDR)
*/ */
void setWatchAddress(address_t addr) { m_WatchAddr = addr; } void setWatchAddress(address_t addr) { m_WatchAddr = addr; }
/** /**
* Checks whether a given address is matching. * Returns the width of the memory area being watched.
*/ */
bool isMatching(address_t addr, accessType_t accesstype) const; size_t getWatchWidth() const { return m_WatchWidth; }
/** /**
* Returns the specific memory address that actually triggered the * Sets the width of the memory area being watched (defaults to 1).
*/
void setWatchWidth(size_t width) { m_WatchWidth = width; }
/**
* Checks whether a given physical memory access is matching.
*/
bool isMatching(address_t addr, size_t width, accessType_t accesstype) const;
/**
* Returns the specific physical memory address that actually triggered the
* listener. * listener.
*/ */
address_t getTriggerAddress() const { return m_TriggerAddr; } address_t getTriggerAddress() const { return m_TriggerAddr; }
/** /**
* Sets the specific memory address that actually triggered the listener. * Sets the specific physical memory address that actually triggered the
* Should not be used by experiment code. * listener. Should not be used by experiment code.
*/ */
void setTriggerAddress(address_t addr) { m_TriggerAddr = addr; } void setTriggerAddress(address_t addr) { m_TriggerAddr = addr; }
/** /**
* Returns the specific memory address that actually triggered the * Returns the width (in bytes) of the memory access that triggered this
* listener. * listener.
*/ */
size_t getTriggerWidth() const { return m_TriggerWidth; } size_t getTriggerWidth() const { return m_TriggerWidth; }
/** /**
* Sets the specific memory address that actually triggered the listener. * Sets the width (in bytes) of the memory access that triggered this
* Should not be used by experiment code. * listener. Should not be used by experiment code.
*/ */
void setTriggerWidth(size_t width) { m_TriggerWidth = width; } void setTriggerWidth(size_t width) { m_TriggerWidth = width; }
/** /**
* Returns the address of the instruction causing this memory * Returns the address of the instruction causing this memory access.
* access.
*/ */
address_t getTriggerInstructionPointer() const { return m_TriggerIP; } address_t getTriggerInstructionPointer() const { return m_TriggerIP; }
/** /**
* Sets the address of the instruction causing this memory * Sets the address of the instruction causing this memory access. Should
* access. Should not be used by experiment code. * not be used by experiment code.
*/ */
void setTriggerInstructionPointer(address_t addr) { m_TriggerIP = addr; } void setTriggerInstructionPointer(address_t addr) { m_TriggerIP = addr; }
/** /**
* Returns type (MEM_READ || MEM_WRITE) of the memory access that * Returns type (MEM_READ || MEM_WRITE) of the memory access that triggered
* triggered this listener. * this listener.
*/ */
accessType_t getTriggerAccessType() const { return m_AccessType; } accessType_t getTriggerAccessType() const { return m_AccessType; }
/** /**
* Sets type of the memory access that triggered this listener. Should * Sets type of the memory access that triggered this listener. Should not
* not be used by experiment code. * be used by experiment code.
*/ */
void setTriggerAccessType(accessType_t type) { m_AccessType = type; } void setTriggerAccessType(accessType_t type) { m_AccessType = type; }
/** /**

View File

@ -84,7 +84,7 @@ void SimulatorController::onMemoryAccessListener(address_t addr, size_t len,
BaseListener* pev = *it; BaseListener* pev = *it;
MemAccessListener* ev = dynamic_cast<MemAccessListener*>(pev); MemAccessListener* ev = dynamic_cast<MemAccessListener*>(pev);
// Is this a MemAccessListener? Correct access type? // Is this a MemAccessListener? Correct access type?
if (!ev || !ev->isMatching(addr, accesstype)) { if (!ev || !ev->isMatching(addr, len, accesstype)) {
++it; ++it;
continue; // skip event activation continue; // skip event activation
} }