Merge branch 'master' of ssh://vamos.informatik.uni-erlangen.de:29418/fail

This commit is contained in:
Björn Döbel
2013-09-10 11:54:29 +02:00
37 changed files with 451 additions and 81 deletions

59
cmake/FindMySQL.cmake Normal file
View File

@ -0,0 +1,59 @@
# Find the MySQL includes and client library
# This module defines
# MYSQL_INCLUDE_DIR, where to find mysql.h
# MYSQL_LIBRARIES, the libraries needed to use MySQL.
# MYSQL_FOUND, If false, do not try to use MySQL.
set(MYSQL_CONFIG_PREFER_PATH "$ENV{MYSQL_HOME}/bin" CACHE FILEPATH
"preferred path to MySQL (mysql_config)")
find_program(MYSQL_CONFIG mysql_config
${MYSQL_CONFIG_PREFER_PATH}
/usr/local/mysql/bin/
/usr/local/bin/
/usr/bin/
)
if(MYSQL_CONFIG)
message(STATUS "Using mysql_config: ${MYSQL_CONFIG}")
# set INCLUDE_DIR
exec_program(${MYSQL_CONFIG}
ARGS --include
OUTPUT_VARIABLE MYSQL_INCLUDE_DIR)
# set LIBRARY_DIR
exec_program(${MYSQL_CONFIG}
ARGS --libs_r
OUTPUT_VARIABLE MYSQL_LIBRARIES)
else(MYSQL_CONFIG)
# FIXME incomplete
find_path(MYSQL_INCLUDE_DIR mysql.h
/usr/local/include
/usr/local/include/mysql
/usr/local/mysql/include
/usr/local/mysql/include/mysql
/usr/include
/usr/include/mysql
#find_library(mysqlclient ...
# PATHS
# ${MYSQL_ADD_LIBRARY_PATH}
# /usr/lib/mysql
# /usr/local/lib
# /usr/local/lib/mysql
# /usr/local/mysql/lib
#)
)
endif(MYSQL_CONFIG)
set(MYSQL_INCLUDE_DIR ${MYSQL_INCLUDE_DIR} CACHE FILEPATH INTERNAL)
set(MYSQL_LIBRARIES ${MYSQL_LIBRARIES} CACHE FILEPATH INTERNAL)
if(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
set(MYSQL_FOUND TRUE CACHE INTERNAL "MySQL found")
message(STATUS "Found MySQL: ${MYSQL_INCLUDE_DIR}, ${MYSQL_LIBRARIES}")
else(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
set(MYSQL_FOUND FALSE CACHE INTERNAL "MySQL found")
message(STATUS "MySQL not found.")
endif(MYSQL_INCLUDE_DIR AND MYSQL_LIBRARIES)
mark_as_advanced(MYSQL_INCLUDE_DIR MYSQL_LIBRARIES)

View File

@ -8,9 +8,9 @@ namespace fail {
void CoroutineManager::m_invoke(void* pData)
{
//std::cerr << "CORO m_invoke " << co_current() << std::endl;
// TODO: Log-Level?
reinterpret_cast<ExperimentFlow*>(pData)->coroutine_entry();
ExperimentFlow *flow = reinterpret_cast<ExperimentFlow*>(pData);
flow->coroutine_entry();
simulator.removeFlow(flow);
//m_togglerstack.pop();
// FIXME: need to pop our caller
co_exit(); // deletes the associated coroutine memory as well
@ -20,7 +20,12 @@ void CoroutineManager::m_invoke(void* pData)
while (1); // freeze.
}
CoroutineManager::~CoroutineManager() { }
CoroutineManager::~CoroutineManager()
{
// Note that we do not destroy the associated coroutines; this causes
// problems when shutting down.
m_Flows.clear();
}
void CoroutineManager::toggle(ExperimentFlow* flow)
{
@ -53,7 +58,9 @@ void CoroutineManager::remove(ExperimentFlow* flow)
// find coroutine handle for this flow
flowmap_t::iterator it = m_Flows.find(flow);
if (it == m_Flows.end()) {
assert(false && "FATAL ERROR: Cannot remove flow");
// Not finding the flow to remove is not an error; especially when
// shutting down this is the common case, as ~CoroutineManager probably
// clears the flow list before the ExperimentFlow destructors run.
return;
}
corohandle_t coro = it->second;
@ -67,7 +74,9 @@ void CoroutineManager::remove(ExperimentFlow* flow)
// delete coroutine (and handle the special case we're removing
// ourselves)
if (coro == co_current()) {
co_exit();
if (!m_Terminated) {
co_exit();
}
} else {
co_delete(coro);
}

View File

@ -29,10 +29,12 @@ private:
std::stack<corohandle_t> m_togglerstack;
//! manages the run-calls for each ExperimentFlow-object
static void m_invoke(void* pData);
//! \c true if terminated explicitly using simulator.terminate()
bool m_Terminated;
public:
static const ExperimentFlow* SIM_FLOW; //!< the simulator coroutine flow
CoroutineManager() : m_simCoro(co_current()) { }
CoroutineManager() : m_simCoro(co_current()), m_Terminated(false) { }
~CoroutineManager();
/**
* Creates a new coroutine for the specified experiment flow.
@ -63,6 +65,12 @@ public:
* @return the current experiment flow.
*/
ExperimentFlow* getCurrent();
/**
* Sets the termination flag. This should be called when Fail
* exists due to a call to \c ::exit() (used, e.g., in
* \c SimulatorController::terminate()). This cannot be undone.
*/
void setTerminated() { m_Terminated = true; }
};
} // end-of-namespace: fail

View File

@ -13,6 +13,11 @@ namespace fail {
class ExperimentFlow {
public:
ExperimentFlow() { }
virtual ~ExperimentFlow()
{
simulator.clearListeners(this); // remove residual events
simulator.removeFlow(this);
}
/**
* Defines the experiment flow.
* @return \c true if the experiment was successful, \c false otherwise

View File

@ -217,6 +217,8 @@ void SimulatorController::terminate(int exCode)
// Attention: This could cause problems, e.g., because of non-closed sockets
std::cout << "[FAIL] Exit called by experiment with exit code: " << exCode << std::endl;
// TODO: (Non-)Verbose-Mode? Log-Level?
m_Flows.setTerminated(); // we are about to terminate
exit(exCode);
}

View File

@ -48,6 +48,10 @@ if(${LIB_IBERTY} STREQUAL LIB_IBERTY-NOTFOUND)
message(FATAL_ERROR "libiberty not found. Try installing binutils-dev: [ sudo aptitude install binutils-dev ]")
endif()
# libz required by gzstream
find_package(ZLIB REQUIRED)
include_directories(${ZLIB_INCLUDE_DIRS})
# objdump required by Diassembler.cc
set(THE_OBJDUMP "${ARCH_TOOL_PREFIX}objdump")
@ -61,7 +65,7 @@ mark_as_advanced(FAIL_OBJDUMP)
add_library(fail-util ${SRCS})
add_dependencies(fail-util fail-comm)
target_link_libraries(fail-util ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${LIB_IBERTY} )
target_link_libraries(fail-util ${PROTOBUF_LIBRARY} ${Boost_LIBRARIES} ${LIB_IBERTY} ${ZLIB_LIBRARIES})
option(BUILD_LLVM_DISASSEMBLER "Build the LLVM-based disassembler (LLVM 3.3 preferred, for 3.1 and 3.2 read doc/how-to-build.txt)" OFF)
if (BUILD_LLVM_DISASSEMBLER)

View File

@ -1,4 +1,3 @@
#ifndef __puma
#include "LLVMDisassembler.hpp"
using namespace fail;
@ -147,5 +146,3 @@ void LLVMDisassembler::disassemble()
}
void LLVMDisassembler::StringRefMemoryObject::anchor() {}
#endif

View File

@ -1,8 +1,6 @@
#ifndef __LLVMDISASSEMBLER_HPP__
#define __LLVMDISASSEMBLER_HPP__
#ifndef __puma
#include <iostream>
#include <vector>
#include <map>
@ -137,5 +135,4 @@ public:
}
#endif // puma
#endif // __LLVMDISASSEMBLER_HPP__

View File

@ -4,7 +4,6 @@
using namespace fail;
LLVMtoFailBochs::LLVMtoFailBochs() {
#ifndef __puma
/* These magic numbers are taken from the llvm compiler (MC), they
do not appear in any header. They hopefully will never
change */
@ -19,12 +18,12 @@ LLVMtoFailBochs::LLVMtoFailBochs() {
llvm_to_fail_map[45] = reginfo_t(RID_CBX, 32, 0); // EBX
llvm_to_fail_map[9] = reginfo_t(RID_CCX, 8, 8); // CH
llvm_to_fail_map[10] = reginfo_t(RID_CCX, 0xff); // CL
llvm_to_fail_map[10] = reginfo_t(RID_CCX, 8, 0); // CL
llvm_to_fail_map[28] = reginfo_t(RID_CCX, 16, 0); // CX
llvm_to_fail_map[46] = reginfo_t(RID_CCX); // ECX
llvm_to_fail_map[29] = reginfo_t(RID_CDX, 8, 8); // DH
llvm_to_fail_map[32] = reginfo_t(RID_CDX, 0xff); // DL
llvm_to_fail_map[32] = reginfo_t(RID_CDX, 8, 0); // DL
llvm_to_fail_map[42] = reginfo_t(RID_CDX, 16, 0); // DX
llvm_to_fail_map[48] = reginfo_t(RID_CDX); // EDX
@ -46,5 +45,4 @@ LLVMtoFailBochs::LLVMtoFailBochs() {
llvm_to_fail_map[54] = reginfo_t(RID_CSP); // ESP
llvm_to_fail_map[117] = reginfo_t(RID_CSP, 16, 0); // SP
llvm_to_fail_map[118] = reginfo_t(RID_CSP, 8, 0); // SPL
#endif
}

View File

@ -4,7 +4,6 @@
using namespace fail;
LLVMtoFailGem5::LLVMtoFailGem5() {
#ifndef __puma
/* These magic numbers are taken from the machine descriptions of
LLVM they (hopefully) will not change, since they are not exported
via a header */
@ -24,5 +23,4 @@ LLVMtoFailGem5::LLVMtoFailGem5() {
llvm_to_fail_map[105] = reginfo_t(RI_SP);
llvm_to_fail_map[40] = reginfo_t(RI_LR);
llvm_to_fail_map[43] = reginfo_t(RI_IP);
#endif
}

View File

@ -4,16 +4,14 @@
using namespace fail;
const LLVMtoFailTranslator::reginfo_t & LLVMtoFailTranslator::getFailRegisterID(unsigned int regid) {
#ifndef __puma
ltof_map_t::iterator it = llvm_to_fail_map.find(regid);
if( it != llvm_to_fail_map.end() ) {// found
return (*it).second;
} else { // not found
std::cout << "Fail ID for LLVM Register id " << regid << " not found :(" << std::endl;
std::cout << "Fail ID for LLVM Register id " << std::dec << regid << " not found :(" << std::endl;
//exit(EXIT_FAILURE);
return notfound;
}
#endif
}
regdata_t LLVMtoFailTranslator::getRegisterContent(ConcreteCPU& cpu, const reginfo_t &reginfo){

View File

@ -13,6 +13,12 @@ namespace fail {
*/
class LLVMtoFailTranslator {
public:
/**
* Maps registers to/from linear addresses usable for def/use-pruning
* purposes and storage in the database. Takes care that the linear
* addresses of x86 subregisters (e.g., AX represents the lower 16 bits of
* EAX) overlap with their siblings.
*/
struct reginfo_t {
int id;
regwidth_t width;
@ -20,18 +26,17 @@ public:
byte_t offset;
int toDataAddress() const {
// .. 5 4 | 7 6 5 4 | 3 2 1 0
// <reg> | <width> | <offset>
return (id << 8) | ((width/8) << 4) | (offset / 8);
// .. 5 4 | 3 2 1 0
// <reg> | <offset>
return (id << 4) | (offset / 8);
}
// does not recreate width or mask
static reginfo_t fromDataAddress(int addr) {
int id = addr >> 8;
regwidth_t width = ((addr >> 4) & 0xf) * 8;
byte_t offset = (addr & 0xf) * 8;
return reginfo_t(id, width, offset);
int id = addr >> 4;
byte_t offset = (addr & 0xf) * 8;
return reginfo_t(id, 0, offset);
}
reginfo_t(int id=-1, regwidth_t width = 32, byte_t offs = 0)
: id(id), width(width), mask((regwidth_t)((((long long)1 << width) - 1) << offs)), offset(offs) {};
};
@ -39,13 +44,16 @@ protected:
LLVMtoFailTranslator(){};
#ifndef __puma
typedef std::map<unsigned int, struct reginfo_t> ltof_map_t;
ltof_map_t llvm_to_fail_map;
#endif
public:
/**
* Translates a backend-specific register ID to a Fail register ID.
* @param regid A backend-specific register ID.
* @return A Fail* register ID, or LLVMtoFailTranslator::notfound if no
* mapping was found.
*/
const reginfo_t & getFailRegisterID(unsigned int regid);
regdata_t getRegisterContent(ConcreteCPU & cpu, const reginfo_t & reg);
@ -58,7 +66,7 @@ public:
}
int getFailRegisterId(unsigned int regid) { return this->getFailRegisterID(regid).id; };
private:
reginfo_t notfound;
};

View File

@ -21,6 +21,9 @@ find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
find_package(MySQL REQUIRED)
include_directories(${MYSQL_INCLUDE_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
## Build library
@ -30,6 +33,6 @@ target_link_libraries(fail-${EXPERIMENT_NAME} ${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 -Wl,--start-group fail-${EXPERIMENT_NAME} fail-sal fail-util fail-cpn fail-comm ${PROTOBUF_LIBRARY} ${Boost_THREAD_LIBRARY} -lmysqlclient -Wl,--end-group)
target_link_libraries(${EXPERIMENT_NAME}-server -Wl,--start-group fail-${EXPERIMENT_NAME} fail-sal fail-util fail-cpn fail-comm ${PROTOBUF_LIBRARY} ${Boost_THREAD_LIBRARY} ${MYSQL_LIBRARIES} -Wl,--end-group)
install(TARGETS ${EXPERIMENT_NAME}-server RUNTIME DESTINATION bin)

View File

@ -22,14 +22,17 @@ find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
find_package(MySQL REQUIRED)
include_directories(${MYSQL_INCLUDE_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
## Build library
add_library(fail-${EXPERIMENT_NAME} ${PROTO_SRCS} ${PROTO_HDRS} ${MY_CAMPAIGN_SRCS})
add_dependencies(fail-${EXPERIMENT_NAME} fail-tracing fail-comm)
target_link_libraries(fail-${EXPERIMENT_NAME} ${PROTOBUF_LIBRARY} -lmysqlclient_r)
target_link_libraries(fail-${EXPERIMENT_NAME} ${PROTOBUF_LIBRARY} ${MYSQL_LIBRARIES})
## 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} -lmysqlclient_r)
target_link_libraries(${EXPERIMENT_NAME}-server fail-${EXPERIMENT_NAME} fail ${PROTOBUF_LIBRARY} ${Boost_THREAD_LIBRARY} ${MYSQL_LIBRARIES})
install(TARGETS ${EXPERIMENT_NAME}-server RUNTIME DESTINATION bin)

View File

@ -1,8 +1,7 @@
#include "experiment.hpp"
#include "sal/SALInst.hpp"
static EcosKernelTestExperiment experiment;
void instantiateEcosKernelTestExperiment()
{
fail::simulator.addFlow(&experiment);
fail::simulator.addFlow(new EcosKernelTestExperiment);
}

View File

@ -12,6 +12,10 @@
// You need to provide the implementation of this function in your experiment
// directory:
void instantiate@EXPERIMENT_TYPE@();
// The experiment needs to be instantiated dynamically (on the stack, or the
// heap), as the ExperimentFlow destructor deregisters from the
// CoroutineManager which may not exist anymore if the global
// construction/destruction order is inappropriate.
aspect @EXPERIMENT_TYPE@ExperimentHook {
advice execution ("void fail::SimulatorController::initExperiments()") : after () {

View File

@ -9,10 +9,14 @@
#include "../experiments/@EXPERIMENT_NAME@/experiment.hpp"
#include "sal/SALInst.hpp"
// The experiment needs to be instantiated dynamically (on the stack, or the
// heap), as the ExperimentFlow destructor deregisters from the
// CoroutineManager which may not exist anymore if the global
// construction/destruction order is inappropriate.
aspect @EXPERIMENT_TYPE@ExperimentHook {
@EXPERIMENT_TYPE@ experiment;
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
fail::simulator.addFlow(&experiment);
fail::simulator.addFlow(new @EXPERIMENT_TYPE@);
}
};

View File

@ -21,6 +21,9 @@ find_package(Protobuf REQUIRED)
include_directories(${PROTOBUF_INCLUDE_DIRS})
include_directories(${CMAKE_CURRENT_BINARY_DIR})
find_package(MySQL REQUIRED)
include_directories(${MYSQL_INCLUDE_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
## Build library
@ -30,5 +33,5 @@ target_link_libraries(fail-${EXPERIMENT_NAME} ${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 -Wl,--start-group fail-${EXPERIMENT_NAME} fail-sal fail-util fail-cpn fail-comm ${PROTOBUF_LIBRARY} ${Boost_THREAD_LIBRARY} -lmysqlclient -Wl,--end-group)
target_link_libraries(${EXPERIMENT_NAME}-server -Wl,--start-group fail-${EXPERIMENT_NAME} fail-sal fail-util fail-cpn fail-comm ${PROTOBUF_LIBRARY} ${Boost_THREAD_LIBRARY} ${MYSQL_LIBRARIES} -Wl,--end-group)
install(TARGETS ${EXPERIMENT_NAME}-server RUNTIME DESTINATION bin)

View File

@ -1,8 +1,7 @@
#include "experiment.hpp"
#include "sal/SALInst.hpp"
static NanoJPEGExperiment experiment;
void instantiateNanoJPEGExperiment()
{
fail::simulator.addFlow(&experiment);
fail::simulator.addFlow(new NanoJPEGExperiment);
}

View File

@ -1,8 +1,7 @@
#include "experiment.hpp"
#include "sal/SALInst.hpp"
static RAMpageExperiment experiment;
void instantiateRAMpageExperiment()
{
fail::simulator.addFlow(&experiment);
fail::simulator.addFlow(new RAMpageExperiment);
}

View File

@ -1,6 +1,7 @@
option(BUILD_DUMP_TRACE "Build the trace dump tool?" OFF)
option(BUILD_IMPORT_TRACE "Build the trace import tool?" OFF)
option(BUILD_PRUNE_TRACE "Build the trace prune tool?" OFF)
option(BUILD_CONVERT_TRACE "Build the trace converter tool?" OFF)
### Setup search paths for headers ##
@ -18,3 +19,7 @@ endif(BUILD_PRUNE_TRACE)
if(BUILD_DUMP_TRACE)
add_subdirectory(dump-trace)
endif(BUILD_DUMP_TRACE)
if(BUILD_CONVERT_TRACE)
add_subdirectory(convert-trace)
endif(BUILD_CONVERT_TRACE)

View File

@ -0,0 +1,10 @@
set(SRCS
main.cc
Gem5Converter.cc
DumpConverter.cc
)
add_executable(convert-trace ${SRCS})
target_link_libraries(convert-trace fail-util fail-comm)
install(TARGETS convert-trace RUNTIME DESTINATION bin)

View File

@ -0,0 +1,73 @@
#include <sstream>
#include <string>
#include "util/Logger.hpp"
#include "comm/TracePlugin.pb.h"
#include "DumpConverter.hpp"
using namespace fail;
using std::stringstream;
using std::endl;
using std::hex;
using std::dec;
static Logger LOG("DumpConverter", true);
// TODO: convert extended trace information, too
bool DumpConverter::convert()
{
char buf[2048], dummy[1024];
int64_t prev_cycle = 0, cycle;
while (m_input.getline(buf, sizeof(buf))) {
Trace_Event ev;
// IP 1035c9 t=0
// MEM R 123abc width 4 IP 1035c9 t=1
// MEM W 123abc width 4 IP 1035c9 t=1
std::stringstream ss(buf);
std::string ev_type;
ss >> ev_type;
if (ev_type == "MEM") {
std::string accesstype;
uint64_t data_address;
uint32_t data_width;
ss >> accesstype >> hex >> data_address >> dummy >> dec >> data_width >> ev_type;
if (!ss) {
LOG << "input mismatch (1), input = " << buf << endl;
continue;
}
ev.set_memaddr(data_address);
ev.set_width(data_width);
ev.set_accesstype(accesstype == "R" ? ev.READ : ev.WRITE);
}
assert(ev_type == "IP");
uint64_t instr_address;
ss >> hex >> instr_address >> dummy;
if (!ss || dummy[0] != 't' || dummy[1] != '=') {
LOG << "input mismatch (2), input = " << buf << endl;
continue;
}
ev.set_ip(instr_address);
ss.clear();
ss.str(dummy + 2);
ss >> dec >> cycle;
if (!ss) {
LOG << "input mismatch (3), 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;
}
m_ps.writeMessage(&ev);
}
return true;
}

View File

@ -0,0 +1,11 @@
#ifndef __DUMPCONVERTER_HPP__
#define __DUMPCONVERTER_HPP__
#include "FormatConverter.hpp"
class DumpConverter : public FormatConverter {
public:
DumpConverter(std::istream& input, fail::ProtoOStream& ps) : FormatConverter(input, ps) {}
bool convert();
};
#endif

View File

@ -0,0 +1,16 @@
#ifndef __FORMATCONVERTER_HPP__
#define __FORMATCONVERTER_HPP__
#include <istream>
#include "util/ProtoStream.hpp"
class FormatConverter {
public:
FormatConverter(std::istream& input, fail::ProtoOStream& ps) : m_input(input), m_ps(ps) {}
virtual bool convert() = 0;
protected:
std::istream& m_input;
fail::ProtoOStream& m_ps;
};
#endif

View 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;
}

View File

@ -0,0 +1,11 @@
#ifndef __GEM5CONVERTER_HPP__
#define __GEM5CONVERTER_HPP__
#include "FormatConverter.hpp"
class Gem5Converter : public FormatConverter {
public:
Gem5Converter(std::istream& input, fail::ProtoOStream& ps) : FormatConverter(input, ps) {}
bool convert();
};
#endif

View File

@ -0,0 +1,65 @@
#include <fstream>
#include <string>
#include "FormatConverter.hpp"
#include "Gem5Converter.hpp"
#include "DumpConverter.hpp"
#include "util/CommandLine.hpp"
#include "util/gzstream/gzstream.h"
#include "util/Logger.hpp"
using namespace fail;
using std::cin;
using std::endl;
static Logger LOG("convert-trace", true);
int main(int argc, char *argv[]) {
CommandLine &cmd = CommandLine::Inst();
cmd.addOption("", "", Arg::None, "usage: convert-trace -f dump|gem5 -t tracefile.tc");
CommandLine::option_handle HELP =
cmd.addOption("h", "help", Arg::None, "-h/--help \tPrint usage and exit");
CommandLine::option_handle FORMAT =
cmd.addOption("f", "format", Arg::Required, "-f/--format FORMAT \tInput format (dump|gem5)");
CommandLine::option_handle OUTFILE =
cmd.addOption("t", "trace", Arg::Required, "-t/--trace FILE \tOutput file");
for (int i = 1; i < argc; ++i) {
cmd.add_args(argv[i]);
}
if (!cmd.parse()) {
LOG << "Error parsing arguments." << endl;
return 1;
}
if (cmd[HELP] || !cmd[OUTFILE] || !cmd[FORMAT] || cmd.parser()->nonOptionsCount() != 0) {
cmd.printUsage();
if (cmd[HELP]) {
exit(0);
} else {
exit(1);
}
}
std::string format = cmd[FORMAT].first()->arg;
std::string trace_file = cmd[OUTFILE].first()->arg;
ogzstream gz_stream(trace_file.c_str());
std::ostream *os = &gz_stream;
ProtoOStream ps(os);
FormatConverter *converter;
if (format == "gem5") {
converter = new Gem5Converter(cin, ps);
} else if (format == "dump") {
converter = new DumpConverter(cin, ps);
} else {
LOG << "unknown input format '" << format << "'" << endl;
return 1;
}
if (!converter->convert()) {
LOG << "converter failed" << endl;
return 1;
}
}

View File

@ -122,7 +122,7 @@ int main(int argc, char *argv[])
if (!stats_only) {
cout << "MEM "
<< (ev.accesstype() == Trace_Event_AccessType_READ ? "R" : "W") << " "
<< ev.memaddr()
<< hex << ev.memaddr()
<< dec << " width " << ev.width()
<< hex << " IP " << ev.ip()
<< dec << " t=" << acctime

View File

@ -17,13 +17,14 @@ if (BUILD_LLVM_DISASSEMBLER)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_CXX_FLAGS} -fexceptions")
endif(BUILD_LLVM_DISASSEMBLER)
find_package(MySQL REQUIRED)
include_directories(${MYSQL_INCLUDE_DIR})
add_executable(import-trace main.cc ${SRCS})
target_link_libraries(import-trace
${PROTOBUF_LIBRARY}
-lmysqlclient
${MYSQL_LIBRARIES}
fail-util
fail-comm
fail-sal)

View File

@ -1,4 +1,3 @@
#ifndef __puma
#include <sstream>
#include <iostream>
#include "InstructionImporter.hpp"
@ -77,6 +76,3 @@ bool InstructionImporter::handle_ip_event(fail::simtime_t curtime, instruction_c
return true;
}
#endif // !__puma

View File

@ -3,16 +3,11 @@
#include "Importer.hpp"
#ifndef __puma
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
#endif
class InstructionImporter : public Importer {
#ifndef __puma
llvm::OwningPtr<llvm::object::Binary> binary;
llvm::OwningPtr<fail::LLVMDisassembler> disas;
#endif
public:
virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,

View File

@ -1,4 +1,3 @@
#ifndef __puma
#include <sstream>
#include <iostream>
#include "util/Logger.hpp"
@ -129,6 +128,3 @@ bool RandomJumpImporter::handle_ip_event(fail::simtime_t curtime, instruction_co
return true;
}
#endif // !__puma

View File

@ -5,16 +5,11 @@
#include "util/CommandLine.hpp"
#include "Importer.hpp"
#ifndef __puma
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
#endif
class RandomJumpImporter : public Importer {
#ifndef __puma
llvm::OwningPtr<llvm::object::Binary> binary;
llvm::OwningPtr<fail::LLVMDisassembler> disas;
#endif
fail::CommandLine::option_handle FROM, TO;

View File

@ -1,4 +1,3 @@
#ifndef __puma
#include <sstream>
#include <iostream>
#include "RegisterImporter.hpp"
@ -33,9 +32,8 @@ bool RegisterImporter::addRegisterTrace(simtime_t curtime, instruction_count_t i
const Trace_Event &ev,
const LLVMtoFailTranslator::reginfo_t &info,
char access_type) {
LLVMtoFailTranslator::reginfo_t one_byte_window = info;
one_byte_window.width = 8;
address_t from = one_byte_window.toDataAddress(), to = one_byte_window.toDataAddress() + (info.width) / 8;
address_t from = info.toDataAddress();
address_t to = from + info.width / 8;
// Iterate over all accessed bytes
for (address_t data_address = from; data_address < to; ++data_address) {
@ -131,6 +129,12 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_uses.begin();
it != opcode.reg_uses.end(); ++it) {
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it);
if (&info == &ltof.notfound) {
LOG << "Could not find a mapping for LLVM input register #" << std::dec << *it
<< " at IP " << std::hex << ev.ip()
<< ", skipping" << std::endl;
continue;
}
/* if not tracing flags, but flags register -> ignore it
if not tracing gp, but ! flags -> ignore it*/
@ -147,6 +151,13 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_defs.begin();
it != opcode.reg_defs.end(); ++it) {
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it);
if (&info == &ltof.notfound) {
LOG << "Could not find a mapping for LLVM output register #" << std::dec << *it
<< " at IP " << std::hex << ev.ip()
<< ", skipping" << std::endl;
continue;
}
/* if not tracing flags, but flags register -> ignore it
if not tracing gp, but ! flags -> ignore it*/
if (info.id == RID_FLAGS && !do_flags)
@ -168,6 +179,3 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
return true;
}
#endif // !__puma

View File

@ -5,13 +5,10 @@
#include "util/CommandLine.hpp"
#include "Importer.hpp"
#ifndef __puma
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
#endif
class RegisterImporter : public Importer {
#ifndef __puma
llvm::OwningPtr<llvm::object::Binary> binary;
llvm::OwningPtr<fail::LLVMDisassembler> disas;
@ -19,8 +16,6 @@ class RegisterImporter : public Importer {
const Trace_Event &ev,
const fail::LLVMtoFailTranslator::reginfo_t &info,
char access_type);
#endif
fail::CommandLine::option_handle NO_GP, FLAGS, IP;
bool do_gp, do_flags, do_ip;

View File

@ -3,7 +3,10 @@ set(SRCS
BasicPruner.cc
)
find_package(MySQL REQUIRED)
include_directories(${MYSQL_INCLUDE_DIR})
## This is the example's campaign server distributing experiment parameters
add_executable(prune-trace main.cc ${SRCS})
target_link_libraries(prune-trace -lmysqlclient fail-util)
target_link_libraries(prune-trace ${MYSQL_LIBRARIES} fail-util)
install(TARGETS prune-trace RUNTIME DESTINATION bin)