Merge branch 'master' of ssh://vamos.informatik.uni-erlangen.de:29418/fail
This commit is contained in:
59
cmake/FindMySQL.cmake
Normal file
59
cmake/FindMySQL.cmake
Normal 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)
|
||||||
@ -8,9 +8,9 @@ namespace fail {
|
|||||||
|
|
||||||
void CoroutineManager::m_invoke(void* pData)
|
void CoroutineManager::m_invoke(void* pData)
|
||||||
{
|
{
|
||||||
//std::cerr << "CORO m_invoke " << co_current() << std::endl;
|
ExperimentFlow *flow = reinterpret_cast<ExperimentFlow*>(pData);
|
||||||
// TODO: Log-Level?
|
flow->coroutine_entry();
|
||||||
reinterpret_cast<ExperimentFlow*>(pData)->coroutine_entry();
|
simulator.removeFlow(flow);
|
||||||
//m_togglerstack.pop();
|
//m_togglerstack.pop();
|
||||||
// FIXME: need to pop our caller
|
// FIXME: need to pop our caller
|
||||||
co_exit(); // deletes the associated coroutine memory as well
|
co_exit(); // deletes the associated coroutine memory as well
|
||||||
@ -20,7 +20,12 @@ void CoroutineManager::m_invoke(void* pData)
|
|||||||
while (1); // freeze.
|
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)
|
void CoroutineManager::toggle(ExperimentFlow* flow)
|
||||||
{
|
{
|
||||||
@ -53,7 +58,9 @@ void CoroutineManager::remove(ExperimentFlow* flow)
|
|||||||
// find coroutine handle for this flow
|
// find coroutine handle for this flow
|
||||||
flowmap_t::iterator it = m_Flows.find(flow);
|
flowmap_t::iterator it = m_Flows.find(flow);
|
||||||
if (it == m_Flows.end()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
corohandle_t coro = it->second;
|
corohandle_t coro = it->second;
|
||||||
@ -67,7 +74,9 @@ void CoroutineManager::remove(ExperimentFlow* flow)
|
|||||||
// delete coroutine (and handle the special case we're removing
|
// delete coroutine (and handle the special case we're removing
|
||||||
// ourselves)
|
// ourselves)
|
||||||
if (coro == co_current()) {
|
if (coro == co_current()) {
|
||||||
co_exit();
|
if (!m_Terminated) {
|
||||||
|
co_exit();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
co_delete(coro);
|
co_delete(coro);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,10 +29,12 @@ private:
|
|||||||
std::stack<corohandle_t> m_togglerstack;
|
std::stack<corohandle_t> m_togglerstack;
|
||||||
//! manages the run-calls for each ExperimentFlow-object
|
//! manages the run-calls for each ExperimentFlow-object
|
||||||
static void m_invoke(void* pData);
|
static void m_invoke(void* pData);
|
||||||
|
//! \c true if terminated explicitly using simulator.terminate()
|
||||||
|
bool m_Terminated;
|
||||||
public:
|
public:
|
||||||
static const ExperimentFlow* SIM_FLOW; //!< the simulator coroutine flow
|
static const ExperimentFlow* SIM_FLOW; //!< the simulator coroutine flow
|
||||||
|
|
||||||
CoroutineManager() : m_simCoro(co_current()) { }
|
CoroutineManager() : m_simCoro(co_current()), m_Terminated(false) { }
|
||||||
~CoroutineManager();
|
~CoroutineManager();
|
||||||
/**
|
/**
|
||||||
* Creates a new coroutine for the specified experiment flow.
|
* Creates a new coroutine for the specified experiment flow.
|
||||||
@ -63,6 +65,12 @@ public:
|
|||||||
* @return the current experiment flow.
|
* @return the current experiment flow.
|
||||||
*/
|
*/
|
||||||
ExperimentFlow* getCurrent();
|
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
|
} // end-of-namespace: fail
|
||||||
|
|||||||
@ -13,6 +13,11 @@ namespace fail {
|
|||||||
class ExperimentFlow {
|
class ExperimentFlow {
|
||||||
public:
|
public:
|
||||||
ExperimentFlow() { }
|
ExperimentFlow() { }
|
||||||
|
virtual ~ExperimentFlow()
|
||||||
|
{
|
||||||
|
simulator.clearListeners(this); // remove residual events
|
||||||
|
simulator.removeFlow(this);
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* Defines the experiment flow.
|
* Defines the experiment flow.
|
||||||
* @return \c true if the experiment was successful, \c false otherwise
|
* @return \c true if the experiment was successful, \c false otherwise
|
||||||
|
|||||||
@ -217,6 +217,8 @@ void SimulatorController::terminate(int exCode)
|
|||||||
// Attention: This could cause problems, e.g., because of non-closed sockets
|
// 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;
|
std::cout << "[FAIL] Exit called by experiment with exit code: " << exCode << std::endl;
|
||||||
// TODO: (Non-)Verbose-Mode? Log-Level?
|
// TODO: (Non-)Verbose-Mode? Log-Level?
|
||||||
|
|
||||||
|
m_Flows.setTerminated(); // we are about to terminate
|
||||||
exit(exCode);
|
exit(exCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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 ]")
|
message(FATAL_ERROR "libiberty not found. Try installing binutils-dev: [ sudo aptitude install binutils-dev ]")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
# libz required by gzstream
|
||||||
|
find_package(ZLIB REQUIRED)
|
||||||
|
include_directories(${ZLIB_INCLUDE_DIRS})
|
||||||
|
|
||||||
# objdump required by Diassembler.cc
|
# objdump required by Diassembler.cc
|
||||||
|
|
||||||
set(THE_OBJDUMP "${ARCH_TOOL_PREFIX}objdump")
|
set(THE_OBJDUMP "${ARCH_TOOL_PREFIX}objdump")
|
||||||
@ -61,7 +65,7 @@ mark_as_advanced(FAIL_OBJDUMP)
|
|||||||
|
|
||||||
add_library(fail-util ${SRCS})
|
add_library(fail-util ${SRCS})
|
||||||
add_dependencies(fail-util fail-comm)
|
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)
|
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)
|
if (BUILD_LLVM_DISASSEMBLER)
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
#ifndef __puma
|
|
||||||
#include "LLVMDisassembler.hpp"
|
#include "LLVMDisassembler.hpp"
|
||||||
|
|
||||||
using namespace fail;
|
using namespace fail;
|
||||||
@ -147,5 +146,3 @@ void LLVMDisassembler::disassemble()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void LLVMDisassembler::StringRefMemoryObject::anchor() {}
|
void LLVMDisassembler::StringRefMemoryObject::anchor() {}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
#ifndef __LLVMDISASSEMBLER_HPP__
|
#ifndef __LLVMDISASSEMBLER_HPP__
|
||||||
#define __LLVMDISASSEMBLER_HPP__
|
#define __LLVMDISASSEMBLER_HPP__
|
||||||
|
|
||||||
#ifndef __puma
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
@ -137,5 +135,4 @@ public:
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
#endif // puma
|
|
||||||
#endif // __LLVMDISASSEMBLER_HPP__
|
#endif // __LLVMDISASSEMBLER_HPP__
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
using namespace fail;
|
using namespace fail;
|
||||||
|
|
||||||
LLVMtoFailBochs::LLVMtoFailBochs() {
|
LLVMtoFailBochs::LLVMtoFailBochs() {
|
||||||
#ifndef __puma
|
|
||||||
/* These magic numbers are taken from the llvm compiler (MC), they
|
/* These magic numbers are taken from the llvm compiler (MC), they
|
||||||
do not appear in any header. They hopefully will never
|
do not appear in any header. They hopefully will never
|
||||||
change */
|
change */
|
||||||
@ -19,12 +18,12 @@ LLVMtoFailBochs::LLVMtoFailBochs() {
|
|||||||
llvm_to_fail_map[45] = reginfo_t(RID_CBX, 32, 0); // EBX
|
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[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[28] = reginfo_t(RID_CCX, 16, 0); // CX
|
||||||
llvm_to_fail_map[46] = reginfo_t(RID_CCX); // ECX
|
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[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[42] = reginfo_t(RID_CDX, 16, 0); // DX
|
||||||
llvm_to_fail_map[48] = reginfo_t(RID_CDX); // EDX
|
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[54] = reginfo_t(RID_CSP); // ESP
|
||||||
llvm_to_fail_map[117] = reginfo_t(RID_CSP, 16, 0); // SP
|
llvm_to_fail_map[117] = reginfo_t(RID_CSP, 16, 0); // SP
|
||||||
llvm_to_fail_map[118] = reginfo_t(RID_CSP, 8, 0); // SPL
|
llvm_to_fail_map[118] = reginfo_t(RID_CSP, 8, 0); // SPL
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,6 @@
|
|||||||
using namespace fail;
|
using namespace fail;
|
||||||
|
|
||||||
LLVMtoFailGem5::LLVMtoFailGem5() {
|
LLVMtoFailGem5::LLVMtoFailGem5() {
|
||||||
#ifndef __puma
|
|
||||||
/* These magic numbers are taken from the machine descriptions of
|
/* These magic numbers are taken from the machine descriptions of
|
||||||
LLVM they (hopefully) will not change, since they are not exported
|
LLVM they (hopefully) will not change, since they are not exported
|
||||||
via a header */
|
via a header */
|
||||||
@ -24,5 +23,4 @@ LLVMtoFailGem5::LLVMtoFailGem5() {
|
|||||||
llvm_to_fail_map[105] = reginfo_t(RI_SP);
|
llvm_to_fail_map[105] = reginfo_t(RI_SP);
|
||||||
llvm_to_fail_map[40] = reginfo_t(RI_LR);
|
llvm_to_fail_map[40] = reginfo_t(RI_LR);
|
||||||
llvm_to_fail_map[43] = reginfo_t(RI_IP);
|
llvm_to_fail_map[43] = reginfo_t(RI_IP);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,16 +4,14 @@
|
|||||||
using namespace fail;
|
using namespace fail;
|
||||||
|
|
||||||
const LLVMtoFailTranslator::reginfo_t & LLVMtoFailTranslator::getFailRegisterID(unsigned int regid) {
|
const LLVMtoFailTranslator::reginfo_t & LLVMtoFailTranslator::getFailRegisterID(unsigned int regid) {
|
||||||
#ifndef __puma
|
|
||||||
ltof_map_t::iterator it = llvm_to_fail_map.find(regid);
|
ltof_map_t::iterator it = llvm_to_fail_map.find(regid);
|
||||||
if( it != llvm_to_fail_map.end() ) {// found
|
if( it != llvm_to_fail_map.end() ) {// found
|
||||||
return (*it).second;
|
return (*it).second;
|
||||||
} else { // not found
|
} 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);
|
//exit(EXIT_FAILURE);
|
||||||
return notfound;
|
return notfound;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
regdata_t LLVMtoFailTranslator::getRegisterContent(ConcreteCPU& cpu, const reginfo_t ®info){
|
regdata_t LLVMtoFailTranslator::getRegisterContent(ConcreteCPU& cpu, const reginfo_t ®info){
|
||||||
|
|||||||
@ -13,6 +13,12 @@ namespace fail {
|
|||||||
*/
|
*/
|
||||||
class LLVMtoFailTranslator {
|
class LLVMtoFailTranslator {
|
||||||
public:
|
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 {
|
struct reginfo_t {
|
||||||
int id;
|
int id;
|
||||||
regwidth_t width;
|
regwidth_t width;
|
||||||
@ -20,18 +26,17 @@ public:
|
|||||||
byte_t offset;
|
byte_t offset;
|
||||||
|
|
||||||
int toDataAddress() const {
|
int toDataAddress() const {
|
||||||
// .. 5 4 | 7 6 5 4 | 3 2 1 0
|
// .. 5 4 | 3 2 1 0
|
||||||
// <reg> | <width> | <offset>
|
// <reg> | <offset>
|
||||||
return (id << 8) | ((width/8) << 4) | (offset / 8);
|
return (id << 4) | (offset / 8);
|
||||||
}
|
}
|
||||||
|
// does not recreate width or mask
|
||||||
static reginfo_t fromDataAddress(int addr) {
|
static reginfo_t fromDataAddress(int addr) {
|
||||||
int id = addr >> 8;
|
int id = addr >> 4;
|
||||||
regwidth_t width = ((addr >> 4) & 0xf) * 8;
|
byte_t offset = (addr & 0xf) * 8;
|
||||||
byte_t offset = (addr & 0xf) * 8;
|
return reginfo_t(id, 0, offset);
|
||||||
return reginfo_t(id, width, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
reginfo_t(int id=-1, regwidth_t width = 32, byte_t offs = 0)
|
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) {};
|
: id(id), width(width), mask((regwidth_t)((((long long)1 << width) - 1) << offs)), offset(offs) {};
|
||||||
};
|
};
|
||||||
@ -39,13 +44,16 @@ protected:
|
|||||||
|
|
||||||
LLVMtoFailTranslator(){};
|
LLVMtoFailTranslator(){};
|
||||||
|
|
||||||
#ifndef __puma
|
|
||||||
typedef std::map<unsigned int, struct reginfo_t> ltof_map_t;
|
typedef std::map<unsigned int, struct reginfo_t> ltof_map_t;
|
||||||
ltof_map_t llvm_to_fail_map;
|
ltof_map_t llvm_to_fail_map;
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
public:
|
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);
|
const reginfo_t & getFailRegisterID(unsigned int regid);
|
||||||
|
|
||||||
regdata_t getRegisterContent(ConcreteCPU & cpu, const reginfo_t & reg);
|
regdata_t getRegisterContent(ConcreteCPU & cpu, const reginfo_t & reg);
|
||||||
@ -58,7 +66,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int getFailRegisterId(unsigned int regid) { return this->getFailRegisterID(regid).id; };
|
int getFailRegisterId(unsigned int regid) { return this->getFailRegisterID(regid).id; };
|
||||||
private:
|
|
||||||
reginfo_t notfound;
|
reginfo_t notfound;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,9 @@ find_package(Protobuf REQUIRED)
|
|||||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
find_package(MySQL REQUIRED)
|
||||||
|
include_directories(${MYSQL_INCLUDE_DIR})
|
||||||
|
|
||||||
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
|
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
|
||||||
|
|
||||||
## Build library
|
## Build library
|
||||||
@ -30,6 +33,6 @@ target_link_libraries(fail-${EXPERIMENT_NAME} ${PROTOBUF_LIBRARY})
|
|||||||
|
|
||||||
## This is the example's campaign server distributing experiment parameters
|
## This is the example's campaign server distributing experiment parameters
|
||||||
add_executable(${EXPERIMENT_NAME}-server main.cc)
|
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)
|
install(TARGETS ${EXPERIMENT_NAME}-server RUNTIME DESTINATION bin)
|
||||||
|
|
||||||
|
|||||||
@ -22,14 +22,17 @@ find_package(Protobuf REQUIRED)
|
|||||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
find_package(MySQL REQUIRED)
|
||||||
|
include_directories(${MYSQL_INCLUDE_DIR})
|
||||||
|
|
||||||
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
|
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
|
||||||
|
|
||||||
## Build library
|
## Build library
|
||||||
add_library(fail-${EXPERIMENT_NAME} ${PROTO_SRCS} ${PROTO_HDRS} ${MY_CAMPAIGN_SRCS})
|
add_library(fail-${EXPERIMENT_NAME} ${PROTO_SRCS} ${PROTO_HDRS} ${MY_CAMPAIGN_SRCS})
|
||||||
add_dependencies(fail-${EXPERIMENT_NAME} fail-tracing fail-comm)
|
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
|
## This is the example's campaign server distributing experiment parameters
|
||||||
add_executable(${EXPERIMENT_NAME}-server main.cc)
|
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)
|
install(TARGETS ${EXPERIMENT_NAME}-server RUNTIME DESTINATION bin)
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
#include "experiment.hpp"
|
#include "experiment.hpp"
|
||||||
#include "sal/SALInst.hpp"
|
#include "sal/SALInst.hpp"
|
||||||
|
|
||||||
static EcosKernelTestExperiment experiment;
|
|
||||||
void instantiateEcosKernelTestExperiment()
|
void instantiateEcosKernelTestExperiment()
|
||||||
{
|
{
|
||||||
fail::simulator.addFlow(&experiment);
|
fail::simulator.addFlow(new EcosKernelTestExperiment);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,6 +12,10 @@
|
|||||||
// You need to provide the implementation of this function in your experiment
|
// You need to provide the implementation of this function in your experiment
|
||||||
// directory:
|
// directory:
|
||||||
void instantiate@EXPERIMENT_TYPE@();
|
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 {
|
aspect @EXPERIMENT_TYPE@ExperimentHook {
|
||||||
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
|
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
|
||||||
|
|||||||
@ -9,10 +9,14 @@
|
|||||||
#include "../experiments/@EXPERIMENT_NAME@/experiment.hpp"
|
#include "../experiments/@EXPERIMENT_NAME@/experiment.hpp"
|
||||||
#include "sal/SALInst.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 {
|
aspect @EXPERIMENT_TYPE@ExperimentHook {
|
||||||
@EXPERIMENT_TYPE@ experiment;
|
|
||||||
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
|
advice execution ("void fail::SimulatorController::initExperiments()") : after () {
|
||||||
fail::simulator.addFlow(&experiment);
|
fail::simulator.addFlow(new @EXPERIMENT_TYPE@);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -21,6 +21,9 @@ find_package(Protobuf REQUIRED)
|
|||||||
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
include_directories(${PROTOBUF_INCLUDE_DIRS})
|
||||||
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
find_package(MySQL REQUIRED)
|
||||||
|
include_directories(${MYSQL_INCLUDE_DIR})
|
||||||
|
|
||||||
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
|
PROTOBUF_GENERATE_CPP(PROTO_SRCS PROTO_HDRS ${MY_PROTOS})
|
||||||
|
|
||||||
## Build library
|
## Build library
|
||||||
@ -30,5 +33,5 @@ target_link_libraries(fail-${EXPERIMENT_NAME} ${PROTOBUF_LIBRARY})
|
|||||||
|
|
||||||
## This is the example's campaign server distributing experiment parameters
|
## This is the example's campaign server distributing experiment parameters
|
||||||
add_executable(${EXPERIMENT_NAME}-server main.cc)
|
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)
|
install(TARGETS ${EXPERIMENT_NAME}-server RUNTIME DESTINATION bin)
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
#include "experiment.hpp"
|
#include "experiment.hpp"
|
||||||
#include "sal/SALInst.hpp"
|
#include "sal/SALInst.hpp"
|
||||||
|
|
||||||
static NanoJPEGExperiment experiment;
|
|
||||||
void instantiateNanoJPEGExperiment()
|
void instantiateNanoJPEGExperiment()
|
||||||
{
|
{
|
||||||
fail::simulator.addFlow(&experiment);
|
fail::simulator.addFlow(new NanoJPEGExperiment);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
#include "experiment.hpp"
|
#include "experiment.hpp"
|
||||||
#include "sal/SALInst.hpp"
|
#include "sal/SALInst.hpp"
|
||||||
|
|
||||||
static RAMpageExperiment experiment;
|
|
||||||
void instantiateRAMpageExperiment()
|
void instantiateRAMpageExperiment()
|
||||||
{
|
{
|
||||||
fail::simulator.addFlow(&experiment);
|
fail::simulator.addFlow(new RAMpageExperiment);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
option(BUILD_DUMP_TRACE "Build the trace dump tool?" OFF)
|
option(BUILD_DUMP_TRACE "Build the trace dump tool?" OFF)
|
||||||
option(BUILD_IMPORT_TRACE "Build the trace import tool?" OFF)
|
option(BUILD_IMPORT_TRACE "Build the trace import tool?" OFF)
|
||||||
option(BUILD_PRUNE_TRACE "Build the trace prune 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 ##
|
### Setup search paths for headers ##
|
||||||
@ -18,3 +19,7 @@ endif(BUILD_PRUNE_TRACE)
|
|||||||
if(BUILD_DUMP_TRACE)
|
if(BUILD_DUMP_TRACE)
|
||||||
add_subdirectory(dump-trace)
|
add_subdirectory(dump-trace)
|
||||||
endif(BUILD_DUMP_TRACE)
|
endif(BUILD_DUMP_TRACE)
|
||||||
|
|
||||||
|
if(BUILD_CONVERT_TRACE)
|
||||||
|
add_subdirectory(convert-trace)
|
||||||
|
endif(BUILD_CONVERT_TRACE)
|
||||||
|
|||||||
10
tools/convert-trace/CMakeLists.txt
Normal file
10
tools/convert-trace/CMakeLists.txt
Normal 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)
|
||||||
73
tools/convert-trace/DumpConverter.cc
Normal file
73
tools/convert-trace/DumpConverter.cc
Normal 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;
|
||||||
|
}
|
||||||
11
tools/convert-trace/DumpConverter.hpp
Normal file
11
tools/convert-trace/DumpConverter.hpp
Normal 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
|
||||||
16
tools/convert-trace/FormatConverter.hpp
Normal file
16
tools/convert-trace/FormatConverter.hpp
Normal 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
|
||||||
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;
|
||||||
|
}
|
||||||
11
tools/convert-trace/Gem5Converter.hpp
Normal file
11
tools/convert-trace/Gem5Converter.hpp
Normal 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
|
||||||
65
tools/convert-trace/main.cc
Normal file
65
tools/convert-trace/main.cc
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -122,7 +122,7 @@ int main(int argc, char *argv[])
|
|||||||
if (!stats_only) {
|
if (!stats_only) {
|
||||||
cout << "MEM "
|
cout << "MEM "
|
||||||
<< (ev.accesstype() == Trace_Event_AccessType_READ ? "R" : "W") << " "
|
<< (ev.accesstype() == Trace_Event_AccessType_READ ? "R" : "W") << " "
|
||||||
<< ev.memaddr()
|
<< hex << ev.memaddr()
|
||||||
<< dec << " width " << ev.width()
|
<< dec << " width " << ev.width()
|
||||||
<< hex << " IP " << ev.ip()
|
<< hex << " IP " << ev.ip()
|
||||||
<< dec << " t=" << acctime
|
<< dec << " t=" << acctime
|
||||||
|
|||||||
@ -17,13 +17,14 @@ if (BUILD_LLVM_DISASSEMBLER)
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_CXX_FLAGS} -fexceptions")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${LLVM_CXX_FLAGS} -fexceptions")
|
||||||
endif(BUILD_LLVM_DISASSEMBLER)
|
endif(BUILD_LLVM_DISASSEMBLER)
|
||||||
|
|
||||||
|
find_package(MySQL REQUIRED)
|
||||||
|
include_directories(${MYSQL_INCLUDE_DIR})
|
||||||
|
|
||||||
add_executable(import-trace main.cc ${SRCS})
|
add_executable(import-trace main.cc ${SRCS})
|
||||||
|
|
||||||
target_link_libraries(import-trace
|
target_link_libraries(import-trace
|
||||||
${PROTOBUF_LIBRARY}
|
${PROTOBUF_LIBRARY}
|
||||||
-lmysqlclient
|
${MYSQL_LIBRARIES}
|
||||||
fail-util
|
fail-util
|
||||||
fail-comm
|
fail-comm
|
||||||
fail-sal)
|
fail-sal)
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
#ifndef __puma
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "InstructionImporter.hpp"
|
#include "InstructionImporter.hpp"
|
||||||
@ -77,6 +76,3 @@ bool InstructionImporter::handle_ip_event(fail::simtime_t curtime, instruction_c
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // !__puma
|
|
||||||
|
|||||||
@ -3,16 +3,11 @@
|
|||||||
|
|
||||||
#include "Importer.hpp"
|
#include "Importer.hpp"
|
||||||
|
|
||||||
#ifndef __puma
|
|
||||||
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
|
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
class InstructionImporter : public Importer {
|
class InstructionImporter : public Importer {
|
||||||
#ifndef __puma
|
|
||||||
llvm::OwningPtr<llvm::object::Binary> binary;
|
llvm::OwningPtr<llvm::object::Binary> binary;
|
||||||
llvm::OwningPtr<fail::LLVMDisassembler> disas;
|
llvm::OwningPtr<fail::LLVMDisassembler> disas;
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,
|
virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
#ifndef __puma
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "util/Logger.hpp"
|
#include "util/Logger.hpp"
|
||||||
@ -129,6 +128,3 @@ bool RandomJumpImporter::handle_ip_event(fail::simtime_t curtime, instruction_co
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // !__puma
|
|
||||||
|
|||||||
@ -5,16 +5,11 @@
|
|||||||
#include "util/CommandLine.hpp"
|
#include "util/CommandLine.hpp"
|
||||||
#include "Importer.hpp"
|
#include "Importer.hpp"
|
||||||
|
|
||||||
#ifndef __puma
|
|
||||||
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
|
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
class RandomJumpImporter : public Importer {
|
class RandomJumpImporter : public Importer {
|
||||||
#ifndef __puma
|
|
||||||
llvm::OwningPtr<llvm::object::Binary> binary;
|
llvm::OwningPtr<llvm::object::Binary> binary;
|
||||||
llvm::OwningPtr<fail::LLVMDisassembler> disas;
|
llvm::OwningPtr<fail::LLVMDisassembler> disas;
|
||||||
#endif
|
|
||||||
|
|
||||||
fail::CommandLine::option_handle FROM, TO;
|
fail::CommandLine::option_handle FROM, TO;
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
#ifndef __puma
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "RegisterImporter.hpp"
|
#include "RegisterImporter.hpp"
|
||||||
@ -33,9 +32,8 @@ bool RegisterImporter::addRegisterTrace(simtime_t curtime, instruction_count_t i
|
|||||||
const Trace_Event &ev,
|
const Trace_Event &ev,
|
||||||
const LLVMtoFailTranslator::reginfo_t &info,
|
const LLVMtoFailTranslator::reginfo_t &info,
|
||||||
char access_type) {
|
char access_type) {
|
||||||
LLVMtoFailTranslator::reginfo_t one_byte_window = info;
|
address_t from = info.toDataAddress();
|
||||||
one_byte_window.width = 8;
|
address_t to = from + info.width / 8;
|
||||||
address_t from = one_byte_window.toDataAddress(), to = one_byte_window.toDataAddress() + (info.width) / 8;
|
|
||||||
|
|
||||||
// Iterate over all accessed bytes
|
// Iterate over all accessed bytes
|
||||||
for (address_t data_address = from; data_address < to; ++data_address) {
|
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();
|
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_uses.begin();
|
||||||
it != opcode.reg_uses.end(); ++it) {
|
it != opcode.reg_uses.end(); ++it) {
|
||||||
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it);
|
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it);
|
||||||
|
if (&info == <of.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 flags, but flags register -> ignore it
|
||||||
if not tracing gp, but ! flags -> 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();
|
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_defs.begin();
|
||||||
it != opcode.reg_defs.end(); ++it) {
|
it != opcode.reg_defs.end(); ++it) {
|
||||||
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it);
|
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it);
|
||||||
|
if (&info == <of.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 flags, but flags register -> ignore it
|
||||||
if not tracing gp, but ! flags -> ignore it*/
|
if not tracing gp, but ! flags -> ignore it*/
|
||||||
if (info.id == RID_FLAGS && !do_flags)
|
if (info.id == RID_FLAGS && !do_flags)
|
||||||
@ -168,6 +179,3 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // !__puma
|
|
||||||
|
|||||||
@ -5,13 +5,10 @@
|
|||||||
#include "util/CommandLine.hpp"
|
#include "util/CommandLine.hpp"
|
||||||
#include "Importer.hpp"
|
#include "Importer.hpp"
|
||||||
|
|
||||||
#ifndef __puma
|
|
||||||
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
|
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
class RegisterImporter : public Importer {
|
class RegisterImporter : public Importer {
|
||||||
#ifndef __puma
|
|
||||||
llvm::OwningPtr<llvm::object::Binary> binary;
|
llvm::OwningPtr<llvm::object::Binary> binary;
|
||||||
llvm::OwningPtr<fail::LLVMDisassembler> disas;
|
llvm::OwningPtr<fail::LLVMDisassembler> disas;
|
||||||
|
|
||||||
@ -19,8 +16,6 @@ class RegisterImporter : public Importer {
|
|||||||
const Trace_Event &ev,
|
const Trace_Event &ev,
|
||||||
const fail::LLVMtoFailTranslator::reginfo_t &info,
|
const fail::LLVMtoFailTranslator::reginfo_t &info,
|
||||||
char access_type);
|
char access_type);
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
fail::CommandLine::option_handle NO_GP, FLAGS, IP;
|
fail::CommandLine::option_handle NO_GP, FLAGS, IP;
|
||||||
bool do_gp, do_flags, do_ip;
|
bool do_gp, do_flags, do_ip;
|
||||||
|
|||||||
@ -3,7 +3,10 @@ set(SRCS
|
|||||||
BasicPruner.cc
|
BasicPruner.cc
|
||||||
)
|
)
|
||||||
|
|
||||||
|
find_package(MySQL REQUIRED)
|
||||||
|
include_directories(${MYSQL_INCLUDE_DIR})
|
||||||
|
|
||||||
## This is the example's campaign server distributing experiment parameters
|
## This is the example's campaign server distributing experiment parameters
|
||||||
add_executable(prune-trace main.cc ${SRCS})
|
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)
|
install(TARGETS prune-trace RUNTIME DESTINATION bin)
|
||||||
|
|||||||
Reference in New Issue
Block a user