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

almost finish code rewrite

parent 2d5579fd
...@@ -4,45 +4,47 @@ ...@@ -4,45 +4,47 @@
#include "assembler_a64.h" #include "assembler_a64.h"
SandHook::Assembler::AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) { using namespace SandHook::Assembler;
AssemblerA64::AssemblerA64(CodeBuffer* codeBuffer) {
codeContainer.setCodeBuffer(codeBuffer); codeContainer.setCodeBuffer(codeBuffer);
} }
void *SandHook::Assembler::AssemblerA64::getPC() { void *AssemblerA64::getPC() {
return reinterpret_cast<void *>(codeContainer.curPc); return reinterpret_cast<void *>(codeContainer.curPc);
} }
void *SandHook::Assembler::AssemblerA64::getStartPC() { void *AssemblerA64::getStartPC() {
return reinterpret_cast<void *>(codeContainer.startPc); return reinterpret_cast<void *>(codeContainer.startPc);
} }
void SandHook::Assembler::AssemblerA64::allocBufferFirst(U32 size) { void AssemblerA64::allocBufferFirst(U32 size) {
codeContainer.allocBufferFirst(size); codeContainer.allocBufferFirst(size);
} }
void *SandHook::Assembler::AssemblerA64::finish() { void *AssemblerA64::finish() {
codeContainer.commit(); codeContainer.commit();
return reinterpret_cast<void *>(codeContainer.startPc); return reinterpret_cast<void *>(codeContainer.startPc);
} }
void SandHook::Assembler::AssemblerA64::Emit(Unit<Base> *unit) { void AssemblerA64::Emit(Unit<Base> *unit) {
codeContainer.append(unit); codeContainer.append(unit);
} }
void 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) { 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 h0 = BITS16L(imme);
const U16 h1 = BITS16H(imme); const U16 h1 = BITS16H(imme);
Movz(rd, h0, INST_A64(MOV_WIDE)::Shift0); Movz(rd, h0, INST_A64(MOV_WIDE)::Shift0);
Movk(rd, h1, INST_A64(MOV_WIDE)::Shift1); 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 wl = BITS32L(imme);
const U32 wh = BITS32H(imme); const U32 wh = BITS32H(imme);
const U16 h0 = BITS16L(wl); const U16 h0 = BITS16L(wl);
...@@ -55,18 +57,83 @@ void SandHook::Assembler::AssemblerA64::Mov(XRegister &rd, U64 imme) { ...@@ -55,18 +57,83 @@ void SandHook::Assembler::AssemblerA64::Mov(XRegister &rd, U64 imme) {
Movk(rd, h3, INST_A64(MOV_WIDE)::Shift3); 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) { INST_A64(MOV_WIDE)::Shift shift) {
MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_Z, imme, 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) { INST_A64(MOV_WIDE)::Shift shift) {
MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_K, imme, 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) { INST_A64(MOV_WIDE)::Shift shift) {
MoveWide(rd, INST_A64(MOV_WIDE)::MOV_WideOp_N, imme, 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 { ...@@ -33,9 +33,31 @@ namespace SandHook {
void Movn(RegisterA64& rd, U64 imme, INST_A64(MOV_WIDE)::Shift shift); void Movn(RegisterA64& rd, U64 imme, INST_A64(MOV_WIDE)::Shift shift);
void Mov(WRegister& rd, U32 imme); void Mov(WRegister& rd, U32 imme);
void Mov(XRegister& rd, U64 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: public:
CodeContainer codeContainer = CodeContainer(nullptr); CodeContainer codeContainer = CodeContainer(nullptr);
......
...@@ -48,6 +48,15 @@ A64_ADR_ADRP::A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst) : A64_INST_PC_REL(&inst) ...@@ -48,6 +48,15 @@ A64_ADR_ADRP::A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst) : A64_INST_PC_REL(&inst)
decode(&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() { Off A64_ADR_ADRP::getImmPCOffset() {
U32 hi = get()->immhi; U32 hi = get()->immhi;
U32 lo = get()->immlo; U32 lo = get()->immlo;
...@@ -63,19 +72,15 @@ Addr A64_ADR_ADRP::getImmPCOffsetTarget() { ...@@ -63,19 +72,15 @@ Addr A64_ADR_ADRP::getImmPCOffsetTarget() {
return getImmPCOffset() + reinterpret_cast<Addr>(base); 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() { void A64_ADR_ADRP::assembler() {
SET_OPCODE(ADR_ADRP); 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 //Mov Wide
...@@ -157,9 +162,14 @@ A64_CBZ_CBNZ::A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst) : A64_INST_PC_REL(&inst) ...@@ -157,9 +162,14 @@ A64_CBZ_CBNZ::A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst) : A64_INST_PC_REL(&inst)
decode(&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), 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() { Off A64_CBZ_CBNZ::getImmPCOffset() {
return signExtend64(19 + 2, COMBINE(get()->imm19, 0b00, 2)); return signExtend64(19 + 2, COMBINE(get()->imm19, 0b00, 2));
...@@ -183,6 +193,11 @@ void A64_CBZ_CBNZ::assembler() { ...@@ -183,6 +193,11 @@ void A64_CBZ_CBNZ::assembler() {
get()->imm19 = TruncateToUint19(offset >> 2); get()->imm19 = TruncateToUint19(offset >> 2);
} }
void A64_CBZ_CBNZ::onOffsetApply(Off offset) {
this->offset = offset;
get()->imm19 = TruncateToUint19(offset >> 2);
}
//B.Cond //B.Cond
...@@ -209,6 +224,15 @@ void A64_B_COND::assembler() { ...@@ -209,6 +224,15 @@ void A64_B_COND::assembler() {
get()->imm19 = TruncateToUint19(offset >> 2); 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 //TBZ TBNZ
...@@ -218,11 +242,17 @@ A64_TBZ_TBNZ::A64_TBZ_TBNZ(STRUCT_A64(TBZ_TBNZ) &inst) : A64_INST_PC_REL(&inst) ...@@ -218,11 +242,17 @@ A64_TBZ_TBNZ::A64_TBZ_TBNZ(STRUCT_A64(TBZ_TBNZ) &inst) : A64_INST_PC_REL(&inst)
decode(&inst); decode(&inst);
} }
A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 *rt, U32 bit, Off offset) : op(op), A64_TBZ_TBNZ::A64_TBZ_TBNZ(A64_TBZ_TBNZ::OP op, RegisterA64 &rt, U32 bit, Off offset) : op(op),
rt(rt), rt(&rt),
bit(bit), bit(bit),
offset(offset) {} 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() { Off A64_TBZ_TBNZ::getImmPCOffset() {
return signExtend64(14 + 2, COMBINE(get()->imm14, 0b00, 2)); return signExtend64(14 + 2, COMBINE(get()->imm14, 0b00, 2));
} }
...@@ -247,6 +277,11 @@ void A64_TBZ_TBNZ::assembler() { ...@@ -247,6 +277,11 @@ void A64_TBZ_TBNZ::assembler() {
get()->imm14 = TruncateToUint14(offset >> 2); get()->imm14 = TruncateToUint14(offset >> 2);
} }
void A64_TBZ_TBNZ::onOffsetApply(Off offset) {
this->offset = offset;
get()->imm14 = TruncateToUint14(offset >> 2);
}
// LDR(literal) // LDR(literal)
......
...@@ -223,7 +223,9 @@ namespace SandHook { ...@@ -223,7 +223,9 @@ namespace SandHook {
A64_ADR_ADRP(STRUCT_A64(ADR_ADRP) &inst); 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) DEFINE_IS(ADR_ADRP)
...@@ -237,14 +239,14 @@ namespace SandHook { ...@@ -237,14 +239,14 @@ namespace SandHook {
Addr getImmPCOffsetTarget() override; Addr getImmPCOffsetTarget() override;
void decode(STRUCT_A64(ADR_ADRP) *decode) override; void decode(A64_STRUCT_ADR_ADRP *inst) override;
void assembler() override; void assembler() override;
public: public:
OP op; OP op;
RegisterA64* rd; XRegister* rd;
S64 imme; S64 offset;
}; };
...@@ -365,13 +367,15 @@ namespace SandHook { ...@@ -365,13 +367,15 @@ namespace SandHook {
A64_CBZ_CBNZ(STRUCT_A64(CBZ_CBNZ) &inst); 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) DEFINE_IS(CBZ_CBNZ)
inline U32 instCode() override { DEFINE_INST_CODE(CBZ_CBNZ)
return op == CBZ ? CompareBranchOp::CBZ : CompareBranchOp::CBNZ;
} void onOffsetApply(Off offset) override;
Off getImmPCOffset() override; Off getImmPCOffset() override;
...@@ -394,12 +398,16 @@ namespace SandHook { ...@@ -394,12 +398,16 @@ namespace SandHook {
A64_B_COND(Condition condition, Off offset); A64_B_COND(Condition condition, Off offset);
A64_B_COND(Condition condition, Label& label);
DEFINE_IS(B_COND) DEFINE_IS(B_COND)
DEFINE_INST_CODE(B_COND) DEFINE_INST_CODE(B_COND)
Off getImmPCOffset() override; Off getImmPCOffset() override;
void onOffsetApply(Off offset) override;
void decode(STRUCT_A64(B_COND) *inst) override; void decode(STRUCT_A64(B_COND) *inst) override;
void assembler() override; void assembler() override;
...@@ -414,20 +422,24 @@ namespace SandHook { ...@@ -414,20 +422,24 @@ namespace SandHook {
public: public:
enum OP { enum OP {
TBZ, TBZ = 0,
TBNZ TBNZ = 1
}; };
A64_TBZ_TBNZ(); A64_TBZ_TBNZ();
A64_TBZ_TBNZ(STRUCT_A64(TBZ_TBNZ) &inst); 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_IS(TBZ_TBNZ)
DEFINE_INST_CODE(TBZ_TBNZ) DEFINE_INST_CODE(TBZ_TBNZ)
void onOffsetApply(Off offset) override;
Off getImmPCOffset() override; Off getImmPCOffset() override;
void decode(STRUCT_A64(TBZ_TBNZ) *inst) override; void decode(STRUCT_A64(TBZ_TBNZ) *inst) override;
......
...@@ -37,19 +37,71 @@ void CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw ...@@ -37,19 +37,71 @@ void CodeRelocateA64::relocate(Instruction<Base> *instruction, void *toPc) throw
} }
IMPL_RELOCATE(B_BL) { 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) { 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) { 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) { 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) { IMPL_RELOCATE(LDR_LIT) {
...@@ -57,5 +109,5 @@ IMPL_RELOCATE(LDR_LIT) { ...@@ -57,5 +109,5 @@ IMPL_RELOCATE(LDR_LIT) {
} }
IMPL_RELOCATE(ADR_ADRP) { 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