75 #define MAX_OPERANDS 7
87 #define check_cond(cond) \
94 const char *
options[] = {
"sy",
"st",
"ld",
"xxx",
"ish",
"ishst",
95 "ishld",
"xxx",
"nsh",
"nshst",
"nshld",
96 "xxx",
"osh",
"oshst",
"oshld",
NULL };
118 while (
x && !(
x & 1)) {
133 while (!(t &
a) &&
a != 0 && t != 0) {
142 return 0xff & (0xff -
a);
163 if (
imm == 0 ||
imm ==
UT64_MAX || (reg_size != 64 && (
imm >> reg_size != 0 ||
imm == (~0ULL >> (64 - reg_size))))) {
206 ut32 n = ((nimms >> 6) & 1) ^ 1;
212 return op->operands[0].reg << 24;
216 return (
op->operands[1].reg & 0x7) << 29 | (
op->operands[1].reg & 0x18) << 13 |
encode1reg(
op);
220 return (
n & 0x1f0) << 4 | (
n & 0xf) << 20;
233 if (!strcmp(
op->mnemonic,
"mov")) {
237 if (
op->operands[0].reg_type &
ARM_SP ||
op->operands[1].reg_type &
ARM_SP) {
243 data =
k |
op->operands[1].reg << 8;
252 imm_inverse &= 0xffffffff;
258 data =
k | 0x00008052;
260 data |= (
imm & 7) << 29 | (
imm & 0x7f8) << 13 | (
imm & 0xf800) >> 3;
267 if (imm_inverse == (imm_inverse &
mask)) {
268 data =
k | 0x00008012;
269 imm_inverse >>=
shift;
270 data |= (imm_inverse & 7) << 29 | (imm_inverse & 0x7f8) << 13 | (imm_inverse & 0xf800) >> 3;
277 data =
k | 0xe0030032;
278 data |= (bitmask & 0x3f) << 18 | (bitmask & 0x1fc0) << 2;
281 if (!strcmp(
op->mnemonic,
"movz")) {
283 }
else if (!strcmp(
op->mnemonic,
"movk")) {
285 }
else if (!strcmp(
op->mnemonic,
"movn")) {
294 if (
op->operands_count >= 3) {
298 shift =
op->operands[2].shift_amount;
303 data |= (
imm & 7) << 29;
304 data |= (
imm & 0x7f8) << 13;
305 data |= (
imm & 0xf800) >> 3;
313 if (!strncmp(
op->mnemonic,
"cbnz", 4)) {
321 }
else if (!strncmp(
op->mnemonic,
"cbz", 3)) {
335 data = data | ((
imm & 0x1fe000) >> 5);
346 if (
op->operands[2].shift_amount > 31) {
354 data =
k | (
op->operands[0].reg & 0x18) << 13 |
op->operands[0].reg << 29 |
op->operands[1].reg << 8;
357 data |=
op->operands[2].shift_amount << 18 |
op->operands[2].shift << 14;
375 int n =
op->operands[2].immediate;
376 if (
n > 0xff ||
n < -0x100) {
384 data |= (0xf & (0xf - (
n - 1))) << 20;
387 data |= (0x1f - ((
n >> 4) - 1)) << 8;
389 data |= (0x1f - (
n >> 4)) << 8;
392 data |= (0xf & (
n & 63)) << 20;
394 data |= (
n >> 4) << 8;
396 data |= (0xff &
n) << 4;
398 data |= (
n >> 8) << 8;
417 data |=
op->operands[2].reg << 8;
419 int n =
op->operands[2].immediate;
420 if (
n > 0x100 ||
n < -0x100) {
431 data |= (0xf & (0xf - (
n - 1))) << 20;
433 data |= (0x1f - ((
n >> 4) - 1)) << 8;
435 data |= (0x1f - (
n >> 4)) << 8;
440 data |= (0xf & (
n & 63)) << 20;
441 data |= (
n >> 4) << 8;
444 data |= (0xff &
n) << 16;
446 data |= (
n >> 8) << 8;
448 data |= (0xf & (
n & 63)) << 20;
450 data |= (
n >> 4) << 8;
452 data |= (0xff &
n) << 15;
454 data |= (
n >> 8) << 23;
464 int op_count =
op->operands_count;
465 if (
k == 0x00000098) {
481 if (!strcmp(
op->mnemonic,
"ldrb") || !strcmp(
op->mnemonic,
"ldrh") || !strcmp(
op->mnemonic,
"strb") || !strcmp(
op->mnemonic,
"strh")) {
483 }
else if (!strcmp(
op->mnemonic,
"ldrsw")) {
490 char width =
op->mnemonic[strlen(
op->mnemonic) - 1];
494 switch (
op->operands[3].shift) {
516 if (
op->operands[3].amount_present) {
519 }
else if (
width ==
'h') {
520 switch (
op->operands[3].shift_amount) {
530 switch (
op->operands[3].shift_amount) {
544 data =
k |
op->operands[2].reg << 8;
549 int n = op_count == 2 ? 0 :
op->operands[2].immediate;
550 if (!
op->writeback && (op_count == 2 ||
op->operands[2].preindex)) {
554 }
else if (
width ==
'h') {
561 data =
k | (
n & 0x3f) << 18 | (
n & 0xfc0) << 2 | 1;
564 check_cond(-0x100 <=
n &&
n < 0x100)
if (
op->operands[2].preindex) {
575 n =
op->operands[0].immediate;
585 int t = (
n & 0xff000000) >> 24;
586 int h = (
n & 0xff0000) >> 16;
587 int m = (
n & 0xff00) >> 8;
596 n =
op->operands[0].reg;
614 n =
op->operands[0].immediate;
617 if (!(
n & 0x3 ||
n > 0x7ffffff)) {
623 data |= (0xff -
a) << 24;
631 data |= (
n & 31) << 27;
632 data |= (0xff & (
n >> 5)) << 16;
633 data |= (0xff & (
n >> 13)) << 8;
648 #define COND_CASE(a, b) case (ut16)(a) << 8 | (ut16)(b)
674 if (!
str[0] || !
str[1] ||
str[2] !=
' ') {
689 if (!strncmp(
op->mnemonic,
"isb", 3)) {
690 if (
op->operands[0].mem_option == 15 ||
op->operands[0].type ==
ARM_NOTYPE) {
697 data |=
op->operands[0].mem_option << 16;
698 }
else if (
op->operands_count == 1 &&
op->operands[0].type ==
ARM_CONSTANT) {
699 data |= (
op->operands[0].immediate << 16);
719 op->operands[1].reg =
op->operands[1].immediate;
727 r =
op->operands[0].reg;
728 b =
op->operands[1].sp_val;
735 op->operands[0].reg =
op->operands[0].immediate;
743 r =
op->operands[1].reg;
744 if (
op->operands[1].sp_val == 0xfffe) {
746 r =
op->operands[1].immediate;
748 b =
op->operands[0].sp_val;
759 data |= (
b & 0xf0) << 12;
760 data |= (
b & 0x0f) << 5;
761 data |= (
r & 0xf) << 8;
773 seq_data = 0x00000000;
774 seq_data |= (data & 0xff) << 8 * 3;
775 seq_data |= (data & 0xff00) << 8 * 1;
776 seq_data |= (data & 0xff0000) >> 8 * 1;
777 seq_data |= (data & 0xff000000) >> 8 * 3;
788 RegType reg_type =
op->operands[0].reg_type;
791 if (!(reg_type ==
op->operands[1].reg_type)) {
795 OpType op2_type =
op->operands[2].type;
811 data |=
op->operands[0].reg;
812 data |=
op->operands[1].reg << 5;
813 data |= (
opc & 3) << 29;
815 ut32 imm_orig =
op->operands[2].immediate;
820 data |= (imm_mask & 0x1fff) << 10;
821 }
else if (op2_type ==
ARM_GPR) {
830 data |=
op->operands[0].reg;
831 data |=
op->operands[1].reg << 5;
832 data |=
op->operands[2].reg << 16;
833 data |= (
opc & 3) << 29;
835 if (
op->operands_count == 4) {
839 data |= (shift_op.
shift & 0x3) << 22;
859 RZ_LOG_ERROR(
"assembler: arm64: adrp: invalid assembly. valid usage: adrp x0, addr\n");
864 at =
op->operands[1].immediate -
addr;
867 RZ_LOG_ERROR(
"assembler: arm64: adrp: invalid assembly. valid usage: adrp x0, addr\n");
871 ut8 b1 = (at >> 3) & 0xff;
874 ut8 b2 = (at >> (8 + 7)) & 0xff;
890 at =
op->operands[1].immediate -
addr;
896 ut8 b1 = (at >> 3) & 0xff;
897 ut8 b2 = (at >> (8 + 7)) & 0xff;
907 if (
op->operands[3].immediate & 0x7) {
910 if (
k == 0x000040a9 && (
op->operands[0].reg ==
op->operands[1].reg)) {
916 data += (
op->operands[3].immediate & 0x8) << 20;
917 data += (
op->operands[3].immediate >> 4) << 8;
925 int n =
op->operands[0].immediate;
927 data += (((
n / 8) & 0xff) << 16);
935 if (
op->operands_count < 3) {
948 data += (
op->operands[1].reg & 7) << (24 + 5);
949 data += (
op->operands[1].reg >> 3) << 16;
951 data +=
op->operands[2].reg << 8;
953 data += (
op->operands[2].reg & 0x3f) << 18;
954 data += (
op->operands[2].reg >> 6) << 8;
958 if ((
op->operands[3].shift ==
ARM_LSL) && (
op->operands[3].shift_amount == 12)) {
964 switch (
op->operands[3].shift) {
966 data |= (0x00040000 *
op->operands[3].shift_amount);
969 data |= (0x00040000 *
op->operands[3].shift_amount) | (0x4000);
972 data |= (0x00040000 *
op->operands[3].shift_amount) | (0x8000);
982 if (
op->operands_count < 2) {
985 op->operands_count++;
986 op->operands[2] =
op->operands[1];
987 op->operands[1].reg = 31;
1002 if (!strcmp(
op->mnemonic,
"sbfx") || !strcmp(
op->mnemonic,
"ubfx")) {
1003 op->operands[3].immediate +=
op->operands[2].immediate - 1;
1004 }
else if (!strcmp(
op->mnemonic,
"sbfiz") || !strcmp(
op->mnemonic,
"ubfiz")) {
1006 int temp =
bits -
op->operands[2].immediate;
1008 op->operands[2].immediate = temp & (
bits - 1);
1009 op->operands[3].immediate--;
1016 k |=
op->operands[2].immediate << 8 |
op->operands[3].immediate << 18;
1028 int msr_op_index = 0;
1029 size_t index_bound = strcspn(t,
"]");
1035 char *next = strchr(token,
',');
1041 while (token[0] ==
' ') {
1045 RZ_LOG_ERROR(
"assembler: arm64: maximum number of operands reached.\n");
1052 if (strcmp(
op->mnemonic,
"msr") == 0 &&
operand == 1) {
1055 if (token[0] ==
'#' || (token[0] >=
'0' && token[0] <=
'9')) {
1066 if ((strcmp(
op->mnemonic,
"mrs") == 0 &&
operand == 1) || (strcmp(
op->mnemonic,
"msr") == 0 &&
operand == 0)) {
1067 for (msr_op_index = 0;
msr_const[msr_op_index].name; msr_op_index++) {
1069 op->operands_count++;
1083 while (token[0] ==
' ' || token[0] ==
'[' || token[0] ==
']') {
1087 if (!strncmp(token,
"lsl", 3)) {
1090 }
else if (!strncmp(token,
"lsr", 3)) {
1093 }
else if (!strncmp(token,
"asr", 3)) {
1096 }
else if (!strncmp(token,
"ror", 3)) {
1099 }
else if (!strncmp(token,
"uxtb", 4)) {
1102 }
else if (!strncmp(token,
"uxth", 4)) {
1105 }
else if (!strncmp(token,
"uxtw", 4)) {
1108 }
else if (!strncmp(token,
"uxtx", 4)) {
1111 }
else if (!strncmp(token,
"sxtb", 4)) {
1114 }
else if (!strncmp(token,
"sxth", 4)) {
1117 }
else if (!strncmp(token,
"sxtw", 4)) {
1120 }
else if (!strncmp(token,
"sxtx", 4)) {
1125 op->operands_count++;
1127 while (*token && *token ==
' ') {
1130 if (*token ==
'#') {
1133 if (!*token || !
isdigit(*token)) {
1137 op->operands[
operand].amount_present =
true;
1138 if (
op->operands[
operand].shift_amount > 63) {
1147 op->operands_count++;
1149 while (*token && *token ==
' ') {
1152 bool present =
false;
1153 if (*token ==
'#') {
1157 if (!*token || !
isdigit(*token)) {
1162 op->operands[
operand].amount_present =
false;
1165 op->operands[
operand].amount_present =
true;
1174 x = strchr(token,
',');
1178 op->operands_count++;
1182 if (!strncmp(token + 1,
"zr", 2)) {
1195 op->operands_count++;
1199 if (!strncmp(token + 1,
"zr", 2)) {
1202 }
else if (!strncmp(token + 1,
"sp", 2)) {
1216 op->operands_count++;
1222 if (token[1] ==
'P' || token[1] ==
'p') {
1230 op->operands_count++;
1237 if (mem_opt != -1) {
1238 op->operands_count++;
1240 op->operands[
operand].mem_option = mem_opt;
1254 if (mem_opt != -1) {
1255 op->operands_count++;
1257 op->operands[
operand].mem_option = mem_opt;
1261 if (token[1] ==
'-') {
1264 op->operands_count++;
1267 op->operands[
operand].preindex = token - t < index_bound;
1274 op->operands_count++;
1277 op->operands[
operand].preindex = token - t < index_bound;
1295 char *space = strchr(
in,
' ');
1304 op->writeback = strstr(space,
"]!") !=
NULL;
1309 if (!strcmp(
str,
"autiasp")) {
1313 if (!strcmp(
str,
"autiaz")) {
1317 if (!strcmp(
str,
"autibsp")) {
1321 if (!strcmp(
str,
"autibz")) {
1325 if (!strcmp(
str,
"paciaz")) {
1329 if (!strcmp(
str,
"pacibz")) {
1333 if (!strcmp(
str,
"paciasp")) {
1337 if (!strcmp(
str,
"pacibsp")) {
1341 if (!strcmp(
str,
"retab")) {
1356 if (!strncmp(
str,
"mov", 3)) {
1358 }
else if (!strncmp(
str,
"cb", 2)) {
1360 }
else if (!strncmp(
str,
"cmp", 3)) {
1362 }
else if (!strncmp(
str,
"ldrb", 4)) {
1364 }
else if (!strncmp(
str,
"ldrh", 4)) {
1366 }
else if (!strncmp(
str,
"ldrsh", 5)) {
1368 }
else if (!strncmp(
str,
"ldrsw", 5)) {
1370 }
else if (!strncmp(
str,
"ldrsb", 5)) {
1372 }
else if (!strncmp(
str,
"strb", 4)) {
1374 }
else if (!strncmp(
str,
"strh", 4)) {
1376 }
else if (!strncmp(
str,
"ldr", 3)) {
1378 }
else if (!strncmp(
str,
"stur", 4)) {
1380 }
else if (!strncmp(
str,
"ldur", 4)) {
1382 }
else if (!strncmp(
str,
"str", 3)) {
1384 }
else if (!strncmp(
str,
"stp", 3)) {
1386 }
else if (!strncmp(
str,
"ldp", 3)) {
1388 }
else if (!strncmp(
str,
"sub", 3)) {
1390 }
else if (!strncmp(
str,
"add x", 5)) {
1392 }
else if (!strncmp(
str,
"add w", 5)) {
1394 }
else if (!strncmp(
str,
"adr x", 5)) {
1396 }
else if (!strncmp(
str,
"adrp x", 6)) {
1398 }
else if (!strncmp(
str,
"neg", 3)) {
1400 }
else if (!strcmp(
str,
"isb")) {
1405 }
else if (!strcmp(
str,
"nop")) {
1407 }
else if (!strcmp(
str,
"ret")) {
1409 }
else if (!strncmp(
str,
"msr ", 4)) {
1411 }
else if (!strncmp(
str,
"mrs ", 4)) {
1413 }
else if (!strncmp(
str,
"ands ", 5)) {
1415 }
else if (!strncmp(
str,
"and ", 4)) {
1417 }
else if (!strncmp(
str,
"bics ", 5)) {
1419 }
else if (!strncmp(
str,
"bic ", 4)) {
1421 }
else if (!strncmp(
str,
"eon ", 4)) {
1423 }
else if (!strncmp(
str,
"eor ", 4)) {
1425 }
else if (!strncmp(
str,
"orn ", 4)) {
1427 }
else if (!strncmp(
str,
"orr ", 4)) {
1429 }
else if (!strncmp(
str,
"svc ", 4)) {
1431 }
else if (!strncmp(
str,
"hvc ", 4)) {
1433 }
else if (!strncmp(
str,
"smc ", 4)) {
1435 }
else if (!strncmp(
str,
"brk ", 4)) {
1437 }
else if (!strncmp(
str,
"hlt ", 4)) {
1439 }
else if (!strncmp(
str,
"b ", 2)) {
1441 }
else if (!strncmp(
str,
"b.", 2)) {
1443 }
else if (!strncmp(
str,
"bl ", 3)) {
1445 }
else if (!strncmp(
str,
"br x", 4)) {
1447 }
else if (!strncmp(
str,
"blr x", 5)) {
1449 }
else if (!strncmp(
str,
"dmb ", 4)) {
1451 }
else if (!strncmp(
str,
"dsb ", 4)) {
1453 }
else if (!strncmp(
str,
"isb", 3)) {
1455 }
else if (!strncmp(
str,
"sbfiz ", 6) || !strncmp(
str,
"sbfm ", 5) || !strncmp(
str,
"sbfx ", 5)) {
1457 }
else if (!strncmp(
str,
"ubfiz ", 6) || !strncmp(
str,
"ubfm ", 5) || !strncmp(
str,
"ubfx ", 5)) {
static unsigned invert(unsigned x)
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
enum shifttype_t ShiftType
static ut32 encodeImm9(ut32 n)
static ut32 parse_bdot(const char *str, ArmOp *op, ut64 addr)
static ut32 branch(ArmOp *op, ut64 addr, int k)
static ut32 bitfield(ArmOp *op, int k)
static bool isMask(ut64 value)
static int countLeadingOnes(ut64 x)
static ut32 logical(ArmOp *op, bool invert, LogicalOp opc)
static ut32 neg(ArmOp *op)
static ut32 cb(ArmOp *op)
static ut32 exception(ArmOp *op, ut32 k)
bool arm64ass(const char *str, ut64 addr, ut32 *op)
static bool isShiftedMask(ut64 value)
static ut32 adrp(ArmOp *op, ut64 addr, ut32 k)
static ut32 mov(ArmOp *op)
static ut32 bdot(ArmOp *op, ut64 addr, int k)
static int countTrailingOnes(ut64 x)
static int calcNegOffset(int n, int shift)
static ut32 encode1reg(ArmOp *op)
static int countLeadingZeros(ut64 x)
static ut32 arithmetic(ArmOp *op, int k)
static ut32 reglsop(ArmOp *op, int k)
static bool handlePAC(ut32 *op, const char *str)
static bool parseOpcode(const char *str, ArmOp *op)
static ut32 mem_barrier(ArmOp *op, ut64 addr, int k)
static int get_mem_option(char *token)
static ut32 lsop(ArmOp *op, int k, ut64 addr)
static ut32 cmp(ArmOp *op)
static ut32 regsluop(ArmOp *op, int k)
static ut32 encodeBitMasksWithSize(ut64 imm, ut32 reg_size)
static ut32 adr(ArmOp *op, int addr)
static int countTrailingZeros(ut64 x)
static ut32 msr(ArmOp *op, int w)
static ut32 encode2regs(ArmOp *op)
static ut32 stp(ArmOp *op, int k)
static bool parseOperands(char *str, ArmOp *op)
static ut8 parse_cond(const char *str)
enum logicalop_t LogicalOp
int bits(struct state *s, int need)
const lzma_allocator const uint8_t * in
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
RZ_API void Ht_() free(HtName_(Ht) *ht)
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static const char struct stat static buf struct stat static buf static vhangup int options
static int is_immediate(ut32 instr)
static ut32 rz_read_be32(const void *src)
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
RZ_API int rz_str_casecmp(const char *dst, const char *orig)
RZ_API int rz_str_ncasecmp(const char *dst, const char *orig, size_t n)
#define cond(bop, top, mask, flags)
if(dbg->bits==RZ_SYS_BITS_64)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()