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:
@ -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() { }
|
||||
|
||||
@ -11,8 +11,8 @@
|
||||
|
||||
aspect @EXPERIMENT_TYPE@ExperimentHook {
|
||||
@EXPERIMENT_TYPE@ experiment;
|
||||
advice execution ("void sal::SimulatorController::initExperiments()") : after () {
|
||||
sal::simulator.addFlow(&experiment);
|
||||
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
|
||||
fail::simulator.addFlow(&experiment);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
#include "util/Logger.hpp"
|
||||
#include "SAL/SALConfig.hpp"
|
||||
|
||||
using namespace fi;
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
char const * const results_csv = "l4sys.csv";
|
||||
|
||||
@ -39,23 +39,23 @@ bool L4SysCampaign::run()
|
||||
d->msg.set_bit_offset(bit_offset);
|
||||
d->msg.set_bit_offset(0);
|
||||
|
||||
fi::campaignmanager.addParam(d);
|
||||
campaignmanager.addParam(d);
|
||||
++count;
|
||||
}
|
||||
}
|
||||
fi::campaignmanager.noMoreParameters();
|
||||
campaignmanager.noMoreParameters();
|
||||
log << "done enqueueing parameter sets (" << count << ")." << endl;
|
||||
|
||||
// collect results
|
||||
L4SysExperimentData *res;
|
||||
int rescount = 0;
|
||||
results << "injection_ip,instr_offset,injection_bit,resulttype,resultdata,output,details" << endl;
|
||||
while ((res = static_cast<L4SysExperimentData *>(fi::campaignmanager.getDone()))) {
|
||||
while ((res = static_cast<L4SysExperimentData *>(campaignmanager.getDone()))) {
|
||||
rescount++;
|
||||
|
||||
results << std::hex
|
||||
results << hex
|
||||
<< res->msg.injection_ip() << ","
|
||||
<< std::dec << res->msg.instr_offset() << ","
|
||||
<< dec << res->msg.instr_offset() << ","
|
||||
<< res->msg.bit_offset() << ","
|
||||
<< res->msg.resulttype() << ","
|
||||
<< res->msg.resultdata();
|
||||
|
||||
@ -1,20 +1,19 @@
|
||||
#ifndef __COOLCAMPAIGN_HPP__
|
||||
#define __COOLCAMPAIGN_HPP__
|
||||
#ifndef __L4SYS_CAMPAIGN_HPP__
|
||||
#define __L4SYS_CAMPAIGN_HPP__
|
||||
|
||||
#include "controller/Campaign.hpp"
|
||||
#include "controller/ExperimentData.hpp"
|
||||
#include "l4sys.pb.h"
|
||||
|
||||
class L4SysExperimentData : public fi::ExperimentData {
|
||||
class L4SysExperimentData : public fail::ExperimentData {
|
||||
public:
|
||||
L4SysProtoMsg msg;
|
||||
L4SysExperimentData() : fi::ExperimentData(&msg) {}
|
||||
L4SysExperimentData() : fail::ExperimentData(&msg) {}
|
||||
};
|
||||
|
||||
|
||||
class L4SysCampaign : public fi::Campaign {
|
||||
class L4SysCampaign : public fail::Campaign {
|
||||
public:
|
||||
virtual bool run();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __L4SYS_CAMPAIGN_HPP__
|
||||
|
||||
@ -20,7 +20,8 @@
|
||||
|
||||
#include "l4sys.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,17 +32,18 @@ using std::endl;
|
||||
save, and restore. Enable these in the configuration.
|
||||
#endif
|
||||
|
||||
char const * const state_folder = "l4sys.state";
|
||||
char const * const state_folder = "l4sys.state";
|
||||
char const * const instr_list_fn = "ip.list";
|
||||
char const * const golden_run_fn = "golden.out";
|
||||
sal::address_t const aspace = 0x01e00000;
|
||||
std::string output;
|
||||
std::vector<sal::address_t> instr_list;
|
||||
std::string golden_run;
|
||||
address_t const aspace = 0x01e00000;
|
||||
string output;
|
||||
vector<address_t> instr_list;
|
||||
string golden_run;
|
||||
//the program needs to run 5 times without a fault
|
||||
const unsigned times_run = 5;
|
||||
|
||||
std::string L4SysExperiment::sanitised(std::string in_str) {
|
||||
string L4SysExperiment::sanitised(string in_str)
|
||||
{
|
||||
string result;
|
||||
result.reserve(in_str.size());
|
||||
for (string::iterator it = in_str.begin(); it != in_str.end(); it++) {
|
||||
@ -57,15 +59,16 @@ std::string L4SysExperiment::sanitised(std::string in_str) {
|
||||
return result;
|
||||
}
|
||||
|
||||
fi::BaseEvent* L4SysExperiment::waitIOOrOther(bool clear_output) {
|
||||
fi::IOPortEvent ev_ioport(0x3F8, true);
|
||||
fi::BaseEvent* ev = NULL;
|
||||
BaseEvent* L4SysExperiment::waitIOOrOther(bool clear_output)
|
||||
{
|
||||
IOPortEvent ev_ioport(0x3F8, true);
|
||||
BaseEvent* ev = NULL;
|
||||
if (clear_output)
|
||||
output.clear();
|
||||
while (true) {
|
||||
sal::simulator.addEvent(&ev_ioport);
|
||||
ev = sal::simulator.waitAny();
|
||||
sal::simulator.removeEvent(&ev_ioport);
|
||||
simulator.addEvent(&ev_ioport);
|
||||
ev = simulator.waitAny();
|
||||
simulator.removeEvent(&ev_ioport);
|
||||
if (ev == &ev_ioport) {
|
||||
output += ev_ioport.getData();
|
||||
} else {
|
||||
@ -75,9 +78,10 @@ fi::BaseEvent* L4SysExperiment::waitIOOrOther(bool clear_output) {
|
||||
return ev;
|
||||
}
|
||||
|
||||
bool L4SysExperiment::run() {
|
||||
bool L4SysExperiment::run()
|
||||
{
|
||||
Logger log("L4Sys", false);
|
||||
fi::BPSingleEvent bp(0, aspace);
|
||||
BPSingleEvent bp(0, aspace);
|
||||
|
||||
log << "startup" << endl;
|
||||
|
||||
@ -87,46 +91,46 @@ bool L4SysExperiment::run() {
|
||||
// STEP 1: run until interesting function starts, and save state
|
||||
if (stat(state_folder, &teststruct) == -1) {
|
||||
bp.setWatchInstructionPointer(L4SYS_FUNC_ENTRY);
|
||||
sal::simulator.addEventAndWait(&bp);
|
||||
simulator.addEventAndWait(&bp);
|
||||
|
||||
log << "test function entry reached, saving state" << endl;
|
||||
log << "EIP = " << std::hex << bp.getTriggerInstructionPointer()
|
||||
log << "EIP = " << hex << bp.getTriggerInstructionPointer()
|
||||
<< " or "
|
||||
<< sal::simulator.getRegisterManager().getInstructionPointer()
|
||||
<< simulator.getRegisterManager().getInstructionPointer()
|
||||
<< endl;
|
||||
sal::simulator.save(state_folder);
|
||||
simulator.save(state_folder);
|
||||
}
|
||||
|
||||
// STEP 2: determine instructions executed
|
||||
if (stat(instr_list_fn, &teststruct) == -1) {
|
||||
log << "restoring state" << endl;
|
||||
sal::simulator.restore(state_folder);
|
||||
log << "EIP = " << std::hex
|
||||
<< sal::simulator.getRegisterManager().getInstructionPointer()
|
||||
simulator.restore(state_folder);
|
||||
log << "EIP = " << hex
|
||||
<< simulator.getRegisterManager().getInstructionPointer()
|
||||
<< endl;
|
||||
|
||||
// make sure the timer interrupt doesn't disturb us
|
||||
sal::simulator.addSuppressedInterrupt(32);
|
||||
simulator.addSuppressedInterrupt(32);
|
||||
|
||||
std::ofstream instr_list_file(instr_list_fn);
|
||||
instr_list_file << std::hex;
|
||||
bp.setWatchInstructionPointer(fi::ANY_ADDR);
|
||||
ofstream instr_list_file(instr_list_fn);
|
||||
instr_list_file << hex;
|
||||
bp.setWatchInstructionPointer(ANY_ADDR);
|
||||
while (bp.getTriggerInstructionPointer() != L4SYS_FUNC_EXIT) {
|
||||
sal::simulator.addEventAndWait(&bp);
|
||||
simulator.addEventAndWait(&bp);
|
||||
//short sanity check
|
||||
sal::address_t curr_instr = bp.getTriggerInstructionPointer();
|
||||
address_t curr_instr = bp.getTriggerInstructionPointer();
|
||||
assert(
|
||||
curr_instr == sal::simulator.getRegisterManager().getInstructionPointer());
|
||||
curr_instr == simulator.getRegisterManager().getInstructionPointer());
|
||||
instr_list.push_back(curr_instr);
|
||||
instr_list_file << curr_instr << endl;
|
||||
}
|
||||
log << "saving instructions triggered during normal execution" << endl;
|
||||
instr_list_file.close();
|
||||
} else {
|
||||
std::ifstream instr_list_file(instr_list_fn);
|
||||
instr_list_file >> std::hex;
|
||||
ifstream instr_list_file(instr_list_fn);
|
||||
instr_list_file >> hex;
|
||||
while (!instr_list_file.eof()) {
|
||||
sal::address_t curr_instr;
|
||||
address_t curr_instr;
|
||||
instr_list_file >> curr_instr;
|
||||
instr_list.push_back(curr_instr);
|
||||
}
|
||||
@ -136,19 +140,19 @@ bool L4SysExperiment::run() {
|
||||
// STEP 3: determine the output of a "golden run"
|
||||
if (stat(golden_run_fn, &teststruct) == -1) {
|
||||
log << "restoring state" << endl;
|
||||
sal::simulator.restore(state_folder);
|
||||
log << "EIP = " << std::hex
|
||||
<< sal::simulator.getRegisterManager().getInstructionPointer()
|
||||
simulator.restore(state_folder);
|
||||
log << "EIP = " << hex
|
||||
<< simulator.getRegisterManager().getInstructionPointer()
|
||||
<< endl;
|
||||
|
||||
// make sure the timer interrupt doesn't disturb us
|
||||
sal::simulator.addSuppressedInterrupt(32);
|
||||
simulator.addSuppressedInterrupt(32);
|
||||
|
||||
std::ofstream golden_run_file(golden_run_fn);
|
||||
ofstream golden_run_file(golden_run_fn);
|
||||
bp.setWatchInstructionPointer(L4SYS_FUNC_EXIT);
|
||||
bp.setCounter(times_run);
|
||||
sal::simulator.addEvent(&bp);
|
||||
fi::BaseEvent* ev = waitIOOrOther(true);
|
||||
simulator.addEvent(&bp);
|
||||
BaseEvent* ev = waitIOOrOther(true);
|
||||
if (ev == &bp) {
|
||||
golden_run.assign(output.c_str());
|
||||
golden_run_file << output.c_str();
|
||||
@ -158,23 +162,23 @@ bool L4SysExperiment::run() {
|
||||
<< "Obviously, there is some trouble with the events registered - aborting simulation!"
|
||||
<< endl;
|
||||
golden_run_file.close();
|
||||
sal::simulator.terminate(10);
|
||||
simulator.terminate(10);
|
||||
}
|
||||
sal::simulator.clearEvents();
|
||||
simulator.clearEvents();
|
||||
bp.setCounter(1);
|
||||
log << "saving output generated during normal execution" << endl;
|
||||
golden_run_file.close();
|
||||
} else {
|
||||
std::ifstream golden_run_file(golden_run_fn);
|
||||
ifstream golden_run_file(golden_run_fn);
|
||||
|
||||
//shamelessly copied from http://stackoverflow.com/questions/2602013/:
|
||||
golden_run_file.seekg(0, std::ios::end);
|
||||
golden_run_file.seekg(0, ios::end);
|
||||
size_t flen = golden_run_file.tellg();
|
||||
golden_run.reserve(flen);
|
||||
golden_run_file.seekg(0, std::ios::beg);
|
||||
golden_run_file.seekg(0, ios::beg);
|
||||
|
||||
golden_run.assign((std::istreambuf_iterator<char>(golden_run_file)),
|
||||
std::istreambuf_iterator<char>());
|
||||
golden_run.assign((istreambuf_iterator<char>(golden_run_file)),
|
||||
istreambuf_iterator<char>());
|
||||
|
||||
golden_run_file.close();
|
||||
|
||||
@ -187,14 +191,14 @@ bool L4SysExperiment::run() {
|
||||
// STEP 4: The actual experiment.
|
||||
for (int i = 0; i < 1/*L4SYS_NUMINSTR*/; i++) {
|
||||
log << "restoring state" << endl;
|
||||
sal::simulator.restore(state_folder);
|
||||
simulator.restore(state_folder);
|
||||
|
||||
log << "asking job server for experiment parameters" << endl;
|
||||
L4SysExperimentData 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();
|
||||
@ -203,28 +207,28 @@ bool L4SysExperiment::run() {
|
||||
<< bit_offset << endl;
|
||||
|
||||
bp.setWatchInstructionPointer(instr_list[instr_offset]);
|
||||
sal::simulator.addEvent(&bp);
|
||||
simulator.addEvent(&bp);
|
||||
//and log the output
|
||||
waitIOOrOther(true);
|
||||
|
||||
// inject
|
||||
sal::RegisterManager& rm = sal::simulator.getRegisterManager();
|
||||
sal::Register *ebx = rm.getRegister(sal::RID_EBX);
|
||||
sal::regdata_t data = ebx->getData();
|
||||
sal::regdata_t newdata = data ^ (1 << bit_offset);
|
||||
RegisterManager& rm = simulator.getRegisterManager();
|
||||
Register *ebx = rm.getRegister(RID_EBX);
|
||||
regdata_t data = ebx->getData();
|
||||
regdata_t newdata = data ^ (1 << bit_offset);
|
||||
ebx->setData(newdata);
|
||||
// note at what IP we did it
|
||||
sal::address_t injection_ip =
|
||||
sal::simulator.getRegisterManager().getInstructionPointer();
|
||||
address_t injection_ip =
|
||||
simulator.getRegisterManager().getInstructionPointer();
|
||||
param.msg.set_injection_ip(injection_ip);
|
||||
log << "inject @ ip " << injection_ip << " (offset " << std::dec
|
||||
log << "inject @ ip " << injection_ip << " (offset " << dec
|
||||
<< instr_offset << ")" << " bit " << bit_offset << ": 0x"
|
||||
<< std::hex << ((int) data) << " -> 0x" << ((int) newdata)
|
||||
<< hex << ((int) data) << " -> 0x" << ((int) newdata)
|
||||
<< endl;
|
||||
|
||||
// sanity check (only works if we're working with an instruction trace)
|
||||
if (injection_ip != instr_list[instr_offset]) {
|
||||
std::stringstream ss;
|
||||
stringstream ss;
|
||||
ss << "SANITY CHECK FAILED: " << injection_ip << " != "
|
||||
<< instr_list[instr_offset] << endl;
|
||||
log << ss.str();
|
||||
@ -232,28 +236,28 @@ bool L4SysExperiment::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(L4SYS_FUNC_EXIT, aspace);
|
||||
BPSingleEvent ev_done(L4SYS_FUNC_EXIT, aspace);
|
||||
ev_done.setCounter(times_run);
|
||||
sal::simulator.addEvent(&ev_done);
|
||||
simulator.addEvent(&ev_done);
|
||||
const unsigned instr_run = times_run * L4SYS_NUMINSTR;
|
||||
fi::BPSingleEvent ev_timeout(fi::ANY_ADDR, aspace);
|
||||
BPSingleEvent ev_timeout(ANY_ADDR, aspace);
|
||||
ev_timeout.setCounter(instr_run + 3000);
|
||||
sal::simulator.addEvent(&ev_timeout);
|
||||
fi::TrapEvent ev_trap(fi::ANY_TRAP);
|
||||
sal::simulator.addEvent(&ev_trap);
|
||||
fi::InterruptEvent ev_intr(fi::ANY_INTERRUPT);
|
||||
simulator.addEvent(&ev_timeout);
|
||||
TrapEvent ev_trap(ANY_TRAP);
|
||||
simulator.addEvent(&ev_trap);
|
||||
InterruptEvent ev_intr(ANY_INTERRUPT);
|
||||
//ten times as many interrupts as instructions justify an exception
|
||||
ev_intr.setCounter(instr_run * 10);
|
||||
sal::simulator.addEvent(&ev_intr);
|
||||
simulator.addEvent(&ev_intr);
|
||||
|
||||
//do not discard output recorded so far
|
||||
fi::BaseEvent *ev = waitIOOrOther(false);
|
||||
BaseEvent *ev = waitIOOrOther(false);
|
||||
|
||||
/* copying a string object that contains control sequences
|
||||
* unfortunately does not work with the library I am using,
|
||||
@ -262,53 +266,53 @@ bool L4SysExperiment::run() {
|
||||
*/
|
||||
if (ev == &ev_done) {
|
||||
if (strcmp(output.c_str(), golden_run.c_str()) == 0) {
|
||||
log << std::dec << "Result DONE" << endl;
|
||||
log << dec << "Result DONE" << endl;
|
||||
param.msg.set_resulttype(param.msg.DONE);
|
||||
} else {
|
||||
log << std::dec << "Result WRONG" << endl;
|
||||
log << dec << "Result WRONG" << endl;
|
||||
param.msg.set_resulttype(param.msg.WRONG);
|
||||
param.msg.set_output(sanitised(output.c_str()));
|
||||
}
|
||||
} 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());
|
||||
simulator.getRegisterManager().getInstructionPointer());
|
||||
param.msg.set_output(sanitised(output.c_str()));
|
||||
} else if (ev == &ev_trap) {
|
||||
log << std::dec << "Result TRAP #" << ev_trap.getTriggerNumber()
|
||||
log << dec << "Result TRAP #" << ev_trap.getTriggerNumber()
|
||||
<< endl;
|
||||
param.msg.set_resulttype(param.msg.TRAP);
|
||||
param.msg.set_resultdata(
|
||||
sal::simulator.getRegisterManager().getInstructionPointer());
|
||||
simulator.getRegisterManager().getInstructionPointer());
|
||||
param.msg.set_output(sanitised(output.c_str()));
|
||||
} else if (ev == &ev_intr) {
|
||||
log << std::hex << "Result INT FLOOD; Last INT #:"
|
||||
log << hex << "Result INT FLOOD; Last INT #:"
|
||||
<< ev_intr.getTriggerNumber() << endl;
|
||||
param.msg.set_resulttype(param.msg.INTR);
|
||||
param.msg.set_resultdata(
|
||||
sal::simulator.getRegisterManager().getInstructionPointer());
|
||||
simulator.getRegisterManager().getInstructionPointer());
|
||||
param.msg.set_output(sanitised(output.c_str()));
|
||||
} 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());
|
||||
simulator.getRegisterManager().getInstructionPointer());
|
||||
param.msg.set_output(sanitised(output.c_str()));
|
||||
|
||||
std::stringstream ss;
|
||||
stringstream ss;
|
||||
ss << "eventid " << ev << " EIP "
|
||||
<< sal::simulator.getRegisterManager().getInstructionPointer()
|
||||
<< simulator.getRegisterManager().getInstructionPointer()
|
||||
<< endl;
|
||||
param.msg.set_details(ss.str());
|
||||
}
|
||||
|
||||
sal::simulator.clearEvents();
|
||||
simulator.clearEvents();
|
||||
m_jc.sendResult(param);
|
||||
}
|
||||
|
||||
#ifdef HEADLESS_EXPERIMENT
|
||||
sal::simulator.terminate(0);
|
||||
simulator.terminate(0);
|
||||
#endif
|
||||
// experiment successfully conducted
|
||||
return true;
|
||||
|
||||
@ -1,17 +1,23 @@
|
||||
#ifndef __COOLEXPERIMENT_HPP__
|
||||
#define __COOLEXPERIMENT_HPP__
|
||||
#ifndef __L4SYS_EXPERIMENT_HPP__
|
||||
#define __L4SYS_EXPERIMENT_HPP__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "controller/ExperimentFlow.hpp"
|
||||
#include "jobserver/JobClient.hpp"
|
||||
|
||||
class L4SysExperiment : public fi::ExperimentFlow {
|
||||
fi::JobClient m_jc;
|
||||
class L4SysExperiment : public fail::ExperimentFlow {
|
||||
fail::JobClient m_jc;
|
||||
public:
|
||||
L4SysExperiment() : m_jc("localhost") {}
|
||||
bool run();
|
||||
private:
|
||||
// NOTE: It's good practise to use "const std::string&" as parameter type.
|
||||
// Additionaly, if you don't need the return value to be copied,
|
||||
// return a (const) reference to a class member or a static string-
|
||||
// object.
|
||||
std::string sanitised(std::string in_str);
|
||||
fi::BaseEvent* waitIOOrOther(bool clear_output);
|
||||
fail::BaseEvent* waitIOOrOther(bool clear_output);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __L4SYS_EXPERIMENT_HPP__
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
#ifndef __EXPERIMENT_INFO_HPP__
|
||||
#define __EXPERIMENT_INFO_HPP__
|
||||
#define __EXPERIMENT_INFO_HPP__
|
||||
|
||||
// FIXME autogenerate this
|
||||
|
||||
@ -9,4 +9,4 @@
|
||||
//#define HEADLESS_EXPERIMENT
|
||||
#define PREPARE_EXPERIMENT
|
||||
|
||||
#endif
|
||||
#endif // __EXPERIMENT_INFO_HPP__
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
L4SysCampaign c;
|
||||
if (fi::campaignmanager.runCampaign(&c)) {
|
||||
if (fail::campaignmanager.runCampaign(&c)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
|
||||
@ -13,10 +13,10 @@
|
||||
|
||||
#include "plugins/tracing/TracingPlugin.hpp"
|
||||
|
||||
using namespace fi;
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
char const * const trace_filename = "trace.pb";
|
||||
char const * const trace_filename = "trace.pb";
|
||||
char const * const results_filename = "weathermonitor.csv";
|
||||
|
||||
// equivalence class type: addr, [i1, i2]
|
||||
@ -24,9 +24,9 @@ char const * const results_filename = "weathermonitor.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;
|
||||
address_t instr2_absolute;
|
||||
};
|
||||
|
||||
bool WeathermonitorCampaign::run()
|
||||
@ -57,15 +57,15 @@ bool WeathermonitorCampaign::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<WeathermonitorExperimentData *, unsigned> experiment_ecs;
|
||||
map<WeathermonitorExperimentData *, unsigned> experiment_ecs;
|
||||
// experiment count
|
||||
int count = 0;
|
||||
|
||||
@ -73,11 +73,11 @@ bool WeathermonitorCampaign::run()
|
||||
// -> one "open" EC for every address
|
||||
// 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();
|
||||
|
||||
@ -131,7 +131,7 @@ bool WeathermonitorCampaign::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) {
|
||||
// a sequence ending with WRITE: an
|
||||
@ -181,11 +181,11 @@ bool WeathermonitorCampaign::run()
|
||||
// store index into ecs_need_experiment
|
||||
experiment_ecs[d] = ecs_need_experiment.size() - 1;
|
||||
|
||||
fi::campaignmanager.addParam(d);
|
||||
campaignmanager.addParam(d);
|
||||
++count;
|
||||
}
|
||||
|
||||
fi::campaignmanager.noMoreParameters();
|
||||
campaignmanager.noMoreParameters();
|
||||
log << "done enqueueing parameter sets (" << count << ")." << endl;
|
||||
|
||||
log << "equivalence classes generated:"
|
||||
@ -194,11 +194,11 @@ bool WeathermonitorCampaign::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;
|
||||
}
|
||||
@ -209,7 +209,7 @@ bool WeathermonitorCampaign::run()
|
||||
results << "ec_instr1\tec_instr2\tec_instr2_absolute\tec_data_address\tbitnr\tbit_width\tresulttype\tlatest_ip\titer1\titer2\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"
|
||||
@ -227,10 +227,10 @@ bool WeathermonitorCampaign::run()
|
||||
// collect results
|
||||
WeathermonitorExperimentData *res;
|
||||
int rescount = 0;
|
||||
while ((res = static_cast<WeathermonitorExperimentData *>(fi::campaignmanager.getDone()))) {
|
||||
while ((res = static_cast<WeathermonitorExperimentData *>(campaignmanager.getDone()))) {
|
||||
rescount++;
|
||||
|
||||
std::map<WeathermonitorExperimentData *, unsigned>::iterator it =
|
||||
map<WeathermonitorExperimentData *, unsigned>::iterator it =
|
||||
experiment_ecs.find(res);
|
||||
if (it == experiment_ecs.end()) {
|
||||
results << "WTF, didn't find res!" << endl;
|
||||
|
||||
@ -1,19 +1,19 @@
|
||||
#ifndef __WEATHERMONITOR_CAMPAIGN_HPP__
|
||||
#define __WEATHERMONITOR_CAMPAIGN_HPP__
|
||||
#define __WEATHERMONITOR_CAMPAIGN_HPP__
|
||||
|
||||
#include "controller/Campaign.hpp"
|
||||
#include "controller/ExperimentData.hpp"
|
||||
#include "weathermonitor.pb.h"
|
||||
|
||||
class WeathermonitorExperimentData : public fi::ExperimentData {
|
||||
class WeathermonitorExperimentData : public fail::ExperimentData {
|
||||
public:
|
||||
WeathermonitorProtoMsg msg;
|
||||
WeathermonitorExperimentData() : fi::ExperimentData(&msg) {}
|
||||
WeathermonitorExperimentData() : fail::ExperimentData(&msg) {}
|
||||
};
|
||||
|
||||
class WeathermonitorCampaign : public fi::Campaign {
|
||||
class WeathermonitorCampaign : public fail::Campaign {
|
||||
public:
|
||||
virtual bool run();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __WEATHERMONITOR_CAMPAIGN_HPP__
|
||||
|
||||
@ -23,12 +23,12 @@
|
||||
|
||||
#define LOCAL 0
|
||||
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
using namespace fail;
|
||||
|
||||
// Check if configuration dependencies are satisfied:
|
||||
#if !defined(CONFIG_EVENT_BREAKPOINTS) || !defined(CONFIG_SR_RESTORE) || \
|
||||
!defined(CONFIG_SR_SAVE) || !defined(CONFIG_EVENT_TRAP)
|
||||
|
||||
#error This experiment needs: breakpoints, traps, save, and restore. Enable these in the configuration.
|
||||
#endif
|
||||
|
||||
@ -36,32 +36,32 @@ bool WeathermonitorExperiment::run()
|
||||
{
|
||||
char const *statename = "bochs.state";
|
||||
Logger log("Weathermonitor", false);
|
||||
fi::BPSingleEvent bp;
|
||||
BPSingleEvent bp;
|
||||
|
||||
log << "startup" << endl;
|
||||
|
||||
#if 1
|
||||
// STEP 0: record memory map with vptr addresses
|
||||
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(WEATHER_FUNC_MAIN);
|
||||
sal::simulator.addEventAndWait(&bp);
|
||||
simulator.addEventAndWait(&bp);
|
||||
log << "test function entry reached, saving state" << endl;
|
||||
log << "EIP = " << std::hex << bp.getTriggerInstructionPointer() << endl;
|
||||
sal::simulator.save(statename);
|
||||
log << "EIP = " << hex << bp.getTriggerInstructionPointer() << endl;
|
||||
simulator.save(statename);
|
||||
assert(bp.getTriggerInstructionPointer() == WEATHER_FUNC_MAIN);
|
||||
assert(sal::simulator.getRegisterManager().getInstructionPointer() == WEATHER_FUNC_MAIN);
|
||||
assert(simulator.getRegisterManager().getInstructionPointer() == WEATHER_FUNC_MAIN);
|
||||
|
||||
// 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() == WEATHER_FUNC_MAIN);
|
||||
simulator.restore(statename);
|
||||
log << "EIP = " << hex << simulator.getRegisterManager().getInstructionPointer() << endl;
|
||||
assert(simulator.getRegisterManager().getInstructionPointer() == WEATHER_FUNC_MAIN);
|
||||
|
||||
log << "enabling tracing" << endl;
|
||||
TracingPlugin tp;
|
||||
@ -76,35 +76,35 @@ bool WeathermonitorExperiment::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);
|
||||
|
||||
// trace WEATHER_NUMITER_TRACING measurement loop iterations
|
||||
bp.setWatchInstructionPointer(WEATHER_FUNC_WAIT_END);
|
||||
bp.setCounter(WEATHER_NUMITER_TRACING);
|
||||
sal::simulator.addEvent(&bp);
|
||||
fi::BPSingleEvent ev_count(fi::ANY_ADDR);
|
||||
sal::simulator.addEvent(&ev_count);
|
||||
simulator.addEvent(&bp);
|
||||
BPSingleEvent ev_count(ANY_ADDR);
|
||||
simulator.addEvent(&ev_count);
|
||||
|
||||
// count instructions
|
||||
// FIXME add SAL functionality for this?
|
||||
int instr_counter = 0;
|
||||
while (sal::simulator.waitAny() == &ev_count) {
|
||||
while (simulator.waitAny() == &ev_count) {
|
||||
++instr_counter;
|
||||
sal::simulator.addEvent(&ev_count);
|
||||
simulator.addEvent(&ev_count);
|
||||
}
|
||||
|
||||
log << std::dec << "tracing finished after " << instr_counter
|
||||
log << dec << "tracing finished after " << instr_counter
|
||||
<< " instructions, seeing wait_end " << WEATHER_NUMITER_TRACING << " times" << 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); // cleanup
|
||||
simulator.clearEvents(this); // cleanup
|
||||
return false;
|
||||
}
|
||||
of.close();
|
||||
@ -113,17 +113,17 @@ bool WeathermonitorExperiment::run()
|
||||
// wait another WEATHER_NUMITER_AFTER measurement loop iterations
|
||||
bp.setWatchInstructionPointer(WEATHER_FUNC_WAIT_END);
|
||||
bp.setCounter(WEATHER_NUMITER_AFTER);
|
||||
sal::simulator.addEvent(&bp);
|
||||
simulator.addEvent(&bp);
|
||||
|
||||
// count instructions
|
||||
// FIXME add SAL functionality for this?
|
||||
instr_counter = 0;
|
||||
while (sal::simulator.waitAny() == &ev_count) {
|
||||
while (simulator.waitAny() == &ev_count) {
|
||||
++instr_counter;
|
||||
sal::simulator.addEvent(&ev_count);
|
||||
simulator.addEvent(&ev_count);
|
||||
}
|
||||
|
||||
log << std::dec << "experiment finished after " << instr_counter
|
||||
log << dec << "experiment finished after " << instr_counter
|
||||
<< " instructions, seeing wait_end " << WEATHER_NUMITER_AFTER << " times" << endl;
|
||||
|
||||
#elif 0
|
||||
@ -139,7 +139,7 @@ bool WeathermonitorExperiment::run()
|
||||
if (!m_jc.getParam(param)) {
|
||||
log << "Dying." << endl;
|
||||
// communicate that we were told to die
|
||||
sal::simulator.terminate(1);
|
||||
simulator.terminate(1);
|
||||
}
|
||||
#else
|
||||
// XXX debug
|
||||
@ -157,62 +157,62 @@ bool WeathermonitorExperiment::run()
|
||||
// 8 results in one job
|
||||
WeathermonitorProtoMsg_Result *result = param.msg.add_result();
|
||||
result->set_bit_offset(bit_offset);
|
||||
log << std::dec << "job " << id << " instr " << instr_offset
|
||||
log << dec << "job " << id << " instr " << instr_offset
|
||||
<< " mem " << mem_addr << "+" << bit_offset << endl;
|
||||
|
||||
log << "restoring state" << endl;
|
||||
sal::simulator.restore(statename);
|
||||
simulator.restore(statename);
|
||||
|
||||
// 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();
|
||||
*/
|
||||
|
||||
// this marks THE END
|
||||
fi::BPSingleEvent ev_end(fi::ANY_ADDR);
|
||||
BPSingleEvent ev_end(ANY_ADDR);
|
||||
ev_end.setCounter(WEATHER_NUMINSTR_TRACING + WEATHER_NUMINSTR_AFTER);
|
||||
sal::simulator.addEvent(&ev_end);
|
||||
simulator.addEvent(&ev_end);
|
||||
|
||||
// count loop iterations by counting wait_begin() calls
|
||||
// FIXME would be nice to have a callback API for this as this needs to
|
||||
// be done "in parallel"
|
||||
fi::BPSingleEvent ev_wait_begin(WEATHER_FUNC_WAIT_BEGIN);
|
||||
sal::simulator.addEvent(&ev_wait_begin);
|
||||
BPSingleEvent ev_wait_begin(WEATHER_FUNC_WAIT_BEGIN);
|
||||
simulator.addEvent(&ev_wait_begin);
|
||||
int count_loop_iter_before = 0;
|
||||
|
||||
// no need to wait if offset is 0
|
||||
if (instr_offset > 0) {
|
||||
// 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);
|
||||
|
||||
// count loop iterations until FI
|
||||
while (sal::simulator.waitAny() == &ev_wait_begin) {
|
||||
while (simulator.waitAny() == &ev_wait_begin) {
|
||||
++count_loop_iter_before;
|
||||
sal::simulator.addEvent(&ev_wait_begin);
|
||||
simulator.addEvent(&ev_wait_begin);
|
||||
}
|
||||
}
|
||||
|
||||
// --- 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);
|
||||
result->set_iter_before_fi(count_loop_iter_before);
|
||||
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;
|
||||
@ -221,7 +221,7 @@ bool WeathermonitorExperiment::run()
|
||||
result->set_details(ss.str());
|
||||
result->set_iter_after_fi(0);
|
||||
|
||||
sal::simulator.clearEvents();
|
||||
simulator.clearEvents();
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -239,63 +239,63 @@ bool WeathermonitorExperiment::run()
|
||||
// - (XXX "sane" display?)
|
||||
|
||||
// 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);
|
||||
// jump outside text segment
|
||||
fi::BPRangeEvent ev_below_text(fi::ANY_ADDR, WEATHER_TEXT_START - 1);
|
||||
fi::BPRangeEvent ev_beyond_text(WEATHER_TEXT_END + 1, fi::ANY_ADDR);
|
||||
sal::simulator.addEvent(&ev_below_text);
|
||||
sal::simulator.addEvent(&ev_beyond_text);
|
||||
BPRangeEvent ev_below_text(ANY_ADDR, WEATHER_TEXT_START - 1);
|
||||
BPRangeEvent ev_beyond_text(WEATHER_TEXT_END + 1, ANY_ADDR);
|
||||
simulator.addEvent(&ev_below_text);
|
||||
simulator.addEvent(&ev_beyond_text);
|
||||
// error detected
|
||||
fi::BPSingleEvent ev_detected(WEATHER_FUNC_VPTR_PANIC);
|
||||
sal::simulator.addEvent(&ev_detected);
|
||||
BPSingleEvent ev_detected(WEATHER_FUNC_VPTR_PANIC);
|
||||
simulator.addEvent(&ev_detected);
|
||||
|
||||
#if LOCAL && 0
|
||||
// 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);
|
||||
#endif
|
||||
|
||||
fi::BaseEvent* ev;
|
||||
BaseEvent* ev;
|
||||
|
||||
// count loop iterations
|
||||
int count_loop_iter_after = 0;
|
||||
while ((ev = sal::simulator.waitAny()) == &ev_wait_begin) {
|
||||
while ((ev = simulator.waitAny()) == &ev_wait_begin) {
|
||||
++count_loop_iter_after;
|
||||
sal::simulator.addEvent(&ev_wait_begin);
|
||||
simulator.addEvent(&ev_wait_begin);
|
||||
}
|
||||
result->set_iter_after_fi(count_loop_iter_after);
|
||||
|
||||
// record latest IP regardless of result
|
||||
result->set_latest_ip(sal::simulator.getRegisterManager().getInstructionPointer());
|
||||
result->set_latest_ip(simulator.getRegisterManager().getInstructionPointer());
|
||||
|
||||
if (ev == &ev_end) {
|
||||
log << "Result FINISHED (" << std::dec
|
||||
log << "Result FINISHED (" << dec
|
||||
<< count_loop_iter_before << "+" << count_loop_iter_after << ")" << endl;
|
||||
result->set_resulttype(result->FINISHED);
|
||||
} else if (ev == &ev_below_text || ev == &ev_beyond_text) {
|
||||
log << "Result OUTSIDE" << endl;
|
||||
result->set_resulttype(result->OUTSIDE);
|
||||
} else if (ev == &ev_trap) {
|
||||
log << std::dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
|
||||
log << dec << "Result TRAP #" << ev_trap.getTriggerNumber() << endl;
|
||||
result->set_resulttype(result->TRAP);
|
||||
|
||||
std::stringstream ss;
|
||||
stringstream ss;
|
||||
ss << ev_trap.getTriggerNumber();
|
||||
result->set_details(ss.str());
|
||||
} else if (ev == &ev_detected) {
|
||||
log << std::dec << "Result DETECTED" << endl;
|
||||
log << dec << "Result DETECTED" << endl;
|
||||
result->set_resulttype(result->DETECTED);
|
||||
} else {
|
||||
log << "Result WTF?" << endl;
|
||||
result->set_resulttype(result->UNKNOWN);
|
||||
|
||||
std::stringstream ss;
|
||||
ss << "eventid " << ev->getId() << " EIP " << sal::simulator.getRegisterManager().getInstructionPointer();
|
||||
stringstream ss;
|
||||
ss << "eventid " << ev->getId() << " EIP " << simulator.getRegisterManager().getInstructionPointer();
|
||||
result->set_details(ss.str());
|
||||
}
|
||||
}
|
||||
@ -311,5 +311,5 @@ bool WeathermonitorExperiment::run()
|
||||
|
||||
#endif
|
||||
// Explicitly terminate, or the simulator will continue to run.
|
||||
sal::simulator.terminate();
|
||||
simulator.terminate();
|
||||
}
|
||||
|
||||
@ -1,14 +1,14 @@
|
||||
#ifndef __WEATHERMONITOR_EXPERIMENT_HPP__
|
||||
#define __WEATHERMONITOR_EXPERIMENT_HPP__
|
||||
#define __WEATHERMONITOR_EXPERIMENT_HPP__
|
||||
|
||||
#include "controller/ExperimentFlow.hpp"
|
||||
#include "jobserver/JobClient.hpp"
|
||||
|
||||
class WeathermonitorExperiment : public fi::ExperimentFlow {
|
||||
fi::JobClient m_jc;
|
||||
class WeathermonitorExperiment : public fail::ExperimentFlow {
|
||||
fail::JobClient m_jc;
|
||||
public:
|
||||
WeathermonitorExperiment() : m_jc("ios.cs.tu-dortmund.de") {}
|
||||
bool run();
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif // __WEATHERMONITOR_EXPERIMENT_HPP__
|
||||
|
||||
@ -7,5 +7,5 @@
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
WeathermonitorCampaign c;
|
||||
return !fi::campaignmanager.runCampaign(&c);
|
||||
return !fail::campaignmanager.runCampaign(&c);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user