import-trace: limit to general-purpose registers
This change limits fault injection to general-purpose registers, instead of relying on the LLVM/Fail* bridge to only recognize the status register (EFLAGS on x86) and general-purpose registers. Since this bridge just learned to translate x86's control and segment registers, and these registers need special handling for fault injection (def/use pruning does not work here), only import register accesses from the RT_GP subset. Status register and instruction pointer injection remain functional, and import-trace now should work architecture independently. Change-Id: Id8ad2f0a9dab1861bf16ea9443c3bdfe7213d3fa
This commit is contained in:
@ -107,6 +107,27 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
|
||||
do_ip = cmd[IP];
|
||||
do_split_registers = !cmd[NO_SPLIT];
|
||||
|
||||
// retrieve register IDs for general-purpose and flags register(s) for
|
||||
// the configured architecture
|
||||
fail::Architecture arch;
|
||||
m_ip_register_id =
|
||||
(*arch.getRegisterSetOfType(RT_IP)->begin())->getId();
|
||||
fail::UniformRegisterSet *regset;
|
||||
if (do_gp) {
|
||||
regset = arch.getRegisterSetOfType(RT_GP);
|
||||
for (fail::UniformRegisterSet::iterator it = regset->begin();
|
||||
it != regset->end(); ++it) {
|
||||
m_register_ids.insert((*it)->getId());
|
||||
}
|
||||
}
|
||||
if (do_flags) {
|
||||
regset = arch.getRegisterSetOfType(RT_ST);
|
||||
for (fail::UniformRegisterSet::iterator it = regset->begin();
|
||||
it != regset->end(); ++it) {
|
||||
m_register_ids.insert((*it)->getId());
|
||||
}
|
||||
}
|
||||
|
||||
/* Disassemble the binary if necessary */
|
||||
llvm::InitializeAllTargetInfos();
|
||||
llvm::InitializeAllTargetMCs();
|
||||
@ -147,12 +168,10 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if not tracing flags, but flags register -> ignore it
|
||||
if not tracing gp, but ! flags -> ignore it*/
|
||||
if (info.id == RID_FLAGS && !do_flags)
|
||||
continue;
|
||||
else if (!do_gp)
|
||||
/* only proceed if we want to inject into this register */
|
||||
if (m_register_ids.find(info.id) == m_register_ids.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!addRegisterTrace(curtime, instr, ev, info, 'R')) {
|
||||
return false;
|
||||
@ -169,18 +188,16 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
|
||||
continue;
|
||||
}
|
||||
|
||||
/* if not tracing flags, but flags register -> ignore it
|
||||
if not tracing gp, but ! flags -> ignore it*/
|
||||
if (info.id == RID_FLAGS && !do_flags)
|
||||
continue;
|
||||
else if (!do_gp)
|
||||
/* only proceed if we want to inject into this register */
|
||||
if (m_register_ids.find(info.id) == m_register_ids.end()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!addRegisterTrace(curtime, instr, ev, info, 'W'))
|
||||
return false;
|
||||
}
|
||||
|
||||
const LLVMtoFailTranslator::reginfo_t info_pc(RID_PC);
|
||||
const LLVMtoFailTranslator::reginfo_t info_pc(m_ip_register_id);
|
||||
if (do_ip) {
|
||||
if (!addRegisterTrace(curtime, instr, ev, info_pc, 'R'))
|
||||
return false;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#ifndef __REGISTER_IMPORTER_H__
|
||||
#define __REGISTER_IMPORTER_H__
|
||||
|
||||
|
||||
#include <set>
|
||||
#include "util/CommandLine.hpp"
|
||||
#include "Importer.hpp"
|
||||
|
||||
@ -20,6 +20,9 @@ class RegisterImporter : public Importer {
|
||||
fail::CommandLine::option_handle NO_GP, FLAGS, IP, NO_SPLIT;
|
||||
bool do_gp, do_flags, do_ip, do_split_registers;
|
||||
|
||||
std::set<unsigned> m_register_ids;
|
||||
unsigned m_ip_register_id;
|
||||
|
||||
public:
|
||||
RegisterImporter() : Importer(), do_gp(true), do_flags(false), do_ip(false),
|
||||
do_split_registers(true) {}
|
||||
|
||||
Reference in New Issue
Block a user