Commit 04e206a0 authored by swift_gan's avatar swift_gan Committed by swift_gan

tweak inst type

parent 785422da
...@@ -8,37 +8,46 @@ ...@@ -8,37 +8,46 @@
using namespace SandHook::Asm; using namespace SandHook::Asm;
template<typename InstStruct>
U8 InstructionA64<InstStruct>::size() {
return sizeof(InstA64);
}
//PC Rel Inst //PC Rel Inst
A64_INST_PC_REL::A64_INST_PC_REL() {} template<typename Inst>
A64_INST_PC_REL<Inst>::A64_INST_PC_REL(Inst *inst):InstructionA64<Inst>(inst) {
}
A64_INST_PC_REL::A64_INST_PC_REL(aarch64_pcrel_insts *inst) : InstructionA64(inst) {} template<typename Inst>
A64_INST_PC_REL<Inst>::A64_INST_PC_REL() {}
int A64_INST_PC_REL::getImmPCRel() {
U32 hi = static_cast<U32>(get()->immhi);
U32 lo = get()->immlo;
U32 offset = (hi << IMM_LO_W) | lo;
int width = IMM_HI_W + IMM_LO_W;
return ExtractSignedBitfield32(width - 1, 0, offset);
}
ADDR A64_INST_PC_REL::getImmPCOffset() { template<typename Inst>
return static_cast<ADDR>(getImmBranch() * size()); ADDR A64_INST_PC_REL<Inst>::getImmPCOffset() {
return static_cast<ADDR>(this->getImmBranch() * this->size());
} }
ADDR A64_INST_PC_REL::getImmPCOffsetTarget() { template<typename Inst>
return reinterpret_cast<ADDR>(getImmPCOffset() + (ADDR) getPC()); ADDR A64_INST_PC_REL<Inst>::getImmPCOffsetTarget() {
return reinterpret_cast<ADDR>(this->getImmPCOffset() + (ADDR) this->getPC());
} }
//ADR ADRP //ADR ADRP
A64_ADR_ADRP::A64_ADR_ADRP() {} A64_ADR_ADRP::A64_ADR_ADRP() {}
A64_ADR_ADRP::A64_ADR_ADRP(aarch64_pcrel_insts *inst) : A64_INST_PC_REL(inst) { A64_ADR_ADRP::A64_ADR_ADRP(aarch64_adr_adrp *inst) : A64_INST_PC_REL(inst) {
decode(inst); decode(inst);
} }
int A64_ADR_ADRP::getImmPCRel() {
U32 hi = static_cast<U32>(get()->immhi);
U32 lo = get()->immlo;
U32 offset = (hi << IMM_LO_W) | lo;
int width = IMM_HI_W + IMM_LO_W;
return ExtractSignedBitfield32(width - 1, 0, offset);
}
ADDR A64_ADR_ADRP::getImmPCOffset() { ADDR A64_ADR_ADRP::getImmPCOffset() {
ADDR offset = static_cast<ADDR>(getImmPCRel()); ADDR offset = static_cast<ADDR>(getImmPCRel());
...@@ -49,7 +58,7 @@ ADDR A64_ADR_ADRP::getImmPCOffset() { ...@@ -49,7 +58,7 @@ ADDR A64_ADR_ADRP::getImmPCOffset() {
} }
ADDR A64_ADR_ADRP::getImmPCOffsetTarget() { ADDR A64_ADR_ADRP::getImmPCOffsetTarget() {
Instruction* base = AlignDown(this, PAGE_SIZE); aarch64_adr_adrp* base = AlignDown(get(), PAGE_SIZE);
return reinterpret_cast<ADDR>(getImmPCOffset() + (ADDR) base); return reinterpret_cast<ADDR>(getImmPCOffset() + (ADDR) base);
} }
...@@ -62,7 +71,7 @@ A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, RegisterA64 *rd, int imme) : op( ...@@ -62,7 +71,7 @@ A64_ADR_ADRP::A64_ADR_ADRP(A64_ADR_ADRP::OP op, RegisterA64 *rd, int imme) : op(
assembler(); assembler();
} }
void A64_ADR_ADRP::decode(aarch64_pcrel_insts *decode) { void A64_ADR_ADRP::decode(aarch64_adr_adrp *decode) {
} }
...@@ -110,4 +119,25 @@ void A64_MOV_WIDE::decode(aarch64_mov_wide *inst) { ...@@ -110,4 +119,25 @@ void A64_MOV_WIDE::decode(aarch64_mov_wide *inst) {
A64_B_BL::A64_B_BL() {} A64_B_BL::A64_B_BL() {}
A64_B_BL::A64_B_BL(aarch64_b_bl *inst) : InstructionA64(inst) {} A64_B_BL::A64_B_BL(aarch64_b_bl *inst) : A64_INST_PC_REL(inst) {
decode(inst);
}
A64_B_BL::A64_B_BL(A64_B_BL::OP op, U32 imme) : op(op), imme(imme) {
assembler();
}
void A64_B_BL::decode(aarch64_b_bl *inst) {
op = static_cast<OP>(inst->op);
imme = inst->imm26;
}
void A64_B_BL::assembler() {
get()->opcode = B_BL_OPCODE;
get()->op = op;
get()->imm26 = imme;
}
int A64_B_BL::getImmBranch() {
}
...@@ -15,27 +15,34 @@ namespace SandHook { ...@@ -15,27 +15,34 @@ namespace SandHook {
namespace Asm { namespace Asm {
template<typename InstStruct> template<typename Inst>
class InstructionA64 : public Instruction<InstStruct> { class InstructionA64 : public Instruction<Inst> {
public: public:
InstructionA64() {} InstructionA64() {}
InstructionA64(InstStruct *inst) : Instruction<InstStruct>(inst) {} InstructionA64(Inst *inst) : Instruction<Inst>(inst) {}
InstStruct mask(InstStruct raw) { Inst mask(Inst raw) {
return raw & *(this->get()); return raw & *(this->get());
} }
U8 size() override;
static inline U32 SignExtend64(unsigned int bits, U64 value) {
U32 C = (U32) ((-1) << (bits - (U32) 1)); // NOLINT
return (value + C) ^ C;
}
bool IsPCRelAddressing() { bool IsPCRelAddressing() {
return mask(PCRelAddressingFMask) == PCRelAddressingFixed; return mask(PCRelAddressingFMask) == PCRelAddressingFixed;
} }
InstType instType() { InstType instType() override {
return A64; return A64;
} }
Arch arch() { Arch arch() override {
return arm64; return arm64;
} }
...@@ -47,15 +54,13 @@ namespace SandHook { ...@@ -47,15 +54,13 @@ namespace SandHook {
}; };
template <typename Inst>
class A64_INST_PC_REL : public InstructionA64<aarch64_pcrel_insts> { class A64_INST_PC_REL : public InstructionA64<Inst> {
public: public:
A64_INST_PC_REL(); A64_INST_PC_REL();
A64_INST_PC_REL(aarch64_pcrel_insts *inst); A64_INST_PC_REL(Inst *inst);
virtual int getImmPCRel();
virtual ADDR getImmPCOffset(); virtual ADDR getImmPCOffset();
...@@ -65,7 +70,7 @@ namespace SandHook { ...@@ -65,7 +70,7 @@ namespace SandHook {
class A64_ADR_ADRP : public A64_INST_PC_REL { class A64_ADR_ADRP : public A64_INST_PC_REL<aarch64_adr_adrp> {
public: public:
enum OP { enum OP {
...@@ -75,25 +80,27 @@ namespace SandHook { ...@@ -75,25 +80,27 @@ namespace SandHook {
A64_ADR_ADRP(); A64_ADR_ADRP();
A64_ADR_ADRP(aarch64_pcrel_insts *inst); A64_ADR_ADRP(aarch64_adr_adrp *inst);
A64_ADR_ADRP(OP op, RegisterA64 *rd, int imme); A64_ADR_ADRP(OP op, RegisterA64 *rd, int imme);
inline U32 instCode() override { U32 instCode() override {
return isADRP() ? PCRelAddressingOp::ADRP : PCRelAddressingOp::ADR; return isADRP() ? PCRelAddressingOp::ADRP : PCRelAddressingOp::ADR;
} }
inline bool isADRP() { bool isADRP() {
return get()->op == OP::ADRP; return get()->op == OP::ADRP;
} }
ADDR getImmPCOffset(); int getImmPCRel();
ADDR getImmPCOffset() override;
ADDR getImmPCOffsetTarget(); ADDR getImmPCOffsetTarget() override;
int getImm(); int getImm();
void decode(aarch64_pcrel_insts *decode) override; void decode(aarch64_adr_adrp *decode) override;
void assembler() override; void assembler() override;
...@@ -168,7 +175,7 @@ namespace SandHook { ...@@ -168,7 +175,7 @@ namespace SandHook {
class A64_B_BL : public InstructionA64<aarch64_b_bl> { class A64_B_BL : public A64_INST_PC_REL<aarch64_b_bl> {
public: public:
enum OP { enum OP {
...@@ -180,10 +187,19 @@ namespace SandHook { ...@@ -180,10 +187,19 @@ namespace SandHook {
A64_B_BL(aarch64_b_bl *inst); A64_B_BL(aarch64_b_bl *inst);
inline U32 instCode() { A64_B_BL(OP op, U32 imme);
inline U32 instCode() override {
return op == B ? UnconditionalBranchOp::B : UnconditionalBranchOp ::BL; return op == B ? UnconditionalBranchOp::B : UnconditionalBranchOp ::BL;
}; };
int getImmBranch() override;
void decode(aarch64_b_bl *decode) override;
void assembler() override;
private: private:
OP op; OP op;
U32 imme; U32 imme;
......
...@@ -39,7 +39,7 @@ enum ImmBranchType { ...@@ -39,7 +39,7 @@ enum ImmBranchType {
#define IMM_LO_W 2 #define IMM_LO_W 2
#define IMM_HI_W 19 #define IMM_HI_W 19
struct aarch64_pcrel_insts { struct aarch64_adr_adrp {
InstA64 op:1; InstA64 op:1;
InstA64 immlo:IMM_LO_W; InstA64 immlo:IMM_LO_W;
InstA64 opcode:5; InstA64 opcode:5;
...@@ -47,8 +47,6 @@ struct aarch64_pcrel_insts { ...@@ -47,8 +47,6 @@ struct aarch64_pcrel_insts {
InstA64 rd:5; InstA64 rd:5;
}; };
struct aarch64_adr_adrp : public aarch64_pcrel_insts {};
#define MOV_WIDE_OPCODE 0b100101 #define MOV_WIDE_OPCODE 0b100101
struct aarch64_mov_wide { struct aarch64_mov_wide {
...@@ -60,10 +58,10 @@ struct aarch64_mov_wide { ...@@ -60,10 +58,10 @@ struct aarch64_mov_wide {
InstA64 rd:5; InstA64 rd:5;
}; };
#define B_BL_OPCODE 0b00101
struct aarch64_b_bl { struct aarch64_b_bl {
InstA64 op:1; InstA64 op:1;
InstA64 opc:5; InstA64 opcode:5;
InstA64 imm26:26; InstA64 imm26:26;
}; };
......
...@@ -161,19 +161,19 @@ inline int32_t ExtractSignedBitfield32(int msb, int lsb, int32_t x) { ...@@ -161,19 +161,19 @@ inline int32_t ExtractSignedBitfield32(int msb, int lsb, int32_t x) {
} }
static inline int16_t BITS16L(int32_t value) { inline int16_t BITS16L(int32_t value) {
return static_cast<int16_t>(value); return static_cast<int16_t>(value);
} }
static inline int16_t BITS16H(int32_t value) { inline int16_t BITS16H(int32_t value) {
return static_cast<int16_t>(value >> 16); return static_cast<int16_t>(value >> 16);
} }
static inline int32_t BITS32L(int64_t value) { inline int32_t BITS32L(int64_t value) {
return static_cast<int32_t>(value); return static_cast<int32_t>(value);
} }
static inline int32_t BITS32H(int64_t value) { inline int32_t BITS32H(int64_t value) {
return static_cast<int32_t>(value >> 32); return static_cast<int32_t>(value >> 32);
} }
...@@ -181,4 +181,7 @@ static inline int32_t BITS32H(int64_t value) { ...@@ -181,4 +181,7 @@ static inline int32_t BITS32H(int64_t value) {
#define LFT(a, b, c) ((a & ((1 << b) - 1)) << c) #define LFT(a, b, c) ((a & ((1 << b) - 1)) << c)
#define RHT(a, b, c) ((a >> c) & ((1 << b) - 1)) #define RHT(a, b, c) ((a >> c) & ((1 << b) - 1))
//big little edd
#endif //SANDHOOK_BASE_H #endif //SANDHOOK_BASE_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