#include #include #include #include "experiment.hpp" #include "util/CommandLine.hpp" using namespace std; using namespace fail; #define EXPERIMENT_CONF "experiment.conf" static void parameterMissing(fail::Logger log, string c) { log << "Error: Missing config parameter (" << c << ")" << endl; simulator.terminate(1); } int L4SysExperiment::updateConfig(string parameter, string value) { bool replaced = false; std::list buf; ifstream is(EXPERIMENT_CONF); if (is) { while(!is.eof()) { string tmp; getline(is, tmp); if( !tmp.compare(0, parameter.length() + 1, string(parameter + "=")) ) { buf.push_back(string(parameter + "=" + value) ); replaced = true; } else { buf.push_back(tmp); } } } else { cerr << "Open config file failed" << endl; return -1; } is.close(); ofstream os(EXPERIMENT_CONF); if (os) { if(!replaced) os << parameter << "=" << value << endl; while(!buf.empty()) { os << buf.front() << endl; buf.pop_front(); } } else { cerr << "Open config file for update failed" << endl; return -1; } return 0; } void L4SysExperiment::parseOptions(L4SysConfig &conf) { CommandLine &cmd = CommandLine::Inst(); ifstream fin(EXPERIMENT_CONF); //Currently we don't delete the parameterstring to avoid deling ptr in the cmd //Nevertheless, we shouldn't need them, so deleting should be safe //We interpret the file content as parameters to our main function, so we don't //need an own parser. Program parameters appear earlier in the parameter list //and will overwrite the parameters from the config file. while(fin.good()) { string buffer; string prefix("--"); getline(fin, buffer, '\n'); if( !(strncmp(buffer.c_str(),"#",1) == 0) && !(strncmp(buffer.c_str()," ",1) == 0 ) && !(strncmp(buffer.c_str(),"",1) == 0 ) ) { string t(prefix + buffer); //Workarround, if we just alloc t.length some of the arguments values //disappear char *c = (char *) malloc(t.length() * 2); strcpy(c, t.c_str()); cmd.add_args( c ); } } cout << "end of config file" << endl; cmd.addOption("", "", Arg::None, "USAGE: fail-client -Wf,[option] -Wf,[option] ... "); CommandLine::option_handle HELP = cmd.addOption("h", "help", Arg::None, "-h,--help \tPrint usage and exit"); CommandLine::option_handle STEP = cmd.addOption("s", "step", Arg::Optional, "-s,--step \tSpecify preparation step, without this argumnt fail-client start in experiment mode (cr3: get CR3, cc: Create Checkpoint, it: collect instruction trace, gr: golden run, all: do the whole preparation)"); CommandLine::option_handle OPT_MAX_INSTR_BYTES = cmd.addOption("", "max_instr_bytes", Arg::Optional, "--max_instr_bytes \t define MAX_INSTR_BYTES"); CommandLine::option_handle OPT_ADDRESS_SPACE = cmd.addOption("", "address_space", Arg::Optional, "--address_space \t define L4SYS_ADDRESS_SPACE"); CommandLine::option_handle OPT_ADDRESS_SPACE_TRACE = cmd.addOption("", "address_space_trace", Arg::Optional, "--address_space_trace \t define L4SYS_ADDRESS_SPACE_TRACE"); CommandLine::option_handle OPT_FUNC_ENTRY = cmd.addOption("", "func_entry", Arg::Optional, "--func_entry \t define L4SYS_FUNC_ENTRY"); CommandLine::option_handle OPT_FUNC_EXIT = cmd.addOption("", "func_exit", Arg::Optional, "--func_exit \t define L4SYS_FUNC_EXIT"); CommandLine::option_handle OPT_FILTER_ENTRY = cmd.addOption("", "filter_entry", Arg::Optional, "--filter_entry \t define L4SYS_FILTER_ENTRY"); CommandLine::option_handle OPT_FILTER_EXIT = cmd.addOption("", "filter_exit", Arg::Optional, "--filter_exit \t define L4SYS_FILTER_EXIT"); CommandLine::option_handle OPT_BREAK_BLINK = cmd.addOption("", "break_blink", Arg::Optional, "--break_blink \t define L4SYS_BREAK_BLINK"); CommandLine::option_handle OPT_BREAK_LONGJMP = cmd.addOption("", "break_longjmp", Arg::Optional, "--break_longjmp \t define L4SYS_BREAK_LONGJMP"); CommandLine::option_handle OPT_BREAK_EXIT = cmd.addOption("", "break_exit", Arg::Optional, "--break_exit \t define L4SYS_BREAK_EXIT"); CommandLine::option_handle OPT_NUMINSTR = cmd.addOption("", "numinstr", Arg::Optional, "--numinstr \t define L4SYS_NUMINSTR"); CommandLine::option_handle OPT_TOTINSTR = cmd.addOption("", "totinstr", Arg::Optional, "--totinstr \t define L4SYS_TOTINSTR"); CommandLine::option_handle OPT_EMUL_IPS = cmd.addOption("", "emul_ips", Arg::Optional, "--emul_ips \t define L4SYS_BOCHS_IPS"); CommandLine::option_handle OPT_STATE_FOLDER = cmd.addOption("", "state_folder", Arg::Optional, "--state_folder \t define L4SYS_STATE_FOLDER"); CommandLine::option_handle OPT_INSTRUCTION_LIST = cmd.addOption("", "instruction_list", Arg::Optional, "--instruction_list \t define L4SYS_INSTRUCTION_LIST"); CommandLine::option_handle OPT_CORRECT_OUTPUT = cmd.addOption("", "golden_run", Arg::Optional, "--correct_output \t define L4SYS_CORRECT_OUTPUT"); CommandLine::option_handle OPT_FILTER = cmd.addOption("", "filter", Arg::Optional, "--filter \t define L4SYS_FILTER"); CommandLine::option_handle OPT_TRACE = cmd.addOption("", "trace", Arg::Optional, "--trace \t define outputfile for trace (default trace.pb)"); if (!cmd.parse()) { cerr << "Error parsing arguments." << endl; simulator.terminate(1); } else if (cmd[HELP]) { cmd.printUsage(); simulator.terminate(0); } if (cmd[OPT_MAX_INSTR_BYTES]) { conf.max_instr_bytes = strtol(cmd[OPT_MAX_INSTR_BYTES].arg, NULL, 10); log << "max_instr_bytes: "<< dec << conf.max_instr_bytes << endl; } else { parameterMissing(log, "max_instr_bytes"); } if (cmd[OPT_ADDRESS_SPACE]) { conf.address_space = strtol(cmd[OPT_ADDRESS_SPACE].arg, NULL, 16); log << "address_space: "<< hex << conf.address_space << endl; } else { parameterMissing(log, "adress_space"); } if (cmd[OPT_ADDRESS_SPACE_TRACE]) { conf.address_space_trace = strtol(cmd[OPT_ADDRESS_SPACE_TRACE].arg, NULL, 16); if( conf.address_space_trace == 0 ) conf.address_space_trace = conf.address_space; else log << "address_space_trace: "<< hex << conf.address_space_trace << endl; } else { conf.address_space_trace = conf.address_space; } if (cmd[OPT_FUNC_ENTRY]) { conf.func_entry = strtol(cmd[OPT_FUNC_ENTRY].arg, NULL, 16); log << "func_entry: "<< hex << conf.func_entry << endl; } else{ parameterMissing(log, "filter_entry"); } if (cmd[OPT_FUNC_EXIT]) { conf.func_exit = strtol(cmd[OPT_FUNC_EXIT].arg, NULL, 16); log << "func_exit: "<< hex << conf.func_exit << endl; } else { parameterMissing(log, "filter_exit"); } if (cmd[OPT_FILTER_ENTRY]) { conf.filter_entry = strtol(cmd[OPT_FILTER_ENTRY].arg, NULL, 16); log << "filter_entry: "<< hex << conf.filter_entry << endl; } else { conf.filter_entry = conf.func_entry; } if (cmd[OPT_FILTER_EXIT]) { conf.filter_exit = strtol(cmd[OPT_FILTER_EXIT].arg, NULL, 16); log << "filter_exit: "<< hex << conf.filter_exit << endl; } else { conf.filter_exit = conf.func_exit; } if (cmd[OPT_BREAK_BLINK]) { conf.break_blink = strtol(cmd[OPT_BREAK_BLINK].arg, NULL, 16); log << "break_blink: "<< hex << conf.break_blink << endl; } else { conf.break_blink = 0; } if (cmd[OPT_BREAK_LONGJMP]) { conf.break_longjmp = strtol(cmd[OPT_BREAK_LONGJMP].arg, NULL, 16); log << "break_longjmp: "<< hex << conf.break_longjmp << endl; } else { conf.break_longjmp = 0; } if (cmd[OPT_BREAK_EXIT]) { conf.break_exit = strtol(cmd[OPT_BREAK_EXIT].arg, NULL, 16); log << "break_exit: "<< hex << conf.break_exit << endl; } else { conf.break_exit = 0; } if (cmd[OPT_NUMINSTR]) { conf.numinstr = strtol(cmd[OPT_NUMINSTR].arg, NULL, 10); log << "numinstr: "<< dec << conf.numinstr << endl; } else { parameterMissing(log, "numinstr"); } if (cmd[OPT_TOTINSTR]) { conf.totinstr = strtol(cmd[OPT_TOTINSTR].arg, NULL, 10); log << "totinstr: "<< dec << conf.totinstr << endl; } else { parameterMissing(log, "totinstr"); } if (cmd[OPT_EMUL_IPS]) { conf.emul_ips = strtol(cmd[OPT_EMUL_IPS].arg, NULL, 10); log << "emul_ips = " << dec << conf.emul_ips << endl; } else { parameterMissing(log, "emul_ips"); } if (cmd[OPT_STATE_FOLDER]) { conf.state_folder = std::string(cmd[OPT_STATE_FOLDER].arg); log << "state_folder: "<< conf.state_folder << endl; } else { conf.state_folder = "l4sys.state"; } if (cmd[OPT_INSTRUCTION_LIST]) { conf.instruction_list = std::string(cmd[OPT_INSTRUCTION_LIST].arg); log << "instruction_list: "<< conf.instruction_list << endl; } else { conf.instruction_list = "ip.list"; } if (cmd[OPT_CORRECT_OUTPUT]) { conf.golden_run = std::string(cmd[OPT_CORRECT_OUTPUT].arg); log << "golden_run: "<< conf.golden_run << endl; } else { conf.golden_run = "golden.out"; } if (cmd[OPT_FILTER]) { conf.filter = std::string(cmd[OPT_FILTER].arg); log << "filter: "<< conf.filter << endl; } else { conf.filter = "filter.list"; } if (cmd[OPT_TRACE]) { conf.trace = std::string(cmd[OPT_TRACE].arg); log << "trace: "<< conf.trace << endl; } else { conf.trace = "trace.pb"; } if (cmd[STEP]) { if (!std::string("cr3").compare(cmd[STEP].arg) ) { log << "calculate cr3" << endl; conf.step = L4SysConfig::GET_CR3; } else if (!std::string("cc").compare(cmd[STEP].arg) ) { log << "Create Checkpoint" << endl; conf.step = L4SysConfig::CREATE_CHECKPOINT; } else if (!std::string("it").compare(cmd[STEP].arg) ) { log << "collect instruction trace" << endl; conf.step = L4SysConfig::COLLECT_INSTR_TRACE; } else if (!std::string("gr").compare(cmd[STEP].arg) ) { log << "golden run" << endl; conf.step = L4SysConfig::GOLDEN_RUN; } else if (!std::string("all").compare(cmd[STEP].arg) ) { log << "do all preparation steps" << endl; conf.step = L4SysConfig::FULL_PREPARATION; } else { cerr << "Wrong argument for option '--step'" << endl; simulator.terminate(1); } } else { conf.step = L4SysConfig::NO_PREP; } }