Merge "util/llvmdisassembler: map registers by names"

This commit is contained in:
Florian Lukas
2014-03-26 16:45:19 +01:00
committed by Gerrit Code Review
7 changed files with 111 additions and 57 deletions

View File

@ -12,10 +12,10 @@ LLVMtoFailTranslator & LLVMDisassembler::getTranslator() {
switch ( llvm::Triple::ArchType(object->getArch()) ) {
case llvm::Triple::x86:
case llvm::Triple::x86_64:
ltofail = new LLVMtoFailBochs;
ltofail = new LLVMtoFailBochs(this);
break;
case llvm::Triple::arm:
ltofail = new LLVMtoFailGem5;
ltofail = new LLVMtoFailGem5(this);
break;
default:
std::cout << " not supported :(";

View File

@ -1,48 +1,68 @@
#include "LLVMDisassembler.hpp"
#include "LLVMtoFailBochs.hpp"
#include "sal/x86/X86Architecture.hpp"
using namespace fail;
LLVMtoFailBochs::LLVMtoFailBochs() {
/* These magic numbers are taken from the llvm compiler (MC), they
do not appear in any header. They hopefully will never
change */
llvm_to_fail_map[1] = reginfo_t(RID_CAX, 8, 8) ; // AH
llvm_to_fail_map[2] = reginfo_t(RID_CAX, 8, 0); // AL
llvm_to_fail_map[3] = reginfo_t(RID_CAX, 16, 0); // AX
llvm_to_fail_map[43] = reginfo_t(RID_CAX, 32, 0); // EAX
LLVMtoFailBochs::LLVMtoFailBochs(LLVMDisassembler *disas) {
std::map<std::string, struct reginfo_t> reg_name_map;
llvm_to_fail_map[4] = reginfo_t(RID_CBX, 8, 8); // BH
llvm_to_fail_map[5] = reginfo_t(RID_CBX, 8, 0); // BL
llvm_to_fail_map[8] = reginfo_t(RID_CBX, 16, 0); // BX
llvm_to_fail_map[45] = reginfo_t(RID_CBX, 32, 0); // EBX
reg_name_map["AH"] = reginfo_t(RID_CAX, 8, 8);
reg_name_map["AL"] = reginfo_t(RID_CAX, 8, 0);
reg_name_map["AX"] = reginfo_t(RID_CAX, 16, 0);
reg_name_map["EAX"] = reginfo_t(RID_CAX, 32, 0);
llvm_to_fail_map[9] = reginfo_t(RID_CCX, 8, 8); // CH
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[46] = reginfo_t(RID_CCX); // ECX
reg_name_map["BH"] = reginfo_t(RID_CBX, 8, 8);
reg_name_map["BL"] = reginfo_t(RID_CBX, 8, 0);
reg_name_map["BX"] = reginfo_t(RID_CBX, 16, 0);
reg_name_map["EBX"] = reginfo_t(RID_CBX, 32, 0);
llvm_to_fail_map[29] = reginfo_t(RID_CDX, 8, 8); // DH
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[48] = reginfo_t(RID_CDX); // EDX
reg_name_map["CH"] = reginfo_t(RID_CCX, 8, 8);
reg_name_map["CL"] = reginfo_t(RID_CCX, 8, 0);
reg_name_map["CX"] = reginfo_t(RID_CCX, 16, 0);
reg_name_map["ECX"] = reginfo_t(RID_CCX);
llvm_to_fail_map[30] = reginfo_t(RID_CDI, 16, 0); // DI
llvm_to_fail_map[31] = reginfo_t(RID_CDI, 8, 0); // DIL
llvm_to_fail_map[47] = reginfo_t(RID_CDI); // EDI
reg_name_map["DH"] = reginfo_t(RID_CDX, 8, 8);
reg_name_map["DL"] = reginfo_t(RID_CDX, 8, 0);
reg_name_map["DX"] = reginfo_t(RID_CDX, 16, 0);
reg_name_map["EDX"] = reginfo_t(RID_CDX);
llvm_to_fail_map[6] = reginfo_t(RID_CBP, 16, 0); // BP
llvm_to_fail_map[7] = reginfo_t(RID_CBP, 8, 0); // BPL
llvm_to_fail_map[44] = reginfo_t(RID_CBP); // EBP
reg_name_map["DI"] = reginfo_t(RID_CDI, 16, 0);
reg_name_map["DIL"] = reginfo_t(RID_CDI, 8, 0);
reg_name_map["EDI"] = reginfo_t(RID_CDI);
llvm_to_fail_map[49] = reginfo_t(RID_FLAGS); // EFLAGS
reg_name_map["BP"] = reginfo_t(RID_CBP, 16, 0);
reg_name_map["BPL"] = reginfo_t(RID_CBP, 8, 0);
reg_name_map["EBP"] = reginfo_t(RID_CBP);
llvm_to_fail_map[50] = reginfo_t(RID_PC); // EIP
reg_name_map["EFLAGS"] = reginfo_t(RID_FLAGS);
llvm_to_fail_map[115] = reginfo_t(RID_CSI, 16, 0); // SI
llvm_to_fail_map[53] = reginfo_t(RID_CSI); // ESI
reg_name_map["EIP"] = reginfo_t(RID_PC);
llvm_to_fail_map[54] = reginfo_t(RID_CSP); // ESP
llvm_to_fail_map[117] = reginfo_t(RID_CSP, 16, 0); // SP
llvm_to_fail_map[118] = reginfo_t(RID_CSP, 8, 0); // SPL
reg_name_map["SI"] = reginfo_t(RID_CSI, 16, 0);
reg_name_map["ESI"] = reginfo_t(RID_CSI);
reg_name_map["ESP"] = reginfo_t(RID_CSP);
reg_name_map["SP"] = reginfo_t(RID_CSP, 16, 0);
reg_name_map["SPL"] = reginfo_t(RID_CSP, 8, 0);
reg_name_map["CR0"] = reginfo_t(RID_CR0);
reg_name_map["CR2"] = reginfo_t(RID_CR2);
reg_name_map["CR3"] = reginfo_t(RID_CR3);
reg_name_map["CR4"] = reginfo_t(RID_CR4);
reg_name_map["CS"] = reginfo_t(RID_CS, 16, 0);
reg_name_map["DS"] = reginfo_t(RID_DS, 16, 0);
reg_name_map["ES"] = reginfo_t(RID_ES, 16, 0);
reg_name_map["FS"] = reginfo_t(RID_FS, 16, 0);
reg_name_map["GS"] = reginfo_t(RID_GS, 16, 0);
reg_name_map["SS"] = reginfo_t(RID_SS, 16, 0);
const llvm::MCRegisterInfo &reg_info = disas->getRegisterInfo();
for (unsigned int i = 0; i < reg_info.getNumRegs(); ++i){
std::string name = reg_info.getName(i);
if (reg_name_map.count(name) > 0) {
llvm_to_fail_map[i] = reg_name_map[name];
}
}
}

View File

@ -7,11 +7,13 @@
namespace fail {
class LLVMDisassembler;
class LLVMtoFailBochs : public LLVMtoFailTranslator {
public:
LLVMtoFailBochs();
LLVMtoFailBochs(LLVMDisassembler *disas);
};
} // end of namespace

View File

@ -1,26 +1,34 @@
#include "LLVMDisassembler.hpp"
#include "LLVMtoFailGem5.hpp"
#include "sal/arm/ArmArchitecture.hpp"
using namespace fail;
LLVMtoFailGem5::LLVMtoFailGem5() {
/* These magic numbers are taken from the machine descriptions of
LLVM they (hopefully) will not change, since they are not exported
via a header */
llvm_to_fail_map[60] = reginfo_t(RI_R0);
llvm_to_fail_map[61] = reginfo_t(RI_R1);
llvm_to_fail_map[62] = reginfo_t(RI_R2);
llvm_to_fail_map[63] = reginfo_t(RI_R3);
llvm_to_fail_map[64] = reginfo_t(RI_R4);
llvm_to_fail_map[65] = reginfo_t(RI_R5);
llvm_to_fail_map[66] = reginfo_t(RI_R6);
llvm_to_fail_map[67] = reginfo_t(RI_R7);
llvm_to_fail_map[68] = reginfo_t(RI_R8);
llvm_to_fail_map[69] = reginfo_t(RI_R9);
llvm_to_fail_map[70] = reginfo_t(RI_R10);
llvm_to_fail_map[71] = reginfo_t(RI_R11);
llvm_to_fail_map[72] = reginfo_t(RI_R12);
llvm_to_fail_map[105] = reginfo_t(RI_SP);
llvm_to_fail_map[40] = reginfo_t(RI_LR);
llvm_to_fail_map[43] = reginfo_t(RI_IP);
LLVMtoFailGem5::LLVMtoFailGem5(LLVMDisassembler *disas) {
std::map<std::string, struct reginfo_t> reg_name_map;
reg_name_map["R0"] = reginfo_t(RI_R0);
reg_name_map["R1"] = reginfo_t(RI_R1);
reg_name_map["R2"] = reginfo_t(RI_R2);
reg_name_map["R3"] = reginfo_t(RI_R3);
reg_name_map["R4"] = reginfo_t(RI_R4);
reg_name_map["R5"] = reginfo_t(RI_R5);
reg_name_map["R6"] = reginfo_t(RI_R6);
reg_name_map["R7"] = reginfo_t(RI_R7);
reg_name_map["R8"] = reginfo_t(RI_R8);
reg_name_map["R9"] = reginfo_t(RI_R9);
reg_name_map["R10"] = reginfo_t(RI_R10);
reg_name_map["R11"] = reginfo_t(RI_R11);
reg_name_map["R12"] = reginfo_t(RI_R12);
reg_name_map["SP"] = reginfo_t(RI_SP);
reg_name_map["LR"] = reginfo_t(RI_LR);
reg_name_map["PC"] = reginfo_t(RI_IP);
const llvm::MCRegisterInfo &reg_info = disas->getRegisterInfo();
for (unsigned int i = 0; i < reg_info.getNumRegs(); ++i){
std::string name = reg_info.getName(i);
if (reg_name_map.count(name) > 0) {
llvm_to_fail_map[i] = reg_name_map[name];
}
}
}

View File

@ -7,11 +7,13 @@
namespace fail {
class LLVMDisassembler;
class LLVMtoFailGem5 : public LLVMtoFailTranslator {
public:
LLVMtoFailGem5();
LLVMtoFailGem5(LLVMDisassembler *disas);
};
} // end of namespace

View File

@ -1,7 +1,10 @@
#include "LLVMDisassembler.hpp"
#include "LLVMtoFailTranslator.hpp"
#include "sal/SALInst.hpp"
using namespace fail;
using namespace llvm;
using namespace llvm::object;
const LLVMtoFailTranslator::reginfo_t & LLVMtoFailTranslator::getFailRegisterID(unsigned int regid) {
ltof_map_t::iterator it = llvm_to_fail_map.find(regid);
@ -38,3 +41,20 @@ void LLVMtoFailTranslator::setRegisterContent(ConcreteCPU & cpu, const reginfo_t
cpu.setRegisterContent( reg, value ); // write back register content
}
LLVMtoFailTranslator* LLVMtoFailTranslator::createFromBinary(const std::string elf_path) {
llvm_shutdown_obj Y;
llvm::InitializeAllTargetInfos();
llvm::InitializeAllTargetMCs();
llvm::InitializeAllDisassemblers();
OwningPtr<Binary> binary;
assert(createBinary(elf_path, binary) == 0);
#ifndef __puma
LLVMDisassembler disas(dyn_cast<ObjectFile>(binary.get()));
return &disas.getTranslator();
#else
return 0;
#endif
}

View File

@ -68,6 +68,8 @@ public:
int getFailRegisterId(unsigned int regid) { return this->getFailRegisterID(regid).id; };
reginfo_t notfound;
static LLVMtoFailTranslator* createFromBinary(const std::string elf_path);
};
} // end of namespace