#include #include #include #include #include #include #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" #include #include #include #include using namespace rapidjson; using namespace std; iss::plugin::cov::cov(std::string const &filename) : instr_if(nullptr) , filename(filename) { output.open("output.trc"); jumped = false; first = true; } iss::plugin::cov::~cov() { output.close(); } bool iss::plugin::cov::registration(const char *const version, vm_if& vm) { instr_if = vm.get_arch()->get_instrumentation_if(); if(!instr_if) return false; const string core_name = instr_if->core_type_name(); if (filename.length() > 0) { ifstream is(filename); if (is.is_open()) { try { IStreamWrapper isw(is); Document d; ParseResult ok = d.ParseStream(isw); if(ok) { Value& val = d[core_name.c_str()]; if(val.IsArray()){ delays.reserve(val.Size()); for (auto it = val.Begin(); it != val.End(); ++it) { auto& name = (*it)["name"]; auto& size = (*it)["size"]; auto& delay = (*it)["delay"]; auto& branch = (*it)["branch"]; if(delay.IsArray()) { auto dt = delay[0].Get(); auto dnt = delay[1].Get(); delays.push_back(instr_desc{size.Get(), dt, dnt, branch.Get()}); } else if(delay.Is()) { auto d = delay.Get(); delays.push_back(instr_desc{size.Get(), d, d, branch.Get()}); } else throw runtime_error("JSON parse error"); } } else { LOG(ERR)<<"plugin cycle_estimate: could not find an entry for "<get_pc()) << "," << delay; // first = false; // } // if(instr_if->get_next_pc()-instr_if->get_pc() != delays[iinfo.instr_id].size/8){ // //The goal is to keep the output in start-target pairs, so after a jump the target address needs to get written // //to the output. If the target happens to also be a start, we keep the pairing by adding a 0-delay entry. // if (jumped) // output <<"\n" <get_pc()) << "," << 0; // output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; // jumped = true; // } // else{ // if (jumped){ // output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; // jumped = false; // } // else if(delay!=1){ // output <<"\n" << formatPC(instr_if->get_pc()) << "," << delay; // output <<"\n" << formatPC(instr_if->get_pc()) << "," << 0; // } // // } //source code for the full output auto delay = 0; size_t id = iinfo.instr_id; auto entry = delays[id]; auto call = (id==2 || id==3) && bit_sub<7,5>(instr_if->get_instr_word())!=0; bool taken = einfo.branch_taken; if (einfo.branch_taken) delay = entry.taken; else delay = entry.not_taken; output<get_pc() <<"," << delay << "\n"; }