formatting, typos, comments, details

Change-Id: Iae5f1acb653a694622e9ac2bad93efcfca588f3a
This commit is contained in:
Horst Schirmeier
2013-10-14 14:43:39 +02:00
parent 7591c9edc5
commit 4cb97a7fa5
138 changed files with 1566 additions and 1576 deletions

View File

@ -1,5 +1,5 @@
#ifndef __EXPERIMENT_DATA_HPP__ #ifndef __EXPERIMENT_DATA_HPP__
#define __EXPERIMENT_DATA_HPP__ #define __EXPERIMENT_DATA_HPP__
#include <string> #include <string>
#include <google/protobuf/message.h> #include <google/protobuf/message.h>

View File

@ -16,52 +16,52 @@ void SocketComm::init()
bool SocketComm::sendMsg(int sockfd, google::protobuf::Message& msg) bool SocketComm::sendMsg(int sockfd, google::protobuf::Message& msg)
{ {
int size = htonl(msg.ByteSize()); int size = htonl(msg.ByteSize());
std::string buf; std::string buf;
if (safe_write(sockfd, &size, sizeof(size)) == -1 if (safe_write(sockfd, &size, sizeof(size)) == -1
|| !msg.SerializeToString(&buf) || !msg.SerializeToString(&buf)
|| safe_write(sockfd, buf.c_str(), buf.size()) == -1) { || safe_write(sockfd, buf.c_str(), buf.size()) == -1) {
return false; return false;
} }
return true; return true;
} }
bool SocketComm::rcvMsg(int sockfd, google::protobuf::Message& msg) bool SocketComm::rcvMsg(int sockfd, google::protobuf::Message& msg)
{ {
char *buf; char *buf;
int bufsiz; int bufsiz;
if ((buf = getBuf(sockfd, &bufsiz))) { if ((buf = getBuf(sockfd, &bufsiz))) {
std::string st(buf, bufsiz); std::string st(buf, bufsiz);
delete [] buf; delete [] buf;
return msg.ParseFromString(st); return msg.ParseFromString(st);
} }
return false; return false;
} }
bool SocketComm::dropMsg(int sockfd) bool SocketComm::dropMsg(int sockfd)
{ {
char *buf; char *buf;
int bufsiz; int bufsiz;
if ((buf = getBuf(sockfd, &bufsiz))) { if ((buf = getBuf(sockfd, &bufsiz))) {
delete [] buf; delete [] buf;
return true; return true;
} }
return false; return false;
} }
char * SocketComm::getBuf(int sockfd, int *size) char * SocketComm::getBuf(int sockfd, int *size)
{ {
char *buf; char *buf;
if (safe_read(sockfd, size, sizeof(int)) == -1) { if (safe_read(sockfd, size, sizeof(int)) == -1) {
return 0; return 0;
} }
*size = ntohl(*size); *size = ntohl(*size);
buf = new char[*size]; buf = new char[*size];
if (safe_read(sockfd, buf, *size) == -1) { if (safe_read(sockfd, buf, *size) == -1) {
delete [] buf; delete [] buf;
return 0; return 0;
} }
return buf; return buf;
} }
int SocketComm::timedAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int timeout) int SocketComm::timedAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int timeout)

View File

@ -3,7 +3,7 @@
*/ */
#ifndef __SOCKET_COMM_HPP__ #ifndef __SOCKET_COMM_HPP__
#define __SOCKET_COMM_HPP__ #define __SOCKET_COMM_HPP__
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
@ -56,11 +56,11 @@ public:
static int timedAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int timeout); static int timedAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int timeout);
private: private:
static char * getBuf(int sockfd, int *size); static char *getBuf(int sockfd, int *size);
static ssize_t safe_write(int fd, const void *buf, size_t count); static ssize_t safe_write(int fd, const void *buf, size_t count);
static ssize_t safe_read(int fd, void *buf, size_t count); static ssize_t safe_read(int fd, void *buf, size_t count);
}; };
} // end-of-namespace: fail } // end-of-namespace: fail
#endif // __SOCKET_COMM_HPP__ #endif // __SOCKET_COMM_HPP__

View File

@ -1,5 +1,5 @@
#ifndef __FAIL_CONFIG_HPP__ #ifndef __FAIL_CONFIG_HPP__
#define __FAIL_CONFIG_HPP__ #define __FAIL_CONFIG_HPP__
// #define / #undef the following configuration macros to enable/disable the // #define / #undef the following configuration macros to enable/disable the
// various event sources, fault injection sinks, and miscellaneous other // various event sources, fault injection sinks, and miscellaneous other

View File

