formatting/naming styles
This commit is contained in:
parent
21c874186d
commit
82e6abc1ee
1 changed files with 297 additions and 309 deletions
|
|
@ -38,300 +38,298 @@
|
|||
|
||||
namespace detour_arm64_disasm
|
||||
{
|
||||
union AddImm12
|
||||
union add_imm12
|
||||
{
|
||||
uint32_t Assembled;
|
||||
uint32_t assembled;
|
||||
struct
|
||||
{
|
||||
uint32_t Rd : 5; // Destination register
|
||||
uint32_t Rn : 5; // Source register
|
||||
uint32_t Imm12 : 12; // 12-bit immediate
|
||||
uint32_t Shift : 2; // shift (must be 0 or 1)
|
||||
uint32_t Opcode1 : 7; // Must be 0010001 == 0x11
|
||||
uint32_t Size : 1; // 0 = 32-bit, 1 = 64-bit
|
||||
uint32_t rd : 5; // Destination register
|
||||
uint32_t rn : 5; // Source register
|
||||
uint32_t imm12 : 12; // 12-bit immediate
|
||||
uint32_t shift : 2; // shift (must be 0 or 1)
|
||||
uint32_t opcode1 : 7; // Must be 0010001 == 0x11
|
||||
uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit
|
||||
} s;
|
||||
static uint32_t Assemble(uint32_t size, uint32_t rd, uint32_t rn, uint32_t imm, uint32_t shift)
|
||||
static uint32_t assemble(uint32_t size, uint32_t rd, uint32_t rn, uint32_t imm, uint32_t shift)
|
||||
{
|
||||
AddImm12 temp;
|
||||
temp.s.Rd = rd;
|
||||
temp.s.Rn = rn;
|
||||
temp.s.Imm12 = imm & 0xfff;
|
||||
temp.s.Shift = shift;
|
||||
temp.s.Opcode1 = 0x11;
|
||||
temp.s.Size = size;
|
||||
return temp.Assembled;
|
||||
add_imm12 temp;
|
||||
temp.s.rd = rd;
|
||||
temp.s.rn = rn;
|
||||
temp.s.imm12 = imm & 0xfff;
|
||||
temp.s.shift = shift;
|
||||
temp.s.opcode1 = 0x11;
|
||||
temp.s.size = size;
|
||||
return temp.assembled;
|
||||
}
|
||||
static uint32_t AssembleAdd32(uint32_t rd, uint32_t rn, uint32_t imm, uint32_t shift) { return Assemble(0, rd, rn, imm, shift); }
|
||||
static uint32_t AssembleAdd64(uint32_t rd, uint32_t rn, uint32_t imm, uint32_t shift) { return Assemble(1, rd, rn, imm, shift); }
|
||||
static uint32_t assemble_add_32(const uint32_t rd, const uint32_t rn, const uint32_t imm, const uint32_t shift) { return assemble(0, rd, rn, imm, shift); }
|
||||
static uint32_t assemble_add_64(const uint32_t rd, const uint32_t rn, const uint32_t imm, const uint32_t shift) { return assemble(1, rd, rn, imm, shift); }
|
||||
};
|
||||
|
||||
union Adr19
|
||||
union adr19
|
||||
{
|
||||
uint32_t Assembled;
|
||||
uint32_t assembled;
|
||||
struct
|
||||
{
|
||||
uint32_t Rd : 5; // Destination register
|
||||
uint32_t Imm19 : 19; // 19-bit upper immediate
|
||||
uint32_t Opcode1 : 5; // Must be 10000 == 0x10
|
||||
uint32_t Imm2 : 2; // 2-bit lower immediate
|
||||
uint32_t Type : 1; // 0 = ADR, 1 = ADRP
|
||||
uint32_t rd : 5; // Destination register
|
||||
uint32_t imm19 : 19; // 19-bit upper immediate
|
||||
uint32_t opcode1 : 5; // Must be 10000 == 0x10
|
||||
uint32_t imm2 : 2; // 2-bit lower immediate
|
||||
uint32_t type : 1; // 0 = ADR, 1 = ADRP
|
||||
} s;
|
||||
inline int32_t Imm() const { uint32_t Imm = (s.Imm19 << 2) | s.Imm2; return (int32_t)(Imm << 11) >> 11; }
|
||||
static uint32_t Assemble(uint32_t type, uint32_t rd, int32_t delta)
|
||||
inline int32_t imm() const { uint32_t Imm = (s.imm19 << 2) | s.imm2; return (int32_t)(Imm << 11) >> 11; }
|
||||
static uint32_t assemble(uint32_t type, uint32_t rd, int32_t delta)
|
||||
{
|
||||
Adr19 temp;
|
||||
temp.s.Rd = rd;
|
||||
temp.s.Imm19 = (delta >> 2) & 0x7ffff;
|
||||
temp.s.Opcode1 = 0x10;
|
||||
temp.s.Imm2 = delta & 3;
|
||||
temp.s.Type = type;
|
||||
return temp.Assembled;
|
||||
adr19 temp;
|
||||
temp.s.rd = rd;
|
||||
temp.s.imm19 = (delta >> 2) & 0x7ffff;
|
||||
temp.s.opcode1 = 0x10;
|
||||
temp.s.imm2 = delta & 3;
|
||||
temp.s.type = type;
|
||||
return temp.assembled;
|
||||
}
|
||||
static uint32_t AssembleAdr(uint32_t rd, int32_t delta) { return Assemble(0, rd, delta); }
|
||||
static uint32_t AssembleAdrp(uint32_t rd, int32_t delta) { return Assemble(1, rd, delta); }
|
||||
static uint32_t assemble_adr(uint32_t rd, int32_t delta) { return assemble(0, rd, delta); }
|
||||
static uint32_t assemble_adrp(uint32_t rd, int32_t delta) { return assemble(1, rd, delta); }
|
||||
};
|
||||
|
||||
union Bcc19
|
||||
union bcc19
|
||||
{
|
||||
uint32_t Assembled;
|
||||
uint32_t assembled;
|
||||
struct
|
||||
{
|
||||
uint32_t Condition : 4; // Condition
|
||||
uint32_t Opcode1 : 1; // Must be 0
|
||||
uint32_t Imm19 : 19; // 19-bit immediate
|
||||
uint32_t Opcode2 : 8; // Must be 01010100 == 0x54
|
||||
uint32_t condition : 4; // Condition
|
||||
uint32_t opcode1 : 1; // Must be 0
|
||||
uint32_t imm19 : 19; // 19-bit immediate
|
||||
uint32_t opcode2 : 8; // Must be 01010100 == 0x54
|
||||
} s;
|
||||
inline int32_t Imm() const { return (int32_t)(s.Imm19 << 13) >> 11; }
|
||||
static uint32_t AssembleBcc(uint32_t condition, int32_t delta)
|
||||
inline int32_t imm() const { return (int32_t)(s.imm19 << 13) >> 11; }
|
||||
static uint32_t assemble_bcc(uint32_t condition, int32_t delta)
|
||||
{
|
||||
Bcc19 temp;
|
||||
temp.s.Condition = condition;
|
||||
temp.s.Opcode1 = 0;
|
||||
temp.s.Imm19 = delta >> 2;
|
||||
temp.s.Opcode2 = 0x54;
|
||||
return temp.Assembled;
|
||||
bcc19 temp;
|
||||
temp.s.condition = condition;
|
||||
temp.s.opcode1 = 0;
|
||||
temp.s.imm19 = delta >> 2;
|
||||
temp.s.opcode2 = 0x54;
|
||||
return temp.assembled;
|
||||
}
|
||||
};
|
||||
|
||||
union Branch26
|
||||
union branch26
|
||||
{
|
||||
uint32_t Assembled;
|
||||
uint32_t assembled;
|
||||
struct
|
||||
{
|
||||
uint32_t Imm26 : 26; // 26-bit immediate
|
||||
uint32_t Opcode1 : 5; // Must be 00101 == 0x5
|
||||
uint32_t Link : 1; // 0 = B, 1 = BL
|
||||
uint32_t imm26 : 26; // 26-bit immediate
|
||||
uint32_t opcode1 : 5; // Must be 00101 == 0x5
|
||||
uint32_t link : 1; // 0 = B, 1 = BL
|
||||
} s;
|
||||
inline int32_t Imm() const { return (int32_t)(s.Imm26 << 6) >> 4; }
|
||||
static uint32_t Assemble(uint32_t link, int32_t delta)
|
||||
inline int32_t imm() const { return (int32_t)(s.imm26 << 6) >> 4; }
|
||||
static uint32_t assemble(uint32_t link, int32_t delta)
|
||||
{
|
||||
Branch26 temp;
|
||||
temp.s.Imm26 = delta >> 2;
|
||||
temp.s.Opcode1 = 0x5;
|
||||
temp.s.Link = link;
|
||||
return temp.Assembled;
|
||||
branch26 temp;
|
||||
temp.s.imm26 = delta >> 2;
|
||||
temp.s.opcode1 = 0x5;
|
||||
temp.s.link = link;
|
||||
return temp.assembled;
|
||||
}
|
||||
static uint32_t AssembleB(int32_t delta) { return Assemble(0, delta); }
|
||||
static uint32_t AssembleBl(int32_t delta) { return Assemble(1, delta); }
|
||||
static uint32_t assemble_b(int32_t delta) { return assemble(0, delta); }
|
||||
static uint32_t assemble_bl(int32_t delta) { return assemble(1, delta); }
|
||||
};
|
||||
|
||||
union Br
|
||||
union br
|
||||
{
|
||||
uint32_t Assembled;
|
||||
uint32_t assembled;
|
||||
struct
|
||||
{
|
||||
uint32_t Opcode1 : 5; // Must be 00000 == 0
|
||||
uint32_t Rn : 5; // Register number
|
||||
uint32_t Opcode2 : 22; // Must be 1101011000011111000000 == 0x3587c0 for Br
|
||||
// 0x358fc0 for Brl
|
||||
uint32_t opcode1 : 5; // Must be 00000 == 0
|
||||
uint32_t rn : 5; // Register number
|
||||
uint32_t opcode2 : 22; // Must be 1101011000011111000000 == 0x3587c0 for Br
|
||||
// 0x358fc0 for Brl
|
||||
} s;
|
||||
static uint32_t Assemble(uint32_t rn, bool link)
|
||||
static uint32_t assemble(uint32_t rn, bool link)
|
||||
{
|
||||
Br temp;
|
||||
temp.s.Opcode1 = 0;
|
||||
temp.s.Rn = rn;
|
||||
temp.s.Opcode2 = 0x3587c0;
|
||||
br temp;
|
||||
temp.s.opcode1 = 0;
|
||||
temp.s.rn = rn;
|
||||
temp.s.opcode2 = 0x3587c0;
|
||||
if (link)
|
||||
temp.Assembled |= 0x00200000;
|
||||
return temp.Assembled;
|
||||
temp.assembled |= 0x00200000;
|
||||
return temp.assembled;
|
||||
}
|
||||
static uint32_t AssembleBr(uint32_t rn)
|
||||
static uint32_t assemble_br(uint32_t rn)
|
||||
{
|
||||
return Assemble(rn, false);
|
||||
return assemble(rn, false);
|
||||
}
|
||||
static uint32_t AssembleBrl(uint32_t rn)
|
||||
static uint32_t assemble_brl(uint32_t rn)
|
||||
{
|
||||
return Assemble(rn, true);
|
||||
return assemble(rn, true);
|
||||
}
|
||||
};
|
||||
|
||||
union Cbz19
|
||||
union cbz19
|
||||
{
|
||||
uint32_t Assembled;
|
||||
uint32_t assembled;
|
||||
struct
|
||||
{
|
||||
uint32_t Rt : 5; // Register to test
|
||||
uint32_t Imm19 : 19; // 19-bit immediate
|
||||
uint32_t Nz : 1; // 0 = CBZ, 1 = CBNZ
|
||||
uint32_t Opcode1 : 6; // Must be 011010 == 0x1a
|
||||
uint32_t Size : 1; // 0 = 32-bit, 1 = 64-bit
|
||||
uint32_t rt : 5; // Register to test
|
||||
uint32_t imm19 : 19; // 19-bit immediate
|
||||
uint32_t nz : 1; // 0 = CBZ, 1 = CBNZ
|
||||
uint32_t opcode1 : 6; // Must be 011010 == 0x1a
|
||||
uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit
|
||||
} s;
|
||||
inline int32_t Imm() const { return (int32_t)(s.Imm19 << 13) >> 11; }
|
||||
static uint32_t Assemble(uint32_t size, uint32_t nz, uint32_t rt, int32_t delta)
|
||||
inline int32_t imm() const { return (int32_t)(s.imm19 << 13) >> 11; }
|
||||
static uint32_t assemble(uint32_t size, uint32_t nz, uint32_t rt, int32_t delta)
|
||||
{
|
||||
Cbz19 temp;
|
||||
temp.s.Rt = rt;
|
||||
temp.s.Imm19 = delta >> 2;
|
||||
temp.s.Nz = nz;
|
||||
temp.s.Opcode1 = 0x1a;
|
||||
temp.s.Size = size;
|
||||
return temp.Assembled;
|
||||
cbz19 temp;
|
||||
temp.s.rt = rt;
|
||||
temp.s.imm19 = delta >> 2;
|
||||
temp.s.nz = nz;
|
||||
temp.s.opcode1 = 0x1a;
|
||||
temp.s.size = size;
|
||||
return temp.assembled;
|
||||
}
|
||||
};
|
||||
|
||||
union LdrLit19
|
||||
union ldr_lit19
|
||||
{
|
||||
uint32_t Assembled;
|
||||
uint32_t assembled;
|
||||
struct
|
||||
{
|
||||
uint32_t Rt : 5; // Destination register
|
||||
uint32_t Imm19 : 19; // 19-bit immediate
|
||||
uint32_t Opcode1 : 2; // Must be 0
|
||||
uint32_t FpNeon : 1; // 0 = LDR Wt/LDR Xt/LDRSW/PRFM, 1 = LDR St/LDR Dt/LDR Qt
|
||||
uint32_t Opcode2 : 3; // Must be 011 = 3
|
||||
uint32_t Size : 2; // 00 = LDR Wt/LDR St, 01 = LDR Xt/LDR Dt, 10 = LDRSW/LDR Qt, 11 = PRFM/invalid
|
||||
uint32_t rt : 5; // Destination register
|
||||
uint32_t imm19 : 19; // 19-bit immediate
|
||||
uint32_t opcode1 : 2; // Must be 0
|
||||
uint32_t fp_neon : 1; // 0 = LDR Wt/LDR Xt/LDRSW/PRFM, 1 = LDR St/LDR Dt/LDR Qt
|
||||
uint32_t opcode2 : 3; // Must be 011 = 3
|
||||
uint32_t size : 2; // 00 = LDR Wt/LDR St, 01 = LDR Xt/LDR Dt, 10 = LDRSW/LDR Qt, 11 = PRFM/invalid
|
||||
} s;
|
||||
inline int32_t Imm() const { return (int32_t)(s.Imm19 << 13) >> 11; }
|
||||
static uint32_t Assemble(uint32_t size, uint32_t fpneon, uint32_t rt, int32_t delta)
|
||||
inline int32_t imm() const { return (int32_t)(s.imm19 << 13) >> 11; }
|
||||
static uint32_t assemble(uint32_t size, uint32_t fpneon, uint32_t rt, int32_t delta)
|
||||
{
|
||||
LdrLit19 temp;
|
||||
temp.s.Rt = rt;
|
||||
temp.s.Imm19 = delta >> 2;
|
||||
temp.s.Opcode1 = 0;
|
||||
temp.s.FpNeon = fpneon;
|
||||
temp.s.Opcode2 = 3;
|
||||
temp.s.Size = size;
|
||||
return temp.Assembled;
|
||||
ldr_lit19 temp;
|
||||
temp.s.rt = rt;
|
||||
temp.s.imm19 = delta >> 2;
|
||||
temp.s.opcode1 = 0;
|
||||
temp.s.fp_neon = fpneon;
|
||||
temp.s.opcode2 = 3;
|
||||
temp.s.size = size;
|
||||
return temp.assembled;
|
||||
}
|
||||
};
|
||||
|
||||
union LdrFpNeonImm9
|
||||
union ldr_fp_neon_imm9
|
||||
{
|
||||
uint32_t Assembled;
|
||||
uint32_t assembled;
|
||||
struct
|
||||
{
|
||||
uint32_t Rt : 5; // Destination register
|
||||
uint32_t Rn : 5; // Base register
|
||||
uint32_t Imm12 : 12; // 12-bit immediate
|
||||
uint32_t Opcode1 : 1; // Must be 1 == 1
|
||||
uint32_t Opc : 1; // Part of size
|
||||
uint32_t Opcode2 : 6; // Must be 111101 == 0x3d
|
||||
uint32_t Size : 2; // Size (0=8-bit, 1=16-bit, 2=32-bit, 3=64-bit, 4=128-bit)
|
||||
uint32_t rt : 5; // Destination register
|
||||
uint32_t rn : 5; // Base register
|
||||
uint32_t imm12 : 12; // 12-bit immediate
|
||||
uint32_t opcode1 : 1; // Must be 1 == 1
|
||||
uint32_t opc : 1; // Part of size
|
||||
uint32_t opcode2 : 6; // Must be 111101 == 0x3d
|
||||
uint32_t size : 2; // Size (0=8-bit, 1=16-bit, 2=32-bit, 3=64-bit, 4=128-bit)
|
||||
} s;
|
||||
static uint32_t Assemble(uint32_t size, uint32_t rt, uint32_t rn, uint32_t imm)
|
||||
static uint32_t assemble(uint32_t size, uint32_t rt, uint32_t rn, uint32_t imm)
|
||||
{
|
||||
LdrFpNeonImm9 temp;
|
||||
temp.s.Rt = rt;
|
||||
temp.s.Rn = rn;
|
||||
temp.s.Imm12 = imm;
|
||||
temp.s.Opcode1 = 1;
|
||||
temp.s.Opc = size >> 2;
|
||||
temp.s.Opcode2 = 0x3d;
|
||||
temp.s.Size = size & 3;
|
||||
return temp.Assembled;
|
||||
ldr_fp_neon_imm9 temp;
|
||||
temp.s.rt = rt;
|
||||
temp.s.rn = rn;
|
||||
temp.s.imm12 = imm;
|
||||
temp.s.opcode1 = 1;
|
||||
temp.s.opc = size >> 2;
|
||||
temp.s.opcode2 = 0x3d;
|
||||
temp.s.size = size & 3;
|
||||
return temp.assembled;
|
||||
}
|
||||
};
|
||||
|
||||
union Mov16
|
||||
union mov16
|
||||
{
|
||||
uint32_t Assembled;
|
||||
uint32_t assembled;
|
||||
struct
|
||||
{
|
||||
uint32_t Rd : 5; // Destination register
|
||||
uint32_t Imm16 : 16; // Immediate
|
||||
uint32_t Shift : 2; // Shift amount (0=0, 1=16, 2=32, 3=48)
|
||||
uint32_t Opcode : 6; // Must be 100101 == 0x25
|
||||
uint32_t Type : 2; // 0 = MOVN, 1 = reserved, 2 = MOVZ, 3 = MOVK
|
||||
uint32_t Size : 1; // 0 = 32-bit, 1 = 64-bit
|
||||
uint32_t rd : 5; // Destination register
|
||||
uint32_t imm16 : 16; // Immediate
|
||||
uint32_t shift : 2; // Shift amount (0=0, 1=16, 2=32, 3=48)
|
||||
uint32_t opcode : 6; // Must be 100101 == 0x25
|
||||
uint32_t type : 2; // 0 = MOVN, 1 = reserved, 2 = MOVZ, 3 = MOVK
|
||||
uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit
|
||||
} s;
|
||||
static uint32_t Assemble(uint32_t size, uint32_t type, uint32_t rd, uint32_t imm, uint32_t shift)
|
||||
static uint32_t assemble(uint32_t size, uint32_t type, uint32_t rd, uint32_t imm, uint32_t shift)
|
||||
{
|
||||
Mov16 temp;
|
||||
temp.s.Rd = rd;
|
||||
temp.s.Imm16 = imm;
|
||||
temp.s.Shift = shift;
|
||||
temp.s.Opcode = 0x25;
|
||||
temp.s.Type = type;
|
||||
temp.s.Size = size;
|
||||
return temp.Assembled;
|
||||
mov16 temp;
|
||||
temp.s.rd = rd;
|
||||
temp.s.imm16 = imm;
|
||||
temp.s.shift = shift;
|
||||
temp.s.opcode = 0x25;
|
||||
temp.s.type = type;
|
||||
temp.s.size = size;
|
||||
return temp.assembled;
|
||||
}
|
||||
static uint32_t AssembleMovn32(uint32_t rd, uint32_t imm, uint32_t shift) { return Assemble(0, 0, rd, imm, shift); }
|
||||
static uint32_t AssembleMovn64(uint32_t rd, uint32_t imm, uint32_t shift) { return Assemble(1, 0, rd, imm, shift); }
|
||||
static uint32_t AssembleMovz32(uint32_t rd, uint32_t imm, uint32_t shift) { return Assemble(0, 2, rd, imm, shift); }
|
||||
static uint32_t AssembleMovz64(uint32_t rd, uint32_t imm, uint32_t shift) { return Assemble(1, 2, rd, imm, shift); }
|
||||
static uint32_t AssembleMovk32(uint32_t rd, uint32_t imm, uint32_t shift) { return Assemble(0, 3, rd, imm, shift); }
|
||||
static uint32_t AssembleMovk64(uint32_t rd, uint32_t imm, uint32_t shift) { return Assemble(1, 3, rd, imm, shift); }
|
||||
static uint32_t assemble_movn32(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(0, 0, rd, imm, shift); }
|
||||
static uint32_t assemble_movn64(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(1, 0, rd, imm, shift); }
|
||||
static uint32_t assemble_movz32(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(0, 2, rd, imm, shift); }
|
||||
static uint32_t assemble_movz64(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(1, 2, rd, imm, shift); }
|
||||
static uint32_t assemble_movk32(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(0, 3, rd, imm, shift); }
|
||||
static uint32_t assemble_movk64(uint32_t rd, uint32_t imm, uint32_t shift) { return assemble(1, 3, rd, imm, shift); }
|
||||
};
|
||||
|
||||
union Tbz14
|
||||
union tbz14
|
||||
{
|
||||
uint32_t Assembled;
|
||||
uint32_t assembled;
|
||||
struct
|
||||
{
|
||||
uint32_t Rt : 5; // Register to test
|
||||
uint32_t Imm14 : 14; // 14-bit immediate
|
||||
uint32_t Bit : 5; // 5-bit index
|
||||
uint32_t Nz : 1; // 0 = TBZ, 1 = TBNZ
|
||||
uint32_t Opcode1 : 6; // Must be 011011 == 0x1b
|
||||
uint32_t Size : 1; // 0 = 32-bit, 1 = 64-bit
|
||||
uint32_t rt : 5; // Register to test
|
||||
uint32_t imm14 : 14; // 14-bit immediate
|
||||
uint32_t bit : 5; // 5-bit index
|
||||
uint32_t nz : 1; // 0 = TBZ, 1 = TBNZ
|
||||
uint32_t opcode1 : 6; // Must be 011011 == 0x1b
|
||||
uint32_t size : 1; // 0 = 32-bit, 1 = 64-bit
|
||||
} s;
|
||||
inline int32_t Imm() const { return (int32_t)(s.Imm14 << 18) >> 16; }
|
||||
static uint32_t Assemble(uint32_t size, uint32_t nz, uint32_t rt, uint32_t bit, int32_t delta)
|
||||
inline int32_t imm() const { return (int32_t)(s.imm14 << 18) >> 16; }
|
||||
static uint32_t assemble(uint32_t size, uint32_t nz, uint32_t rt, uint32_t bit, int32_t delta)
|
||||
{
|
||||
Tbz14 temp;
|
||||
temp.s.Rt = rt;
|
||||
temp.s.Imm14 = delta >> 2;
|
||||
temp.s.Bit = bit;
|
||||
temp.s.Nz = nz;
|
||||
temp.s.Opcode1 = 0x1b;
|
||||
temp.s.Size = size;
|
||||
return temp.Assembled;
|
||||
tbz14 temp;
|
||||
temp.s.rt = rt;
|
||||
temp.s.imm14 = delta >> 2;
|
||||
temp.s.bit = bit;
|
||||
temp.s.nz = nz;
|
||||
temp.s.opcode1 = 0x1b;
|
||||
temp.s.size = size;
|
||||
return temp.assembled;
|
||||
}
|
||||
};
|
||||
|
||||
static uint8_t PureCopy32(uint8_t* pSource, uint8_t* pDest);
|
||||
static uint8_t EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, uint64_t immediate);
|
||||
static uint8_t CopyAdr(uint8_t* pSource, uint8_t* pDest, uint32_t instruction) ;
|
||||
static uint8_t CopyBcc(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
|
||||
static uint8_t CopyB(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
|
||||
static uint8_t CopyBl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
|
||||
static uint8_t CopyB_or_Bl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction, bool link);
|
||||
static uint8_t CopyCbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
|
||||
static uint8_t CopyTbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
|
||||
static uint8_t CopyLdrLiteral(uint8_t* pSource, uint8_t* pDest, uint32_t instruction);
|
||||
static uint8_t pure_copy32(uint8_t* source, uint8_t* dest);
|
||||
static uint8_t emit_mov_immediate(uint32_t*& dst_inst, uint8_t rd, uint64_t immediate);
|
||||
static uint8_t copy_adr(uint8_t* source, uint8_t* dest, uint32_t instruction) ;
|
||||
static uint8_t copy_bcc(uint8_t* source, uint8_t* dest, uint32_t instruction);
|
||||
static uint8_t copy_b_or_bl(uint8_t* source, uint8_t* dest, uint32_t instruction, bool link);
|
||||
static uint8_t copy_cbz(uint8_t* source, uint8_t* dest, uint32_t instruction);
|
||||
static uint8_t copy_tbz(uint8_t* source, uint8_t* dest, uint32_t instruction);
|
||||
static uint8_t copy_ldr_literal(uint8_t* source, uint8_t* dest, uint32_t instruction);
|
||||
|
||||
static uint32_t GetInstruction(uint8_t* pSource)
|
||||
static uint32_t get_instruction(uint8_t* source)
|
||||
{
|
||||
return ((uint32_t*)pSource)[0];
|
||||
return ((uint32_t*)source)[0];
|
||||
}
|
||||
|
||||
static uint8_t EmitInstruction(uint32_t*& pDstInst, uint32_t instruction)
|
||||
static uint8_t emit_instruction(uint32_t*& dst_inst, uint32_t instruction)
|
||||
{
|
||||
*pDstInst++ = instruction;
|
||||
*dst_inst++ = instruction;
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
};
|
||||
|
||||
uint8_t detour_arm64_disasm::PureCopy32(uint8_t* pSource, uint8_t* pDest)
|
||||
uint8_t detour_arm64_disasm::pure_copy32(uint8_t* source, uint8_t* dest)
|
||||
{
|
||||
*(uint32_t *)pDest = *(uint32_t*)pSource;
|
||||
*(uint32_t *)dest = *(uint32_t*)source;
|
||||
return sizeof(uint32_t);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////// Disassembler Code.
|
||||
//
|
||||
|
||||
uint8_t detour_arm64_disasm::EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, uint64_t immediate)
|
||||
uint8_t detour_arm64_disasm::emit_mov_immediate(uint32_t*& dst_inst, uint8_t rd, uint64_t immediate)
|
||||
{
|
||||
uint32_t piece[4];
|
||||
piece[3] = (uint32_t)((immediate >> 48) & 0xffff);
|
||||
|
|
@ -343,7 +341,7 @@ uint8_t detour_arm64_disasm::EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, u
|
|||
// special case: MOVN with 32-bit dest
|
||||
if (piece[3] == 0 && piece[2] == 0 && piece[1] == 0xffff)
|
||||
{
|
||||
EmitInstruction(pDstInst, Mov16::AssembleMovn32(rd, piece[0] ^ 0xffff, 0));
|
||||
emit_instruction(dst_inst, mov16::assemble_movn32(rd, piece[0] ^ 0xffff, 0));
|
||||
count++;
|
||||
}
|
||||
|
||||
|
|
@ -352,29 +350,29 @@ uint8_t detour_arm64_disasm::EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, u
|
|||
{
|
||||
int zero_pieces = (piece[3] == 0x0000) + (piece[2] == 0x0000) + (piece[1] == 0x0000) + (piece[0] == 0x0000);
|
||||
int ffff_pieces = (piece[3] == 0xffff) + (piece[2] == 0xffff) + (piece[1] == 0xffff) + (piece[0] == 0xffff);
|
||||
uint32_t defaultPiece = (ffff_pieces > zero_pieces) ? 0xffff : 0x0000;
|
||||
uint32_t default_piece = (ffff_pieces > zero_pieces) ? 0xffff : 0x0000;
|
||||
bool first = true;
|
||||
for (int pieceNum = 3; pieceNum >= 0; pieceNum--)
|
||||
for (int piece_num = 3; piece_num >= 0; piece_num--)
|
||||
{
|
||||
uint32_t curPiece = piece[pieceNum];
|
||||
if (curPiece != defaultPiece || (pieceNum == 0 && first))
|
||||
uint32_t cur_piece = piece[piece_num];
|
||||
if (cur_piece != default_piece || (piece_num == 0 && first))
|
||||
{
|
||||
count++;
|
||||
if (first)
|
||||
{
|
||||
if (defaultPiece == 0xffff)
|
||||
if (default_piece == 0xffff)
|
||||
{
|
||||
EmitInstruction(pDstInst, Mov16::AssembleMovn64(rd, curPiece ^ 0xffff, pieceNum));
|
||||
emit_instruction(dst_inst, mov16::assemble_movn64(rd, cur_piece ^ 0xffff, piece_num));
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitInstruction(pDstInst, Mov16::AssembleMovz64(rd, curPiece, pieceNum));
|
||||
emit_instruction(dst_inst, mov16::assemble_movz64(rd, cur_piece, piece_num));
|
||||
}
|
||||
first = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
EmitInstruction(pDstInst, Mov16::AssembleMovk64(rd, curPiece, pieceNum));
|
||||
emit_instruction(dst_inst, mov16::assemble_movk64(rd, cur_piece, piece_num));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -382,255 +380,245 @@ uint8_t detour_arm64_disasm::EmitMovImmediate(uint32_t*& pDstInst, uint8_t rd, u
|
|||
return (uint8_t)(count * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
uint8_t detour_arm64_disasm::CopyAdr(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
|
||||
uint8_t detour_arm64_disasm::copy_adr(uint8_t* source, uint8_t* dest, uint32_t instruction)
|
||||
{
|
||||
Adr19& decoded = (Adr19&)(instruction);
|
||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
||||
adr19& decoded = (adr19&)(instruction);
|
||||
uint32_t* dst_inst = (uint32_t*)(dest);
|
||||
|
||||
// ADR case
|
||||
if (decoded.s.Type == 0)
|
||||
if (decoded.s.type == 0)
|
||||
{
|
||||
uint8_t* pTarget = pSource + decoded.Imm();
|
||||
int64_t delta = pTarget - pDest;
|
||||
int64_t deltaPage = ((std::ptrdiff_t)pTarget >> 12) - ((std::ptrdiff_t)pDest >> 12);
|
||||
uint8_t* target = source + decoded.imm();
|
||||
int64_t delta = target - dest;
|
||||
int64_t delta_page = ((std::ptrdiff_t)target >> 12) - ((std::ptrdiff_t)dest >> 12);
|
||||
|
||||
// output as ADR
|
||||
if (delta >= -(1 << 20) && delta < (1 << 20))
|
||||
{
|
||||
EmitInstruction(pDstInst, Adr19::AssembleAdr(decoded.s.Rd, (int32_t)delta));
|
||||
emit_instruction(dst_inst, adr19::assemble_adr(decoded.s.rd, (int32_t)delta));
|
||||
}
|
||||
|
||||
// output as ADRP; ADD
|
||||
else if (deltaPage >= -(1 << 20) && (deltaPage < (1 << 20)))
|
||||
else if (delta_page >= -(1 << 20) && (delta_page < (1 << 20)))
|
||||
{
|
||||
EmitInstruction(pDstInst, Adr19::AssembleAdrp(decoded.s.Rd, (int32_t)deltaPage));
|
||||
EmitInstruction(pDstInst, AddImm12::AssembleAdd32(decoded.s.Rd, decoded.s.Rd, ((std::ptrdiff_t)pTarget) & 0xfff, 0));
|
||||
emit_instruction(dst_inst, adr19::assemble_adrp(decoded.s.rd, (int32_t)delta_page));
|
||||
emit_instruction(dst_inst, add_imm12::assemble_add_32(decoded.s.rd, decoded.s.rd, ((std::ptrdiff_t)target) & 0xfff, 0));
|
||||
}
|
||||
|
||||
// output as immediate move
|
||||
else
|
||||
{
|
||||
EmitMovImmediate(pDstInst, decoded.s.Rd, (std::ptrdiff_t)pTarget);
|
||||
emit_mov_immediate(dst_inst, decoded.s.rd, (std::ptrdiff_t)target);
|
||||
}
|
||||
}
|
||||
|
||||
// ADRP case
|
||||
else
|
||||
{
|
||||
uint8_t* pTarget = (uint8_t*)((((std::ptrdiff_t)pSource >> 12) + decoded.Imm()) << 12);
|
||||
int64_t deltaPage = ((std::ptrdiff_t)pTarget >> 12) - ((std::ptrdiff_t)pDest >> 12);
|
||||
uint8_t* target = (uint8_t*)((((std::ptrdiff_t)source >> 12) + decoded.imm()) << 12);
|
||||
int64_t delta_page = ((std::ptrdiff_t)target >> 12) - ((std::ptrdiff_t)dest >> 12);
|
||||
|
||||
// output as ADRP
|
||||
if (deltaPage >= -(1 << 20) && (deltaPage < (1 << 20)))
|
||||
if (delta_page >= -(1 << 20) && (delta_page < (1 << 20)))
|
||||
{
|
||||
EmitInstruction(pDstInst, Adr19::AssembleAdrp(decoded.s.Rd, (int32_t)deltaPage));
|
||||
emit_instruction(dst_inst, adr19::assemble_adrp(decoded.s.rd, (int32_t)delta_page));
|
||||
}
|
||||
|
||||
// output as immediate move
|
||||
else
|
||||
{
|
||||
EmitMovImmediate(pDstInst, decoded.s.Rd, (std::ptrdiff_t)pTarget);
|
||||
emit_mov_immediate(dst_inst, decoded.s.rd, (std::ptrdiff_t)target);
|
||||
}
|
||||
}
|
||||
|
||||
return (uint8_t)((uint8_t*)pDstInst - pDest);
|
||||
return (uint8_t)((uint8_t*)dst_inst - dest);
|
||||
}
|
||||
|
||||
uint8_t detour_arm64_disasm::CopyBcc(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
|
||||
uint8_t detour_arm64_disasm::copy_bcc(uint8_t* source, uint8_t* dest, uint32_t instruction)
|
||||
{
|
||||
Bcc19& decoded = (Bcc19&)(instruction);
|
||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
||||
bcc19& decoded = (bcc19&)(instruction);
|
||||
uint32_t* dst_inst = (uint32_t*)(dest);
|
||||
|
||||
uint8_t* pTarget = pSource + decoded.Imm();
|
||||
int64_t delta = pTarget - pDest;
|
||||
int64_t delta4 = pTarget - (pDest + 4);
|
||||
uint8_t* target = source + decoded.imm();
|
||||
int64_t delta = target - dest;
|
||||
int64_t delta4 = target - (dest + 4);
|
||||
|
||||
// output as BCC
|
||||
if (delta >= -(1 << 20) && delta < (1 << 20))
|
||||
{
|
||||
EmitInstruction(pDstInst, Bcc19::AssembleBcc(decoded.s.Condition, (int32_t)delta));
|
||||
emit_instruction(dst_inst, bcc19::assemble_bcc(decoded.s.condition, (int32_t)delta));
|
||||
}
|
||||
|
||||
// output as BCC <skip>; B
|
||||
else if (delta4 >= -(1 << 27) && (delta4 < (1 << 27)))
|
||||
{
|
||||
EmitInstruction(pDstInst, Bcc19::AssembleBcc(decoded.s.Condition ^ 1, 8));
|
||||
EmitInstruction(pDstInst, Branch26::AssembleB((int32_t)delta4));
|
||||
emit_instruction(dst_inst, bcc19::assemble_bcc(decoded.s.condition ^ 1, 8));
|
||||
emit_instruction(dst_inst, branch26::assemble_b((int32_t)delta4));
|
||||
}
|
||||
|
||||
// output as MOV x17, Target; BCC <skip>; BR x17 (BIG assumption that x17 isn't being used for anything!!)
|
||||
else
|
||||
{
|
||||
EmitMovImmediate(pDstInst, 17, (std::ptrdiff_t)pTarget);
|
||||
EmitInstruction(pDstInst, Bcc19::AssembleBcc(decoded.s.Condition ^ 1, 8));
|
||||
EmitInstruction(pDstInst, Br::AssembleBr(17));
|
||||
emit_mov_immediate(dst_inst, 17, (std::ptrdiff_t)target);
|
||||
emit_instruction(dst_inst, bcc19::assemble_bcc(decoded.s.condition ^ 1, 8));
|
||||
emit_instruction(dst_inst, br::assemble_br(17));
|
||||
}
|
||||
|
||||
return (uint8_t)((uint8_t*)pDstInst - pDest);
|
||||
return (uint8_t)((uint8_t*)dst_inst - dest);
|
||||
}
|
||||
|
||||
uint8_t detour_arm64_disasm::CopyB_or_Bl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction, bool link)
|
||||
uint8_t detour_arm64_disasm::copy_b_or_bl(uint8_t* source, uint8_t* dest, uint32_t instruction, bool link)
|
||||
{
|
||||
Branch26& decoded = (Branch26&)(instruction);
|
||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
||||
branch26& decoded = (branch26&)(instruction);
|
||||
uint32_t* dst_inst = (uint32_t*)(dest);
|
||||
|
||||
uint8_t* pTarget = pSource + decoded.Imm();
|
||||
int64_t delta = pTarget - pDest;
|
||||
uint8_t* target = source + decoded.imm();
|
||||
int64_t delta = target - dest;
|
||||
|
||||
// output as B or BRL
|
||||
if (delta >= -(1 << 27) && (delta < (1 << 27)))
|
||||
{
|
||||
EmitInstruction(pDstInst, Branch26::Assemble(link, (int32_t)delta));
|
||||
emit_instruction(dst_inst, branch26::assemble(link, (int32_t)delta));
|
||||
}
|
||||
|
||||
// output as MOV x17, Target; BR or BRL x17 (BIG assumption that x17 isn't being used for anything!!)
|
||||
else
|
||||
{
|
||||
EmitMovImmediate(pDstInst, 17, (std::ptrdiff_t)pTarget);
|
||||
EmitInstruction(pDstInst, Br::Assemble(17, link));
|
||||
emit_mov_immediate(dst_inst, 17, (std::ptrdiff_t)target);
|
||||
emit_instruction(dst_inst, br::assemble(17, link));
|
||||
}
|
||||
|
||||
return (uint8_t)((uint8_t*)pDstInst - pDest);
|
||||
return (uint8_t)((uint8_t*)dst_inst - dest);
|
||||
}
|
||||
|
||||
uint8_t detour_arm64_disasm::CopyB(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
|
||||
uint8_t detour_arm64_disasm::copy_cbz(uint8_t* source, uint8_t* dest, uint32_t instruction)
|
||||
{
|
||||
return CopyB_or_Bl(pSource, pDest, instruction, false);
|
||||
}
|
||||
cbz19& decoded = (cbz19&)(instruction);
|
||||
uint32_t* dst_inst = (uint32_t*)(dest);
|
||||
|
||||
uint8_t detour_arm64_disasm::CopyBl(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
|
||||
{
|
||||
return CopyB_or_Bl(pSource, pDest, instruction, true);
|
||||
}
|
||||
|
||||
uint8_t detour_arm64_disasm::CopyCbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
|
||||
{
|
||||
Cbz19& decoded = (Cbz19&)(instruction);
|
||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
||||
|
||||
uint8_t* pTarget = pSource + decoded.Imm();
|
||||
int64_t delta = pTarget - pDest;
|
||||
int64_t delta4 = pTarget - (pDest + 4);
|
||||
uint8_t* target = source + decoded.imm();
|
||||
int64_t delta = target - dest;
|
||||
int64_t delta4 = target - (dest + 4);
|
||||
|
||||
// output as CBZ/NZ
|
||||
if (delta >= -(1 << 20) && delta < (1 << 20))
|
||||
{
|
||||
EmitInstruction(pDstInst, Cbz19::Assemble(decoded.s.Size, decoded.s.Nz, decoded.s.Rt, (int32_t)delta));
|
||||
emit_instruction(dst_inst, cbz19::assemble(decoded.s.size, decoded.s.nz, decoded.s.rt, (int32_t)delta));
|
||||
}
|
||||
|
||||
// output as CBNZ/Z <skip>; B
|
||||
else if (delta4 >= -(1 << 27) && (delta4 < (1 << 27)))
|
||||
{
|
||||
EmitInstruction(pDstInst, Cbz19::Assemble(decoded.s.Size, decoded.s.Nz ^ 1, decoded.s.Rt, 8));
|
||||
EmitInstruction(pDstInst, Branch26::AssembleB((int32_t)delta4));
|
||||
emit_instruction(dst_inst, cbz19::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, 8));
|
||||
emit_instruction(dst_inst, branch26::assemble_b((int32_t)delta4));
|
||||
}
|
||||
|
||||
// output as MOV x17, Target; CBNZ/Z <skip>; BR x17 (BIG assumption that x17 isn't being used for anything!!)
|
||||
else
|
||||
{
|
||||
EmitMovImmediate(pDstInst, 17, (std::ptrdiff_t)pTarget);
|
||||
EmitInstruction(pDstInst, Cbz19::Assemble(decoded.s.Size, decoded.s.Nz ^ 1, decoded.s.Rt, 8));
|
||||
EmitInstruction(pDstInst, Br::AssembleBr(17));
|
||||
emit_mov_immediate(dst_inst, 17, (std::ptrdiff_t)target);
|
||||
emit_instruction(dst_inst, cbz19::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, 8));
|
||||
emit_instruction(dst_inst, br::assemble_br(17));
|
||||
}
|
||||
|
||||
return (uint8_t)((uint8_t*)pDstInst - pDest);
|
||||
return (uint8_t)((uint8_t*)dst_inst - dest);
|
||||
}
|
||||
|
||||
uint8_t detour_arm64_disasm::CopyTbz(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
|
||||
uint8_t detour_arm64_disasm::copy_tbz(uint8_t* source, uint8_t* dest, uint32_t instruction)
|
||||
{
|
||||
Tbz14& decoded = (Tbz14&)(instruction);
|
||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
||||
tbz14& decoded = (tbz14&)(instruction);
|
||||
uint32_t* dst_inst = (uint32_t*)(dest);
|
||||
|
||||
uint8_t* pTarget = pSource + decoded.Imm();
|
||||
int64_t delta = pTarget - pDest;
|
||||
int64_t delta4 = pTarget - (pDest + 4);
|
||||
uint8_t* target = source + decoded.imm();
|
||||
int64_t delta = target - dest;
|
||||
int64_t delta4 = target - (dest + 4);
|
||||
|
||||
// output as TBZ/NZ
|
||||
if (delta >= -(1 << 13) && delta < (1 << 13))
|
||||
{
|
||||
EmitInstruction(pDstInst, Tbz14::Assemble(decoded.s.Size, decoded.s.Nz, decoded.s.Rt, decoded.s.Bit, (int32_t)delta));
|
||||
emit_instruction(dst_inst, tbz14::assemble(decoded.s.size, decoded.s.nz, decoded.s.rt, decoded.s.bit, (int32_t)delta));
|
||||
}
|
||||
|
||||
// output as TBNZ/Z <skip>; B
|
||||
else if (delta4 >= -(1 << 27) && (delta4 < (1 << 27)))
|
||||
{
|
||||
EmitInstruction(pDstInst, Tbz14::Assemble(decoded.s.Size, decoded.s.Nz ^ 1, decoded.s.Rt, decoded.s.Bit, 8));
|
||||
EmitInstruction(pDstInst, Branch26::AssembleB((int32_t)delta4));
|
||||
emit_instruction(dst_inst, tbz14::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, decoded.s.bit, 8));
|
||||
emit_instruction(dst_inst, branch26::assemble_b((int32_t)delta4));
|
||||
}
|
||||
|
||||
// output as MOV x17, Target; TBNZ/Z <skip>; BR x17 (BIG assumption that x17 isn't being used for anything!!)
|
||||
else
|
||||
{
|
||||
EmitMovImmediate(pDstInst, 17, (std::ptrdiff_t)pTarget);
|
||||
EmitInstruction(pDstInst, Tbz14::Assemble(decoded.s.Size, decoded.s.Nz ^ 1, decoded.s.Rt, decoded.s.Bit, 8));
|
||||
EmitInstruction(pDstInst, Br::AssembleBr(17));
|
||||
emit_mov_immediate(dst_inst, 17, (std::ptrdiff_t)target);
|
||||
emit_instruction(dst_inst, tbz14::assemble(decoded.s.size, decoded.s.nz ^ 1, decoded.s.rt, decoded.s.bit, 8));
|
||||
emit_instruction(dst_inst, br::assemble_br(17));
|
||||
}
|
||||
|
||||
return (uint8_t)((uint8_t*)pDstInst - pDest);
|
||||
return (uint8_t)((uint8_t*)dst_inst - dest);
|
||||
}
|
||||
|
||||
uint8_t detour_arm64_disasm::CopyLdrLiteral(uint8_t* pSource, uint8_t* pDest, uint32_t instruction)
|
||||
uint8_t detour_arm64_disasm::copy_ldr_literal(uint8_t* source, uint8_t* dest, uint32_t instruction)
|
||||
{
|
||||
LdrLit19& decoded = (LdrLit19&)(instruction);
|
||||
uint32_t* pDstInst = (uint32_t*)(pDest);
|
||||
ldr_lit19& decoded = (ldr_lit19&)(instruction);
|
||||
uint32_t* dst_inst = (uint32_t*)(dest);
|
||||
|
||||
uint8_t* pTarget = pSource + decoded.Imm();
|
||||
int64_t delta = pTarget - pDest;
|
||||
uint8_t* target = source + decoded.imm();
|
||||
int64_t delta = target - dest;
|
||||
|
||||
// output as LDR
|
||||
if (delta >= -(1 << 21) && delta < (1 << 21))
|
||||
{
|
||||
EmitInstruction(pDstInst, LdrLit19::Assemble(decoded.s.Size, decoded.s.FpNeon, decoded.s.Rt, (int32_t)delta));
|
||||
emit_instruction(dst_inst, ldr_lit19::assemble(decoded.s.size, decoded.s.fp_neon, decoded.s.rt, (int32_t)delta));
|
||||
}
|
||||
|
||||
// output as move immediate
|
||||
else if (decoded.s.FpNeon == 0)
|
||||
else if (decoded.s.fp_neon == 0)
|
||||
{
|
||||
uint64_t value = 0;
|
||||
switch (decoded.s.Size)
|
||||
switch (decoded.s.size)
|
||||
{
|
||||
case 0: value = *(uint32_t*)pTarget; break;
|
||||
case 1: value = *(uint64_t*)pTarget; break;
|
||||
case 2: value = *(int32_t*)pTarget; break;
|
||||
case 0: value = *(uint32_t*)target; break;
|
||||
case 1: value = *(uint64_t*)target; break;
|
||||
case 2: value = *(int32_t*)target; break;
|
||||
}
|
||||
EmitMovImmediate(pDstInst, decoded.s.Rt, value);
|
||||
emit_mov_immediate(dst_inst, decoded.s.rt, value);
|
||||
}
|
||||
|
||||
// FP/NEON register: compute address in x17 and load from there (BIG assumption that x17 isn't being used for anything!!)
|
||||
else
|
||||
{
|
||||
EmitMovImmediate(pDstInst, 17, (std::ptrdiff_t)pTarget);
|
||||
EmitInstruction(pDstInst, LdrFpNeonImm9::Assemble(2 + decoded.s.Size, decoded.s.Rt, 17, 0));
|
||||
emit_mov_immediate(dst_inst, 17, (std::ptrdiff_t)target);
|
||||
emit_instruction(dst_inst, ldr_fp_neon_imm9::assemble(2 + decoded.s.size, decoded.s.rt, 17, 0));
|
||||
}
|
||||
|
||||
return (uint8_t)((uint8_t*)pDstInst - pDest);
|
||||
return (uint8_t)((uint8_t*)dst_inst - dest);
|
||||
}
|
||||
|
||||
uint8_t* internal_detour_copy_instruction(uint8_t* dst, uint8_t* src, uint32_t* out_extra_len)
|
||||
{
|
||||
using namespace detour_arm64_disasm;
|
||||
|
||||
const uint32_t Instruction = GetInstruction(src);
|
||||
const uint32_t instruction = get_instruction(src);
|
||||
|
||||
uint32_t CopiedSize;
|
||||
if ((Instruction & 0x1f000000) == 0x10000000) {
|
||||
CopiedSize = CopyAdr(src, dst, Instruction);
|
||||
} else if ((Instruction & 0xff000010) == 0x54000000) {
|
||||
CopiedSize = CopyBcc(src, dst, Instruction);
|
||||
} else if ((Instruction & 0x7c000000) == 0x14000000) {
|
||||
CopiedSize = CopyB_or_Bl(src, dst, Instruction, (Instruction & 0x80000000) != 0);
|
||||
} else if ((Instruction & 0x7e000000) == 0x34000000) {
|
||||
CopiedSize = CopyCbz(src, dst, Instruction);
|
||||
} else if ((Instruction & 0x7e000000) == 0x36000000) {
|
||||
CopiedSize = CopyTbz(src, dst, Instruction);
|
||||
} else if ((Instruction & 0x3b000000) == 0x18000000) {
|
||||
CopiedSize = CopyLdrLiteral(src, dst, Instruction);
|
||||
uint32_t copied_size;
|
||||
if ((instruction & 0x1f000000) == 0x10000000) {
|
||||
copied_size = copy_adr(src, dst, instruction);
|
||||
} else if ((instruction & 0xff000010) == 0x54000000) {
|
||||
copied_size = copy_bcc(src, dst, instruction);
|
||||
} else if ((instruction & 0x7c000000) == 0x14000000) {
|
||||
copied_size = copy_b_or_bl(src, dst, instruction, (instruction & 0x80000000) != 0);
|
||||
} else if ((instruction & 0x7e000000) == 0x34000000) {
|
||||
copied_size = copy_cbz(src, dst, instruction);
|
||||
} else if ((instruction & 0x7e000000) == 0x36000000) {
|
||||
copied_size = copy_tbz(src, dst, instruction);
|
||||
} else if ((instruction & 0x3b000000) == 0x18000000) {
|
||||
copied_size = copy_ldr_literal(src, dst, instruction);
|
||||
} else {
|
||||
CopiedSize = PureCopy32(src, dst);
|
||||
copied_size = pure_copy32(src, dst);
|
||||
}
|
||||
|
||||
if (out_extra_len) {
|
||||
*out_extra_len = CopiedSize - sizeof(uint32_t);
|
||||
*out_extra_len = copied_size - sizeof(uint32_t);
|
||||
}
|
||||
|
||||
return src + 4;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue