Merge branch 'register-mapping-fixes'
This commit is contained in:
@ -18,12 +18,12 @@ LLVMtoFailBochs::LLVMtoFailBochs() {
|
|||||||
llvm_to_fail_map[45] = reginfo_t(RID_CBX, 32, 0); // EBX
|
llvm_to_fail_map[45] = reginfo_t(RID_CBX, 32, 0); // EBX
|
||||||
|
|
||||||
llvm_to_fail_map[9] = reginfo_t(RID_CCX, 8, 8); // CH
|
llvm_to_fail_map[9] = reginfo_t(RID_CCX, 8, 8); // CH
|
||||||
llvm_to_fail_map[10] = reginfo_t(RID_CCX, 0xff); // CL
|
llvm_to_fail_map[10] = reginfo_t(RID_CCX, 8, 0); // CL
|
||||||
llvm_to_fail_map[28] = reginfo_t(RID_CCX, 16, 0); // CX
|
llvm_to_fail_map[28] = reginfo_t(RID_CCX, 16, 0); // CX
|
||||||
llvm_to_fail_map[46] = reginfo_t(RID_CCX); // ECX
|
llvm_to_fail_map[46] = reginfo_t(RID_CCX); // ECX
|
||||||
|
|
||||||
llvm_to_fail_map[29] = reginfo_t(RID_CDX, 8, 8); // DH
|
llvm_to_fail_map[29] = reginfo_t(RID_CDX, 8, 8); // DH
|
||||||
llvm_to_fail_map[32] = reginfo_t(RID_CDX, 0xff); // DL
|
llvm_to_fail_map[32] = reginfo_t(RID_CDX, 8, 0); // DL
|
||||||
llvm_to_fail_map[42] = reginfo_t(RID_CDX, 16, 0); // DX
|
llvm_to_fail_map[42] = reginfo_t(RID_CDX, 16, 0); // DX
|
||||||
llvm_to_fail_map[48] = reginfo_t(RID_CDX); // EDX
|
llvm_to_fail_map[48] = reginfo_t(RID_CDX); // EDX
|
||||||
|
|
||||||
|
|||||||
@ -8,7 +8,7 @@ const LLVMtoFailTranslator::reginfo_t & LLVMtoFailTranslator::getFailRegisterID
|
|||||||
if( it != llvm_to_fail_map.end() ) {// found
|
if( it != llvm_to_fail_map.end() ) {// found
|
||||||
return (*it).second;
|
return (*it).second;
|
||||||
} else { // not found
|
} else { // not found
|
||||||
std::cout << "Fail ID for LLVM Register id " << regid << " not found :(" << std::endl;
|
std::cout << "Fail ID for LLVM Register id " << std::dec << regid << " not found :(" << std::endl;
|
||||||
//exit(EXIT_FAILURE);
|
//exit(EXIT_FAILURE);
|
||||||
return notfound;
|
return notfound;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,6 +13,12 @@ namespace fail {
|
|||||||
*/
|
*/
|
||||||
class LLVMtoFailTranslator {
|
class LLVMtoFailTranslator {
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Maps registers to/from linear addresses usable for def/use-pruning
|
||||||
|
* purposes and storage in the database. Takes care that the linear
|
||||||
|
* addresses of x86 subregisters (e.g., AX represents the lower 16 bits of
|
||||||
|
* EAX) overlap with their siblings.
|
||||||
|
*/
|
||||||
struct reginfo_t {
|
struct reginfo_t {
|
||||||
int id;
|
int id;
|
||||||
regwidth_t width;
|
regwidth_t width;
|
||||||
@ -20,18 +26,17 @@ public:
|
|||||||
byte_t offset;
|
byte_t offset;
|
||||||
|
|
||||||
int toDataAddress() const {
|
int toDataAddress() const {
|
||||||
// .. 5 4 | 7 6 5 4 | 3 2 1 0
|
// .. 5 4 | 3 2 1 0
|
||||||
// <reg> | <width> | <offset>
|
// <reg> | <offset>
|
||||||
return (id << 8) | ((width/8) << 4) | (offset / 8);
|
return (id << 4) | (offset / 8);
|
||||||
}
|
}
|
||||||
|
// does not recreate width or mask
|
||||||
static reginfo_t fromDataAddress(int addr) {
|
static reginfo_t fromDataAddress(int addr) {
|
||||||
int id = addr >> 8;
|
int id = addr >> 4;
|
||||||
regwidth_t width = ((addr >> 4) & 0xf) * 8;
|
byte_t offset = (addr & 0xf) * 8;
|
||||||
byte_t offset = (addr & 0xf) * 8;
|
return reginfo_t(id, 0, offset);
|
||||||
return reginfo_t(id, width, offset);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
reginfo_t(int id=-1, regwidth_t width = 32, byte_t offs = 0)
|
reginfo_t(int id=-1, regwidth_t width = 32, byte_t offs = 0)
|
||||||
: id(id), width(width), mask((regwidth_t)((((long long)1 << width) - 1) << offs)), offset(offs) {};
|
: id(id), width(width), mask((regwidth_t)((((long long)1 << width) - 1) << offs)), offset(offs) {};
|
||||||
};
|
};
|
||||||
@ -43,6 +48,12 @@ protected:
|
|||||||
ltof_map_t llvm_to_fail_map;
|
ltof_map_t llvm_to_fail_map;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* Translates a backend-specific register ID to a Fail register ID.
|
||||||
|
* @param regid A backend-specific register ID.
|
||||||
|
* @return A Fail* register ID, or LLVMtoFailTranslator::notfound if no
|
||||||
|
* mapping was found.
|
||||||
|
*/
|
||||||
const reginfo_t & getFailRegisterID(unsigned int regid);
|
const reginfo_t & getFailRegisterID(unsigned int regid);
|
||||||
|
|
||||||
regdata_t getRegisterContent(ConcreteCPU & cpu, const reginfo_t & reg);
|
regdata_t getRegisterContent(ConcreteCPU & cpu, const reginfo_t & reg);
|
||||||
@ -55,7 +66,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
int getFailRegisterId(unsigned int regid) { return this->getFailRegisterID(regid).id; };
|
int getFailRegisterId(unsigned int regid) { return this->getFailRegisterID(regid).id; };
|
||||||
private:
|
|
||||||
reginfo_t notfound;
|
reginfo_t notfound;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -32,9 +32,8 @@ bool RegisterImporter::addRegisterTrace(simtime_t curtime, instruction_count_t i
|
|||||||
const Trace_Event &ev,
|
const Trace_Event &ev,
|
||||||
const LLVMtoFailTranslator::reginfo_t &info,
|
const LLVMtoFailTranslator::reginfo_t &info,
|
||||||
char access_type) {
|
char access_type) {
|
||||||
LLVMtoFailTranslator::reginfo_t one_byte_window = info;
|
address_t from = info.toDataAddress();
|
||||||
one_byte_window.width = 8;
|
address_t to = from + info.width / 8;
|
||||||
address_t from = one_byte_window.toDataAddress(), to = one_byte_window.toDataAddress() + (info.width) / 8;
|
|
||||||
|
|
||||||
// Iterate over all accessed bytes
|
// Iterate over all accessed bytes
|
||||||
for (address_t data_address = from; data_address < to; ++data_address) {
|
for (address_t data_address = from; data_address < to; ++data_address) {
|
||||||
@ -130,6 +129,12 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
|
|||||||
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_uses.begin();
|
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_uses.begin();
|
||||||
it != opcode.reg_uses.end(); ++it) {
|
it != opcode.reg_uses.end(); ++it) {
|
||||||
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it);
|
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it);
|
||||||
|
if (&info == <of.notfound) {
|
||||||
|
LOG << "Could not find a mapping for LLVM input register #" << std::dec << *it
|
||||||
|
<< " at IP " << std::hex << ev.ip()
|
||||||
|
<< ", skipping" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* if not tracing flags, but flags register -> ignore it
|
/* if not tracing flags, but flags register -> ignore it
|
||||||
if not tracing gp, but ! flags -> ignore it*/
|
if not tracing gp, but ! flags -> ignore it*/
|
||||||
@ -146,6 +151,13 @@ bool RegisterImporter::handle_ip_event(fail::simtime_t curtime, instruction_coun
|
|||||||
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_defs.begin();
|
for (std::vector<LLVMDisassembler::register_t>::const_iterator it = opcode.reg_defs.begin();
|
||||||
it != opcode.reg_defs.end(); ++it) {
|
it != opcode.reg_defs.end(); ++it) {
|
||||||
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it);
|
const LLVMtoFailTranslator::reginfo_t &info = ltof.getFailRegisterID(*it);
|
||||||
|
if (&info == <of.notfound) {
|
||||||
|
LOG << "Could not find a mapping for LLVM output register #" << std::dec << *it
|
||||||
|
<< " at IP " << std::hex << ev.ip()
|
||||||
|
<< ", skipping" << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* if not tracing flags, but flags register -> ignore it
|
/* if not tracing flags, but flags register -> ignore it
|
||||||
if not tracing gp, but ! flags -> ignore it*/
|
if not tracing gp, but ! flags -> ignore it*/
|
||||||
if (info.id == RID_FLAGS && !do_flags)
|
if (info.id == RID_FLAGS && !do_flags)
|
||||||
|
|||||||
Reference in New Issue
Block a user