Commit 80c60326 authored by swift_gan's avatar swift_gan Committed by swift_gan

almost finish code rewrite

parent 2d5579fd
......@@ -4,45 +4,47 @@
#include "assembler_a64.h"
SandHook::Assembler::AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) {
using namespace SandHook::Assembler;
AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) {
codeContainer.setCodeBuffer(codeBuffer);
}
void *SandHook::Assembler::AssemblerA64::getPC() {
void *AssemblerA64::getPC() {
return reinterpret_cast<void *>(codeContainer.curPc);
}
void *SandHook::Assembler::AssemblerA64::getStartPC() {
void *AssemblerA64::getStartPC() {
return reinterpret_cast<void *>(codeContainer.startPc);
}
void SandHook::Assembler::AssemblerA64::allocBufferFirst(U32 size) {
void AssemblerA64::allocBufferFirst(U32 size) {
codeContainer.allocBufferFirst(size);
}
void *SandHook::Assembler::AssemblerA64::finish() {
void *AssemblerA64::finish() {
codeContainer.commit();
return reinterpret_cast<void *>(codeContainer.startPc);
}
void SandHook::Assembler::AssemblerA64::Emit(Unit<Base> *unit) {
void AssemblerA64::Emit(Unit<Base> *unit) {
codeContainer.append(unit);
}
void
SandHook::Assembler::AssemblerA64::MoveWide(RegisterA64 &rd, INST_A64(MOV_WIDE)::OP op, U64 imme,
AssemblerA64::MoveWide(RegisterA64 &rd, INST_A64(MOV_WIDE)::OP op, U64 imme,
INST_A64(MOV_WIDE)::Shift shift) {
codeContainer.append(reinterpret_cast<Unit<Base> *>(new INST_A64(MOV_WIDE)(op, &rd, imme, shift)));
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(MOV_WIDE)(op, &rd, imme, shift)));
}
void SandHook::Assembler::AssemblerA64::Mov(WRegister &rd, U32 imme) {
void AssemblerA64::Mov(WRegister &rd, U32 imme) {
const U16 h0 = BITS16L(imme);
const U16 h1 = BITS16H(imme);
Movz(rd, h0, INST_A64(MOV_WIDE)::Shift0);
Movk(rd, h1, INST_A64(MOV_WIDE)::Shift1);
}
void SandHook::Assembler::AssemblerA64::Mov(XRegister &rd, U64 imme) {
void AssemblerA64::Mov(XRegister &rd, U64 imme) {
const U32 wl = BITS32L(imme);
const U32 wh = BITS32H(imme);
const U16 h0 = BITS16L(wl);
......@@ -55,18 +57,83 @@ void SandHook::Assembler::AssemblerA64::Mov(XRegister &rd, U64 imme) {
Movk(rd, h3, INST_A64(MOV_WIDE)::Shift3);
}
void SandHook::Assembler::AssemblerA64::Movz(RegisterA64 &rd, U64 imme,
void AssemblerA64::Movz(RegisterA64 &rd, U64 imme,
INST_A64(MOV_WIDE)::Shift shift) {
MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_Z, imme, shift);
}
void SandHook::Assembler::AssemblerA64::Movk(RegisterA64 &rd, U64 imme,
void AssemblerA64::Movk(RegisterA64 &rd, U64 imme,
INST_A64(MOV_WIDE)::Shift shift) {
MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_K, imme, shift);
}
void SandHook::Assembler::AssemblerA64::Movn(RegisterA64 &rd, U64 imme,
void AssemblerA64::Movn(RegisterA64 &rd, U64 imme,
INST_A64(MOV_WIDE)::Shift shift) {
MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_N, imme, shift);
}
void AssemblerA64::Br(XRegister &rn) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(BR_BLR_RET)(INST_A64(BR_BLR_RET)::BR, rn)));
}
void AssemblerA64::B(Off offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::B, offset)));
}
void AssemblerA64::B(Label *label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::B, *label)));
}
void AssemblerA64::Bl(Off offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::BL, offset)));
}
void AssemblerA64::Bl(Label *label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_BL)(INST_A64(B_BL)::BL, *label)));
}
void AssemblerA64::B(Condition condition, Off offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_COND)(condition, offset)));
}
void AssemblerA64::B(Condition condition, Label *label) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(B_COND)(condition, *label)));
}
void AssemblerA64::Tbz(RegisterA64 &rt, U32 bit, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBZ, rt, bit, *label))));
}
void AssemblerA64::Tbz(RegisterA64 &rt, U32 bit, Off offset) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBZ, rt, bit, offset))));
}
void AssemblerA64::Tbnz(RegisterA64 &rt, U32 bit, Off offset) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBNZ, rt, bit, offset))));
}
void AssemblerA64::Tbnz(RegisterA64 &rt, U32 bit, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(TBZ_TBNZ)(INST_A64(TBZ_TBNZ)::TBNZ, rt, bit, *label))));
}
void AssemblerA64::Cbz(RegisterA64 &rt, Off offset) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBZ, offset, rt))));
}
void AssemblerA64::Cbz(RegisterA64 &rt, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBZ, *label, rt))));
}
void AssemblerA64::Cbnz(RegisterA64 &rt, Off offset) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBNZ, offset, rt))));
}
void AssemblerA64::Cbnz(RegisterA64 &rt, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBNZ, *label, rt))));
}
......@@ -33,9 +33,31 @@ namespace SandHook {
void Movn(RegisterA64& rd, U64 imme, INST_A64(MOV_WIDE)::Shift shift);
void Mov(WRegister& rd, U32 imme);
void Mov(XRegister& rd, U64 imme);
void Br(XRegister& rn);
void B(Off offset);
void B(Label* label);
void Bl(Off offset);
void Bl(Label* label);
void B(Condition condition, Off offset);
void B(Condition condition, Label* label);
void Tbz(RegisterA64 &rt, U32 bit, Off offset);
void Tbz(RegisterA64 &rt, U32 bit, Label* label);
void Tbnz(RegisterA64 &rt, U32 bit, Off offset);
void Tbnz(RegisterA64 &rt, U32 bit, Label* label);
void Cbz(RegisterA64 &rt, Off offset);
void Cbz(RegisterA64 &rt, Label* label);
void Cbnz(RegisterA64 &rt, Off offset);
void Cbnz(RegisterA64 &rt, Label* label);
public:
CodeContainer codeContainer = CodeContainer(nullptr);
......
......@@ -48,6 +48,15 @@ A64_ADR_ADRP::A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst) : A64_INST_PC_REL(&inst)
decode(&inst);
}
A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, XRegister &rd, S64 offset) : op(op), rd(&rd),
offset(offset) {
assembler();
}
A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, XRegister &rd, Label &label) {
bindLabel(label);
}
Off A64_ADR_ADRP::getImmPCOffset() {
U32 hi = get()->immhi;
U32 lo = get()->immlo;
......@@ -63,19 +72,15 @@ Addr A64_ADR_ADRP::getImmPCOffsetTarget() {
return getImmPCOffset() + reinterpret_cast<Addr>(base);
}
A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, RegisterA64 *rd, S64 imme) : op(op), rd(rd),
imme(imme) {
assembler();
}
void A64_ADR_ADRP::decode(STRUCT_A64(ADR_ADRP) *decode) {
}
void A64_ADR_ADRP::assembler() {
SET_OPCODE(ADR_ADRP);
}
void A64_ADR_ADRP::decode(STRUCT_A64(ADR_ADRP) *inst) {
offset = getImmPCOffsetTarget();
rd = XReg(static_cast<U8>(get()->rd));
op = OP(get()->op);
}
//Mov Wide
......@@ -157,9 +162,14 @@ A64_CBZ_CBNZ::A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst) : A64_INST_PC_REL(&inst)
decode(&inst);
}
A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Off offset, RegisterA64 *rt) : op(op),
A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Off offset, RegisterA64 &rt) : op(op),
offset(offset),
rt(rt) {}
rt(&rt) {}
A64_CBZ_CBNZ::A64_CBZ_CBNZ(A64_CBZ_CBNZ::OP op, Label& label, RegisterA64 &rt) : op(op),
rt(&rt) {
bindLabel(label);
}
Off A64_CBZ_CBNZ::getImmPCOffset() {
return signExtend64(19 + 2, COMBINE(get()->imm19, 0b00, 2));
......@@ -183,6 +193,11 @@ void A64_CBZ_CBNZ::assembler() {
get()->imm19 = TruncateToUint19(offset >> 2);
}
void A64_CBZ_CBNZ::onOffsetApply(Off offset) {
this->offset = offset;
get()->imm19 = TruncateToUint19(offset >> 2);
}
//B.Cond
......@@ -209,6 +224,15 @@ void A64_B_COND::assembler() {
get()->imm19 = TruncateToUint19(offset >> 2);
}
A64_B_COND::A64_B_COND(Condition condition, Label &label) {
bindLabel(label);
}
void A64_B_COND::onOffsetApply(Off offset) {
this->offset = offset;
get()->imm19 = TruncateToUint19(offset >> 2);
}
//TBZ TBNZ
......@@ -218,11 +242,17 @@ A64_TBZ_TBNZ::A64_TBZ_TBNZ(STRUCT_A64(TBZ_TBNZ) &inst) : A64_INST_PC_REL(&inst)
decode(&inst);
}
A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 *rt, U32 bit, Off offset) : op(op),
rt(rt),
A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Off offset) : op(op),
rt(&rt),
bit(bit),
offset(offset) {}
A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Label &label) : op(op),
rt(&rt),
bit(bit) {
bindLabel(label);
}
Off A64_TBZ_TBNZ::getImmPCOffset() {
return signExtend64(14 + 2, COMBINE(get()->imm14, 0b00, 2));
}
......@@ -247,6 +277,11 @@ void A64_TBZ_TBNZ::assembler() {
get()->imm14 = TruncateToUint14(offset >> 2);
}
void A64_TBZ_TBNZ::onOffsetApply(Off offset) {
this->offset = offset;
get()->imm14 = TruncateToUint14(offset >> 2);
}
// LDR(literal)
......
......@@ -223,7 +223,9 @@ namespace SandHook {
A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst);
A64_ADR_ADRP(OP op, RegisterA64 *rd, S64 imme);
A64_ADR_ADRP(OP op, XRegister &rd, S64 offset);
A64_ADR_ADRP(OP op, XRegister &rd, Label &label);
DEFINE_IS(ADR_ADRP)
......@@ -237,14 +239,14 @@ namespace SandHook {
Addr getImmPCOffsetTarget() override;
void decode(STRUCT_A64(ADR_ADRP) *decode) override;
void decode(A64_STRUCT_ADR_ADRP *inst) override;
void assembler() override;
public:
OP op;
RegisterA64* rd;
S64 imme;
XRegister* rd;
S64 offset;
};
......@@ -365,13 +367,15 @@ namespace SandHook {
A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst);
A64_CBZ_CBNZ(OP op, Off offset, RegisterA64 *rt);
A64_CBZ_CBNZ(OP op, Off offset, RegisterA64 &rt);
A64_CBZ_CBNZ(OP op, Label& label, RegisterA64 &rt);
DEFINE_IS(CBZ_CBNZ)
inline U32 instCode() override {
return op == CBZ ? CompareBranchOp::CBZ : CompareBranchOp::CBNZ;
}
DEFINE_INST_CODE(CBZ_CBNZ)
void onOffsetApply(Off offset) override;
Off getImmPCOffset() override;
......@@ -394,12 +398,16 @@ namespace SandHook {
A64_B_COND(Condition condition, Off offset);
A64_B_COND(Condition condition, Label& label);
DEFINE_IS(B_COND)
DEFINE_INST_CODE(B_COND)
Off getImmPCOffset() override;
void onOffsetApply(Off offset) override;
void decode(STRUCT_A64(B_COND) *inst) override;
void assembler() override;
......@@ -414,20 +422,24 @@ namespace SandHook {
public:
enum OP {
TBZ,
TBNZ
TBZ = 0,
TBNZ = 1
};
A64_TBZ_TBNZ();
A64_TBZ_TBNZ(STRUCT_A64(TBZ_TBNZ) &inst);
A64_TBZ_TBNZ(OP op, RegisterA64 *rt, U32 bit, Off offset);
A64_TBZ_TBNZ(OP op, RegisterA64 &rt, U32 bit, Off offset);
A64_TBZ_TBNZ(OP op, RegisterA64 &rt, U32 bit, Label& label);
DEFINE_IS(TBZ_TBNZ)
DEFINE_INST_CODE(TBZ_TBNZ)
void onOffsetApply(Off offset) override;
Off getImmPCOffset() override;
void decode(STRUCT_A64(TBZ_TBNZ) *inst) override;
......
......@@ -37,19 +37,71 @@ void CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw
}
IMPL_RELOCATE(B_BL) {
Addr targetAddr = inst->getImmPCOffsetTarget();
if (inst->op == inst->BL) {
__ Mov(LR, targetAddr + inst->size());
}
__ Mov(IP1, targetAddr);
__ Br(IP1);
}
IMPL_RELOCATE(B_COND) {
Addr targetAddr = inst->getImmPCOffsetTarget();
Label *true_label = new Label();
Label *false_label = new Label();
__ B(inst->condition, true_label);
__ B(false_label);
__ Emit(true_label);
__ Mov(IP1, targetAddr);
__ Br(IP1);
__ Emit(false_label);
}
IMPL_RELOCATE(TBZ_TBNZ) {
Addr targetAddr = inst->getImmPCOffsetTarget();
Label *true_label = new Label();
Label *false_label = new Label();
if (inst->op == INST_A64(TBZ_TBNZ)::TBNZ) {
__ Tbnz(*inst->rt, inst->bit, true_label);
} else {
__ Tbz(*inst->rt, inst->bit, true_label);
}
__ B(false_label);
__ Emit(true_label);
__ Mov(IP1, targetAddr);
__ Br(IP1);
__ Emit(false_label);
}
IMPL_RELOCATE(CBZ_CBNZ) {
Addr targetAddr = inst->getImmPCOffsetTarget();
Label *true_label = new Label();
Label *false_label = new Label();
if (inst->op == INST_A64(CBZ_CBNZ)::CBNZ) {
__ Cbnz(*inst->rt, true_label);
} else {
__ Cbz(*inst->rt, true_label);
}
__ B(false_label);
__ Emit(true_label);
__ Mov(IP1, targetAddr);
__ Br(IP1);
__ Emit(false_label);
}
IMPL_RELOCATE(LDR_LIT) {
......@@ -57,5 +109,5 @@ IMPL_RELOCATE(LDR_LIT) {
}
IMPL_RELOCATE(ADR_ADRP) {
__ Mov(*inst->rd, inst->getImmPCOffsetTarget());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment