This was never a real problem, but keeps us on the safe side. Found by Coverity Scan, CID 25731/25808/25817. Change-Id: Ie4bd9fb52ff6140ce7ae024738b43c82f6f5045c
66 lines
2.4 KiB
C++
66 lines
2.4 KiB
C++
#ifndef __ADVANCED_MEMORY_IMPORTER_H__
|
|
#define __ADVANCED_MEMORY_IMPORTER_H__
|
|
|
|
#include <vector>
|
|
#include <deque>
|
|
#include "MemoryImporter.hpp"
|
|
|
|
#include "util/llvmdisassembler/LLVMDisassembler.hpp"
|
|
|
|
/**
|
|
* A MemoryImporter that additionally imports Relyzer-style conditional branch
|
|
* history, instruction opcodes, and a virtual duration = time2 - time1 + 1
|
|
* column (MariaDB 5.2+ only!) for fault-space pruning purposes.
|
|
*
|
|
* Initially this was implemented by directly passing through trace events to
|
|
* the MemoryImporter, keeping a record of conditional jumps and opcodes, and
|
|
* UPDATEing all inserted rows in a second pass when the MemoryImporter is
|
|
* finished.
|
|
*
|
|
* Unfortunately, UPDATE is very slow, and keeping all information in memory
|
|
* till the end doesn't scale indefinitely. Therefore the implementation now
|
|
* delays passing memory access events upwards to the MemoryImporter only until
|
|
* enough branch history is aggregated, and taps into Importer's database
|
|
* operations with a set of new virtual functions that are called downwards.
|
|
*/
|
|
class AdvancedMemoryImporter : public MemoryImporter {
|
|
llvm::OwningPtr<llvm::object::Binary> binary;
|
|
llvm::OwningPtr<fail::LLVMDisassembler> disas;
|
|
bool m_last_was_conditional_branch;
|
|
fail::guest_address_t m_ip_jump_not_taken;
|
|
std::vector<bool> branches_taken;
|
|
struct DelayedTraceEntry {
|
|
fail::simtime_t curtime;
|
|
instruction_count_t instr;
|
|
Trace_Event ev;
|
|
unsigned opcode;
|
|
unsigned branches_before;
|
|
};
|
|
std::deque<DelayedTraceEntry> delayed_entries;
|
|
static const unsigned BRANCH_WINDOW_SIZE = 16; //!< increasing this requires changing the underlying data types
|
|
|
|
unsigned m_cur_branchmask;
|
|
|
|
void insert_delayed_entries(bool finalizing);
|
|
|
|
public:
|
|
AdvancedMemoryImporter() : m_last_was_conditional_branch(false),
|
|
m_ip_jump_not_taken(0), m_cur_branchmask(0) {}
|
|
|
|
protected:
|
|
virtual std::string database_additional_columns();
|
|
virtual void database_insert_columns(std::string& sql, unsigned& num_columns);
|
|
virtual bool database_insert_data(Trace_Event &ev, std::stringstream& value_sql, unsigned num_columns, bool is_fake);
|
|
virtual bool handle_ip_event(fail::simtime_t curtime, instruction_count_t instr,
|
|
Trace_Event &ev);
|
|
virtual bool handle_mem_event(fail::simtime_t curtime, instruction_count_t instr,
|
|
Trace_Event &ev);
|
|
virtual bool trace_end_reached();
|
|
|
|
void getAliases(std::deque<std::string> *aliases) {
|
|
aliases->push_back("AdvancedMemoryImporter");
|
|
}
|
|
};
|
|
|
|
#endif
|