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__
#define __EXPERIMENT_DATA_HPP__
#define __EXPERIMENT_DATA_HPP__
#include <string>
#include <google/protobuf/message.h>

View File

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

View File

@ -3,7 +3,7 @@
*/
#ifndef __SOCKET_COMM_HPP__
#define __SOCKET_COMM_HPP__
#define __SOCKET_COMM_HPP__
#include <stdio.h>
#include <unistd.h>
@ -56,11 +56,11 @@ public:
static int timedAccept(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int timeout);
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_read(int fd, void *buf, size_t count);
};
} // end-of-namespace: fail
#endif // __SOCKET_COMM_HPP__

View File

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

View File

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

View File

@ -4,7 +4,7 @@
*/
#ifndef __CAMPAIGN_MANAGER_HPP__
#define __CAMPAIGN_MANAGER_HPP__
#define __CAMPAIGN_MANAGER_HPP__
#include "sal/SALInst.hpp"
#include "comm/ExperimentData.hpp"
@ -16,7 +16,7 @@ namespace fail {
/**
* \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.
*/
class CampaignManager {
@ -30,12 +30,12 @@ public:
* Executes a user campaign
*/
bool runCampaign(Campaign* c)
{
{
if (!m_jobserver) {
m_jobserver = new JobServer;
}
m_currentCampaign = c;
bool ret = c->run();
bool ret = c->run();
m_jobserver->done();
return ret;
}
@ -43,7 +43,7 @@ public:
* Returns a const reference for acquiring constant simulator specific information.
* e.g., Registernames, to ease experiment data construction.
* 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.
*/
SimulatorController const& getSimulator() const { return simulator; }

View File

@ -29,13 +29,13 @@ bool DatabaseCampaign::run() {
if (!cb_commandline_init()) return false;
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,
"-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,
"-p/--prune-method \tWhich import method to use (default: basic)");
if(!cmd.parse()) {
if (!cmd.parse()) {
log_send << "Error parsing arguments." << std::endl;
exit(-1);
}
@ -82,7 +82,7 @@ bool DatabaseCampaign::run() {
std::vector<Database::Variant> variants = db->get_variants(variant, benchmark);
for (std::vector<Database::Variant>::const_iterator it = variants.begin();
it != variants.end(); ++it) {
if(!run_variant(*it)) {
if (!run_variant(*it)) {
log_send << "run_variant failed for " << it->variant << "/" << it->benchmark <<std::endl;
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());
log_send << "Found " << experiment_count << " unfinished experiments in database. ("
log_send << "Found " << experiment_count << " unfinished experiments in database. ("
<< variant.variant << "/" << variant.benchmark << ")" << std::endl;
sent_pilots = 0;

View File

@ -61,7 +61,7 @@ public:
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;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
#ifndef __LISTENER_HPP__
#define __LISTENER_HPP__
#define __LISTENER_HPP__
#include <string>
#include <cassert>
@ -205,12 +205,12 @@ public:
};
#if defined CONFIG_EVENT_BREAKPOINTS
#define BP_CTOR_SCOPE public
#define BP_CTOR_SCOPE public
#else
#define BP_CTOR_SCOPE protected
// This prevents an experiment from instantiating an object of BPSingleListener
// without having enabled the appropriate configuration flag, i.e.,
// CONFIG_EVENT_BREAKPOINTS = ON.
#define BP_CTOR_SCOPE protected
// This prevents an experiment from instantiating an object of BPSingleListener
// without having enabled the appropriate configuration flag, i.e.,
// CONFIG_EVENT_BREAKPOINTS = ON.
#endif
/**
* \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
#define BPRANGE_CTOR_SCOPE public
#define BPRANGE_CTOR_SCOPE public
#else
#define BPRANGE_CTOR_SCOPE protected
#define BPRANGE_CTOR_SCOPE protected
#endif
/**
* \class BPRangeListener
@ -300,12 +300,12 @@ public:
};
#if defined CONFIG_EVENT_MEMREAD || defined CONFIG_EVENT_MEMWRITE
#define WP_CTOR_SCOPE public
#define WP_CTOR_SCOPE public
#else
#define WP_CTOR_SCOPE protected
// 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).
// Clearly, MemAccessListener is *not* a leaf class.
#define WP_CTOR_SCOPE protected
// 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).
// Clearly, MemAccessListener is *not* a leaf class.
#endif
/**
* \class MemAccessListener
@ -413,9 +413,9 @@ public:
};
#ifdef CONFIG_EVENT_MEMREAD
#define WPREAD_CTOR_SCOPE public
#define WPREAD_CTOR_SCOPE public
#else
#define WPREAD_CTOR_SCOPE protected
#define WPREAD_CTOR_SCOPE protected
#endif
/**
* \class MemReadListener
@ -430,9 +430,9 @@ WPREAD_CTOR_SCOPE:
};
#ifdef CONFIG_EVENT_MEMWRITE
#define WPWRITE_CTOR_SCOPE public
#define WPWRITE_CTOR_SCOPE public
#else
#define WPWRITE_CTOR_SCOPE protected
#define WPWRITE_CTOR_SCOPE protected
#endif
/**
* \class MemWriteListener
@ -447,9 +447,9 @@ WPWRITE_CTOR_SCOPE:
};
#if defined CONFIG_EVENT_INTERRUPT || defined CONFIG_EVENT_TRAP
#define TROUBLE_CTOR_SCOPE public
#define TROUBLE_CTOR_SCOPE public
#else
#define TROUBLE_CTOR_SCOPE protected
#define TROUBLE_CTOR_SCOPE protected
#endif
/**
* \class TroubleListener
@ -513,9 +513,9 @@ public:
};
#ifdef CONFIG_EVENT_INTERRUPT
#define INT_CTOR_SCOPE public
#define INT_CTOR_SCOPE public
#else
#define INT_CTOR_SCOPE protected
#define INT_CTOR_SCOPE protected
#endif
/**
* \class InterruptListener
@ -540,9 +540,9 @@ public:
};
#ifdef CONFIG_EVENT_TRAP
#define TRAP_CTOR_SCOPE public
#define TRAP_CTOR_SCOPE public
#else
#define TRAP_CTOR_SCOPE protected
#define TRAP_CTOR_SCOPE protected
#endif
/**
* \class TrapListener
@ -556,9 +556,9 @@ TRAP_CTOR_SCOPE:
};
#ifdef CONFIG_EVENT_GUESTSYS
#define GUESTSYS_CTOR_SCOPE public
#define GUESTSYS_CTOR_SCOPE public
#else
#define GUESTSYS_CTOR_SCOPE protected
#define GUESTSYS_CTOR_SCOPE protected
#endif
/**
* \class GuestListener
@ -592,9 +592,9 @@ public:
};
#ifdef CONFIG_EVENT_IOPORT
#define IOPORT_CTOR_SCOPE public
#define IOPORT_CTOR_SCOPE public
#else
#define IOPORT_CTOR_SCOPE protected
#define IOPORT_CTOR_SCOPE protected
#endif
/**
* \class IOPortListener
@ -661,9 +661,9 @@ public:
};
#ifdef CONFIG_EVENT_JUMP
#define JUMP_CTOR_SCOPE public
#define JUMP_CTOR_SCOPE public
#else
#define JUMP_CTOR_SCOPE protected
#define JUMP_CTOR_SCOPE protected
#endif
/**
* \class JumpListener

View File

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

View File

@ -1,5 +1,5 @@
#ifndef __LISTENER_MANAGER_HPP__
#define __LISTENER_MANAGER_HPP__
#define __LISTENER_MANAGER_HPP__
#include <cassert>
#include <list>
@ -184,7 +184,7 @@ public:
* regarding their location and performance-buffer reference, i.e. their index and
* performance-buffer pointer will be invalidated (by setting \c INVALID_INDEX and
* \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
* \c pLi->getPerformanceBuffer(). If the performance buffer-list ptr is
* \c NULL, nothing will be done.

View File

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

View File

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

View File

@ -1,5 +1,5 @@
#ifndef __REGISTER_HPP__
#define __REGISTER_HPP__
#define __REGISTER_HPP__
#include <vector>
#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 timer_id_t INVALID_TIMER = static_cast<timer_id_t> (0);
#else
#error SAL Config Target not defined
#error SAL Config Target not defined
#endif
} // end-of-namespace: fail

View File

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

View File

@ -1,5 +1,5 @@
#ifndef __SAL_INSTANCE_HPP__
#define __SAL_INSTANCE_HPP__
#define __SAL_INSTANCE_HPP__
#include "SALConfig.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,
bool is_write, address_t instrPtr)
bool is_write, address_t instrPtr)
{
MemAccessEvent::access_type_t accesstype =
is_write ? MemAccessEvent::MEM_WRITE
@ -114,7 +114,7 @@ void SimulatorController::onInterrupt(ConcreteCPU* cpu, unsigned interruptNum, b
{
ListenerManager::iterator it = m_LstList.begin();
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;
InterruptListener* pie = dynamic_cast<InterruptListener*>(pev);
if (!pie || !pie->isMatching(&tmp)) {

View File

@ -1,5 +1,5 @@
#ifndef __SIMULATOR_CONTROLLER_HPP__
#define __SIMULATOR_CONTROLLER_HPP__
#define __SIMULATOR_CONTROLLER_HPP__
#include <iostream>
#include <string>
@ -83,7 +83,7 @@ public:
* @param is_write \c true if memory is written, \c false if read
* @param instrPtr the address of the instruction causing the memory
* access
*
*
* FIXME: should instrPtr be part of this interface?
*/
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__
#define __ARM_ARCHITECURE_HPP__
#define __ARM_ARCHITECURE_HPP__
#include "../CPU.hpp"
#include "../CPUState.hpp"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@
*/
#ifndef __BOCHS_CONFIG_HPP__
#define __BOCHS_CONFIG_HPP__
#define __BOCHS_CONFIG_HPP__
#include "bochs.h"
#include "config.h"
@ -15,15 +15,15 @@ namespace fail {
typedef bx_address guest_address_t; //!< the guest memory address type
typedef Bit8u* host_address_t; //!< the host memory address type
#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
typedef Bit32u register_data_t; //!< register data type (32 bit)
typedef Bit32u register_data_t; //!< register data type (32 bit)
#endif
typedef int timer_t; //!< type of timer IDs
// 'Publish' 64 bit ability (if enabled in Bochs):
#if BX_SUPPORT_X86_64
#define SIM_SUPPORT_64
#define SIM_SUPPORT_64
#endif
} // 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)
{
int stat;
stat = mkdir(path.c_str(), 0777);
if (!(stat == 0 || errno == EEXIST)) {
return false;
// 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?
}
save_bochs_request = true;
BX_CPU(0)->async_event |= 1;
sr_path = path;
@ -164,12 +164,12 @@ const std::string& BochsController::getMnemonic() const
ConcreteCPU& BochsController::detectCPU(BX_CPU_C* pCPU) const
{
unsigned i = 0;
#if BX_SUPPORT_SMP
#if BX_SUPPORT_SMP
for (; i < BX_SMP_PROCESSORS; i++) {
if (BX_CPU_C[i] == pCPU) // cmp this ptr with all possible CPU objects
break; // index "i" found! -> stop!
}
#endif
#endif
return getCPU(i);
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
#ifndef __GEM5_CONTROLLER_HPP__
#define __GEM5_CONTROLLER_HPP__
#define __GEM5_CONTROLLER_HPP__
#include <string>
@ -42,7 +42,7 @@ public:
virtual simtime_t getTimerTicksPerSecond();
#if defined(CONFIG_EVENT_BREAKPOINTS) ||\
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; }
#endif
};

View File

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

View File

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

View File

@ -10,7 +10,7 @@ ResultSet& PerfVectorBreakpoints::gather(BPEvent* pData)
static ResultSet res;
res.clear(); // FIXME: This should not free the memory of the underlying std::vector.
// 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));
if (pLi->isMatching(pData)) {
// Update trigger IPtr:

View File

@ -1,9 +1,9 @@
#ifndef __BREAKPOINT_BUFFER_HPP__
#define __BREAKPOINT_BUFFER_HPP__
#define __BREAKPOINT_BUFFER_HPP__
#include "BufferInterface.hpp"
// TODOs:
// TODOs:
// - Make these implementations even faster (see below: continue PerfVecSortedSingleBP).
namespace fail {
@ -20,7 +20,7 @@ public:
/**
* \class PerfVecSortedSingleBP
*
*
* This class implements a faster mechanism to store BPSingleListener
* 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)
{
SimulatorController* pSim = static_cast<SimulatorController*>(pStuff);
@ -80,9 +80,9 @@ public:
while (first <= last) {
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.
else if (VAL(key) < VAL(vec[mid]))
else if (VAL(key) < VAL(vec[mid]))
last = mid - 1; // repeat search in bottom half.
else
return mid; // found it. return position
@ -100,7 +100,7 @@ public:
// TODO: Improve this by using binary search, too!
ResultSet res;
// 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));
if (pLi->isMatching(pData)) {
// Update trigger IPtr:

View File

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

View File

@ -11,7 +11,7 @@ ResultSet& PerfVectorWatchpoints::gather(MemAccessEvent* pData)
static ResultSet res;
res.clear(); // FIXME: This should not free the memory of the underlying std::vector.
// 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));
if (pmal->isMatching(pData)) {
// Update trigger data:

View File

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

View File

@ -5,7 +5,7 @@
*/
#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)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
#ifndef __X86_ARCHITECTURE_HPP__
#define __X86_ARCHITECTURE_HPP__
#define __X86_ARCHITECTURE_HPP__
#include "../CPU.hpp"
#include "../CPUState.hpp"
@ -35,8 +35,8 @@ enum GPRegisterId {
#else // 32 bit register id's:
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):
RID_CAX = 0, RID_CCX, RID_CDX, RID_CBX, RID_CSP, RID_CBP, RID_CSI, RID_CDI,
RID_LAST_GP_ID
RID_CAX = 0, RID_CCX, RID_CDX, RID_CBX, RID_CSP, RID_CBP, RID_CSI, RID_CDI,
RID_LAST_GP_ID
};
/**

View File

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

View File

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

View File

@ -17,93 +17,94 @@
#pragma GCC diagnostic pop
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;
option::Option *parsed_options, *parsed_buffer;
option::Parser *m_parser;
public:
/// Handle for accessing the parsed data of an option
typedef int option_handle;
/**
* @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;
/**
* Singleton accessor
*
* @return reference to the CommandLine singleton object
*/
static CommandLine &Inst() { return m_instance; }
std::vector<const char *> argv;
std::vector<option::Descriptor> options;
option::Option *parsed_options, *parsed_buffer;
option::Parser *m_parser;
public:
/// Handle for accessing the parsed data of an option
typedef int option_handle;
/**
* Called by the simulator to filter all fail arguments from
* argc, argv
*/
void collect_args(argument_count &, argument_value &);
/**
* Singleton accessor
*
* @return reference to the CommandLine singleton object
*/
static CommandLine &Inst() { return m_instance; }
/**
* Add a argument manually
*/
void add_args(const char *value) { argv.push_back(value); }
/**
* Called by the simulator to filter all fail arguments from
* argc, argv
*/
void collect_args(argument_count &, argument_value &);
/**
* Add a option to the command line interface of the fail-client
*
* @param shortopt e.g "m" for -m
* @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 argument manually
*/
void add_args(const char *value) { argv.push_back(value); }
/**
*
* do the actual parsing, called by the experiment
*
* @return true on success
*/
bool parse();
/**
* Add a option to the command line interface of the fail-client
*
* @param shortopt e.g "m" for -m
* @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);
/**
* Accessor for the command line option objects
*
* @param handle option handle
*
* @return reference to the option parser object
*/
option::Option &operator[](option_handle handle) {
assert(parsed_options != 0);
assert(handle >= 0 && handle < (int)options.size());
return parsed_options[handle];
}
/**
* Print help message.
*/
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;
}
};
/**
*
* do the actual parsing, called by the experiment
*
* @return true on success
*/
bool parse();
/**
* Accessor for the command line option objects
*
* @param handle option handle
*
* @return reference to the option parser object
*/
option::Option &operator[](option_handle handle) {
assert(parsed_options != 0);
assert(handle >= 0 && handle < (int)options.size());
return parsed_options[handle];
}
/**
* Print help message.
*/
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

View File

@ -6,15 +6,15 @@
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){
const char* res = cplus_demangle(name.c_str(), 0);
if(res != NULL){
return std::string(res);
}else{
return Demangler::DEMANGLE_FAILED;
}
}
std::string Demangler::demangle(const std::string& name){
const char* res = cplus_demangle(name.c_str(), 0);
if (res != NULL) {
return std::string(res);
} else {
return Demangler::DEMANGLE_FAILED;
}
}
} // end of namespace

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
#ifndef __MEMORYMAP_HPP__
#define __MEMORYMAP_HPP__
#define __MEMORYMAP_HPP__
#ifdef BOOST_1_46_OR_NEWER
#include <boost/icl/interval_set.hpp>
@ -47,7 +47,7 @@ public:
}
/**
* 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)
{

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -5,7 +5,7 @@ using namespace fail;
const LLVMtoFailTranslator::reginfo_t & LLVMtoFailTranslator::getFailRegisterID(unsigned int 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;
} else { // not found
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__
#define __ABO_SIMPLE_ARM_EXPERIMENT_HPP__
#define __ABO_SIMPLE_ARM_EXPERIMENT_HPP__
#include "efw/ExperimentFlow.hpp"
#include "efw/JobClient.hpp"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

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