Namespaces unified (sal+fi -> fail), Code cleanups (-> coding-style.txt), Doxygen-comments fixed.
git-svn-id: https://www4.informatik.uni-erlangen.de/i4svn/danceos/trunk/devel/fail@1319 8c4709b5-6ec9-48aa-a5cd-a96041d1645a
This commit is contained in:
@ -134,7 +134,7 @@ void BX_CPU_C::cpu_loop(Bit32u max_instr_count)
|
||||
}
|
||||
// DanceOS
|
||||
#ifdef DANCEOS_RESTORE
|
||||
else if(sal::restore_bochs_request) {
|
||||
else if(fail::restore_bochs_request) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -454,7 +454,7 @@ unsigned BX_CPU_C::handleAsyncEvent(void)
|
||||
|
||||
//DanceOS
|
||||
#ifdef DANCEOS_RESTORE
|
||||
if (sal::restore_bochs_request) {
|
||||
if (fail::restore_bochs_request) {
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -668,8 +668,8 @@ void bx_gui_c::restore_handler(void)
|
||||
bx_param_string_c::SELECT_FOLDER_DLG);
|
||||
if ((ret >= 0) && (strcmp(temp_path, "none"))) {
|
||||
|
||||
sal::restore_bochs_request = true;
|
||||
sal::sr_path = temp_path;
|
||||
fail::restore_bochs_request = true;
|
||||
fail::sr_path = temp_path;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -304,7 +304,7 @@ marke:
|
||||
|
||||
//DanceOS
|
||||
#ifdef DANCEOS_RESTORE
|
||||
if(sal::restore_bochs_request){
|
||||
if(fail::restore_bochs_request){
|
||||
|
||||
bx_devices.exit();
|
||||
|
||||
@ -656,10 +656,10 @@ int bx_init_main(int argc, char *argv[])
|
||||
}
|
||||
//DanceOS
|
||||
#ifdef DANCEOS_RESTORE
|
||||
if(sal::restore_bochs_request){
|
||||
if(fail::restore_bochs_request){
|
||||
SIM->get_param_bool(BXPN_RESTORE_FLAG)->set(1);
|
||||
SIM->get_param_enum(BXPN_BOCHS_START)->set(BX_QUICK_START);
|
||||
SIM->get_param_string(BXPN_RESTORE_PATH)->set(sal::sr_path.c_str());
|
||||
SIM->get_param_string(BXPN_RESTORE_PATH)->set(fail::sr_path.c_str());
|
||||
}
|
||||
#endif
|
||||
#if BX_WITH_CARBON
|
||||
@ -980,7 +980,7 @@ int bx_begin_simulation (int argc, char *argv[])
|
||||
}
|
||||
//DanceOS
|
||||
#ifdef DANCEOS_RESTORE
|
||||
if(sal::restore_bochs_request){
|
||||
if(fail::restore_bochs_request){
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -1004,7 +1004,7 @@ int bx_begin_simulation (int argc, char *argv[])
|
||||
}
|
||||
//DanceOS
|
||||
#ifdef DANCEOS_RESTORE
|
||||
if(sal::restore_bochs_request){
|
||||
if(fail::restore_bochs_request){
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -215,7 +215,7 @@ void BX_MEM_C::cleanup_memory()
|
||||
|
||||
// DanceOS
|
||||
#ifdef DANCEOS_RESTORE
|
||||
if (BX_MEM_THIS vector != NULL || sal::restore_bochs_request) {
|
||||
if (BX_MEM_THIS vector != NULL || fail::restore_bochs_request) {
|
||||
#else
|
||||
if (BX_MEM_THIS vector != NULL) {
|
||||
#endif
|
||||
|
||||
@ -1,12 +1,9 @@
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 09.09.2011
|
||||
#include <cstdlib>
|
||||
|
||||
#include "Memory.hpp"
|
||||
|
||||
#include <cstdlib>
|
||||
namespace fail {
|
||||
|
||||
const guest_address_t ADDR_INV = 0;
|
||||
|
||||
namespace sal
|
||||
{
|
||||
const guest_address_t ADDR_INV = 0;
|
||||
}
|
||||
|
||||
@ -1,17 +1,13 @@
|
||||
#ifndef __MEMORY_HPP__
|
||||
#define __MEMORY_HPP__
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 07.09.2011
|
||||
|
||||
#include <vector>
|
||||
#include <stdint.h>
|
||||
#include <cstring> // Added for size_t support
|
||||
|
||||
#include "SALConfig.hpp"
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class MemoryManager
|
||||
@ -73,6 +69,6 @@ class MemoryManager
|
||||
virtual host_address_t guestToHost(guest_address_t addr) = 0;
|
||||
};
|
||||
|
||||
} // end-of-namespace: sal
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __MEMORY_HPP__ */
|
||||
#endif // __MEMORY_HPP__
|
||||
|
||||
@ -1,72 +1,69 @@
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 07.09.2011
|
||||
|
||||
#include "Register.hpp"
|
||||
|
||||
namespace sal
|
||||
namespace fail {
|
||||
|
||||
Register* UniformRegisterSet::getRegister(size_t i)
|
||||
{
|
||||
Register* UniformRegisterSet::getRegister(size_t i)
|
||||
{
|
||||
assert(i < m_Regs.size() && "FATAL ERROR: Invalid index provided!");
|
||||
return (m_Regs[i]);
|
||||
}
|
||||
|
||||
Register* RegisterManager::getRegister(size_t i)
|
||||
{
|
||||
assert(i < m_Registers.size() && "FATAL ERROR: Invalid index provided!");
|
||||
return (m_Registers[i]);
|
||||
}
|
||||
|
||||
void RegisterManager::add(Register* reg)
|
||||
{
|
||||
assert(!reg->isAssigned() && "FATAL ERROR: The register is already assigned!");
|
||||
m_Registers.push_back(reg);
|
||||
|
||||
UniformRegisterSet* urs = getSetOfType(reg->getType());
|
||||
if(urs == NULL) {
|
||||
urs = new UniformRegisterSet(reg->getType());
|
||||
m_Subsets.push_back(urs);
|
||||
}
|
||||
urs->m_add(reg);
|
||||
}
|
||||
|
||||
void UniformRegisterSet::m_add(Register* preg)
|
||||
{
|
||||
assert(!preg->m_Assigned &&
|
||||
"FATAL ERROR: The register has already been assigned.");
|
||||
m_Regs.push_back(preg);
|
||||
preg->m_Assigned = true;
|
||||
preg->m_Index = m_Regs.size()-1; // the index within the vector (set)
|
||||
}
|
||||
|
||||
size_t RegisterManager::count() const
|
||||
{
|
||||
return (m_Registers.size());
|
||||
}
|
||||
|
||||
UniformRegisterSet& RegisterManager::getSet(size_t i)
|
||||
{
|
||||
assert(i < m_Subsets.size() && "FATAL ERROR: Invalid index provided!");
|
||||
return (*m_Subsets[i]);
|
||||
}
|
||||
|
||||
UniformRegisterSet* RegisterManager::getSetOfType(RegisterType t)
|
||||
{
|
||||
for(std::vector< UniformRegisterSet* >::iterator it = m_Subsets.begin();
|
||||
it != m_Subsets.end(); it++)
|
||||
{
|
||||
if((*it)->getType() == t)
|
||||
return (*it);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void RegisterManager::clear()
|
||||
{
|
||||
for(std::vector< UniformRegisterSet* >::iterator it = m_Subsets.begin();
|
||||
it != m_Subsets.end(); it++)
|
||||
delete (*it);
|
||||
m_Subsets.clear();
|
||||
}
|
||||
assert(i < m_Regs.size() && "FATAL ERROR: Invalid index provided!");
|
||||
return (m_Regs[i]);
|
||||
}
|
||||
|
||||
Register* RegisterManager::getRegister(size_t i)
|
||||
{
|
||||
assert(i < m_Registers.size() && "FATAL ERROR: Invalid index provided!");
|
||||
return (m_Registers[i]);
|
||||
}
|
||||
|
||||
void RegisterManager::add(Register* reg)
|
||||
{
|
||||
assert(!reg->isAssigned() && "FATAL ERROR: The register is already assigned!");
|
||||
m_Registers.push_back(reg);
|
||||
|
||||
UniformRegisterSet* urs = getSetOfType(reg->getType());
|
||||
if(urs == NULL) {
|
||||
urs = new UniformRegisterSet(reg->getType());
|
||||
m_Subsets.push_back(urs);
|
||||
}
|
||||
urs->m_add(reg);
|
||||
}
|
||||
|
||||
void UniformRegisterSet::m_add(Register* preg)
|
||||
{
|
||||
assert(!preg->m_Assigned &&
|
||||
"FATAL ERROR: The register has already been assigned.");
|
||||
m_Regs.push_back(preg);
|
||||
preg->m_Assigned = true;
|
||||
preg->m_Index = m_Regs.size()-1; // the index within the vector (set)
|
||||
}
|
||||
|
||||
size_t RegisterManager::count() const
|
||||
{
|
||||
return (m_Registers.size());
|
||||
}
|
||||
|
||||
UniformRegisterSet& RegisterManager::getSet(size_t i)
|
||||
{
|
||||
assert(i < m_Subsets.size() && "FATAL ERROR: Invalid index provided!");
|
||||
return (*m_Subsets[i]);
|
||||
}
|
||||
|
||||
UniformRegisterSet* RegisterManager::getSetOfType(RegisterType t)
|
||||
{
|
||||
for(std::vector< UniformRegisterSet* >::iterator it = m_Subsets.begin();
|
||||
it != m_Subsets.end(); it++)
|
||||
{
|
||||
if((*it)->getType() == t)
|
||||
return (*it);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
void RegisterManager::clear()
|
||||
{
|
||||
for(std::vector< UniformRegisterSet* >::iterator it = m_Subsets.begin();
|
||||
it != m_Subsets.end(); it++)
|
||||
delete (*it);
|
||||
m_Subsets.clear();
|
||||
}
|
||||
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -9,11 +9,11 @@
|
||||
|
||||
#include "SALConfig.hpp"
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \enum RegisterType
|
||||
*
|
||||
* Lists the different register types. You need to expand this enumeration
|
||||
* to provide more detailed types for your concrete derived register classes
|
||||
* specific to a simulator.
|
||||
@ -27,6 +27,7 @@ enum RegisterType
|
||||
|
||||
/**
|
||||
* \class Register
|
||||
*
|
||||
* Represents the basic generic register class. A set of registers is composed
|
||||
* of classes which had been derived from this class.
|
||||
*/
|
||||
@ -106,6 +107,7 @@ class Register
|
||||
|
||||
/**
|
||||
* \class UniformRegisterSet
|
||||
*
|
||||
* Represents a (type-uniform) set of registers, e.g. all general purpose
|
||||
* registers. The granularity of the register type is determined by the
|
||||
* enumeration \c RegisterType. (All registers within this set must be of the
|
||||
@ -271,6 +273,6 @@ class RegisterManager
|
||||
virtual address_t getBasePointer() = 0;
|
||||
};
|
||||
|
||||
} // end-of-namespace: sal
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __REGISTER_HPP__ */
|
||||
#endif // __REGISTER_HPP__
|
||||
|
||||
@ -13,8 +13,7 @@
|
||||
#error SAL Config Target not defined
|
||||
#endif
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
typedef guest_address_t address_t; //!< common address type to be used in experiment flows
|
||||
typedef uint8_t byte_t; //!< 8 bit type for memory access (read or write)
|
||||
@ -24,6 +23,6 @@ typedef timer_t timer_id_t; //!< type of timer IDs
|
||||
|
||||
extern const address_t ADDR_INV; //!< invalid address flag (defined in Memory.cc)
|
||||
|
||||
}
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif // __SAL_CONFIG_HPP__
|
||||
|
||||
@ -8,8 +8,7 @@
|
||||
|
||||
#include "bochs/BochsController.hpp"
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
typedef BochsController ConcreteSimulatorController; //!< concrete simulator (type)
|
||||
extern ConcreteSimulatorController simulator; //!< the global simulator-controller instance
|
||||
@ -20,8 +19,7 @@ extern ConcreteSimulatorController simulator; //!< the global simulator-controll
|
||||
|
||||
#include "ovp/OVPController.hpp"
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
typedef OVPController ConcreteSimulatorController; //!< concrete simulator (type)
|
||||
extern ConcreteSimulatorController simulator; //!< the global simulator-controller instance
|
||||
@ -32,4 +30,4 @@ extern ConcreteSimulatorController simulator; //!< the global simulator-controll
|
||||
#error SAL Instance not defined
|
||||
#endif
|
||||
|
||||
#endif /* __SAL_INSTANCE_HPP__ */
|
||||
#endif // __SAL_INSTANCE_HPP__
|
||||
|
||||
@ -2,25 +2,24 @@
|
||||
#include "SALInst.hpp"
|
||||
#include "../controller/Event.hpp"
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
// External reference declared in SALInst.hpp
|
||||
ConcreteSimulatorController simulator;
|
||||
|
||||
fi::EventId SimulatorController::addEvent(fi::BaseEvent* ev)
|
||||
EventId SimulatorController::addEvent(BaseEvent* ev)
|
||||
{
|
||||
assert(ev != NULL && "FATAL ERROR: ev pointer cannot be NULL!");
|
||||
fi::EventId ret = m_EvList.add(ev, m_Flows.getCurrent());
|
||||
EventId ret = m_EvList.add(ev, m_Flows.getCurrent());
|
||||
// Call the common postprocessing function:
|
||||
if (!onEventAddition(ev)) { // If the return value signals "false"...,
|
||||
m_EvList.remove(ev); // ...skip the addition
|
||||
ret = -1;
|
||||
ret = INVALID_EVENT;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
fi::BaseEvent* SimulatorController::waitAny(void)
|
||||
BaseEvent* SimulatorController::waitAny(void)
|
||||
{
|
||||
m_Flows.resume();
|
||||
assert(m_EvList.getLastFired() != NULL &&
|
||||
@ -32,6 +31,7 @@ void SimulatorController::startup()
|
||||
{
|
||||
// Some greetings to the user:
|
||||
std::cout << "[SimulatorController] Initializing..." << std::endl;
|
||||
// TODO: Log-Level?
|
||||
|
||||
// Activate previously added experiments to allow initialization:
|
||||
initExperiments();
|
||||
@ -50,12 +50,12 @@ void SimulatorController::onBreakpointEvent(address_t instrPtr, address_t addres
|
||||
// FIXME: Improve performance
|
||||
|
||||
// Loop through all events of type BP*Event:
|
||||
fi::EventList::iterator it = m_EvList.begin();
|
||||
EventList::iterator it = m_EvList.begin();
|
||||
while (it != m_EvList.end())
|
||||
{
|
||||
fi::BaseEvent* pev = *it;
|
||||
fi::BPSingleEvent* pbp; fi::BPRangeEvent* pbpr;
|
||||
if((pbp = dynamic_cast<fi::BPSingleEvent*>(pev)) && pbp->isMatching(instrPtr, address_space))
|
||||
BaseEvent* pev = *it;
|
||||
BPSingleEvent* pbp; BPRangeEvent* pbpr;
|
||||
if((pbp = dynamic_cast<BPSingleEvent*>(pev)) && pbp->isMatching(instrPtr, address_space))
|
||||
{
|
||||
pbp->setTriggerInstructionPointer(instrPtr);
|
||||
it = m_EvList.makeActive(it);
|
||||
@ -63,7 +63,7 @@ void SimulatorController::onBreakpointEvent(address_t instrPtr, address_t addres
|
||||
// makeActive()):
|
||||
continue; // -> skip iterator increment
|
||||
}
|
||||
else if((pbpr = dynamic_cast<fi::BPRangeEvent*>(pev)) &&
|
||||
else if((pbpr = dynamic_cast<BPRangeEvent*>(pev)) &&
|
||||
pbpr->isMatching(instrPtr, address_space))
|
||||
{
|
||||
pbpr->setTriggerInstructionPointer(instrPtr);
|
||||
@ -80,15 +80,15 @@ void SimulatorController::onMemoryAccessEvent(address_t addr, size_t len,
|
||||
{
|
||||
// FIXME: Improve performance
|
||||
|
||||
fi::MemAccessEvent::accessType_t accesstype =
|
||||
is_write ? fi::MemAccessEvent::MEM_WRITE
|
||||
: fi::MemAccessEvent::MEM_READ;
|
||||
MemAccessEvent::accessType_t accesstype =
|
||||
is_write ? MemAccessEvent::MEM_WRITE
|
||||
: MemAccessEvent::MEM_READ;
|
||||
|
||||
fi::EventList::iterator it = m_EvList.begin();
|
||||
EventList::iterator it = m_EvList.begin();
|
||||
while(it != m_EvList.end()) // check for active events
|
||||
{
|
||||
fi::BaseEvent* pev = *it;
|
||||
fi::MemAccessEvent* ev = dynamic_cast<fi::MemAccessEvent*>(pev);
|
||||
BaseEvent* pev = *it;
|
||||
MemAccessEvent* ev = dynamic_cast<MemAccessEvent*>(pev);
|
||||
// Is this a MemAccessEvent? Correct access type?
|
||||
if(!ev || !ev->isMatching(addr, accesstype))
|
||||
{
|
||||
@ -106,11 +106,11 @@ void SimulatorController::onMemoryAccessEvent(address_t addr, size_t len,
|
||||
|
||||
void SimulatorController::onInterruptEvent(unsigned interruptNum, bool nmi)
|
||||
{
|
||||
fi::EventList::iterator it = m_EvList.begin();
|
||||
EventList::iterator it = m_EvList.begin();
|
||||
while(it != m_EvList.end()) // check for active events
|
||||
{
|
||||
fi::BaseEvent* pev = *it;
|
||||
fi::InterruptEvent* pie = dynamic_cast<fi::InterruptEvent*>(pev);
|
||||
BaseEvent* pev = *it;
|
||||
InterruptEvent* pie = dynamic_cast<InterruptEvent*>(pev);
|
||||
if(!pie || !pie->isMatching(interruptNum))
|
||||
{
|
||||
++it;
|
||||
@ -127,7 +127,7 @@ bool SimulatorController::isSuppressedInterrupt(unsigned interruptNum)
|
||||
{
|
||||
for(size_t i = 0; i < m_SuppressedInterrupts.size(); i++)
|
||||
if((m_SuppressedInterrupts[i] == interruptNum ||
|
||||
m_SuppressedInterrupts[i] == fi::ANY_INTERRUPT) && interruptNum != (unsigned) interrupt_to_fire+32 ){
|
||||
m_SuppressedInterrupts[i] == ANY_INTERRUPT) && interruptNum != (unsigned) interrupt_to_fire+32 ){
|
||||
if((int)interruptNum == interrupt_to_fire+32){
|
||||
interrupt_to_fire = -1;
|
||||
return(true);
|
||||
@ -143,7 +143,7 @@ bool SimulatorController::addSuppressedInterrupt(unsigned interruptNum)
|
||||
if(isSuppressedInterrupt(interruptNum+32))
|
||||
return (false); // already added: nothing to do here
|
||||
|
||||
if(interruptNum == fi::ANY_INTERRUPT){
|
||||
if(interruptNum == ANY_INTERRUPT){
|
||||
m_SuppressedInterrupts.push_back(interruptNum);
|
||||
return (true);
|
||||
}else{
|
||||
@ -156,7 +156,7 @@ bool SimulatorController::removeSuppressedInterrupt(unsigned interruptNum)
|
||||
{
|
||||
for(size_t i = 0; i < m_SuppressedInterrupts.size(); i++)
|
||||
{
|
||||
if(m_SuppressedInterrupts[i] == interruptNum+32 || m_SuppressedInterrupts[i] == fi::ANY_INTERRUPT)
|
||||
if(m_SuppressedInterrupts[i] == interruptNum+32 || m_SuppressedInterrupts[i] == ANY_INTERRUPT)
|
||||
{
|
||||
m_SuppressedInterrupts.erase(m_SuppressedInterrupts.begin() + i);
|
||||
return (true);
|
||||
@ -167,11 +167,11 @@ bool SimulatorController::removeSuppressedInterrupt(unsigned interruptNum)
|
||||
|
||||
void SimulatorController::onTrapEvent(unsigned trapNum)
|
||||
{
|
||||
fi::EventList::iterator it = m_EvList.begin();
|
||||
EventList::iterator it = m_EvList.begin();
|
||||
while(it != m_EvList.end()) // check for active events
|
||||
{
|
||||
fi::BaseEvent* pev = *it;
|
||||
fi::TrapEvent* pte = dynamic_cast<fi::TrapEvent*>(pev);
|
||||
BaseEvent* pev = *it;
|
||||
TrapEvent* pte = dynamic_cast<TrapEvent*>(pev);
|
||||
if(!pte || !pte->isMatching(trapNum))
|
||||
{
|
||||
++it;
|
||||
@ -185,11 +185,11 @@ void SimulatorController::onTrapEvent(unsigned trapNum)
|
||||
|
||||
void SimulatorController::onGuestSystemEvent(char data, unsigned port)
|
||||
{
|
||||
fi::EventList::iterator it = m_EvList.begin();
|
||||
EventList::iterator it = m_EvList.begin();
|
||||
while(it != m_EvList.end()) // check for active events
|
||||
{
|
||||
fi::BaseEvent* pev = *it;
|
||||
fi::GuestEvent* pge = dynamic_cast<fi::GuestEvent*>(pev);
|
||||
BaseEvent* pev = *it;
|
||||
GuestEvent* pge = dynamic_cast<GuestEvent*>(pev);
|
||||
if(pge != NULL)
|
||||
{
|
||||
pge->setData(data);
|
||||
@ -204,10 +204,10 @@ void SimulatorController::onGuestSystemEvent(char data, unsigned port)
|
||||
|
||||
void SimulatorController::onJumpEvent(bool flagTriggered, unsigned opcode)
|
||||
{
|
||||
fi::EventList::iterator it = m_EvList.begin();
|
||||
EventList::iterator it = m_EvList.begin();
|
||||
while(it != m_EvList.end()) // check for active events
|
||||
{
|
||||
fi::JumpEvent* pje = dynamic_cast<fi::JumpEvent*>(*it);
|
||||
JumpEvent* pje = dynamic_cast<JumpEvent*>(*it);
|
||||
if(pje != NULL)
|
||||
{
|
||||
pje->setOpcode(opcode);
|
||||
@ -220,7 +220,7 @@ void SimulatorController::onJumpEvent(bool flagTriggered, unsigned opcode)
|
||||
m_EvList.fireActiveEvents();
|
||||
}
|
||||
|
||||
void SimulatorController::addFlow(fi::ExperimentFlow* flow)
|
||||
void SimulatorController::addFlow(ExperimentFlow* flow)
|
||||
{
|
||||
// Store the (flow,corohandle)-tuple internally and create its coroutine:
|
||||
m_Flows.create(flow);
|
||||
@ -228,7 +228,7 @@ void SimulatorController::addFlow(fi::ExperimentFlow* flow)
|
||||
m_Flows.toggle(flow);
|
||||
}
|
||||
|
||||
void SimulatorController::removeFlow(fi::ExperimentFlow* flow)
|
||||
void SimulatorController::removeFlow(ExperimentFlow* flow)
|
||||
{
|
||||
// remove all remaining events of this flow
|
||||
clearEvents(flow);
|
||||
@ -236,7 +236,7 @@ void SimulatorController::removeFlow(fi::ExperimentFlow* flow)
|
||||
m_Flows.remove(flow);
|
||||
}
|
||||
|
||||
fi::BaseEvent* SimulatorController::addEventAndWait(fi::BaseEvent* ev)
|
||||
BaseEvent* SimulatorController::addEventAndWait(BaseEvent* ev)
|
||||
{
|
||||
addEvent(ev);
|
||||
return (waitAny());
|
||||
@ -247,7 +247,7 @@ T* SimulatorController::getExperimentData()
|
||||
{
|
||||
//BEGIN ONLY FOR TESTING------REMOVE--------REMOVE---------REMOVE--------REMOVE-------REMOVE-------
|
||||
//Daten in Struktur schreiben und in Datei speichern
|
||||
ofstream fileWrite;
|
||||
std::ofstream fileWrite;
|
||||
fileWrite.open("test.txt");
|
||||
|
||||
T* faultCovExWrite = new T();;
|
||||
@ -261,7 +261,7 @@ T* SimulatorController::getExperimentData()
|
||||
faultCovExWrite->set_m_instrptr2(0x1122);
|
||||
|
||||
//In ExperimentData verpacken
|
||||
fi::ExperimentData exDaWrite(faultCovExWrite);
|
||||
ExperimentData exDaWrite(faultCovExWrite);
|
||||
//Serialisierung ueber Wrapper-Methode in ExperimentData
|
||||
exDaWrite.serialize(&fileWrite);
|
||||
|
||||
@ -269,13 +269,13 @@ T* SimulatorController::getExperimentData()
|
||||
|
||||
fileWrite.close();
|
||||
|
||||
ifstream fileRead;
|
||||
std::ifstream fileRead;
|
||||
fileRead.open("test.txt");
|
||||
//END ONLY FOR TESTING------REMOVE--------REMOVE---------REMOVE--------REMOVE-------REMOVE-------
|
||||
//TODO: implement server-client communication----------------------------------------------
|
||||
|
||||
T* concreteExpDat = new T();
|
||||
fi::ExperimentData exDaRead(concreteExpDat);
|
||||
ExperimentData exDaRead(concreteExpDat);
|
||||
exDaRead.unserialize(&fileRead);
|
||||
|
||||
return (concreteExpDat);
|
||||
@ -285,8 +285,8 @@ void SimulatorController::terminate(int exCode)
|
||||
{
|
||||
// Attention: This could cause problems, e.g., because of non-closed sockets
|
||||
std::cout << "[FAIL] Exit called by experiment with exit code: " << exCode << std::endl;
|
||||
// TODO: (Non-)Verbose-Mode?
|
||||
// TODO: (Non-)Verbose-Mode? Log-Level?
|
||||
exit(exCode);
|
||||
}
|
||||
|
||||
} // end-of-namespace: sal
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -1,8 +1,5 @@
|
||||
#ifndef __SIMULATOR_CONTROLLER_HPP__
|
||||
#define __SIMULATOR_CONTROLLER_HPP__
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 23.01.2012
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
@ -19,17 +16,10 @@
|
||||
#include "../controller/ExperimentData.hpp"
|
||||
#include "SALConfig.hpp"
|
||||
|
||||
using namespace std;
|
||||
namespace fail {
|
||||
|
||||
namespace fi {
|
||||
// Incomplete types suffice here:
|
||||
class ExperimentFlow;
|
||||
}
|
||||
|
||||
/// Simulator Abstraction Layer namespace
|
||||
namespace sal
|
||||
{
|
||||
|
||||
// incomplete types suffice here
|
||||
class RegisterManager;
|
||||
class MemoryManager;
|
||||
|
||||
@ -37,7 +27,8 @@ class MemoryManager;
|
||||
* \class SimulatorController
|
||||
*
|
||||
* \brief The abstract interface for controlling simulators and
|
||||
* accessing experiment data/flows.
|
||||
* accessing experiment data/flows (as part of the "Simulator
|
||||
* Abstraction Layer".
|
||||
*
|
||||
* This class manages (1..N) experiments and provides access to the underlying
|
||||
* simulator/debugger system. Experiments can enlist arbritrary events
|
||||
@ -48,13 +39,13 @@ class MemoryManager;
|
||||
class SimulatorController
|
||||
{
|
||||
protected:
|
||||
fi::EventList m_EvList; //!< storage where events are being buffered
|
||||
fi::CoroutineManager m_Flows; //!< managed experiment flows
|
||||
EventList m_EvList; //!< storage where events are being buffered
|
||||
CoroutineManager m_Flows; //!< managed experiment flows
|
||||
RegisterManager *m_Regs; //!< access to cpu register
|
||||
MemoryManager *m_Mem; //!< access to memory pool
|
||||
//! list of suppressed interrupts
|
||||
std::vector<unsigned> m_SuppressedInterrupts;
|
||||
friend class fi::EventList; //!< "outsources" the event management
|
||||
friend class EventList; //!< "outsources" the event management
|
||||
public:
|
||||
SimulatorController()
|
||||
: m_Regs(NULL), m_Mem(NULL) { }
|
||||
@ -130,7 +121,7 @@ class SimulatorController
|
||||
* the addition of the event \a pev, yielding an error in the
|
||||
* experiment flow (i.e. -1 is returned).
|
||||
*/
|
||||
virtual bool onEventAddition(fi::BaseEvent* pev) { return true; }
|
||||
virtual bool onEventAddition(BaseEvent* pev) { return true; }
|
||||
/**
|
||||
* This method is called when an experiment flow removes an event from
|
||||
* the event-management by calling \c removeEvent(prev), \c clearEvents()
|
||||
@ -138,7 +129,7 @@ class SimulatorController
|
||||
* event handler will be called *before* the event is actually deleted.
|
||||
* @param pev the event to be deleted when returning from the event handler
|
||||
*/
|
||||
virtual void onEventDeletion(fi::BaseEvent* pev) { }
|
||||
virtual void onEventDeletion(BaseEvent* pev) { }
|
||||
/**
|
||||
* This method is called when an previously added event is about to be
|
||||
* triggered by the simulator-backend. More specifically, this event handler
|
||||
@ -146,7 +137,7 @@ class SimulatorController
|
||||
* corresponding coroutine is toggled.
|
||||
* @param pev the event to be triggered when returning from the event handler
|
||||
*/
|
||||
virtual void onEventTrigger(fi::BaseEvent* pev) { }
|
||||
virtual void onEventTrigger(BaseEvent* pev) { }
|
||||
/* ********************************************************************
|
||||
* Simulator Controller & Access API:
|
||||
* ********************************************************************/
|
||||
@ -154,13 +145,13 @@ class SimulatorController
|
||||
* Save simulator state.
|
||||
* @param path Location to store state information
|
||||
*/
|
||||
virtual void save(const string& path) = 0;
|
||||
virtual void save(const std::string& path) = 0;
|
||||
/**
|
||||
* Restore simulator state. Implicitly discards all previously
|
||||
* registered events.
|
||||
* @param path Location to previously saved state information
|
||||
*/
|
||||
virtual void restore(const string& path) = 0;
|
||||
virtual void restore(const std::string& path) = 0;
|
||||
/**
|
||||
* Reboot simulator.
|
||||
*/
|
||||
@ -221,13 +212,13 @@ class SimulatorController
|
||||
* run it in.
|
||||
* @param flow the experiment flow object to be added
|
||||
*/
|
||||
void addFlow(fi::ExperimentFlow* flow);
|
||||
void addFlow(ExperimentFlow* flow);
|
||||
/**
|
||||
* Removes the specified experiment or plugin and destroys its coroutine
|
||||
* and all associated events.
|
||||
* @param flow the experiment flow object to be removed
|
||||
*/
|
||||
void removeFlow(fi::ExperimentFlow* flow);
|
||||
void removeFlow(ExperimentFlow* flow);
|
||||
/**
|
||||
* Add event ev to the event management. This causes the event to be
|
||||
* active.
|
||||
@ -235,19 +226,19 @@ class SimulatorController
|
||||
* @return the id of the event used to identify the object on occurrence;
|
||||
* -1 is returned on errors
|
||||
*/
|
||||
fi::EventId addEvent(fi::BaseEvent* ev);
|
||||
EventId addEvent(BaseEvent* ev);
|
||||
/**
|
||||
* Removes the event with the specified id.
|
||||
* @param ev the pointer of the event-object to be removed; if \a ev is
|
||||
* equal to \c NULL all events (for all experiments) will be
|
||||
* removed
|
||||
*/
|
||||
void removeEvent(fi::BaseEvent* ev) { m_EvList.remove(ev); }
|
||||
void removeEvent(BaseEvent* ev) { m_EvList.remove(ev); }
|
||||
/**
|
||||
* Removes all previously added events for all experiments. To
|
||||
* restrict this to a specific experiment flow, pass a pointer to it.
|
||||
*/
|
||||
void clearEvents(fi::ExperimentFlow *flow = 0) { m_EvList.remove(flow); }
|
||||
void clearEvents(ExperimentFlow *flow = 0) { m_EvList.remove(flow); }
|
||||
/**
|
||||
* Waits on any events which have been added to the event management. If
|
||||
* one of those events occour, waitAny() will return the id of that event.
|
||||
@ -256,7 +247,7 @@ class SimulatorController
|
||||
* FIXME: Maybe this should return immediately if there are not events?
|
||||
* (additional parameter flag?)
|
||||
*/
|
||||
fi::BaseEvent* waitAny();
|
||||
BaseEvent* waitAny();
|
||||
/**
|
||||
* Add event \a ev to the global buffer and wait for it (combines
|
||||
* \c addEvent() and \c waitAny()).
|
||||
@ -266,7 +257,7 @@ class SimulatorController
|
||||
*
|
||||
* FIXME: Rename to make clear this returns when *any* event occurs
|
||||
*/
|
||||
fi::BaseEvent* addEventAndWait(fi::BaseEvent* ev);
|
||||
BaseEvent* addEventAndWait(BaseEvent* ev);
|
||||
/**
|
||||
* Checks whether any experiment flow has events in the event-list.
|
||||
* @return \c true if there are still events, or \c false otherwise
|
||||
@ -285,6 +276,6 @@ class SimulatorController
|
||||
template <class T> T* getExperimentData();
|
||||
};
|
||||
|
||||
} // end-of-namespace: sal
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __SIMULATOR_CONTROLLER_HPP__ */
|
||||
#endif // __SIMULATOR_CONTROLLER_HPP__
|
||||
|
||||
@ -7,8 +7,7 @@
|
||||
// Type definitions and configuration settings for
|
||||
// the Bochs simulator.
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
typedef bx_address guest_address_t; //!< the guest memory address type
|
||||
typedef Bit8u* host_address_t; //!< the host memory address type
|
||||
@ -19,7 +18,6 @@ typedef Bit8u* host_address_t; //!< the host memory address type
|
||||
#endif
|
||||
typedef int timer_t; //!< type of timer IDs
|
||||
|
||||
};
|
||||
|
||||
#endif /* __BOCHS_CONFIG_HPP__ */
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif // __BOCHS_CONFIG_HPP__
|
||||
|
||||
@ -6,13 +6,12 @@
|
||||
#include "../Register.hpp"
|
||||
#include "../SALInst.hpp"
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
#ifdef DANCEOS_RESTORE
|
||||
bx_bool restore_bochs_request = false;
|
||||
bx_bool save_bochs_request = false;
|
||||
string sr_path = "";
|
||||
std::string sr_path = "";
|
||||
#endif
|
||||
|
||||
bx_bool reboot_bochs_request = false;
|
||||
@ -26,9 +25,9 @@ BochsController::BochsController()
|
||||
// Add the general purpose register:
|
||||
#if BX_SUPPORT_X86_64
|
||||
// -- 64 bit register --
|
||||
const string names[] = { "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI",
|
||||
"RDI", "R8", "R9", "R10", "R11", "R12", "R13",
|
||||
"R14", "R15" };
|
||||
const std::string names[] = { "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI",
|
||||
"RDI", "R8", "R9", "R10", "R11", "R12", "R13",
|
||||
"R14", "R15" };
|
||||
for(unsigned short i = 0; i < 16; i++)
|
||||
{
|
||||
BxGPReg* pReg = new BxGPReg(i, 64, &(BX_CPU(0)->gen_reg[i].rrx));
|
||||
@ -37,8 +36,8 @@ BochsController::BochsController()
|
||||
}
|
||||
#else
|
||||
// -- 32 bit register --
|
||||
const string names[] = { "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI",
|
||||
"EDI" };
|
||||
const std::string names[] = { "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI",
|
||||
"EDI" };
|
||||
for(unsigned short i = 0; i < 8; i++)
|
||||
{
|
||||
BxGPReg* pReg = new BxGPReg(i, 32, &(BX_CPU(0)->gen_reg[i].dword.erx));
|
||||
@ -101,11 +100,11 @@ void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_sp
|
||||
(*m_pDest) << "0x" << std::hex << instrPtr;
|
||||
#endif
|
||||
// Check for active breakpoint-events:
|
||||
fi::EventList::iterator it = m_EvList.begin();
|
||||
EventList::iterator it = m_EvList.begin();
|
||||
while(it != m_EvList.end())
|
||||
{
|
||||
// FIXME: Maybe we need to improve the performance of this check.
|
||||
fi::BPEvent* pEvBreakpt = dynamic_cast<fi::BPEvent*>(*it);
|
||||
BPEvent* pEvBreakpt = dynamic_cast<BPEvent*>(*it);
|
||||
if(pEvBreakpt && pEvBreakpt->isMatching(instrPtr, address_space))
|
||||
{
|
||||
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
|
||||
@ -121,18 +120,18 @@ void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_sp
|
||||
//this code is highly optimised for the average case, so it me appear a bit ugly
|
||||
bool do_fire = false;
|
||||
unsigned i = 0;
|
||||
fi::BufferCache<fi::BPEvent*> *buffer_cache = m_EvList.getBPBuffer();
|
||||
while(i < buffer_cache->get_count()) {
|
||||
fi::BPEvent *pEvBreakpt = buffer_cache->get(i);
|
||||
BufferCache<BPEvent*> *buffer_cache = m_EvList.getBPBuffer();
|
||||
while(i < buffer_cache->getCount()) {
|
||||
BPEvent *pEvBreakpt = buffer_cache->get(i);
|
||||
if(pEvBreakpt->isMatching(instrPtr, address_space)) {
|
||||
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
|
||||
|
||||
//transition to STL: find the element we are working on in the Event List
|
||||
fi::EventList::iterator it = std::find(m_EvList.begin(), m_EvList.end(), pEvBreakpt);
|
||||
EventList::iterator it = std::find(m_EvList.begin(), m_EvList.end(), pEvBreakpt);
|
||||
it = m_EvList.makeActive(it);
|
||||
//find out how much elements need to be skipped to get in sync again
|
||||
//(should be one or none, the loop is just to make sure)
|
||||
for(unsigned j = i; j < buffer_cache->get_count(); j++) {
|
||||
for(unsigned j = i; j < buffer_cache->getCount(); j++) {
|
||||
if(buffer_cache->get(j) == (*it)) {
|
||||
i = j;
|
||||
break;
|
||||
@ -154,11 +153,11 @@ void BochsController::onInstrPtrChanged(address_t instrPtr, address_t address_sp
|
||||
|
||||
void BochsController::onIOPortEvent(unsigned char data, unsigned port, bool out) {
|
||||
// Check for active breakpoint-events:
|
||||
fi::EventList::iterator it = m_EvList.begin();
|
||||
EventList::iterator it = m_EvList.begin();
|
||||
while(it != m_EvList.end())
|
||||
{
|
||||
// FIXME: Maybe we need to improve the performance of this check.
|
||||
fi::IOPortEvent* pIOPt = dynamic_cast<fi::IOPortEvent*>(*it);
|
||||
IOPortEvent* pIOPt = dynamic_cast<IOPortEvent*>(*it);
|
||||
if(pIOPt && pIOPt->isMatching(port, out))
|
||||
{
|
||||
pIOPt->setData(data);
|
||||
@ -174,14 +173,14 @@ void BochsController::onIOPortEvent(unsigned char data, unsigned port, bool out)
|
||||
// implementation.
|
||||
}
|
||||
|
||||
void BochsController::save(const string& path)
|
||||
void BochsController::save(const std::string& path)
|
||||
{
|
||||
int stat;
|
||||
|
||||
stat = mkdir(path.c_str(), 0777);
|
||||
if(!(stat == 0 || errno == EEXIST))
|
||||
std::cout << "[FAIL] Can not create target-directory to save!" << std::endl;
|
||||
// TODO: (Non-)Verbose-Mode? Maybe better: use return value to indicate failure?
|
||||
// TODO: (Non-)Verbose-Mode? Log-level? Maybe better: use return value to indicate failure?
|
||||
|
||||
save_bochs_request = true;
|
||||
sr_path = path;
|
||||
@ -195,7 +194,7 @@ void BochsController::saveDone()
|
||||
m_Flows.toggle(m_CurrFlow);
|
||||
}
|
||||
|
||||
void BochsController::restore(const string& path)
|
||||
void BochsController::restore(const std::string& path)
|
||||
{
|
||||
clearEvents();
|
||||
restore_bochs_request = true;
|
||||
@ -242,10 +241,10 @@ void BochsController::m_onTimerTrigger(void* thisPtr)
|
||||
{
|
||||
// FIXME: The timer logic can be modified to use only one timer in Bochs.
|
||||
// (For now, this suffices.)
|
||||
fi::TimerEvent* pTmEv = static_cast<fi::TimerEvent*>(thisPtr);
|
||||
TimerEvent* pTmEv = static_cast<TimerEvent*>(thisPtr);
|
||||
// Check for a matching TimerEvent. (In fact, we are only
|
||||
// interessted in the iterator pointing at pTmEv.):
|
||||
fi::EventList::iterator it = std::find(simulator.m_EvList.begin(),
|
||||
EventList::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,
|
||||
@ -254,7 +253,7 @@ void BochsController::m_onTimerTrigger(void* thisPtr)
|
||||
simulator.m_EvList.fireActiveEvents();
|
||||
}
|
||||
|
||||
timer_id_t BochsController::m_registerTimer(fi::TimerEvent* pev)
|
||||
timer_id_t BochsController::m_registerTimer(TimerEvent* pev)
|
||||
{
|
||||
assert(pev != NULL);
|
||||
return static_cast<timer_id_t>(
|
||||
@ -262,18 +261,18 @@ timer_id_t BochsController::m_registerTimer(fi::TimerEvent* pev)
|
||||
1/*start immediately*/, "Fail*: BochsController"/*name*/));
|
||||
}
|
||||
|
||||
bool BochsController::m_unregisterTimer(fi::TimerEvent* pev)
|
||||
bool BochsController::m_unregisterTimer(TimerEvent* pev)
|
||||
{
|
||||
assert(pev != NULL);
|
||||
bx_pc_system.deactivate_timer(static_cast<unsigned>(pev->getId()));
|
||||
return bx_pc_system.unregisterTimer(static_cast<unsigned>(pev->getId()));
|
||||
}
|
||||
|
||||
bool BochsController::onEventAddition(fi::BaseEvent* pev)
|
||||
bool BochsController::onEventAddition(BaseEvent* pev)
|
||||
{
|
||||
fi::TimerEvent* tmev;
|
||||
TimerEvent* tmev;
|
||||
// Register the timer event in the Bochs simulator:
|
||||
if ((tmev = dynamic_cast<fi::TimerEvent*>(pev)) != NULL) {
|
||||
if ((tmev = dynamic_cast<TimerEvent*>(pev)) != NULL) {
|
||||
tmev->setId(m_registerTimer(tmev));
|
||||
if(tmev->getId() == -1)
|
||||
return false; // unable to register the timer (error in Bochs' function call)
|
||||
@ -282,21 +281,21 @@ bool BochsController::onEventAddition(fi::BaseEvent* pev)
|
||||
return true;
|
||||
}
|
||||
|
||||
void BochsController::onEventDeletion(fi::BaseEvent* pev)
|
||||
void BochsController::onEventDeletion(BaseEvent* pev)
|
||||
{
|
||||
fi::TimerEvent* tmev;
|
||||
TimerEvent* tmev;
|
||||
// Unregister the time event:
|
||||
if ((tmev = dynamic_cast<fi::TimerEvent*>(pev)) != NULL) {
|
||||
if ((tmev = dynamic_cast<TimerEvent*>(pev)) != NULL) {
|
||||
m_unregisterTimer(tmev);
|
||||
}
|
||||
// Note: Maybe more stuff to do here for other event types.
|
||||
}
|
||||
|
||||
void BochsController::onEventTrigger(fi::BaseEvent* pev)
|
||||
void BochsController::onEventTrigger(BaseEvent* pev)
|
||||
{
|
||||
fi::TimerEvent* tmev;
|
||||
TimerEvent* tmev;
|
||||
// Unregister the time event, if once-flag is true:
|
||||
if ((tmev = dynamic_cast<fi::TimerEvent*>(pev)) != NULL) {
|
||||
if ((tmev = dynamic_cast<TimerEvent*>(pev)) != NULL) {
|
||||
if (tmev->getOnceFlag()) // deregister the timer (timer = single timeout)
|
||||
m_unregisterTimer(tmev);
|
||||
else // re-add the event (repetitive timer), tunneling the onEventAddition-handler
|
||||
@ -305,4 +304,4 @@ void BochsController::onEventTrigger(fi::BaseEvent* pev)
|
||||
// Note: Maybe more stuff to do here for other event types.
|
||||
}
|
||||
|
||||
} // end-of-namespace: sal
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -20,13 +20,9 @@
|
||||
#include "../../../bochs/iodev/iodev.h"
|
||||
#include "../../../bochs/pc_system.h"
|
||||
|
||||
using namespace std;
|
||||
namespace fail {
|
||||
|
||||
namespace fi { class ExperimentFlow; }
|
||||
|
||||
/// Simulator Abstraction Layer namespace
|
||||
namespace sal
|
||||
{
|
||||
class ExperimentFlow;
|
||||
|
||||
/**
|
||||
* \class BochsController
|
||||
@ -35,7 +31,7 @@ namespace sal
|
||||
class BochsController : public SimulatorController
|
||||
{
|
||||
private:
|
||||
fi::ExperimentFlow* m_CurrFlow; //!< Stores the current flow for save/restore-operations
|
||||
ExperimentFlow* m_CurrFlow; //!< Stores the current flow for save/restore-operations
|
||||
#ifdef DEBUG
|
||||
unsigned m_Regularity;
|
||||
unsigned m_Counter;
|
||||
@ -67,14 +63,14 @@ class BochsController : public SimulatorController
|
||||
* along with the TimerEvent, @see getId(). On error, -1 is returned
|
||||
* (e.g. because a timer with the same id is already existing)
|
||||
*/
|
||||
timer_id_t m_registerTimer(fi::TimerEvent* pev);
|
||||
timer_id_t m_registerTimer(TimerEvent* pev);
|
||||
/**
|
||||
* 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
|
||||
* successfully, \c false otherwise
|
||||
*/
|
||||
bool m_unregisterTimer(fi::TimerEvent* pev);
|
||||
bool m_unregisterTimer(TimerEvent* pev);
|
||||
public:
|
||||
// Initialize the controller.
|
||||
BochsController();
|
||||
@ -106,7 +102,7 @@ class BochsController : public SimulatorController
|
||||
* @return You should return \c true to continue and \c false to prevent
|
||||
* the addition of the event \a pev.
|
||||
*/
|
||||
bool onEventAddition(fi::BaseEvent* pev);
|
||||
bool onEventAddition(BaseEvent* pev);
|
||||
/**
|
||||
* This method is called when an experiment flow removes an event from
|
||||
* the event-management by calling \c removeEvent(prev), \c clearEvents()
|
||||
@ -114,7 +110,7 @@ class BochsController : public SimulatorController
|
||||
* this event handler will be called *before* the event is actually deleted.
|
||||
* @param pev the event to be deleted when returning from the event handler
|
||||
*/
|
||||
void onEventDeletion(fi::BaseEvent* pev);
|
||||
void onEventDeletion(BaseEvent* pev);
|
||||
/**
|
||||
* This method is called when an previously added event is about to be
|
||||
* triggered by the simulator-backend. More specifically, this event handler
|
||||
@ -122,7 +118,7 @@ class BochsController : public SimulatorController
|
||||
* corresponding coroutine is toggled.
|
||||
* @param pev the event to be triggered when returning from the event handler
|
||||
*/
|
||||
void onEventTrigger(fi::BaseEvent* pev);
|
||||
void onEventTrigger(BaseEvent* pev);
|
||||
/* ********************************************************************
|
||||
* Simulator Controller & Access API:
|
||||
* ********************************************************************/
|
||||
@ -130,7 +126,7 @@ class BochsController : public SimulatorController
|
||||
* Save simulator state.
|
||||
* @param path Location to store state information
|
||||
*/
|
||||
void save(const string& path);
|
||||
void save(const std::string& path);
|
||||
/**
|
||||
* Save finished: Callback from Simulator
|
||||
*/
|
||||
@ -139,7 +135,7 @@ class BochsController : public SimulatorController
|
||||
* Restore simulator state. Clears all Events.
|
||||
* @param path Location to previously saved state information
|
||||
*/
|
||||
void restore(const string& path);
|
||||
void restore(const std::string& path);
|
||||
/**
|
||||
* Restore finished: Callback from Simulator
|
||||
*/
|
||||
@ -168,7 +164,7 @@ class BochsController : public SimulatorController
|
||||
* instruction pointer, 0 to disable
|
||||
* @param dest specifies the output destition; defaults to \c std::cout
|
||||
*/
|
||||
void dbgEnableInstrPtrOutput(unsigned regularity, std::ostream* dest = &cout);
|
||||
void dbgEnableInstrPtrOutput(unsigned regularity, std::ostream* dest = &std::cout);
|
||||
#endif
|
||||
/* ********************************************************************
|
||||
* BochsController-specific (not implemented in SimulatorController!):
|
||||
@ -196,6 +192,6 @@ class BochsController : public SimulatorController
|
||||
}
|
||||
};
|
||||
|
||||
} // end-of-namespace: sal
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __BOCHS_CONTROLLER_HPP__ */
|
||||
#endif // __BOCHS_CONTROLLER_HPP__
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
|
||||
#include "../Memory.hpp"
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class BochsMemoryManager
|
||||
@ -115,6 +114,6 @@ class BochsMemoryManager : public MemoryManager
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif
|
||||
#endif // __BOCHS_MEMORY_HPP__
|
||||
|
||||
@ -2,13 +2,12 @@
|
||||
#define __BOCHS_REGISTER_HPP__
|
||||
|
||||
#include "../Register.hpp"
|
||||
|
||||
#include "../../../bochs/bochs.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
namespace sal {
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class BochsRegister
|
||||
@ -241,6 +240,6 @@ class BochsRegisterManager : public RegisterManager
|
||||
}
|
||||
};
|
||||
|
||||
} // end-of-namespace: sal
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __BOCHS_REGISTER_HPP__ */
|
||||
#endif // __BOCHS_REGISTER_HPP__
|
||||
|
||||
@ -25,11 +25,11 @@ aspect Breakpoints
|
||||
//bxInstruction_c* pInstr = *(tjp->arg<1>());
|
||||
|
||||
// report this event to the Bochs controller:
|
||||
sal::simulator.onInstrPtrChanged(pThis->get_instruction_pointer(), pThis->cr3);
|
||||
fail::simulator.onInstrPtrChanged(pThis->get_instruction_pointer(), pThis->cr3);
|
||||
// Note: get_bx_opcode_name(pInstr->getIaOpcode()) retrieves the mnemonics.
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // CONFIG_EVENT_BREAKPOINTS
|
||||
|
||||
#endif
|
||||
#endif // __BREAKPOINTS_AH__
|
||||
|
||||
@ -13,10 +13,10 @@
|
||||
|
||||
// Fixed "port number" for "Guest system >> Bochs" communication
|
||||
#define BOCHS_COM_PORT 0x378
|
||||
// FIXME: This #define should be located in a config or passed within the event object...
|
||||
|
||||
aspect GuestSysCom
|
||||
{
|
||||
|
||||
pointcut outInstructions() = "% ...::bx_cpu_c::OUT_DX%(...)";
|
||||
|
||||
advice execution (outInstructions()) : after ()
|
||||
@ -27,11 +27,11 @@ aspect GuestSysCom
|
||||
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) {
|
||||
sal::simulator.onGuestSystemEvent((char)rAL, rDX);
|
||||
fail::simulator.onGuestSystemEvent((char)rAL, rDX);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CONFIG_EVENT_GUESTSYS
|
||||
|
||||
#endif /* __GUESTSYS_COM_AH__ */
|
||||
#endif // __GUESTSYS_COM_AH__
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef __IOPORT_COM_AH__
|
||||
#define __IOPORT_COM_AH__
|
||||
#define __IOPORT_COM_AH__
|
||||
|
||||
#include "config/FailConfig.hpp"
|
||||
|
||||
@ -20,7 +20,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
|
||||
sal::simulator.onIOPortEvent(rAL, rDX, true);
|
||||
fail::simulator.onIOPortEvent(rAL, rDX, true);
|
||||
}
|
||||
|
||||
pointcut inInstruction() = "% ...::bx_cpu_c::IN_ALDX(...)";
|
||||
@ -29,10 +29,10 @@ 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
|
||||
sal::simulator.onIOPortEvent(rAL, rDX, false);
|
||||
fail::simulator.onIOPortEvent(rAL, rDX, false);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CONFIG_EVENT_IOPORT
|
||||
|
||||
#endif /* __IOPORT_COM_AH__ */
|
||||
#endif // __IOPORT_COM_AH__
|
||||
|
||||
@ -29,12 +29,12 @@ aspect Interrupt
|
||||
unsigned vector = *(tjp->arg<0>());
|
||||
unsigned type = *(tjp->arg<1>());
|
||||
if(type == BX_EXTERNAL_INTERRUPT)
|
||||
sal::simulator.onInterruptEvent(vector, false);
|
||||
fail::simulator.onInterruptEvent(vector, false);
|
||||
else if(type == BX_NMI)
|
||||
sal::simulator.onInterruptEvent(vector, true);
|
||||
fail::simulator.onInterruptEvent(vector, true);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // CONFIG_EVENT_INTERRUPT
|
||||
|
||||
#endif /* __INTERRUPT_AH__ */
|
||||
#endif // __INTERRUPT_AH__
|
||||
|
||||
@ -16,7 +16,7 @@ aspect Interrupt_FI
|
||||
advice execution (interrupt_method()) : around ()
|
||||
{
|
||||
unsigned vector = *(tjp->arg<0>());
|
||||
if(!sal::simulator.isSuppressedInterrupt(vector)){
|
||||
if(!fail::simulator.isSuppressedInterrupt(vector)){
|
||||
tjp->proceed();
|
||||
}
|
||||
}
|
||||
@ -24,4 +24,4 @@ aspect Interrupt_FI
|
||||
|
||||
#endif // CONFIG_SUPPRESS_INTERRUPTS
|
||||
|
||||
#endif /* __INTERRUPT_SUPPRESSION_AH__ */
|
||||
#endif // __INTERRUPT_SUPPRESSION_AH__
|
||||
|
||||
@ -9,10 +9,11 @@
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <ctime>
|
||||
|
||||
#include "../../../bochs/bochs.h"
|
||||
#include "../SALInst.hpp"
|
||||
|
||||
using namespace std;
|
||||
// FIXME: This seems (partial) deprecated as well...
|
||||
|
||||
aspect Jump
|
||||
{
|
||||
@ -59,7 +60,7 @@ aspect Jump
|
||||
advice execution (defJumpInstructions()) : around()
|
||||
{
|
||||
bxInstruction_c* pInstr = *(tjp->arg<0>()); // bxInstruction_c-object
|
||||
sal::simulator.onJumpEvent(true, pInstr->getIaOpcode());
|
||||
fail::simulator.onJumpEvent(true, pInstr->getIaOpcode());
|
||||
/*
|
||||
JoinPoint::That* pThis = tjp->that();
|
||||
if(pThis == NULL)
|
||||
@ -108,7 +109,7 @@ aspect Jump
|
||||
advice execution (regJumpInstructions()) : around ()
|
||||
{
|
||||
bxInstruction_c* pInstr = *(tjp->arg<0>()); // bxInstruction_c-object
|
||||
sal::simulator.onJumpEvent(false, pInstr->getIaOpcode());
|
||||
fail::simulator.onJumpEvent(false, pInstr->getIaOpcode());
|
||||
/*
|
||||
JoinPoint::That* pThis = tjp->that();
|
||||
|
||||
@ -135,5 +136,5 @@ aspect Jump
|
||||
|
||||
#endif // CONFIG_EVENT_JUMP
|
||||
|
||||
#endif /* __JUMP_AH__ */
|
||||
#endif // __JUMP_AH__
|
||||
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
|
||||
#include "config/FailConfig.hpp"
|
||||
|
||||
// FIXME: What's the purpose of this file/code? Deprecated?
|
||||
|
||||
#if 0
|
||||
// #if defined(CONFIG_SR_RESTORE) || defined(CONFIG_SR_REBOOT)
|
||||
|
||||
@ -18,11 +20,11 @@ aspect jumpToPreviousCtx
|
||||
advice execution (end_reset_handler()) : after ()
|
||||
{
|
||||
|
||||
if (sal::restore_bochs_request || sal::reboot_bochs_request )
|
||||
if (fail::restore_bochs_request || fail::reboot_bochs_request )
|
||||
{
|
||||
sal::restore_bochs_request = false;
|
||||
sal::reboot_bochs_request = false;
|
||||
sal::simulator.toPreviousCtx();
|
||||
fail::restore_bochs_request = false;
|
||||
fail::reboot_bochs_request = false;
|
||||
fail::simulator.toPreviousCtx();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -8,11 +8,13 @@
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include "bochs.h"
|
||||
|
||||
#include "bochs.h"
|
||||
#include "../../controller/EventList.hpp"
|
||||
#include "../../controller/Event.hpp"
|
||||
|
||||
// FIXME: This is deprecated stuff. Delete this file.
|
||||
|
||||
using namespace std;
|
||||
|
||||
// FIXME this code doesn't make any sense for the read_virtual_% functions
|
||||
|
||||
@ -18,7 +18,7 @@
|
||||
// TODO warn on uncovered memory accesses
|
||||
aspect MemEvents
|
||||
{
|
||||
sal::address_t rmw_address;
|
||||
fail::address_t rmw_address;
|
||||
|
||||
pointcut write_methods() =
|
||||
"% ...::bx_cpu_c::write_virtual_%(...)" && // -> access32/64.cc
|
||||
@ -59,27 +59,29 @@ aspect MemEvents
|
||||
//
|
||||
#ifdef CONFIG_EVENT_MEMWRITE
|
||||
advice execution (write_methods()) : after () {
|
||||
sal::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
*(tjp->arg<1>()), sizeof(*(tjp->arg<2>())), true,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
|
||||
advice execution (write_methods_RMW()) : after () {
|
||||
sal::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
rmw_address, sizeof(*(tjp->arg<0>())), true,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
|
||||
advice execution (write_methods_new_stack()) : after () {
|
||||
std::cerr << "WOOOOOT write_methods_new_stack" << std::endl;
|
||||
sal::simulator.onMemoryAccessEvent(
|
||||
// TODO: Log-level?
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
*(tjp->arg<1>()), sizeof(*(tjp->arg<3>())), true,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
|
||||
advice execution (write_methods_new_stack_64()) : after () {
|
||||
std::cerr << "WOOOOOT write_methods_new_stack_64" << std::endl;
|
||||
sal::simulator.onMemoryAccessEvent(
|
||||
// TODO: Log-level?
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
*(tjp->arg<0>()), sizeof(*(tjp->arg<2>())), true,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
@ -90,7 +92,7 @@ aspect MemEvents
|
||||
// memory (e.g., to read vectors from the interrupt vector
|
||||
// table).
|
||||
/*
|
||||
sal::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
*(tjp->arg<0>()), sizeof(*(tjp->arg<1>())), true,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
*/
|
||||
@ -105,13 +107,13 @@ aspect MemEvents
|
||||
//
|
||||
#ifdef CONFIG_EVENT_MEMREAD
|
||||
advice execution (read_methods()) : before () {
|
||||
sal::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
*(tjp->arg<1>()), sizeof(*(tjp->result())), false,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
|
||||
advice execution (read_methods_dqword()) : before () {
|
||||
sal::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
*(tjp->arg<1>()), 16, false,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
}
|
||||
@ -120,7 +122,7 @@ aspect MemEvents
|
||||
advice execution (read_methods_RMW()) : before () {
|
||||
rmw_address = *(tjp->arg<1>());
|
||||
#ifdef CONFIG_EVENT_MEMREAD
|
||||
sal::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
*(tjp->arg<1>()), sizeof(*(tjp->result())), false,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
#endif
|
||||
@ -133,7 +135,7 @@ aspect MemEvents
|
||||
// memory (e.g., to read vectors from the interrupt vector
|
||||
// table).
|
||||
/*
|
||||
sal::simulator.onMemoryAccessEvent(
|
||||
fail::simulator.onMemoryAccessEvent(
|
||||
*(tjp->arg<0>()), sizeof(*(tjp->result())), false,
|
||||
getCPU(tjp->that())->prev_rip);
|
||||
*/
|
||||
@ -143,4 +145,4 @@ aspect MemEvents
|
||||
|
||||
#endif // CONFIG_EVENT_MEMACCESS
|
||||
|
||||
#endif /* __MEM_EVENTS_AH__ */
|
||||
#endif // __MEM_EVENTS_AH__
|
||||
|
||||
@ -16,7 +16,7 @@ aspect Trap
|
||||
|
||||
advice execution (exception_method()) : before ()
|
||||
{
|
||||
sal::simulator.onTrapEvent(*(tjp->arg<0>()));
|
||||
fail::simulator.onTrapEvent(*(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?
|
||||
}
|
||||
@ -24,4 +24,4 @@ aspect Trap
|
||||
|
||||
#endif // CONFIG_EVENT_TRAP
|
||||
|
||||
#endif /* __TRAP_AH__ */
|
||||
#endif // __TRAP_AH__
|
||||
|
||||
@ -12,4 +12,4 @@ static inline BX_CPU_C *getCPU(BX_CPU_C *that)
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // __BOCHS_HELPERS_HPP__
|
||||
|
||||
@ -11,7 +11,8 @@ aspect credits {
|
||||
advice call ("% bx_center_print(...)")
|
||||
&& within ("void bx_print_header()")
|
||||
&& args(file, line, maxwidth)
|
||||
: around (FILE *file, const char *line, unsigned maxwidth) {
|
||||
: around (FILE *file, const char *line, unsigned maxwidth)
|
||||
{
|
||||
if (!first) {
|
||||
tjp->proceed();
|
||||
return;
|
||||
|
||||
@ -16,4 +16,4 @@ aspect DisableLogfn {
|
||||
advice execution (add_remove_logfn()) : around () {}
|
||||
};
|
||||
|
||||
#endif /* __DISABLE_ADD_REMOVE_LOGFN_AH__ */
|
||||
#endif // __DISABLE_ADD_REMOVE_LOGFN_AH__
|
||||
|
||||
@ -21,6 +21,6 @@ aspect DisableKeybInt {
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* CONFIG_DISABLE_KEYB_INTERRUPTS */
|
||||
#endif // CONFIG_DISABLE_KEYB_INTERRUPTS
|
||||
|
||||
#endif /* __DISABLE_KEYBOARD_INTERRUPT_AH__ */
|
||||
#endif // __DISABLE_KEYBOARD_INTERRUPT_AH__
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
#ifndef __FAILBOCHS_HPP__
|
||||
#define __FAILBOCHS_HPP__
|
||||
#define __FAILBOCHS_HPP__
|
||||
|
||||
#include <string>
|
||||
#include <string.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
namespace sal
|
||||
{
|
||||
// FIXME: Maybe rename this file to "FailBochsGlobals.hpp"?
|
||||
|
||||
namespace fail {
|
||||
|
||||
#ifdef DANCEOS_RESTORE
|
||||
extern bx_bool restore_bochs_request;
|
||||
@ -21,4 +21,4 @@ extern int interrupt_to_fire;
|
||||
|
||||
}
|
||||
|
||||
#endif /* __FAILBOCHS_HPP__ */
|
||||
#endif // __FAILBOCHS_HPP__
|
||||
|
||||
@ -16,11 +16,11 @@ aspect fireInterrupt
|
||||
|
||||
advice execution (cpuLoop()) : before ()
|
||||
{
|
||||
if (!sal::interrupt_injection_request) {
|
||||
if (!fail::interrupt_injection_request) {
|
||||
return;
|
||||
}else{
|
||||
BX_SET_INTR(sal::interrupt_to_fire);
|
||||
DEV_pic_raise_irq(sal::interrupt_to_fire);
|
||||
BX_SET_INTR(fail::interrupt_to_fire);
|
||||
DEV_pic_raise_irq(fail::interrupt_to_fire);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -32,12 +32,12 @@ aspect InterruptDone
|
||||
|
||||
advice execution (interrupt_method()) : before ()
|
||||
{
|
||||
if (!sal::interrupt_injection_request) {
|
||||
if (!fail::interrupt_injection_request) {
|
||||
return;
|
||||
}else{
|
||||
if(*(tjp->arg<0>()) == 32 + sal::interrupt_to_fire){
|
||||
DEV_pic_lower_irq(sal::interrupt_to_fire);
|
||||
sal::simulator.fireInterruptDone();
|
||||
if(*(tjp->arg<0>()) == 32 + fail::interrupt_to_fire){
|
||||
DEV_pic_lower_irq(fail::interrupt_to_fire);
|
||||
fail::simulator.fireInterruptDone();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -45,4 +45,4 @@ aspect InterruptDone
|
||||
|
||||
#endif // CONFIG_FIRE_INTERRUPTS
|
||||
|
||||
#endif /* __FIREINTERRUPT_AH__ */
|
||||
#endif // __FIREINTERRUPT_AH__
|
||||
|
||||
@ -3,11 +3,13 @@
|
||||
|
||||
#include <iostream>
|
||||
|
||||
// FIXME: This seems deprecated...?!
|
||||
|
||||
aspect fireTimer {
|
||||
|
||||
advice "bx_pc_system_c" : slice class {
|
||||
public:
|
||||
// TODO: Log-level?
|
||||
void fireTimer(Bit32u timerNum){
|
||||
if(timerNum <= numTimers){
|
||||
if(!timer[timerNum].active){
|
||||
|
||||
@ -4,8 +4,9 @@
|
||||
#include "../SALInst.hpp"
|
||||
|
||||
aspect BochsInit {
|
||||
advice call("int bxmain()") : before () {
|
||||
sal::simulator.startup();
|
||||
advice call("int bxmain()") : before ()
|
||||
{
|
||||
fail::simulator.startup();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -12,13 +12,14 @@ aspect reboot {
|
||||
pointcut cpuLoop() = "void defineCPULoopJoinPoint(...)";
|
||||
|
||||
advice execution (cpuLoop()) : after () {
|
||||
if (!sal::reboot_bochs_request) {
|
||||
if (!fail::reboot_bochs_request) {
|
||||
return;
|
||||
}
|
||||
|
||||
bx_gui_c::reset_handler();
|
||||
std::cout << "[FAIL] Reboot finished" << std::endl;
|
||||
sal::simulator.rebootDone();
|
||||
// TODO: Log-level?
|
||||
fail::simulator.rebootDone();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
#define __RESTORE_AH__
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "config/FailConfig.hpp"
|
||||
#include "../SALInst.hpp"
|
||||
|
||||
@ -14,7 +15,7 @@ aspect restore {
|
||||
|
||||
advice execution (restoreState()) : after () {
|
||||
std::cout << "[FAIL] Restore finished" << std::endl;
|
||||
sal::simulator.restoreDone();
|
||||
fail::simulator.restoreDone();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -17,13 +17,13 @@ aspect save {
|
||||
advice execution (cpuLoop()) : order ("save", "Breakpoints");
|
||||
|
||||
advice execution (cpuLoop()) : after () {
|
||||
if (!sal::save_bochs_request) {
|
||||
if (!fail::save_bochs_request) {
|
||||
return;
|
||||
}
|
||||
assert(sal::sr_path.size() > 0 && "[FAIL] tried to save state without valid path");
|
||||
SIM->save_state(sal::sr_path.c_str());
|
||||
assert(fail::sr_path.size() > 0 && "[FAIL] tried to save state without valid path");
|
||||
SIM->save_state(fail::sr_path.c_str());
|
||||
std::cout << "[FAIL] Save finished" << std::endl;
|
||||
sal::simulator.saveDone();
|
||||
fail::simulator.saveDone();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -49,6 +49,6 @@ aspect nonverbose {
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // CONFIG_STFU
|
||||
|
||||
#endif
|
||||
#endif // __NONVERBOSE_AH__
|
||||
|
||||
@ -1,10 +1,11 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "OVPController.hpp"
|
||||
#include "OVPMemory.hpp"
|
||||
#include "OVPRegister.hpp"
|
||||
#include "../../../ovp/OVPStatusRegister.hpp"
|
||||
|
||||
namespace sal {
|
||||
namespace fail {
|
||||
|
||||
OVPController::OVPController()
|
||||
: SimulatorController(new OVPRegisterManager(), new OVPMemoryManager())
|
||||
@ -78,14 +79,14 @@ void OVPController::onInstrPtrChanged(address_t instrPtr)
|
||||
// << " R0: 0x" << hex << r0 << " ST: 0x" << hex << st << endl;
|
||||
|
||||
// Check for active breakpoint-events:
|
||||
fi::EventList::iterator it = m_EvList.begin();
|
||||
EventList::iterator it = m_EvList.begin();
|
||||
while(it != m_EvList.end())
|
||||
{
|
||||
// FIXME: Performance verbessern (dazu muss entsprechend auch die Speicherung
|
||||
// in EventList(.cc|.hpp) angepasst bzw. verbessert werden).
|
||||
fi::BPSingleEvent* pEvBreakpt = dynamic_cast<fi::BPSingleEvent*>(*it);
|
||||
BPSingleEvent* pEvBreakpt = dynamic_cast<BPSingleEvent*>(*it);
|
||||
if(pEvBreakpt && (instrPtr == pEvBreakpt->getWatchInstructionPointer() ||
|
||||
pEvBreakpt->getWatchInstructionPointer() == fi::ANY_ADDR))
|
||||
pEvBreakpt->getWatchInstructionPointer() == ANY_ADDR))
|
||||
{
|
||||
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
|
||||
it = m_EvList.makeActive(it);
|
||||
@ -93,7 +94,7 @@ void OVPController::onInstrPtrChanged(address_t instrPtr)
|
||||
// makeActive()):
|
||||
continue; // -> skip iterator increment
|
||||
}
|
||||
fi::BPRangeEvent* pEvRange = dynamic_cast<fi::BPRangeEvent*>(*it);
|
||||
BPRangeEvent* pEvRange = dynamic_cast<BPRangeEvent*>(*it);
|
||||
if(pEvRange && pEvRange->isMatching(instrPtr))
|
||||
{
|
||||
pEvBreakpt->setTriggerInstructionPointer(instrPtr);
|
||||
@ -130,4 +131,4 @@ void OVPController::reboot()
|
||||
//bx_gui_c::reset_handler();//TODO: leider protected, so geht das also nicht...
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@ -4,15 +4,13 @@
|
||||
// Type definitions and configuration settings for
|
||||
// the OVP simulator.
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
typedef uint32_t guest_address_t; //!< the guest memory address type
|
||||
typedef uint8_t* host_address_t; //!< the host memory address type
|
||||
typedef uint32_t register_data_t; //!< register data type (32 bit)
|
||||
typedef int timer_t; //!< type of timer IDs
|
||||
|
||||
};
|
||||
|
||||
#endif /* __OVP_CONFIG_HPP__ */
|
||||
}
|
||||
|
||||
#endif // __OVP_CONFIG_HPP__
|
||||
|
||||
@ -8,18 +8,12 @@
|
||||
|
||||
#include "../SimulatorController.hpp"
|
||||
#include "../../controller/Event.hpp"
|
||||
|
||||
#include "../../../ovp/OVPPlatform.hpp"
|
||||
|
||||
#include "../Register.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
extern OVPPlatform ovpplatform;
|
||||
|
||||
/// Simulator Abstraction Layer namespace
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class OVPController
|
||||
@ -46,12 +40,12 @@ class OVPController : public SimulatorController
|
||||
* Save simulator state.
|
||||
* @param path Location to store state information
|
||||
*/
|
||||
virtual void save(const string& path);
|
||||
virtual void save(const std::string& path);
|
||||
/**
|
||||
* Restore simulator state.
|
||||
* @param path Location to previously saved state information
|
||||
*/
|
||||
virtual void restore(const string& path);
|
||||
virtual void restore(const std::string& path);
|
||||
/**
|
||||
* Reboot simulator.
|
||||
*/
|
||||
@ -60,10 +54,9 @@ class OVPController : public SimulatorController
|
||||
* Returns the current instruction pointer.
|
||||
* @return the current eip
|
||||
*/
|
||||
|
||||
void makeGPRegister(int, void*, const string&);
|
||||
void makeSTRegister(Register *, const string&);
|
||||
void makePCRegister(int, void*, const string&);
|
||||
void makeGPRegister(int, void*, const std::string&);
|
||||
void makeSTRegister(Register *, const std::string&);
|
||||
void makePCRegister(int, void*, const std::string&);
|
||||
|
||||
//DELETE-ME:This should be obsolete now...
|
||||
/**
|
||||
@ -71,8 +64,8 @@ class OVPController : public SimulatorController
|
||||
* must tell OVPController when it is finished
|
||||
*/
|
||||
//void finishedRegisterCreation();
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // __OVP_CONTROLLER_HPP__
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
|
||||
#include "../Memory.hpp"
|
||||
|
||||
namespace sal
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class OVPMemoryManager
|
||||
@ -90,4 +89,4 @@ class OVPMemoryManager : public MemoryManager
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // __OVP_MEMORY_HPP__
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
extern OVPPlatform ovpplatform;
|
||||
|
||||
namespace sal {
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class OVPRegister
|
||||
@ -74,7 +74,8 @@ class OVPRegisterManager : public RegisterManager
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // __OVP_REGISTER_HPP__
|
||||
|
||||
@ -4,9 +4,10 @@
|
||||
#include "../SALInst.hpp"
|
||||
|
||||
aspect OVPInit {
|
||||
advice call("% ...::startSimulation(...)") : before () {
|
||||
cout << "OVP init aspect!" << endl;
|
||||
sal::simulator.startup();
|
||||
advice call("% ...::startSimulation(...)") : before ()
|
||||
{
|
||||
std::cout << "OVP init aspect!" << std::endl;
|
||||
fail::simulator.startup();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -35,4 +35,4 @@
|
||||
// Fault injection
|
||||
#cmakedefine CONFIG_FI_MEM_ACCESS_BITFLIP
|
||||
|
||||
#endif /* __FAIL_CONFIG_HPP__ */
|
||||
#endif // __FAIL_CONFIG_HPP__
|
||||
|
||||
@ -1,11 +1,12 @@
|
||||
#include "BufferCache.hpp"
|
||||
#include "Event.hpp"
|
||||
|
||||
namespace fi {
|
||||
namespace fail {
|
||||
|
||||
template<class T> int BufferCache<T>::add(T val) {
|
||||
size_t new_size = get_count() + 1;
|
||||
size_t new_last_index = get_count();
|
||||
template<class T> int BufferCache<T>::add(T val)
|
||||
{
|
||||
size_t new_size = getCount() + 1;
|
||||
size_t new_last_index = getCount();
|
||||
|
||||
int res = reallocate_buffer(new_size);
|
||||
if (res == 0) {
|
||||
@ -15,14 +16,15 @@ template<class T> int BufferCache<T>::add(T val) {
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class T> int BufferCache<T>::remove(T val) {
|
||||
template<class T> int BufferCache<T>::remove(T val)
|
||||
{
|
||||
bool do_remove = false;
|
||||
for (size_t i = 0; i < get_count(); i++) {
|
||||
for (size_t i = 0; i < getCount(); i++) {
|
||||
if (get(i) == val) {
|
||||
do_remove = true;
|
||||
}
|
||||
if (do_remove) {
|
||||
if (i > get_count() - 1) {
|
||||
if (i > getCount() - 1) {
|
||||
set(i, get(i + 1));
|
||||
}
|
||||
}
|
||||
@ -30,31 +32,34 @@ template<class T> int BufferCache<T>::remove(T val) {
|
||||
|
||||
int res = 0;
|
||||
if (do_remove) {
|
||||
size_t new_size = get_count() - 1;
|
||||
size_t new_size = getCount() - 1;
|
||||
res = reallocate_buffer(new_size);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
template<class T> void BufferCache<T>::clear() {
|
||||
set_count(0);
|
||||
template<class T> void BufferCache<T>::clear()
|
||||
{
|
||||
setCount(0);
|
||||
free(m_Buffer);
|
||||
m_Buffer = NULL;
|
||||
}
|
||||
|
||||
template<class T> int BufferCache<T>::erase(int idx) {
|
||||
for (size_t i = idx; i < get_count() - 1; i++) {
|
||||
template<class T> int BufferCache<T>::erase(int idx)
|
||||
{
|
||||
for (size_t i = idx; i < getCount() - 1; i++) {
|
||||
set(i, get(i + 1));
|
||||
}
|
||||
|
||||
size_t new_size = get_count() - 1;
|
||||
size_t new_size = getCount() - 1;
|
||||
if (reallocate_buffer(new_size) != 0)
|
||||
return -1;
|
||||
return idx;
|
||||
}
|
||||
|
||||
template<class T> int BufferCache<T>::reallocate_buffer(size_t new_size) {
|
||||
template<class T> int BufferCache<T>::reallocate_buffer(size_t new_size)
|
||||
{
|
||||
if (new_size == 0) {
|
||||
clear();
|
||||
return 0;
|
||||
@ -63,12 +68,11 @@ template<class T> int BufferCache<T>::reallocate_buffer(size_t new_size) {
|
||||
if (new_buffer == NULL)
|
||||
return 10;
|
||||
m_Buffer = static_cast<T*>(new_buffer);
|
||||
set_count(new_size);
|
||||
setCount(new_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//declare whatever instances of the template
|
||||
//you are going to use here:
|
||||
// Declare whatever instances of the template you are going to use here:
|
||||
template class BufferCache<BPEvent*>;
|
||||
|
||||
} /* namespace fi */
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -1,9 +1,12 @@
|
||||
#ifndef __BUFFERCACHE_HPP__
|
||||
#define __BUFFERCACHE_HPP__
|
||||
#ifndef __BUFFER_CACHE_HPP__
|
||||
#define __BUFFER_CACHE_HPP__
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
namespace fi {
|
||||
// FIXME: (Maybe) This should be located in utils, because
|
||||
// it's "Fail*-independend"...?
|
||||
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class BufferCache
|
||||
@ -18,24 +21,24 @@ namespace fi {
|
||||
template<class T> class BufferCache {
|
||||
public:
|
||||
BufferCache()
|
||||
: m_Buffer(NULL), m_Buffer_count(0) {}
|
||||
: m_Buffer(NULL), m_BufferCount(0) {}
|
||||
~BufferCache() {}
|
||||
/**
|
||||
* Add an element to the array. The object pointed to remains untouched.
|
||||
* @param val the element to add
|
||||
* @returns 0 if successful, an error code otherwise (ATM only 10 if malloc() fails)
|
||||
* @return 0 if successful, an error code otherwise (ATM only 10 if malloc() fails)
|
||||
*/
|
||||
int add(T val);
|
||||
/**
|
||||
* Remove an element from the array. The object pointed to remains untouched.
|
||||
* @param val the element to remove
|
||||
* @returns 0 if successful, an error code otherwise (ATM only 10 if malloc() fails)
|
||||
* @return 0 if successful, an error code otherwise (ATM only 10 if malloc() fails)
|
||||
*/
|
||||
int remove(T val);
|
||||
/**
|
||||
* Remove an element at a specific position. The object pointed to remains untouched.
|
||||
* @param val the element to remove
|
||||
* @returns a pointer to the given element's successor if successful, -1 otherwise
|
||||
* @return a pointer to the given element's successor if successful, -1 otherwise
|
||||
*/
|
||||
int erase(int i);
|
||||
/**
|
||||
@ -45,7 +48,7 @@ public:
|
||||
/**
|
||||
* Retrieve an element from the array. Should be inlined.
|
||||
* @param idx the position to retrieve the element from
|
||||
* @returns the element at the given position
|
||||
* @return the element at the given position
|
||||
*/
|
||||
inline T get(size_t idx) { return m_Buffer[idx]; }
|
||||
/**
|
||||
@ -56,27 +59,29 @@ public:
|
||||
inline void set(size_t idx, T val) { m_Buffer[idx] = val; }
|
||||
/**
|
||||
* Retrieves the current length of the array. Should be inlined.
|
||||
* @returns the array length
|
||||
* @return the array length
|
||||
*/
|
||||
inline size_t get_count() { return m_Buffer_count; }
|
||||
inline size_t getCount() { return m_BufferCount; }
|
||||
protected:
|
||||
/**
|
||||
* Changes the current length of the array. Should be inlined.
|
||||
* @param new_count the new array length
|
||||
*/
|
||||
inline void set_count(size_t new_count) { m_Buffer_count = new_count; }
|
||||
inline void setCount(size_t new_count) { m_BufferCount = new_count; }
|
||||
/**
|
||||
* Reallocates the buffer. This implementation is extremely primitive,
|
||||
* but since the amount of entries is small,
|
||||
* this will not be significant, hopefully. Should be inlined.
|
||||
* @param new_size the new number of elements in the array
|
||||
* @returns 0 if successful, an error code otherwise (ATM only 10 if malloc() fails)
|
||||
* @return 0 if successful, an error code otherwise (ATM only 10 if malloc() fails)
|
||||
*/
|
||||
inline int reallocate_buffer(size_t new_size);
|
||||
private:
|
||||
// TODO: comments needed!
|
||||
T *m_Buffer;
|
||||
size_t m_Buffer_count;
|
||||
size_t m_BufferCount;
|
||||
};
|
||||
|
||||
} /* namespace fi */
|
||||
#endif /* BUFFERCACHE_H_ */
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif // __BUFFER_CACHE_HPP__
|
||||
|
||||
@ -4,9 +4,6 @@ set(SRCS
|
||||
CoroutineManager.cc
|
||||
Event.cc
|
||||
EventList.cc
|
||||
ExperimentDataQueue.cc
|
||||
Signal.cc
|
||||
SynchronizedExperimentDataQueue.cc
|
||||
)
|
||||
|
||||
add_library(controller ${SRCS})
|
||||
|
||||
@ -1,31 +1,25 @@
|
||||
#ifndef __CAMPAIGN_HPP__
|
||||
#define __CAMPAIGN_HPP__
|
||||
|
||||
// Author: Martin Hoffmann
|
||||
// Date: 09.12.2011
|
||||
|
||||
|
||||
namespace fi
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class Campaign
|
||||
*
|
||||
* Basic interface for user-defined campaigns. To create a new
|
||||
* campaign, derive your own class from Campaign,
|
||||
* define the run method, and add it to the CampaignManager.
|
||||
*/
|
||||
class Campaign
|
||||
{
|
||||
|
||||
public:
|
||||
Campaign() { };
|
||||
/**
|
||||
* Defines the campaign.
|
||||
* @return \c true if the campaign was successful, \c false otherwise
|
||||
*/
|
||||
virtual bool run() = 0;
|
||||
class Campaign {
|
||||
public:
|
||||
Campaign() { };
|
||||
/**
|
||||
* Defines the campaign.
|
||||
* @return \c true if the campaign was successful, \c false otherwise
|
||||
*/
|
||||
virtual bool run() = 0;
|
||||
};
|
||||
|
||||
}
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __CAMPAIGN_HPP__ */
|
||||
#endif // __CAMPAIGN_HPP__
|
||||
|
||||
@ -1,9 +1,7 @@
|
||||
#include "CampaignManager.hpp"
|
||||
|
||||
namespace fail {
|
||||
|
||||
namespace fi
|
||||
{
|
||||
|
||||
CampaignManager campaignmanager;
|
||||
|
||||
}//end-of-namespace
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -1,91 +1,77 @@
|
||||
/**
|
||||
* \brief The manager for an entire campaign
|
||||
*
|
||||
* The CampaignManager allows a user-campaign access to all constant
|
||||
* simulator information and forwards single experiments to the JobServer.
|
||||
*
|
||||
* \author Martin Hoffmann
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __CAMPAIGN_MANAGER_H__
|
||||
#define __CAMPAIGN_MANAGER_H__
|
||||
#ifndef __CAMPAIGN_MANAGER_HPP__
|
||||
#define __CAMPAIGN_MANAGER_HPP__
|
||||
|
||||
#include "SAL/SALInst.hpp"
|
||||
#include "ExperimentData.hpp"
|
||||
#include "jobserver/JobServer.hpp"
|
||||
#include "controller/Campaign.hpp"
|
||||
|
||||
namespace fi
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class CampaignManager
|
||||
* Class manageing an FI campaign.
|
||||
*
|
||||
* The CampaignManager allows a user-campaign access to all constant
|
||||
* simulator information and forwards single experiments to the JobServer.
|
||||
*/
|
||||
class CampaignManager
|
||||
{
|
||||
|
||||
JobServer m_jobserver;
|
||||
Campaign* m_currentCampaign;
|
||||
|
||||
public:
|
||||
CampaignManager(){};
|
||||
|
||||
/**
|
||||
* Executes a user campaign
|
||||
*/
|
||||
bool runCampaign(Campaign* c){
|
||||
m_currentCampaign = c;
|
||||
bool ret = c->run();
|
||||
m_jobserver.done();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a const reference for acquiring constant simulator specific information.
|
||||
* e.g., Registernames, to ease experiment data construction.
|
||||
* The campaign description is not allowed to change the simulator
|
||||
* state, as the actual simulation runs within another process (Minion)
|
||||
* @return constant reference to the current simulator backend.
|
||||
*/
|
||||
sal::SimulatorController const& getSimulator() const { return sal::simulator; };
|
||||
|
||||
/**
|
||||
* Add a experiment parameter set.
|
||||
* The user campaign has to allocate the Parameter object,
|
||||
* and deallocate it after result reception.
|
||||
* A Parameter set includes space for results.
|
||||
* @param exp A pointer to a ExperimentData set.
|
||||
*/
|
||||
void addParam(ExperimentData* exp) { m_jobserver.addParam(exp); };
|
||||
|
||||
/**
|
||||
* A user campaign can request a single result (blocking) from the queue.
|
||||
*
|
||||
* @return Pointer to a parameter object with filled result data
|
||||
* @see addParam.
|
||||
*/
|
||||
ExperimentData* getDone() { return m_jobserver.getDone(); };
|
||||
|
||||
/**
|
||||
* Signal, that there will not come any further parameter sets.
|
||||
*/
|
||||
void noMoreParameters() { m_jobserver.setNoMoreExperiments(); };
|
||||
|
||||
/**
|
||||
* Wait actively, until all experiments expired.
|
||||
*/
|
||||
// void waitForCompletion();
|
||||
|
||||
/**
|
||||
* User campaign has finished.
|
||||
*/
|
||||
void done() { m_jobserver.done(); };
|
||||
|
||||
|
||||
|
||||
class CampaignManager {
|
||||
private:
|
||||
JobServer m_jobserver;
|
||||
Campaign* m_currentCampaign;
|
||||
public:
|
||||
CampaignManager() { }
|
||||
/**
|
||||
* Executes a user campaign
|
||||
*/
|
||||
bool runCampaign(Campaign* c)
|
||||
{
|
||||
m_currentCampaign = c;
|
||||
bool ret = c->run();
|
||||
m_jobserver.done();
|
||||
return ret;
|
||||
}
|
||||
/**
|
||||
* Returns a const reference for acquiring constant simulator specific information.
|
||||
* e.g., Registernames, to ease experiment data construction.
|
||||
* The campaign description is not allowed to change the simulator
|
||||
* state, as the actual simulation runs within another process (Minion)
|
||||
* @return constant reference to the current simulator backend.
|
||||
*/
|
||||
SimulatorController const& getSimulator() const { return simulator; }
|
||||
/**
|
||||
* Add a experiment parameter set.
|
||||
* The user campaign has to allocate the Parameter object,
|
||||
* and deallocate it after result reception.
|
||||
* A Parameter set includes space for results.
|
||||
* @param exp A pointer to a ExperimentData set.
|
||||
*/
|
||||
void addParam(ExperimentData* exp) { m_jobserver.addParam(exp); }
|
||||
/**
|
||||
* A user campaign can request a single result (blocking) from the queue.
|
||||
* @return Pointer to a parameter object with filled result data
|
||||
* @see addParam()
|
||||
*/
|
||||
ExperimentData* getDone() { return m_jobserver.getDone(); }
|
||||
/**
|
||||
* Signal, that there will not come any further parameter sets.
|
||||
*/
|
||||
void noMoreParameters() { m_jobserver.setNoMoreExperiments(); }
|
||||
/**
|
||||
* Wait actively, until all experiments expired.
|
||||
*/
|
||||
// void waitForCompletion();
|
||||
/**
|
||||
* User campaign has finished.
|
||||
*/
|
||||
void done() { m_jobserver.done(); }
|
||||
};
|
||||
|
||||
extern CampaignManager campaignmanager;
|
||||
} //end-of-namespace
|
||||
#endif
|
||||
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif // __CAMPAIGN_MANAGER_HPP__
|
||||
|
||||
@ -1,29 +1,26 @@
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 05.10.2011
|
||||
|
||||
#include <iostream>
|
||||
#include <cassert>
|
||||
|
||||
#include "CoroutineManager.hpp"
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
|
||||
namespace fi
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
void CoroutineManager::m_invoke(void* pData)
|
||||
{
|
||||
//std::cerr << "CORO m_invoke " << co_current() << std::endl;
|
||||
// TODO: Log-Level?
|
||||
reinterpret_cast<ExperimentFlow*>(pData)->coroutine_entry();
|
||||
//m_togglerstack.pop(); // FIXME need to pop our caller
|
||||
//m_togglerstack.pop();
|
||||
// FIXME: need to pop our caller
|
||||
co_exit(); // deletes the associated coroutine memory as well
|
||||
|
||||
// we really shouldn't get here
|
||||
std::cerr << "CoroutineManager::m_invoke() shitstorm unloading" << std::endl;
|
||||
while (1) ;
|
||||
// We really shouldn't get here:
|
||||
assert(false && "FATAL ERROR: CoroutineManager::m_invoke() -- shitstorm unloading!");
|
||||
while (1); // freeze.
|
||||
}
|
||||
|
||||
CoroutineManager::~CoroutineManager()
|
||||
{
|
||||
}
|
||||
CoroutineManager::~CoroutineManager() { }
|
||||
|
||||
void CoroutineManager::toggle(ExperimentFlow* flow)
|
||||
{
|
||||
@ -94,4 +91,4 @@ ExperimentFlow* CoroutineManager::getCurrent()
|
||||
|
||||
const ExperimentFlow* CoroutineManager::SIM_FLOW = NULL;
|
||||
|
||||
}
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -1,17 +1,12 @@
|
||||
#ifndef __COROUTINE_MANAGER_HPP__
|
||||
#define __COROUTINE_MANAGER_HPP__
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 05.10.2011
|
||||
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
||||
#include <pcl.h> // the underlying "portable coroutine library"
|
||||
|
||||
|
||||
namespace fi
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
class ExperimentFlow;
|
||||
|
||||
@ -73,6 +68,6 @@ class CoroutineManager
|
||||
ExperimentFlow* getCurrent();
|
||||
};
|
||||
|
||||
} // end-of-namespace: fi
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __COROUTINE_MANAGER_HPP__ */
|
||||
#endif // __COROUTINE_MANAGER_HPP__
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
#include "Event.hpp"
|
||||
#include "../SAL/SALInst.hpp"
|
||||
|
||||
namespace fi
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
EventId BaseEvent::m_Counter = 0;
|
||||
|
||||
@ -42,7 +41,7 @@ bool TroubleEvent::addWatchNumber(unsigned troubleNumber)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool MemAccessEvent::isMatching(sal::address_t addr, accessType_t accesstype) const
|
||||
bool MemAccessEvent::isMatching(address_t addr, accessType_t accesstype) const
|
||||
{
|
||||
if(!(m_WatchType & accesstype))
|
||||
return (false);
|
||||
@ -52,20 +51,20 @@ bool MemAccessEvent::isMatching(sal::address_t addr, accessType_t accesstype) co
|
||||
return (true);
|
||||
}
|
||||
|
||||
bool BPEvent::aspaceIsMatching(sal::address_t aspace) const
|
||||
bool BPEvent::aspaceIsMatching(address_t aspace) const
|
||||
{
|
||||
if (m_CR3 == ANY_ADDR || m_CR3 == aspace)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void BPRangeEvent::setWatchInstructionPointerRange(sal::address_t start, sal::address_t end)
|
||||
void BPRangeEvent::setWatchInstructionPointerRange(address_t start, address_t end)
|
||||
{
|
||||
m_WatchStartAddr = start;
|
||||
m_WatchEndAddr = end;
|
||||
}
|
||||
|
||||
bool BPRangeEvent::isMatching(sal::address_t addr, sal::address_t aspace) const
|
||||
bool BPRangeEvent::isMatching(address_t addr, address_t aspace) const
|
||||
{
|
||||
if (!aspaceIsMatching(aspace))
|
||||
return false;
|
||||
@ -75,7 +74,7 @@ bool BPRangeEvent::isMatching(sal::address_t addr, sal::address_t aspace) const
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BPSingleEvent::isMatching(sal::address_t addr, sal::address_t aspace) const
|
||||
bool BPSingleEvent::isMatching(address_t addr, address_t aspace) const
|
||||
{
|
||||
if (aspaceIsMatching(aspace)) {
|
||||
if (m_WatchInstrPtr == ANY_ADDR || m_WatchInstrPtr == addr) {
|
||||
@ -85,4 +84,4 @@ bool BPSingleEvent::isMatching(sal::address_t addr, sal::address_t aspace) const
|
||||
return false;
|
||||
}
|
||||
|
||||
} // end-of-namespace: fi
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -6,19 +6,20 @@
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <utility>
|
||||
#include <iostream>
|
||||
|
||||
#include "../SAL/SALConfig.hpp"
|
||||
#include <iostream>
|
||||
namespace fi
|
||||
{
|
||||
|
||||
namespace fail {
|
||||
|
||||
class ExperimentFlow;
|
||||
|
||||
typedef unsigned long EventId; //!< type of event ids
|
||||
|
||||
//! invalid event id (used as a return indicator)
|
||||
const EventId INVALID_EVENT = (EventId)-1;
|
||||
//! address wildcard (e.g. for BPEvent)
|
||||
const sal::address_t ANY_ADDR = static_cast<sal::address_t>(-1);
|
||||
//! address wildcard (e.g. for BPEvent's)
|
||||
const address_t ANY_ADDR = static_cast<address_t>(-1);
|
||||
//! instruction wildcard
|
||||
const unsigned ANY_INSTR = static_cast<unsigned>(-1);
|
||||
//! trap wildcard
|
||||
@ -93,9 +94,6 @@ class BaseEvent
|
||||
*/
|
||||
void setParent(ExperimentFlow* pFlow) { m_Parent = pFlow; }
|
||||
};
|
||||
// FIXME: Dynamische Casts zur Laufzeit evtl. zu uneffizient?
|
||||
// (vgl. auf NULL evtl. akzeptabel?) Bessere Lösungen?
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// Specialized events:
|
||||
//
|
||||
@ -107,8 +105,8 @@ class BaseEvent
|
||||
class BPEvent : virtual public BaseEvent
|
||||
{
|
||||
private:
|
||||
sal::address_t m_CR3;
|
||||
sal::address_t m_TriggerInstrPtr;
|
||||
address_t m_CR3;
|
||||
address_t m_TriggerInstrPtr;
|
||||
public:
|
||||
/**
|
||||
* Creates a new breakpoint event. The range information is specific to
|
||||
@ -119,37 +117,37 @@ class BPEvent : virtual public BaseEvent
|
||||
* ANY_ADDR can be used as a placeholder to allow debugging
|
||||
* in a random address space.
|
||||
*/
|
||||
BPEvent(sal::address_t address_space = ANY_ADDR)
|
||||
BPEvent(address_t address_space = ANY_ADDR)
|
||||
: m_CR3(address_space), m_TriggerInstrPtr(ANY_ADDR)
|
||||
{}
|
||||
/**
|
||||
* Returns the address space register of this event.
|
||||
*/
|
||||
sal::address_t getCR3() const
|
||||
address_t getCR3() const
|
||||
{ return m_CR3; }
|
||||
/**
|
||||
* Sets the address space register for this event.
|
||||
*/
|
||||
void setCR3(sal::address_t iptr)
|
||||
void setCR3(address_t iptr)
|
||||
{ m_CR3 = iptr; }
|
||||
/**
|
||||
* Checks whether a given address space is matching.
|
||||
*/
|
||||
bool aspaceIsMatching(sal::address_t address_space = ANY_ADDR) const;
|
||||
bool aspaceIsMatching(address_t address_space = ANY_ADDR) const;
|
||||
/**
|
||||
* Checks whether a given address is matching.
|
||||
*/
|
||||
virtual bool isMatching(sal::address_t addr = 0, sal::address_t address_space = ANY_ADDR) const = 0;
|
||||
virtual bool isMatching(address_t addr = 0, address_t address_space = ANY_ADDR) const = 0;
|
||||
/**
|
||||
* Returns the instruction pointer that triggered this event.
|
||||
*/
|
||||
sal::address_t getTriggerInstructionPointer() const
|
||||
address_t getTriggerInstructionPointer() const
|
||||
{ return m_TriggerInstrPtr; }
|
||||
/**
|
||||
* Sets the instruction pointer that triggered this event. Should not
|
||||
* be used by experiment code.
|
||||
*/
|
||||
void setTriggerInstructionPointer(sal::address_t iptr)
|
||||
void setTriggerInstructionPointer(address_t iptr)
|
||||
{ m_TriggerInstrPtr = iptr; }
|
||||
};
|
||||
|
||||
@ -160,7 +158,7 @@ class BPEvent : virtual public BaseEvent
|
||||
class BPSingleEvent : virtual public BPEvent
|
||||
{
|
||||
private:
|
||||
sal::address_t m_WatchInstrPtr;
|
||||
address_t m_WatchInstrPtr;
|
||||
public:
|
||||
/**
|
||||
* Creates a new breakpoint event.
|
||||
@ -174,22 +172,22 @@ class BPSingleEvent : virtual public BPEvent
|
||||
* Here, too, ANY_ADDR is a placeholder to allow debugging
|
||||
* in a random address space.
|
||||
*/
|
||||
BPSingleEvent(sal::address_t ip = 0, sal::address_t address_space = ANY_ADDR)
|
||||
BPSingleEvent(address_t ip = 0, address_t address_space = ANY_ADDR)
|
||||
: BPEvent(address_space), m_WatchInstrPtr(ip) { }
|
||||
/**
|
||||
* Returns the instruction pointer this event waits for.
|
||||
*/
|
||||
sal::address_t getWatchInstructionPointer() const
|
||||
address_t getWatchInstructionPointer() const
|
||||
{ return m_WatchInstrPtr; }
|
||||
/**
|
||||
* Sets the instruction pointer this event waits for.
|
||||
*/
|
||||
void setWatchInstructionPointer(sal::address_t iptr)
|
||||
void setWatchInstructionPointer(address_t iptr)
|
||||
{ m_WatchInstrPtr = iptr; }
|
||||
/**
|
||||
* Checks whether a given address is matching.
|
||||
*/
|
||||
bool isMatching(sal::address_t addr, sal::address_t address_space) const;
|
||||
bool isMatching(address_t addr, address_t address_space) const;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -199,8 +197,8 @@ class BPSingleEvent : virtual public BPEvent
|
||||
class BPRangeEvent : virtual public BPEvent
|
||||
{
|
||||
private:
|
||||
sal::address_t m_WatchStartAddr;
|
||||
sal::address_t m_WatchEndAddr;
|
||||
address_t m_WatchStartAddr;
|
||||
address_t m_WatchEndAddr;
|
||||
public:
|
||||
/**
|
||||
* Creates a new breakpoint-range event. The range's ends are both
|
||||
@ -208,24 +206,24 @@ class BPRangeEvent : virtual public BPEvent
|
||||
* ANY_ADDR denotes the lower respectively the upper end of the address
|
||||
* space.
|
||||
*/
|
||||
BPRangeEvent(sal::address_t start = 0, sal::address_t end = 0, sal::address_t address_space = ANY_ADDR)
|
||||
BPRangeEvent(address_t start = 0, address_t end = 0, address_t address_space = ANY_ADDR)
|
||||
: BPEvent(address_space), m_WatchStartAddr(start), m_WatchEndAddr(end)
|
||||
{ }
|
||||
/**
|
||||
* Returns the instruction pointer watch range of this event.
|
||||
*/
|
||||
std::pair<sal::address_t, sal::address_t> getWatchInstructionPointerRange() const
|
||||
std::pair<address_t, address_t> getWatchInstructionPointerRange() const
|
||||
{ return std::make_pair(m_WatchStartAddr, m_WatchEndAddr); }
|
||||
/**
|
||||
* Sets the instruction pointer watch range. Both ends of the range
|
||||
* may be ANY_ADDR (cf. constructor).
|
||||
*/
|
||||
void setWatchInstructionPointerRange(sal::address_t start,
|
||||
sal::address_t end);
|
||||
void setWatchInstructionPointerRange(address_t start,
|
||||
address_t end);
|
||||
/**
|
||||
* Checks whether a given address is within the range.
|
||||
*/
|
||||
bool isMatching(sal::address_t addr, sal::address_t address_space) const;
|
||||
bool isMatching(address_t addr, address_t address_space) const;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -246,18 +244,18 @@ class MemAccessEvent : virtual public BaseEvent
|
||||
};
|
||||
private:
|
||||
//! Specific guest system address to watch, or ANY_ADDR.
|
||||
sal::address_t m_WatchAddr;
|
||||
address_t m_WatchAddr;
|
||||
/**
|
||||
* Memory access type we want to watch
|
||||
* (MEM_READ || MEM_WRITE || MEM_READWRITE).
|
||||
*/
|
||||
accessType_t m_WatchType;
|
||||
//! Specific guest system address that actually triggered the event.
|
||||
sal::address_t m_TriggerAddr;
|
||||
address_t m_TriggerAddr;
|
||||
//! Width of the memory access (# bytes).
|
||||
size_t m_TriggerWidth;
|
||||
//! Address of the instruction that caused the memory access.
|
||||
sal::address_t m_TriggerIP;
|
||||
address_t m_TriggerIP;
|
||||
//! Memory access type at m_TriggerAddr.
|
||||
accessType_t m_AccessType;
|
||||
public:
|
||||
@ -265,7 +263,7 @@ class MemAccessEvent : virtual public BaseEvent
|
||||
: m_WatchAddr(ANY_ADDR), m_WatchType(watchtype),
|
||||
m_TriggerAddr(ANY_ADDR), m_TriggerIP(ANY_ADDR),
|
||||
m_AccessType(MEM_UNKNOWN) { }
|
||||
MemAccessEvent(sal::address_t addr,
|
||||
MemAccessEvent(address_t addr,
|
||||
accessType_t watchtype = MEM_READWRITE)
|
||||
: m_WatchAddr(addr), m_WatchType(watchtype),
|
||||
m_TriggerAddr(ANY_ADDR), m_TriggerIP(ANY_ADDR),
|
||||
@ -273,25 +271,25 @@ class MemAccessEvent : virtual public BaseEvent
|
||||
/**
|
||||
* Returns the memory address to be observed.
|
||||
*/
|
||||
sal::address_t getWatchAddress() const { return m_WatchAddr; }
|
||||
address_t getWatchAddress() const { return m_WatchAddr; }
|
||||
/**
|
||||
* Sets the memory address to be observed. (Wildcard: ANY_ADDR)
|
||||
*/
|
||||
void setWatchAddress(sal::address_t addr) { m_WatchAddr = addr; }
|
||||
void setWatchAddress(address_t addr) { m_WatchAddr = addr; }
|
||||
/**
|
||||
* Checks whether a given address is matching.
|
||||
*/
|
||||
bool isMatching(sal::address_t addr, accessType_t accesstype) const;
|
||||
bool isMatching(address_t addr, accessType_t accesstype) const;
|
||||
/**
|
||||
* Returns the specific memory address that actually triggered the
|
||||
* event.
|
||||
*/
|
||||
sal::address_t getTriggerAddress() const { return (m_TriggerAddr); }
|
||||
address_t getTriggerAddress() const { return (m_TriggerAddr); }
|
||||
/**
|
||||
* Sets the specific memory address that actually triggered the event.
|
||||
* Should not be used by experiment code.
|
||||
*/
|
||||
void setTriggerAddress(sal::address_t addr) { m_TriggerAddr = addr; }
|
||||
void setTriggerAddress(address_t addr) { m_TriggerAddr = addr; }
|
||||
/**
|
||||
* Returns the specific memory address that actually triggered the
|
||||
* event.
|
||||
@ -306,13 +304,13 @@ class MemAccessEvent : virtual public BaseEvent
|
||||
* Returns the address of the instruction causing this memory
|
||||
* access.
|
||||
*/
|
||||
sal::address_t getTriggerInstructionPointer() const
|
||||
address_t getTriggerInstructionPointer() const
|
||||
{ return (m_TriggerIP); }
|
||||
/**
|
||||
* Sets the address of the instruction causing this memory
|
||||
* access. Should not be used by experiment code.
|
||||
*/
|
||||
void setTriggerInstructionPointer(sal::address_t addr)
|
||||
void setTriggerInstructionPointer(address_t addr)
|
||||
{ m_TriggerIP = addr; }
|
||||
/**
|
||||
* Returns type (MEM_READ || MEM_WRITE) of the memory access that
|
||||
@ -330,6 +328,7 @@ class MemAccessEvent : virtual public BaseEvent
|
||||
*/
|
||||
accessType_t getWatchAccessType() const { return (m_WatchType); }
|
||||
};
|
||||
|
||||
/**
|
||||
* \class MemReadEvent
|
||||
* Observes memory read accesses.
|
||||
@ -339,7 +338,7 @@ class MemReadEvent : virtual public MemAccessEvent
|
||||
public:
|
||||
MemReadEvent()
|
||||
: MemAccessEvent(MEM_READ) { }
|
||||
MemReadEvent(sal::address_t addr)
|
||||
MemReadEvent(address_t addr)
|
||||
: MemAccessEvent(addr, MEM_READ) { }
|
||||
};
|
||||
|
||||
@ -352,7 +351,7 @@ class MemWriteEvent : virtual public MemAccessEvent
|
||||
public:
|
||||
MemWriteEvent()
|
||||
: MemAccessEvent(MEM_READ) { }
|
||||
MemWriteEvent(sal::address_t addr)
|
||||
MemWriteEvent(address_t addr)
|
||||
: MemAccessEvent(addr, MEM_WRITE) { }
|
||||
};
|
||||
|
||||
@ -582,7 +581,7 @@ class TimerEvent : public BaseEvent
|
||||
{
|
||||
private:
|
||||
unsigned m_Timeout; //!< timeout interval in milliseconds
|
||||
sal::timer_id_t m_Id; //!< internal timer id (sim-specific)
|
||||
timer_id_t m_Id; //!< internal timer id (sim-specific)
|
||||
bool m_Once; //!< true, if the timer should be triggered only once
|
||||
public:
|
||||
/**
|
||||
@ -600,12 +599,12 @@ class TimerEvent : public BaseEvent
|
||||
* Retrieves the internal timer id. Maybe useful for debug output.
|
||||
* @return the timer id
|
||||
*/
|
||||
sal::timer_id_t getId() const { return m_Id; }
|
||||
timer_id_t getId() const { return m_Id; }
|
||||
/**
|
||||
* Sets the internal timer id. This should not be used by the experiment.
|
||||
* @param id the new timer id, given by the underlying simulator-backend
|
||||
*/
|
||||
void setId(sal::timer_id_t id) { m_Id = id; }
|
||||
void setId(timer_id_t id) { m_Id = id; }
|
||||
/**
|
||||
* Retrieves the timer's timeout value.
|
||||
* @return the timout in milliseconds
|
||||
@ -618,6 +617,6 @@ class TimerEvent : public BaseEvent
|
||||
bool getOnceFlag() const { return m_Once; }
|
||||
};
|
||||
|
||||
} // end-of-namespace: fi
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __EVENT_HPP__ */
|
||||
#endif // __EVENT_HPP__
|
||||
|
||||
@ -3,9 +3,8 @@
|
||||
#include "EventList.hpp"
|
||||
#include "../SAL/SALInst.hpp"
|
||||
|
||||
namespace fi
|
||||
{
|
||||
|
||||
namespace fail {
|
||||
|
||||
EventId EventList::add(BaseEvent* ev, ExperimentFlow* pExp)
|
||||
{
|
||||
assert(ev != NULL && "FATAL ERROR: Event (of base type BaseEvent*) cannot be NULL!");
|
||||
@ -28,9 +27,9 @@ void EventList::remove(BaseEvent* ev)
|
||||
// * copy m_FireList to m_DeleteList
|
||||
if (ev == 0) {
|
||||
for (bufferlist_t::iterator it = m_BufferList.begin(); it != m_BufferList.end(); it++)
|
||||
sal::simulator.onEventDeletion(*it);
|
||||
simulator.onEventDeletion(*it);
|
||||
for (firelist_t::iterator it = m_FireList.begin(); it != m_FireList.end(); it++)
|
||||
sal::simulator.onEventDeletion(*it);
|
||||
simulator.onEventDeletion(*it);
|
||||
m_Bp_cache.clear();
|
||||
m_BufferList.clear();
|
||||
// all remaining active events must not fire anymore
|
||||
@ -40,7 +39,7 @@ void EventList::remove(BaseEvent* ev)
|
||||
// * find/remove ev in m_BufferList
|
||||
// * if ev in m_FireList, copy to m_DeleteList
|
||||
} else {
|
||||
sal::simulator.onEventDeletion(ev);
|
||||
simulator.onEventDeletion(ev);
|
||||
|
||||
BPEvent *bp_ev;
|
||||
if((bp_ev = dynamic_cast<BPEvent*>(ev)) != NULL)
|
||||
@ -67,7 +66,7 @@ EventList::iterator EventList::m_remove(iterator it, bool skip_deletelist)
|
||||
// from the buffer list to the fire-list. Therefor we only need to call the simulator's
|
||||
// event handler (m_onEventDeletion), if m_remove is called with the primary intention
|
||||
// to *delete* (not "move") an event.
|
||||
sal::simulator.onEventDeletion(*it);
|
||||
simulator.onEventDeletion(*it);
|
||||
m_DeleteList.push_back(*it);
|
||||
}
|
||||
|
||||
@ -82,7 +81,7 @@ void EventList::remove(ExperimentFlow* flow)
|
||||
// WARNING: (*it) (= all elements in the lists) can be an invalid ptr because
|
||||
// clearEvents will be called automatically when the allocating experiment (i.e.
|
||||
// run()) has already ended. Accordingly, we cannot call
|
||||
// sal::simulator.onEventDeletion(*it)
|
||||
// simulator.onEventDeletion(*it)
|
||||
// because a dynamic-cast of *it would cause a SEGFAULT. Therefor we require the
|
||||
// experiment flow to remove all residual events by calling clearEvents() (with-
|
||||
// in run()). As a consequence, we are now allowed to call the event-handler here.
|
||||
@ -92,14 +91,14 @@ void EventList::remove(ExperimentFlow* flow)
|
||||
if (flow == 0) {
|
||||
for (bufferlist_t::iterator it = m_BufferList.begin();
|
||||
it != m_BufferList.end(); it++)
|
||||
sal::simulator.onEventDeletion(*it); // invoke event handler
|
||||
simulator.onEventDeletion(*it); // invoke event handler
|
||||
m_Bp_cache.clear();
|
||||
m_BufferList.clear();
|
||||
} else { // remove all events corresponding to a specific experiment ("flow"):
|
||||
for (bufferlist_t::iterator it = m_BufferList.begin();
|
||||
it != m_BufferList.end(); ) {
|
||||
if ((*it)->getParent() == flow) {
|
||||
sal::simulator.onEventDeletion(*it);
|
||||
simulator.onEventDeletion(*it);
|
||||
it = m_BufferList.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
@ -116,7 +115,7 @@ void EventList::remove(ExperimentFlow* flow)
|
||||
// ... need to be pushed into m_DeleteList, as we're currently
|
||||
// iterating over m_FireList in fireActiveEvents() and cannot modify it
|
||||
if (flow == 0 || (*it)->getParent() == flow) {
|
||||
sal::simulator.onEventDeletion(*it);
|
||||
simulator.onEventDeletion(*it);
|
||||
m_DeleteList.push_back(*it);
|
||||
}
|
||||
}
|
||||
@ -160,14 +159,14 @@ void EventList::fireActiveEvents()
|
||||
for (firelist_t::iterator it = m_FireList.begin();
|
||||
it != m_FireList.end(); it++) {
|
||||
if (std::find(m_DeleteList.begin(), m_DeleteList.end(), *it)
|
||||
== m_DeleteList.end()) { // not found in delete-list?
|
||||
== m_DeleteList.end()) { // not found in delete-list?
|
||||
m_pFired = *it;
|
||||
// Inform (call) the simulator's (internal) event handler that we are about
|
||||
// to trigger an event (*before* we actually toggle the experiment flow):
|
||||
sal::simulator.onEventTrigger(m_pFired);
|
||||
simulator.onEventTrigger(m_pFired);
|
||||
ExperimentFlow* pFlow = m_pFired->getParent();
|
||||
assert(pFlow && "FATAL ERROR: The event has no parent experiment (owner)!");
|
||||
sal::simulator.m_Flows.toggle(pFlow);
|
||||
simulator.m_Flows.toggle(pFlow);
|
||||
}
|
||||
}
|
||||
m_FireList.clear();
|
||||
@ -177,11 +176,12 @@ void EventList::fireActiveEvents()
|
||||
|
||||
size_t EventList::getContextCount() const
|
||||
{
|
||||
set<ExperimentFlow*> uniqueFlows; // count unique ExperimentFlow-ptr
|
||||
std::set<ExperimentFlow*> uniqueFlows; // count unique ExperimentFlow-ptr
|
||||
for(bufferlist_t::const_iterator it = m_BufferList.begin();
|
||||
it != m_BufferList.end(); it++)
|
||||
uniqueFlows.insert((*it)->getParent());
|
||||
return (uniqueFlows.size());
|
||||
|
||||
return uniqueFlows.size();
|
||||
}
|
||||
|
||||
} // end-of-namespace: fi
|
||||
} // end-of-namespace: fail
|
||||
|
||||
@ -9,8 +9,7 @@
|
||||
#include "Event.hpp"
|
||||
#include "BufferCache.hpp"
|
||||
|
||||
namespace fi
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
class ExperimentFlow;
|
||||
|
||||
@ -49,10 +48,10 @@ typedef std::vector<BaseEvent*> deletelist_t;
|
||||
class EventList
|
||||
{
|
||||
private:
|
||||
// TODO: List separation of "critical types"? Hashing/sorted lists? (-> performance!)
|
||||
bufferlist_t m_BufferList; //!< the storage for events added by exp.
|
||||
firelist_t m_FireList; //!< the active events (used temporarily)
|
||||
deletelist_t m_DeleteList; //!< the deleted events (used temporarily)
|
||||
// TODO: Hashing?
|
||||
BaseEvent* m_pFired; //!< the recently fired Event-object
|
||||
BufferCache<BPEvent*> m_Bp_cache;
|
||||
public:
|
||||
@ -189,6 +188,6 @@ class EventList
|
||||
inline BufferCache<BPEvent*> *getBPBuffer() { return &m_Bp_cache; }
|
||||
};
|
||||
|
||||
}; // end-of-namespace: fi
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __EVENT_LIST_HPP__ */
|
||||
#endif // __EVENT_LIST_HPP__
|
||||
|
||||
@ -1,56 +1,51 @@
|
||||
/**
|
||||
* \brief ExperimentData interface
|
||||
*
|
||||
* This is the base class for all user-defined data types for
|
||||
* \brief This is the base class for all user-defined data types for
|
||||
* expirement parameter and results.
|
||||
*
|
||||
* \author Martin Hoffmann, Richard Hellwig
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __EXPERIMENT_DATA_H__
|
||||
#define __EXPERIMENT_DATA_H__
|
||||
#ifndef __EXPERIMENT_DATA_HPP__
|
||||
#define __EXPERIMENT_DATA_HPP__
|
||||
|
||||
#include <string>
|
||||
#include <google/protobuf/message.h>
|
||||
using namespace std;
|
||||
|
||||
namespace fi{
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class ExperimentData
|
||||
* Container for experiment data with wrapper methods for serialization and deserialization.
|
||||
*/
|
||||
class ExperimentData
|
||||
{
|
||||
protected:
|
||||
google::protobuf::Message* msg;
|
||||
uint32_t m_workloadID;
|
||||
public:
|
||||
ExperimentData() : msg(0), m_workloadID(0) {};
|
||||
ExperimentData(google::protobuf::Message* m) : msg(m) , m_workloadID(0) {};
|
||||
|
||||
class ExperimentData
|
||||
{
|
||||
protected:
|
||||
google::protobuf::Message* msg;
|
||||
uint32_t m_workloadID;
|
||||
public:
|
||||
ExperimentData() : msg(0), m_workloadID(0) {};
|
||||
ExperimentData(google::protobuf::Message* m) : msg(m) , m_workloadID(0) {};
|
||||
|
||||
google::protobuf::Message& getMessage() { return *msg; };
|
||||
uint32_t getWorkloadID() const { return m_workloadID;};
|
||||
void setWorkloadID(uint32_t id) { m_workloadID = id; };
|
||||
/**
|
||||
* Serializes the ExperimentData.
|
||||
* @param ped output the target-stream.
|
||||
* @return \c true if the serialization was successful, \c false otherwise
|
||||
*/
|
||||
bool serialize(ostream * output) const { return msg->SerializeToOstream(output); }
|
||||
/**
|
||||
* Unserializes the ExperimentData.
|
||||
* @param ped input the stream which is read from
|
||||
* @return \c true if the unserialization was successful, \c false otherwise
|
||||
*/
|
||||
bool unserialize(istream * input) { return msg->ParseFromIstream(input); }
|
||||
string DebugString() const { return msg->DebugString(); };
|
||||
};
|
||||
|
||||
google::protobuf::Message& getMessage() { return *msg; };
|
||||
uint32_t getWorkloadID() const { return m_workloadID;};
|
||||
void setWorkloadID(uint32_t id) { m_workloadID = id; };
|
||||
/**
|
||||
* Serializes the ExperimentData.
|
||||
* @param ped output the target-stream.
|
||||
* @return \c true if the serialization was successful, \c false otherwise
|
||||
*/
|
||||
bool serialize(std::ostream* output) const { return msg->SerializeToOstream(output); }
|
||||
/**
|
||||
* Unserializes the ExperimentData.
|
||||
* @param ped input the stream which is read from
|
||||
* @return \c true if the unserialization was successful, \c false otherwise
|
||||
*/
|
||||
bool unserialize(std::istream* input) { return msg->ParseFromIstream(input); }
|
||||
/**
|
||||
* Returns a debug string.
|
||||
* @return the debug string
|
||||
*/
|
||||
std::string debugString() const { return msg->DebugString(); };
|
||||
};
|
||||
|
||||
#endif //__EXPERIMENT_DATA_H__
|
||||
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif //__EXPERIMENT_DATA_HPP__
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
// FIXME: This is deprecated stuff. Remove it.
|
||||
|
||||
namespace fi
|
||||
{
|
||||
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// FIXME: This is deprecated stuff. Remove it.
|
||||
|
||||
#ifndef __EXPERIMENT_DATA_QUEUE_H__
|
||||
#define __EXPERIMENT_DATA_QUEUE_H__
|
||||
|
||||
|
||||
@ -3,8 +3,7 @@
|
||||
|
||||
#include "../SAL/SALInst.hpp"
|
||||
|
||||
namespace fi
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class ExperimentFlow
|
||||
@ -20,7 +19,6 @@ class ExperimentFlow
|
||||
* @return \c true if the experiment was successful, \c false otherwise
|
||||
*/
|
||||
virtual bool run() = 0;
|
||||
|
||||
/**
|
||||
* The entry point for this experiment's coroutine.
|
||||
* Should do some cleanup afterwards.
|
||||
@ -28,13 +26,13 @@ class ExperimentFlow
|
||||
void coroutine_entry()
|
||||
{
|
||||
run();
|
||||
sal::simulator.clearEvents(this); // remove residual events
|
||||
simulator.clearEvents(this); // remove residual events
|
||||
// FIXME: Consider removing this call (see EventList.cc, void remove(ExperimentFlow* flow))
|
||||
// a) with the advantage that we will potentially prevent serious segfaults but
|
||||
// b) with the drawback that we cannot enforce any cleanups.
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __EXPERIMENT_FLOW_HPP__ */
|
||||
#endif // __EXPERIMENT_FLOW_HPP__
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
/**
|
||||
* \brief The representation of a minion.
|
||||
*
|
||||
* \author Richard Hellwig
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __MINION_HPP__
|
||||
#define __MINION_HPP__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "controller/ExperimentData.hpp"
|
||||
|
||||
namespace fi
|
||||
{
|
||||
namespace fail {
|
||||
|
||||
/**
|
||||
* \class Minion
|
||||
*
|
||||
@ -20,26 +20,32 @@ namespace fi
|
||||
class Minion
|
||||
{
|
||||
private:
|
||||
string hostname;
|
||||
std::string hostname;
|
||||
bool isWorking;
|
||||
ExperimentData* currentExperimentData;
|
||||
int sockfd;
|
||||
public:
|
||||
Minion() : isWorking(false), currentExperimentData(0), sockfd(-1) { }
|
||||
|
||||
/**
|
||||
* Sets the socket descriptor.
|
||||
* @param sock the new socket descriptor (used internal)
|
||||
*/
|
||||
void setSocketDescriptor(int sock) { sockfd = sock; }
|
||||
/**
|
||||
* Retrives the socket descriptor.
|
||||
* @return the socket descriptor
|
||||
*/
|
||||
int getSocketDescriptor() const { return (sockfd); }
|
||||
|
||||
/**
|
||||
* Returns the hostname of the minion.
|
||||
* @return the hostname
|
||||
*/
|
||||
string getHostname() { return (hostname); }
|
||||
const std::string& getHostname() { return (hostname); }
|
||||
/**
|
||||
* Sets the hostname of the minion.
|
||||
* @param host the hostname
|
||||
*/
|
||||
void setHostname(string host) { hostname = host; }
|
||||
void setHostname(const std::string& host) { hostname = host; }
|
||||
/**
|
||||
* Returns the current ExperimentData which the minion is working with.
|
||||
* @return a pointer of the current ExperimentData
|
||||
@ -62,6 +68,6 @@ class Minion
|
||||
void setBusy(bool state) { isWorking = state; }
|
||||
};
|
||||
|
||||
};
|
||||
} // end-of-namespace: fail
|
||||
|
||||
#endif /* __MINION_HPP__ */
|
||||
#endif // __MINION_HPP__
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 15.06.2011
|
||||
|
||||
// FIXME: This is deprecated stuff. Delete it.
|
||||
|
||||
#include "Signal.hpp"
|
||||
|
||||
namespace fi
|
||||
|
||||
@ -1,8 +1,7 @@
|
||||
#ifndef __SIGNAL_HPP__
|
||||
#define __SIGNAL_HPP__
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 15.06.2011
|
||||
// FIXME: This is deprecated stuff. Delete it.
|
||||
|
||||
#include <cassert>
|
||||
#include <memory>
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#include "SynchronizedExperimentDataQueue.hpp"
|
||||
|
||||
// FIXME: This file is not used. Delete it either.
|
||||
|
||||
namespace fi {
|
||||
|
||||
void SynchronizedExperimentDataQueue::addData(ExperimentData* exp){
|
||||
@ -20,4 +22,4 @@ ExperimentData* SynchronizedExperimentDataQueue::getData(){
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
// FIXME: This file is not used. Delete it.
|
||||
|
||||
#ifndef __SYNC_EXPERIMENT_DATA_QUEUE_H__
|
||||
#define __SYNC_EXPERIMENT_DATA_QUEUE_H__
|
||||
|
||||
|
||||
@ -10,12 +10,11 @@
|
||||
#include "../../util/Logger.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace sal;
|
||||
using namespace fi;
|
||||
using namespace sal;
|
||||
using namespace fail;
|
||||
|
||||
bool FaultCoverageExperiment::run()
|
||||
{
|
||||
// FIXME: This should be translated (-> English)!
|
||||
/*
|
||||
Experimentskizze:
|
||||
- starte Gastsystem
|
||||
@ -109,7 +108,7 @@ bool FaultCoverageExperiment::run()
|
||||
#else
|
||||
const size_t expected_size = sizeof(uint64_t)*8;
|
||||
#endif
|
||||
Register* pCAX = simulator.getRegisterManager().getSetOfType(RT_GP)->getRegister(sal::RID_CAX);
|
||||
Register* pCAX = simulator.getRegisterManager().getSetOfType(RT_GP)->getRegister(RID_CAX);
|
||||
assert(expected_size == pCAX->getWidth()); // we assume to get 32(64) bits...
|
||||
regdata_t result = pCAX->getData();
|
||||
res << "[FaultCoverageExperiment] Reg: " << pCAX->getName()
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef __FAULTCOVERAGE_EXPERIMENT_HPP__
|
||||
#define __FAULTCOVERAGE_EXPERIMENT_HPP__
|
||||
#ifndef __FAULT_COVERAGE_EXPERIMENT_HPP__
|
||||
#define __FAULT_COVERAGE_EXPERIMENT_HPP__
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
@ -17,13 +17,9 @@
|
||||
breakpoints, traps, save/restore. Enable these in the configuration.
|
||||
#endif
|
||||
|
||||
using namespace fi;
|
||||
|
||||
class FaultCoverageExperiment : public ExperimentFlow
|
||||
{
|
||||
public:
|
||||
bool run();
|
||||
class FaultCoverageExperiment : public fail::ExperimentFlow {
|
||||
public:
|
||||
bool run();
|
||||
};
|
||||
|
||||
#endif // __FAULTCOVERAGE_EXPERIMENT_HPP__
|
||||
|
||||
#endif // __FAULT_COVERAGE_EXPERIMENT_HPP__
|
||||
|
||||
@ -1,21 +1,21 @@
|
||||
#include "MHTestCampaign.hpp"
|
||||
#include <controller/CampaignManager.hpp>
|
||||
#include <iostream>
|
||||
|
||||
using namespace fi;
|
||||
#include "MHTestCampaign.hpp"
|
||||
#include <controller/CampaignManager.hpp>
|
||||
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
bool MHTestCampaign::run()
|
||||
{
|
||||
|
||||
MHExperimentData* datas[m_parameter_count];
|
||||
cout << "[MHTestCampaign] Adding " << m_parameter_count << " values." << endl;
|
||||
for(int i = 1; i <= m_parameter_count; i++){
|
||||
datas[i] = new MHExperimentData;
|
||||
datas[i]->msg.set_input(i);
|
||||
|
||||
campaignmanager.addParam(datas[i]);
|
||||
usleep(100 * 1000); // 100 ms
|
||||
for (int i = 1; i <= m_parameter_count; i++) {
|
||||
datas[i] = new MHExperimentData;
|
||||
datas[i]->msg.set_input(i);
|
||||
|
||||
campaignmanager.addParam(datas[i]);
|
||||
usleep(100 * 1000); // 100 ms
|
||||
}
|
||||
campaignmanager.noMoreParameters();
|
||||
// test results.
|
||||
@ -23,8 +23,8 @@ bool MHTestCampaign::run()
|
||||
int res = 0;
|
||||
int res2 = 0;
|
||||
MHExperimentData * exp;
|
||||
for(int i = 1; i <= m_parameter_count; i++){
|
||||
exp = static_cast<MHExperimentData*>( campaignmanager.getDone() );
|
||||
for (int i = 1; i <= m_parameter_count; i++) {
|
||||
exp = static_cast<MHExperimentData*>(campaignmanager.getDone());
|
||||
f = exp->msg.output();
|
||||
// cout << ">>>>>>>>>>>>>>> Output: " << i << "^2 = " << f << endl;
|
||||
res += f;
|
||||
@ -33,7 +33,7 @@ bool MHTestCampaign::run()
|
||||
}
|
||||
if (res == res2) {
|
||||
cout << "TEST SUCCESSFUL FINISHED! " << "[" << res << "==" << res2 << "]" << endl;
|
||||
}else{
|
||||
} else {
|
||||
cout << "TEST FAILED!" << " [" << res << "!=" << res2 << "]" << endl;
|
||||
}
|
||||
cout << "thats all... " << endl;
|
||||
|
||||
@ -1,27 +1,23 @@
|
||||
#ifndef __TESTCAMPAIGN_HPP__
|
||||
#define __TESTCAMPAIGN_HPP__
|
||||
|
||||
|
||||
#ifndef __MH_TEST_CAMPAIGN_HPP__
|
||||
#define __MH_TEST_CAMPAIGN_HPP__
|
||||
|
||||
#include <controller/Campaign.hpp>
|
||||
#include "controller/ExperimentData.hpp"
|
||||
#include <experiments/MHTestCampaign/MHTest.pb.h>
|
||||
|
||||
using namespace fi;
|
||||
|
||||
class MHExperimentData : public ExperimentData {
|
||||
public:
|
||||
MHTestData msg;
|
||||
public:
|
||||
MHExperimentData() : ExperimentData(&msg){ };
|
||||
class MHExperimentData : public fail::ExperimentData {
|
||||
public:
|
||||
MHTestData msg;
|
||||
MHExperimentData() : fail::ExperimentData(&msg) { }
|
||||
};
|
||||
|
||||
|
||||
class MHTestCampaign : public Campaign {
|
||||
int m_parameter_count;
|
||||
public:
|
||||
MHTestCampaign(int parametercount) : m_parameter_count(parametercount){};
|
||||
virtual bool run();
|
||||
class MHTestCampaign : public fail::Campaign {
|
||||
private:
|
||||
int m_parameter_count;
|
||||
public:
|
||||
MHTestCampaign(int parametercount) : m_parameter_count(parametercount) { }
|
||||
bool run();
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
#endif // __MH_TEST_CAMPAIGN_HPP__
|
||||
|
||||
@ -1,32 +1,35 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "experiment.hpp"
|
||||
#include "MHTestCampaign.hpp"
|
||||
#include "SAL/SALInst.hpp"
|
||||
#include "SAL/Register.hpp"
|
||||
#include "controller/Event.hpp"
|
||||
|
||||
#include <iostream>
|
||||
// FIXME: You should provide a dependency check here!
|
||||
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
bool MHTestExperiment::run()
|
||||
{
|
||||
|
||||
cout << "[MHTestExperiment] Let's go" << endl;
|
||||
#if 0
|
||||
fi::BPSingleEvent mainbp(0x00003c34);
|
||||
sal::simulator.addEventAndWait(&mainbp);
|
||||
BPSingleEvent mainbp(0x00003c34);
|
||||
simulator.addEventAndWait(&mainbp);
|
||||
cout << "[MHTestExperiment] breakpoint reached, saving" << endl;
|
||||
sal::simulator.save("hello.main");
|
||||
simulator.save("hello.main");
|
||||
#else
|
||||
MHExperimentData par;
|
||||
if(m_jc.getParam(par)){
|
||||
|
||||
if (m_jc.getParam(par)) {
|
||||
int num = par.msg.input();
|
||||
cout << "[MHExperiment] stepping " << num << " instructions" << endl;
|
||||
if (num > 0) {
|
||||
fi::BPSingleEvent nextbp(fi::ANY_ADDR);
|
||||
BPSingleEvent nextbp(ANY_ADDR);
|
||||
nextbp.setCounter(num);
|
||||
sal::simulator.addEventAndWait(&nextbp);
|
||||
simulator.addEventAndWait(&nextbp);
|
||||
}
|
||||
sal::address_t instr = sal::simulator.getRegisterManager().getInstructionPointer();
|
||||
address_t instr = simulator.getRegisterManager().getInstructionPointer();
|
||||
cout << "[MHTestExperiment] Reached instruction: "
|
||||
<< hex << instr
|
||||
<< endl;
|
||||
@ -36,8 +39,8 @@ bool MHTestExperiment::run()
|
||||
cout << "No data for me? :(" << endl;
|
||||
}
|
||||
#endif
|
||||
sal::simulator.clearEvents(this);
|
||||
sal::simulator.terminate();
|
||||
simulator.clearEvents(this);
|
||||
|
||||
simulator.terminate();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@ -1,17 +1,17 @@
|
||||
#ifndef __TESTEXPERIMENT_HPP__
|
||||
#define __TESTEXPERIMENT_HPP__
|
||||
#ifndef __MH_TEST_EXPERIMENT_HPP__
|
||||
#define __MH_TEST_EXPERIMENT_HPP__
|
||||
|
||||
#include "controller/ExperimentFlow.hpp"
|
||||
#include "jobserver/JobClient.hpp"
|
||||
|
||||
class MHTestExperiment : public fi::ExperimentFlow {
|
||||
fi::JobClient m_jc;
|
||||
public:
|
||||
MHTestExperiment(){};
|
||||
~MHTestExperiment(){};
|
||||
bool run();
|
||||
class MHTestExperiment : public fail::ExperimentFlow {
|
||||
private:
|
||||
fail::JobClient m_jc;
|
||||
public:
|
||||
MHTestExperiment() { }
|
||||
~MHTestExperiment() { }
|
||||
|
||||
bool run();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
#endif // __MH_TEST_EXPERIMENT_HPP__
|
||||
|
||||
@ -1,25 +1,24 @@
|
||||
#include "controller/CampaignManager.hpp"
|
||||
#include "experiments/MHTestCampaign/MHTestCampaign.hpp"
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
#include "controller/CampaignManager.hpp"
|
||||
#include "experiments/MHTestCampaign/MHTestCampaign.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char**argv){
|
||||
int main(int argc, char**argv)
|
||||
{
|
||||
int paramcount = 0;
|
||||
if (argc == 2)
|
||||
paramcount = atoi(argv[1]);
|
||||
else
|
||||
paramcount = 10;
|
||||
cout << "Running MHTestCampaign [" << paramcount << " parameter sets]" << endl;
|
||||
|
||||
int paramcount = 0;
|
||||
if(argc == 2){
|
||||
paramcount = atoi(argv[1]);
|
||||
}else{
|
||||
paramcount = 10;
|
||||
}
|
||||
cout << "Running MHTestCampaign [" << paramcount << " parameter sets]" << endl;
|
||||
|
||||
MHTestCampaign mhc(paramcount);
|
||||
campaignmanager.runCampaign(&mhc);
|
||||
|
||||
cout << "Campaign complete." << endl;
|
||||
|
||||
return 0;
|
||||
|
||||
MHTestCampaign mhc(paramcount);
|
||||
campaignmanager.runCampaign(&mhc);
|
||||
|
||||
cout << "Campaign complete." << endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -10,16 +10,14 @@
|
||||
#include <google/protobuf/io/gzip_stream.h>
|
||||
*/
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using namespace fi;
|
||||
using namespace sal;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
bool TracingTest::run()
|
||||
{
|
||||
cout << "[TracingTest] Setting up experiment" << endl;
|
||||
|
||||
#if 1
|
||||
#if 0
|
||||
// STEP 1: run until interesting function starts, and save state
|
||||
BPSingleEvent breakpoint(0x00101658);
|
||||
simulator.addEventAndWait(&breakpoint);
|
||||
@ -33,17 +31,17 @@ bool TracingTest::run()
|
||||
cout << "[TracingTest] enabling tracing" << endl;
|
||||
|
||||
TracingPlugin tp;
|
||||
std::ofstream of("trace.pb");
|
||||
ofstream of("trace.pb");
|
||||
tp.setTraceFile(&of);
|
||||
// this must be done *after* configuring the plugin:
|
||||
simulator.addFlow(&tp);
|
||||
|
||||
cout << "[TracingTest] tracing 1000000 instructions" << endl;
|
||||
BPSingleEvent timeout(fi::ANY_ADDR);
|
||||
BPSingleEvent timeout(ANY_ADDR);
|
||||
timeout.setCounter(1000000);
|
||||
simulator.addEvent(&timeout);
|
||||
|
||||
InterruptEvent ie(fi::ANY_INTERRUPT);
|
||||
InterruptEvent ie(ANY_INTERRUPT);
|
||||
while (simulator.addEventAndWait(&ie) != &timeout) {
|
||||
cout << "INTERRUPT #" << ie.getTriggerNumber() << "\n";
|
||||
}
|
||||
@ -54,7 +52,7 @@ bool TracingTest::run()
|
||||
|
||||
/*
|
||||
// serialize trace to file
|
||||
std::ofstream of("trace.pb");
|
||||
ofstream of("trace.pb");
|
||||
if (of.fail()) { return false; }
|
||||
trace.SerializeToOstream(&of);
|
||||
of.close();
|
||||
|
||||
@ -3,10 +3,10 @@
|
||||
|
||||
#include "controller/ExperimentFlow.hpp"
|
||||
|
||||
class TracingTest : public fi::ExperimentFlow
|
||||
class TracingTest : public fail::ExperimentFlow
|
||||
{
|
||||
public:
|
||||
bool run();
|
||||
};
|
||||
|
||||
#endif /* __TRACING_TEST_HPP__ */
|
||||
#endif // __TRACING_TEST_HPP__
|
||||
|
||||
@ -5,9 +5,8 @@
|
||||
#include "../controller/Event.hpp"
|
||||
#include "ExperimentDataExample/FaultCoverageExperiment.pb.h"
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using std::hex;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
#define MEMTEST86_BREAKPOINT 0x4EDC
|
||||
|
||||
@ -16,22 +15,22 @@ bool DataRetrievalExperiment::run()
|
||||
cout << "[getExperimentDataExperiment] Experiment start." << endl;
|
||||
|
||||
// Breakpoint address for Memtest86:
|
||||
fi::BPSingleEvent mainbp(MEMTEST86_BREAKPOINT);
|
||||
sal::simulator.addEventAndWait(&mainbp);
|
||||
BPSingleEvent mainbp(MEMTEST86_BREAKPOINT);
|
||||
simulator.addEventAndWait(&mainbp);
|
||||
cout << "[getExperimentDataExperiment] Breakpoint reached." << endl;
|
||||
|
||||
FaultCoverageExperimentData* test = NULL;
|
||||
cout << "[getExperimentDataExperiment] Getting ExperimentData (FaultCoverageExperiment)..." << endl;
|
||||
test = sal::simulator.getExperimentData<FaultCoverageExperimentData>();
|
||||
test = simulator.getExperimentData<FaultCoverageExperimentData>();
|
||||
cout << "[getExperimentDataExperiment] Content of ExperimentData (FaultCoverageExperiment):" << endl;
|
||||
|
||||
if(test->has_data_name())
|
||||
if (test->has_data_name())
|
||||
cout << "Name: "<< test->data_name() << endl;
|
||||
// m_instrptr1 augeben
|
||||
cout << "m_instrptr1: " << hex << test->m_instrptr1() << endl;
|
||||
// m_instrptr2 augeben
|
||||
cout << "m_instrptr2: " << hex << test->m_instrptr2() << endl;
|
||||
|
||||
sal::simulator.clearEvents(this);
|
||||
simulator.clearEvents(this);
|
||||
return true; // experiment successful
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
|
||||
class DataRetrievalExperiment : public fi::ExperimentFlow
|
||||
class DataRetrievalExperiment : public fail::ExperimentFlow
|
||||
{
|
||||
public:
|
||||
DataRetrievalExperiment() { }
|
||||
@ -11,4 +11,4 @@ class DataRetrievalExperiment : public fi::ExperimentFlow
|
||||
bool run();
|
||||
};
|
||||
|
||||
#endif /* __DATA_RETRIEVAL_EXPERIMENT_HPP__ */
|
||||
#endif // __DATA_RETRIEVAL_EXPERIMENT_HPP__
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
|
||||
#include "controller/ExperimentData.hpp"
|
||||
#include "controller/ExperimentDataQueue.hpp"
|
||||
#include "jobserver/JobServer.hpp"
|
||||
@ -7,83 +8,56 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char* argv[]){
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
// FIXME: Translation missing.
|
||||
|
||||
ExperimentDataQueue exDaQu;
|
||||
ExperimentData* readFromQueue;
|
||||
|
||||
fi::ExperimentDataQueue exDaQu;
|
||||
fi::ExperimentData* readFromQueue;
|
||||
|
||||
|
||||
//Daten in Struktur schreiben und in Datei speichern
|
||||
|
||||
// Daten in Struktur schreiben und in Datei speichern
|
||||
ofstream fileWrite;
|
||||
fileWrite.open("test.txt");
|
||||
|
||||
|
||||
FaultCoverageExperimentData faultCovExWrite;
|
||||
|
||||
//Namen setzen
|
||||
// Namen setzen
|
||||
faultCovExWrite.set_data_name("Testfall 42");
|
||||
|
||||
//Instruktionpointer 1
|
||||
// Instruktionpointer 1
|
||||
faultCovExWrite.set_m_instrptr1(0x4711);
|
||||
|
||||
|
||||
//Instruktionpointer 2
|
||||
// Instruktionpointer 2
|
||||
faultCovExWrite.set_m_instrptr2(0x1122);
|
||||
|
||||
|
||||
//In ExperimentData verpacken
|
||||
fi::ExperimentData exDaWrite(&faultCovExWrite);
|
||||
|
||||
//In Queue einbinden
|
||||
// In ExperimentData verpacken
|
||||
ExperimentData exDaWrite(&faultCovExWrite);
|
||||
// In Queue einbinden
|
||||
exDaQu.addData(&exDaWrite);
|
||||
|
||||
//Aus Queue holen
|
||||
if(exDaQu.size() != 0)
|
||||
// Aus Queue holen
|
||||
if (exDaQu.size() != 0)
|
||||
readFromQueue = exDaQu.getData();
|
||||
|
||||
//Serialisierung ueber Wrapper-Methode in ExperimentData
|
||||
// Serialisierung ueber Wrapper-Methode in ExperimentData
|
||||
readFromQueue->serialize(&fileWrite);
|
||||
|
||||
//cout << "Ausgabe: " << out << endl;
|
||||
|
||||
// cout << "Ausgabe: " << out << endl;
|
||||
fileWrite.close();
|
||||
|
||||
//---------------------------------------------------------------
|
||||
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
//Daten aus Datei lesen und in Struktur schreiben
|
||||
|
||||
|
||||
// Daten aus Datei lesen und in Struktur schreiben
|
||||
ifstream fileRead;
|
||||
fileRead.open("test.txt");
|
||||
|
||||
|
||||
FaultCoverageExperimentData faultCovExRead;
|
||||
|
||||
fi::ExperimentData exDaRead(&faultCovExRead);
|
||||
|
||||
ExperimentData exDaRead(&faultCovExRead);
|
||||
exDaRead.unserialize( &fileRead);
|
||||
|
||||
|
||||
//Wenn Name, dann ausgeben
|
||||
// Wenn Name, dann ausgeben
|
||||
if(faultCovExRead.has_data_name()){
|
||||
cout << "Name: "<< faultCovExRead.data_name() << endl;
|
||||
}
|
||||
|
||||
//m_instrptr1 augeben
|
||||
// m_instrptr1 augeben
|
||||
cout << "m_instrptr1: " << faultCovExRead.m_instrptr1() << endl;
|
||||
|
||||
//m_instrptr2 augeben
|
||||
// m_instrptr2 augeben
|
||||
cout << "m_instrptr2: " << faultCovExRead.m_instrptr2() << endl;
|
||||
|
||||
fileRead.close();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
#ifndef __JUMP_AND_RUN_EXPERIMENT_HPP__
|
||||
#define __JUMP_AND_RUN_EXPERIMENT_HPP__
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 07.11.2011
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
@ -16,69 +13,64 @@
|
||||
#error Breakpoint- and jump-events needed! Enable aspects first (see FailConfig.hpp)!
|
||||
#endif
|
||||
|
||||
using namespace fi;
|
||||
using namespace std;
|
||||
using namespace sal;
|
||||
using namespace fail;
|
||||
|
||||
class JumpAndRunExperiment : public fi::ExperimentFlow
|
||||
{
|
||||
public:
|
||||
bool run()
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
// Wait for function entry adresss:
|
||||
cout << "[JumpAndRunExperiment] Setting up experiment. Allowing to "
|
||||
<< "start now." << endl;
|
||||
BPEvent mainFuncEntry(0x3c1f);
|
||||
simulator.addEvent(&mainFuncEntry);
|
||||
if(&mainFuncEntry != simulator.waitAny())
|
||||
{
|
||||
cerr << "[JumpAndRunExperiment] Now, we are completely lost! "
|
||||
<< "It's time to cry! :-(" << endl;
|
||||
class JumpAndRunExperiment : public fail::ExperimentFlow {
|
||||
public:
|
||||
bool run()
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
// Wait for function entry adresss:
|
||||
cout << "[JumpAndRunExperiment] Setting up experiment. Allowing to "
|
||||
<< "start now." << endl;
|
||||
BPEvent mainFuncEntry(0x3c1f);
|
||||
simulator.addEvent(&mainFuncEntry);
|
||||
if (&mainFuncEntry != simulator.waitAny()) {
|
||||
cerr << "[JumpAndRunExperiment] Now, we are completely lost! "
|
||||
<< "It's time to cry! :-(" << endl;
|
||||
simulator.clearEvents(this);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
cout << "[JumpAndRunExperiment] Entry of main function reached! "
|
||||
<< " Let's see who's jumping around here..." << endl;
|
||||
|
||||
const unsigned COUNTER = 20000;
|
||||
unsigned i = 0;
|
||||
BxFlagsReg* pFlags = dynamic_cast<BxFlagsReg*>(simulator.
|
||||
getRegisterManager().getSetOfType(RT_ST).snatch());
|
||||
assert(pFlags != NULL && "FATAL ERROR: NULL ptr not expected!");
|
||||
JumpEvent ev;
|
||||
// Catch the next "counter" jumps:
|
||||
while (++i <= COUNTER) {
|
||||
ev.setWatchInstructionPointer(ANY_INSTR);
|
||||
simulator.addEvent(&ev);
|
||||
if (simulator.waitAny() != &ev) {
|
||||
cerr << "[JumpAndRunExperiment] Damn! Something went "
|
||||
<< "terribly wrong! Who added that event?! :-(" << endl;
|
||||
simulator.clearEvents(this);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
cout << "[JumpAndRunExperiment] Entry of main function reached! "
|
||||
<< " Let's see who's jumping around here..." << endl;
|
||||
|
||||
const unsigned COUNTER = 20000;
|
||||
unsigned i = 0;
|
||||
BxFlagsReg* pFlags = dynamic_cast<BxFlagsReg*>(simulator.
|
||||
getRegisterManager().getSetOfType(RT_ST).snatch());
|
||||
assert(pFlags != NULL && "FATAL ERROR: NULL ptr not expected!");
|
||||
JumpEvent ev;
|
||||
// Catch the next "counter" jumps:
|
||||
while(++i <= COUNTER)
|
||||
{
|
||||
ev.setWatchInstructionPointer(ANY_INSTR);
|
||||
simulator.addEvent(&ev);
|
||||
if(simulator.waitAny() != &ev)
|
||||
{
|
||||
cerr << "[JumpAndRunExperiment] Damn! Something went "
|
||||
<< "terribly wrong! Who added that event?! :-(" << endl;
|
||||
simulator.clearEvents(this);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
cout << "[JumpAndRunExperiment] Jump detected. Instruction: "
|
||||
<< "0x" hex << ev.getTriggerInstructionPointer()
|
||||
<< " -- FLAGS [CF, ZF, OF, PF, SF] = ["
|
||||
<< pFlags->getCarryFlag() << ", "
|
||||
<< pFlags->getZeroFlag() << ", "
|
||||
<< pFlags->getOverflowFlag() << ", "
|
||||
<< pFlags->getParityFlag() << ", "
|
||||
<< pFlags->getSignFlag() << "]." << endl;
|
||||
}
|
||||
cout << "[JumpAndRunExperiment] " << dec << counter
|
||||
<< " jump(s) detected -- enough for today...exiting! :-)"
|
||||
<< endl;
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
cout << "[JumpAndRunExperiment] Jump detected. Instruction: "
|
||||
<< "0x" hex << ev.getTriggerInstructionPointer()
|
||||
<< " -- FLAGS [CF, ZF, OF, PF, SF] = ["
|
||||
<< pFlags->getCarryFlag() << ", "
|
||||
<< pFlags->getZeroFlag() << ", "
|
||||
<< pFlags->getOverflowFlag() << ", "
|
||||
<< pFlags->getParityFlag() << ", "
|
||||
<< pFlags->getSignFlag() << "]." << endl;
|
||||
}
|
||||
cout << "[JumpAndRunExperiment] " << dec << counter
|
||||
<< " jump(s) detected -- enough for today...exiting! :-)"
|
||||
<< endl;
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* __JUMP_AND_RUN_EXPERIMENT_HPP__ */
|
||||
#endif // __JUMP_AND_RUN_EXPERIMENT_HPP__
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
#ifndef __MEM_WRITE_EXPERIMENT_HPP__
|
||||
#define __MEM_WRITE_EXPERIMENT_HPP__
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 16.06.2011
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
@ -15,63 +12,60 @@
|
||||
#error Event dependecies not satisfied! Enabled needed aspects in FailConfig.hpp!
|
||||
#endif
|
||||
|
||||
using namespace fi;
|
||||
using namespace std;
|
||||
using sal::simulator;
|
||||
using namespace fail;
|
||||
|
||||
class MemWriteExperiment : public ExperimentFlow
|
||||
{
|
||||
public:
|
||||
bool run() // Example experiment (defines "what we wanna do")
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
class MemWriteExperiment : public fail::ExperimentFlow {
|
||||
public:
|
||||
bool run() // Example experiment (defines "what we wanna do")
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
|
||||
// 1. Add some events (set up the experiment):
|
||||
cout << "[MemWriteExperiment] Setting up experiment. Allowing to"
|
||||
<< " start now." << endl;
|
||||
MemWriteEvent mem1(0x000904F0), mem2(0x02ff0916), mem3(0x0050C8E8);
|
||||
BPEvent breakpt(0x4ae6);
|
||||
simulator.addEvent(&mem1);
|
||||
simulator.addEvent(&mem2);
|
||||
simulator.addEvent(&mem3);
|
||||
simulator.addEvent(&breakpt);
|
||||
// 1. Add some events (set up the experiment):
|
||||
cout << "[MemWriteExperiment] Setting up experiment. Allowing to"
|
||||
<< " start now." << endl;
|
||||
MemWriteEvent mem1(0x000904F0), mem2(0x02ff0916), mem3(0x0050C8E8);
|
||||
BPEvent breakpt(0x4ae6);
|
||||
simulator.addEvent(&mem1);
|
||||
simulator.addEvent(&mem2);
|
||||
simulator.addEvent(&mem3);
|
||||
simulator.addEvent(&breakpt);
|
||||
|
||||
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
|
||||
cout << "[MemWriteExperiment] Waiting for condition (1) (\"(id1 &&"
|
||||
<< " id2) || id3\") to become true..." << endl;
|
||||
bool f1 = false, f2 = false, f3 = false, f4 = false;
|
||||
while(!(f1 || f2 || f3 || f4))
|
||||
{
|
||||
BPEvent* pev = simulator.waitAny();
|
||||
cout << "[MemWriteExperiment] Received event id=" << id
|
||||
<< "." << endl;
|
||||
if(pev == &mem4)
|
||||
f4 = true;
|
||||
if(pev == &mem3)
|
||||
f3 = true;
|
||||
if(pev == &mem2)
|
||||
f2 = true;
|
||||
if(pev == &mem1)
|
||||
f1 = true;
|
||||
}
|
||||
cout << "[MemWriteExperiment] Condition (1) satisfied! Ready to "
|
||||
<< "add next event..." << endl;
|
||||
// 3. Add a new event now:
|
||||
cout << "[MemWriteExperiment] Adding new Event..."; cout.flush();
|
||||
simulator.clearEvents(); // remove residual events in the buffer
|
||||
// (we're just interested in the new event)
|
||||
simulator.save("./bochs_save_point");
|
||||
cout << "done!" << endl;
|
||||
|
||||
// 4. Continue simulation (waitAny) and inject bitflip:
|
||||
// ...
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
|
||||
cout << "[MemWriteExperiment] Waiting for condition (1) (\"(id1 &&"
|
||||
<< " id2) || id3\") to become true..." << endl;
|
||||
bool f1 = false, f2 = false, f3 = false, f4 = false;
|
||||
while (!(f1 || f2 || f3 || f4)) {
|
||||
BPEvent* pev = simulator.waitAny();
|
||||
cout << "[MemWriteExperiment] Received event id=" << id
|
||||
<< "." << endl;
|
||||
if(pev == &mem4)
|
||||
f4 = true;
|
||||
if(pev == &mem3)
|
||||
f3 = true;
|
||||
if(pev == &mem2)
|
||||
f2 = true;
|
||||
if(pev == &mem1)
|
||||
f1 = true;
|
||||
}
|
||||
cout << "[MemWriteExperiment] Condition (1) satisfied! Ready to "
|
||||
<< "add next event..." << endl;
|
||||
// 3. Add a new event now:
|
||||
cout << "[MemWriteExperiment] Adding new Event..."; cout.flush();
|
||||
simulator.clearEvents(); // remove residual events in the buffer
|
||||
// (we're just interested in the new event)
|
||||
simulator.save("./bochs_save_point");
|
||||
cout << "done!" << endl;
|
||||
|
||||
// 4. Continue simulation (waitAny) and inject bitflip:
|
||||
// ...
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* __MEM_WRITE_EXPERIMENT_HPP__ */
|
||||
#endif // __MEM_WRITE_EXPERIMENT_HPP__
|
||||
|
||||
|
||||
@ -1,66 +1,60 @@
|
||||
#ifndef __MY_EXPERIMENT_HPP__
|
||||
#define __MY_EXPERIMENT_HPP__
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 16.06.2011
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
#include "../SAL/SALInst.hpp"
|
||||
|
||||
using namespace fi;
|
||||
using namespace std;
|
||||
using sal::simulator;
|
||||
using namespace fail;
|
||||
|
||||
class MyExperiment : public fi::ExperimentFlow
|
||||
{
|
||||
public:
|
||||
bool run() // Example experiment (defines "what we wanna do")
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
|
||||
// 1. Add some events (set up the experiment):
|
||||
cout << "[MyExperiment] Setting up experiment. Allowing to start"
|
||||
<< " now." << endl;
|
||||
BPEvent ev1(0x8048A00), ev2(0x8048F01), ev3(0x3c1f);
|
||||
simulator.addEvent(&ev1);
|
||||
simulator.addEvent(&ev2);
|
||||
simulator.addEvent(&ev3);
|
||||
class MyExperiment : public fail::ExperimentFlow {
|
||||
public:
|
||||
bool run() // Example experiment (defines "what we wanna do")
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
|
||||
// 1. Add some events (set up the experiment):
|
||||
cout << "[MyExperiment] Setting up experiment. Allowing to start"
|
||||
<< " now." << endl;
|
||||
BPEvent ev1(0x8048A00), ev2(0x8048F01), ev3(0x3c1f);
|
||||
simulator.addEvent(&ev1);
|
||||
simulator.addEvent(&ev2);
|
||||
simulator.addEvent(&ev3);
|
||||
|
||||
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
|
||||
BPEvent* pev;
|
||||
cout << "[MyExperiment] Waiting for condition (1) (\"(id1 && id2)"
|
||||
<< " || id3\") to become true..." << endl;
|
||||
bool f1 = false, f2 = false, f3 = false;
|
||||
while(!((f1 && f2) || f3))
|
||||
{
|
||||
pev = simulator.waitAny();
|
||||
cout << "[MyExperiment] Received event id=" << pev->getId()
|
||||
<< "." << endl;
|
||||
if(pev == &ev3)
|
||||
f3 = true;
|
||||
if(pev == &ev2)
|
||||
f2 = true;
|
||||
if(pev == &ev1)
|
||||
f1 = true;
|
||||
}
|
||||
cout << "[MyExperiment] Condition (1) satisfied! Ready..." << endl;
|
||||
// Remove residual (for all active experiments!)
|
||||
// events in the buffer:
|
||||
simulator.clearEvents();
|
||||
BPEvent foobar(ANY_ADDR);
|
||||
foobar.setCounter(400);
|
||||
cout << "[MyExperiment] Adding breakpoint-event, firing after the"
|
||||
<< " next 400 instructions..."; cout.flush();
|
||||
simulator.addEventAndWait(&foobar);
|
||||
cout << "cought! Exiting now." << endl;
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
// 2. Wait for event condition "(id1 && id2) || id3" to become true:
|
||||
BPEvent* pev;
|
||||
cout << "[MyExperiment] Waiting for condition (1) (\"(id1 && id2)"
|
||||
<< " || id3\") to become true..." << endl;
|
||||
bool f1 = false, f2 = false, f3 = false;
|
||||
while (!((f1 && f2) || f3)) {
|
||||
pev = simulator.waitAny();
|
||||
cout << "[MyExperiment] Received event id=" << pev->getId()
|
||||
<< "." << endl;
|
||||
if(pev == &ev3)
|
||||
f3 = true;
|
||||
if(pev == &ev2)
|
||||
f2 = true;
|
||||
if(pev == &ev1)
|
||||
f1 = true;
|
||||
}
|
||||
cout << "[MyExperiment] Condition (1) satisfied! Ready..." << endl;
|
||||
// Remove residual (for all active experiments!)
|
||||
// events in the buffer:
|
||||
simulator.clearEvents();
|
||||
BPEvent foobar(ANY_ADDR);
|
||||
foobar.setCounter(400);
|
||||
cout << "[MyExperiment] Adding breakpoint-event, firing after the"
|
||||
<< " next 400 instructions..."; cout.flush();
|
||||
simulator.addEventAndWait(&foobar);
|
||||
cout << "cought! Exiting now." << endl;
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* __MY_EXPERIMENT_HPP__ */
|
||||
#endif // __MY_EXPERIMENT_HPP__
|
||||
|
||||
@ -1,9 +1,6 @@
|
||||
#ifndef __SINGLE_STEPPING_EXPERIMENT_HPP__
|
||||
#define __SINGLE_STEPPING_EXPERIMENT_HPP__
|
||||
|
||||
// Author: Adrian Böckenkamp
|
||||
// Date: 09.11.2011
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include "../controller/ExperimentFlow.hpp"
|
||||
@ -16,52 +13,48 @@
|
||||
#error Breakpoint-events needed! Enable aspect first (see FailConfig.hpp)!
|
||||
#endif
|
||||
|
||||
using namespace fi;
|
||||
using namespace std;
|
||||
using namespace sal;
|
||||
using namespace fail;
|
||||
|
||||
#define FUNCTION_ENTRY_ADDRESS 0x3c1f
|
||||
|
||||
class SingleSteppingExperiment : public fi::ExperimentFlow
|
||||
{
|
||||
public:
|
||||
bool run()
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
// Wait for function entry adresss:
|
||||
cout << "[SingleSteppingExperiment] Setting up experiment. Allowing"
|
||||
<< " to start now." << endl;
|
||||
BPEvent mainFuncEntry(FUNCTION_ENTRY_ADDRESS);
|
||||
simulator.addEvent(&mainFuncEntry);
|
||||
if(&mainFuncEntry != simulator.waitAny())
|
||||
{
|
||||
cerr << "[SingleSteppingExperiment] Now, we are completely lost!"
|
||||
<< " It's time to cry! :-(" << endl;
|
||||
simulator.clearEvents(this);
|
||||
return false;
|
||||
}
|
||||
cout << "[SingleSteppingExperiment] Entry of main function reached!"
|
||||
<< " Beginning single-stepping..." << endl;
|
||||
char action;
|
||||
while(true)
|
||||
{
|
||||
BPEvent bp(ANY_ADDR);
|
||||
simulator.addEvent(&bp);
|
||||
simulator.waitAny();
|
||||
cout << "0x" << hex
|
||||
<< simulator.getRegisterManager().getInstructionPointer()
|
||||
<< endl;
|
||||
cout << "Continue (y/n)? ";
|
||||
cin >> action; cin.sync(); cin.clear();
|
||||
if(action != 'y')
|
||||
break;
|
||||
}
|
||||
|
||||
class SingleSteppingExperiment : public fail::ExperimentFlow {
|
||||
public:
|
||||
bool run()
|
||||
{
|
||||
/************************************
|
||||
* Description of experiment flow. *
|
||||
************************************/
|
||||
// Wait for function entry adresss:
|
||||
cout << "[SingleSteppingExperiment] Setting up experiment. Allowing"
|
||||
<< " to start now." << endl;
|
||||
BPEvent mainFuncEntry(FUNCTION_ENTRY_ADDRESS);
|
||||
simulator.addEvent(&mainFuncEntry);
|
||||
if (&mainFuncEntry != simulator.waitAny()) {
|
||||
cerr << "[SingleSteppingExperiment] Now, we are completely lost!"
|
||||
<< " It's time to cry! :-(" << endl;
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
cout << "[SingleSteppingExperiment] Entry of main function reached!"
|
||||
<< " Beginning single-stepping..." << endl;
|
||||
char action;
|
||||
while (true) {
|
||||
BPEvent bp(ANY_ADDR);
|
||||
simulator.addEvent(&bp);
|
||||
simulator.waitAny();
|
||||
cout << "0x" << hex
|
||||
<< simulator.getRegisterManager().getInstructionPointer()
|
||||
<< endl;
|
||||
cout << "Continue (y/n)? ";
|
||||
cin >> action; cin.sync(); cin.clear();
|
||||
if (action != 'y')
|
||||
break;
|
||||
}
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* __SINGLE_STEPPING_EXPERIMENT_HPP__ */
|
||||
#endif // __SINGLE_STEPPING_EXPERIMENT_HPP__
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
|
||||
aspect hscsimple {
|
||||
hscsimpleExperiment experiment;
|
||||
advice execution ("void sal::SimulatorController::initExperiments()") : after () {
|
||||
sal::simulator.addFlow(&experiment);
|
||||
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
|
||||
fail::simulator.addFlow(&experiment);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -14,8 +14,8 @@
|
||||
#include "plugins/tracing/TracingPlugin.hpp"
|
||||
char const * const trace_filename = "trace.pb";
|
||||
|
||||
using namespace fi;
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
char const * const results_csv = "chksumoostubs.csv";
|
||||
|
||||
@ -24,9 +24,9 @@ char const * const results_csv = "chksumoostubs.csv";
|
||||
// [i1, i2]: interval of instruction numbers, counted from experiment
|
||||
// begin
|
||||
struct equivalence_class {
|
||||
sal::address_t data_address;
|
||||
address_t data_address;
|
||||
int instr1, instr2;
|
||||
sal::address_t instr2_absolute; // FIXME we could record them all here
|
||||
address_t instr2_absolute; // FIXME we could record them all here
|
||||
};
|
||||
|
||||
bool ChecksumOOStuBSCampaign::run()
|
||||
@ -62,26 +62,26 @@ bool ChecksumOOStuBSCampaign::run()
|
||||
|
||||
// set of equivalence classes that need one (rather: eight, one for
|
||||
// each bit in that byte) experiment to determine them all
|
||||
std::vector<equivalence_class> ecs_need_experiment;
|
||||
vector<equivalence_class> ecs_need_experiment;
|
||||
// set of equivalence classes that need no experiment, because we know
|
||||
// they'd be identical to the golden run
|
||||
std::vector<equivalence_class> ecs_no_effect;
|
||||
vector<equivalence_class> ecs_no_effect;
|
||||
|
||||
equivalence_class current_ec;
|
||||
|
||||
// map for efficient access when results come in
|
||||
std::map<ChecksumOOStuBSExperimentData *, unsigned> experiment_ecs;
|
||||
map<ChecksumOOStuBSExperimentData *, unsigned> experiment_ecs;
|
||||
// experiment count
|
||||
int count = 0;
|
||||
|
||||
// XXX do it the other way around: iterate over trace, search addresses
|
||||
// for every injection address ...
|
||||
for (MemoryMap::iterator it = mm.begin(); it != mm.end(); ++it) {
|
||||
std::cerr << ".";
|
||||
sal::address_t data_address = *it;
|
||||
cerr << ".";
|
||||
address_t data_address = *it;
|
||||
current_ec.instr1 = 0;
|
||||
int instr = 0;
|
||||
sal::address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
|
||||
address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
|
||||
Trace_Event ev;
|
||||
ps.reset();
|
||||
|
||||
@ -136,7 +136,7 @@ bool ChecksumOOStuBSCampaign::run()
|
||||
// store index into ecs_need_experiment
|
||||
experiment_ecs[d] = ecs_need_experiment.size() - 1;
|
||||
|
||||
fi::campaignmanager.addParam(d);
|
||||
campaignmanager.addParam(d);
|
||||
++count;
|
||||
}
|
||||
} else if (ev.accesstype() == ev.WRITE) {
|
||||
@ -173,7 +173,7 @@ bool ChecksumOOStuBSCampaign::run()
|
||||
ecs_no_effect.push_back(current_ec);
|
||||
}
|
||||
|
||||
fi::campaignmanager.noMoreParameters();
|
||||
campaignmanager.noMoreParameters();
|
||||
log << "done enqueueing parameter sets (" << count << ")." << endl;
|
||||
|
||||
log << "equivalence classes generated:"
|
||||
@ -182,11 +182,11 @@ bool ChecksumOOStuBSCampaign::run()
|
||||
|
||||
// statistics
|
||||
unsigned long num_dumb_experiments = 0;
|
||||
for (std::vector<equivalence_class>::const_iterator it = ecs_need_experiment.begin();
|
||||
for (vector<equivalence_class>::const_iterator it = ecs_need_experiment.begin();
|
||||
it != ecs_need_experiment.end(); ++it) {
|
||||
num_dumb_experiments += (*it).instr2 - (*it).instr1 + 1;
|
||||
}
|
||||
for (std::vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
|
||||
for (vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
|
||||
it != ecs_no_effect.end(); ++it) {
|
||||
num_dumb_experiments += (*it).instr2 - (*it).instr1 + 1;
|
||||
}
|
||||
@ -197,7 +197,7 @@ bool ChecksumOOStuBSCampaign::run()
|
||||
results << "ec_instr1\tec_instr2\tec_instr2_absolute\tec_data_address\tbitnr\tresulttype\tresult0\tresult1\tresult2\tfinish_reached\tlatest_ip\terror_corrected\tdetails" << endl;
|
||||
|
||||
// store no-effect "experiment" results
|
||||
for (std::vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
|
||||
for (vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
|
||||
it != ecs_no_effect.end(); ++it) {
|
||||
results
|
||||
<< (*it).instr1 << "\t"
|
||||
@ -215,10 +215,10 @@ bool ChecksumOOStuBSCampaign::run()
|
||||
// collect results
|
||||
ChecksumOOStuBSExperimentData *res;
|
||||
int rescount = 0;
|
||||
while ((res = static_cast<ChecksumOOStuBSExperimentData *>(fi::campaignmanager.getDone()))) {
|
||||
while ((res = static_cast<ChecksumOOStuBSExperimentData *>(campaignmanager.getDone()))) {
|
||||
rescount++;
|
||||
|
||||
std::map<ChecksumOOStuBSExperimentData *, unsigned>::iterator it =
|
||||
map<ChecksumOOStuBSExperimentData *, unsigned>::iterator it =
|
||||
experiment_ecs.find(res);
|
||||
if (it == experiment_ecs.end()) {
|
||||
results << "WTF, didn't find res!" << endl;
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
#ifndef __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__
|
||||
#define __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__
|
||||
#define __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__
|
||||
|
||||
#include "controller/Campaign.hpp"
|
||||
#include "controller/ExperimentData.hpp"
|
||||
#include "checksum-oostubs.pb.h"
|
||||
|
||||
class ChecksumOOStuBSExperimentData : public fi::ExperimentData {
|
||||
class ChecksumOOStuBSExperimentData : public fail::ExperimentData {
|
||||
public:
|
||||
OOStuBSProtoMsg msg;
|
||||
ChecksumOOStuBSExperimentData() : fi::ExperimentData(&msg) {}
|
||||
ChecksumOOStuBSExperimentData() : fail::ExperimentData(&msg) {}
|
||||
};
|
||||
|
||||
class ChecksumOOStuBSCampaign : public fi::Campaign {
|
||||
class ChecksumOOStuBSCampaign : public fail::Campaign {
|
||||
public:
|
||||
virtual bool run();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__
|
||||
|
||||
@ -5,11 +5,9 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "util/Logger.hpp"
|
||||
|
||||
#include "experiment.hpp"
|
||||
#include "experimentInfo.hpp"
|
||||
#include "campaign.hpp"
|
||||
|
||||
#include "SAL/SALConfig.hpp"
|
||||
#include "SAL/SALInst.hpp"
|
||||
#include "SAL/Memory.hpp"
|
||||
@ -21,7 +19,8 @@
|
||||
|
||||
#include "ecc_region.hpp"
|
||||
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
// Check if configuration dependencies are satisfied:
|
||||
#if !defined(CONFIG_EVENT_BREAKPOINTS) || !defined(CONFIG_SR_RESTORE) || \
|
||||
@ -33,33 +32,33 @@ bool ChecksumOOStuBSExperiment::run()
|
||||
{
|
||||
char const *statename = "checksum-oostubs.state";
|
||||
Logger log("Checksum-OOStuBS", false);
|
||||
fi::BPSingleEvent bp;
|
||||
BPSingleEvent bp;
|
||||
|
||||
log << "startup" << endl;
|
||||
|
||||
#if 1
|
||||
// STEP 0: record memory map with addresses of "interesting" objects
|
||||
fi::GuestEvent g;
|
||||
GuestEvent g;
|
||||
while (true) {
|
||||
sal::simulator.addEventAndWait(&g);
|
||||
std::cout << g.getData() << std::flush;
|
||||
simulator.addEventAndWait(&g);
|
||||
cout << g.getData() << flush;
|
||||
}
|
||||
#elif 0
|
||||
// STEP 1: run until interesting function starts, and save state
|
||||
bp.setWatchInstructionPointer(OOSTUBS_FUNC_ENTRY);
|
||||
sal::simulator.addEventAndWait(&bp);
|
||||
simulator.addEventAndWait(&bp);
|
||||
log << "test function entry reached, saving state" << endl;
|
||||
log << "EIP = " << std::hex << bp.getTriggerInstructionPointer() << endl;
|
||||
log << "error_corrected = " << std::dec << ((int)sal::simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED)) << endl;
|
||||
sal::simulator.save(statename);
|
||||
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << endl;
|
||||
log << "error_corrected = " << dec << ((int)simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED)) << endl;
|
||||
simulator.save(statename);
|
||||
assert(bp.getTriggerInstructionPointer() == OOSTUBS_FUNC_ENTRY);
|
||||
assert(sal::simulator.getRegisterManager().getInstructionPointer() == OOSTUBS_FUNC_ENTRY);
|
||||
assert(simulator.getRegisterManager().getInstructionPointer() == OOSTUBS_FUNC_ENTRY);
|
||||
#elif 1
|
||||
// STEP 2: record trace for fault-space pruning
|
||||
log << "restoring state" << endl;
|
||||
sal::simulator.restore(statename);
|
||||
log << "EIP = " << std::hex << sal::simulator.getRegisterManager().getInstructionPointer() << endl;
|
||||
assert(sal::simulator.getRegisterManager().getInstructionPointer() == OOSTUBS_FUNC_ENTRY);
|
||||
simulator.restore(statename);
|
||||
log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
|
||||
assert(simulator.getRegisterManager().getInstructionPointer() == OOSTUBS_FUNC_ENTRY);
|
||||
|
||||
log << "enabling tracing" << endl;
|
||||
TracingPlugin tp;
|
||||
@ -73,37 +72,37 @@ bool ChecksumOOStuBSExperiment::run()
|
||||
|
||||
// record trace
|
||||
char const *tracefile = "trace.pb";
|
||||
std::ofstream of(tracefile);
|
||||
ofstream of(tracefile);
|
||||
tp.setTraceFile(&of);
|
||||
|
||||
// this must be done *after* configuring the plugin:
|
||||
sal::simulator.addFlow(&tp);
|
||||
simulator.addFlow(&tp);
|
||||
|
||||
bp.setWatchInstructionPointer(fi::ANY_ADDR);
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
bp.setCounter(OOSTUBS_NUMINSTR);
|
||||
sal::simulator.addEvent(&bp);
|
||||
fi::BPSingleEvent func_finish(OOSTUBS_FUNC_FINISH);
|
||||
sal::simulator.addEvent(&func_finish);
|
||||
simulator.addEvent(&bp);
|
||||
BPSingleEvent func_finish(OOSTUBS_FUNC_FINISH);
|
||||
simulator.addEvent(&func_finish);
|
||||
|
||||
if (sal::simulator.waitAny() == &func_finish) {
|
||||
if (simulator.waitAny() == &func_finish) {
|
||||
log << "experiment reached finish()" << endl;
|
||||
// FIXME add instruction counter to SimulatorController
|
||||
sal::simulator.waitAny();
|
||||
simulator.waitAny();
|
||||
}
|
||||
log << "experiment finished after " << std::dec << OOSTUBS_NUMINSTR << " instructions" << endl;
|
||||
log << "experiment finished after " << dec << OOSTUBS_NUMINSTR << " instructions" << endl;
|
||||
|
||||
uint32_t results[OOSTUBS_RESULTS_BYTES / sizeof(uint32_t)];
|
||||
sal::simulator.getMemoryManager().getBytes(OOSTUBS_RESULTS_ADDR, sizeof(results), results);
|
||||
simulator.getMemoryManager().getBytes(OOSTUBS_RESULTS_ADDR, sizeof(results), results);
|
||||
for (unsigned i = 0; i < sizeof(results) / sizeof(*results); ++i) {
|
||||
log << "results[" << i << "]: " << std::dec << results[i] << endl;
|
||||
log << "results[" << i << "]: " << dec << results[i] << endl;
|
||||
}
|
||||
|
||||
sal::simulator.removeFlow(&tp);
|
||||
simulator.removeFlow(&tp);
|
||||
|
||||
// serialize trace to file
|
||||
if (of.fail()) {
|
||||
log << "failed to write " << tracefile << endl;
|
||||
sal::simulator.clearEvents(this);
|
||||
simulator.clearEvents(this);
|
||||
return false;
|
||||
}
|
||||
of.close();
|
||||
@ -117,7 +116,7 @@ bool ChecksumOOStuBSExperiment::run()
|
||||
|
||||
// STEP 3: The actual experiment.
|
||||
log << "restoring state" << endl;
|
||||
sal::simulator.restore(statename);
|
||||
simulator.restore(statename);
|
||||
|
||||
// get an experiment parameter set
|
||||
log << "asking job server for experiment parameters" << endl;
|
||||
@ -125,7 +124,7 @@ bool ChecksumOOStuBSExperiment::run()
|
||||
if (!m_jc.getParam(param)) {
|
||||
log << "Dying." << endl;
|
||||
// communicate that we were told to die
|
||||
sal::simulator.terminate(1);
|
||||
simulator.terminate(1);
|
||||
}
|
||||
/*
|
||||
// XXX debug
|
||||
@ -142,49 +141,49 @@ bool ChecksumOOStuBSExperiment::run()
|
||||
log << "job " << id << " instr " << instr_offset << " mem " << mem_addr << "+" << bit_offset << endl;
|
||||
|
||||
// XXX debug
|
||||
std::stringstream fname;
|
||||
stringstream fname;
|
||||
fname << "job." << ::getpid();
|
||||
std::ofstream job(fname.str().c_str());
|
||||
ofstream job(fname.str().c_str());
|
||||
job << "job " << id << " instr " << instr_offset << " (" << param.msg.instr_address() << ") mem " << mem_addr << "+" << bit_offset << endl;
|
||||
job.close();
|
||||
|
||||
// reaching finish() could happen before OR after FI
|
||||
fi::BPSingleEvent func_finish(OOSTUBS_FUNC_FINISH);
|
||||
sal::simulator.addEvent(&func_finish);
|
||||
BPSingleEvent func_finish(OOSTUBS_FUNC_FINISH);
|
||||
simulator.addEvent(&func_finish);
|
||||
bool finish_reached = false;
|
||||
|
||||
// no need to wait if offset is 0
|
||||
if (instr_offset > 0) {
|
||||
// XXX test this with coolchecksum first (or reassure with sanity checks)
|
||||
// XXX could be improved with intermediate states (reducing runtime until injection)
|
||||
bp.setWatchInstructionPointer(fi::ANY_ADDR);
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
bp.setCounter(instr_offset);
|
||||
sal::simulator.addEvent(&bp);
|
||||
simulator.addEvent(&bp);
|
||||
|
||||
// finish() before FI?
|
||||
if (sal::simulator.waitAny() == &func_finish) {
|
||||
if (simulator.waitAny() == &func_finish) {
|
||||
finish_reached = true;
|
||||
log << "experiment reached finish() before FI" << endl;
|
||||
|
||||
// wait for bp
|
||||
sal::simulator.waitAny();
|
||||
simulator.waitAny();
|
||||
}
|
||||
}
|
||||
|
||||
// --- fault injection ---
|
||||
sal::MemoryManager& mm = sal::simulator.getMemoryManager();
|
||||
sal::byte_t data = mm.getByte(mem_addr);
|
||||
sal::byte_t newdata = data ^ (1 << bit_offset);
|
||||
MemoryManager& mm = simulator.getMemoryManager();
|
||||
byte_t data = mm.getByte(mem_addr);
|
||||
byte_t newdata = data ^ (1 << bit_offset);
|
||||
mm.setByte(mem_addr, newdata);
|
||||
// note at what IP we did it
|
||||
int32_t injection_ip = sal::simulator.getRegisterManager().getInstructionPointer();
|
||||
int32_t injection_ip = simulator.getRegisterManager().getInstructionPointer();
|
||||
param.msg.set_injection_ip(injection_ip);
|
||||
log << "fault injected @ ip " << injection_ip
|
||||
<< " 0x" << std::hex << ((int)data) << " -> 0x" << ((int)newdata) << endl;
|
||||
<< " 0x" << hex << ((int)data) << " -> 0x" << ((int)newdata) << endl;
|
||||
// sanity check
|
||||
if (param.msg.has_instr_address() &&
|
||||
injection_ip != param.msg.instr_address()) {
|
||||
std::stringstream ss;
|
||||
stringstream ss;
|
||||
ss << "SANITY CHECK FAILED: " << injection_ip
|
||||
<< " != " << param.msg.instr_address();
|
||||
log << ss.str() << endl;
|
||||
@ -192,7 +191,7 @@ bool ChecksumOOStuBSExperiment::run()
|
||||
param.msg.set_latest_ip(injection_ip);
|
||||
param.msg.set_details(ss.str());
|
||||
|
||||
sal::simulator.clearEvents();
|
||||
simulator.clearEvents();
|
||||
m_jc.sendResult(param);
|
||||
continue;
|
||||
}
|
||||
@ -209,27 +208,27 @@ bool ChecksumOOStuBSExperiment::run()
|
||||
// * a correct result[0-2]
|
||||
|
||||
// catch traps as "extraordinary" ending
|
||||
fi::TrapEvent ev_trap(fi::ANY_TRAP);
|
||||
sal::simulator.addEvent(&ev_trap);
|
||||
TrapEvent ev_trap(ANY_TRAP);
|
||||
simulator.addEvent(&ev_trap);
|
||||
// OOStuBS' way to terminally halt (CLI+HLT)
|
||||
fi::BPSingleEvent ev_halt(OOSTUBS_FUNC_CPU_HALT);
|
||||
sal::simulator.addEvent(&ev_halt);
|
||||
BPSingleEvent ev_halt(OOSTUBS_FUNC_CPU_HALT);
|
||||
simulator.addEvent(&ev_halt);
|
||||
// remaining instructions until "normal" ending
|
||||
fi::BPSingleEvent ev_done(fi::ANY_ADDR);
|
||||
BPSingleEvent ev_done(ANY_ADDR);
|
||||
ev_done.setCounter(OOSTUBS_NUMINSTR + OOSTUBS_RECOVERYINSTR - instr_offset);
|
||||
sal::simulator.addEvent(&ev_done);
|
||||
simulator.addEvent(&ev_done);
|
||||
|
||||
/*
|
||||
// XXX debug
|
||||
log << "enabling tracing" << endl;
|
||||
TracingPlugin tp;
|
||||
tp.setLogIPOnly(true);
|
||||
tp.setOstream(&std::cout);
|
||||
tp.setOstream(&cout);
|
||||
// this must be done *after* configuring the plugin:
|
||||
sal::simulator.addFlow(&tp);
|
||||
simulator.addFlow(&tp);
|
||||
*/
|
||||
|
||||
fi::BaseEvent* ev = sal::simulator.waitAny();
|
||||
BaseEvent* ev = simulator.waitAny();
|
||||
|
||||
// Do we reach finish() while waiting for ev_trap/ev_done?
|
||||
if (ev == &func_finish) {
|
||||
@ -237,40 +236,40 @@ bool ChecksumOOStuBSExperiment::run()
|
||||
log << "experiment reached finish()" << endl;
|
||||
|
||||
// wait for ev_trap/ev_done
|
||||
ev = sal::simulator.waitAny();
|
||||
ev = simulator.waitAny();
|
||||
}
|
||||
|
||||
// record resultdata, finish_reached and error_corrected regardless of result
|
||||
uint32_t results[OOSTUBS_RESULTS_BYTES / sizeof(uint32_t)];
|
||||
sal::simulator.getMemoryManager().getBytes(OOSTUBS_RESULTS_ADDR, sizeof(results), results);
|
||||
simulator.getMemoryManager().getBytes(OOSTUBS_RESULTS_ADDR, sizeof(results), results);
|
||||
for (unsigned i = 0; i < sizeof(results) / sizeof(*results); ++i) {
|
||||
log << "results[" << i << "]: " << std::dec << results[i] << endl;
|
||||
log << "results[" << i << "]: " << dec << results[i] << endl;
|
||||
param.msg.add_resultdata(results[i]);
|
||||
}
|
||||
param.msg.set_finish_reached(finish_reached);
|
||||
int32_t error_corrected = sal::simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED);
|
||||
int32_t error_corrected = simulator.getMemoryManager().getByte(OOSTUBS_ERROR_CORRECTED);
|
||||
param.msg.set_error_corrected(error_corrected);
|
||||
param.msg.set_latest_ip(sal::simulator.getRegisterManager().getInstructionPointer());
|
||||
param.msg.set_latest_ip(simulator.getRegisterManager().getInstructionPointer());
|
||||
|
||||
if (ev == &ev_done) {
|
||||
log << std::dec << "Result FINISHED" << endl;
|
||||
log << dec << "Result FINISHED" << endl;
|
||||
param.msg.set_resulttype(param.msg.FINISHED);
|
||||
} else if (ev == &ev_halt) {
|
||||
log << std::dec << "Result HALT" << endl;
|
||||
log << dec << "Result HALT" << endl;
|
||||
param.msg.set_resulttype(param.msg.HALT);
|
||||
} else if (ev == &ev_trap) {
|
||||
log << std::dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
|
||||
log << dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
|
||||
param.msg.set_resulttype(param.msg.TRAP);
|
||||
|
||||
std::stringstream ss;
|
||||
stringstream ss;
|
||||
ss << ev_trap.getTriggerNumber();
|
||||
param.msg.set_details(ss.str());
|
||||
} else {
|
||||
log << std::dec << "Result WTF?" << endl;
|
||||
log << dec << "Result WTF?" << endl;
|
||||
param.msg.set_resulttype(param.msg.UNKNOWN);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "eventid " << ev->getId() << " EIP " << sal::simulator.getRegisterManager().getInstructionPointer();
|
||||
stringstream ss;
|
||||
ss << "eventid " << ev->getId() << " EIP " << simulator.getRegisterManager().getInstructionPointer();
|
||||
param.msg.set_details(ss.str());
|
||||
}
|
||||
m_jc.sendResult(param);
|
||||
@ -278,5 +277,5 @@ bool ChecksumOOStuBSExperiment::run()
|
||||
}
|
||||
#endif
|
||||
// Explicitly terminate, or the simulator will continue to run.
|
||||
sal::simulator.terminate();
|
||||
simulator.terminate();
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
#ifndef __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__
|
||||
#define __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__
|
||||
#define __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__
|
||||
|
||||
#include "controller/ExperimentFlow.hpp"
|
||||
#include "jobserver/JobClient.hpp"
|
||||
|
||||
class ChecksumOOStuBSExperiment : public fi::ExperimentFlow {
|
||||
fi::JobClient m_jc;
|
||||
class ChecksumOOStuBSExperiment : public fail::ExperimentFlow {
|
||||
fail::JobClient m_jc;
|
||||
public:
|
||||
ChecksumOOStuBSExperiment() : m_jc("ios.cs.tu-dortmund.de") {}
|
||||
bool run();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef __EXPERIMENT_INFO_HPP__
|
||||
#define __EXPERIMENT_INFO_HPP__
|
||||
#define __EXPERIMENT_INFO_HPP__
|
||||
|
||||
// FIXME autogenerate this
|
||||
|
||||
@ -48,4 +48,4 @@
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif // __EXPERIMENT_INFO_HPP__
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
ChecksumOOStuBSCampaign c;
|
||||
if (fi::campaignmanager.runCampaign(&c)) {
|
||||
if (fail::campaignmanager.runCampaign(&c)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
|
||||
@ -12,8 +12,8 @@
|
||||
char const * const trace_filename = "trace.pb";
|
||||
#endif
|
||||
|
||||
using namespace fi;
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
char const * const results_csv = "coolcampaign.csv";
|
||||
|
||||
@ -24,7 +24,7 @@ char const * const results_csv = "coolcampaign.csv";
|
||||
struct equivalence_class {
|
||||
unsigned byte_offset;
|
||||
int instr1, instr2;
|
||||
sal::address_t instr2_absolute; // FIXME we could record them all here
|
||||
address_t instr2_absolute; // FIXME we could record them all here
|
||||
};
|
||||
|
||||
bool CoolChecksumCampaign::run()
|
||||
@ -52,18 +52,18 @@ bool CoolChecksumCampaign::run()
|
||||
d->msg.set_instr_offset(instr_offset);
|
||||
d->msg.set_bit_offset(bit_offset);
|
||||
|
||||
fi::campaignmanager.addParam(d);
|
||||
campaignmanager.addParam(d);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
fi::campaignmanager.noMoreParameters();
|
||||
campaignmanager.noMoreParameters();
|
||||
log << "done enqueueing parameter sets (" << count << ")." << endl;
|
||||
|
||||
// collect results
|
||||
CoolChecksumExperimentData *res;
|
||||
int rescount = 0;
|
||||
results << "injection_ip\tinstr_offset\tinjection_bit\tresulttype\tresultdata\terror_corrected\tdetails" << endl;
|
||||
while ((res = static_cast<CoolChecksumExperimentData *>(fi::campaignmanager.getDone()))) {
|
||||
while ((res = static_cast<CoolChecksumExperimentData *>(campaignmanager.getDone()))) {
|
||||
rescount++;
|
||||
|
||||
results
|
||||
@ -87,10 +87,10 @@ bool CoolChecksumCampaign::run()
|
||||
|
||||
// set of equivalence classes that need one (rather: eight, one for
|
||||
// each bit in that byte) experiment to determine them all
|
||||
std::vector<equivalence_class> ecs_need_experiment;
|
||||
vector<equivalence_class> ecs_need_experiment;
|
||||
// set of equivalence classes that need no experiment, because we know
|
||||
// they'd be identical to the golden run
|
||||
std::vector<equivalence_class> ecs_no_effect;
|
||||
vector<equivalence_class> ecs_no_effect;
|
||||
|
||||
equivalence_class current_ec;
|
||||
|
||||
@ -103,7 +103,7 @@ bool CoolChecksumCampaign::run()
|
||||
// accesses to that address ...
|
||||
// XXX reorganizing the trace for efficient seeks could speed this up
|
||||
int instr = 0;
|
||||
sal::address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
|
||||
address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
|
||||
Trace_Event ev;
|
||||
ps.reset();
|
||||
|
||||
@ -180,11 +180,11 @@ bool CoolChecksumCampaign::run()
|
||||
|
||||
// statistics
|
||||
int num_dumb_experiments = 0;
|
||||
for (std::vector<equivalence_class>::const_iterator it = ecs_need_experiment.begin();
|
||||
for (vector<equivalence_class>::const_iterator it = ecs_need_experiment.begin();
|
||||
it != ecs_need_experiment.end(); ++it) {
|
||||
num_dumb_experiments += (*it).instr2 - (*it).instr1 + 1;
|
||||
}
|
||||
for (std::vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
|
||||
for (vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
|
||||
it != ecs_no_effect.end(); ++it) {
|
||||
num_dumb_experiments += (*it).instr2 - (*it).instr1 + 1;
|
||||
}
|
||||
@ -192,9 +192,9 @@ bool CoolChecksumCampaign::run()
|
||||
" experiments to " << ecs_need_experiment.size() * 8 << endl;
|
||||
|
||||
// map for efficient access when results come in
|
||||
std::map<CoolChecksumExperimentData *, equivalence_class *> experiment_ecs;
|
||||
map<CoolChecksumExperimentData *, equivalence_class *> experiment_ecs;
|
||||
int count = 0;
|
||||
for (std::vector<equivalence_class>::iterator it = ecs_need_experiment.begin();
|
||||
for (vector<equivalence_class>::iterator it = ecs_need_experiment.begin();
|
||||
it != ecs_need_experiment.end(); ++it) {
|
||||
for (int bitnr = 0; bitnr < 8; ++bitnr) {
|
||||
CoolChecksumExperimentData *d = new CoolChecksumExperimentData;
|
||||
@ -205,11 +205,11 @@ bool CoolChecksumCampaign::run()
|
||||
|
||||
experiment_ecs[d] = &(*it);
|
||||
|
||||
fi::campaignmanager.addParam(d);
|
||||
campaignmanager.addParam(d);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
fi::campaignmanager.noMoreParameters();
|
||||
campaignmanager.noMoreParameters();
|
||||
log << "done enqueueing parameter sets (" << count << ")." << endl;
|
||||
|
||||
// CSV header
|
||||
@ -217,7 +217,7 @@ bool CoolChecksumCampaign::run()
|
||||
|
||||
// store no-effect "experiment" results
|
||||
// (for comparison reasons; we'll store that more compactly later)
|
||||
for (std::vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
|
||||
for (vector<equivalence_class>::const_iterator it = ecs_no_effect.begin();
|
||||
it != ecs_no_effect.end(); ++it) {
|
||||
for (int bitnr = 0; bitnr < 8; ++bitnr) {
|
||||
for (int instr = (*it).instr1; instr <= (*it).instr2; ++instr) {
|
||||
@ -236,7 +236,7 @@ bool CoolChecksumCampaign::run()
|
||||
// collect results
|
||||
CoolChecksumExperimentData *res;
|
||||
int rescount = 0;
|
||||
while ((res = static_cast<CoolChecksumExperimentData *>(fi::campaignmanager.getDone()))) {
|
||||
while ((res = static_cast<CoolChecksumExperimentData *>(campaignmanager.getDone()))) {
|
||||
rescount++;
|
||||
|
||||
equivalence_class *ec = experiment_ecs[res];
|
||||
|
||||
@ -1,20 +1,19 @@
|
||||
#ifndef __COOLCAMPAIGN_HPP__
|
||||
#define __COOLCAMPAIGN_HPP__
|
||||
#define __COOLCAMPAIGN_HPP__
|
||||
|
||||
#include "controller/Campaign.hpp"
|
||||
#include "controller/ExperimentData.hpp"
|
||||
#include "coolchecksum.pb.h"
|
||||
|
||||
class CoolChecksumExperimentData : public fi::ExperimentData {
|
||||
class CoolChecksumExperimentData : public fail::ExperimentData {
|
||||
public:
|
||||
CoolChecksumProtoMsg msg;
|
||||
CoolChecksumExperimentData() : fi::ExperimentData(&msg) {}
|
||||
CoolChecksumExperimentData() : fail::ExperimentData(&msg) {}
|
||||
};
|
||||
|
||||
|
||||
class CoolChecksumCampaign : public fi::Campaign {
|
||||
class CoolChecksumCampaign : public fail::Campaign {
|
||||
public:
|
||||
virtual bool run();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __COOLCAMPAIGN_HPP__
|
||||
|
||||
@ -1,11 +1,9 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "util/Logger.hpp"
|
||||
|
||||
#include "experiment.hpp"
|
||||
#include "experimentInfo.hpp"
|
||||
#include "campaign.hpp"
|
||||
|
||||
#include "SAL/SALConfig.hpp"
|
||||
#include "SAL/SALInst.hpp"
|
||||
#include "SAL/Memory.hpp"
|
||||
@ -19,7 +17,8 @@
|
||||
|
||||
#include "coolchecksum.pb.h"
|
||||
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
// Check if configuration dependencies are satisfied:
|
||||
#if !defined(CONFIG_EVENT_BREAKPOINTS) || !defined(CONFIG_SR_RESTORE) || \
|
||||
@ -31,24 +30,24 @@ using std::endl;
|
||||
bool CoolChecksumExperiment::run()
|
||||
{
|
||||
Logger log("CoolChecksum", false);
|
||||
fi::BPSingleEvent bp;
|
||||
BPSingleEvent bp;
|
||||
|
||||
log << "startup" << endl;
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
// STEP 1: run until interesting function starts, and save state
|
||||
bp.setWatchInstructionPointer(COOL_ECC_FUNC_ENTRY);
|
||||
sal::simulator.addEventAndWait(&bp);
|
||||
simulator.addEventAndWait(&bp);
|
||||
log << "test function entry reached, saving state" << endl;
|
||||
log << "EIP = " << std::hex << bp.getTriggerInstructionPointer() << " or " << sal::simulator.getRegisterManager().getInstructionPointer() << endl;
|
||||
log << "error_corrected = " << std::dec << ((int)sal::simulator.getMemoryManager().getByte(COOL_ECC_ERROR_CORRECTED)) << endl;
|
||||
sal::simulator.save("coolecc.state");
|
||||
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << " or " << simulator.getRegisterManager().getInstructionPointer() << endl;
|
||||
log << "error_corrected = " << dec << ((int)simulator.getMemoryManager().getByte(COOL_ECC_ERROR_CORRECTED)) << endl;
|
||||
simulator.save("coolecc.state");
|
||||
#elif 0
|
||||
|
||||
// STEP 2: determine # instructions from start to end
|
||||
log << "restoring state" << endl;
|
||||
sal::simulator.restore("coolecc.state");
|
||||
log << "EIP = " << std::hex << sal::simulator.getRegisterManager().getInstructionPointer() << endl;
|
||||
simulator.restore("coolecc.state");
|
||||
log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
|
||||
|
||||
#if COOL_FAULTSPACE_PRUNING
|
||||
// STEP 2.5: Additionally do a golden run with memory access tracing
|
||||
@ -62,33 +61,33 @@ bool CoolChecksumExperiment::run()
|
||||
tp.restrictMemoryAddresses(&mm);
|
||||
|
||||
// record trace
|
||||
std::ofstream of("trace.pb");
|
||||
ofstream of("trace.pb");
|
||||
tp.setTraceFile(&of);
|
||||
|
||||
// this must be done *after* configuring the plugin:
|
||||
sal::simulator.addFlow(&tp);
|
||||
simulator.addFlow(&tp);
|
||||
#endif
|
||||
|
||||
// make sure the timer interrupt doesn't disturb us
|
||||
sal::simulator.addSuppressedInterrupt(0);
|
||||
simulator.addSuppressedInterrupt(0);
|
||||
|
||||
int count;
|
||||
bp.setWatchInstructionPointer(fi::ANY_ADDR);
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
for (count = 0; bp.getTriggerInstructionPointer() != COOL_ECC_CALCDONE; ++count) {
|
||||
sal::simulator.addEventAndWait(&bp);
|
||||
// log << "EIP = " << std::hex << sal::simulator.getRegisterManager().getInstructionPointer() << endl;
|
||||
simulator.addEventAndWait(&bp);
|
||||
// log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
|
||||
}
|
||||
log << "test function calculation position reached after " << std::dec << count << " instructions" << endl;
|
||||
sal::Register* reg = sal::simulator.getRegisterManager().getRegister(sal::RID_CDX);
|
||||
log << std::dec << reg->getName() << " = " << reg->getData() << endl;
|
||||
log << "test function calculation position reached after " << dec << count << " instructions" << endl;
|
||||
Register* reg = simulator.getRegisterManager().getRegister(RID_CDX);
|
||||
log << dec << reg->getName() << " = " << reg->getData() << endl;
|
||||
|
||||
#if COOL_FAULTSPACE_PRUNING
|
||||
sal::simulator.removeFlow(&tp);
|
||||
simulator.removeFlow(&tp);
|
||||
|
||||
// serialize trace to file
|
||||
if (of.fail()) {
|
||||
log << "failed to write trace.pb" << endl;
|
||||
sal::simulator.clearEvents(this);
|
||||
simulator.clearEvents(this);
|
||||
return false;
|
||||
}
|
||||
of.close();
|
||||
@ -102,14 +101,14 @@ bool CoolChecksumExperiment::run()
|
||||
|
||||
// STEP 3: The actual experiment.
|
||||
log << "restoring state" << endl;
|
||||
sal::simulator.restore("coolecc.state");
|
||||
simulator.restore("coolecc.state");
|
||||
|
||||
log << "asking job server for experiment parameters" << endl;
|
||||
CoolChecksumExperimentData param;
|
||||
if (!m_jc.getParam(param)) {
|
||||
log << "Dying." << endl;
|
||||
// communicate that we were told to die
|
||||
sal::simulator.terminate(1);
|
||||
simulator.terminate(1);
|
||||
}
|
||||
int id = param.getWorkloadID();
|
||||
int instr_offset = param.msg.instr_offset();
|
||||
@ -119,28 +118,28 @@ bool CoolChecksumExperiment::run()
|
||||
// FIXME could be improved (especially for backends supporting
|
||||
// breakpoints natively) by utilizing a previously recorded instruction
|
||||
// trace
|
||||
bp.setWatchInstructionPointer(fi::ANY_ADDR);
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
for (int count = 0; count < instr_offset; ++count) {
|
||||
sal::simulator.addEventAndWait(&bp);
|
||||
simulator.addEventAndWait(&bp);
|
||||
}
|
||||
|
||||
// inject
|
||||
sal::guest_address_t inject_addr = COOL_ECC_OBJUNDERTEST + bit_offset / 8;
|
||||
sal::MemoryManager& mm = sal::simulator.getMemoryManager();
|
||||
sal::byte_t data = mm.getByte(inject_addr);
|
||||
sal::byte_t newdata = data ^ (1 << (bit_offset % 8));
|
||||
guest_address_t inject_addr = COOL_ECC_OBJUNDERTEST + bit_offset / 8;
|
||||
MemoryManager& mm = simulator.getMemoryManager();
|
||||
byte_t data = mm.getByte(inject_addr);
|
||||
byte_t newdata = data ^ (1 << (bit_offset % 8));
|
||||
mm.setByte(inject_addr, newdata);
|
||||
// note at what IP we did it
|
||||
int32_t injection_ip = sal::simulator.getRegisterManager().getInstructionPointer();
|
||||
int32_t injection_ip = simulator.getRegisterManager().getInstructionPointer();
|
||||
param.msg.set_injection_ip(injection_ip);
|
||||
log << "inject @ ip " << injection_ip
|
||||
<< " (offset " << std::dec << instr_offset << ")"
|
||||
<< " (offset " << dec << instr_offset << ")"
|
||||
<< " bit " << bit_offset << ": 0x"
|
||||
<< std::hex << ((int)data) << " -> 0x" << ((int)newdata) << endl;
|
||||
<< hex << ((int)data) << " -> 0x" << ((int)newdata) << endl;
|
||||
// sanity check (only works if we're working with an instruction trace)
|
||||
if (param.msg.has_instr_address() &&
|
||||
injection_ip != param.msg.instr_address()) {
|
||||
std::stringstream ss;
|
||||
stringstream ss;
|
||||
ss << "SANITY CHECK FAILED: " << injection_ip
|
||||
<< " != " << param.msg.instr_address() << endl;
|
||||
log << ss.str();
|
||||
@ -148,55 +147,55 @@ bool CoolChecksumExperiment::run()
|
||||
param.msg.set_resultdata(injection_ip);
|
||||
param.msg.set_details(ss.str());
|
||||
|
||||
sal::simulator.clearEvents();
|
||||
simulator.clearEvents();
|
||||
m_jc.sendResult(param);
|
||||
continue;
|
||||
}
|
||||
|
||||
// aftermath
|
||||
fi::BPSingleEvent ev_done(COOL_ECC_CALCDONE);
|
||||
sal::simulator.addEvent(&ev_done);
|
||||
fi::BPSingleEvent ev_timeout(fi::ANY_ADDR);
|
||||
BPSingleEvent ev_done(COOL_ECC_CALCDONE);
|
||||
simulator.addEvent(&ev_done);
|
||||
BPSingleEvent ev_timeout(ANY_ADDR);
|
||||
ev_timeout.setCounter(COOL_ECC_NUMINSTR + 3000);
|
||||
sal::simulator.addEvent(&ev_timeout);
|
||||
fi::TrapEvent ev_trap(fi::ANY_TRAP);
|
||||
sal::simulator.addEvent(&ev_trap);
|
||||
simulator.addEvent(&ev_timeout);
|
||||
TrapEvent ev_trap(ANY_TRAP);
|
||||
simulator.addEvent(&ev_trap);
|
||||
|
||||
fi::BaseEvent* ev = sal::simulator.waitAny();
|
||||
BaseEvent* ev = simulator.waitAny();
|
||||
if (ev == &ev_done) {
|
||||
sal::Register* pRegRes = sal::simulator.getRegisterManager().getRegister(sal::RID_CDX);
|
||||
Register* pRegRes = simulator.getRegisterManager().getRegister(RID_CDX);
|
||||
int32_t data = pRegRes->getData();
|
||||
log << std::dec << "Result " << pRegRes->getName() << " = " << data << endl;
|
||||
log << dec << "Result " << pRegRes->getName() << " = " << data << endl;
|
||||
param.msg.set_resulttype(param.msg.CALCDONE);
|
||||
param.msg.set_resultdata(data);
|
||||
} else if (ev == &ev_timeout) {
|
||||
log << std::dec << "Result TIMEOUT" << endl;
|
||||
log << dec << "Result TIMEOUT" << endl;
|
||||
param.msg.set_resulttype(param.msg.TIMEOUT);
|
||||
param.msg.set_resultdata(sal::simulator.getRegisterManager().getInstructionPointer());
|
||||
param.msg.set_resultdata(simulator.getRegisterManager().getInstructionPointer());
|
||||
} else if (ev == &ev_trap) {
|
||||
log << std::dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
|
||||
log << dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
|
||||
param.msg.set_resulttype(param.msg.TRAP);
|
||||
param.msg.set_resultdata(sal::simulator.getRegisterManager().getInstructionPointer());
|
||||
param.msg.set_resultdata(simulator.getRegisterManager().getInstructionPointer());
|
||||
} else {
|
||||
log << std::dec << "Result WTF?" << endl;
|
||||
log << dec << "Result WTF?" << endl;
|
||||
param.msg.set_resulttype(param.msg.UNKNOWN);
|
||||
param.msg.set_resultdata(sal::simulator.getRegisterManager().getInstructionPointer());
|
||||
param.msg.set_resultdata(simulator.getRegisterManager().getInstructionPointer());
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "eventid " << ev << " EIP " << sal::simulator.getRegisterManager().getInstructionPointer();
|
||||
stringstream ss;
|
||||
ss << "eventid " << ev << " EIP " << simulator.getRegisterManager().getInstructionPointer();
|
||||
param.msg.set_details(ss.str());
|
||||
}
|
||||
sal::simulator.clearEvents();
|
||||
int32_t error_corrected = sal::simulator.getMemoryManager().getByte(COOL_ECC_ERROR_CORRECTED);
|
||||
simulator.clearEvents();
|
||||
int32_t error_corrected = simulator.getMemoryManager().getByte(COOL_ECC_ERROR_CORRECTED);
|
||||
param.msg.set_error_corrected(error_corrected);
|
||||
m_jc.sendResult(param);
|
||||
}
|
||||
|
||||
// we do not want the simulator to continue running, especially for
|
||||
// headless and distributed experiments
|
||||
sal::simulator.terminate();
|
||||
simulator.terminate();
|
||||
#endif
|
||||
// simulator continues to run
|
||||
sal::simulator.clearEvents(this);
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
#ifndef __COOLEXPERIMENT_HPP__
|
||||
#define __COOLEXPERIMENT_HPP__
|
||||
#define __COOLEXPERIMENT_HPP__
|
||||
|
||||
#include "controller/ExperimentFlow.hpp"
|
||||
#include "jobserver/JobClient.hpp"
|
||||
|
||||
class CoolChecksumExperiment : public fi::ExperimentFlow {
|
||||
fi::JobClient m_jc;
|
||||
class CoolChecksumExperiment : public fail::ExperimentFlow {
|
||||
fail::JobClient m_jc;
|
||||
public:
|
||||
CoolChecksumExperiment() : m_jc("ios.cs.tu-dortmund.de") {}
|
||||
bool run();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __COOLEXPERIMENT_HPP__
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef __EXPERIMENT_INFO_HPP__
|
||||
#define __EXPERIMENT_INFO_HPP__
|
||||
#define __EXPERIMENT_INFO_HPP__
|
||||
|
||||
#define COOL_FAULTSPACE_PRUNING 0
|
||||
|
||||
@ -37,4 +37,4 @@
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif // __EXPERIMENT_INFO_HPP__
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
CoolChecksumCampaign c;
|
||||
if (fi::campaignmanager.runCampaign(&c)) {
|
||||
if (fail::campaignmanager.runCampaign(&c)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
|
||||
@ -1,9 +1,17 @@
|
||||
/**
|
||||
* \brief This experiment demonstrates the fireInterrupt feature.
|
||||
*
|
||||
* The keyboard-interrupts are disabled. So nothing happens if you press a button
|
||||
* on keyboard. Only the pressed button will be stored in keyboard-buffer. With
|
||||
* the fireInterrupt feature keyboard-interrupts are generated manually. The result
|
||||
* is that the keyboard interrupts will be compensated manually. bootdisk.img can
|
||||
* be used as example image (Turbo-Pacman :-) ).
|
||||
*/
|
||||
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "experiment.hpp"
|
||||
#include "SAL/SALInst.hpp"
|
||||
#include "SAL/bochs/BochsRegister.hpp"
|
||||
#include "controller/Event.hpp"
|
||||
#include "util/Logger.hpp"
|
||||
#include "config/FailConfig.hpp"
|
||||
@ -13,35 +21,27 @@
|
||||
#error This experiment needs: breakpoints, disabled keyboard interrupts and fire interrupts. Enable these in the configuration.
|
||||
#endif
|
||||
|
||||
/* This experiment demonstrates the fireInterrupt feature.
|
||||
* The keyboard-interrupts are disabled. So nothing happens if you press a button on keyboard.
|
||||
* Only the pressed button will be stored in keyboard-buffer.
|
||||
* With the fireInterrupt feature keyboard-interrupts are generated manually.
|
||||
* The result is that the keyboard interrupts will be compensated manually.
|
||||
* bootdisk.img can be used as example image. (turbo-pacman :) )
|
||||
*/
|
||||
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
bool fireinterruptExperiment::run()
|
||||
{
|
||||
Logger log("FireInterrupt", false);
|
||||
log << "experiment start" << endl;
|
||||
|
||||
#if 1
|
||||
while(1){
|
||||
while (true) {
|
||||
int j = 0;
|
||||
for(j=0 ; j<=100 ; j++){
|
||||
fi::BPSingleEvent mainbp(0x1045f5);
|
||||
sal::simulator.addEventAndWait(&mainbp);
|
||||
for (j = 0; j <= 100; j++) {
|
||||
BPSingleEvent mainbp(0x1045f5);
|
||||
simulator.addEventAndWait(&mainbp);
|
||||
}
|
||||
sal::simulator.fireInterrupt(1);
|
||||
simulator.fireInterrupt(1);
|
||||
}
|
||||
#elif 1
|
||||
|
||||
sal::simulator.dbgEnableInstrPtrOutput(500);
|
||||
|
||||
simulator.dbgEnableInstrPtrOutput(500);
|
||||
#endif
|
||||
|
||||
sal::simulator.clearEvents(this);
|
||||
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3,11 +3,10 @@
|
||||
|
||||
#include "controller/ExperimentFlow.hpp"
|
||||
|
||||
class fireinterruptExperiment : public fi::ExperimentFlow
|
||||
class fireinterruptExperiment : public fail::ExperimentFlow
|
||||
{
|
||||
public:
|
||||
fireinterruptExperiment() { }
|
||||
|
||||
bool run();
|
||||
};
|
||||
|
||||
|
||||
@ -14,7 +14,8 @@
|
||||
#error This experiment needs: breakpoints, save, and restore. Enable these in the configuration.
|
||||
#endif
|
||||
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
bool hscsimpleExperiment::run()
|
||||
{
|
||||
@ -24,31 +25,31 @@ bool hscsimpleExperiment::run()
|
||||
// do funny things here...
|
||||
#if 1
|
||||
// STEP 1
|
||||
fi::BPSingleEvent mainbp(0x00003c34);
|
||||
sal::simulator.addEventAndWait(&mainbp);
|
||||
BPSingleEvent mainbp(0x00003c34);
|
||||
simulator.addEventAndWait(&mainbp);
|
||||
log << "breakpoint reached, saving" << endl;
|
||||
sal::simulator.save("hello.state");
|
||||
simulator.save("hello.state");
|
||||
#elif 0
|
||||
// STEP 2
|
||||
log << "restoring ..." << endl;
|
||||
sal::simulator.restore("hello.state");
|
||||
simulator.restore("hello.state");
|
||||
log << "restored!" << endl;
|
||||
|
||||
log << "waiting for last square() instruction" << endl;
|
||||
fi::BPSingleEvent breakpoint(0x3c9e); // square(x) ret instruction
|
||||
sal::simulator.addEventAndWait(&breakpoint);
|
||||
BPSingleEvent breakpoint(0x3c9e); // square(x) ret instruction
|
||||
simulator.addEventAndWait(&breakpoint);
|
||||
log << "injecting hellish fault" << endl;
|
||||
// RID_CAX is the RAX register in 64 bit mode and EAX in 32 bit mode:
|
||||
sal::simulator.getRegisterManager().getRegister(sal::RID_CAX)->setData(666);
|
||||
simulator.getRegisterManager().getRegister(RID_CAX)->setData(666);
|
||||
log << "waiting for last main() instruction" << endl;
|
||||
breakpoint.setWatchInstructionPointer(0x3c92);
|
||||
sal::simulator.addEventAndWait(&breakpoint);
|
||||
simulator.addEventAndWait(&breakpoint);
|
||||
|
||||
log << "reached" << endl;
|
||||
|
||||
sal::simulator.addEventAndWait(&breakpoint);
|
||||
simulator.addEventAndWait(&breakpoint);
|
||||
#endif
|
||||
|
||||
sal::simulator.clearEvents(this);
|
||||
simulator.clearEvents(this);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@
|
||||
|
||||
#include "controller/ExperimentFlow.hpp"
|
||||
|
||||
class hscsimpleExperiment : public fi::ExperimentFlow
|
||||
class hscsimpleExperiment : public fail::ExperimentFlow
|
||||
{
|
||||
public:
|
||||
hscsimpleExperiment() { }
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user