Events -> Listeners, waitAny -> resume, addEventAndWait -> addListenerAndResume, ... (refactoring), updated experiments/plugin accordingly, coding-style fixed.
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1448 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
@ -101,13 +101,13 @@ void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_sp
|
||||
m_CacheEntry = cache_entry;
|
||||
bool do_fire = false;
|
||||
// Check for active breakpoint-events:
|
||||
bp_cache_t &buffer_cache = m_EvList.getBPBuffer();
|
||||
bp_cache_t &buffer_cache = m_LstList.getBPBuffer();
|
||||
bp_cache_t::iterator it = buffer_cache.begin();
|
||||
while (it != buffer_cache.end()) {
|
||||
BPEvent* pEvBreakpt = *it;
|
||||
BPListener* pEvBreakpt = *it;
|
||||
if (pEvBreakpt->isMatching(instrPtr, address_space)) {
|
||||
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
|
||||
it = buffer_cache.makeActive(m_EvList, it);
|
||||
it = buffer_cache.makeActive(m_LstList, it);
|
||||
do_fire = true;
|
||||
// "it" has already been set to the next element (by calling
|
||||
// makeActive()):
|
||||
@ -116,28 +116,28 @@ void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_sp
|
||||
it++;
|
||||
}
|
||||
if (do_fire)
|
||||
m_EvList.fireActiveEvents();
|
||||
// Note: SimulatorController::onBreakpointEvent will not be invoked in this
|
||||
m_LstList.triggerActiveListeners();
|
||||
// Note: SimulatorController::onBreakpointListener will not be invoked in this
|
||||
// implementation.
|
||||
}
|
||||
|
||||
void BochsController::onIOPortEvent(unsigned char data, unsigned port, bool out) {
|
||||
void BochsController::onIOPortListener(unsigned char data, unsigned port, bool out) {
|
||||
// Check for active breakpoint-events:
|
||||
io_cache_t &buffer_cache = m_EvList.getIOBuffer();
|
||||
io_cache_t &buffer_cache = m_LstList.getIOBuffer();
|
||||
io_cache_t::iterator it = buffer_cache.begin();
|
||||
while (it != buffer_cache.end()) {
|
||||
IOPortEvent* pIOPt = (*it);
|
||||
IOPortListener* pIOPt = (*it);
|
||||
if (pIOPt->isMatching(port, out)) {
|
||||
pIOPt->setData(data);
|
||||
it = buffer_cache.makeActive(m_EvList, it);
|
||||
it = buffer_cache.makeActive(m_LstList, it);
|
||||
// "it" has already been set to the next element (by calling
|
||||
// makeActive()):
|
||||
continue; // -> skip iterator increment
|
||||
}
|
||||
it++;
|
||||
}
|
||||
m_EvList.fireActiveEvents();
|
||||
// Note: SimulatorController::onBreakpointEvent will not be invoked in this
|
||||
m_LstList.triggerActiveListeners();
|
||||
// Note: SimulatorController::onBreakpointListener will not be invoked in this
|
||||
// implementation.
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ void BochsController::saveDone()
|
||||
|
||||
void BochsController::restore(const std::string& path)
|
||||
{
|
||||
clearEvents();
|
||||
clearListeners();
|
||||
restore_bochs_request = true;
|
||||
BX_CPU(0)->async_event |= 1;
|
||||
sr_path = path;
|
||||
@ -181,7 +181,7 @@ void BochsController::restoreDone()
|
||||
|
||||
void BochsController::reboot()
|
||||
{
|
||||
clearEvents();
|
||||
clearListeners();
|
||||
reboot_bochs_request = true;
|
||||
BX_CPU(0)->async_event |= 1;
|
||||
m_CurrFlow = m_Flows.getCurrent();
|
||||
@ -213,16 +213,16 @@ void BochsController::onTimerTrigger(void* thisPtr)
|
||||
{
|
||||
// FIXME: The timer logic can be modified to use only one timer in Bochs.
|
||||
// (For now, this suffices.)
|
||||
TimerEvent* pTmEv = static_cast<TimerEvent*>(thisPtr);
|
||||
// Check for a matching TimerEvent. (In fact, we are only
|
||||
// interessted in the iterator pointing at pTmEv.):
|
||||
EventManager::iterator it = std::find(simulator.m_EvList.begin(),
|
||||
simulator.m_EvList.end(), pTmEv);
|
||||
// TODO: This has O(|m_EvList|) time complexity. We can further improve this
|
||||
// by creating a method such that makeActive(pTmEv) works as well,
|
||||
TimerListener* pli = static_cast<TimerListener*>(thisPtr);
|
||||
// Check for a matching TimerListener. (In fact, we are only
|
||||
// interessted in the iterator pointing at pli.)
|
||||
ListenerManager::iterator it = std::find(simulator.m_LstList.begin(),
|
||||
simulator.m_LstList.end(), pli);
|
||||
// TODO: This has O(|m_LstList|) time complexity. We can further improve this
|
||||
// by creating a method such that makeActive(pli) works as well,
|
||||
// reducing the time complexity to O(1).
|
||||
simulator.m_EvList.makeActive(it);
|
||||
simulator.m_EvList.fireActiveEvents();
|
||||
simulator.m_LstList.makeActive(it);
|
||||
simulator.m_LstList.triggerActiveListeners();
|
||||
}
|
||||
|
||||
const std::string& BochsController::getMnemonic() const
|
||||
|
||||
@ -8,10 +8,10 @@
|
||||
#include <string.h>
|
||||
|
||||
#include "FailBochsGlobals.hpp"
|
||||
#include "BochsEvents.hpp"
|
||||
#include "BochsListener.hpp"
|
||||
|
||||
#include "../SimulatorController.hpp"
|
||||
#include "../Event.hpp"
|
||||
#include "../Listener.hpp"
|
||||
|
||||
#include "bochs.h"
|
||||
#include "cpu/cpu.h"
|
||||
@ -40,7 +40,7 @@ public:
|
||||
BochsController();
|
||||
~BochsController();
|
||||
/* ********************************************************************
|
||||
* Standard Event Handler API:
|
||||
* Standard Listener Handler API:
|
||||
* ********************************************************************/
|
||||
/**
|
||||
* Instruction pointer modification handler. This method is called (from
|
||||
@ -57,20 +57,20 @@ public:
|
||||
* @param port the port it was transmitted on
|
||||
* @param out true if the I/O traffic has been outbound, false otherwise
|
||||
*/
|
||||
void onIOPortEvent(unsigned char data, unsigned port, bool out);
|
||||
void onIOPortListener(unsigned char data, unsigned port, bool out);
|
||||
/**
|
||||
* Static internal event handler for TimerEvents. This static function is
|
||||
* Static internal handler for TimerListeners. This static function is
|
||||
* called when a previously registered (Bochs) timer triggers. This function
|
||||
* searches for the provided TimerEvent object within the EventManager and
|
||||
* fires such an event by calling \c fireActiveEvents().
|
||||
* @param thisPtr a pointer to the TimerEvent-object triggered
|
||||
* searches for the provided TimerListener object within the ListenerManager and
|
||||
* fires such an event by calling \c triggerActiveListeners().
|
||||
* @param thisPtr a pointer to the TimerListener-object triggered
|
||||
*
|
||||
* FIXME: Due to Bochs internal timer and ips-configuration related stuff,
|
||||
* the simulator sometimes panics with "keyboard error:21" (see line
|
||||
* 1777 in bios/rombios.c, function keyboard_init()) if a TimerEvent
|
||||
* 1777 in bios/rombios.c, function keyboard_init()) if a TimerListener
|
||||
* is added *before* the bios has been loaded and initialized. To
|
||||
* reproduce this error, try adding a \c TimerEvent as the initial step
|
||||
* in your experiment code and wait for it (\c addEventAndWait()).
|
||||
* reproduce this error, try adding a \c TimerListener as the initial step
|
||||
* in your experiment code and wait for it (\c addListenerAndResume()).
|
||||
*/
|
||||
static void onTimerTrigger(void *thisPtr);
|
||||
/* ********************************************************************
|
||||
@ -86,7 +86,7 @@ public:
|
||||
*/
|
||||
void saveDone();
|
||||
/**
|
||||
* Restore simulator state. Clears all Events.
|
||||
* Restore simulator state. Clears all Listeners.
|
||||
* @param path Location to previously saved state information
|
||||
*/
|
||||
void restore(const std::string& path);
|
||||
@ -95,7 +95,7 @@ public:
|
||||
*/
|
||||
void restoreDone();
|
||||
/**
|
||||
* Reboot simulator. Clears all Events.
|
||||
* Reboot simulator. Clears all Listeners.
|
||||
*/
|
||||
void reboot();
|
||||
/**
|
||||
|
||||
@ -1,34 +1,34 @@
|
||||
#include "BochsEvents.hpp"
|
||||
#include "BochsListener.hpp"
|
||||
#include "../SALInst.hpp"
|
||||
|
||||
namespace fail {
|
||||
|
||||
bool TimerEvent::onEventAddition()
|
||||
bool TimerListener::onAddition()
|
||||
{
|
||||
// Register the timer event in the Bochs simulator:
|
||||
// Register the timer listener in the Bochs simulator:
|
||||
setId(m_registerTimer(this));
|
||||
if(getId() == -1)
|
||||
return false; // unable to register the timer (error in Bochs' function call)
|
||||
return true;
|
||||
}
|
||||
|
||||
void TimerEvent::onEventDeletion()
|
||||
void TimerListener::onDeletion()
|
||||
{
|
||||
// Unregister the time event:
|
||||
// Unregister the time listener:
|
||||
m_unregisterTimer(this);
|
||||
}
|
||||
|
||||
timer_id_t TimerEvent::m_registerTimer(TimerEvent* pev)
|
||||
timer_id_t TimerListener::m_registerTimer(TimerListener* pev)
|
||||
{
|
||||
assert(pev != NULL && "FATAL ERROR: TimerEvent object ptr cannot be NULL!");
|
||||
assert(pev != NULL && "FATAL ERROR: TimerListener object ptr cannot be NULL!");
|
||||
return static_cast<timer_id_t>(
|
||||
bx_pc_system.register_timer(pev, BochsController::onTimerTrigger, pev->getTimeout(),
|
||||
false, 1/*start immediately*/, "Fail*: BochsController"/*name*/));
|
||||
}
|
||||
|
||||
bool TimerEvent::m_unregisterTimer(TimerEvent* pev)
|
||||
bool TimerListener::m_unregisterTimer(TimerListener* pev)
|
||||
{
|
||||
assert(pev != NULL && "FATAL ERROR: TimerEvent object ptr cannot be NULL!");
|
||||
assert(pev != NULL && "FATAL ERROR: TimerListener object ptr cannot be NULL!");
|
||||
bx_pc_system.deactivate_timer(static_cast<unsigned>(pev->getId()));
|
||||
return bx_pc_system.unregisterTimer(static_cast<unsigned>(pev->getId()));
|
||||
}
|
||||
@ -1,74 +1,76 @@
|
||||
#ifndef __BOCHS_EVENTS_HPP__
|
||||
#define __BOCHS_EVENTS_HPP__
|
||||
|
||||
#include "../Event.hpp"
|
||||
#include "../Listener.hpp"
|
||||
|
||||
#include "BochsController.hpp"
|
||||
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class TimerEvent
|
||||
* Concrete TimerEvent implementation of GenericTimerEvent for the Bochs
|
||||
* \class TimerListener
|
||||
* Concrete TimerListener implementation of GenericTimerListener for the Bochs
|
||||
* simulator backend.
|
||||
*/
|
||||
class TimerEvent : public GenericTimerEvent {
|
||||
class TimerListener : public GenericTimerListener {
|
||||
private:
|
||||
/**
|
||||
* Registers a timer in the Bochs simulator. This timer fires \a TimerEvents
|
||||
* Registers a timer in the Bochs simulator. This timer triggers \a TimerListeners
|
||||
* to inform the corresponding experiment-flow. Note that the number of timers
|
||||
* (in Bochs) is limited to \c BX_MAX_TIMERS (defaults to 64 in v2.4.6).
|
||||
* @param pev a pointer to the (experiment flow-) allocated TimerEvent object,
|
||||
* providing all required information to start the time, e.g. the
|
||||
* timeout value.
|
||||
* @return \c The unique id of the timer recently created. This id is carried
|
||||
* along with the TimerEvent, @see getId(). On errors, -1 is returned
|
||||
* (e.g. because a timer with the same id is already existing)
|
||||
* @param pli a pointer to the (experiment flow-) allocated TimerListener object,
|
||||
* providing all required information to start the timer (e.g. the
|
||||
* timeout value).
|
||||
* @return The unique id of the timer recently created. This id is carried
|
||||
* along with the TimerListener. On errors, -1 is returned (e.g. because
|
||||
* a timer with the same id is already existing)
|
||||
* @see TimerListener::getId()
|
||||
*/
|
||||
static timer_id_t m_registerTimer(TimerEvent* pev);
|
||||
static timer_id_t m_registerTimer(TimerListener* pli);
|
||||
/**
|
||||
* Deletes a timer. No further events will be triggered by the timer.
|
||||
* @param pev a pointer to the TimerEvent-object to be removed
|
||||
* @return \c true if the timer with \a pev->getId() has been removed
|
||||
* @param pli a pointer to the TimerListener-object to be removed
|
||||
* @return \c true if the timer with \a pli->getId() has been removed
|
||||
* successfully, \c false otherwise
|
||||
*/
|
||||
static bool m_unregisterTimer(TimerEvent* pev);
|
||||
static bool m_unregisterTimer(TimerListener* pli);
|
||||
public:
|
||||
/**
|
||||
* Creates a new timer event. This can be used to implement a timeout-
|
||||
* mechanism in the experiment-flow. The timer starts automatically when
|
||||
* added to FailBochs.
|
||||
* @param timeout the time intervall in milliseconds (ms)
|
||||
* @see SimulatorController::addEvent
|
||||
* @see SimulatorController::addListener
|
||||
*/
|
||||
TimerEvent(unsigned timeout)
|
||||
: GenericTimerEvent(timeout) { }
|
||||
~TimerEvent() { onEventDeletion(); }
|
||||
TimerListener(unsigned timeout)
|
||||
: GenericTimerListener(timeout) { }
|
||||
~TimerListener() { onDeletion(); }
|
||||
|
||||
/**
|
||||
* This method is called when an experiment flow adds a new event by
|
||||
* calling \c simulator.addEvent(pev) or \c simulator.addEventAndWait(pev).
|
||||
* calling \c simulator.addListener() or \c simulator.addListenerAndResume().
|
||||
* More specifically, the event will be added to the event-list first
|
||||
* (buffer-list, to be precise) and then this event handler is called.
|
||||
* @return You should return \c true to continue and \c false to prevent
|
||||
* the addition of the event \a pev, yielding an error in the
|
||||
* experiment flow (i.e. -1 is returned).
|
||||
*/
|
||||
bool onEventAddition();
|
||||
bool onAddition();
|
||||
/**
|
||||
* This method is called when an experiment flow removes an event from
|
||||
* the event-management by calling \c removeEvent(prev), \c clearEvents()
|
||||
* the event-management by calling \c removeListener(prev), \c clearListeners()
|
||||
* or by deleting a complete flow (\c removeFlow). More specifically, this
|
||||
* event handler will be called *before* the event is actually deleted.
|
||||
*/
|
||||
void onEventDeletion();
|
||||
void onDeletion();
|
||||
/**
|
||||
* This method is called when an previously added event is about to be
|
||||
* triggered by the simulator-backend. More specifically, this event handler
|
||||
* will be called *before* the event is actually triggered, i.e. before the
|
||||
* corresponding coroutine is toggled.
|
||||
*/
|
||||
void onEventTrigger() { onEventDeletion(); }
|
||||
void onTrigger() { onDeletion(); }
|
||||
// TODO/FIXME: bei neuer impl. anpassen
|
||||
};
|
||||
|
||||
} // end-of-namespace: fail
|
||||
@ -32,7 +32,7 @@ public:
|
||||
* Retrieves the data of the register.
|
||||
* @return the current register data
|
||||
*/
|
||||
regdata_t getData() { return (*m_pData); }
|
||||
regdata_t getData() { return *m_pData; }
|
||||
/**
|
||||
* Sets the content of the register.
|
||||
* @param data the new register data to be written
|
||||
@ -136,44 +136,42 @@ public:
|
||||
* Returns \c true if the corresponding flag is set, or \c false
|
||||
* otherwise.
|
||||
*/
|
||||
bool getCarryFlag() const { return (BX_CPU(0)->get_CF()); }
|
||||
bool getParityFlag() const { return (BX_CPU(0)->get_PF()); }
|
||||
bool getZeroFlag() const { return (BX_CPU(0)->get_ZF()); }
|
||||
bool getSignFlag() const { return (BX_CPU(0)->get_SF()); }
|
||||
bool getOverflowFlag() const { return (BX_CPU(0)->get_OF()); }
|
||||
|
||||
bool getTrapFlag() const { return (BX_CPU(0)->get_TF()); }
|
||||
bool getInterruptFlag() const { return (BX_CPU(0)->get_IF()); }
|
||||
bool getDirectionFlag() const { return (BX_CPU(0)->get_DF()); }
|
||||
unsigned getIOPrivilegeLevel() const { return (BX_CPU(0)->get_IOPL()); }
|
||||
bool getNestedTaskFlag() const { return (BX_CPU(0)->get_NT()); }
|
||||
bool getResumeFlag() const { return (BX_CPU(0)->get_RF()); }
|
||||
bool getVMFlag() const { return (BX_CPU(0)->get_VM()); }
|
||||
bool getAlignmentCheckFlag() const { return (BX_CPU(0)->get_AC()); }
|
||||
bool getVInterruptFlag() const { return (BX_CPU(0)->get_VIF()); }
|
||||
bool getVInterruptPendingFlag() const { return (BX_CPU(0)->get_VIP()); }
|
||||
bool getIdentificationFlag() const { return (BX_CPU(0)->get_ID()); }
|
||||
bool getCarryFlag() const { return BX_CPU(0)->get_CF(); }
|
||||
bool getParityFlag() const { return BX_CPU(0)->get_PF(); }
|
||||
bool getZeroFlag() const { return BX_CPU(0)->get_ZF(); }
|
||||
bool getSignFlag() const { return BX_CPU(0)->get_SF(); }
|
||||
bool getOverflowFlag() const { return BX_CPU(0)->get_OF(); }
|
||||
bool getTrapFlag() const { return BX_CPU(0)->get_TF(); }
|
||||
bool getInterruptFlag() const { return BX_CPU(0)->get_IF(); }
|
||||
bool getDirectionFlag() const { return BX_CPU(0)->get_DF(); }
|
||||
unsigned getIOPrivilegeLevel() const { return BX_CPU(0)->get_IOPL(); }
|
||||
bool getNestedTaskFlag() const { return BX_CPU(0)->get_NT(); }
|
||||
bool getResumeFlag() const { return BX_CPU(0)->get_RF(); }
|
||||
bool getVMFlag() const { return BX_CPU(0)->get_VM(); }
|
||||
bool getAlignmentCheckFlag() const { return BX_CPU(0)->get_AC(); }
|
||||
bool getVInterruptFlag() const { return BX_CPU(0)->get_VIF(); }
|
||||
bool getVInterruptPendingFlag() const { return BX_CPU(0)->get_VIP(); }
|
||||
bool getIdentificationFlag() const { return BX_CPU(0)->get_ID(); }
|
||||
|
||||
/**
|
||||
* Sets/resets various status FLAGS.
|
||||
*/
|
||||
void setCarryFlag(bool bit) { BX_CPU(0)->set_CF(bit); }
|
||||
void setParityFlag(bool bit) { BX_CPU(0)->set_PF(bit); }
|
||||
void setZeroFlag(bool bit) { BX_CPU(0)->set_ZF(bit); }
|
||||
void setSignFlag(bool bit) { BX_CPU(0)->set_SF(bit); }
|
||||
void setOverflowFlag(bool bit) { BX_CPU(0)->set_OF(bit); }
|
||||
|
||||
void setTrapFlag(bool bit) { BX_CPU(0)->set_TF(bit); }
|
||||
void setInterruptFlag(bool bit) { BX_CPU(0)->set_IF(bit); }
|
||||
void setDirectionFlag(bool bit) { BX_CPU(0)->set_DF(bit); }
|
||||
void setIOPrivilegeLevel(unsigned lvl) { BX_CPU(0)->set_IOPL(lvl); }
|
||||
void setNestedTaskFlag(bool bit) { BX_CPU(0)->set_NT(bit); }
|
||||
void setResumeFlag(bool bit) { BX_CPU(0)->set_RF(bit); }
|
||||
void setVMFlag(bool bit) { BX_CPU(0)->set_VM(bit); }
|
||||
void setAlignmentCheckFlag(bool bit) { BX_CPU(0)->set_AC(bit); }
|
||||
void setVInterruptFlag(bool bit) { BX_CPU(0)->set_VIF(bit); }
|
||||
void setVInterruptPendingFlag(bool bit) { BX_CPU(0)->set_VIP(bit); }
|
||||
void setIdentificationFlag(bool bit) { BX_CPU(0)->set_ID(bit); }
|
||||
void setCarryFlag(bool bit) { BX_CPU(0)->set_CF(bit); }
|
||||
void setParityFlag(bool bit) { BX_CPU(0)->set_PF(bit); }
|
||||
void setZeroFlag(bool bit) { BX_CPU(0)->set_ZF(bit); }
|
||||
void setSignFlag(bool bit) { BX_CPU(0)->set_SF(bit); }
|
||||
void setOverflowFlag(bool bit) { BX_CPU(0)->set_OF(bit); }
|
||||
void setTrapFlag(bool bit) { BX_CPU(0)->set_TF(bit); }
|
||||
void setInterruptFlag(bool bit) { BX_CPU(0)->set_IF(bit); }
|
||||
void setDirectionFlag(bool bit) { BX_CPU(0)->set_DF(bit); }
|
||||
void setIOPrivilegeLevel(unsigned lvl) { BX_CPU(0)->set_IOPL(lvl); }
|
||||
void setNestedTaskFlag(bool bit) { BX_CPU(0)->set_NT(bit); }
|
||||
void setResumeFlag(bool bit) { BX_CPU(0)->set_RF(bit); }
|
||||
void setVMFlag(bool bit) { BX_CPU(0)->set_VM(bit); }
|
||||
void setAlignmentCheckFlag(bool bit) { BX_CPU(0)->set_AC(bit); }
|
||||
void setVInterruptFlag(bool bit) { BX_CPU(0)->set_VIF(bit); }
|
||||
void setVInterruptPendingFlag(bool bit) { BX_CPU(0)->set_VIP(bit); }
|
||||
void setIdentificationFlag(bool bit) { BX_CPU(0)->set_ID(bit); }
|
||||
|
||||
/**
|
||||
* Sets the content of the status register.
|
||||
@ -184,8 +182,7 @@ public:
|
||||
{
|
||||
#ifdef BX_SUPPORT_X86_64
|
||||
// We are in 64 bit mode: Just assign the lower 32 bits!
|
||||
(*m_pData) = ((*m_pData) & 0xFFFFFFFF00000000ULL) |
|
||||
(data & 0xFFFFFFFFULL);
|
||||
(*m_pData) = ((*m_pData) & 0xFFFFFFFF00000000ULL) | (data & 0xFFFFFFFFULL);
|
||||
#else
|
||||
*m_pData = data;
|
||||
#endif
|
||||
@ -204,7 +201,7 @@ public:
|
||||
*/
|
||||
address_t getInstructionPointer()
|
||||
{
|
||||
return (static_cast<address_t>(getSetOfType(RT_PC)->first()->getData()));
|
||||
return static_cast<address_t>(getSetOfType(RT_PC)->first()->getData());
|
||||
}
|
||||
/**
|
||||
* Retruns the top address of the stack.
|
||||
@ -213,9 +210,9 @@ public:
|
||||
address_t getStackPointer()
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
return (static_cast<address_t>(getRegister(RID_RSP)->getData()));
|
||||
return static_cast<address_t>(getRegister(RID_RSP)->getData());
|
||||
#else
|
||||
return (static_cast<address_t>(getRegister(RID_ESP)->getData()));
|
||||
return static_cast<address_t>(getRegister(RID_ESP)->getData());
|
||||
#endif
|
||||
}
|
||||
/**
|
||||
@ -226,9 +223,9 @@ public:
|
||||
address_t getBasePointer()
|
||||
{
|
||||
#if BX_SUPPORT_X86_64
|
||||
return (static_cast<address_t>(getRegister(RID_RBP)->getData()));
|
||||
return static_cast<address_t>(getRegister(RID_RBP)->getData());
|
||||
#else
|
||||
return (static_cast<address_t>(getRegister(RID_EBP)->getData()));
|
||||
return static_cast<address_t>(getRegister(RID_EBP)->getData());
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
@ -13,7 +13,7 @@
|
||||
aspect Breakpoints {
|
||||
pointcut cpuLoop() = "void defineCPULoopJoinPoint(...)";
|
||||
|
||||
advice execution (cpuLoop()) : after () // Event source: "instruction pointer"
|
||||
advice execution (cpuLoop()) : after () // event source: "instruction pointer"
|
||||
{
|
||||
// Points to the cpu class: "this" if BX_USE_CPU_SMF == 0,
|
||||
// BX_CPU(0) otherwise
|
||||
|
||||
@ -19,12 +19,12 @@
|
||||
aspect GuestSysCom {
|
||||
pointcut outInstructions() = "% ...::bx_cpu_c::OUT_DX%(...)";
|
||||
|
||||
advice execution (outInstructions()) : after () // Event source: "guest system"
|
||||
advice execution (outInstructions()) : after () // Listener source: "guest system"
|
||||
{
|
||||
unsigned rDX = getCPU(tjp->that())->gen_reg[2].word.rx; // port number
|
||||
unsigned rAL = getCPU(tjp->that())->gen_reg[0].word.byte.rl; // data
|
||||
if (rDX == BOCHS_COM_PORT)
|
||||
fail::simulator.onGuestSystemEvent((char)rAL, rDX);
|
||||
fail::simulator.onGuestSystemListener((char)rAL, rDX);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@ aspect IOPortCom {
|
||||
{
|
||||
unsigned rDX = getCPU(tjp->that())->gen_reg[2].word.rx; // port number
|
||||
unsigned char rAL = getCPU(tjp->that())->gen_reg[0].word.byte.rl; // data
|
||||
fail::simulator.onIOPortEvent(rAL, rDX, true);
|
||||
fail::simulator.onIOPortListener(rAL, rDX, true);
|
||||
}
|
||||
|
||||
pointcut inInstruction() = "% ...::bx_cpu_c::IN_ALDX(...)";
|
||||
@ -30,7 +30,7 @@ aspect IOPortCom {
|
||||
{
|
||||
unsigned rDX = getCPU(tjp->that())->gen_reg[2].word.rx; // port number
|
||||
unsigned char rAL = getCPU(tjp->that())->gen_reg[0].word.byte.rl; // data
|
||||
fail::simulator.onIOPortEvent(rAL, rDX, false);
|
||||
fail::simulator.onIOPortListener(rAL, rDX, false);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -28,9 +28,9 @@ aspect Interrupt {
|
||||
unsigned vector = *(tjp->arg<0>());
|
||||
unsigned type = *(tjp->arg<1>());
|
||||
if (type == BX_EXTERNAL_INTERRUPT)
|
||||
fail::simulator.onInterruptEvent(vector, false);
|
||||
fail::simulator.onInterruptListener(vector, false);
|
||||
else if (type == BX_NMI)
|
||||
fail::simulator.onInterruptEvent(vector, true);
|
||||
fail::simulator.onInterruptListener(vector, true);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -60,7 +60,7 @@ aspect Jump {
|
||||
advice execution (defJumpInstructions()) : around()
|
||||
{
|
||||
bxInstruction_c* pInstr = *(tjp->arg<0>()); // bxInstruction_c-object
|
||||
fail::simulator.onJumpEvent(true, pInstr->getIaOpcode());
|
||||
fail::simulator.onJumpListener(true, pInstr->getIaOpcode());
|
||||
/*
|
||||
JoinPoint::That* pThis = tjp->that();
|
||||
if(pThis == NULL)
|
||||
@ -77,7 +77,7 @@ aspect Jump {
|
||||
// Step-1: Modify one or more of the fxxxFlag according to the error you want to inject
|
||||
// (using pThis->set_XX(new_val))
|
||||
// Step-2: Call tjp->proceed();
|
||||
// Step-3: Eventually, unwind the changes of Step-1
|
||||
// Step-3: Listenerually, unwind the changes of Step-1
|
||||
//
|
||||
|
||||
// Example:
|
||||
@ -109,7 +109,7 @@ aspect Jump {
|
||||
advice execution (regJumpInstructions()) : around ()
|
||||
{
|
||||
bxInstruction_c* pInstr = *(tjp->arg<0>()); // bxInstruction_c-object
|
||||
fail::simulator.onJumpEvent(false, pInstr->getIaOpcode());
|
||||
fail::simulator.onJumpListener(false, pInstr->getIaOpcode());
|
||||
/*
|
||||
JoinPoint::That* pThis = tjp->that();
|
||||
|
||||
|
||||
@ -56,19 +56,19 @@ aspect MemAccess {
|
||||
// Fire a memory-write-event each time the guest system requests
|
||||
// to write data to RAM:
|
||||
//
|
||||
// Event source: "memory write access"
|
||||
// Listener source: "memory write access"
|
||||
//
|
||||
#ifdef CONFIG_EVENT_MEMWRITE
|
||||
advice execution (write_methods()) : after ()
|
||||
{
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessListener(
|
||||
*(tjp->arg<1>()), sizeof(*(tjp->arg<2>())), true,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
|
||||
advice execution (write_methods_RMW()) : after ()
|
||||
{
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessListener(
|
||||
rmw_address, sizeof(*(tjp->arg<0>())), true,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
@ -77,7 +77,7 @@ aspect MemAccess {
|
||||
{
|
||||
std::cerr << "WOOOOOT write_methods_new_stack" << std::endl;
|
||||
// TODO: Log-level?
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessListener(
|
||||
*(tjp->arg<1>()), sizeof(*(tjp->arg<3>())), true,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
@ -86,7 +86,7 @@ aspect MemAccess {
|
||||
{
|
||||
std::cerr << "WOOOOOT write_methods_new_stack_64" << std::endl;
|
||||
// TODO: Log-level?
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessListener(
|
||||
*(tjp->arg<0>()), sizeof(*(tjp->arg<2>())), true,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
@ -98,7 +98,7 @@ aspect MemAccess {
|
||||
// memory (e.g., to read vectors from the interrupt vector
|
||||
// table).
|
||||
/*
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessListener(
|
||||
*(tjp->arg<0>()), sizeof(*(tjp->arg<1>())), true,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
*/
|
||||
@ -109,19 +109,19 @@ aspect MemAccess {
|
||||
// Fire a memory-read-event each time the guest system requests
|
||||
// to read data in RAM:
|
||||
//
|
||||
// Event source: "memory read access"
|
||||
// Listener source: "memory read access"
|
||||
//
|
||||
#ifdef CONFIG_EVENT_MEMREAD
|
||||
advice execution (read_methods()) : before ()
|
||||
{
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessListener(
|
||||
*(tjp->arg<1>()), sizeof(*(tjp->result())), false,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
|
||||
advice execution (read_methods_dqword()) : before ()
|
||||
{
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessListener(
|
||||
*(tjp->arg<1>()), 16, false,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
@ -131,7 +131,7 @@ aspect MemAccess {
|
||||
{
|
||||
rmw_address = *(tjp->arg<1>());
|
||||
#ifdef CONFIG_EVENT_MEMREAD
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessListener(
|
||||
*(tjp->arg<1>()), sizeof(*(tjp->result())), false,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
#endif
|
||||
@ -145,7 +145,7 @@ aspect MemAccess {
|
||||
// memory (e.g., to read vectors from the interrupt vector
|
||||
// table).
|
||||
/*
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessListener(
|
||||
*(tjp->arg<0>()), sizeof(*(tjp->result())), false,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
*/
|
||||
|
||||
@ -15,9 +15,9 @@ aspect Trap {
|
||||
|
||||
advice execution (exception_method()) : before ()
|
||||
{
|
||||
fail::simulator.onTrapEvent(*(tjp->arg<0>()));
|
||||
fail::simulator.onTrapListener(*(tjp->arg<0>()));
|
||||
// TODO: There are some different types of exceptions at cpu.h (line 265-281)
|
||||
// Which kind of a trap are these types?
|
||||
// Which kind of traps are these types?
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user