@ -1,5 +1,5 @@
#ifndef __CAMPAIGN_HPP__ #ifndef __CAMPAIGN_HPP__
#define __CAMPAIGN_HPP__ #define __CAMPAIGN_HPP__
namespace fail { namespace fail {

View File

@ -4,7 +4,7 @@
*/ */
#ifndef __CAMPAIGN_MANAGER_HPP__ #ifndef __CAMPAIGN_MANAGER_HPP__
#define __CAMPAIGN_MANAGER_HPP__ #define __CAMPAIGN_MANAGER_HPP__
#include "sal/SALInst.hpp" #include "sal/SALInst.hpp"
#include "comm/ExperimentData.hpp" #include "comm/ExperimentData.hpp"
@ -16,7 +16,7 @@ namespace fail {
/** /**
* \class CampaignManager * \class CampaignManager
* *
* The CampaignManager allows a user-campaign access to all constant * The CampaignManager allows a user-campaign access to all constant
* simulator information and forwards single experiments to the JobServer. * simulator information and forwards single experiments to the JobServer.
*/ */
class CampaignManager { class CampaignManager {
@ -30,12 +30,12 @@ public:
* Executes a user campaign * Executes a user campaign
*/ */
bool runCampaign(Campaign* c) bool runCampaign(Campaign* c)
{ {
if (!m_jobserver) { if (!m_jobserver) {
m_jobserver = new JobServer; m_jobserver = new JobServer;
} }
m_currentCampaign = c; m_currentCampaign = c;
bool ret = c->run(); bool ret = c->run();
m_jobserver->done(); m_jobserver->done();
return ret; return ret;
} }
@ -43,7 +43,7 @@ public:
* Returns a const reference for acquiring constant simulator specific information. * Returns a const reference for acquiring constant simulator specific information.
* e.g., Registernames, to ease experiment data construction. * e.g., Registernames, to ease experiment data construction.
* The campaign description is not allowed to change the simulator * The campaign description is not allowed to change the simulator
* state, as the actual simulation runs within another process (Minion) * state, as the actual simulation runs within another process (Minion)
* @return constant reference to the current simulator backend. * @return constant reference to the current simulator backend.
*/ */
SimulatorController const& getSimulator() const { return simulator; } SimulatorController const& getSimulator() const { return simulator; }

View File

@ -29,13 +29,13 @@ bool DatabaseCampaign::run() {
if (!cb_commandline_init()) return false; if (!cb_commandline_init()) return false;
CommandLine::option_handle VARIANT = cmd.addOption("v", "variant", Arg::Required, CommandLine::option_handle VARIANT = cmd.addOption("v", "variant", Arg::Required,
"-v/--variant \tVariant label (default: \"none\")"); "-v/--variant \tVariant label (default: \"none\"; use % and _ as wildcard characters)");
CommandLine::option_handle BENCHMARK = cmd.addOption("b", "benchmark", Arg::Required, CommandLine::option_handle BENCHMARK = cmd.addOption("b", "benchmark", Arg::Required,
"-b/--benchmark \tBenchmark label (default: \"none\")\n"); "-b/--benchmark \tBenchmark label (default: \"none\"; use % and _ as wildcard characters)\n");
CommandLine::option_handle PRUNER = cmd.addOption("p", "prune-method", Arg::Required, CommandLine::option_handle PRUNER = cmd.addOption("p", "prune-method", Arg::Required,
"-p/--prune-method \tWhich import method to use (default: basic)"); "-p/--prune-method \tWhich import method to use (default: basic)");
if(!cmd.parse()) { if (!cmd.parse()) {
log_send << "Error parsing arguments." << std::endl; log_send << "Error parsing arguments." << std::endl;
exit(-1); exit(-1);
} }
@ -82,7 +82,7 @@ bool DatabaseCampaign::run() {
std::vector<Database::Variant> variants = db->get_variants(variant, benchmark); std::vector<Database::Variant> variants = db->get_variants(variant, benchmark);
for (std::vector<Database::Variant>::const_iterator it = variants.begin(); for (std::vector<Database::Variant>::const_iterator it = variants.begin();
it != variants.end(); ++it) { it != variants.end(); ++it) {
if(!run_variant(*it)) { if (!run_variant(*it)) {
log_send << "run_variant failed for " << it->variant << "/" << it->benchmark <<std::endl; log_send << "run_variant failed for " << it->variant << "/" << it->benchmark <<std::endl;
return false; return false;
} }
@ -147,7 +147,7 @@ bool DatabaseCampaign::run_variant(Database::Variant variant) {
MYSQL_RES *pilots = db->query_stream ((sql_select + sql_body).c_str()); MYSQL_RES *pilots = db->query_stream ((sql_select + sql_body).c_str());
log_send << "Found " << experiment_count << " unfinished experiments in database. (" log_send << "Found " << experiment_count << " unfinished experiments in database. ("
<< variant.variant << "/" << variant.benchmark << ")" << std::endl; << variant.variant << "/" << variant.benchmark << ")" << std::endl;
sent_pilots = 0; sent_pilots = 0;

View File

@ -61,7 +61,7 @@ public:
virtual bool cb_commandline_init() { return true; } virtual bool cb_commandline_init() { return true; }
/** /**
* Callback to the campagin to get the result message descriptor * Callback to the campaign to get the result message descriptor
*/ */
virtual const google::protobuf::Descriptor * cb_result_message() = 0; virtual const google::protobuf::Descriptor * cb_result_message() = 0;

View File

@ -159,7 +159,7 @@ void JobServer::run()
// TODO: Log-level? // TODO: Log-level?
#ifndef __puma #ifndef __puma
boost::thread* th; boost::thread* th;
while (!m_finish){ while (!m_finish) {
// Accept connection // Accept connection
int cs = SocketComm::timedAccept(s, (struct sockaddr*)&clientaddr, &clen, 100); int cs = SocketComm::timedAccept(s, (struct sockaddr*)&clientaddr, &clen, 100);
if (cs < 0) { if (cs < 0) {

View File

@ -1,5 +1,5 @@
#ifndef __JOB_SERVER_H__ #ifndef __JOB_SERVER_H__
#define __JOB_SERVER_H__ #define __JOB_SERVER_H__
#include "Minion.hpp" #include "Minion.hpp"
#include "util/SynchronizedQueue.hpp" #include "util/SynchronizedQueue.hpp"
@ -110,7 +110,7 @@ public:
/** /**
* Adds a new experiment data set to the job queue. * Adds a new experiment data set to the job queue.
* @param data Pointer to an expoeriment data object * @param data Pointer to an expoeriment data object
*/ */
void addParam(ExperimentData* data); void addParam(ExperimentData* data);
/** /**
* Retrieve an experiment result. Blocks if we currently have no results. * Retrieve an experiment result. Blocks if we currently have no results.

View File

@ -4,7 +4,7 @@
*/ */
#ifndef __MINION_HPP__ #ifndef __MINION_HPP__
#define __MINION_HPP__ #define __MINION_HPP__
#include <string> #include <string>
@ -14,14 +14,14 @@ namespace fail {
/** /**
* \class Minion * \class Minion
* *
* Contains all informations about a minion. * Contains all informations about a minion.
*/ */
class Minion { class Minion {
private: private:
std::string hostname; std::string hostname;
bool isWorking; bool isWorking;
ExperimentData* currentExperimentData; ExperimentData* currentExperimentData;
int sockfd; int sockfd;
public: public:
Minion() : isWorking(false), currentExperimentData(0), sockfd(-1) { } Minion() : isWorking(false), currentExperimentData(0), sockfd(-1) { }

View File

@ -1,5 +1,5 @@
#ifndef __COROUTINE_MANAGER_HPP__ #ifndef __COROUTINE_MANAGER_HPP__
#define __COROUTINE_MANAGER_HPP__ #define __COROUTINE_MANAGER_HPP__
#include <map> #include <map>
#include <stack> #include <stack>

View File

@ -1,5 +1,5 @@
#ifndef __EXPERIMENT_FLOW_HPP__ #ifndef __EXPERIMENT_FLOW_HPP__
#define __EXPERIMENT_FLOW_HPP__ #define __EXPERIMENT_FLOW_HPP__
#include "sal/SALInst.hpp" #include "sal/SALInst.hpp"

View File

@ -15,8 +15,10 @@ JobClient::JobClient(const std::string& server, int port)
{ {
SocketComm::init(); SocketComm::init();
m_server_ent = gethostbyname(m_server.c_str()); m_server_ent = gethostbyname(m_server.c_str());
cout << "JobServer: " << m_server.c_str() << endl;
if(m_server_ent == NULL) { cout << "JobServer: " << m_server.c_str() << endl;
if (m_server_ent == NULL) {
perror("[Client@gethostbyname()]"); perror("[Client@gethostbyname()]");
// TODO: Log-level? // TODO: Log-level?
exit(1); exit(1);
@ -109,7 +111,6 @@ bool JobClient::getParam(ExperimentData& exp)
FailControlMessage_Command JobClient::tryToGetExperimentData(ExperimentData& exp) FailControlMessage_Command JobClient::tryToGetExperimentData(ExperimentData& exp)
{ {
FailControlMessage ctrlmsg; FailControlMessage ctrlmsg;
//Are there other jobs for the experiment //Are there other jobs for the experiment
@ -144,7 +145,7 @@ FailControlMessage_Command JobClient::tryToGetExperimentData(ExperimentData& exp
switch (ctrlmsg.command()) { switch (ctrlmsg.command()) {
case FailControlMessage::WORK_FOLLOWS: case FailControlMessage::WORK_FOLLOWS:
uint32_t i; uint32_t i;
for (i = 0 ; i < ctrlmsg.job_size() ; i++) { for (i = 0; i < ctrlmsg.job_size(); i++) {
ExperimentData* temp_exp = new ExperimentData(exp.getMessage().New()); ExperimentData* temp_exp = new ExperimentData(exp.getMessage().New());
if (!SocketComm::rcvMsg(m_sockfd, temp_exp->getMessage())) { if (!SocketComm::rcvMsg(m_sockfd, temp_exp->getMessage())) {
@ -187,8 +188,6 @@ FailControlMessage_Command JobClient::tryToGetExperimentData(ExperimentData& exp
} else { } else {
return ctrlmsg.command(); return ctrlmsg.command();
} }
} }
bool JobClient::sendResult(ExperimentData& result) bool JobClient::sendResult(ExperimentData& result)
@ -198,7 +197,7 @@ bool JobClient::sendResult(ExperimentData& result)
temp_exp->getMessage().CopyFrom(result.getMessage()); temp_exp->getMessage().CopyFrom(result.getMessage());
temp_exp->setWorkloadID(result.getWorkloadID()); temp_exp->setWorkloadID(result.getWorkloadID());
m_results.push_back( temp_exp ); m_results.push_back(temp_exp);
if (m_parameters.size() != 0) { if (m_parameters.size() != 0) {
//If job request time is over send back all existing results //If job request time is over send back all existing results
@ -259,7 +258,7 @@ bool JobClient::sendResultsToServer()
cout << "[Client] Sending back result ["; cout << "[Client] Sending back result [";
uint32_t i; uint32_t i;
for (i = 0; i < m_results.size() ; i++) { for (i = 0; i < m_results.size(); i++) {
ctrlmsg.add_workloadid(m_results[i]->getWorkloadID()); ctrlmsg.add_workloadid(m_results[i]->getWorkloadID());
cout << std::dec << m_results[i]->getWorkloadID(); cout << std::dec << m_results[i]->getWorkloadID();
cout << " "; cout << " ";
@ -272,7 +271,7 @@ bool JobClient::sendResultsToServer()
return false; return false;
} }
for (i = 0; i < ctrlmsg.job_size() ; i++) { for (i = 0; i < ctrlmsg.job_size(); i++) {
if (!SocketComm::sendMsg(m_sockfd, m_results.front()->getMessage())) { if (!SocketComm::sendMsg(m_sockfd, m_results.front()->getMessage())) {
close(m_sockfd); close(m_sockfd);
return false; return false;

View File

@ -1,5 +1,5 @@
#ifndef __JOB_CLIENT_H__ #ifndef __JOB_CLIENT_H__
#define __JOB_CLIENT_H__ #define __JOB_CLIENT_H__
#include <string> #include <string>
#include <ctime> #include <ctime>

View File

@ -1,6 +1,6 @@
// Architecture.hpp: wraps architecture definition headers // Architecture.hpp: wraps architecture definition headers
#ifndef __ARCHITECTURE_HPP__ #ifndef __ARCHITECTURE_HPP__
#define __ARCHITECTURE_HPP__ #define __ARCHITECTURE_HPP__
#include "config/FailConfig.hpp" #include "config/FailConfig.hpp"

View File

@ -1,5 +1,5 @@
#ifndef __CPU_HPP__ #ifndef __CPU_HPP__
#define __CPU_HPP__ #define __CPU_HPP__
#include <cstring> #include <cstring>
#include <vector> #include <vector>

View File

@ -26,7 +26,7 @@ bool CPUState::addSuppressedInterrupt(unsigned interruptNum)
// Check if already existing: // Check if already existing:
if (isSuppressedInterrupt(interruptNum+32)) if (isSuppressedInterrupt(interruptNum+32))
return false; // already added: nothing to do here return false; // already added: nothing to do here
// FIXME: addSuppressedInterrupt(ANY_INTERRUPT) can still be called more // FIXME: addSuppressedInterrupt(ANY_INTERRUPT) can still be called more
// than once. This is not handled by the if-statement above. // than once. This is not handled by the if-statement above.
if (interruptNum == ANY_INTERRUPT) if (interruptNum == ANY_INTERRUPT)

View File

@ -1,5 +1,5 @@
#ifndef __CPU_STATE_HPP__ #ifndef __CPU_STATE_HPP__
#define __CPU_STATE_HPP__ #define __CPU_STATE_HPP__
#include <cstring> #include <cstring>
#include <vector> #include <vector>

View File

@ -1,25 +1,25 @@
#ifndef __CONCRETE_CPU_HPP__ #ifndef __CONCRETE_CPU_HPP__
#define __CONCRETE_CPU_HPP__ #define __CONCRETE_CPU_HPP__
#if defined BUILD_BOCHS #if defined BUILD_BOCHS
#include "bochs/BochsCPU.hpp" #include "bochs/BochsCPU.hpp"
#elif defined BUILD_GEM5 #elif defined BUILD_GEM5
#if defined BUILD_ARM #if defined BUILD_ARM
#include "gem5/Gem5ArmCPU.hpp" #include "gem5/Gem5ArmCPU.hpp"
#else #else
#error Active config currently not supported! #error Active config currently not supported!
#endif #endif
#elif defined BUILD_QEMU #elif defined BUILD_QEMU
#include "qemu/QEMUConfig.hpp" #include "qemu/QEMUConfig.hpp"
#elif defined BUILD_T32 #elif defined BUILD_T32
#include "t32/T32Config.hpp" #include "t32/T32Config.hpp"
#if defined BUILD_ARM #if defined BUILD_ARM
#include "t32/T32ArmCPU.hpp" #include "t32/T32ArmCPU.hpp"
#else #else
#error Active config currently not supported! #error Active config currently not supported!
#endif #endif
#else #else
#error SAL Config Target not defined #error SAL Config Target not defined
#endif #endif
#endif // __CONCRETE_CPU_HPP__ #endif // __CONCRETE_CPU_HPP__

View File

@ -1,5 +1,5 @@
#ifndef __EVENT_HPP__ #ifndef __EVENT_HPP__
#define __EVENT_HPP__ #define __EVENT_HPP__
#include <ctime> #include <ctime>
#include <string> #include <string>

View File

@ -1,5 +1,5 @@
#ifndef __LISTENER_HPP__ #ifndef __LISTENER_HPP__
#define __LISTENER_HPP__ #define __LISTENER_HPP__
#include <string> #include <string>
#include <cassert> #include <cassert>
@ -205,12 +205,12 @@ public:
}; };
#if defined CONFIG_EVENT_BREAKPOINTS #if defined CONFIG_EVENT_BREAKPOINTS
#define BP_CTOR_SCOPE public #define BP_CTOR_SCOPE public
#else #else
#define BP_CTOR_SCOPE protected #define BP_CTOR_SCOPE protected
// This prevents an experiment from instantiating an object of BPSingleListener // This prevents an experiment from instantiating an object of BPSingleListener
// without having enabled the appropriate configuration flag, i.e., // without having enabled the appropriate configuration flag, i.e.,
// CONFIG_EVENT_BREAKPOINTS = ON. // CONFIG_EVENT_BREAKPOINTS = ON.
#endif #endif
/** /**
* \class BPSingleListener * \class BPSingleListener
@ -252,9 +252,9 @@ public: // reset scope in order to allow compiling the various other Fail* sourc
}; };
#if defined CONFIG_EVENT_BREAKPOINTS_RANGE #if defined CONFIG_EVENT_BREAKPOINTS_RANGE
#define BPRANGE_CTOR_SCOPE public #define BPRANGE_CTOR_SCOPE public
#else #else
#define BPRANGE_CTOR_SCOPE protected #define BPRANGE_CTOR_SCOPE protected
#endif #endif
/** /**
* \class BPRangeListener * \class BPRangeListener
@ -300,12 +300,12 @@ public:
}; };
#if defined CONFIG_EVENT_MEMREAD || defined CONFIG_EVENT_MEMWRITE #if defined CONFIG_EVENT_MEMREAD || defined CONFIG_EVENT_MEMWRITE
#define WP_CTOR_SCOPE public #define WP_CTOR_SCOPE public
#else #else
#define WP_CTOR_SCOPE protected #define WP_CTOR_SCOPE protected
// Note: "private" works only in case of a "final class" (a leaf class) because when using // Note: "private" works only in case of a "final class" (a leaf class) because when using
// "private", the derived classes wouldn't compile anymore (even if they are not used anyway). // "private", the derived classes wouldn't compile anymore (even if they are not used anyway).
// Clearly, MemAccessListener is *not* a leaf class. // Clearly, MemAccessListener is *not* a leaf class.
#endif #endif
/** /**
* \class MemAccessListener * \class MemAccessListener
@ -413,9 +413,9 @@ public:
}; };
#ifdef CONFIG_EVENT_MEMREAD #ifdef CONFIG_EVENT_MEMREAD
#define WPREAD_CTOR_SCOPE public #define WPREAD_CTOR_SCOPE public
#else #else
#define WPREAD_CTOR_SCOPE protected #define WPREAD_CTOR_SCOPE protected
#endif #endif
/** /**
* \class MemReadListener * \class MemReadListener
@ -430,9 +430,9 @@ WPREAD_CTOR_SCOPE:
}; };
#ifdef CONFIG_EVENT_MEMWRITE #ifdef CONFIG_EVENT_MEMWRITE
#define WPWRITE_CTOR_SCOPE public #define WPWRITE_CTOR_SCOPE public
#else #else
#define WPWRITE_CTOR_SCOPE protected #define WPWRITE_CTOR_SCOPE protected
#endif #endif
/** /**
* \class MemWriteListener * \class MemWriteListener
@ -447,9 +447,9 @@ WPWRITE_CTOR_SCOPE:
}; };
#if defined CONFIG_EVENT_INTERRUPT || defined CONFIG_EVENT_TRAP #if defined CONFIG_EVENT_INTERRUPT || defined CONFIG_EVENT_TRAP
#define TROUBLE_CTOR_SCOPE public #define TROUBLE_CTOR_SCOPE public
#else #else
#define TROUBLE_CTOR_SCOPE protected #define TROUBLE_CTOR_SCOPE protected
#endif #endif
/** /**
* \class TroubleListener * \class TroubleListener
@ -513,9 +513,9 @@ public:
}; };
#ifdef CONFIG_EVENT_INTERRUPT #ifdef CONFIG_EVENT_INTERRUPT
#define INT_CTOR_SCOPE public #define INT_CTOR_SCOPE public
#else #else
#define INT_CTOR_SCOPE protected #define INT_CTOR_SCOPE protected
#endif #endif
/** /**
* \class InterruptListener * \class InterruptListener
@ -540,9 +540,9 @@ public:
}; };
#ifdef CONFIG_EVENT_TRAP #ifdef CONFIG_EVENT_TRAP
#define TRAP_CTOR_SCOPE public #define TRAP_CTOR_SCOPE public
#else #else
#define TRAP_CTOR_SCOPE protected #define TRAP_CTOR_SCOPE protected
#endif #endif
/** /**
* \class TrapListener * \class TrapListener
@ -556,9 +556,9 @@ TRAP_CTOR_SCOPE:
}; };
#ifdef CONFIG_EVENT_GUESTSYS #ifdef CONFIG_EVENT_GUESTSYS
#define GUESTSYS_CTOR_SCOPE public #define GUESTSYS_CTOR_SCOPE public
#else #else
#define GUESTSYS_CTOR_SCOPE protected #define GUESTSYS_CTOR_SCOPE protected
#endif #endif
/** /**
* \class GuestListener * \class GuestListener
@ -592,9 +592,9 @@ public:
}; };
#ifdef CONFIG_EVENT_IOPORT #ifdef CONFIG_EVENT_IOPORT
#define IOPORT_CTOR_SCOPE public #define IOPORT_CTOR_SCOPE public
#else #else
#define IOPORT_CTOR_SCOPE protected #define IOPORT_CTOR_SCOPE protected
#endif #endif
/** /**
* \class IOPortListener * \class IOPortListener
@ -661,9 +661,9 @@ public:
}; };
#ifdef CONFIG_EVENT_JUMP #ifdef CONFIG_EVENT_JUMP
#define JUMP_CTOR_SCOPE public #define JUMP_CTOR_SCOPE public
#else #else
#define JUMP_CTOR_SCOPE protected #define JUMP_CTOR_SCOPE protected
#endif #endif
/** /**
* \class JumpListener * \class JumpListener

View File

@ -37,7 +37,7 @@ void ListenerManager::remove(BaseListener* li)
for (index_t i = 0; i < m_BufferList.size(); ) { for (index_t i = 0; i < m_BufferList.size(); ) {
if (m_BufferList[i]->getParent() == simulator.m_Flows.getCurrent()) { if (m_BufferList[i]->getParent() == simulator.m_Flows.getCurrent()) {
m_BufferList[i]->onDeletion(); m_BufferList[i]->onDeletion();
if(m_BufferList[i]->getPerformanceBuffer() != NULL) if (m_BufferList[i]->getPerformanceBuffer() != NULL)
m_BufferList[i]->getPerformanceBuffer()->remove(i); m_BufferList[i]->getPerformanceBuffer()->remove(i);
m_remove(i); m_remove(i);
// Inspect the element at m_BufferList[i] a 2nd time // Inspect the element at m_BufferList[i] a 2nd time
@ -117,7 +117,7 @@ void ListenerManager::remove(ExperimentFlow* flow)
std::set<PerfBufferBase*> perfBufLists; std::set<PerfBufferBase*> perfBufLists;
for (bufferlist_t::iterator it = m_BufferList.begin(); it != m_BufferList.end(); it++) { for (bufferlist_t::iterator it = m_BufferList.begin(); it != m_BufferList.end(); it++) {
(*it)->onDeletion(); // invoke listener handler (*it)->onDeletion(); // invoke listener handler
if((*it)->getPerformanceBuffer() != NULL) if ((*it)->getPerformanceBuffer() != NULL)
perfBufLists.insert((*it)->getPerformanceBuffer()); perfBufLists.insert((*it)->getPerformanceBuffer());
(*it)->setPerformanceBuffer(NULL); (*it)->setPerformanceBuffer(NULL);
(*it)->setLocation(INVALID_INDEX); (*it)->setLocation(INVALID_INDEX);
@ -184,7 +184,7 @@ ListenerManager::iterator ListenerManager::makeActive(iterator it)
// this slot stores the element which has previously been stored in the last slot): // this slot stores the element which has previously been stored in the last slot):
// This is required because the provided iterator "it" isn't valid anymore (due // This is required because the provided iterator "it" isn't valid anymore (due
// to the deletion of the last element within m_remove(index_t)). // to the deletion of the last element within m_remove(index_t)).
iterator it_next = begin() + dist; // O(1) iterator it_next = begin() + dist; // O(1)
// Note: "begin() + dist" yields end() if dist is "large enough" (as computed above) // Note: "begin() + dist" yields end() if dist is "large enough" (as computed above)

View File

@ -1,5 +1,5 @@
#ifndef __LISTENER_MANAGER_HPP__ #ifndef __LISTENER_MANAGER_HPP__
#define __LISTENER_MANAGER_HPP__ #define __LISTENER_MANAGER_HPP__
#include <cassert> #include <cassert>
#include <list> #include <list>
@ -184,7 +184,7 @@ public:
* regarding their location and performance-buffer reference, i.e. their index and * regarding their location and performance-buffer reference, i.e. their index and
* performance-buffer pointer will be invalidated (by setting \c INVALID_INDEX and * performance-buffer pointer will be invalidated (by setting \c INVALID_INDEX and
* \c NULL, respectively). * \c NULL, respectively).
* To actually fire the listeners, call triggerActiveListeners(). * To actually fire the listeners, call triggerActiveListeners().
* @param pLi the listener object pointer to trigger; \c pLi will be removed in * @param pLi the listener object pointer to trigger; \c pLi will be removed in
* \c pLi->getPerformanceBuffer(). If the performance buffer-list ptr is * \c pLi->getPerformanceBuffer(). If the performance buffer-list ptr is
* \c NULL, nothing will be done. * \c NULL, nothing will be done.

View File

@ -1,5 +1,5 @@
#ifndef __MEMORY_HPP__ #ifndef __MEMORY_HPP__
#define __MEMORY_HPP__ #define __MEMORY_HPP__
#include <vector> #include <vector>
#include <stdint.h> #include <stdint.h>

View File

@ -6,34 +6,34 @@
namespace fail { namespace fail {
class MemoryInstruction { class MemoryInstruction {
regdata_t address; regdata_t address;
regdata_t value; regdata_t value;
uint8_t width; uint8_t width;
bool writeAccess; bool writeAccess;
public: public:
MemoryInstruction(regdata_t address = ADDR_INV, regdata_t value = 0, uint8_t width = 0, bool writeAccess = false) : MemoryInstruction(regdata_t address = ADDR_INV, regdata_t value = 0, uint8_t width = 0, bool writeAccess = false) :
address(address), value(value), width(width), writeAccess(writeAccess) { }; address(address), value(value), width(width), writeAccess(writeAccess) { };
bool isWriteAccess(void) const { return writeAccess; } bool isWriteAccess(void) const { return writeAccess; }
regdata_t getAddress() const { return address; } regdata_t getAddress() const { return address; }
regdata_t getValue() const { return value; } regdata_t getValue() const { return value; }
uint8_t getWidth() const { return width; } uint8_t getWidth() const { return width; }
bool isValid(void) const { return address != ADDR_INV; } bool isValid(void) const { return address != ADDR_INV; }
void setAddress(regdata_t addr) { address = addr; } void setAddress(regdata_t addr) { address = addr; }
void setValue(regdata_t val) { value = val; } void setValue(regdata_t val) { value = val; }
void setWidth(uint8_t w) { width = w; } void setWidth(uint8_t w) { width = w; }
void setWriteAccess(bool iswrite) { writeAccess = iswrite; } void setWriteAccess(bool iswrite) { writeAccess = iswrite; }
}; };
class MemoryInstructionAnalyzer { class MemoryInstructionAnalyzer {
public: public:
virtual bool eval(address_t opcode, MemoryInstruction & result) = 0; virtual bool eval(address_t opcode, MemoryInstruction& result) = 0;
}; };
extern MemoryInstructionAnalyzer & meminstruction; extern MemoryInstructionAnalyzer& meminstruction;
} // end of namespace fail } // end of namespace fail
#endif // __MEMORYINSTRUCTION_HPP__ #endif // __MEMORYINSTRUCTION_HPP__

View File

@ -1,5 +1,5 @@
#ifndef __REGISTER_HPP__ #ifndef __REGISTER_HPP__
#define __REGISTER_HPP__ #define __REGISTER_HPP__
#include <vector> #include <vector>
#include <cstdlib> #include <cstdlib>

View File

@ -13,7 +13,7 @@ const unsigned ANY_TRAP = static_cast<unsigned> (-1);
const unsigned ANY_INTERRUPT = static_cast<unsigned> (-1); const unsigned ANY_INTERRUPT = static_cast<unsigned> (-1);
const timer_id_t INVALID_TIMER = static_cast<timer_id_t> (0); const timer_id_t INVALID_TIMER = static_cast<timer_id_t> (0);
#else #else
#error SAL Config Target not defined #error SAL Config Target not defined
#endif #endif
} // end-of-namespace: fail } // end-of-namespace: fail

View File

@ -1,5 +1,5 @@
#ifndef __SAL_CONFIG_HPP__ #ifndef __SAL_CONFIG_HPP__
#define __SAL_CONFIG_HPP__ #define __SAL_CONFIG_HPP__
#include <stdint.h> #include <stdint.h>
@ -7,15 +7,15 @@
// Type-config depends on the current selected simulator: // Type-config depends on the current selected simulator:
#if defined BUILD_BOCHS #if defined BUILD_BOCHS
#include "bochs/BochsConfig.hpp" #include "bochs/BochsConfig.hpp"
#elif defined BUILD_GEM5 #elif defined BUILD_GEM5
#include "gem5/Gem5Config.hpp" #include "gem5/Gem5Config.hpp"
#elif defined BUILD_QEMU #elif defined BUILD_QEMU
#include "qemu/QEMUConfig.hpp" #include "qemu/QEMUConfig.hpp"
#elif defined BUILD_T32 #elif defined BUILD_T32
#include "t32/T32Config.hpp" #include "t32/T32Config.hpp"
#else #else
#error SAL Config Target not defined #error SAL Config Target not defined
#endif #endif
namespace fail { namespace fail {

View File

@ -1,5 +1,5 @@
#ifndef __SAL_INSTANCE_HPP__ #ifndef __SAL_INSTANCE_HPP__
#define __SAL_INSTANCE_HPP__ #define __SAL_INSTANCE_HPP__
#include "SALConfig.hpp" #include "SALConfig.hpp"
#include "config/VariantConfig.hpp" #include "config/VariantConfig.hpp"

View File

@ -84,7 +84,7 @@ void SimulatorController::onBreakpoint(ConcreteCPU* cpu, address_t instrPtr, add
} }
void SimulatorController::onMemoryAccess(ConcreteCPU* cpu, address_t addr, size_t len, void SimulatorController::onMemoryAccess(ConcreteCPU* cpu, address_t addr, size_t len,
bool is_write, address_t instrPtr) bool is_write, address_t instrPtr)
{ {
MemAccessEvent::access_type_t accesstype = MemAccessEvent::access_type_t accesstype =
is_write ? MemAccessEvent::MEM_WRITE is_write ? MemAccessEvent::MEM_WRITE
@ -114,7 +114,7 @@ void SimulatorController::onInterrupt(ConcreteCPU* cpu, unsigned interruptNum, b
{ {
ListenerManager::iterator it = m_LstList.begin(); ListenerManager::iterator it = m_LstList.begin();
InterruptEvent tmp(nmi, interruptNum, cpu); InterruptEvent tmp(nmi, interruptNum, cpu);
while (it != m_LstList.end()) { // check for active listeners while (it != m_LstList.end()) { // check for active listeners
BaseListener* pev = *it; BaseListener* pev = *it;
InterruptListener* pie = dynamic_cast<InterruptListener*>(pev); InterruptListener* pie = dynamic_cast<InterruptListener*>(pev);
if (!pie || !pie->isMatching(&tmp)) { if (!pie || !pie->isMatching(&tmp)) {

View File

@ -1,5 +1,5 @@
#ifndef __SIMULATOR_CONTROLLER_HPP__ #ifndef __SIMULATOR_CONTROLLER_HPP__
#define __SIMULATOR_CONTROLLER_HPP__ #define __SIMULATOR_CONTROLLER_HPP__
#include <iostream> #include <iostream>
#include <string> #include <string>
@ -83,7 +83,7 @@ public:
* @param is_write \c true if memory is written, \c false if read * @param is_write \c true if memory is written, \c false if read
* @param instrPtr the address of the instruction causing the memory * @param instrPtr the address of the instruction causing the memory
* access * access
* *
* FIXME: should instrPtr be part of this interface? * FIXME: should instrPtr be part of this interface?
*/ */
void onMemoryAccess(ConcreteCPU* cpu, address_t addr, size_t len, bool is_write, address_t instrPtr); void onMemoryAccess(ConcreteCPU* cpu, address_t addr, size_t len, bool is_write, address_t instrPtr);

View File

@ -1,5 +1,5 @@
#ifndef __ARM_ARCHITECURE_HPP__ #ifndef __ARM_ARCHITECURE_HPP__
#define __ARM_ARCHITECURE_HPP__ #define __ARM_ARCHITECURE_HPP__
#include "../CPU.hpp" #include "../CPU.hpp"
#include "../CPUState.hpp" #include "../CPUState.hpp"

View File

@ -1,5 +1,5 @@
#ifndef __ARM_CPU_STATE_HPP__ #ifndef __ARM_CPU_STATE_HPP__
#define __ARM_CPU_STATE_HPP__ #define __ARM_CPU_STATE_HPP__
#include "../CPU.hpp" #include "../CPU.hpp"
#include "../CPUState.hpp" #include "../CPUState.hpp"

View File

@ -1266,7 +1266,7 @@ static int evaluate_mrs_msr(uint32_t opcode,
uint32_t address, struct arm_instruction *instruction) uint32_t address, struct arm_instruction *instruction)
{ {
int R = (opcode & 0x00400000) >> 22; int R = (opcode & 0x00400000) >> 22;
std::string PSR = (R) ? "SPSR" : "CPSR"; std::string PSR = (R) ? "SPSR" : "CPSR";
/* Move register to status register (MSR) */ /* Move register to status register (MSR) */
if (opcode & 0x00200000) { if (opcode & 0x00200000) {
@ -1922,64 +1922,64 @@ int arm_evaluate_opcode(uint32_t opcode, uint32_t address,
} }
void arm_load_store_instr::evaluate() { void arm_load_store_instr::evaluate() {
fail::Register * reg = fail::simulator.getCPU(0).getRegister(Rd); fail::Register * reg = fail::simulator.getCPU(0).getRegister(Rd);
value = fail::simulator.getCPU(0).getRegisterContent(reg); value = fail::simulator.getCPU(0).getRegisterContent(reg);
uint32_t offs = 0; uint32_t offs = 0;
std::cout << " Value Register: r" << (int)(Rd) << " = 0x" << std::hex << value << std::endl; std::cout << " Value Register: r" << (int)(Rd) << " = 0x" << std::hex << value << std::endl;
// Address holding register: // Address holding register:
reg = fail::simulator.getCPU(0).getRegister(Rn); reg = fail::simulator.getCPU(0).getRegister(Rn);
address = fail::simulator.getCPU(0).getRegisterContent(reg); address = fail::simulator.getCPU(0).getRegisterContent(reg);
if(offset_mode == 0) { // immediate if (offset_mode == 0) { // immediate
offs = offset.offset; offs = offset.offset;
} else { // (scaled) register } else { // (scaled) register
reg = fail::simulator.getCPU(0).getRegister(offset.reg.Rm); reg = fail::simulator.getCPU(0).getRegister(offset.reg.Rm);
// get scale register // get scale register
uint32_t rm = fail::simulator.getCPU(0).getRegisterContent(reg); uint32_t rm = fail::simulator.getCPU(0).getRegisterContent(reg);
// get shift value // get shift value
uint8_t shimm = offset.reg.shift_imm; uint8_t shimm = offset.reg.shift_imm;
switch(offset.reg.shift) { switch (offset.reg.shift) {
case 0: // LSL case 0: // LSL
offs = rm << shimm; offs = rm << shimm;
break; break;
case 1: // LSR case 1: // LSR
offs = rm >> shimm; offs = rm >> shimm;
break; break;
case 2: // ASR case 2: // ASR
offs = (rm >> shimm) | (rm & (1 << 31)); offs = (rm >> shimm) | (rm & (1 << 31));
break; break;
case 3: // ROR case 3: // ROR
offs = ror(rm, shimm); offs = ror(rm, shimm);
break; break;
case 4: // RRX case 4: // RRX
// This might be wrong! // This might be wrong!
// RRX rotates right 1 bit, the carry flag is moved to 31 // RRX rotates right 1 bit, the carry flag is moved to 31
// and to original bit 0 is moved to the carry flag. // and to original bit 0 is moved to the carry flag.
// Now we have a problem: The original carry flag is updated, // Now we have a problem: The original carry flag is updated,
// The offset is either: // The offset is either:
offs = rm >> 1; offs = rm >> 1;
// OR: offs = (rm >> 1) | (1 << 31); // if CF = 1 // OR: offs = (rm >> 1) | (1 << 31); // if CF = 1
break; break;
default: break; default: break;
} }
} }
// Apply the offset to the address register // Apply the offset to the address register
if(index_mode == 1) { // pre indexed if (index_mode == 1) { // pre indexed
// the calculated address was already written back into Rn // the calculated address was already written back into Rn
} else if (index_mode == 2) { // post indexed } else if (index_mode == 2) { // post indexed
// the address got the offset after the mem access // the address got the offset after the mem access
address = address - offs; address = address - offs;
} else { // we have to apply the offset ourselfs } else { // we have to apply the offset ourselfs
address = address + offs; address = address + offs;
} }
std::cout << " Address Register: r" << (int)(Rn) << " = 0x" << std::hex << address << std::endl; std::cout << " Address Register: r" << (int)(Rn) << " = 0x" << std::hex << address << std::endl;
} }
@ -2793,7 +2793,7 @@ static int evaluate_ifthen_thumb(uint16_t opcode, uint32_t address,
struct arm_instruction *instruction) struct arm_instruction *instruction)
{ {
unsigned cond = (opcode >> 4) & 0x0f; unsigned cond = (opcode >> 4) & 0x0f;
std::string x = "", y = "", z = ""; std::string x = "", y = "", z = "";
if (opcode & 0x01) if (opcode & 0x01)
z = (opcode & 0x02) ? "T" : "E"; z = (opcode & 0x02) ? "T" : "E";
@ -3431,7 +3431,7 @@ static int t2ev_store_single(uint32_t opcode, uint32_t address,
if (rn == 0xf) if (rn == 0xf)
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
instruction->type = ARM_STR; instruction->type = ARM_STR;
if (opcode & 0x0800) if (opcode & 0x0800)
op |= 1; op |= 1;
switch (op) { switch (op) {
@ -3439,29 +3439,29 @@ static int t2ev_store_single(uint32_t opcode, uint32_t address,
case 0x8: case 0x8:
case 0x9: case 0x9:
size = "B"; size = "B";
instruction->type = ARM_STRB; instruction->type = ARM_STRB;
goto imm12; goto imm12;
case 0x1: case 0x1:
size = "B"; size = "B";
instruction->type = ARM_STRB; instruction->type = ARM_STRB;
goto imm8; goto imm8;
case 0x0: case 0x0:
size = "B"; size = "B";
instruction->type = ARM_STRB; instruction->type = ARM_STRB;
break; break;
/* halfword */ /* halfword */
case 0xa: case 0xa:
case 0xb: case 0xb:
size = "H"; size = "H";
instruction->type = ARM_STRH; instruction->type = ARM_STRH;
goto imm12; goto imm12;
case 0x3: case 0x3:
size = "H"; size = "H";
instruction->type = ARM_STRH; instruction->type = ARM_STRH;
goto imm8; goto imm8;
case 0x2: case 0x2:
size = "H"; size = "H";
instruction->type = ARM_STRH; instruction->type = ARM_STRH;
break; break;
/* word */ /* word */
case 0xc: case 0xc:
@ -3479,12 +3479,12 @@ static int t2ev_store_single(uint32_t opcode, uint32_t address,
sprintf(cp, "STR%s.W\tr%d, [r%d, r%d, LSL #%d]", sprintf(cp, "STR%s.W\tr%d, [r%d, r%d, LSL #%d]",
size, rt, rn, (int) opcode & 0x0f, size, rt, rn, (int) opcode & 0x0f,
(int) (opcode >> 4) & 0x03); (int) (opcode >> 4) & 0x03);
instruction->info.load_store.Rn = rn; //MH instruction->info.load_store.Rn = rn; //MH
instruction->info.load_store.Rd = rt; //MH instruction->info.load_store.Rd = rt; //MH
instruction->info.load_store.offset_mode = 1; // scaled reg instruction->info.load_store.offset_mode = 1; // scaled reg
instruction->info.load_store.offset.reg.Rm = (int)(opcode & 0x0f); instruction->info.load_store.offset.reg.Rm = (int)(opcode & 0x0f);
instruction->info.load_store.offset.reg.shift = 0; // LSL = 0 instruction->info.load_store.offset.reg.shift = 0; // LSL = 0
instruction->info.load_store.offset.reg.shift_imm = (int)((opcode >> 4) & 0x03); instruction->info.load_store.offset.reg.shift_imm = (int)((opcode >> 4) & 0x03);
return ERROR_OK; return ERROR_OK;
@ -3493,17 +3493,17 @@ imm12:
sprintf(cp, "STR%s.W\tr%d, [r%d, #%u]\t; %#3.3x", sprintf(cp, "STR%s.W\tr%d, [r%d, #%u]\t; %#3.3x",
size, rt, rn, immed, immed); size, rt, rn, immed, immed);
instruction->info.load_store.Rn = rn; //MH instruction->info.load_store.Rn = rn; //MH
instruction->info.load_store.Rd = rt; //MH instruction->info.load_store.Rd = rt; //MH
instruction->info.load_store.offset_mode = 0; // immediate instruction->info.load_store.offset_mode = 0; // immediate
instruction->info.load_store.offset.offset = immed; instruction->info.load_store.offset.offset = immed;
return ERROR_OK; return ERROR_OK;
imm8: imm8:
immed = opcode & 0x00ff; immed = opcode & 0x00ff;
instruction->info.load_store.Rn = rn; //MH instruction->info.load_store.Rn = rn; //MH
instruction->info.load_store.Rd = rt; //MH instruction->info.load_store.Rd = rt; //MH
instruction->info.load_store.offset_mode = 0; // immediate instruction->info.load_store.offset_mode = 0; // immediate
instruction->info.load_store.offset.offset = immed; instruction->info.load_store.offset.offset = immed;
switch (opcode & 0x700) { switch (opcode & 0x700) {
case 0x600: case 0x600:
@ -3518,11 +3518,11 @@ imm8:
if (opcode & 0x100) { if (opcode & 0x100) {
if (opcode & 0x400) { /* pre-indexed */ if (opcode & 0x400) { /* pre-indexed */
p2 = "]!"; p2 = "]!";
instruction->info.load_store.index_mode = 1; // pre indexed instruction->info.load_store.index_mode = 1; // pre indexed
} else { /* post-indexed */ } else { /* post-indexed */
p1 = "]"; p1 = "]";
p2 = ""; p2 = "";
instruction->info.load_store.index_mode = 2; // post indexed instruction->info.load_store.index_mode = 2; // post indexed
} }
} }
@ -3684,11 +3684,11 @@ static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
switch (op1op2) { switch (op1op2) {
case 0: case 0:
mnemonic = "STREX"; mnemonic = "STREX";
instruction->type = ARM_STREX; instruction->type = ARM_STREX;
goto strex; goto strex;
case 1: case 1:
mnemonic = "LDREX"; mnemonic = "LDREX";
instruction->type = ARM_LDREX; instruction->type = ARM_LDREX;
goto ldrex; goto ldrex;
case 2: case 2:
case 6: case 6:
@ -3697,7 +3697,7 @@ static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
case 12: case 12:
case 14: case 14:
mnemonic = "STRD"; mnemonic = "STRD";
instruction->type = ARM_LDRD; instruction->type = ARM_LDRD;
goto immediate; goto immediate;
case 3: case 3:
case 7: case 7:
@ -3706,7 +3706,7 @@ static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
case 13: case 13:
case 15: case 15:
mnemonic = "LDRD"; mnemonic = "LDRD";
instruction->type = ARM_LDRD; instruction->type = ARM_LDRD;
if (rn == 15) if (rn == 15)
goto literal; goto literal;
else else
@ -3715,11 +3715,11 @@ static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
switch (op3) { switch (op3) {
case 4: case 4:
mnemonic = "STREXB"; mnemonic = "STREXB";
instruction->type = ARM_STREXB; instruction->type = ARM_STREXB;
break; break;
case 5: case 5:
mnemonic = "STREXH"; mnemonic = "STREXH";
instruction->type = ARM_STREXH; instruction->type = ARM_STREXH;
break; break;
default: default:
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
@ -3737,11 +3737,11 @@ static int t2ev_ldrex_strex(uint32_t opcode, uint32_t address,
return ERROR_OK; return ERROR_OK;
case 4: case 4:
mnemonic = "LDREXB"; mnemonic = "LDREXB";
instruction->type = ARM_LDREXB; instruction->type = ARM_LDREXB;
break; break;
case 5: case 5:
mnemonic = "LDREXH"; mnemonic = "LDREXH";
instruction->type = ARM_LDREXH; instruction->type = ARM_LDREXH;
break; break;
default: default:
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
@ -3756,10 +3756,10 @@ strex:
if (imm) { if (imm) {
sprintf(cp, "%s\tr%u, r%u, [r%u, #%u]\t; %#2.2x", sprintf(cp, "%s\tr%u, r%u, [r%u, #%u]\t; %#2.2x",
mnemonic, rd, rt, rn, imm, imm); mnemonic, rd, rt, rn, imm, imm);
} else { } else {
sprintf(cp, "%s\tr%u, r%u, [r%u]", sprintf(cp, "%s\tr%u, r%u, [r%u]",
mnemonic, rd, rt, rn); mnemonic, rd, rt, rn);
} }
return ERROR_OK; return ERROR_OK;
ldrex: ldrex:
@ -4093,7 +4093,7 @@ static int t2ev_load_word(uint32_t opcode, uint32_t address,
sprintf(cp, "LDR\tr%d, %#8.8" PRIx32, sprintf(cp, "LDR\tr%d, %#8.8" PRIx32,
(int) (opcode >> 12) & 0xf, (int) (opcode >> 12) & 0xf,
thumb_alignpc4(address) + immed); thumb_alignpc4(address) + immed);
//MH TODO pc relative //MH TODO pc relative
return ERROR_OK; return ERROR_OK;
} }
@ -4103,9 +4103,9 @@ static int t2ev_load_word(uint32_t opcode, uint32_t address,
(int) (opcode >> 12) & 0xf, (int) (opcode >> 12) & 0xf,
rn, immed, immed); rn, immed, immed);
instruction->info.load_store.Rn = rn; instruction->info.load_store.Rn = rn;
instruction->info.load_store.Rd = (int) (opcode >> 12) & 0xf; instruction->info.load_store.Rd = (int) (opcode >> 12) & 0xf;
instruction->info.load_store.offset.offset = immed; instruction->info.load_store.offset.offset = immed;
return ERROR_OK; return ERROR_OK;
} }
@ -4115,12 +4115,12 @@ static int t2ev_load_word(uint32_t opcode, uint32_t address,
rn, rn,
(int) (opcode >> 0) & 0xf, (int) (opcode >> 0) & 0xf,
(int) (opcode >> 4) & 0x3); (int) (opcode >> 4) & 0x3);
instruction->info.load_store.Rd = (int) (opcode >> 12) & 0xf; instruction->info.load_store.Rd = (int) (opcode >> 12) & 0xf;
instruction->info.load_store.Rn = rn; instruction->info.load_store.Rn = rn;
instruction->info.load_store.offset_mode = 1; instruction->info.load_store.offset_mode = 1;
instruction->info.load_store.offset.reg.Rm = (int) (opcode >> 0) & 0xf; instruction->info.load_store.offset.reg.Rm = (int) (opcode >> 0) & 0xf;
instruction->info.load_store.offset.reg.shift = 0; // LSL instruction->info.load_store.offset.reg.shift = 0; // LSL
instruction->info.load_store.offset.reg.shift_imm = (int) (opcode >> 4) & 0x3; instruction->info.load_store.offset.reg.shift_imm = (int) (opcode >> 4) & 0x3;
return ERROR_OK; return ERROR_OK;
} }
@ -4132,10 +4132,10 @@ static int t2ev_load_word(uint32_t opcode, uint32_t address,
(int) (opcode >> 12) & 0xf, (int) (opcode >> 12) & 0xf,
rn, immed, immed); rn, immed, immed);
instruction->info.load_store.Rn = rn; instruction->info.load_store.Rn = rn;
instruction->info.load_store.Rd = (int) (opcode >> 12) & 0xf; instruction->info.load_store.Rd = (int) (opcode >> 12) & 0xf;
instruction->info.load_store.offset.offset = immed; instruction->info.load_store.offset.offset = immed;
return ERROR_OK; return ERROR_OK;
} }
if (((opcode >> 8) & 0xf) == 0xc || (opcode & 0x0900) == 0x0900) { if (((opcode >> 8) & 0xf) == 0xc || (opcode & 0x0900) == 0x0900) {
@ -4150,11 +4150,11 @@ static int t2ev_load_word(uint32_t opcode, uint32_t address,
if (opcode & 0x100) { if (opcode & 0x100) {
if (opcode & 0x400) { /* pre-indexed */ if (opcode & 0x400) { /* pre-indexed */
p2 = "]!"; p2 = "]!";
instruction->info.load_store.index_mode = 1; instruction->info.load_store.index_mode = 1;
} else { /* post-indexed */ } else { /* post-indexed */
p1 = "]"; p1 = "]";
p2 = ""; p2 = "";
instruction->info.load_store.index_mode = 2; instruction->info.load_store.index_mode = 2;
} }
} }
@ -4164,10 +4164,10 @@ static int t2ev_load_word(uint32_t opcode, uint32_t address,
(opcode & 0x200) ? "" : "-", (opcode & 0x200) ? "" : "-",
immed, p2, immed); immed, p2, immed);
instruction->info.load_store.Rd = (int) (opcode >> 12) & 0xf; instruction->info.load_store.Rd = (int) (opcode >> 12) & 0xf;
instruction->info.load_store.Rn = rn; instruction->info.load_store.Rn = rn;
instruction->info.load_store.offset_mode = 0; instruction->info.load_store.offset_mode = 0;
instruction->info.load_store.offset.offset = immed; instruction->info.load_store.offset.offset = immed;
return ERROR_OK; return ERROR_OK;
} }
@ -4181,7 +4181,7 @@ static int t2ev_load_byte_hints(uint32_t opcode, uint32_t address,
int rt = (opcode >> 12) & 0xf; int rt = (opcode >> 12) & 0xf;
int op2 = (opcode >> 6) & 0x3f; int op2 = (opcode >> 6) & 0x3f;
unsigned immed; unsigned immed;
std::string p1 = "", p2 = "]"; std::string p1 = "", p2 = "]";
char *mnemonic; char *mnemonic;
switch ((opcode >> 23) & 0x3) { switch ((opcode >> 23) & 0x3) {
@ -4450,7 +4450,7 @@ int thumb2_opcode(uint32_t address, uint32_t opcode, struct arm_instruction *ins
case 0xe8000000: case 0xe8000000:
/* 32-bit instructions */ /* 32-bit instructions */
instruction->instruction_size = 4; instruction->instruction_size = 4;
instruction->opcode = opcode; instruction->opcode = opcode;
break; break;
default: default:
/* 16-bit: Thumb1 + IT + CBZ/CBNZ + ... */ /* 16-bit: Thumb1 + IT + CBZ/CBNZ + ... */

View File

@ -58,9 +58,9 @@ enum arm_instruction_type {
ARM_LDRH, ARM_LDRH,
ARM_LDRSB, ARM_LDRSB,
ARM_LDRSH, ARM_LDRSH,
ARM_LDREX, ARM_LDREX,
ARM_LDREXB, ARM_LDREXB,
ARM_LDREXH, ARM_LDREXH,
ARM_LDM, ARM_LDM,
ARM_STR, ARM_STR,
@ -69,9 +69,9 @@ enum arm_instruction_type {
ARM_STRBT, ARM_STRBT,
ARM_STRH, ARM_STRH,
ARM_STREX, ARM_STREX,
ARM_STREXB, ARM_STREXB,
ARM_STREXH, ARM_STREXH,
ARM_STM, ARM_STM,
/* Status register access instructions */ /* Status register access instructions */
@ -167,10 +167,10 @@ struct arm_load_store_instr {
} reg; } reg;
} offset; } offset;
uint32_t address; uint32_t address;
uint32_t value; uint32_t value;
uint8_t width; uint8_t width;
void evaluate(void); void evaluate(void);
}; };
struct arm_load_store_multiple_instr { struct arm_load_store_multiple_instr {
@ -196,21 +196,21 @@ struct arm_instruction {
struct arm_load_store_multiple_instr load_store_multiple; struct arm_load_store_multiple_instr load_store_multiple;
} info; } info;
bool isBranchInstruction(void) const { bool isBranchInstruction(void) const {
return (type == ARM_B) || (type == ARM_BL) || (type == ARM_BX) || (type == ARM_BLX); return (type == ARM_B) || (type == ARM_BL) || (type == ARM_BX) || (type == ARM_BLX);
}; };
bool isLoadInstruction(void) const { bool isLoadInstruction(void) const {
return (type >= ARM_LDR) && (type <= ARM_LDM); return (type >= ARM_LDR) && (type <= ARM_LDM);
} }
bool isStoreInstruction(void) const { bool isStoreInstruction(void) const {
return (type >= ARM_STR) && (type <= ARM_STM); return (type >= ARM_STR) && (type <= ARM_STM);
} }
bool isMemoryAccess(void) const { bool isMemoryAccess(void) const {
return isLoadInstruction() || isStoreInstruction(); return isLoadInstruction() || isStoreInstruction();
}; };
}; };
int arm_evaluate_opcode(uint32_t opcode, uint32_t address, int arm_evaluate_opcode(uint32_t opcode, uint32_t address,

View File

@ -4,113 +4,112 @@
using namespace std; using namespace std;
namespace fail { namespace fail {
static ArmMemoryInstructionAnalyzer anal; static ArmMemoryInstructionAnalyzer anal;
MemoryInstructionAnalyzer & meminstruction = anal; MemoryInstructionAnalyzer& meminstruction = anal;
address_t ArmMemoryInstructionAnalyzer::findPrevious(address_t address){ address_t ArmMemoryInstructionAnalyzer::findPrevious(address_t address){
if(m_dis.hasInstructionAt(address)) { if (m_dis.hasInstructionAt(address)) {
return address; return address;
} else if (m_dis.hasInstructionAt(address - 2)) { } else if (m_dis.hasInstructionAt(address - 2)) {
return address - 2; return address - 2;
} else { } else {
return ADDR_INV; return ADDR_INV;
} }
} }
void ArmMemoryInstructionAnalyzer::evaluate(arm_instruction & inst, MemoryInstruction& result){ void ArmMemoryInstructionAnalyzer::evaluate(arm_instruction & inst, MemoryInstruction& result){
cout << "Memory Access: " << inst.text << " - Size: " << inst.instruction_size << " Type " << inst.type << endl; cout << "Memory Access: " << inst.text << " - Size: " << inst.instruction_size << " Type " << inst.type << endl;
inst.info.load_store.evaluate(); inst.info.load_store.evaluate();
result.setValue(inst.info.load_store.value); result.setValue(inst.info.load_store.value);
result.setAddress(inst.info.load_store.address); result.setAddress(inst.info.load_store.address);
result.setWidth(4); // TODO; result.setWidth(4); // TODO;
result.setWriteAccess(inst.isStoreInstruction()); result.setWriteAccess(inst.isStoreInstruction());
} }
// The Cortex M3 Lauterbach is a pain in the ass, as a Memory Watchpoint does not stop // The Cortex M3 Lauterbach is a pain in the ass, as a Memory Watchpoint does not stop
// at the accessing instruction, but 1 or 2 instructions later. // at the accessing instruction, but 1 or 2 instructions later.
bool ArmMemoryInstructionAnalyzer::eval_cm3(address_t address, MemoryInstruction& result){ bool ArmMemoryInstructionAnalyzer::eval_cm3(address_t address, MemoryInstruction& result){
arm_instruction inst; arm_instruction inst;
uint32_t opcode =0; uint32_t opcode =0;
address = findPrevious(address); address = findPrevious(address);
opcode = m_dis.disassemble(address).opcode; opcode = m_dis.disassemble(address).opcode;
// OpenOCDs thumb2_opcode evaluation is not complete yet. :( // OpenOCDs thumb2_opcode evaluation is not complete yet. :(
thumb2_opcode(address, opcode, &inst); thumb2_opcode(address, opcode, &inst);
if(inst.isMemoryAccess()){ if (inst.isMemoryAccess()) {
evaluate(inst, result); evaluate(inst, result);
return true; return true;
}else{ } else {
return false; return false;
} }
#if 0 #if 0
arm_instruction inst; arm_instruction inst;
uint32_t opcode =0; uint32_t opcode =0;
address = findPrevious(address); // Cortex M3: memory access is at the previous instruction address = findPrevious(address); // Cortex M3: memory access is at the previous instruction
opcode = m_dis.disassemble(address).opcode; opcode = m_dis.disassemble(address).opcode;
// OpenOCDs thumb2_opcode evaluation is not complete yet. :( // OpenOCDs thumb2_opcode evaluation is not complete yet. :(
thumb2_opcode(address, opcode, &inst); thumb2_opcode(address, opcode, &inst);
if(inst.isMemoryAccess()){ if (inst.isMemoryAccess()) {
evaluate(inst, result); evaluate(inst, result);
return true; return true;
} else if(inst.isBranchInstruction()){ } else if (inst.isBranchInstruction()) {
// The memory access took place within the function previously branched // The memory access took place within the function previously branched
int regop = inst.info.b_bl_bx_blx.reg_operand; int regop = inst.info.b_bl_bx_blx.reg_operand;
uint32_t addr = inst.info.b_bl_bx_blx.target_address; uint32_t addr = inst.info.b_bl_bx_blx.target_address;
//cout << " Reg:" << hex << regop << " address " << hex << addr << endl; //cout << " Reg:" << hex << regop << " address " << hex << addr << endl;
// Lets look into this function // Lets look into this function
if( regop == -1 ){ if ( regop == -1 ) {
// address should be set.. // address should be set..
const ElfSymbol & sym = m_elf.getSymbol(addr|1); // | 1 to set first bit -> thumbmode const ElfSymbol & sym = m_elf.getSymbol(addr|1); // | 1 to set first bit -> thumbmode
addr += sym.getSize(); // Go to end of function. addr += sym.getSize(); // Go to end of function.
// THIS IS DANGEROUS: The memory access can be anywhere within this function, one instruction before a ret. // THIS IS DANGEROUS: The memory access can be anywhere within this function, one instruction before a ret.
// OR, the memory access itself can result in leaving the function :e.g., ldr pc, [r3] // OR, the memory access itself can result in leaving the function :e.g., ldr pc, [r3]
// We cannot be sure :( Here we assume the first memory access from the back. // We cannot be sure :( Here we assume the first memory access from the back.
do { // go backwards until there is a memory instruction. do { // go backwards until there is a memory instruction.
addr = findPrevious(addr); // find previous addr = findPrevious(addr); // find previous
thumb2_opcode(addr, m_dis.disassemble(addr).opcode, &inst); thumb2_opcode(addr, m_dis.disassemble(addr).opcode, &inst);
} while( !inst.isMemoryAccess() ); } while ( !inst.isMemoryAccess() );
evaluate(inst, result); evaluate(inst, result);
return true; return true;
} }
} else { } else {
// There was a memory access before, but the previous instruction // There was a memory access before, but the previous instruction
// is neither an access nor a branch. // is neither an access nor a branch.
// This can happen if we came here from anywhere, e.g. by ldr pc, [r4] // This can happen if we came here from anywhere, e.g. by ldr pc, [r4]
} }
return false; return false;
#endif #endif
} }
bool ArmMemoryInstructionAnalyzer::eval_ca9(address_t address, MemoryInstruction& result){ bool ArmMemoryInstructionAnalyzer::eval_ca9(address_t address, MemoryInstruction& result){
arm_instruction inst; arm_instruction inst;
uint32_t opcode = m_dis.disassemble(address).opcode; uint32_t opcode = m_dis.disassemble(address).opcode;
arm_evaluate_opcode(address, opcode, &inst); arm_evaluate_opcode(address, opcode, &inst);
if( inst.isMemoryAccess() ){ if ( inst.isMemoryAccess() ) {
evaluate(inst, result); evaluate(inst, result);
return true; return true;
} }
return false; return false;
} }
#define CORTEXM3 #define CORTEXM3
bool ArmMemoryInstructionAnalyzer::eval(address_t address, MemoryInstruction & result){ bool ArmMemoryInstructionAnalyzer::eval(address_t address, MemoryInstruction & result){
#ifdef CORTEXM3 #ifdef CORTEXM3
#warning "Memory Accesses cannot be evaluated completely!" #warning "Memory Accesses cannot be evaluated completely!"
return eval_cm3(address, result); return eval_cm3(address, result);
#elif defined CORTEXA9 #elif defined CORTEXA9
return eval_ca9(address, result); return eval_ca9(address, result);
#else #else
#warning "Memory Accesses are not evaluated!" #warning "Memory Accesses are not evaluated!"
return false; return false;
#endif #endif
} }
}; };

View File

@ -8,27 +8,24 @@
namespace fail { namespace fail {
class ArmMemoryInstructionAnalyzer : public MemoryInstructionAnalyzer { class ArmMemoryInstructionAnalyzer : public MemoryInstructionAnalyzer {
fail::ElfReader m_elf; fail::ElfReader m_elf;
fail::Disassembler m_dis; fail::Disassembler m_dis;
address_t findPrevious(address_t addr); address_t findPrevious(address_t addr);
void evaluate(arm_instruction & inst, MemoryInstruction& result); void evaluate(arm_instruction & inst, MemoryInstruction& result);
bool eval_ca9(address_t address, MemoryInstruction& result); bool eval_ca9(address_t address, MemoryInstruction& result);
bool eval_cm3(address_t address, MemoryInstruction& result); bool eval_cm3(address_t address, MemoryInstruction& result);
public: public:
ArmMemoryInstructionAnalyzer() { ArmMemoryInstructionAnalyzer() {
m_dis.init(); m_dis.init();
}; };
bool eval(address_t opcode, MemoryInstruction & result); bool eval(address_t opcode, MemoryInstruction & result);
};
};
} //end of namespace fail } //end of namespace fail
#endif // __ARMMEMORYINSTRUCITON_HPP__ #endif // __ARMMEMORYINSTRUCITON_HPP__

View File

@ -12,19 +12,19 @@ regdata_t BochsCPU::getRegisterContent(const Register* reg) const
if (reg->getId() == RID_FLAGS) { // EFLAGS register? if (reg->getId() == RID_FLAGS) { // EFLAGS register?
return static_cast<regdata_t>(BX_CPU(id)->read_eflags()); return static_cast<regdata_t>(BX_CPU(id)->read_eflags());
} }
#ifdef SIM_SUPPORT_64 #ifdef SIM_SUPPORT_64
if (reg->getId() == RID_PC) // program counter? if (reg->getId() == RID_PC) // program counter?
return static_cast<regdata_t>(BX_CPU(id)->gen_reg[BX_64BIT_REG_RIP].rrx); return static_cast<regdata_t>(BX_CPU(id)->gen_reg[BX_64BIT_REG_RIP].rrx);
else // 64 bit general purpose registers else // 64 bit general purpose registers
return static_cast<regdata_t>(BX_CPU(id)->gen_reg[reg->getId()].rrx); return static_cast<regdata_t>(BX_CPU(id)->gen_reg[reg->getId()].rrx);
#else // 32 bit mode #else // 32 bit mode
if (reg->getId() == RID_PC) if (reg->getId() == RID_PC)
return static_cast<regdata_t>(BX_CPU(id)->gen_reg[BX_32BIT_REG_EIP].dword.erx); return static_cast<regdata_t>(BX_CPU(id)->gen_reg[BX_32BIT_REG_EIP].dword.erx);
else // 32 bit general purpose registers else // 32 bit general purpose registers
return static_cast<regdata_t>(BX_CPU(id)->gen_reg[reg->getId()].dword.erx); return static_cast<regdata_t>(BX_CPU(id)->gen_reg[reg->getId()].dword.erx);
#endif // SIM_SUPPORT_64 #endif // SIM_SUPPORT_64
} }
void BochsCPU::setRegisterContent(const Register* reg, regdata_t value) void BochsCPU::setRegisterContent(const Register* reg, regdata_t value)
@ -46,17 +46,17 @@ void BochsCPU::setRegisterContent(const Register* reg, regdata_t value)
} }
regdata_t* pData; regdata_t* pData;
#ifdef SIM_SUPPORT_64 #ifdef SIM_SUPPORT_64
if (reg->getId() == RID_PC) // program counter? if (reg->getId() == RID_PC) // program counter?
pData = &(BX_CPU(id)->gen_reg[BX_64BIT_REG_RIP].rrx); pData = &(BX_CPU(id)->gen_reg[BX_64BIT_REG_RIP].rrx);
else // 64 bit general purpose registers else // 64 bit general purpose registers
pData = &(BX_CPU(id)->gen_reg[reg->getId()].rrx); pData = &(BX_CPU(id)->gen_reg[reg->getId()].rrx);
#else // 32 bit mode #else // 32 bit mode
if (reg->getId() == RID_PC) if (reg->getId() == RID_PC)
pData = &(BX_CPU(id)->gen_reg[BX_32BIT_REG_EIP].dword.erx); pData = &(BX_CPU(id)->gen_reg[BX_32BIT_REG_EIP].dword.erx);
else // 32 bit general purpose registers else // 32 bit general purpose registers
pData = &(BX_CPU(id)->gen_reg[reg->getId()].dword.erx); pData = &(BX_CPU(id)->gen_reg[reg->getId()].dword.erx);
#endif // SIM_SUPPORT_64 #endif // SIM_SUPPORT_64
*pData = value; *pData = value;
} }

View File

@ -1,5 +1,5 @@
#ifndef __BOCHS_CPU_HPP__ #ifndef __BOCHS_CPU_HPP__
#define __BOCHS_CPU_HPP__ #define __BOCHS_CPU_HPP__
#include "../x86/X86Architecture.hpp" #include "../x86/X86Architecture.hpp"
#include "../x86/X86CPUState.hpp" #include "../x86/X86CPUState.hpp"
@ -11,12 +11,12 @@ namespace fail {
/** /**
* \class BochsCPU * \class BochsCPU
* *
* \c BochsCPU is the concrete CPU implementation for the Bochs x86 simulator. It * \c BochsCPU is the concrete CPU implementation for the Bochs x86 simulator. It
* implements the CPU interfaces \c X86Architecture and \c X86CPUState. * implements the CPU interfaces \c X86Architecture and \c X86CPUState.
* \c X86Architecture refers to architectural information (e.g. register \a count) * \c X86Architecture refers to architectural information (e.g. register \a count)
* while \c X86CPUState encapsulates the CPU state (e.g. register \a content). * while \c X86CPUState encapsulates the CPU state (e.g. register \a content).
* *
*/ */
class BochsCPU : public X86Architecture, public X86CPUState { class BochsCPU : public X86Architecture, public X86CPUState {
private: private:
@ -29,7 +29,7 @@ public:
BochsCPU(unsigned int id) : m_Id(id) { } BochsCPU(unsigned int id) : m_Id(id) { }
/** /**
* Virtual Destructor is required. * Virtual Destructor is required.
*/ */
virtual ~BochsCPU() { } virtual ~BochsCPU() { }
/** /**
* Retrieves the content of the register \c reg. * Retrieves the content of the register \c reg.

View File

@ -5,7 +5,7 @@
*/ */
#ifndef __BOCHS_CONFIG_HPP__ #ifndef __BOCHS_CONFIG_HPP__
#define __BOCHS_CONFIG_HPP__ #define __BOCHS_CONFIG_HPP__
#include "bochs.h" #include "bochs.h"
#include "config.h" #include "config.h"
@ -15,15 +15,15 @@ namespace fail {
typedef bx_address guest_address_t; //!< the guest memory address type typedef bx_address guest_address_t; //!< the guest memory address type
typedef Bit8u* host_address_t; //!< the host memory address type typedef Bit8u* host_address_t; //!< the host memory address type
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
typedef Bit64u register_data_t; //!< register data type (64 bit) typedef Bit64u register_data_t; //!< register data type (64 bit)
#else #else
typedef Bit32u register_data_t; //!< register data type (32 bit) typedef Bit32u register_data_t; //!< register data type (32 bit)
#endif #endif
typedef int timer_t; //!< type of timer IDs typedef int timer_t; //!< type of timer IDs
// 'Publish' 64 bit ability (if enabled in Bochs): // 'Publish' 64 bit ability (if enabled in Bochs):
#if BX_SUPPORT_X86_64 #if BX_SUPPORT_X86_64
#define SIM_SUPPORT_64 #define SIM_SUPPORT_64
#endif #endif
} // end-of-namespace: fail } // end-of-namespace: fail

View File

@ -80,14 +80,14 @@ void BochsController::onIOPort(ConcreteCPU* cpu, unsigned char data, unsigned po
bool BochsController::save(const std::string& path) bool BochsController::save(const std::string& path)
{ {
int stat; int stat;
stat = mkdir(path.c_str(), 0777); stat = mkdir(path.c_str(), 0777);
if (!(stat == 0 || errno == EEXIST)) { if (!(stat == 0 || errno == EEXIST)) {
return false; return false;
// std::cout << "[FAIL] Can not create target-directory to save!" << std::endl; // std::cout << "[FAIL] Can not create target-directory to save!" << std::endl;
// TODO: (Non-)Verbose-Mode? Log-level? Maybe better: use return value to indicate failure? // TODO: (Non-)Verbose-Mode? Log-level? Maybe better: use return value to indicate failure?
} }
save_bochs_request = true; save_bochs_request = true;
BX_CPU(0)->async_event |= 1; BX_CPU(0)->async_event |= 1;
sr_path = path; sr_path = path;
@ -164,12 +164,12 @@ const std::string& BochsController::getMnemonic() const
ConcreteCPU& BochsController::detectCPU(BX_CPU_C* pCPU) const ConcreteCPU& BochsController::detectCPU(BX_CPU_C* pCPU) const
{ {
unsigned i = 0; unsigned i = 0;
#if BX_SUPPORT_SMP #if BX_SUPPORT_SMP
for (; i < BX_SMP_PROCESSORS; i++) { for (; i < BX_SMP_PROCESSORS; i++) {
if (BX_CPU_C[i] == pCPU) // cmp this ptr with all possible CPU objects if (BX_CPU_C[i] == pCPU) // cmp this ptr with all possible CPU objects
break; // index "i" found! -> stop! break; // index "i" found! -> stop!
} }
#endif #endif
return getCPU(i); return getCPU(i);
} }

View File

@ -1,5 +1,5 @@
#ifndef __BOCHS_CONTROLLER_HPP__ #ifndef __BOCHS_CONTROLLER_HPP__
#define __BOCHS_CONTROLLER_HPP__ #define __BOCHS_CONTROLLER_HPP__
#include <string> #include <string>
#include <cassert> #include <cassert>
@ -25,7 +25,7 @@ class ExperimentFlow;
/** /**
* \class BochsController * \class BochsController
* Bochs-specific implementation of a SimulatorController. * Bochs-specific implementation of a SimulatorController.
* *
* @note The instruction (IP) pointer modification handler (onBreakpoint()) * @note The instruction (IP) pointer modification handler (onBreakpoint())
* is called (from the Breakpoints aspect) *every* time the Bochs-internal IP * is called (from the Breakpoints aspect) *every* time the Bochs-internal IP
* changes. The handler itself evaluates if a breakpoint event needs to be * changes. The handler itself evaluates if a breakpoint event needs to be
@ -65,7 +65,7 @@ public:
* object within the ListenerManager and fires such an event by calling * object within the ListenerManager and fires such an event by calling
* \c triggerActiveListeners(). * \c triggerActiveListeners().
* @param thisPtr a pointer to the TimerListener-object triggered * @param thisPtr a pointer to the TimerListener-object triggered
* *
* FIXME: Due to Bochs internal timer and ips-configuration related stuff, * FIXME: Due to Bochs internal timer and ips-configuration related stuff,
* the simulator sometimes panics with "keyboard error:21" (see line * the simulator sometimes panics with "keyboard error:21" (see line
* 1777 in bios/rombios.c, function keyboard_init()) if a TimerListener * 1777 in bios/rombios.c, function keyboard_init()) if a TimerListener
@ -112,7 +112,7 @@ public:
*/ */
void fireInterrupt(unsigned irq); void fireInterrupt(unsigned irq);
/** /**
* Fire done: Callback from Simulator * Fire done: Callback from Simulator
*/ */
void fireInterruptDone(); void fireInterruptDone();
virtual simtime_t getTimerTicks() { return bx_pc_system.time_ticks(); } virtual simtime_t getTimerTicks() { return bx_pc_system.time_ticks(); }

View File

@ -1,5 +1,5 @@
#ifndef __BOCHS_HELPERS_HPP__ #ifndef __BOCHS_HELPERS_HPP__
#define __BOCHS_HELPERS_HPP__ #define __BOCHS_HELPERS_HPP__
#include "cpu/cpu.h" #include "cpu/cpu.h"

View File

@ -1,5 +1,5 @@
#ifndef __BOCHS_LISTENER_HPP__ #ifndef __BOCHS_LISTENER_HPP__
#define __BOCHS_LISTENER_HPP__ #define __BOCHS_LISTENER_HPP__
namespace fail { namespace fail {

View File

@ -1,5 +1,5 @@
#ifndef __BOCHS_MEMORY_HPP__ #ifndef __BOCHS_MEMORY_HPP__
#define __BOCHS_MEMORY_HPP__ #define __BOCHS_MEMORY_HPP__
#include "../Memory.hpp" #include "../Memory.hpp"

View File

@ -1,5 +1,5 @@
#ifndef __FAIL_BOCHS_GLOBALS_HPP__ #ifndef __FAIL_BOCHS_GLOBALS_HPP__
#define __FAIL_BOCHS_GLOBALS_HPP__ #define __FAIL_BOCHS_GLOBALS_HPP__
#include <string> #include <string>
@ -8,9 +8,9 @@
namespace fail { namespace fail {
#ifdef DANCEOS_RESTORE #ifdef DANCEOS_RESTORE
extern bx_bool restore_bochs_request; extern bx_bool restore_bochs_request;
extern bx_bool save_bochs_request; extern bx_bool save_bochs_request;
extern std::string sr_path; extern std::string sr_path;
#endif #endif
extern bx_bool reboot_bochs_request; extern bx_bool reboot_bochs_request;

View File

@ -1,5 +1,5 @@
#ifndef __GEM5_ARM_CPU_HPP__ #ifndef __GEM5_ARM_CPU_HPP__
#define __GEM5_ARM_CPU_HPP__ #define __GEM5_ARM_CPU_HPP__
#include "../arm/ArmArchitecture.hpp" #include "../arm/ArmArchitecture.hpp"
#include "../arm/ArmCPUState.hpp" #include "../arm/ArmCPUState.hpp"

View File

@ -5,7 +5,7 @@
*/ */
#ifndef __GEM5_CONFIG_HPP__ #ifndef __GEM5_CONFIG_HPP__
#define __GEM5_CONFIG_HPP__ #define __GEM5_CONFIG_HPP__
#include <stdint.h> #include <stdint.h>

View File

@ -1,5 +1,5 @@
#ifndef __GEM5_CONTROLLER_HPP__ #ifndef __GEM5_CONTROLLER_HPP__
#define __GEM5_CONTROLLER_HPP__ #define __GEM5_CONTROLLER_HPP__
#include <string> #include <string>
@ -42,7 +42,7 @@ public:
virtual simtime_t getTimerTicksPerSecond(); virtual simtime_t getTimerTicksPerSecond();
#if defined(CONFIG_EVENT_BREAKPOINTS) ||\ #if defined(CONFIG_EVENT_BREAKPOINTS) ||\
defined(CONFIG_EVENT_BREAKPOINTS_RANGE) defined(CONFIG_EVENT_BREAKPOINTS_RANGE)
void setMnemonic(const std::string& mn) { m_Mnemonic = mn; } void setMnemonic(const std::string& mn) { m_Mnemonic = mn; }
const std::string& getMnemonic() const { return m_Mnemonic; } const std::string& getMnemonic() const { return m_Mnemonic; }
#endif #endif
}; };

View File

@ -1,5 +1,5 @@
#ifndef __GEM5_MEMORY_HPP__ #ifndef __GEM5_MEMORY_HPP__
#define __GEM5_MEMORY_HPP__ #define __GEM5_MEMORY_HPP__
#include "../Memory.hpp" #include "../Memory.hpp"
#include "Gem5Wrapper.hpp" #include "Gem5Wrapper.hpp"

View File

@ -1,5 +1,5 @@
#ifndef __GEM5_WRAPPER_HPP__ #ifndef __GEM5_WRAPPER_HPP__
#define __GEM5_WRAPPER_HPP__ #define __GEM5_WRAPPER_HPP__
#include "../Register.hpp" #include "../Register.hpp"
#include "../SALConfig.hpp" #include "../SALConfig.hpp"

View File

@ -10,7 +10,7 @@ ResultSet& PerfVectorBreakpoints::gather(BPEvent* pData)
static ResultSet res; static ResultSet res;
res.clear(); // FIXME: This should not free the memory of the underlying std::vector. res.clear(); // FIXME: This should not free the memory of the underlying std::vector.
// Search for all indices of matching listener objects: // Search for all indices of matching listener objects:
for(std::vector<index_t>::iterator it = m_BufList.begin(); it != m_BufList.end(); ++it) { for (std::vector<index_t>::iterator it = m_BufList.begin(); it != m_BufList.end(); ++it) {
BPListener* pLi = static_cast<BPListener*>(simulator.dereference(*it)); BPListener* pLi = static_cast<BPListener*>(simulator.dereference(*it));
if (pLi->isMatching(pData)) { if (pLi->isMatching(pData)) {
// Update trigger IPtr: // Update trigger IPtr:

View File

@ -1,9 +1,9 @@
#ifndef __BREAKPOINT_BUFFER_HPP__ #ifndef __BREAKPOINT_BUFFER_HPP__
#define __BREAKPOINT_BUFFER_HPP__ #define __BREAKPOINT_BUFFER_HPP__
#include "BufferInterface.hpp" #include "BufferInterface.hpp"
// TODOs: // TODOs:
// - Make these implementations even faster (see below: continue PerfVecSortedSingleBP). // - Make these implementations even faster (see below: continue PerfVecSortedSingleBP).
namespace fail { namespace fail {
@ -20,7 +20,7 @@ public:
/** /**
* \class PerfVecSortedSingleBP * \class PerfVecSortedSingleBP
* *
* This class implements a faster mechanism to store BPSingleListener * This class implements a faster mechanism to store BPSingleListener
* based on binary search on their corresponding instruction pointer. * based on binary search on their corresponding instruction pointer.
*/ */
@ -52,7 +52,7 @@ public:
// } // }
} }
} }
static bool CompareInstrPtr(index_t arg1, index_t arg2, void* pStuff) static bool CompareInstrPtr(index_t arg1, index_t arg2, void* pStuff)
{ {
SimulatorController* pSim = static_cast<SimulatorController*>(pStuff); SimulatorController* pSim = static_cast<SimulatorController*>(pStuff);
@ -80,9 +80,9 @@ public:
while (first <= last) { while (first <= last) {
int mid = (first + last) / 2; // compute mid point. int mid = (first + last) / 2; // compute mid point.
if (VAL(key) > VAL(vec[mid])) if (VAL(key) > VAL(vec[mid]))
first = mid + 1; // repeat search in top half. first = mid + 1; // repeat search in top half.
else if (VAL(key) < VAL(vec[mid])) else if (VAL(key) < VAL(vec[mid]))
last = mid - 1; // repeat search in bottom half. last = mid - 1; // repeat search in bottom half.
else else
return mid; // found it. return position return mid; // found it. return position
@ -100,7 +100,7 @@ public:
// TODO: Improve this by using binary search, too! // TODO: Improve this by using binary search, too!
ResultSet res; ResultSet res;
// Search for all indices of matching listener objects: // Search for all indices of matching listener objects:
for(std::vector<index_t>::iterator it = m_BufList.begin(); it != m_BufList.end(); ++it) { for (std::vector<index_t>::iterator it = m_BufList.begin(); it != m_BufList.end(); ++it) {
BPListener* pLi = static_cast<BPListener*>(simulator.dereference(*it)); BPListener* pLi = static_cast<BPListener*>(simulator.dereference(*it));
if (pLi->isMatching(pData)) { if (pLi->isMatching(pData)) {
// Update trigger IPtr: // Update trigger IPtr:

View File

@ -1,5 +1,5 @@
#ifndef __BUFFER_INTERFACE_HPP__ #ifndef __BUFFER_INTERFACE_HPP__
#define __BUFFER_INTERFACE_HPP__ #define __BUFFER_INTERFACE_HPP__
#include <cstddef> #include <cstddef>
#include <vector> #include <vector>
@ -58,7 +58,7 @@ public:
/** /**
* \class DefPerfVector * \class DefPerfVector
* *
* Default \c std::vector based performance implementation (abstract) * Default \c std::vector based performance implementation (abstract)
*/ */
template<class T> template<class T>

View File

@ -11,7 +11,7 @@ ResultSet& PerfVectorWatchpoints::gather(MemAccessEvent* pData)
static ResultSet res; static ResultSet res;
res.clear(); // FIXME: This should not free the memory of the underlying std::vector. res.clear(); // FIXME: This should not free the memory of the underlying std::vector.
// Search for all indices of matching listener objects: // Search for all indices of matching listener objects:
for(std::vector<index_t>::iterator it = m_BufList.begin(); it != m_BufList.end(); ++it) { for (std::vector<index_t>::iterator it = m_BufList.begin(); it != m_BufList.end(); ++it) {
MemAccessListener* pmal = static_cast<MemAccessListener*>(simulator.dereference(*it)); MemAccessListener* pmal = static_cast<MemAccessListener*>(simulator.dereference(*it));
if (pmal->isMatching(pData)) { if (pmal->isMatching(pData)) {
// Update trigger data: // Update trigger data:

View File

@ -1,5 +1,5 @@
#ifndef __WATCHPOINT_BUFFER_HPP__ #ifndef __WATCHPOINT_BUFFER_HPP__
#define __WATCHPOINT_BUFFER_HPP__ #define __WATCHPOINT_BUFFER_HPP__
#include "BufferInterface.hpp" #include "BufferInterface.hpp"

View File

@ -5,7 +5,7 @@
*/ */
#ifndef __QEMU_CONFIG_HPP__ #ifndef __QEMU_CONFIG_HPP__
#define __QEMU_CONFIG_HPP__ #define __QEMU_CONFIG_HPP__
// FIXME: qemu/targphys.h defines address types (but relies on a global preprocessor macro) // FIXME: qemu/targphys.h defines address types (but relies on a global preprocessor macro)

View File

@ -1,5 +1,5 @@
#ifndef __QEMU_CONTROLLER_HPP__ #ifndef __QEMU_CONTROLLER_HPP__
#define __QEMU_CONTROLLER_HPP__ #define __QEMU_CONTROLLER_HPP__
#include <string> #include <string>
#include <cassert> #include <cassert>

View File

@ -1,5 +1,5 @@
#ifndef __QEMU_MEMORY_HPP__ #ifndef __QEMU_MEMORY_HPP__
#define __QEMU_MEMORY_HPP__ #define __QEMU_MEMORY_HPP__
#include "../Memory.hpp" #include "../Memory.hpp"

View File

@ -1,5 +1,5 @@
#ifndef __QEMU_REGISTER_HPP__ #ifndef __QEMU_REGISTER_HPP__
#define __QEMU_REGISTER_HPP__ #define __QEMU_REGISTER_HPP__
#include "../Register.hpp" #include "../Register.hpp"

View File

@ -8,50 +8,50 @@ static const uint64_t lower = 0x00000000ffffffff;
regdata_t T32ArmCPU::getRegisterContent(const Register* reg) const regdata_t T32ArmCPU::getRegisterContent(const Register* reg) const
{ {
// T32_ReadRegister wants a mask of bits representig the registers to read: // T32_ReadRegister wants a mask of bits representig the registers to read:
// e.g., reading R1 and R4 and R63 // e.g., reading R1 and R4 and R63
// mask1 // mask1
// 0000 0000 0000 0000 0001 0010 -> R1/R4 // 0000 0000 0000 0000 0001 0010 -> R1/R4
// mask2 // mask2
// 1000 0000 0000 0000 0000 0000 -> R63 // 1000 0000 0000 0000 0000 0000 -> R63
uint64_t mask = (1 << reg->getIndex()); uint64_t mask = (1 << reg->getIndex());
if(mask){ if (mask) {
if( T32_ReadRegister(static_cast<dword>(mask & lower ), static_cast<dword>(mask >> 32), m_regbuffer) == 0 ){ if ( T32_ReadRegister(static_cast<dword>(mask & lower ), static_cast<dword>(mask >> 32), m_regbuffer) == 0 ) {
// No error, return value. // No error, return value.
return m_regbuffer[reg->getIndex()]; return m_regbuffer[reg->getIndex()];
} else { } else {
/// TODO Error handling! /// TODO Error handling!
std::cout << "could not read register :(" << std::endl; std::cout << "could not read register :(" << std::endl;
} }
} }
return 0; // we should not come here. return 0; // we should not come here.
} }
void T32ArmCPU::setRegisterContent(const Register* reg, regdata_t value) void T32ArmCPU::setRegisterContent(const Register* reg, regdata_t value)
{ {
uint64_t mask = (1 << reg->getIndex()); uint64_t mask = (1 << reg->getIndex());
// set value to be set by T32: // set value to be set by T32:
m_regbuffer[reg->getIndex()] = value; m_regbuffer[reg->getIndex()] = value;
if(mask){ if (mask) {
if( T32_WriteRegister(static_cast<dword>(mask & lower), static_cast<dword>(mask >> 32), m_regbuffer) == 0 ){ if ( T32_WriteRegister(static_cast<dword>(mask & lower), static_cast<dword>(mask >> 32), m_regbuffer) == 0 ) {
// No error, return value. // No error, return value.
return; return;
} else { } else {
/// TODO Error handling! /// TODO Error handling!
std::cout << "could not write register :(" << std::endl; std::cout << "could not write register :(" << std::endl;
} }
} }
} }
address_t T32ArmCPU::getInstructionPointer() const address_t T32ArmCPU::getInstructionPointer() const
{ {
// TODO: programpointer is only valid when Emulation is stopped! -> T32_GetState) // TODO: programpointer is only valid when Emulation is stopped! -> T32_GetState)
address_t programpointer; address_t programpointer;
T32_ReadPP( &programpointer ); T32_ReadPP( &programpointer );
return programpointer; return programpointer;
} }
} // end-of-namespace: fail } // end-of-namespace: fail

View File

@ -1,5 +1,5 @@
#ifndef __T32_ARM_CPU_HPP__ #ifndef __T32_ARM_CPU_HPP__
#define __T32_ARM_CPU_HPP__ #define __T32_ARM_CPU_HPP__
#include "../arm/ArmArchitecture.hpp" #include "../arm/ArmArchitecture.hpp"
#include "../arm/ArmCPUState.hpp" #include "../arm/ArmCPUState.hpp"
@ -39,7 +39,7 @@ public:
/** /**
* Retrieves the current instruction pointer (IP aka program counter, PC for short) * Retrieves the current instruction pointer (IP aka program counter, PC for short)
* for the current CPU \c this. * for the current CPU \c this.
* @return the current instruction ptr address * @return the current instruction ptr address
*/ */
address_t getInstructionPointer() const; address_t getInstructionPointer() const;
@ -63,8 +63,8 @@ public:
unsigned int getId() const { return m_Id; } unsigned int getId() const { return m_Id; }
private: private:
unsigned int m_Id; //!< the unique ID of this CPU unsigned int m_Id; //!< the unique ID of this CPU
mutable dword m_regbuffer[64]; //!< internal buffer for reading/writing registers, wow mutable really makes sense sometimes. mutable dword m_regbuffer[64]; //!< internal buffer for reading/writing registers, wow mutable really makes sense sometimes.
// char* cpuname? OMAP4430APP1 ?? // char* cpuname? OMAP4430APP1 ??
}; };

View File

@ -6,35 +6,36 @@
#define __T32_CONSTANTS_HPP__ #define __T32_CONSTANTS_HPP__
namespace fail { namespace fail {
namespace T32 { namespace T32 {
//!< Breakpoint configuration
struct BP { //!< Breakpoint configuration
enum { struct BP {
EXECUTION = 1<<0, enum {
HLL_STEP = 1<<1, EXECUTION = 1<<0,
SPOT = 1<<2, HLL_STEP = 1<<1,
READ = 1<<3, SPOT = 1<<2,
WRITE = 1<<4, READ = 1<<3,
ALPHA = 1<<5, WRITE = 1<<4,
BETA = 1<<6, ALPHA = 1<<5,
CHARLY = 1<<7, BETA = 1<<6,
CLEAR = 1<<8, CHARLY = 1<<7,
}; CLEAR = 1<<8,
}; // struct BP };
}; // struct BP
//!< Memory access variants //!< Memory access variants
struct MEMACCESS { struct MEMACCESS {
enum { enum {
DATA = 0, DATA = 0,
PROGRAM = 1, PROGRAM = 1,
AD = 12, AD = 12,
AP = 13, AP = 13,
USR = 15, USR = 15,
}; };
}; // struct MEMACCESS }; // struct MEMACCESS
}; // namespace T32 }; // namespace T32
}; // namespace fail }; // namespace fail
#endif // __T32_CONSTANTS_HPP__ #endif // __T32_CONSTANTS_HPP__

View File

@ -4,11 +4,11 @@
namespace fail { namespace fail {
void T32Controller::startup(){ void T32Controller::startup(){
// Do some T32-specific startup // Do some T32-specific startup
addCPU(new ConcreteCPU(0)); addCPU(new ConcreteCPU(0));
// Startup generic SimulatorController // Startup generic SimulatorController
// TODO pass on command-line parameters // TODO pass on command-line parameters
SimulatorController::startup(); SimulatorController::startup();
} }

View File

@ -12,8 +12,8 @@ namespace fail {
*/ */
class T32Controller : public SimulatorController { class T32Controller : public SimulatorController {
public: public:
void startup(); void startup();
T32Controller() : SimulatorController(new T32MemoryManager()) { }; T32Controller() : SimulatorController(new T32MemoryManager()) { };
~T32Controller(); ~T32Controller();
/* ******************************************************************** /* ********************************************************************

View File

@ -1,5 +1,5 @@
#ifndef __T32_MEMORY_HPP__ #ifndef __T32_MEMORY_HPP__
#define __T32_MEMORY_HPP__ #define __T32_MEMORY_HPP__
#include "../Memory.hpp" #include "../Memory.hpp"
#include <t32.h> #include <t32.h>
@ -21,26 +21,26 @@ public:
byte_t getByte(guest_address_t addr) byte_t getByte(guest_address_t addr)
{ {
char b; char b;
getBytes(addr, 1, &b); getBytes(addr, 1, &b);
return b; return b;
} }
void getBytes(guest_address_t addr, size_t cnt, void *dest) void getBytes(guest_address_t addr, size_t cnt, void *dest)
{ {
int access = T32::MEMACCESS::DATA; // TODO what access class do we need?! int access = T32::MEMACCESS::DATA; // TODO what access class do we need?!
T32_ReadMemory( addr, access, (byte*)(dest), cnt); T32_ReadMemory( addr, access, (byte*)(dest), cnt);
} }
void setByte(guest_address_t addr, byte_t data) void setByte(guest_address_t addr, byte_t data)
{ {
setBytes(addr, 1, &data); setBytes(addr, 1, &data);
} }
void setBytes(guest_address_t addr, size_t cnt, void const *src) void setBytes(guest_address_t addr, size_t cnt, void const *src)
{ {
int access = T32::MEMACCESS::DATA; // TODO what access class do we really need?! int access = T32::MEMACCESS::DATA; // TODO what access class do we really need?!
T32_WriteMemory(addr, access, (byte*)(src), cnt); T32_WriteMemory(addr, access, (byte*)(src), cnt);
} }
}; };

View File

@ -8,35 +8,35 @@ X86Architecture::X86Architecture()
{ {
// ------------------------------------- // -------------------------------------
// Add the general purpose register: // Add the general purpose register:
#ifdef SIM_SUPPORT_64 #ifdef SIM_SUPPORT_64
// -- 64 bit register -- // -- 64 bit register --
const std::string names[] = { "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8", const std::string names[] = { "RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", "R8",
"R9", "R10", "R11", "R12", "R13", "R14", "R15" }; "R9", "R10", "R11", "R12", "R13", "R14", "R15" };
for (unsigned short i = 0; i < 16; i++) { for (unsigned short i = 0; i < 16; i++) {
Register* pReg = new Register(i, 64); Register* pReg = new Register(i, 64);
pReg->setName(names[i]); pReg->setName(names[i]);
m_addRegister(pReg, RT_GP); m_addRegister(pReg, RT_GP);
} }
#else #else
// -- 32 bit register -- // -- 32 bit register --
const std::string names[] = { "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI" }; const std::string names[] = { "EAX", "ECX", "EDX", "EBX", "ESP", "EBP", "ESI", "EDI" };
for (unsigned short i = 0; i < 8; i++) { for (unsigned short i = 0; i < 8; i++) {
Register* pReg = new Register(i, 32); Register* pReg = new Register(i, 32);
pReg->setName(names[i]); pReg->setName(names[i]);
m_addRegister(pReg, RT_GP); m_addRegister(pReg, RT_GP);
} }
#endif // SIM_SUPPORT_64 #endif // SIM_SUPPORT_64
// ------------------------------------- // -------------------------------------
// Add the program counter (PC) register: // Add the program counter (PC) register:
#ifdef SIM_SUPPORT_64 #ifdef SIM_SUPPORT_64
Register* pPCReg = new Register(RID_PC, 64); Register* pPCReg = new Register(RID_PC, 64);
pPCReg->setName("RIP"); pPCReg->setName("RIP");
#else #else
Register* pPCReg = new Register(RID_PC, 32); Register* pPCReg = new Register(RID_PC, 32);
pPCReg->setName("EIP"); pPCReg->setName("EIP");
#endif // SIM_SUPPORT_64 #endif // SIM_SUPPORT_64
m_addRegister(pPCReg, RT_IP); m_addRegister(pPCReg, RT_IP);
// ------------------------------------- // -------------------------------------
// Add the status register (EFLAGS): // Add the status register (EFLAGS):
Register* pFlagReg = new Register(RID_FLAGS, 32); Register* pFlagReg = new Register(RID_FLAGS, 32);
pFlagReg->setName("EFLAGS"); pFlagReg->setName("EFLAGS");

View File

@ -1,5 +1,5 @@
#ifndef __X86_ARCHITECTURE_HPP__ #ifndef __X86_ARCHITECTURE_HPP__
#define __X86_ARCHITECTURE_HPP__ #define __X86_ARCHITECTURE_HPP__
#include "../CPU.hpp" #include "../CPU.hpp"
#include "../CPUState.hpp" #include "../CPUState.hpp"
@ -35,8 +35,8 @@ enum GPRegisterId {
#else // 32 bit register id's: #else // 32 bit register id's:
RID_EAX = 0, RID_ECX, RID_EDX, RID_EBX, RID_ESP, RID_EBP, RID_ESI, RID_EDI, RID_EAX = 0, RID_ECX, RID_EDX, RID_EBX, RID_ESP, RID_EBP, RID_ESI, RID_EDI,
#endif // common register id's (independent of the current register width): #endif // common register id's (independent of the current register width):
RID_CAX = 0, RID_CCX, RID_CDX, RID_CBX, RID_CSP, RID_CBP, RID_CSI, RID_CDI, RID_CAX = 0, RID_CCX, RID_CDX, RID_CBX, RID_CSP, RID_CBP, RID_CSI, RID_CDI,
RID_LAST_GP_ID RID_LAST_GP_ID
}; };
/** /**

View File

@ -1,5 +1,5 @@
#ifndef __X86_CPU_STATE_HPP__ #ifndef __X86_CPU_STATE_HPP__
#define __X86_CPU_STATE_HPP__ #define __X86_CPU_STATE_HPP__
#include "../CPU.hpp" #include "../CPU.hpp"
#include "../CPUState.hpp" #include "../CPUState.hpp"
@ -23,7 +23,7 @@ public:
* @return the current (E)FLAGS processor register content * @return the current (E)FLAGS processor register content
*/ */
virtual regdata_t getFlagsRegister() const = 0; virtual regdata_t getFlagsRegister() const = 0;
/** /**
* Returns \c true if the corresponding flag is set, or \c false * Returns \c true if the corresponding flag is set, or \c false
* otherwise. * otherwise.

View File

@ -5,65 +5,65 @@
namespace fail { namespace fail {
CommandLine CommandLine::m_instance; CommandLine CommandLine::m_instance;
void CommandLine::collect_args(argument_count &argc, argument_value &argv) { void CommandLine::collect_args(argument_count &argc, argument_value &argv) {
// Filter out all command line arguments that start with -Wf, // Filter out all command line arguments that start with -Wf,
for (int i = 0; i < argc; ++i) { for (int i = 0; i < argc; ++i) {
if (strncmp(argv[i], "-Wf,", 4) == 0) { if (strncmp(argv[i], "-Wf,", 4) == 0) {
this->argv.push_back(argv[i] + 4); this->argv.push_back(argv[i] + 4);
// also copy argv[argc], which equals 0 // also copy argv[argc], which equals 0
for (int x = i + 1; x <= argc; ++x) { for (int x = i + 1; x <= argc; ++x) {
argv[x - 1] = argv[x]; argv[x - 1] = argv[x];
} }
i --; i --;
argc --; argc --;
} }
} }
} }
CommandLine::option_handle CommandLine::addOption(const std::string &shortopt, CommandLine::option_handle CommandLine::addOption(
const std::string &longopt, const std::string &shortopt,
const option::CheckArg & check_arg, const std::string &longopt,
const std::string &help) { const option::CheckArg & check_arg,
const std::string &help) {
const unsigned int handle = this->options.size(); const unsigned int handle = this->options.size();
option::Descriptor desc = {handle, 0, strdup(shortopt.c_str()), option::Descriptor desc = {handle, 0, strdup(shortopt.c_str()),
strdup(longopt.c_str()), strdup(longopt.c_str()),
check_arg, strdup(help.c_str())}; check_arg, strdup(help.c_str())};
this->options.push_back(desc); this->options.push_back(desc);
return handle; return handle;
} }
bool CommandLine::parse() { bool CommandLine::parse() {
// Terminate the descriptor list // Terminate the descriptor list
option::Descriptor desc = {0, 0, 0, 0, 0, 0}; option::Descriptor desc = {0, 0, 0, 0, 0, 0};
this->options.push_back(desc); this->options.push_back(desc);
// Generate the options stats // Generate the options stats
option::Stats stats(this->options.data(), argv.size(), argv.data()); option::Stats stats(this->options.data(), argv.size(), argv.data());
if (parsed_options) if (parsed_options)
delete[] parsed_options; delete[] parsed_options;
if (parsed_buffer) if (parsed_buffer)
delete[] parsed_buffer; delete[] parsed_buffer;
if (m_parser) if (m_parser)
delete m_parser; delete m_parser;
parsed_options = new option::Option[stats.options_max]; parsed_options = new option::Option[stats.options_max];
parsed_buffer = new option::Option[stats.buffer_max]; parsed_buffer = new option::Option[stats.buffer_max];
m_parser = new option::Parser(this->options.data(), argv.size(), argv.data(), m_parser = new option::Parser(this->options.data(), argv.size(), argv.data(),
parsed_options, parsed_buffer); parsed_options, parsed_buffer);
// Pop the terminating entry // Pop the terminating entry
this->options.pop_back(); this->options.pop_back();
return !m_parser->error();
}
return !m_parser->error();
}
} // end of namespace } // end of namespace

View File

@ -17,93 +17,94 @@
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
namespace fail { namespace fail {
/**
* @class CommandLine
* @brief Implements a command line interface, that filters the
* simulators command line. It is a Singleton.
*/
class CommandLine {
public:
typedef int argument_count;
typedef char **argument_value;
private:
static CommandLine m_instance;
std::vector<const char *> argv; /**
std::vector<option::Descriptor> options; * @class CommandLine
option::Option *parsed_options, *parsed_buffer; * @brief Implements a command line interface, that filters the
option::Parser *m_parser; * simulators command line. It is a Singleton.
public: */
/// Handle for accessing the parsed data of an option class CommandLine {
typedef int option_handle; public:
typedef int argument_count;
typedef char **argument_value;
private:
static CommandLine m_instance;
/** std::vector<const char *> argv;
* Singleton accessor std::vector<option::Descriptor> options;
* option::Option *parsed_options, *parsed_buffer;
* @return reference to the CommandLine singleton object option::Parser *m_parser;
*/ public:
static CommandLine &Inst() { return m_instance; } /// Handle for accessing the parsed data of an option
typedef int option_handle;
/** /**
* Called by the simulator to filter all fail arguments from * Singleton accessor
* argc, argv *
*/ * @return reference to the CommandLine singleton object
void collect_args(argument_count &, argument_value &); */
static CommandLine &Inst() { return m_instance; }
/** /**
* Add a argument manually * Called by the simulator to filter all fail arguments from
*/ * argc, argv
void add_args(const char *value) { argv.push_back(value); } */
void collect_args(argument_count &, argument_value &);
/** /**
* Add a option to the command line interface of the fail-client * Add a argument manually
* */
* @param shortopt e.g "m" for -m void add_args(const char *value) { argv.push_back(value); }
* @param longopt e.g. "memory-region" for --memory-region=
* @param check_arg argument is required.
* @param help help text to be printed for -h
*
* @return return handle to option
*/
option_handle addOption(const std::string &shortopt,
const std::string &longopt,
const option::CheckArg & check_arg,
const std::string &help);
/** /**
* * Add a option to the command line interface of the fail-client
* do the actual parsing, called by the experiment *
* * @param shortopt e.g "m" for -m
* @return true on success * @param longopt e.g. "memory-region" for --memory-region=
*/ * @param check_arg argument is required.
bool parse(); * @param help help text to be printed for -h
*
* @return return handle to option
*/
option_handle addOption(const std::string &shortopt,
const std::string &longopt,
const option::CheckArg & check_arg,
const std::string &help);
/** /**
* Accessor for the command line option objects *
* * do the actual parsing, called by the experiment
* @param handle option handle *
* * @return true on success
* @return reference to the option parser object */
*/ bool parse();
option::Option &operator[](option_handle handle) {
assert(parsed_options != 0); /**
assert(handle >= 0 && handle < (int)options.size()); * Accessor for the command line option objects
return parsed_options[handle]; *
} * @param handle option handle
/** *
* Print help message. * @return reference to the option parser object
*/ */
void printUsage() { option::Option &operator[](option_handle handle) {
int columns = getenv("COLUMNS")? atoi(getenv("COLUMNS")) : 80; assert(parsed_options != 0);
option::printUsage(fwrite, stdout, options.data(), columns); assert(handle >= 0 && handle < (int)options.size());
} return parsed_options[handle];
/** }
* Return the internal option::Parser object for further usage. /**
*/ * Print help message.
option::Parser *parser() { */
return m_parser; void printUsage() {
} int columns = getenv("COLUMNS")? atoi(getenv("COLUMNS")) : 80;
}; option::printUsage(fwrite, stdout, options.data(), columns);
}
/**
* Return the internal option::Parser object for further usage.
*/
option::Parser *parser() {
return m_parser;
}
};
} // end of namespace } // end of namespace

View File

@ -6,15 +6,15 @@
namespace fail { namespace fail {
const std::string Demangler::DEMANGLE_FAILED = "[Demangler] Demangle failed."; const std::string Demangler::DEMANGLE_FAILED = "[Demangler] Demangle failed.";
std::string Demangler::demangle(const std::string& name){ std::string Demangler::demangle(const std::string& name){
const char* res = cplus_demangle(name.c_str(), 0); const char* res = cplus_demangle(name.c_str(), 0);
if(res != NULL){ if (res != NULL) {
return std::string(res); return std::string(res);
}else{ } else {
return Demangler::DEMANGLE_FAILED; return Demangler::DEMANGLE_FAILED;
} }
} }
} // end of namespace } // end of namespace

View File

@ -5,19 +5,19 @@
namespace fail { namespace fail {
class Demangler { class Demangler {
public: public:
/** /**
* Get the demangled symbol name of a mangled string. * Get the demangled symbol name of a mangled string.
* @param name The mangled symbol * @param name The mangled symbol
* @return The according demangled name if found, else Demangler::DEMANGLE_FAILED * @return The according demangled name if found, else Demangler::DEMANGLE_FAILED
*/ */
static std::string demangle(const std::string & name); static std::string demangle(const std::string & name);
//! Inform about failed demangling. //! Inform about failed demangling.
static const std::string DEMANGLE_FAILED; static const std::string DEMANGLE_FAILED;
}; };
} // end of namespace } // end of namespace

View File

@ -13,100 +13,99 @@
namespace fail { namespace fail {
const std::string DISASSEMBLER::FAILED = "[Disassembler] Disassemble failed."; const std::string DISASSEMBLER::FAILED = "[Disassembler] Disassemble failed.";
Disassembler::Disassembler() : m_log("Fail*Disassembler", false){ } Disassembler::Disassembler() : m_log("Fail*Disassembler", false) { }
int Disassembler::init() { int Disassembler::init() {
// try to open elf file from environment variable // try to open elf file from environment variable
char * elfpath = getenv("FAIL_ELF_PATH"); char * elfpath = getenv("FAIL_ELF_PATH");
if(elfpath == NULL){ if (elfpath == NULL) {
m_log << "FAIL_ELF_PATH not set :(" << std::endl; m_log << "FAIL_ELF_PATH not set :(" << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
}else{ } else {
return init(elfpath); return init(elfpath);
} }
} }
int Disassembler::init(const char* path){ int Disassembler::init(const char* path) {
// Disassemble ELF // Disassemble ELF
#ifndef __puma #ifndef __puma
std::string command = std::string(ARCH_TOOL_PREFIX) + std::string("objdump -d ") + std::string(path); std::string command = std::string(ARCH_TOOL_PREFIX) + std::string("objdump -d ") + std::string(path);
m_log << "Executing: " << command << std::endl; m_log << "Executing: " << command << std::endl;
redi::ipstream objdump( command ); redi::ipstream objdump( command );
std::string str; std::string str;
while(std::getline(objdump, str)){ while (std::getline(objdump, str)) {
evaluate(str); evaluate(str);
} }
objdump.close(); objdump.close();
if(objdump.rdbuf()->exited()){ if (objdump.rdbuf()->exited()) {
int ex = objdump.rdbuf()->status(); int ex = objdump.rdbuf()->status();
if(ex != 0){ if (ex != 0) {
m_code.clear(); m_code.clear();
m_log << "Could not disassemble!" << std::endl; m_log << "Could not disassemble!" << std::endl;
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
} }
m_log << "disassembled " << m_code.size() << " lines." << std::endl; m_log << "disassembled " << m_code.size() << " lines." << std::endl;
#endif #endif
return m_code.size(); return m_code.size();
} }
std::ostream& operator <<(std::ostream & os, const fail::Instruction & i) { std::ostream& operator <<(std::ostream & os, const fail::Instruction & i) {
#ifndef __puma #ifndef __puma
os << std::hex << ((int)(i.address)) << "\t" << i.opcode << "\t" << i.instruction << "\t" << i.comment; os << std::hex << ((int)(i.address)) << "\t" << i.opcode << "\t" << i.instruction << "\t" << i.comment;
#endif #endif
return os; return os;
} }
void Disassembler::evaluate(const std::string& line){ void Disassembler::evaluate(const std::string& line) {
#ifndef __puma #ifndef __puma
// Only read in real code lines: // Only read in real code lines:
// Code lines start with a leading whitespace! (hopefully in each objdump implementation!) // Code lines start with a leading whitespace! (hopefully in each objdump implementation!)
if(line.size() > 0 && isspace(line[0])){ if (line.size() > 0 && isspace(line[0])) {
// a line looks like: 800156c:\tdd14 \tble.n 8001598 <_ZN2hw3hal7T32Term8PutBlockEPci+0x30> // a line looks like: 800156c:\tdd14 \tble.n 8001598 <_ZN2hw3hal7T32Term8PutBlockEPci+0x30>
boost::regex expr("\\s+([A-Fa-f0-9]+):\\t(.*?)\\t(.+?)(;.*)?$"); boost::regex expr("\\s+([A-Fa-f0-9]+):\\t(.*?)\\t(.+?)(;.*)?$");
boost::smatch res; boost::smatch res;
if(boost::regex_search(line, res, expr)){ if (boost::regex_search(line, res, expr)) {
std::string address = res[1]; std::string address = res[1];
std::stringstream ss; std::stringstream ss;
ss << std::hex << address; ss << std::hex << address;
address_t addr = 0; address_t addr = 0;
ss >> addr; ss >> addr;
ss.clear(); ss.clear();
ss.str(""); ss.str("");
std::string opcode = res[2]; std::string opcode = res[2];
// delete trailing/leading whitespaces // delete trailing/leading whitespaces
boost::trim(opcode); boost::trim(opcode);
// delete inner whitespaces and merge nibbles // delete inner whitespaces and merge nibbles
opcode.erase(std::remove(opcode.begin(), opcode.end(), ' '), opcode.end()); opcode.erase(std::remove(opcode.begin(), opcode.end(), ' '), opcode.end());
ss << std::hex << opcode; ss << std::hex << opcode;
unsigned opc = 0; unsigned opc = 0;
ss >> opc; ss >> opc;
std::string instruction = res[3]; std::string instruction = res[3];
boost::trim(instruction); boost::trim(instruction);
std::string comment = res[4]; std::string comment = res[4];
boost::trim(comment); boost::trim(comment);
m_code.insert(std::make_pair(addr, Instruction(addr, opc, instruction, comment))); m_code.insert(std::make_pair(addr, Instruction(addr, opc, instruction, comment)));
} }
} }
#endif #endif
} }
static Instruction g_InstructionNotFound;
const Instruction & Disassembler::disassemble(address_t address) const {
InstructionMap_t::const_iterator it = m_code.find(address);
if(it == m_code.end()){
return g_InstructionNotFound;
}else{
return it->second;
}
}
static Instruction g_InstructionNotFound;
const Instruction & Disassembler::disassemble(address_t address) const {
InstructionMap_t::const_iterator it = m_code.find(address);
if (it == m_code.end()) {
return g_InstructionNotFound;
} else {
return it->second;
}
}
} // end of namespace } // end of namespace

View File

@ -1,5 +1,5 @@
#ifndef __DISASSEMBLER_HPP #ifndef __DISASSEMBLER_HPP
#define __DISASSEMBLER_HPP #define __DISASSEMBLER_HPP
#include <string> #include <string>
#include "Logger.hpp" #include "Logger.hpp"
@ -9,70 +9,70 @@
namespace fail { namespace fail {
struct DISASSEMBLER { struct DISASSEMBLER {
//! Inform about failed disassembly //! Inform about failed disassembly
static const std::string FAILED; static const std::string FAILED;
}; };
/** /**
* @class Instruction * @class Instruction
* @brief An Instruction represents an disassembled opcode * @brief An Instruction represents an disassembled opcode
*/ */
struct Instruction { struct Instruction {
address_t address; //!< The instruction address address_t address; //!< The instruction address
regdata_t opcode; //!< The opcode itself regdata_t opcode; //!< The opcode itself
std::string instruction; //!< The disassembled instruction std::string instruction; //!< The disassembled instruction
std::string comment; //!< Comment (rest of line after ; ) std::string comment; //!< Comment (rest of line after ; )
Instruction(address_t address = ADDR_INV, regdata_t opcode = 0, const std::string& instr = DISASSEMBLER::FAILED, const std::string& comment = "") Instruction(address_t address = ADDR_INV, regdata_t opcode = 0, const std::string& instr = DISASSEMBLER::FAILED, const std::string& comment = "")
: address(address), opcode(opcode), instruction(instr), comment(comment) { }; : address(address), opcode(opcode), instruction(instr), comment(comment) { };
}; };
//<! This allows to print an Instruction via Logger or cout //<! This allows to print an Instruction via Logger or cout
std::ostream& operator <<(std::ostream & os, const fail::Instruction & i); std::ostream& operator <<(std::ostream & os, const fail::Instruction & i);
class Disassembler { class Disassembler {
public: public:
/** /**
* Constructor. * Constructor.
*/ */
Disassembler(); Disassembler();
/** /**
* Get disassembler instruction * Get disassembler instruction
* @param address The instruction address * @param address The instruction address
* @return The according disassembled instruction if found, else DISASSEMBLER::FAILED * @return The according disassembled instruction if found, else DISASSEMBLER::FAILED
*/ */
const Instruction & disassemble(address_t address) const; const Instruction & disassemble(address_t address) const;
/** /**
* Test if there is an instruction at a given address * Test if there is an instruction at a given address
* @param address The address to test * @param address The address to test
* @return true if found, else false * @return true if found, else false
*/ */
bool hasInstructionAt(address_t address) const { bool hasInstructionAt(address_t address) const {
return m_code.find(address) != m_code.end();; return m_code.find(address) != m_code.end();;
}; };
/** /**
* Evaluate new ELF file * Evaluate new ELF file
* @param elfpath Path to ELF file. * @param elfpath Path to ELF file.
* @return Number of disassembled lines. * @return Number of disassembled lines.
*/ */
int init(const char* elfpath); int init(const char* elfpath);
/** /**
* Evaluate new ELF file from env variable $FAIL_ELF_PATH * Evaluate new ELF file from env variable $FAIL_ELF_PATH
* @return Number of disassembled lines. * @return Number of disassembled lines.
* @note The path is guessed from a FAIL_ELF_PATH environment variable * @note The path is guessed from a FAIL_ELF_PATH environment variable
*/ */
int init(void); int init(void);
private: private:
Logger m_log; Logger m_log;
typedef std::map<address_t, Instruction> InstructionMap_t; typedef std::map<address_t, Instruction> InstructionMap_t;
InstructionMap_t m_code; InstructionMap_t m_code;
void evaluate(const std::string &); void evaluate(const std::string &);
}; };
} // end of namespace } // end of namespace
#endif // DISASSEMBLER_HPP #endif // DISASSEMBLER_HPP

View File

@ -11,245 +11,243 @@ const std::string ELF::NOTFOUND = "[ELFReader] Function not found.";
static const ElfSymbol g_SymbolNotFound; static const ElfSymbol g_SymbolNotFound;
bool operator==(const std::string & str, const ElfSymbol & sym) { bool operator==(const std::string & str, const ElfSymbol & sym) {
return sym.getName() == str; return sym.getName() == str;
} }
bool operator==(guest_address_t address, const ElfSymbol & sym) { bool operator==(guest_address_t address, const ElfSymbol & sym) {
return sym.getAddress() == address; return sym.getAddress() == address;
} }
std::ostream& operator<< (std::ostream &out, const ElfSymbol &symbol) { std::ostream& operator<< (std::ostream &out, const ElfSymbol &symbol) {
return (out << symbol.getName() return (out << symbol.getName()
<< " @ 0x" << std::hex << symbol.getAddress() << " @ 0x" << std::hex << symbol.getAddress()
<< " size " << std::dec << symbol.getSize()); << " size " << std::dec << symbol.getSize());
} }
ElfReader::ElfReader() : m_log("Fail*Elfinfo", false){ ElfReader::ElfReader() : m_log("Fail*Elfinfo", false) {
// try to open elf file from environment variable // try to open elf file from environment variable
char * elfpath = getenv("FAIL_ELF_PATH"); char * elfpath = getenv("FAIL_ELF_PATH");
if(elfpath == NULL){ if (elfpath == NULL) {
m_log << "FAIL_ELF_PATH not set :(" << std::endl; m_log << "FAIL_ELF_PATH not set :(" << std::endl;
}else{ } else {
setup(elfpath); setup(elfpath);
} }
} }
ElfReader::ElfReader(const char* path) : m_log("Fail*Elfinfo", false){ ElfReader::ElfReader(const char* path) : m_log("Fail*Elfinfo", false) {
setup(path); setup(path);
} }
void ElfReader::setup(const char* path) { void ElfReader::setup(const char* path) {
// Try to open the ELF file // Try to open the ELF file
FILE * fp = fopen(path, "r"); FILE * fp = fopen(path, "r");
if (!fp) { if (!fp) {
m_log << "Error: Could not open " << path << std::endl; m_log << "Error: Could not open " << path << std::endl;
return; return;
} }
m_filename = std::string(path); m_filename = std::string(path);
// Evaluate headers // Evaluate headers
Elf32_Ehdr ehdr; Elf32_Ehdr ehdr;
Elf32_Shdr sec_hdr; Elf32_Shdr sec_hdr;
int num_hdrs,i; int num_hdrs,i;
fseek(fp,(off_t)0,SEEK_SET); fseek(fp,(off_t)0,SEEK_SET);
read_ELF_file_header(fp, &ehdr); read_ELF_file_header(fp, &ehdr);
num_hdrs=ehdr.e_shnum; num_hdrs=ehdr.e_shnum;
m_log << "Evaluating ELF File: " << path << std::endl; m_log << "Evaluating ELF File: " << path << std::endl;
// Parse symbol table and generate internal map // Parse symbol table and generate internal map
for(i=0;i<num_hdrs;i++) for (i=0;i<num_hdrs;i++)
{ {
if(read_ELF_section_header(i,&sec_hdr,fp)==-1) if (read_ELF_section_header(i,&sec_hdr,fp)==-1)
{ {
m_log << "Wrong Section to read" << std::endl; m_log << "Wrong Section to read" << std::endl;
} }
else else
{ {
if((sec_hdr.sh_type==SHT_SYMTAB)||(sec_hdr.sh_type==SHT_DYNSYM)) if ((sec_hdr.sh_type==SHT_SYMTAB)||(sec_hdr.sh_type==SHT_DYNSYM))
{ {
process_symboltable(i,fp); process_symboltable(i,fp);
} }
else else
{ {
continue; continue;
} }
} }
} }
// Parse section information // Parse section information
if(read_ELF_section_header(ehdr.e_shstrndx,&sec_hdr,fp)==-1) if (read_ELF_section_header(ehdr.e_shstrndx,&sec_hdr,fp)==-1)
{ {
m_log << "Error: reading section string table sect_num = " << ehdr.e_shstrndx << std::endl; m_log << "Error: reading section string table sect_num = " << ehdr.e_shstrndx << std::endl;
} }
char* buff=(char*)malloc(sec_hdr.sh_size); char* buff=(char*)malloc(sec_hdr.sh_size);
if (!buff) if (!buff)
{ {
m_log << "Malloc failed to allocate buffer for shstrtab" << std::endl; m_log << "Malloc failed to allocate buffer for shstrtab" << std::endl;
exit(0); exit(0);
} }
//seek to the offset in the file, // seek to the offset in the file,
fseek(fp,(off_t)sec_hdr.sh_offset,SEEK_SET); fseek(fp,(off_t)sec_hdr.sh_offset,SEEK_SET);
fread(buff,sec_hdr.sh_size,1,fp); fread(buff,sec_hdr.sh_size,1,fp);
m_log << "Total number of sections: " << num_hdrs << std::endl; m_log << "Total number of sections: " << num_hdrs << std::endl;
for(i=0;i<num_hdrs;i++) for (i=0;i<num_hdrs;i++)
{ {
if(read_ELF_section_header(i,&sec_hdr,fp)==-1) if (read_ELF_section_header(i,&sec_hdr,fp)==-1)
{ {
m_log << "Wrong Section to read\n" << std::endl; m_log << "Wrong Section to read\n" << std::endl;
} }
else else
{ {
process_section(&sec_hdr, buff); process_section(&sec_hdr, buff);
} }
} }
if(buff) if (buff)
free(buff); free(buff);
fclose(fp); fclose(fp);
// printDemangled(); // printDemangled();
// printSections(); // printSections();
} }
int ElfReader::process_section(Elf32_Shdr *sect_hdr, char* sect_name_buff){ int ElfReader::process_section(Elf32_Shdr *sect_hdr, char* sect_name_buff) {
// Add section name, start address and size to list // Add section name, start address and size to list
int idx=sect_hdr->sh_name; int idx=sect_hdr->sh_name;
// m_sections_map.push_back( sect_hdr->sh_addr, sect_hdr->sh_size, sect_name_buff+idx ); // m_sections_map.push_back( sect_hdr->sh_addr, sect_hdr->sh_size, sect_name_buff+idx );
m_sectiontable.push_back( ElfSymbol(sect_name_buff+idx, sect_hdr->sh_addr, sect_hdr->sh_size, ElfSymbol::SECTION) ); m_sectiontable.push_back( ElfSymbol(sect_name_buff+idx, sect_hdr->sh_addr, sect_hdr->sh_size, ElfSymbol::SECTION) );
return 0; return 0;
} }
int ElfReader::process_symboltable(int sect_num, FILE* fp){ int ElfReader::process_symboltable(int sect_num, FILE* fp) {
Elf32_Shdr sect_hdr; Elf32_Shdr sect_hdr;
Elf32_Sym mysym; Elf32_Sym mysym;
char *name_buf=NULL; char *name_buf=NULL;
int num_sym,link,i,idx; int num_sym,link,i,idx;
off_t sym_data_offset; off_t sym_data_offset;
int sym_data_size; int sym_data_size;
if(read_ELF_section_header(sect_num,&sect_hdr,fp)==-1) if (read_ELF_section_header(sect_num,&sect_hdr,fp)==-1)
{ {
return -1; return -1;
} }
//we have to check to which strtab it is linked // we have to check to which strtab it is linked
link=sect_hdr.sh_link; link=sect_hdr.sh_link;
sym_data_offset=sect_hdr.sh_offset; sym_data_offset=sect_hdr.sh_offset;
sym_data_size=sect_hdr.sh_size; sym_data_size=sect_hdr.sh_size;
num_sym=sym_data_size/sizeof(Elf32_Sym); num_sym=sym_data_size/sizeof(Elf32_Sym);
//read the coresponding strtab // read the coresponding strtab
if(read_ELF_section_header(link,&sect_hdr,fp)==-1) if (read_ELF_section_header(link,&sect_hdr,fp)==-1)
{ {
return -1; return -1;
} }
//get the size of strtab in file and allocate a buffer // get the size of strtab in file and allocate a buffer
name_buf=(char*)malloc(sect_hdr.sh_size); name_buf=(char*)malloc(sect_hdr.sh_size);
if(!name_buf) if (!name_buf)
return -1; return -1;
//get the offset of strtab in file and seek to it // get the offset of strtab in file and seek to it
fseek(fp,sect_hdr.sh_offset,SEEK_SET); fseek(fp,sect_hdr.sh_offset,SEEK_SET);
//read all data from the section to the buffer. // read all data from the section to the buffer.
fread(name_buf,sect_hdr.sh_size,1,fp); fread(name_buf,sect_hdr.sh_size,1,fp);
//so we have the namebuf now seek to symtab data // so we have the namebuf now seek to symtab data
fseek(fp,sym_data_offset,SEEK_SET); fseek(fp,sym_data_offset,SEEK_SET);
for(i=0;i<num_sym;i++) for (i=0;i<num_sym;i++)
{ {
fread(&mysym,sizeof(Elf32_Sym),1,fp); fread(&mysym,sizeof(Elf32_Sym),1,fp);
idx=mysym.st_name; idx=mysym.st_name;
int type = ELF32_ST_TYPE(mysym.st_info); int type = ELF32_ST_TYPE(mysym.st_info);
if((type != STT_SECTION) && (type != STT_FILE)){ if ((type != STT_SECTION) && (type != STT_FILE)) {
m_symboltable.push_back( ElfSymbol(name_buf+idx, mysym.st_value, mysym.st_size, ElfSymbol::SYMBOL, m_symboltable.push_back( ElfSymbol(name_buf+idx, mysym.st_value, mysym.st_size, ElfSymbol::SYMBOL,
type) ); type) );
} }
} }
free (name_buf); free (name_buf);
return 0; return 0;
} }
const ElfSymbol& ElfReader::getSymbol(guest_address_t address){ const ElfSymbol& ElfReader::getSymbol(guest_address_t address) {
for(container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it){ for (container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it) {
if(it->contains(address)){ if (it->contains(address)) {
return *it; return *it;
} }
} }
return g_SymbolNotFound; return g_SymbolNotFound;
} }
// Symbol search // Symbol search
const ElfSymbol& ElfReader::getSymbol( const std::string& name ){ const ElfSymbol& ElfReader::getSymbol( const std::string& name ) {
container_t::const_iterator it; container_t::const_iterator it;
// Fist, try to find as mangled symbol // Fist, try to find as mangled symbol
it = std::find(m_symboltable.begin(), m_symboltable.end(), name); it = std::find(m_symboltable.begin(), m_symboltable.end(), name);
if(it != m_symboltable.end()){ if (it != m_symboltable.end()) {
return *it; return *it;
} }
// Then, try to find as demangled symbol // Then, try to find as demangled symbol
std::string dname = Demangler::demangle(name); std::string dname = Demangler::demangle(name);
if(dname == Demangler::DEMANGLE_FAILED){ if (dname == Demangler::DEMANGLE_FAILED) {
return g_SymbolNotFound; return g_SymbolNotFound;
} }
it = std::find(m_symboltable.begin(), m_symboltable.end(), dname); it = std::find(m_symboltable.begin(), m_symboltable.end(), dname);
if(it != m_symboltable.end()){ if (it != m_symboltable.end()) {
return *it; return *it;
} }
return g_SymbolNotFound; return g_SymbolNotFound;
} }
// Section search // Section search
const ElfSymbol& ElfReader::getSection(guest_address_t address){ const ElfSymbol& ElfReader::getSection(guest_address_t address) {
for(container_t::const_iterator it = m_sectiontable.begin(); it != m_sectiontable.end(); ++it){ for (container_t::const_iterator it = m_sectiontable.begin(); it != m_sectiontable.end(); ++it) {
if(it->contains(address)){ if (it->contains(address)) {
return *it; return *it;
} }
} }
return g_SymbolNotFound; return g_SymbolNotFound;
} }
const ElfSymbol& ElfReader::getSection( const std::string& name ){ const ElfSymbol& ElfReader::getSection( const std::string& name ) {
for(container_t::const_iterator it = m_sectiontable.begin(); it !=m_sectiontable.end(); ++it){ for (container_t::const_iterator it = m_sectiontable.begin(); it !=m_sectiontable.end(); ++it) {
if(it->getName() == name){ if (it->getName() == name) {
return *it; return *it;
} }
} }
return g_SymbolNotFound; return g_SymbolNotFound;
} }
// "Pretty" Print // "Pretty" Print
void ElfReader::printDemangled(){ void ElfReader::printDemangled() {
m_log << "Demangled: " << std::endl; m_log << "Demangled: " << std::endl;
for(container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it){ for (container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it) {
std::string str = Demangler::demangle(it->getName()); std::string str = Demangler::demangle(it->getName());
if(str == Demangler::DEMANGLE_FAILED){ if (str == Demangler::DEMANGLE_FAILED) {
str = it->getName(); str = it->getName();
} }
m_log << "0x" << std::hex << it->getAddress() << "\t" << str.c_str() << "\t" << it->getSize() << std::endl; m_log << "0x" << std::hex << it->getAddress() << "\t" << str.c_str() << "\t" << it->getSize() << std::endl;
} }
} }
void ElfReader::printMangled(){ void ElfReader::printMangled() {
for(container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it){ for (container_t::const_iterator it = m_symboltable.begin(); it !=m_symboltable.end(); ++it) {
m_log << "0x" << std::hex << it->getAddress() << "\t" << it->getName().c_str() << "\t" << it->getSize() << std::endl; m_log << "0x" << std::hex << it->getAddress() << "\t" << it->getName().c_str() << "\t" << it->getSize() << std::endl;
} }
} }
void ElfReader::printSections() { void ElfReader::printSections() {
for(container_t::const_iterator it = m_sectiontable.begin(); it !=m_sectiontable.end(); ++it){ for (container_t::const_iterator it = m_sectiontable.begin(); it !=m_sectiontable.end(); ++it) {
m_log << "0x" << it->getAddress() << "\t" << it->getName().c_str() << "\t" << it->getSize() << std::endl; m_log << "0x" << it->getAddress() << "\t" << it->getName().c_str() << "\t" << it->getSize() << std::endl;
} }
} }
} // end-of-namespace fail } // end-of-namespace fail

View File

@ -12,164 +12,163 @@
namespace fail { namespace fail {
struct ELF { struct ELF {
static const std::string NOTFOUND; static const std::string NOTFOUND;
}; };
class ElfSymbol { class ElfSymbol {
std::string name; std::string name;
guest_address_t address; guest_address_t address;
size_t size; size_t size;
int m_type; int m_type;
int m_symbol_type; int m_symbol_type;
public: public:
enum { SECTION = 1, SYMBOL = 2, UNDEF = 3, }; enum { SECTION = 1, SYMBOL = 2, UNDEF = 3, };
ElfSymbol(const std::string & name = ELF::NOTFOUND, guest_address_t addr = ADDR_INV, size_t size = -1, int type = UNDEF, ElfSymbol(const std::string & name = ELF::NOTFOUND, guest_address_t addr = ADDR_INV,
int symbol_type = 0) size_t size = -1, int type = UNDEF, int symbol_type = 0)
: name(name), address(addr), size(size), m_type(type), m_symbol_type(symbol_type) {}; : name(name), address(addr), size(size), m_type(type), m_symbol_type(symbol_type) {};
const std::string& getName() const { return name; }; const std::string& getName() const { return name; };
std::string getDemangledName() const { return Demangler::demangle(name); }; std::string getDemangledName() const { return Demangler::demangle(name); };
guest_address_t getAddress() const { return address; }; guest_address_t getAddress() const { return address; };
size_t getSize() const { return size; }; size_t getSize() const { return size; };
guest_address_t getStart() const { return getAddress(); }; // alias guest_address_t getStart() const { return getAddress(); }; // alias
guest_address_t getEnd() const { return address + size; }; guest_address_t getEnd() const { return address + size; };
int getSymbolType() const { return m_symbol_type; }; int getSymbolType() const { return m_symbol_type; };
bool isSection() const { return m_type == SECTION; }; bool isSection() const { return m_type == SECTION; };
bool isSymbol() const { return m_type == SYMBOL; }; bool isSymbol() const { return m_type == SYMBOL; };
bool isValid() const { return name != ELF::NOTFOUND; }; bool isValid() const { return name != ELF::NOTFOUND; };
bool operator==(const std::string& rhs) const { bool operator==(const std::string& rhs) const {
if(rhs == name){ if (rhs == name) {
return true; return true;
} }
if( rhs == Demangler::demangle(name) ){ if ( rhs == Demangler::demangle(name) ) {
return true; return true;
} }
return false; return false;
} }
bool operator==(const guest_address_t rhs) const { bool operator==(const guest_address_t rhs) const {
return rhs == address; return rhs == address;
} }
bool contains(guest_address_t ad) const { bool contains(guest_address_t ad) const {
return (ad >= address) && (ad < address+size); return (ad >= address) && (ad < address+size);
} }
}; };
/** /**
* \fn * \fn
* \relates ElfSymbol * \relates ElfSymbol
* overloaded stream operator for printing ElfSymbol * overloaded stream operator for printing ElfSymbol
*/ */
std::ostream& operator<< (std::ostream &out, const ElfSymbol &symbol); std::ostream& operator<< (std::ostream &out, const ElfSymbol &symbol);
/** /**
* \class ElfReader * \class ElfReader
* Parses an ELF file and provides a list of symbol names * Parses an ELF file and provides a list of symbol names
* and corresponding addresses * and corresponding addresses
*/ */
class ElfReader { class ElfReader {
public: public:
typedef ElfSymbol entry_t; typedef ElfSymbol entry_t;
typedef std::vector<entry_t> container_t; typedef std::vector<entry_t> container_t;
typedef container_t::const_iterator symbol_iterator; typedef container_t::const_iterator symbol_iterator;
typedef container_t::const_iterator section_iterator; typedef container_t::const_iterator section_iterator;
/** /**
* Constructor. * Constructor.
* @param path Path to the ELF file. * @param path Path to the ELF file.
*/ */
ElfReader(const char* path); ElfReader(const char* path);
/** /**
* Constructor. * Constructor.
* @note The path is guessed from a FAIL_ELF_PATH environment variable * @note The path is guessed from a FAIL_ELF_PATH environment variable
*/ */
ElfReader(); ElfReader();
/** /**
* Print the list of available mangled symbols * Print the list of available mangled symbols
* @note This includes both C and C++ symbols * @note This includes both C and C++ symbols
*/ */
void printMangled(); void printMangled();
/** /**
* Print a list of demangled symbols. * Print a list of demangled symbols.
*/ */
void printDemangled(); void printDemangled();
/** /**
* Print the list of all available sections. * Print the list of all available sections.
*/ */
void printSections(); void printSections();
/** /**
* Get symbol by address * Get symbol by address
* @param address Address within range of the symbol * @param address Address within range of the symbol
* @return The according symbol name if symbol.address <= address < symbol.address + symbol.size , else g_SymbolNotFound * @return The according symbol name if symbol.address <= address < symbol.address + symbol.size , else g_SymbolNotFound
*/ */
const ElfSymbol& getSymbol(guest_address_t address); const ElfSymbol& getSymbol(guest_address_t address);
/** /**
* Get symbol by name * Get symbol by name
* @param address Name of the symbol * @param address Name of the symbol
* @return The according symbol name if section was found, else g_SymbolNotFound * @return The according symbol name if section was found, else g_SymbolNotFound
*/ */
const ElfSymbol& getSymbol( const std::string& name ); const ElfSymbol& getSymbol( const std::string& name );
/** /**
* Get section by address * Get section by address
* @param address An address to search for a section containing that address. * @param address An address to search for a section containing that address.
* @return The according section name if section was found, else g_SymbolNotFound * @return The according section name if section was found, else g_SymbolNotFound
*/ */
const ElfSymbol& getSection(guest_address_t address); const ElfSymbol& getSection(guest_address_t address);
/** /**
* Get section by name * Get section by name
* @param name The name of the section * @param name The name of the section
* @return The according section if section was found, else g_SymbolNotFound * @return The according section if section was found, else g_SymbolNotFound
*/ */
const ElfSymbol& getSection( const std::string& name ); const ElfSymbol& getSection( const std::string& name );
/** /**
* Get symboltable iterator. Derefences to a ElfSymbol * Get symboltable iterator. Derefences to a ElfSymbol
* @return iterator * @return iterator
*/ */
container_t::const_iterator sym_begin() { return m_symboltable.begin(); } container_t::const_iterator sym_begin() { return m_symboltable.begin(); }
container_t::const_iterator sym_end() { return m_symboltable.end(); } container_t::const_iterator sym_end() { return m_symboltable.end(); }
/** /**
* Get section iterator. Derefences to a ElfSymbol * Get section iterator. Derefences to a ElfSymbol
* @return iterator * @return iterator
*/ */
container_t::const_iterator sec_begin() { return m_sectiontable.begin(); } container_t::const_iterator sec_begin() { return m_sectiontable.begin(); }
container_t::const_iterator sec_end() { return m_sectiontable.end(); } container_t::const_iterator sec_end() { return m_sectiontable.end(); }
const std::string & getFilename() { return m_filename; } const std::string & getFilename() { return m_filename; }
private: private:
Logger m_log; Logger m_log;
std::string m_filename; std::string m_filename;
void setup(const char*); void setup(const char*);
int process_symboltable(int sect_num, FILE* fp); int process_symboltable(int sect_num, FILE* fp);
int process_section(Elf32_Shdr *sect_hdr, char* sect_name_buff); int process_section(Elf32_Shdr *sect_hdr, char* sect_name_buff);
container_t m_symboltable; container_t m_symboltable;
container_t m_sectiontable; container_t m_sectiontable;
guest_address_t getAddress(const std::string& name); guest_address_t getAddress(const std::string& name);
std::string getName(guest_address_t address); std::string getName(guest_address_t address);
}; };
} // end-of-namespace fail } // end-of-namespace fail
#endif //__ELFREADER_HPP__ #endif //__ELFREADER_HPP__

View File

@ -1,5 +1,5 @@
#ifndef __LOGGER_HPP__ #ifndef __LOGGER_HPP__
#define __LOGGER_HPP__ #define __LOGGER_HPP__
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>

View File

@ -1,5 +1,5 @@
#ifndef __MEMORYMAP_HPP__ #ifndef __MEMORYMAP_HPP__
#define __MEMORYMAP_HPP__ #define __MEMORYMAP_HPP__
#ifdef BOOST_1_46_OR_NEWER #ifdef BOOST_1_46_OR_NEWER
#include <boost/icl/interval_set.hpp> #include <boost/icl/interval_set.hpp>
@ -47,7 +47,7 @@ public:
} }
/** /**
* Determines whether a given memory access at address \a addr with width * Determines whether a given memory access at address \a addr with width
* \a size hits the map. * \a size hits the map.
*/ */
bool isMatching(address_t addr, int size = 1) bool isMatching(address_t addr, int size = 1)
{ {

View File

@ -9,20 +9,20 @@ ProtoOStream::ProtoOStream(std::ostream *outfile) : m_outfile(outfile)
m_log.showTime(false); m_log.showTime(false);
} }
bool ProtoOStream::writeMessage(google::protobuf::Message* m) bool ProtoOStream::writeMessage(google::protobuf::Message *m)
{ {
m_size = htonl(m->ByteSize()); m_size = htonl(m->ByteSize());
m_outfile->write(reinterpret_cast<char*>(&m_size), sizeof(m_size)); m_outfile->write(reinterpret_cast<char*>(&m_size), sizeof(m_size));
if (m_outfile->bad()) { if (m_outfile->bad()) {
m_log << "Could not write to file!" << std::endl; m_log << "Could not write to file!" << std::endl;
// TODO: log-Level? // TODO: log-Level?
return false; return false;
} }
m->SerializeToOstream(m_outfile); m->SerializeToOstream(m_outfile);
return true; return true;
} }
ProtoIStream::ProtoIStream(std::istream *infile) : m_infile(infile) ProtoIStream::ProtoIStream(std::istream *infile) : m_infile(infile)
@ -38,23 +38,23 @@ void ProtoIStream::reset()
m_infile->seekg(0, std::ios::beg); m_infile->seekg(0, std::ios::beg);
} }
bool ProtoIStream::getNext(google::protobuf::Message* m) bool ProtoIStream::getNext(google::protobuf::Message *m)
{ {
m_infile->read(reinterpret_cast<char*>(&m_size), sizeof(m_size)); m_infile->read(reinterpret_cast<char*>(&m_size), sizeof(m_size));
if (!m_infile->good()) if (!m_infile->good())
return false; return false;
m_size = ntohl(m_size); m_size = ntohl(m_size);
// FIXME reuse buffer (efficiency) // FIXME reuse buffer (efficiency)
// FIXME new[] may fail (i.e., return 0) // FIXME new[] may fail (i.e., return 0)
char *buf = new char[m_size]; char *buf = new char[m_size];
m_infile->read(buf, m_size); m_infile->read(buf, m_size);
if (!m_infile->good()) if (!m_infile->good())
// FIXME we're leaking buf[] // FIXME we're leaking buf[]
return false; return false;
std::string st(buf, m_size); std::string st(buf, m_size);
m->ParseFromString(st); m->ParseFromString(st);
delete [] buf; delete [] buf;
return true; return true;
} }

View File

@ -1,4 +1,4 @@
/** /**
* \brief One way to manage large protobuf-messages * \brief One way to manage large protobuf-messages
* *
* Google protobuf is not designed for large messages. That leads to * Google protobuf is not designed for large messages. That leads to
@ -8,14 +8,14 @@
* written sequentially in a file. Written in the format: * written sequentially in a file. Written in the format:
* *
* \code * \code
* | 4 bytes length-information of the first message | first message * | 4 bytes length-information of the first message | first message
* | 4 bytes length-information of the second message | second message * | 4 bytes length-information of the second message | second message
* | ... * | ...
* \endcode * \endcode
*/ */
#ifndef __PROTOSTREAM_HPP__ #ifndef __PROTOSTREAM_HPP__
#define __PROTOSTREAM_HPP__ #define __PROTOSTREAM_HPP__
#include <iostream> #include <iostream>
#include <sys/types.h> #include <sys/types.h>
@ -28,7 +28,7 @@ namespace fail {
/** /**
* \class ProtoOStream * \class ProtoOStream
* *
* This class can be used to sequentially write a large number of * This class can be used to sequentially write a large number of
* protocol buffer messages to a \c std::ostream. * protocol buffer messages to a \c std::ostream.
*/ */
@ -41,16 +41,16 @@ public:
ProtoOStream(std::ostream *outfile); ProtoOStream(std::ostream *outfile);
virtual ~ProtoOStream() { } virtual ~ProtoOStream() { }
/** /**
* Writes a message to a file. * Writes a message to a file.
* @param m The protobuf-message to be written * @param m The protobuf-message to be written
* @return Returns \c true on success, \c false otherwise * @return Returns \c true on success, \c false otherwise
*/ */
bool writeMessage(google::protobuf::Message* m); bool writeMessage(google::protobuf::Message *m);
}; };
/** /**
* \class ProtoIStream * \class ProtoIStream
* *
* This class can be used to read protocol buffer messages sequentially * This class can be used to read protocol buffer messages sequentially
* from a \c std::istream. * from a \c std::istream.
*/ */
@ -73,7 +73,7 @@ public:
* @param m The output protobuf message * @param m The output protobuf message
* @return Returns \c true on success, \c false otherwise * @return Returns \c true on success, \c false otherwise
*/ */
bool getNext(google::protobuf::Message* m); bool getNext(google::protobuf::Message * m);
}; };
} // end-of-namespace: fail } // end-of-namespace: fail

View File

@ -14,54 +14,54 @@ namespace fail {
* concatenating strings with a separator. * concatenating strings with a separator.
* *
* The behaviour is similar to the python list().join(",") construct. * The behaviour is similar to the python list().join(",") construct.
* *
*/ */
struct StringJoiner : public std::deque<std::string> { struct StringJoiner : public std::deque<std::string> {
/** /**
* \brief join all strings in the container, * \brief join all strings in the container,
* *
* Join all the collected strings to one string. The separator is * Join all the collected strings to one string. The separator is
* inserted between each element. * inserted between each element.
*/ */
std::string join(const char *j) { std::string join(const char *j) {
std::stringstream ss; std::stringstream ss;
if (size() == 0) if (size() == 0)
return ""; return "";
ss << front(); ss << front();
std::deque<std::string>::const_iterator i = begin() + 1; std::deque<std::string>::const_iterator i = begin() + 1;
while (i != end()) { while (i != end()) {
ss << j << *i; ss << j << *i;
i++; i++;
} }
return ss.str(); return ss.str();
} }
/** /**
* \brief append strings to list. * \brief append strings to list.
* *
* Appends the given value to the list of values if it isn't the * Appends the given value to the list of values if it isn't the
* empty string. "" will be ignored. * empty string. "" will be ignored.
*/ */
void push_back(const value_type &x) { void push_back(const value_type &x) {
if (x.compare("") == 0) if (x.compare("") == 0)
return; return;
std::deque<value_type>::push_back(x); std::deque<value_type>::push_back(x);
} }
/** /**
* \brief append strings to list. * \brief append strings to list.
* *
* Appends the given value to the list of values if it isn't the * Appends the given value to the list of values if it isn't the
* empty string. "" will be ignored. * empty string. "" will be ignored.
*/ */
void push_front(const value_type &x) { void push_front(const value_type &x) {
if (x.compare("") == 0) if (x.compare("") == 0)
return; return;
std::deque<value_type>::push_front(x); std::deque<value_type>::push_front(x);
} }
}; };
} }

View File

@ -3,7 +3,7 @@
*/ */
#ifndef __SYNCHRONIZED_COUNTER_HPP__ #ifndef __SYNCHRONIZED_COUNTER_HPP__
#define __SYNCHRONIZED_COUNTER_HPP__ #define __SYNCHRONIZED_COUNTER_HPP__
#ifndef __puma #ifndef __puma
#include <boost/thread.hpp> #include <boost/thread.hpp>
@ -14,7 +14,7 @@ namespace fail {
/** /**
* \class ssd * \class ssd
* *
* Provides a thread safe (synchronized) counter. When a method is called, * Provides a thread safe (synchronized) counter. When a method is called,
* the internal mutex is automatically locked. On return, the lock is * the internal mutex is automatically locked. On return, the lock is
* automatically released ("scoped lock"). * automatically released ("scoped lock").

View File

@ -3,7 +3,7 @@
*/ */
#ifndef __SYNCHRONIZED_MAP_HPP__ #ifndef __SYNCHRONIZED_MAP_HPP__
#define __SYNCHRONIZED_MAP_HPP__ #define __SYNCHRONIZED_MAP_HPP__
#include <map> #include <map>
@ -20,7 +20,7 @@ class SynchronizedMap {
private: private:
typedef std::map< Tkey, Tvalue > Tmap; typedef std::map< Tkey, Tvalue > Tmap;
typedef typename Tmap::iterator Tit; typedef typename Tmap::iterator Tit;
Tmap m_map; //! Use STL map to store data Tmap m_map; //! Use STL map to store data
#ifndef __puma #ifndef __puma
boost::mutex m_mutex; //! The mutex to synchronise on boost::mutex m_mutex; //! The mutex to synchronise on
@ -75,7 +75,7 @@ public:
* Add data to the map, return false if already present * Add data to the map, return false if already present
* @param key Map key * @param key Map key
* @param value value according to key * @param value value according to key
* @return false if key already present * @return false if key already present
*/ */
bool insert(const Tkey& key, const Tvalue& value) bool insert(const Tkey& key, const Tvalue& value)
{ {
@ -83,20 +83,20 @@ public:
#ifndef __puma #ifndef __puma
boost::unique_lock<boost::mutex> lock(m_mutex); boost::unique_lock<boost::mutex> lock(m_mutex);
#endif #endif
if( m_map.find(key) == m_map.end() ){ // not present, add it if ( m_map.find(key) == m_map.end() ) { // not present, add it
m_map[key] = value; m_map[key] = value;
return true; return true;
}else{ // item is already in, oops } else { // item is already in, oops
return false; return false;
} }
} // Lock is automatically released here } // Lock is automatically released here
/** /**
* Remove value from the map. * Remove value from the map.
* @param key The Map key to remove * @param key The Map key to remove
* @return false if key was not present * @return false if key was not present
* *
*/ */
bool remove(const Tkey& key, Tvalue& value) bool remove(const Tkey& key, Tvalue& value)
{ {

View File

@ -3,7 +3,7 @@
*/ */
#ifndef __SYNCHRONIZED_QUEUE_HPP__ #ifndef __SYNCHRONIZED_QUEUE_HPP__
#define __SYNCHRONIZED_QUEUE_HPP__ #define __SYNCHRONIZED_QUEUE_HPP__
#include <queue> #include <queue>
@ -32,7 +32,7 @@ public:
#ifndef __puma #ifndef __puma
boost::unique_lock<boost::mutex> lock(m_mutex); boost::unique_lock<boost::mutex> lock(m_mutex);
#endif #endif
return m_queue.size(); return m_queue.size();
} }
// Add data to the queue and notify others // Add data to the queue and notify others
void Enqueue(const T& data) void Enqueue(const T& data)
@ -95,7 +95,7 @@ public:
* Get data from the queue. Non blocking variant. * Get data from the queue. Non blocking variant.
* @param d Pointer to copy queue element to * @param d Pointer to copy queue element to
* @return false if no element in queue * @return false if no element in queue
* *
*/ */
bool Dequeue_nb(T& d) bool Dequeue_nb(T& d)
{ {

View File

@ -18,7 +18,7 @@ std::string WallclockTimer::getRuntimeAsString() const
{ {
std::stringstream result; std::stringstream result;
result << getRuntimeAsDouble(); result << getRuntimeAsDouble();
return result.str().c_str(); return result.str().c_str();
} }
@ -26,7 +26,7 @@ double WallclockTimer::getRuntimeAsDouble() const
{ {
double result; double result;
struct timeval current; struct timeval current;
if (m_IsRunning) { if (m_IsRunning) {
gettimeofday(&current, NULL); gettimeofday(&current, NULL);
result = current.tv_sec - m_Start.tv_sec; result = current.tv_sec - m_Start.tv_sec;
@ -35,7 +35,7 @@ double WallclockTimer::getRuntimeAsDouble() const
result = m_End.tv_sec - m_Start.tv_sec; result = m_End.tv_sec - m_Start.tv_sec;
result = result + (((double)m_End.tv_usec-m_Start.tv_usec)/1000000); result = result + (((double)m_End.tv_usec-m_Start.tv_usec)/1000000);
} }
return result; return result;
} }
@ -44,7 +44,7 @@ void WallclockTimer::stopTimer()
if (m_IsRunning) { if (m_IsRunning) {
m_IsRunning = false; m_IsRunning = false;
gettimeofday(&m_End, NULL); gettimeofday(&m_End, NULL);
} }
} }
void WallclockTimer::reset() void WallclockTimer::reset()

View File

@ -1,12 +1,12 @@
/** /**
* \brief The WallclockTimer measures the elapsed time * \brief The WallclockTimer measures the elapsed time
* *
* The WallclockTimer measures the time which is elapsed between start * The WallclockTimer measures the time which is elapsed between start
* and stop of the timer. * and stop of the timer.
*/ */
#ifndef __WALLCLOCKTIMER_HPP__ #ifndef __WALLCLOCKTIMER_HPP__
#define __WALLCLOCKTIMER_HPP__ #define __WALLCLOCKTIMER_HPP__
#include <string> #include <string>
#include <stdlib.h> #include <stdlib.h>
@ -16,7 +16,7 @@ namespace fail {
/** /**
* \class WallclockTimer * \class WallclockTimer
* *
* The class WallclockTimer contains all functions for start, * The class WallclockTimer contains all functions for start,
* stop, reset and to get the elapsed time. * stop, reset and to get the elapsed time.
*/ */

View File

@ -6,7 +6,7 @@ using namespace llvm::object;
LLVMtoFailTranslator & LLVMDisassembler::getTranslator() { LLVMtoFailTranslator & LLVMDisassembler::getTranslator() {
if ( ltofail == 0 ){ if ( ltofail == 0 ) {
std::cout << "ArchType: " << llvm::Triple::getArchTypeName( llvm::Triple::ArchType(object->getArch()) ) << std::endl; std::cout << "ArchType: " << llvm::Triple::getArchTypeName( llvm::Triple::ArchType(object->getArch()) ) << std::endl;
switch ( llvm::Triple::ArchType(object->getArch()) ) { switch ( llvm::Triple::ArchType(object->getArch()) ) {

View File

@ -5,7 +5,7 @@ using namespace fail;
const LLVMtoFailTranslator::reginfo_t & LLVMtoFailTranslator::getFailRegisterID(unsigned int regid) { const LLVMtoFailTranslator::reginfo_t & LLVMtoFailTranslator::getFailRegisterID(unsigned int regid) {
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 " << std::dec << regid << " not found :(" << std::endl; std::cout << "Fail ID for LLVM Register id " << std::dec << regid << " not found :(" << std::endl;

View File

@ -1,6 +1,6 @@
#ifndef __ABO_SIMPLE_ARM_EXPERIMENT_HPP__ #ifndef __ABO_SIMPLE_ARM_EXPERIMENT_HPP__
#define __ABO_SIMPLE_ARM_EXPERIMENT_HPP__ #define __ABO_SIMPLE_ARM_EXPERIMENT_HPP__
#include "efw/ExperimentFlow.hpp" #include "efw/ExperimentFlow.hpp"
#include "efw/JobClient.hpp" #include "efw/JobClient.hpp"

View File

@ -1,5 +1,5 @@
#ifndef __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__ #ifndef __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__
#define __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__ #define __CHECKSUM_OOSTUBS_CAMPAIGN_HPP__
#include "cpn/Campaign.hpp" #include "cpn/Campaign.hpp"
#include "comm/ExperimentData.hpp" #include "comm/ExperimentData.hpp"

View File

@ -36,7 +36,7 @@ bool ChecksumOOStuBSExperiment::run()
char const *statename = "checksum-oostubs.state"; char const *statename = "checksum-oostubs.state";
Logger log("Checksum-OOStuBS", false); Logger log("Checksum-OOStuBS", false);
BPSingleListener bp; BPSingleListener bp;
log << "startup" << endl; log << "startup" << endl;
#if 0 #if 0
@ -107,7 +107,7 @@ bool ChecksumOOStuBSExperiment::run()
} }
log << dec << "tracing finished after " << instr_counter << endl; log << dec << "tracing finished after " << instr_counter << endl;
uint32_t results[OOSTUBS_RESULTS_BYTES / sizeof(uint32_t)]; uint32_t results[OOSTUBS_RESULTS_BYTES / sizeof(uint32_t)];
simulator.getMemoryManager().getBytes(OOSTUBS_RESULTS_ADDR, sizeof(results), results); simulator.getMemoryManager().getBytes(OOSTUBS_RESULTS_ADDR, sizeof(results), results);
for (unsigned i = 0; i < sizeof(results) / sizeof(*results); ++i) { for (unsigned i = 0; i < sizeof(results) / sizeof(*results); ++i) {
@ -124,7 +124,7 @@ bool ChecksumOOStuBSExperiment::run()
} }
of.close(); of.close();
log << "trace written to " << tracefile << endl; log << "trace written to " << tracefile << endl;
#elif 1 #elif 1
// STEP 3: The actual experiment. // STEP 3: The actual experiment.
#if !LOCAL #if !LOCAL

View File

@ -1,6 +1,6 @@
#ifndef __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__ #ifndef __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__
#define __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__ #define __CHECKSUM_OOSTUBS_EXPERIMENT_HPP__
#include "efw/ExperimentFlow.hpp" #include "efw/ExperimentFlow.hpp"
#include "efw/JobClient.hpp" #include "efw/JobClient.hpp"

View File

@ -1,5 +1,5 @@
#ifndef __EXPERIMENT_INFO_HPP__ #ifndef __EXPERIMENT_INFO_HPP__
#define __EXPERIMENT_INFO_HPP__ #define __EXPERIMENT_INFO_HPP__
// FIXME autogenerate this // FIXME autogenerate this

View File

@ -52,7 +52,7 @@ bool CoolChecksumCampaign::run()
CoolChecksumExperimentData *d = new CoolChecksumExperimentData; CoolChecksumExperimentData *d = new CoolChecksumExperimentData;
d->msg.set_instr_offset(instr_offset); d->msg.set_instr_offset(instr_offset);
d->msg.set_bit_offset(bit_offset); d->msg.set_bit_offset(bit_offset);
campaignmanager.addParam(d); campaignmanager.addParam(d);
++count; ++count;
} }
@ -107,8 +107,8 @@ bool CoolChecksumCampaign::run()
address_t instr_absolute = 0; // FIXME this one probably should also be recorded ... address_t instr_absolute = 0; // FIXME this one probably should also be recorded ...
Trace_Event ev; Trace_Event ev;
ps.reset(); ps.reset();
while(ps.getNext(&ev)) { while (ps.getNext(&ev)) {
// only count instruction events // only count instruction events
if (!ev.has_memaddr()) { if (!ev.has_memaddr()) {
// new instruction // new instruction
@ -131,7 +131,7 @@ bool CoolChecksumCampaign::run()
// we now have an interval-terminating R/W // we now have an interval-terminating R/W
// event to the memaddr we're currently looking // event to the memaddr we're currently looking
// at: // at:
// complete the equivalence interval // complete the equivalence interval
current_ec.instr2 = instr; current_ec.instr2 = instr;
current_ec.instr2_absolute = instr_absolute; current_ec.instr2_absolute = instr_absolute;
@ -150,7 +150,7 @@ bool CoolChecksumCampaign::run()
} else { } else {
log << "WAT" << endl; log << "WAT" << endl;
} }
// next interval must start at next // next interval must start at next
// instruction; the aforementioned // instruction; the aforementioned
// skipping mechanism wouldn't work // skipping mechanism wouldn't work

View File

@ -1,5 +1,5 @@
#ifndef __COOLCAMPAIGN_HPP__ #ifndef __COOLCAMPAIGN_HPP__
#define __COOLCAMPAIGN_HPP__ #define __COOLCAMPAIGN_HPP__
#include "cpn/Campaign.hpp" #include "cpn/Campaign.hpp"
#include "comm/ExperimentData.hpp" #include "comm/ExperimentData.hpp"

View File

@ -30,7 +30,7 @@ bool CoolChecksumExperiment::run()
{ {
Logger log("CoolChecksum", false); Logger log("CoolChecksum", false);
BPSingleListener bp; BPSingleListener bp;
log << "startup" << endl; log << "startup" << endl;
#if 1 #if 1

View File

@ -1,6 +1,6 @@
#ifndef __COOLEXPERIMENT_HPP__ #ifndef __COOLEXPERIMENT_HPP__
#define __COOLEXPERIMENT_HPP__ #define __COOLEXPERIMENT_HPP__
#include "efw/ExperimentFlow.hpp" #include "efw/ExperimentFlow.hpp"
#include "efw/JobClient.hpp" #include "efw/JobClient.hpp"

View File

@ -1,5 +1,5 @@
#ifndef __EXPERIMENT_INFO_HPP__ #ifndef __EXPERIMENT_INFO_HPP__
#define __EXPERIMENT_INFO_HPP__ #define __EXPERIMENT_INFO_HPP__
#define COOL_FAULTSPACE_PRUNING 0 #define COOL_FAULTSPACE_PRUNING 0

Some files were not shown because too many files have changed in this diff Show More