Commit 5e75202d authored by swift_gan's avatar swift_gan Committed by swift_gan

tweak code

parent 48cfbe09
......@@ -133,6 +133,29 @@ void AssemblerA64::Cbnz(RegisterA64 &rt, Off offset) {
void AssemblerA64::Cbnz(RegisterA64 &rt, Label *label) {
Emit((reinterpret_cast<Unit<Base> *>(new INST_A64(CBZ_CBNZ)(INST_A64(CBZ_CBNZ)::CBNZ, *label, rt))));
}
void AssemblerA64::Str(RegisterA64 &rt, const MemOperand& memOperand) {
if (memOperand.addr_mode == Offset) {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(STR_UIMM)(rt, memOperand)));
} else {
Emit(reinterpret_cast<Unit<Base> *>(new INST_A64(STR_IMM)(rt, memOperand)));
}
}
void AssemblerA64::Pop(RegisterA64 &rd) {
}
void AssemblerA64::Push(RegisterA64 &rt) {
if (rt.isX()) {
Str(rt, MemOperand(&SP, -1 * rt.getWideInBytes(), PreIndex));
} else {
Str(rt, MemOperand(&WSP, -1 * rt.getWideInBytes(), PreIndex));
}
}
void AssemblerA64::Cmp(RegisterA64 &rn, const Operand &operand) {
}
......
......@@ -58,6 +58,15 @@ namespace SandHook {
void Cbnz(RegisterA64 &rt, Off offset);
void Cbnz(RegisterA64 &rt, Label* label);
void Str(RegisterA64& rt, const MemOperand& memOperand);
void Pop(RegisterA64& rt);
void Push(RegisterA64& rt);
void Subs();
void Cmp(RegisterA64& rn, const Operand& operand);
public:
CodeContainer codeContainer = CodeContainer(nullptr);
......
......@@ -350,11 +350,11 @@ void A64_BR_BLR_RET::assembler() {
A64_STR_IMM::A64_STR_IMM() {}
A64_STR_IMM::A64_STR_IMM(STRUCT_A64(STR_IMM) &inst) : InstructionA64(&inst) {
A64_STR_IMM::A64_STR_IMM(STRUCT_A64(STR_IMM) &inst) : A64LoadAndStoreImm(&inst) {
decode(&inst);
}
A64_STR_IMM::A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand) : rt(&rt), operand(operand) {
A64_STR_IMM::A64_STR_IMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, operand) {
}
......@@ -426,11 +426,11 @@ void A64_STR_IMM::assembler() {
A64_STR_UIMM::A64_STR_UIMM() {}
A64_STR_UIMM::A64_STR_UIMM(STRUCT_A64(STR_UIMM) &inst) : InstructionA64(&inst) {
A64_STR_UIMM::A64_STR_UIMM(STRUCT_A64(STR_UIMM) &inst) : A64LoadAndStoreImm(&inst) {
decode(&inst);
}
A64_STR_UIMM::A64_STR_UIMM(RegisterA64 &rt, const MemOperand &operand) : rt(&rt), operand(operand) {
A64_STR_UIMM::A64_STR_UIMM(RegisterA64 &rt, const MemOperand &operand) : A64LoadAndStoreImm(&rt, operand) {
}
......@@ -571,3 +571,128 @@ A64_SVC::A64_SVC(U16 imme) : A64_EXCEPTION_GEN(XXC, EL1,imme) {}
A64_SVC::A64_SVC() {}
A64_SVC::A64_SVC(STRUCT_A64(SVC) &inst) : A64_EXCEPTION_GEN(inst) {}
A64_LDR_IMM::A64_LDR_IMM() {}
A64_LDR_IMM::A64_LDR_IMM(STRUCT_A64(LDR_IMM) &inst) : A64LoadAndStoreImm(&inst) {
decode(&inst);
}
A64_LDR_IMM::A64_LDR_IMM(RegisterA64 *rt, const MemOperand &operand) : A64LoadAndStoreImm(rt,
operand) {}
void A64_LDR_IMM::decode(STRUCT_A64(LDR_IMM) *inst) {
regSize = Size(inst->size);
switch (regSize) {
case Size64:
rt = XReg(static_cast<U8>(inst->rt));
operand.base = XReg(static_cast<U8>(inst->rn));
break;
case Size32:
rt = WReg(static_cast<U8>(inst->rt));
operand.base = WReg(static_cast<U8>(inst->rn));
break;
default:
valid = false;
return;
}
addrMode = AdMod(inst->addrmode);
switch (addrMode) {
case PostIndex:
wback = true;
postindex = true;
operand.addr_mode = AddrMode::PostIndex;
break;
case PreIndex:
wback = true;
postindex = false;
operand.addr_mode = AddrMode::PreIndex;
break;
default:
valid = false;
return;
}
scale = static_cast<U8>(inst->size);
offset = signExtend64(9, inst->imm9);
operand.offset = offset;
}
void A64_LDR_IMM::assembler() {
SET_OPCODE(LDR_IMM);
get()->rt = rt->getCode();
get()->rn = operand.base->getCode();
get()->imm9 = TruncateToUint9(operand.offset);
if (rt->isX()) {
get()->size = Size64;
} else if (rt->isW()) {
get()->size = Size32;
} else {
valid = false;
return;
}
switch (operand.addr_mode) {
case AddrMode::PostIndex:
wback = true;
postindex = true;
get()->addrmode = PostIndex;
break;
case AddrMode::PreIndex:
wback = true;
postindex = false;
get()->addrmode = PreIndex;
break;
default:
valid = false;
return;
}
}
A64_LDR_UIMM::A64_LDR_UIMM() {}
A64_LDR_UIMM::A64_LDR_UIMM(STRUCT_A64(LDR_UIMM) &inst) : A64LoadAndStoreImm(&inst) {
decode(&inst);
}
A64_LDR_UIMM::A64_LDR_UIMM(RegisterA64 *rt, const MemOperand &operand) : A64LoadAndStoreImm(rt,
operand) {}
void A64_LDR_UIMM::decode(STRUCT_A64(LDR_UIMM) *inst) {
regSize = Size(inst->size);
switch (regSize) {
case Size64:
rt = XReg(static_cast<U8>(inst->rt));
operand.base = XReg(static_cast<U8>(inst->rn));
break;
case Size32:
rt = WReg(static_cast<U8>(inst->rt));
operand.base = WReg(static_cast<U8>(inst->rn));
break;
default:
valid = false;
return;
}
operand.addr_mode = AddrMode::Offset;
scale = static_cast<U8>(inst->size);
offset = inst->imm12 << regSize;
operand.offset = offset;
}
void A64_LDR_UIMM::assembler() {
SET_OPCODE(LDR_UIMM);
get()->rt = rt->getCode();
get()->rn = operand.base->getCode();
if (rt->isX()) {
get()->size = Size64;
} else if (rt->isW()) {
get()->size = Size32;
} else {
valid = false;
return;
}
get()->imm12 = operand.offset >> get()->size;
}
......@@ -66,10 +66,6 @@ namespace SandHook {
return ExtractSignedBitfield32(bits - 1, 0, value);
}
bool isPCRelAddressing() {
return mask(PCRelAddressingFMask) == PCRelAddressingFixed;
}
InstType instType() override {
return A64;
}
......@@ -520,7 +516,8 @@ namespace SandHook {
};
class INST_A64(STR_IMM) : public InstructionA64<STRUCT_A64(STR_IMM)> {
template <typename Inst>
class A64LoadAndStoreImm : public InstructionA64<Inst> {
public:
enum AdMod {
......@@ -533,6 +530,28 @@ namespace SandHook {
Size64 = 0b11
};
A64LoadAndStoreImm() {}
A64LoadAndStoreImm(Inst *inst) : InstructionA64<Inst>(inst) {}
A64LoadAndStoreImm(RegisterA64 *rt, const MemOperand &operand) : rt(rt),
operand(operand) {}
RegisterA64* rt;
MemOperand operand = MemOperand();
protected:
AdMod addrMode;
Size regSize;
U8 scale;
bool wback;
bool postindex;
Off offset;
};
class INST_A64(STR_IMM) : public A64LoadAndStoreImm<STRUCT_A64(STR_IMM)> {
public:
A64_STR_IMM();
A64_STR_IMM(STRUCT_A64(STR_IMM)& inst);
......@@ -547,27 +566,12 @@ namespace SandHook {
void assembler() override;
public:
RegisterA64* rt;
MemOperand operand = MemOperand();
private:
AdMod addrMode;
Size regSize;
U8 scale;
bool wback;
bool postindex;
Off offset;
};
class INST_A64(STR_UIMM) : public InstructionA64<STRUCT_A64(STR_UIMM)> {
class INST_A64(STR_UIMM) : public A64LoadAndStoreImm<STRUCT_A64(STR_UIMM)> {
public:
enum Size {
Size32 = 0b10,
Size64 = 0b11
};
A64_STR_UIMM();
A64_STR_UIMM(STRUCT_A64(STR_UIMM)& inst);
......@@ -581,16 +585,6 @@ namespace SandHook {
void decode(STRUCT_A64(STR_UIMM) *inst) override;
void assembler() override;
public:
RegisterA64* rt;
MemOperand operand = MemOperand();
private:
Size regSize;
U8 scale;
bool wback = false;
bool postindex = false;
Off offset;
};
......@@ -694,6 +688,36 @@ namespace SandHook {
DEFINE_INST_CODE(SVC)
};
class INST_A64(LDR_IMM) : A64LoadAndStoreImm<STRUCT_A64(LDR_IMM)> {
public:
A64_LDR_IMM();
A64_LDR_IMM(STRUCT_A64(LDR_IMM) &inst);
A64_LDR_IMM(RegisterA64 *rt, const MemOperand &operand);
private:
void decode(STRUCT_A64(LDR_IMM) *inst) override;
void assembler() override;
};
class INST_A64(LDR_UIMM) : A64LoadAndStoreImm<STRUCT_A64(LDR_UIMM)> {
public:
A64_LDR_UIMM();
A64_LDR_UIMM(STRUCT_A64(LDR_UIMM) &inst);
A64_LDR_UIMM(RegisterA64 *rt, const MemOperand &operand);
private:
void decode(STRUCT_A64(LDR_UIMM) *inst) override;
void assembler() override;
};
}
}
......
......@@ -13,6 +13,8 @@ enum InstCodeA64 {
MOV_REG,
ADR_ADRP,
LDR_LIT,
LDR_UIMM,
LDR_IMM,
STR_IMM,
STR_UIMM,
B_BL,
......@@ -25,130 +27,4 @@ enum InstCodeA64 {
SVC
};
// Generic fields.
enum GenericInstrField {
SixtyFourBits = 0x80000000,
ThirtyTwoBits = 0x00000000,
FPTypeMask = 0x00C00000,
FP16 = 0x00C00000,
FP32 = 0x00000000,
FP64 = 0x00400000
};
enum PCRelAddressingOp {
PCRelAddressingFixed = 0x10000000,
PCRelAddressingFMask = 0x1F000000,
PCRelAddressingMask = 0x9F000000,
ADR = PCRelAddressingFixed | 0x00000000,
ADRP = PCRelAddressingFixed | 0x80000000
};
// Move wide immediate.
enum MoveWideImmediateOp {
MoveWideImmediateFixed = 0x12800000,
MoveWideImmediateFMask = 0x1F800000,
MoveWideImmediateMask = 0xFF800000,
MOVN = 0x00000000,
MOVZ = 0x40000000,
MOVK = 0x60000000,
MOVN_w = MoveWideImmediateFixed | MOVN,
MOVN_x = MoveWideImmediateFixed | MOVN | SixtyFourBits,
MOVZ_w = MoveWideImmediateFixed | MOVZ,
MOVZ_x = MoveWideImmediateFixed | MOVZ | SixtyFourBits,
MOVK_w = MoveWideImmediateFixed | MOVK,
MOVK_x = MoveWideImmediateFixed | MOVK | SixtyFourBits
};
// Unconditional branch.
enum UnconditionalBranchOp {
UnconditionalBranchFixed = 0x14000000,
UnconditionalBranchFMask = 0x7C000000,
UnconditionalBranchMask = 0xFC000000,
B = UnconditionalBranchFixed | 0x00000000,
BL = UnconditionalBranchFixed | 0x80000000
};
// Compare and branch.
enum CompareBranchOp {
CompareBranchFixed = 0x34000000,
CompareBranchFMask = 0x7E000000,
CompareBranchMask = 0xFF000000,
CBZ_w = CompareBranchFixed | 0x00000000,
CBZ_x = CompareBranchFixed | 0x80000000,
CBZ = CBZ_w,
CBNZ_w = CompareBranchFixed | 0x01000000,
CBNZ_x = CompareBranchFixed | 0x81000000,
CBNZ = CBNZ_w
};
// Conditional branch.
enum ConditionalBranchOp {
ConditionalBranchFixed = 0x54000000,
ConditionalBranchFMask = 0xFE000000,
ConditionalBranchMask = 0xFF000010,
B_cond = ConditionalBranchFixed | 0x00000000
};
// Test and branch.
enum TestBranchOp {
TestBranchFixed = 0x36000000,
TestBranchFMask = 0x7E000000,
TestBranchMask = 0x7F000000,
TBZ = TestBranchFixed | 0x00000000,
TBNZ = TestBranchFixed | 0x01000000
};
// Load literal.
enum LoadLiteralOp {
LoadLiteralFixed = 0x18000000,
LoadLiteralFMask = 0x3B000000,
LoadLiteralMask = 0xFF000000,
LDR_w_lit = LoadLiteralFixed | 0x00000000,
LDR_x_lit = LoadLiteralFixed | 0x40000000,
LDRSW_x_lit = LoadLiteralFixed | 0x80000000,
PRFM_lit = LoadLiteralFixed | 0xC0000000,
LDR_s_lit = LoadLiteralFixed | 0x04000000,
LDR_d_lit = LoadLiteralFixed | 0x44000000,
LDR_q_lit = LoadLiteralFixed | 0x84000000
};
#define LOAD_STORE_OP_LIST(V) \
V(ST, RB, w, 0x00000000), \
V(ST, RH, w, 0x40000000), \
V(ST, R, w, 0x80000000), \
V(ST, R, x, 0xC0000000), \
V(LD, RB, w, 0x00400000), \
V(LD, RH, w, 0x40400000), \
V(LD, R, w, 0x80400000), \
V(LD, R, x, 0xC0400000), \
V(LD, RSB, x, 0x00800000), \
V(LD, RSH, x, 0x40800000), \
V(LD, RSW, x, 0x80800000), \
V(LD, RSB, w, 0x00C00000), \
V(LD, RSH, w, 0x40C00000), \
V(ST, R, b, 0x04000000), \
V(ST, R, h, 0x44000000), \
V(ST, R, s, 0x84000000), \
V(ST, R, d, 0xC4000000), \
V(ST, R, q, 0x04800000), \
V(LD, R, b, 0x04400000), \
V(LD, R, h, 0x44400000), \
V(LD, R, s, 0x84400000), \
V(LD, R, d, 0xC4400000), \
V(LD, R, q, 0x04C00000)
// Load/store (post, pre, offset and unsigned.)
enum LoadStoreOp {
LoadStoreMask = 0xC4C00000,
LoadStoreVMask = 0x04000000,
#define LOAD_STORE(A, B, C, D) \
A##B##_##C = D
LOAD_STORE_OP_LIST(LOAD_STORE),
#undef LOAD_STORE
PRFM = 0xC0800000
};
#endif //SANDHOOK_NH_INST_CODE_ARM64_H
......@@ -149,6 +149,26 @@ DEFINE_STRUCT_A64(LDR_LIT) {
InstA64 op:2;
};
DEFINE_OPCODE(LDR_UIMM, 0b11100101)
DEFINE_STRUCT_A64(LDR_UIMM) {
InstA64 rt:WideReg;
InstA64 rn:WideReg;
InstA64 imm12:12;
InstA64 opcode:8;
InstA64 size:2;
};
DEFINE_OPCODE(LDR_IMM, 0b111000010)
DEFINE_STRUCT_A64(LDR_IMM) {
InstA64 rt:WideReg;
InstA64 rn:WideReg;
InstA64 addrmode:2;
InstA64 imm9:9;
InstA64 opcode:9;
InstA64 size:2;
};
DEFINE_OPCODE(BR_BLR_RET_1, 0b110101100)
DEFINE_OPCODE(BR_BLR_RET_2, 0b11111000000)
DEFINE_OPCODE(BR_BLR_RET_3, 0b00000)
......@@ -205,8 +225,10 @@ DEFINE_STRUCT_A64(EXCEPTION_GEN) {
};
struct STRUCT_A64(SVC) : STRUCT_A64(EXCEPTION_GEN) {
};
#endif //SANDHOOK_NH_INST_AARCH64_H
......@@ -36,6 +36,10 @@ namespace SandHook {
return 0;
};
inline U8 getWideInBytes() {
return static_cast<U8>(getWide() / BITS_OF_BYTE);
};
inline bool is32Bit() {
return getWide() == Reg32Bit;
}
......
......@@ -197,11 +197,6 @@ inline int32_t BITS32H(int64_t value) {
return static_cast<int32_t>(value >> 32);
}
// left/right shift
#define LFT(a, b, c) ((a & ((1 << b) - 1)) << c)
#define RHT(a, b, c) ((a >> c) & ((1 << b) - 1))
#define COMBINE(hi, lo, lowide) (hi << lowide) | lo
/* borrow from gdb, refer: binutils-gdb/gdb/arch/arm.h */
......
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