Files
fail/tools/import-trace/MemoryImporter.cc
Christian Dietrich be8d5edbc3 import-trace: reorder functionality in importer
BasicImporter is renamed to MemoryImporter. An alias for BasicImporter
in the cmdline interface will remain. The MemoryImporter does now only
handle memory and IP events. The simulation time, dynamic instruction
count and handling of open ECs is moved to Importer.

Change-Id: I04eb0fd4b52fbf5b0ca9ab97778a62130cb626ee
2013-07-03 13:19:12 +02:00

58 lines
2.1 KiB
C++

#include "util/Logger.hpp"
#include "MemoryImporter.hpp"
using namespace fail;
static fail::Logger LOG("MemoryImporter");
bool MemoryImporter::handle_ip_event(simtime_t curtime, instruction_count_t instr, const Trace_Event &ev) {
return true;
}
bool MemoryImporter::handle_mem_event(simtime_t curtime, instruction_count_t instr,
const Trace_Event &ev) {
address_t from = ev.memaddr(), to = ev.memaddr() + ev.width();
// Iterate over all accessed bytes
// FIXME Keep complete trace information (access width)?
// advantages: may be used for pruning strategies, complete value would be visible; less DB entries
// disadvantages: may need splitting when width varies, lots of special case handling
// Probably implement this in a separate importer when necessary.
for (address_t data_address = from; data_address < to; ++data_address) {
// skip events outside a possibly supplied memory map
if (m_mm && !m_mm->isMatching(data_address)) {
continue;
}
margin_info_t left_margin = getOpenEC(data_address);
margin_info_t right_margin;
right_margin.time = curtime;
right_margin.dyninstr = instr; // !< The current instruction
right_margin.ip = ev.ip();
// skip zero-sized intervals: these can occur when an instruction
// accesses a memory location more than once (e.g., INC, CMPXCHG)
// FIXME: look at timing instead?
if (left_margin.dyninstr > right_margin.dyninstr) {
continue;
}
// we now have an interval-terminating R/W event to the memaddr
// we're currently looking at; the EC is defined by
// data_address, dynamic instruction start/end, the absolute PC at
// the end, and time start/end
access_info_t access;
access.access_type = ev.accesstype() == ev.READ ? 'R' : 'W';
access.data_address = data_address;
access.data_width = 1; // exactly one byte
if (!add_trace_event(left_margin, right_margin, access)) {
LOG << "add_trace_event failed" << std::endl;
return false;
}
// next interval must start at next instruction; the aforementioned
// skipping mechanism wouldn't work otherwise
newOpenEC(data_address, curtime + 1, instr + 1, ev.ip());
}
return true;
}