introduce convert-trace tool
The input (taken on stdin) is a gem5.opt --debug-flags=MemoryAccess trace (--format gem5), or a dump-trace output (--format dump) for easy trace synthesis (for testing purposes). gem5 format: Currently imports physical, not virtual memory addresses. dump format: Currently ignores extended trace information. Change-Id: Ic26a996d6fb9ce4175c855fadcbcff9ac9263888
This commit is contained in:
93
tools/convert-trace/Gem5Converter.cc
Normal file
93
tools/convert-trace/Gem5Converter.cc
Normal file
@ -0,0 +1,93 @@
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include "util/Logger.hpp"
|
||||
#include "comm/TracePlugin.pb.h"
|
||||
#include "Gem5Converter.hpp"
|
||||
|
||||
using namespace fail;
|
||||
using std::stringstream;
|
||||
using std::endl;
|
||||
using std::hex;
|
||||
using std::dec;
|
||||
|
||||
static Logger LOG("Gem5Converter", true);
|
||||
|
||||
bool Gem5Converter::convert()
|
||||
{
|
||||
char buf[2048], dummy[2048];
|
||||
int64_t prev_cycle = 0, cycle;
|
||||
uint64_t cur_ip = 0;
|
||||
bool ifetch_seen = false;
|
||||
|
||||
while (m_input.getline(buf, sizeof(buf))) {
|
||||
Trace_Event ev;
|
||||
// reset ifetch_seen in case we're getting multiple concatenated gem5 traces
|
||||
if (strstr(buf, "http://gem5.org")) {
|
||||
ifetch_seen = false;
|
||||
continue;
|
||||
}
|
||||
if (!strstr(buf, "system.physmem") || strstr(buf, "access wrote")) {
|
||||
continue;
|
||||
}
|
||||
// 5000: system.physmem: access wrote 4 bytes to address f7ee8
|
||||
// 5000: system.physmem: Write of size 4 on address 0xf7ee8 data 0x61190
|
||||
// 6000: system.physmem: IFetch of size 4 on address 0xd58 data 0xe59f000c
|
||||
// 6000: system.physmem: Read of size 4 on address 0xd6c data 0x8e2c
|
||||
// 161000: system.physmem: 00000000 4c 69 6e 75 78 00 00 00 00 00 00 00 00 00 00 00 Linux
|
||||
|
||||
std::stringstream ss(buf);
|
||||
std::string access_type;
|
||||
unsigned access_width;
|
||||
uint64_t access_address;
|
||||
ss >> dec >> cycle >> dummy >> dummy >> access_type
|
||||
>> dummy >> dummy >> dec >> access_width
|
||||
>> dummy >> dummy >> hex >> access_address;
|
||||
if (!ss) {
|
||||
if (ifetch_seen && !access_type.c_str()[0] == '0') {
|
||||
LOG << "input mismatch, input = " << buf << endl;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cycle - prev_cycle > 0) {
|
||||
ev.set_time_delta(cycle - prev_cycle);
|
||||
prev_cycle = cycle;
|
||||
} else if (cycle - prev_cycle < 0) {
|
||||
LOG << "ignoring time discontinuity " << dec << prev_cycle << " -> " << cycle << endl;
|
||||
prev_cycle = cycle;
|
||||
}
|
||||
|
||||
if (access_type == "IFetch") {
|
||||
ifetch_seen = true;
|
||||
cur_ip = access_address;
|
||||
ev.set_ip(cur_ip);
|
||||
//LOG << "ip = " << hex << cur_ip << endl;
|
||||
|
||||
} else {
|
||||
bool is_read;
|
||||
if (access_type == "Read") {
|
||||
is_read = true;
|
||||
} else if (access_type == "Write") {
|
||||
is_read = false;
|
||||
} else if (access_type.c_str()[0] == '0') {
|
||||
continue;
|
||||
} else {
|
||||
LOG << "input mismatch, input = " << buf << endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!ifetch_seen) {
|
||||
// skip all accesses before the first ifetch
|
||||
continue;
|
||||
}
|
||||
ev.set_ip(cur_ip);
|
||||
ev.set_memaddr(access_address);
|
||||
ev.set_width(access_width);
|
||||
ev.set_accesstype(is_read ? ev.READ : ev.WRITE);
|
||||
//cout << "ip = " << hex << cur_ip << " mem " << access_address << " " << access_width << " " << (is_read ? 'R' : 'W') << endl;
|
||||
}
|
||||
m_ps.writeMessage(&ev);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
Reference in New Issue
Block a user