Skip to content

Commit

Permalink
Implemented parent register handling
Browse files Browse the repository at this point in the history
- Register parent map
- Storing registers
- Loading registers
- Headers

- Need more changes to conversions, I think 'mov w0, avast#3' zeroes out
  the upper 32bits of x0 register. But need to investigate further.
  • Loading branch information
MatejKastak committed Sep 22, 2018
1 parent bf88c1e commit 8916e12
Show file tree
Hide file tree
Showing 4 changed files with 145 additions and 10 deletions.
7 changes: 7 additions & 0 deletions include/retdec/capstone2llvmir/arm64/arm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,13 @@ class Capstone2LlvmIrTranslatorArm64 : virtual public Capstone2LlvmIrTranslator
{
public:
virtual ~Capstone2LlvmIrTranslatorArm64() {};

public:
/**
* @return Capstone register that is parent to the specified Capstone
* register @p r. Register can be its own parent.
*/
virtual uint32_t getParentRegister(uint32_t r) const = 0;
};

} // namespace capstone2llvmir
Expand Down
71 changes: 61 additions & 10 deletions src/capstone2llvmir/arm64/arm64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ Capstone2LlvmIrTranslatorArm64_impl::Capstone2LlvmIrTranslatorArm64_impl(
cs_mode basic,
cs_mode extra)
:
Capstone2LlvmIrTranslator_impl(CS_ARCH_ARM64, basic, extra, m)
Capstone2LlvmIrTranslator_impl(CS_ARCH_ARM64, basic, extra, m),
_reg2parentMap(ARM64_REG_ENDING, ARM64_REG_INVALID)
{
initialize();
}
Expand Down Expand Up @@ -58,7 +59,7 @@ uint32_t Capstone2LlvmIrTranslatorArm64_impl::getArchByteSize()

void Capstone2LlvmIrTranslatorArm64_impl::generateEnvironmentArchSpecific()
{
// Nothing.
initializeRegistersParentMap();
}

void Capstone2LlvmIrTranslatorArm64_impl::generateDataLayout()
Expand Down Expand Up @@ -103,6 +104,7 @@ void Capstone2LlvmIrTranslatorArm64_impl::generateRegisters()

// Lower 32 bits of 64 arm{xN} bit regs.
//
/*
createRegister(ARM64_REG_W0, _regLt);
createRegister(ARM64_REG_W1, _regLt);
createRegister(ARM64_REG_W2, _regLt);
Expand Down Expand Up @@ -134,6 +136,7 @@ void Capstone2LlvmIrTranslatorArm64_impl::generateRegisters()
createRegister(ARM64_REG_W28, _regLt);
createRegister(ARM64_REG_W29, _regLt);
createRegister(ARM64_REG_W30, _regLt);
*/

// Special registers.

Expand All @@ -145,11 +148,11 @@ void Capstone2LlvmIrTranslatorArm64_impl::generateRegisters()

// Stack pointer.
createRegister(ARM64_REG_SP, _regLt);
createRegister(ARM64_REG_WSP, _regLt);
//createRegister(ARM64_REG_WSP, _regLt);

// Zero.
createRegister(ARM64_REG_XZR, _regLt);
createRegister(ARM64_REG_WZR, _regLt);
//createRegister(ARM64_REG_WZR, _regLt);

// Flags.
createRegister(ARM64_REG_CPSR_N, _regLt);
Expand All @@ -159,8 +162,6 @@ void Capstone2LlvmIrTranslatorArm64_impl::generateRegisters()

// Program counter.
createRegister(ARM64_REG_PC, _regLt);

// TODO: Generate parent register map
}

uint32_t Capstone2LlvmIrTranslatorArm64_impl::getCarryRegister()
Expand Down Expand Up @@ -209,6 +210,12 @@ void Capstone2LlvmIrTranslatorArm64_impl::translateInstruction(
}
}

uint32_t Capstone2LlvmIrTranslatorArm64_impl::getParentRegister(uint32_t r) const
{
return r < _reg2parentMap.size() ? _reg2parentMap[r] : r;
}


//
//==============================================================================
// ARM64-specific methods.
Expand Down Expand Up @@ -447,13 +454,22 @@ llvm::Value* Capstone2LlvmIrTranslatorArm64_impl::loadRegister(
// TODO: Check
}

auto* llvmReg = getRegister(r);
auto* rt = getRegisterType(r);
auto pr = getParentRegister(r);
auto* llvmReg = getRegister(pr);
if (llvmReg == nullptr)
{
throw Capstone2LlvmIrError("loadRegister() unhandled reg.");
}

return irb.CreateLoad(llvmReg);
llvm::Value* ret = irb.CreateLoad(llvmReg);
if (r != pr)
{
ret = irb.CreateTrunc(ret, rt);
}

ret = generateTypeConversion(irb, ret, dstType, ct);
return ret;
}

