L4Sys: adapt to DatabaseCampaign
Change-Id: Ia4912e7a74afccb51f6d704830a2d9c5b5c0159a
This commit is contained in:
@ -37,10 +37,10 @@ add_library(fail-${EXPERIMENT_NAME} ${PROTO_SRCS} ${PROTO_HDRS} ${MY_CAMPAIGN_SR
|
||||
find_package(LibUdis86 REQUIRED)
|
||||
include_directories(${LIBUDIS86_INCLUDE_DIRS})
|
||||
link_directories(${LIBUDIS86_LINK_DIRS})
|
||||
add_dependencies(fail-${EXPERIMENT_NAME} fail-comm fail-tracing)
|
||||
add_dependencies(fail-${EXPERIMENT_NAME} fail-comm)
|
||||
target_link_libraries(fail-${EXPERIMENT_NAME} ${LIBUDIS86_LIBRARIES} ${PROTOBUF_LIBRARY})
|
||||
|
||||
## This is the example's campaign server distributing experiment parameters
|
||||
add_executable(${EXPERIMENT_NAME}-server main.cc)
|
||||
target_link_libraries(${EXPERIMENT_NAME}-server fail-${EXPERIMENT_NAME} fail ${PROTOBUF_LIBRARY} ${Boost_THREAD_LIBRARY})
|
||||
target_link_libraries(${EXPERIMENT_NAME}-server fail-${EXPERIMENT_NAME} -Wl,--start-group fail-sal fail-util fail-cpn fail-comm ${PROTOBUF_LIBRARY} ${Boost_THREAD_LIBRARY} -lmysqlclient -Wl,--end-group)
|
||||
install(TARGETS ${EXPERIMENT_NAME}-server RUNTIME DESTINATION bin)
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "campaign.hpp"
|
||||
#include "experimentInfo.hpp"
|
||||
#include "conversion.hpp"
|
||||
#include "comm/DatabaseCampaignMessage.pb.h"
|
||||
#include "cpn/CampaignManager.hpp"
|
||||
#include "util/Logger.hpp"
|
||||
#include "sal/SALConfig.hpp"
|
||||
@ -17,6 +18,7 @@ extern L4SysConversion l4sysResultConversion;
|
||||
extern L4SysConversion l4sysExperimentConversion;
|
||||
extern L4SysConversion l4sysRegisterConversion;
|
||||
|
||||
#if 0
|
||||
bool L4SysCampaign::run() {
|
||||
Logger log("L4SysCampaign");
|
||||
|
||||
@ -51,7 +53,6 @@ bool L4SysCampaign::run() {
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
for (int i = 0; i < 20000; ++i) {
|
||||
L4SysExperimentData *d = new L4SysExperimentData;
|
||||
d->msg.set_exp_type(d->msg.GPRFLIP);
|
||||
@ -106,7 +107,6 @@ bool L4SysCampaign::run() {
|
||||
campaignmanager.addParam(d);
|
||||
++count;
|
||||
}
|
||||
#endif
|
||||
|
||||
campaignmanager.noMoreParameters();
|
||||
log << "done enqueueing parameter sets (" << count << ")." << endl;
|
||||
@ -143,3 +143,21 @@ bool L4SysCampaign::run() {
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
using namespace google::protobuf;
|
||||
|
||||
void L4SysCampaign::cb_send_pilot(DatabaseCampaignMessage p)
|
||||
{
|
||||
#if 0
|
||||
int inj_instr = p.injection_instr();
|
||||
int data_addr = p.data_address();
|
||||
int reg = (data_addr >> 8) & 0xF;
|
||||
int width = (data_addr >> 4) & 0xF;
|
||||
int offs = data_addr & 0xF;
|
||||
#endif
|
||||
L4SysExperimentData *d = new L4SysExperimentData;
|
||||
d->msg.mutable_fsppilot()->CopyFrom(p);
|
||||
d->msg.set_exp_type(d->msg.GPRFLIP);
|
||||
campaignmanager.addParam(d);
|
||||
}
|
||||
|
||||
@ -1,9 +1,10 @@
|
||||
#ifndef __L4SYS_CAMPAIGN_HPP__
|
||||
#define __L4SYS_CAMPAIGN_HPP__
|
||||
#define __L4SYS_CAMPAIGN_HPP__
|
||||
|
||||
#include "cpn/Campaign.hpp"
|
||||
#include "cpn/DatabaseCampaign.hpp"
|
||||
#include "comm/ExperimentData.hpp"
|
||||
#include "l4sys.pb.h"
|
||||
#include <google/protobuf/descriptor.h>
|
||||
|
||||
class L4SysExperimentData : public fail::ExperimentData {
|
||||
public:
|
||||
@ -11,9 +12,16 @@ public:
|
||||
L4SysExperimentData() : fail::ExperimentData(&msg) {}
|
||||
};
|
||||
|
||||
class L4SysCampaign : public fail::Campaign {
|
||||
class L4SysCampaign : public fail::DatabaseCampaign {
|
||||
#if 0
|
||||
public:
|
||||
virtual bool run();
|
||||
#else
|
||||
virtual const google::protobuf::Descriptor * cb_result_message()
|
||||
{ return google::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName("L4SysProtoMsg"); }
|
||||
|
||||
virtual void cb_send_pilot(DatabaseCampaignMessage pilot);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif // __L4SYS_CAMPAIGN_HPP__
|
||||
|
||||
@ -21,6 +21,7 @@
|
||||
#include "config/FailConfig.hpp"
|
||||
#include "util/ProtoStream.hpp"
|
||||
#include "TracePlugin.pb.h"
|
||||
#include "util/gzstream/gzstream.h"
|
||||
|
||||
#include "l4sys.pb.h"
|
||||
|
||||
@ -35,8 +36,7 @@ using namespace fail;
|
||||
save, and restore. Enable these in the configuration.
|
||||
#endif
|
||||
|
||||
string output;
|
||||
string golden_run;
|
||||
//string golden_run;
|
||||
extern L4SysConversion l4sysRegisterConversion;
|
||||
|
||||
string L4SysExperiment::sanitised(const string &in_str) {
|
||||
@ -62,13 +62,13 @@ BaseListener* L4SysExperiment::waitIOOrOther(bool clear_output) {
|
||||
IOPortListener ev_ioport(0x3F8, true);
|
||||
BaseListener* ev = NULL;
|
||||
if (clear_output)
|
||||
output.clear();
|
||||
currentOutput.clear();
|
||||
while (true) {
|
||||
simulator.addListener(&ev_ioport);
|
||||
ev = simulator.resume();
|
||||
simulator.removeListener(&ev_ioport);
|
||||
if (ev == &ev_ioport) {
|
||||
output += ev_ioport.getData();
|
||||
currentOutput += ev_ioport.getData();
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
@ -112,6 +112,8 @@ bx_bool L4SysExperiment::fetchInstruction(BX_CPU_C *instance,
|
||||
}
|
||||
|
||||
void L4SysExperiment::logInjection() {
|
||||
// XXX fixme
|
||||
#if 0
|
||||
// explicit type assignment necessary before sending over output stream
|
||||
int id = param->getWorkloadID();
|
||||
int instr_offset = param->msg.instr_offset();
|
||||
@ -122,9 +124,13 @@ void L4SysExperiment::logInjection() {
|
||||
log << "job " << id << " exp_type " << exp_type << endl;
|
||||
log << "inject @ ip " << hex << injection_ip << " (offset " << dec << instr_offset
|
||||
<< ")" << " bit " << bit_offset << endl;
|
||||
#endif
|
||||
}
|
||||
|
||||
BaseListener *L4SysExperiment::singleStep(bool preserveAddressSpace) {
|
||||
// XXX: fixme
|
||||
return 0;
|
||||
#if 0
|
||||
address_t aspace = (preserveAddressSpace ? L4SYS_ADDRESS_SPACE : ANY_ADDR);
|
||||
BPSingleListener singlestepping_event(ANY_ADDR, aspace);
|
||||
simulator.addListener(&singlestepping_event);
|
||||
@ -143,13 +149,14 @@ BaseListener *L4SysExperiment::singleStep(bool preserveAddressSpace) {
|
||||
param->msg.set_resulttype(param->msg.TIMEOUT);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
param->msg.set_output(sanitised(currentOutput.c_str()));
|
||||
param->msg.set_details("Timed out immediately after injecting");
|
||||
|
||||
m_jc.sendResult(*param);
|
||||
terminate(0);
|
||||
}
|
||||
return ev;
|
||||
#endif
|
||||
}
|
||||
|
||||
void L4SysExperiment::injectInstruction(
|
||||
@ -195,11 +202,11 @@ void L4SysExperiment::terminate(int reason) {
|
||||
}
|
||||
|
||||
void L4SysExperiment::terminateWithError(string details, int reason) {
|
||||
param->msg.set_resulttype(param->msg.UNKNOWN);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
param->msg.set_details(details);
|
||||
L4SysProtoMsg_Result *result = param->msg.add_result();
|
||||
result->set_resulttype(param->msg.UNKNOWN);
|
||||
result->set_resultdata(simulator.getCPU(0).getInstructionPointer());
|
||||
result->set_output(sanitised(currentOutput.c_str()));
|
||||
result->set_details(details);
|
||||
|
||||
m_jc.sendResult(*param);
|
||||
terminate(reason);
|
||||
@ -237,7 +244,7 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp)
|
||||
map<address_t, unsigned> times_called_map;
|
||||
bool injecting = false;
|
||||
|
||||
std::ofstream out("trace.pb");
|
||||
ogzstream out("trace.pb");
|
||||
ProtoOStream *os = new ProtoOStream(&out);
|
||||
|
||||
while (bp.getTriggerInstructionPointer() != L4SYS_FUNC_EXIT) {
|
||||
@ -281,6 +288,7 @@ void L4SysExperiment::collectInstructionTrace(fail::BPSingleListener& bp)
|
||||
// the generic *-trace tools
|
||||
// XXX: need to log CR3 if we want multiple binaries here
|
||||
Trace_Event e;
|
||||
e.set_time_delta(1);
|
||||
e.set_ip(curr_addr);
|
||||
os->writeMessage(&e);
|
||||
}
|
||||
@ -317,13 +325,14 @@ void L4SysExperiment::goldenRun(fail::BPSingleListener& bp)
|
||||
<< simulator.getCPU(0).getInstructionPointer()
|
||||
<< endl;
|
||||
|
||||
std::string golden_run;
|
||||
ofstream golden_run_file(L4SYS_CORRECT_OUTPUT);
|
||||
bp.setWatchInstructionPointer(L4SYS_FUNC_EXIT);
|
||||
simulator.addListener(&bp);
|
||||
BaseListener* ev = waitIOOrOther(true);
|
||||
if (ev == &bp) {
|
||||
golden_run.assign(output.c_str());
|
||||
golden_run_file << output.c_str();
|
||||
golden_run.assign(currentOutput.c_str());
|
||||
golden_run_file << currentOutput.c_str();
|
||||
log << "Output successfully logged!" << endl;
|
||||
} else {
|
||||
log
|
||||
@ -364,6 +373,9 @@ bool L4SysExperiment::run() {
|
||||
log << "Important data missing - call \"prepare\" first." << endl;
|
||||
terminate(10);
|
||||
}
|
||||
|
||||
// Read the golden run output for validation purposes
|
||||
std::string golden_run;
|
||||
ifstream golden_run_file(L4SYS_CORRECT_OUTPUT);
|
||||
|
||||
if (!golden_run_file.good()) {
|
||||
@ -377,12 +389,7 @@ bool L4SysExperiment::run() {
|
||||
|
||||
golden_run_file.close();
|
||||
|
||||
//the generated output probably has a similar length
|
||||
output.reserve(teststruct.st_size);
|
||||
|
||||
log << "restoring state" << endl;
|
||||
simulator.restore(L4SYS_STATE_FOLDER);
|
||||
|
||||
// get the experiment parameters
|
||||
log << "asking job server for experiment parameters" << endl;
|
||||
if (!m_jc.getParam(*param)) {
|
||||
log << "Dying." << endl;
|
||||
@ -390,14 +397,39 @@ bool L4SysExperiment::run() {
|
||||
terminate(1);
|
||||
}
|
||||
|
||||
int instr_offset = param->msg.instr_offset();
|
||||
int bit_offset = param->msg.bit_offset();
|
||||
int exp_type = param->msg.exp_type();
|
||||
int instr_offset = param->msg.fsppilot().injection_instr();
|
||||
int regData = param->msg.fsppilot().data_address();
|
||||
|
||||
log << " got job parameters: offs " << hex << instr_offset
|
||||
<< " bit " << bit_offset << " exp " << exp_type << endl;
|
||||
int reg, width, offset;
|
||||
reg = ((regData >> 8) & 0xF) + 1; // regs start at 1
|
||||
width = (regData >> 4) & 0xF;
|
||||
offset = regData & 0xF;
|
||||
|
||||
log << "Inject type " << exp_type << " at instr. offset " << instr_offset
|
||||
<< " reg data (" << reg << ", " << width << ", "
|
||||
<< offset << ")" << std::endl;
|
||||
|
||||
/* Each experiment message stands for 8 bits to be tested */
|
||||
for (unsigned bit_offset = 0; bit_offset < 8; ++bit_offset) {
|
||||
|
||||
//the generated output probably has a similar length
|
||||
currentOutput.clear();
|
||||
currentOutput.reserve(teststruct.st_size);
|
||||
simulator.clearListeners();
|
||||
|
||||
L4SysProtoMsg_Result *result = param->msg.add_result();
|
||||
result->set_instr_offset(instr_offset);
|
||||
result->set_bit_offset(bit_offset + 8 * offset);
|
||||
result->set_register_offset(static_cast<L4SysProtoMsg_RegisterType>(reg));
|
||||
|
||||
// restore experiment state
|
||||
log << "restoring state" << endl;
|
||||
simulator.restore(L4SYS_STATE_FOLDER);
|
||||
log << "EIP = " << hex << simulator.getCPU(0).getInstructionPointer() << endl;
|
||||
|
||||
#ifdef L4SYS_FILTER_INSTRUCTIONS
|
||||
// XXX still needed???
|
||||
ifstream instr_list_file(L4SYS_INSTRUCTION_LIST, ios::binary);
|
||||
|
||||
if (!instr_list_file.good()) {
|
||||
@ -429,9 +461,18 @@ bool L4SysExperiment::run() {
|
||||
waitIOOrOther(true);
|
||||
|
||||
// note at what IP we will do the injection
|
||||
address_t testIP = param->msg.fsppilot().injection_instr_absolute() & 0xFFFFFFFF;
|
||||
address_t injection_ip =
|
||||
simulator.getCPU(0).getInstructionPointer();
|
||||
param->msg.set_injection_ip(injection_ip);
|
||||
result->set_injection_ip(injection_ip);
|
||||
log << std::hex << "testIP " << testIP << " <-> " << injection_ip
|
||||
<< " inject_ip_abs" << std::endl;
|
||||
if (testIP != injection_ip) {
|
||||
stringstream ss;
|
||||
ss << std::hex << "Test IP " << testIP << " does not match injection IP "
|
||||
<< injection_ip << std::endl;
|
||||
terminateWithError(ss.str(), 19);
|
||||
}
|
||||
|
||||
#ifdef L4SYS_FILTER_INSTRUCTIONS
|
||||
// only works if we filter instructions
|
||||
@ -447,16 +488,11 @@ bool L4SysExperiment::run() {
|
||||
|
||||
// inject
|
||||
if (exp_type == param->msg.GPRFLIP) {
|
||||
if (!param->msg.has_register_offset()) {
|
||||
terminateWithError(
|
||||
"Sent package did not contain the injection location (register offset)",
|
||||
30);
|
||||
}
|
||||
int reg_offset = param->msg.register_offset();
|
||||
int reg_offset = reg; // XXX redundant
|
||||
ConcreteCPU& cpu = simulator.getCPU(0);
|
||||
Register *reg_target = cpu.getRegister(reg_offset - 1);
|
||||
regdata_t data = cpu.getRegisterContent(reg_target);
|
||||
regdata_t newdata = data ^ (1 << bit_offset);
|
||||
regdata_t newdata = data ^ (1 << (bit_offset + 8 * offset));
|
||||
cpu.setRegisterContent(reg_target, newdata);
|
||||
|
||||
// do the logging in case everything worked out
|
||||
@ -464,7 +500,10 @@ bool L4SysExperiment::run() {
|
||||
log << "IP " << hex << simulator.getCPU(0).getInstructionPointer()
|
||||
<< " register data: 0x" << hex << ((int) data) << " -> 0x"
|
||||
<< ((int) newdata) << endl;
|
||||
} else if (exp_type == param->msg.IDCFLIP) {
|
||||
}
|
||||
// XXX: Fixme to work with database campaign!
|
||||
#if 0
|
||||
else if (exp_type == param->msg.IDCFLIP) {
|
||||
// this is a twisted one
|
||||
|
||||
// initial definitions
|
||||
@ -579,8 +618,7 @@ bool L4SysExperiment::run() {
|
||||
|
||||
// some declarations
|
||||
GPRegisterId bochs_reg = Udis86::udisGPRToFailBochsGPR(which);
|
||||
param->msg.set_register_offset(
|
||||
static_cast<L4SysProtoMsg_RegisterType>(bochs_reg + 1));
|
||||
param->msg.set_register_offset(static_cast<L4SysProtoMsg_RegisterType>(bochs_reg + 1));
|
||||
ConcreteCPU &cpu = simulator.getCPU(0);
|
||||
Register *bochsRegister = cpu.getRegister(bochs_reg);
|
||||
Register *exchangeRegister = NULL;
|
||||
@ -675,6 +713,7 @@ bool L4SysExperiment::run() {
|
||||
// do the logging
|
||||
logInjection();
|
||||
}
|
||||
#endif
|
||||
|
||||
// aftermath
|
||||
BPSingleListener ev_done(L4SYS_FUNC_EXIT, L4SYS_ADDRESS_SPACE);
|
||||
@ -682,8 +721,7 @@ bool L4SysExperiment::run() {
|
||||
|
||||
unsigned instr_left = L4SYS_TOTINSTR - instr_offset; // XXX offset is in NUMINSTR, TOTINSTR is higher
|
||||
BPSingleListener ev_incomplete(ANY_ADDR, L4SYS_ADDRESS_SPACE);
|
||||
ev_incomplete.setCounter(
|
||||
static_cast<unsigned>(instr_left * 1.1));
|
||||
ev_incomplete.setCounter(static_cast<unsigned>(instr_left * 1.1));
|
||||
simulator.addListener(&ev_incomplete);
|
||||
|
||||
TimerListener ev_timeout(calculateTimeout(instr_left));
|
||||
@ -698,32 +736,31 @@ bool L4SysExperiment::run() {
|
||||
* the string compare is done on C strings
|
||||
*/
|
||||
if (ev == &ev_done) {
|
||||
if (strcmp(output.c_str(), golden_run.c_str()) == 0) {
|
||||
if (strcmp(currentOutput.c_str(), golden_run.c_str()) == 0) {
|
||||
log << "Result DONE" << endl;
|
||||
param->msg.set_resulttype(param->msg.DONE);
|
||||
result->set_resulttype(param->msg.DONE);
|
||||
} else {
|
||||
log << "Result WRONG" << endl;
|
||||
param->msg.set_resulttype(param->msg.WRONG);
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
result->set_resulttype(param->msg.WRONG);
|
||||
result->set_output(sanitised(currentOutput.c_str()));
|
||||
}
|
||||
} else if (ev == &ev_incomplete) {
|
||||
log << "Result INCOMPLETE" << endl;
|
||||
param->msg.set_resulttype(param->msg.INCOMPLETE);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
result->set_resulttype(param->msg.INCOMPLETE);
|
||||
result->set_resultdata(simulator.getCPU(0).getInstructionPointer());
|
||||
result->set_output(sanitised(currentOutput.c_str()));
|
||||
} else if (ev == &ev_timeout) {
|
||||
log << "Result TIMEOUT" << endl;
|
||||
param->msg.set_resulttype(param->msg.TIMEOUT);
|
||||
param->msg.set_resultdata(
|
||||
simulator.getCPU(0).getInstructionPointer());
|
||||
param->msg.set_output(sanitised(output.c_str()));
|
||||
result->set_resulttype(param->msg.TIMEOUT);
|
||||
result->set_resultdata(simulator.getCPU(0).getInstructionPointer());
|
||||
result->set_output(sanitised(currentOutput.c_str()));
|
||||
} else {
|
||||
log << "Result WTF?" << endl;
|
||||
stringstream ss;
|
||||
ss << "eventid " << ev;
|
||||
terminateWithError(ss.str(), 50);
|
||||
}
|
||||
}
|
||||
|
||||
m_jc.sendResult(*param);
|
||||
#endif
|
||||
|
||||
@ -30,6 +30,7 @@ private:
|
||||
fail::JobClient m_jc; //!< the job client connecting to the campaign server
|
||||
fail::Logger log; //<! the logger
|
||||
L4SysExperimentData *param; //<! the parameter set currently in use by the client
|
||||
std::string currentOutput; //<! output for the current experiment run
|
||||
public:
|
||||
L4SysExperiment();
|
||||
~L4SysExperiment();
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
import "DatabaseCampaignMessage.proto";
|
||||
|
||||
message L4SysProtoMsg {
|
||||
|
||||
// experiment types
|
||||
enum ExperimentType {
|
||||
GPRFLIP = 1;
|
||||
@ -6,10 +9,6 @@ message L4SysProtoMsg {
|
||||
IDCFLIP = 3;
|
||||
ALUINSTR = 4;
|
||||
}
|
||||
// parameters
|
||||
required ExperimentType exp_type = 1;
|
||||
required int32 instr_offset = 2;
|
||||
required int32 bit_offset = 3;
|
||||
|
||||
// registers
|
||||
enum RegisterType {
|
||||
@ -22,7 +21,6 @@ message L4SysProtoMsg {
|
||||
ESI = 7;
|
||||
EDI = 8;
|
||||
}
|
||||
optional RegisterType register_offset = 4;
|
||||
|
||||
// results
|
||||
// make these optional to reduce overhead for server->client communication
|
||||
@ -33,14 +31,26 @@ message L4SysProtoMsg {
|
||||
WRONG = 4;
|
||||
UNKNOWN = 5;
|
||||
}
|
||||
|
||||
required DatabaseCampaignMessage fsppilot = 1;
|
||||
required ExperimentType exp_type = 2;
|
||||
|
||||
repeated group Result = 3 {
|
||||
// parameters
|
||||
required int32 instr_offset = 1;
|
||||
required int32 bit_offset = 2 [(sql_primary_key) = true];
|
||||
|
||||
optional RegisterType register_offset = 3;
|
||||
|
||||
// instruction pointer where injection was done
|
||||
optional uint32 injection_ip = 5;
|
||||
optional uint32 injection_ip = 4;
|
||||
// result type, see above
|
||||
optional ResultType resulttype = 6;
|
||||
optional ResultType resulttype = 5;
|
||||
// result data, depending on resulttype (see source code)
|
||||
optional uint32 resultdata = 7;
|
||||
optional uint32 resultdata = 6;
|
||||
// generated output
|
||||
optional string output = 8;
|
||||
optional string output = 7;
|
||||
// optional textual description of what happened
|
||||
optional string details = 9;
|
||||
optional string details = 8;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user