llvm::Value* Capstone2LlvmIrTranslatorArm64_impl::loadOp(
Expand Down Expand Up @@ -517,14 +533,49 @@ llvm::Instruction* Capstone2LlvmIrTranslatorArm64_impl::storeRegister(
// TODO: Check?
}

auto* llvmReg = getRegister(r);
auto* rt = getRegisterType(r);
auto pr = getParentRegister(r);
auto* llvmReg = getRegister(pr);
if (llvmReg == nullptr)
{
throw Capstone2LlvmIrError("storeRegister() unhandled reg.");
}

val = generateTypeConversion(irb, val, llvmReg->getValueType(), ct);

return irb.CreateStore(val, llvmReg);
llvm::StoreInst* ret = nullptr;
if (r == pr
// Zext for 64-bit target llvmRegs & 32-bit source regs.
|| (getRegisterBitSize(pr) == 64 && getRegisterBitSize(r) == 32))
{
ret = irb.CreateStore(val, llvmReg);
}
else
{
llvm::Value* l = irb.CreateLoad(llvmReg);
if (!(l->getType()->isIntegerTy(16)
|| l->getType()->isIntegerTy(32)
|| l->getType()->isIntegerTy(64)))
{
throw Capstone2LlvmIrError("Unexpected parent type.");
}

llvm::Value* andC = nullptr;
if (rt->isIntegerTy(32))
{
if (l->getType()->isIntegerTy(64))
{
andC = irb.getInt64(0xffffffff00000000);
}
}
assert(andC);
l = irb.CreateAnd(l, andC);

auto* o = irb.CreateOr(l, val);
ret = irb.CreateStore(o, llvmReg);
}

return ret;
}

llvm::Instruction* Capstone2LlvmIrTranslatorArm64_impl::storeOp(
Expand Down
18 changes: 18 additions & 0 deletions src/capstone2llvmir/arm64/arm64_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ class Capstone2LlvmIrTranslatorArm64_impl :
virtual bool isAllowedBasicMode(cs_mode m) override;
virtual bool isAllowedExtraMode(cs_mode m) override;
virtual uint32_t getArchByteSize() override;

//
//==============================================================================
// x86 specialization methods - from Capstone2LlvmIrTranslatorX86
//==============================================================================
//
public:

virtual uint32_t getParentRegister(uint32_t r) const override;
//
//==============================================================================
// Pure virtual methods from Capstone2LlvmIrTranslator_impl
Expand All @@ -58,6 +67,12 @@ class Capstone2LlvmIrTranslatorArm64_impl :
protected:
llvm::Value* getCurrentPc(cs_insn* i);

void initializeRegistersParentMapToOther(
const std::vector<arm64_reg>& rs,
arm64_reg other);

void initializeRegistersParentMap();

llvm::Value* generateOperandShift(
llvm::IRBuilder<>& irb,
cs_arm64_op& op,
Expand Down Expand Up @@ -115,6 +130,9 @@ class Capstone2LlvmIrTranslatorArm64_impl :
//==============================================================================
//
protected:

std::vector<uint32_t> _reg2parentMap;

static std::map<
std::size_t,
void (Capstone2LlvmIrTranslatorArm64_impl::*)(
Expand Down
59 changes: 59 additions & 0 deletions src/capstone2llvmir/arm64/arm64_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,65 @@ void Capstone2LlvmIrTranslatorArm64_impl::initializePseudoCallInstructionIDs()
};
}

void Capstone2LlvmIrTranslatorArm64_impl::initializeRegistersParentMapToOther(
const std::vector<arm64_reg>& rs,
arm64_reg other)
{
for (auto r : rs)
{
assert(r < _reg2parentMap.size());
_reg2parentMap[r] = other;
}
}


void Capstone2LlvmIrTranslatorArm64_impl::initializeRegistersParentMap()
{
// Last element in vector is its own parent.
std::vector<std::vector<arm64_reg>> rss =
{
{ARM64_REG_W0, ARM64_REG_X0},
{ARM64_REG_W1, ARM64_REG_X1},
{ARM64_REG_W2, ARM64_REG_X2},
{ARM64_REG_W3, ARM64_REG_X3},
{ARM64_REG_W4, ARM64_REG_X4},
{ARM64_REG_W5, ARM64_REG_X5},
{ARM64_REG_W6, ARM64_REG_X6},
{ARM64_REG_W7, ARM64_REG_X7},
{ARM64_REG_W8, ARM64_REG_X8},
{ARM64_REG_W9, ARM64_REG_X9},
{ARM64_REG_W10, ARM64_REG_X10},
{ARM64_REG_W11, ARM64_REG_X11},
{ARM64_REG_W12, ARM64_REG_X12},
{ARM64_REG_W13, ARM64_REG_X13},
{ARM64_REG_W14, ARM64_REG_X14},
{ARM64_REG_W15, ARM64_REG_X15},
{ARM64_REG_W16, ARM64_REG_X16},
{ARM64_REG_W17, ARM64_REG_X17},
{ARM64_REG_W18, ARM64_REG_X18},
{ARM64_REG_W19, ARM64_REG_X19},
{ARM64_REG_W20, ARM64_REG_X20},
{ARM64_REG_W21, ARM64_REG_X21},
{ARM64_REG_W22, ARM64_REG_X22},
{ARM64_REG_W23, ARM64_REG_X23},
{ARM64_REG_W24, ARM64_REG_X24},
{ARM64_REG_W25, ARM64_REG_X25},
{ARM64_REG_W26, ARM64_REG_X26},
{ARM64_REG_W27, ARM64_REG_X27},
{ARM64_REG_W28, ARM64_REG_X28},
{ARM64_REG_W29, ARM64_REG_X29},
{ARM64_REG_W30, ARM64_REG_X30},

{ARM64_REG_WSP, ARM64_REG_SP},
{ARM64_REG_WZR, ARM64_REG_XZR}
};

for (std::vector<arm64_reg>& rs : rss)
{
initializeRegistersParentMapToOther(rs, rs.back());
}
}

//
//==============================================================================
// Instruction translation map initialization.
Expand Down

0 comments on commit 8916e12

Please sign in to comment.