Rizin
unix-like reverse engineering framework and cli tools
arm_cs.h File Reference
#include <rz_analysis.h>
#include <capstone/capstone.h>

Go to the source code of this file.

Functions

RZ_IPI int rz_arm_cs_analysis_op_32_esil (RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn, bool thumb)
 
RZ_IPI int rz_arm_cs_analysis_op_64_esil (RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *buf, int len, csh *handle, cs_insn *insn)
 
RZ_IPI const char * rz_arm_cs_esil_prefix_cond (RzAnalysisOp *op, int cond_type)
 
RZ_IPI RzILOpEffectrz_arm_cs_32_il (csh *handle, cs_insn *insn, bool thumb)
 
RZ_IPI RzAnalysisILConfigrz_arm_cs_32_il_config (bool big_endian)
 
RZ_IPI RzILOpEffectrz_arm_cs_64_il (csh *handle, cs_insn *insn)
 
RZ_IPI RzAnalysisILConfigrz_arm_cs_64_il_config (bool big_endian)
 

Function Documentation

◆ rz_arm_cs_32_il()

RZ_IPI RzILOpEffect* rz_arm_cs_32_il ( csh handle,
cs_insn *  insn,
bool  thumb 
)

Definition at line 2647 of file arm_il32.c.

2647  {
2648  if (insn->id == ARM_INS_IT) {
2649  // Note: IT is **not** a conditional branch!
2650  // It's currently handled in analysis_arm_cs.c using ArmCSContext as a hack to turn the following instructions
2651  // into conditional ones. So in the IL, we don't do anything for IT.
2652  return NOP();
2653  }
2654  RzILOpEffect *eff = il_unconditional(handle, insn, thumb);
2655  if (!eff) {
2656  return NULL;
2657  }
2658  RzILOpBool *c = cond(insn->detail->arm.cc);
2659  if (c) {
2660  return BRANCH(c, eff, NOP());
2661  }
2662  return eff;
2663 }
#define BRANCH
static RzILOpEffect * il_unconditional(csh *handle, cs_insn *insn, bool is_thumb)
Definition: arm_il32.c:2354
static RZ_NULLABLE RzILOpBool * cond(arm_cc c)
Definition: arm_il32.c:141
static mcore_handle handle
Definition: asm_mcore.c:8
@ ARM_INS_IT
Definition: arm.h:857
#define NULL
Definition: cris-opc.c:27
#define NOP
Definition: rsp_idec.c:182
#define c(i)
Definition: sha256.c:43
An IL op performing a pure computation, 'a pure.

References ARM_INS_IT, BRANCH, c, cond(), handle, il_unconditional(), NOP, and NULL.

Referenced by analysis_op().

◆ rz_arm_cs_32_il_config()

RZ_IPI RzAnalysisILConfig* rz_arm_cs_32_il_config ( bool  big_endian)

Definition at line 2667 of file arm_il32.c.

2667  {
2668  RzAnalysisILConfig *r = rz_analysis_il_config_new(32, big_endian, 32);
2669  r->reg_bindings = regs_bound_32;
2671  svc_label->hook = label_svc;
2672  rz_analysis_il_config_add_label(r, svc_label);
2674  hvc_label->hook = label_hvc;
2675  rz_analysis_il_config_add_label(r, hvc_label);
2676  return r;
2677 }
RZ_API void rz_analysis_il_config_add_label(RZ_NONNULL RzAnalysisILConfig *cfg, RZ_NONNULL RZ_OWN RzILEffectLabel *label)
Definition: analysis_il.c:77
RZ_API RZ_OWN RzAnalysisILConfig * rz_analysis_il_config_new(ut32 pc_size, bool big_endian, ut32 mem_key_size)
Definition: analysis_il.c:53
static const char * regs_bound_32[]
Definition: arm_il32.c:17
static void label_hvc(RzILVM *vm, RzILOpEffect *op)
Definition: arm_il32.c:1152
static void label_svc(RzILVM *vm, RzILOpEffect *op)
Definition: arm_il32.c:1138
#define r
Definition: crypto_rc6.c:12
RZ_API RzILEffectLabel * rz_il_effect_label_new(RZ_NONNULL const char *name, RzILEffectLabelType type)
Definition: label.c:6
@ EFFECT_LABEL_SYSCALL
Definition: label.h:19
Description of the global context of an RzAnalysisILVM.
Definition: rz_analysis.h:1134
void * hook
Function pointer if EFFECT_LABEL_SYSCALL / EFFECT_LABEL_HOOK.
Definition: label.h:28

References EFFECT_LABEL_SYSCALL, rz_il_effect_label_t::hook, label_hvc(), label_svc(), r, regs_bound_32, rz_analysis_il_config_add_label(), rz_analysis_il_config_new(), and rz_il_effect_label_new().

Referenced by il_config().

◆ rz_arm_cs_64_il()

RZ_IPI RzILOpEffect* rz_arm_cs_64_il ( csh handle,
cs_insn *  insn 
)

Lift an AArch64 instruction to RzIL

Currently unimplemented:

FEAT_MTE/FEAT_MTE2/FEAT_MTE3: Memory Tagging Extension

Plausible to represent by adding another memory with a 60bit keys and 4bit values to hold the memory tags. Instructions:

  • ADDG, SUBG, SUBP, SUBPS
  • CMPP
  • GMI
  • IRG
  • LDG, LDGM
  • ST2G, STZ2G
  • STG, STGM, STGP, STZG, STZGM

FEAT_PAuth: Pointer Authentication

Extremely complex internal calculations. Different options to implement it include:

  • Fully implementing it in IL (probably theoretically possible, but may not be worth it)
  • Implementing the complex parts in uninterpreted functions and the simpler ones (e.g. stripping of auth bits) in IL. Might be a very good final solution since all data flow is correctly represented.
  • Implementing only stripping in IL and leaving everything else as nop. Might be useful as an interims solution to be able to strip pointers, but always unconditionally succeed authentication. Unimplemented Instructions:
  • AUTDA, AUTDZA
  • AUTDB, AUTDZB
  • AUTIA, AUTIA1716, AUTIASP, AUTIAZ, AUTIZA
  • AUTIB, AUTIB1716, AUTIBSP, AUTIBZ, AUTIZB
  • PACDA, PACDZA
  • PACDB, PACDZB
  • PACGA
  • PACIA, PACIA1716, PACIASP, PACIAZ, PACIZA
  • PACIB, PACIB1716, PACIBSP, PACIBZ, PACIZB
  • BLRAA, BLRAAZ, BLRAB, BLRABZ
  • BRAA, BRAAZ, BRAB, BRABZ
  • XPACD, XPACI, XPACLRI Stub-implemented Instructions:
  • LDRAA, LDRAB: currently behave like regular ldr

Cache maintenance, tlb maintenance and address translation

  • AT
  • CFP
  • CPP
  • SYS, SYSL
  • DC
  • DVP
  • IC
  • TLBI

Miscellaneous

  • BRK: causes a breakpoint instruction exception
  • BTI: FEAT_BTI/Branch Target Identification
  • CLREX: clears the local monitor
  • CRC32B, CRC32H, CRC32W, CRC32X, CRC32CB, CRC32CH, CRC32CW, CRC32CX: does crc32
  • CSDB, DMB, DSB, ESB, ISB, PSB CSYNC, PSSBB, SB, SSBB, TSB CSYNC: synchronization, memory barriers
  • DCPS1, DCPS2, DCPS3, DRPS, HLT: debug
  • ERET, ERETAA, ERETAB: exception return
  • SMC: secure monitor call
  • UDF: permanently undefined

Not supported by capstone v4 or v5 at the time of writing

  • AXFLAG, XAFLAG
  • FEAT_MTE (see above)
  • DGH
  • LD64B
  • ST64B
  • ST64BV
  • ST64BV0
  • WFET

Definition at line 2316 of file arm_il64.c.

2316  {
2317  switch (insn->id) {
2318  case ARM64_INS_NOP:
2319  case ARM64_INS_HINT:
2320  case ARM64_INS_PRFM:
2321  case ARM64_INS_PRFUM:
2322  case ARM64_INS_SEV:
2323  case ARM64_INS_SEVL:
2324  case ARM64_INS_WFE:
2325  case ARM64_INS_WFI:
2326  case ARM64_INS_YIELD:
2327  return NOP();
2328  case ARM64_INS_ADD:
2329  case ARM64_INS_ADC:
2330  case ARM64_INS_SUB:
2331  case ARM64_INS_SBC:
2332 #if CS_API_MAJOR > 4
2333  case ARM64_INS_ADDS:
2334  case ARM64_INS_SUBS:
2335  case ARM64_INS_ADCS:
2336  case ARM64_INS_SBCS:
2337 #endif
2338  return add_sub(insn);
2339  case ARM64_INS_ADR:
2340  case ARM64_INS_ADRP:
2341  return adr(insn);
2342  case ARM64_INS_AND:
2343 #if CS_API_MAJOR > 4
2344  case ARM64_INS_ANDS:
2345 #endif
2346  case ARM64_INS_EOR:
2347  case ARM64_INS_EON:
2348  case ARM64_INS_ORN:
2349  case ARM64_INS_ORR:
2350  return bitwise(insn);
2351  case ARM64_INS_ASR:
2352  case ARM64_INS_LSL:
2353  case ARM64_INS_LSR:
2354  case ARM64_INS_ROR:
2355  return shift(insn);
2356  case ARM64_INS_B:
2357  case ARM64_INS_BR:
2358  case ARM64_INS_RET:
2359 #if CS_API_MAJOR > 4
2360  case ARM64_INS_BRAA:
2361  case ARM64_INS_BRAAZ:
2362  case ARM64_INS_BRAB:
2363  case ARM64_INS_BRABZ:
2364  case ARM64_INS_RETAA:
2365  case ARM64_INS_RETAB:
2366 #endif
2367  return branch(insn);
2368  case ARM64_INS_BL:
2369  case ARM64_INS_BLR:
2370 #if CS_API_MAJOR > 4
2371  case ARM64_INS_BLRAA:
2372  case ARM64_INS_BLRAAZ:
2373  case ARM64_INS_BLRAB:
2374  case ARM64_INS_BLRABZ:
2375 #endif
2376  return bl(insn);
2377  case ARM64_INS_BFM:
2378  case ARM64_INS_BFI:
2379  case ARM64_INS_BFXIL:
2380  return bfm(insn);
2381  case ARM64_INS_BIC:
2382 #if CS_API_MAJOR > 4
2383  case ARM64_INS_BICS:
2384 #endif
2385  return bic(insn);
2386 #if CS_API_MAJOR > 4
2387  case ARM64_INS_CAS:
2388  case ARM64_INS_CASA:
2389  case ARM64_INS_CASAL:
2390  case ARM64_INS_CASL:
2391  case ARM64_INS_CASB:
2392  case ARM64_INS_CASAB:
2393  case ARM64_INS_CASALB:
2394  case ARM64_INS_CASLB:
2395  case ARM64_INS_CASH:
2396  case ARM64_INS_CASAH:
2397  case ARM64_INS_CASALH:
2398  case ARM64_INS_CASLH:
2399  return cas(insn);
2400  case ARM64_INS_CASP:
2401  case ARM64_INS_CASPA:
2402  case ARM64_INS_CASPAL:
2403  case ARM64_INS_CASPL:
2404  return casp(insn);
2405 #endif
2406  case ARM64_INS_CBZ:
2407  case ARM64_INS_CBNZ:
2408  return cbz(insn);
2409  case ARM64_INS_CMP:
2410  case ARM64_INS_CMN:
2411  case ARM64_INS_CCMP:
2412  case ARM64_INS_CCMN:
2413  return cmp(insn);
2414 #if CS_API_MAJOR > 4
2415  case ARM64_INS_CFINV:
2416  return SETG("cf", INV(VARG("cf")));
2417 #endif
2418  case ARM64_INS_CINC:
2419  case ARM64_INS_CSINC:
2420  case ARM64_INS_CINV:
2421  case ARM64_INS_CSINV:
2422  case ARM64_INS_CNEG:
2423  case ARM64_INS_CSNEG:
2424  case ARM64_INS_CSEL:
2425  return csinc(insn);
2426  case ARM64_INS_CSET:
2427  case ARM64_INS_CSETM:
2428  return cset(insn);
2429  case ARM64_INS_CLS:
2430  return cls(insn);
2431  case ARM64_INS_CLZ:
2432  return clz(insn);
2433  case ARM64_INS_EXTR:
2434  return extr(insn);
2435  case ARM64_INS_HVC:
2436  return hvc(insn);
2437  case ARM64_INS_SVC:
2438  return svc(insn);
2439  case ARM64_INS_LDR:
2440  case ARM64_INS_LDRB:
2441  case ARM64_INS_LDRH:
2442  case ARM64_INS_LDUR:
2443  case ARM64_INS_LDURB:
2444  case ARM64_INS_LDURH:
2445  case ARM64_INS_LDRSW:
2446  case ARM64_INS_LDRSB:
2447  case ARM64_INS_LDRSH:
2448  case ARM64_INS_LDURSW:
2449  case ARM64_INS_LDURSB:
2450  case ARM64_INS_LDURSH:
2451  case ARM64_INS_LDAR:
2452  case ARM64_INS_LDARB:
2453  case ARM64_INS_LDARH:
2454  case ARM64_INS_LDAXP:
2455  case ARM64_INS_LDXP:
2456  case ARM64_INS_LDAXR:
2457  case ARM64_INS_LDAXRB:
2458  case ARM64_INS_LDAXRH:
2459  case ARM64_INS_LDP:
2460  case ARM64_INS_LDNP:
2461  case ARM64_INS_LDPSW:
2462  case ARM64_INS_LDTR:
2463  case ARM64_INS_LDTRB:
2464  case ARM64_INS_LDTRH:
2465  case ARM64_INS_LDTRSW:
2466  case ARM64_INS_LDTRSB:
2467  case ARM64_INS_LDTRSH:
2468  case ARM64_INS_LDXR:
2469  case ARM64_INS_LDXRB:
2470  case ARM64_INS_LDXRH:
2471 #if CS_API_MAJOR > 4
2472  case ARM64_INS_LDAPR:
2473  case ARM64_INS_LDAPRB:
2474  case ARM64_INS_LDAPRH:
2475  case ARM64_INS_LDAPUR:
2476  case ARM64_INS_LDAPURB:
2477  case ARM64_INS_LDAPURH:
2478  case ARM64_INS_LDAPURSB:
2479  case ARM64_INS_LDAPURSH:
2480  case ARM64_INS_LDAPURSW:
2481  case ARM64_INS_LDLAR:
2482  case ARM64_INS_LDLARB:
2483  case ARM64_INS_LDLARH:
2484  case ARM64_INS_LDRAA:
2485  case ARM64_INS_LDRAB:
2486 #endif
2487  return ldr(insn);
2488 #if CS_API_MAJOR > 4
2489  case ARM64_INS_LDADD:
2490  case ARM64_INS_LDADDA:
2491  case ARM64_INS_LDADDAL:
2492  case ARM64_INS_LDADDL:
2493  case ARM64_INS_LDADDB:
2494  case ARM64_INS_LDADDAB:
2495  case ARM64_INS_LDADDALB:
2496  case ARM64_INS_LDADDLB:
2497  case ARM64_INS_LDADDH:
2498  case ARM64_INS_LDADDAH:
2499  case ARM64_INS_LDADDALH:
2500  case ARM64_INS_LDADDLH:
2501  case ARM64_INS_STADD:
2502  case ARM64_INS_STADDL:
2503  case ARM64_INS_STADDB:
2504  case ARM64_INS_STADDLB:
2505  case ARM64_INS_STADDH:
2506  case ARM64_INS_STADDLH:
2507  case ARM64_INS_LDCLRB:
2508  case ARM64_INS_LDCLRAB:
2509  case ARM64_INS_LDCLRALB:
2510  case ARM64_INS_LDCLRLB:
2511  case ARM64_INS_LDCLRH:
2512  case ARM64_INS_LDCLRAH:
2513  case ARM64_INS_LDCLRALH:
2514  case ARM64_INS_LDCLRLH:
2515  case ARM64_INS_LDCLR:
2516  case ARM64_INS_LDCLRA:
2517  case ARM64_INS_LDCLRAL:
2518  case ARM64_INS_LDCLRL:
2519  case ARM64_INS_STCLR:
2520  case ARM64_INS_STCLRL:
2521  case ARM64_INS_STCLRB:
2522  case ARM64_INS_STCLRLB:
2523  case ARM64_INS_STCLRH:
2524  case ARM64_INS_STCLRLH:
2525  case ARM64_INS_LDEORB:
2526  case ARM64_INS_LDEORAB:
2527  case ARM64_INS_LDEORALB:
2528  case ARM64_INS_LDEORLB:
2529  case ARM64_INS_LDEORH:
2530  case ARM64_INS_LDEORAH:
2531  case ARM64_INS_LDEORALH:
2532  case ARM64_INS_LDEORLH:
2533  case ARM64_INS_LDEOR:
2534  case ARM64_INS_LDEORA:
2535  case ARM64_INS_LDEORAL:
2536  case ARM64_INS_LDEORL:
2537  case ARM64_INS_STEOR:
2538  case ARM64_INS_STEORL:
2539  case ARM64_INS_STEORB:
2540  case ARM64_INS_STEORLB:
2541  case ARM64_INS_STEORH:
2542  case ARM64_INS_STEORLH:
2543  case ARM64_INS_LDSETB:
2544  case ARM64_INS_LDSETAB:
2545  case ARM64_INS_LDSETALB:
2546  case ARM64_INS_LDSETLB:
2547  case ARM64_INS_LDSETH:
2548  case ARM64_INS_LDSETAH:
2549  case ARM64_INS_LDSETALH:
2550  case ARM64_INS_LDSETLH:
2551  case ARM64_INS_LDSET:
2552  case ARM64_INS_LDSETA:
2553  case ARM64_INS_LDSETAL:
2554  case ARM64_INS_LDSETL:
2555  case ARM64_INS_STSET:
2556  case ARM64_INS_STSETL:
2557  case ARM64_INS_STSETB:
2558  case ARM64_INS_STSETLB:
2559  case ARM64_INS_STSETH:
2560  case ARM64_INS_STSETLH:
2561  case ARM64_INS_LDSMAXB:
2562  case ARM64_INS_LDSMAXAB:
2563  case ARM64_INS_LDSMAXALB:
2564  case ARM64_INS_LDSMAXLB:
2565  case ARM64_INS_LDSMAXH:
2566  case ARM64_INS_LDSMAXAH:
2567  case ARM64_INS_LDSMAXALH:
2568  case ARM64_INS_LDSMAXLH:
2569  case ARM64_INS_LDSMAX:
2570  case ARM64_INS_LDSMAXA:
2571  case ARM64_INS_LDSMAXAL:
2572  case ARM64_INS_LDSMAXL:
2573  case ARM64_INS_STSMAX:
2574  case ARM64_INS_STSMAXL:
2575  case ARM64_INS_STSMAXB:
2576  case ARM64_INS_STSMAXLB:
2577  case ARM64_INS_STSMAXH:
2578  case ARM64_INS_STSMAXLH:
2579  case ARM64_INS_LDSMINB:
2580  case ARM64_INS_LDSMINAB:
2581  case ARM64_INS_LDSMINALB:
2582  case ARM64_INS_LDSMINLB:
2583  case ARM64_INS_LDSMINH:
2584  case ARM64_INS_LDSMINAH:
2585  case ARM64_INS_LDSMINALH:
2586  case ARM64_INS_LDSMINLH:
2587  case ARM64_INS_LDSMIN:
2588  case ARM64_INS_LDSMINA:
2589  case ARM64_INS_LDSMINAL:
2590  case ARM64_INS_LDSMINL:
2591  case ARM64_INS_STSMIN:
2592  case ARM64_INS_STSMINL:
2593  case ARM64_INS_STSMINB:
2594  case ARM64_INS_STSMINLB:
2595  case ARM64_INS_STSMINH:
2596  case ARM64_INS_STSMINLH:
2597  case ARM64_INS_LDUMAXB:
2598  case ARM64_INS_LDUMAXAB:
2599  case ARM64_INS_LDUMAXALB:
2600  case ARM64_INS_LDUMAXLB:
2601  case ARM64_INS_LDUMAXH:
2602  case ARM64_INS_LDUMAXAH:
2603  case ARM64_INS_LDUMAXALH:
2604  case ARM64_INS_LDUMAXLH:
2605  case ARM64_INS_LDUMAX:
2606  case ARM64_INS_LDUMAXA:
2607  case ARM64_INS_LDUMAXAL:
2608  case ARM64_INS_LDUMAXL:
2609  case ARM64_INS_STUMAX:
2610  case ARM64_INS_STUMAXL:
2611  case ARM64_INS_STUMAXB:
2612  case ARM64_INS_STUMAXLB:
2613  case ARM64_INS_STUMAXH:
2614  case ARM64_INS_STUMAXLH:
2615  case ARM64_INS_LDUMINB:
2616  case ARM64_INS_LDUMINAB:
2617  case ARM64_INS_LDUMINALB:
2618  case ARM64_INS_LDUMINLB:
2619  case ARM64_INS_LDUMINH:
2620  case ARM64_INS_LDUMINAH:
2621  case ARM64_INS_LDUMINALH:
2622  case ARM64_INS_LDUMINLH:
2623  case ARM64_INS_LDUMIN:
2624  case ARM64_INS_LDUMINA:
2625  case ARM64_INS_LDUMINAL:
2626  case ARM64_INS_LDUMINL:
2627  case ARM64_INS_STUMIN:
2628  case ARM64_INS_STUMINL:
2629  case ARM64_INS_STUMINB:
2630  case ARM64_INS_STUMINLB:
2631  case ARM64_INS_STUMINH:
2632  case ARM64_INS_STUMINLH:
2633  return ldadd(insn);
2634 #endif
2635  case ARM64_INS_MADD:
2636  case ARM64_INS_MSUB:
2637  return madd(insn);
2638  case ARM64_INS_MUL:
2639  case ARM64_INS_MNEG:
2640  return mul(insn);
2641  case ARM64_INS_MOV:
2642  case ARM64_INS_MOVZ:
2643  return mov(insn);
2644  case ARM64_INS_MOVK:
2645  return movk(insn);
2646  case ARM64_INS_MOVN:
2647  return movn(insn);
2648  case ARM64_INS_MSR:
2649  return msr(insn);
2650  case ARM64_INS_MRS:
2651  return mrs(insn);
2652  case ARM64_INS_MVN:
2653  case ARM64_INS_NEG:
2654  case ARM64_INS_NGC:
2655 #if CS_API_MAJOR > 3
2656  case ARM64_INS_NEGS:
2657  case ARM64_INS_NGCS:
2658 #endif
2659  return mvn(insn);
2660  case ARM64_INS_RBIT:
2661  return rbit(insn);
2662  case ARM64_INS_REV:
2663  case ARM64_INS_REV32:
2664  case ARM64_INS_REV16:
2665  return rev(insn);
2666 #if CS_API_MAJOR > 4
2667  case ARM64_INS_RMIF:
2668  return rmif(insn);
2669 #endif
2670  case ARM64_INS_SBFIZ:
2671  case ARM64_INS_SBFX:
2672  case ARM64_INS_UBFIZ:
2673  case ARM64_INS_UBFX:
2674  return sbfx(insn);
2675  case ARM64_INS_SDIV:
2676  return sdiv(insn);
2677 #if CS_API_MAJOR > 4
2678  case ARM64_INS_SETF8:
2679  case ARM64_INS_SETF16:
2680  return setf(insn);
2681 #endif
2682  case ARM64_INS_SMADDL:
2683  case ARM64_INS_SMSUBL:
2684  case ARM64_INS_UMADDL:
2685  case ARM64_INS_UMSUBL:
2686  return smaddl(insn);
2687  case ARM64_INS_SMULL:
2688  case ARM64_INS_SMNEGL:
2689  case ARM64_INS_UMULL:
2690  case ARM64_INS_UMNEGL:
2691  return smull(insn);
2692  case ARM64_INS_SMULH:
2693  case ARM64_INS_UMULH:
2694  return smulh(insn);
2695  case ARM64_INS_STR:
2696  case ARM64_INS_STUR:
2697  case ARM64_INS_STRB:
2698  case ARM64_INS_STURB:
2699  case ARM64_INS_STRH:
2700  case ARM64_INS_STURH:
2701  case ARM64_INS_STLR:
2702  case ARM64_INS_STLRB:
2703  case ARM64_INS_STLRH:
2704  case ARM64_INS_STP:
2705  case ARM64_INS_STNP:
2706  case ARM64_INS_STXR:
2707  case ARM64_INS_STXRB:
2708  case ARM64_INS_STXRH:
2709  case ARM64_INS_STXP:
2710  case ARM64_INS_STLXR:
2711  case ARM64_INS_STLXRB:
2712  case ARM64_INS_STLXRH:
2713  case ARM64_INS_STLXP:
2714  case ARM64_INS_STTR:
2715  case ARM64_INS_STTRB:
2716  case ARM64_INS_STTRH:
2717 #if CS_API_MAJOR > 4
2718  case ARM64_INS_STLLR:
2719  case ARM64_INS_STLLRB:
2720  case ARM64_INS_STLLRH:
2721  case ARM64_INS_STLUR:
2722  case ARM64_INS_STLURB:
2723  case ARM64_INS_STLURH:
2724 #endif
2725  return str(insn);
2726 #if CS_API_MAJOR > 4
2727  case ARM64_INS_SWP:
2728  case ARM64_INS_SWPA:
2729  case ARM64_INS_SWPAL:
2730  case ARM64_INS_SWPL:
2731  case ARM64_INS_SWPB:
2732  case ARM64_INS_SWPAB:
2733  case ARM64_INS_SWPALB:
2734  case ARM64_INS_SWPLB:
2735  case ARM64_INS_SWPH:
2736  case ARM64_INS_SWPAH:
2737  case ARM64_INS_SWPALH:
2738  case ARM64_INS_SWPLH:
2739  return swp(insn);
2740 #endif
2741  case ARM64_INS_SXTB:
2742  case ARM64_INS_SXTH:
2743  case ARM64_INS_SXTW:
2744  case ARM64_INS_UXTB:
2745  case ARM64_INS_UXTH:
2746  return sxt(insn);
2747  case ARM64_INS_TBNZ:
2748  case ARM64_INS_TBZ:
2749  return tbz(insn);
2750  case ARM64_INS_TST:
2751  return tst(insn);
2752  case ARM64_INS_UDIV:
2753  return udiv(insn);
2754  default:
2755  break;
2756  }
2757  return NULL;
2758 }
static RzILOpEffect * msr(cs_insn *insn)
Definition: arm_il64.c:1708
static RzILOpEffect * movk(cs_insn *insn)
Definition: arm_il64.c:1670
static RzILOpEffect * cbz(cs_insn *insn)
Definition: arm_il64.c:789
static RzILOpEffect * smull(cs_insn *insn)
Definition: arm_il64.c:2068
static RzILOpEffect * bl(cs_insn *insn)
Definition: arm_il64.c:618
static RzILOpEffect * extr(cs_insn *insn)
Definition: arm_il64.c:962
static RzILOpEffect * tst(cs_insn *insn)
Definition: arm_il64.c:2229
static RzILOpEffect * bfm(cs_insn *insn)
Definition: arm_il64.c:633
static RzILOpEffect * sxt(cs_insn *insn)
Definition: arm_il64.c:2173
static RzILOpEffect * str(cs_insn *insn)
Definition: arm_il64.c:1169
static RzILOpEffect * mul(cs_insn *insn)
Definition: arm_il64.c:1618
static RzILOpEffect * madd(cs_insn *insn)
Definition: arm_il64.c:1591
static RzILOpEffect * sdiv(cs_insn *insn)
Definition: arm_il64.c:1970
static RzILOpEffect * ldr(cs_insn *insn)
Definition: arm_il64.c:1058
static RzILOpEffect * cset(cs_insn *insn)
Definition: arm_il64.c:899
static RzILOpEffect * sbfx(cs_insn *insn)
Definition: arm_il64.c:1770
static RzILOpEffect * smulh(cs_insn *insn)
Definition: arm_il64.c:2092
static RzILOpEffect * smaddl(cs_insn *insn)
Definition: arm_il64.c:2039
static RzILOpEffect * tbz(cs_insn *insn)
Definition: arm_il64.c:2207
static RzILOpEffect * udiv(cs_insn *insn)
Definition: arm_il64.c:1996
static RzILOpEffect * rev(cs_insn *insn)
Definition: arm_il64.c:1904
static RzILOpEffect * bic(cs_insn *insn)
Definition: arm_il64.c:664
static RzILOpEffect * hvc(cs_insn *insn)
Definition: arm_il64.c:999
static RzILOpEffect * adr(cs_insn *insn)
Definition: arm_il64.c:497
static RzILOpEffect * cls(cs_insn *insn)
Definition: arm_il64.c:915
static RzILOpEffect * rbit(cs_insn *insn)
Definition: arm_il64.c:1875
static RzILOpEffect * shift(cs_insn *insn)
Definition: arm_il64.c:555
static RzILOpEffect * mrs(cs_insn *insn)
Definition: arm_il64.c:1800
static RzILOpEffect * csinc(cs_insn *insn)
Definition: arm_il64.c:840
static RzILOpEffect * add_sub(cs_insn *insn)
Definition: arm_il64.c:442
static RzILOpEffect * clz(cs_insn *insn)
Definition: arm_il64.c:939
static RzILOpEffect * bitwise(cs_insn *insn)
Definition: arm_il64.c:508
static RzILOpEffect * svc(cs_insn *insn)
Definition: arm_il64.c:987
static RzILOpEffect * cmp(cs_insn *insn)
Definition: arm_il64.c:805
static RzILOpEffect * movn(cs_insn *insn)
Definition: arm_il64.c:1688
static RzILOpEffect * branch(cs_insn *insn)
Definition: arm_il64.c:595
static RzILOpEffect * mvn(cs_insn *insn)
Definition: arm_il64.c:1829
static RzILOpEffect * mov(cs_insn *insn)
Definition: arm_il64.c:1646
@ ARM64_INS_SMSUBL
Definition: arm64.h:944
@ ARM64_INS_BFI
Definition: arm64.h:1110
@ ARM64_INS_LDAR
Definition: arm64.h:828
@ ARM64_INS_STNP
Definition: arm64.h:1000
@ ARM64_INS_AND
Definition: arm64.h:687
@ ARM64_INS_CSINC
Definition: arm64.h:725
@ ARM64_INS_NOP
Definition: arm64.h:1099
@ ARM64_INS_SEV
Definition: arm64.h:1103
@ ARM64_INS_LDTRH
Definition: arm64.h:843
@ ARM64_INS_SEVL
Definition: arm64.h:1104
@ ARM64_INS_MVN
Definition: arm64.h:1113
@ ARM64_INS_LDURH
Definition: arm64.h:851
@ ARM64_INS_RBIT
Definition: arm64.h:884
@ ARM64_INS_CCMN
Definition: arm64.h:701
@ ARM64_INS_TBNZ
Definition: arm64.h:1023
@ ARM64_INS_ORN
Definition: arm64.h:875
@ ARM64_INS_LDPSW
Definition: arm64.h:835
@ ARM64_INS_CSNEG
Definition: arm64.h:727
@ ARM64_INS_STUR
Definition: arm64.h:1009
@ ARM64_INS_CSETM
Definition: arm64.h:1117
@ ARM64_INS_LDRH
Definition: arm64.h:838
@ ARM64_INS_LDARH
Definition: arm64.h:827
@ ARM64_INS_WFE
Definition: arm64.h:1101
@ ARM64_INS_ADC
Definition: arm64.h:675
@ ARM64_INS_SXTH
Definition: arm64.h:1121
@ ARM64_INS_SVC
Definition: arm64.h:1019
@ ARM64_INS_CSINV
Definition: arm64.h:726
@ ARM64_INS_LDAXRB
Definition: arm64.h:830
@ ARM64_INS_STLXR
Definition: arm64.h:999
@ ARM64_INS_CMN
Definition: arm64.h:1112
@ ARM64_INS_LDXP
Definition: arm64.h:855
@ ARM64_INS_EON
Definition: arm64.h:735
@ ARM64_INS_CSEL
Definition: arm64.h:724
@ ARM64_INS_REV32
Definition: arm64.h:887
@ ARM64_INS_CCMP
Definition: arm64.h:702
@ ARM64_INS_UMADDL
Definition: arm64.h:1046
@ ARM64_INS_RET
Definition: arm64.h:885
@ ARM64_INS_TBZ
Definition: arm64.h:1025
@ ARM64_INS_LDXRH
Definition: arm64.h:857
@ ARM64_INS_LDTRSB
Definition: arm64.h:844
@ ARM64_INS_PRFM
Definition: arm64.h:880
@ ARM64_INS_LDTR
Definition: arm64.h:848
@ ARM64_INS_LDNP
Definition: arm64.h:833
@ ARM64_INS_LDRSW
Definition: arm64.h:841
@ ARM64_INS_LDAXRH
Definition: arm64.h:831
@ ARM64_INS_STXR
Definition: arm64.h:1014
@ ARM64_INS_LDARB
Definition: arm64.h:826
@ ARM64_INS_STXRB
Definition: arm64.h:1012
@ ARM64_INS_CINC
Definition: arm64.h:1116
@ ARM64_INS_MOVK
Definition: arm64.h:865
@ ARM64_INS_MRS
Definition: arm64.h:868
@ ARM64_INS_MOVN
Definition: arm64.h:866
@ ARM64_INS_STXP
Definition: arm64.h:1011
@ ARM64_INS_STURH
Definition: arm64.h:1010
@ ARM64_INS_UMULL
Definition: arm64.h:1061
@ ARM64_INS_SXTW
Definition: arm64.h:1122
@ ARM64_INS_ROR
Definition: arm64.h:890
@ ARM64_INS_CSET
Definition: arm64.h:1115
@ ARM64_INS_UXTH
Definition: arm64.h:1125
@ ARM64_INS_LDTRSW
Definition: arm64.h:847
@ ARM64_INS_LDURB
Definition: arm64.h:849
@ ARM64_INS_BFXIL
Definition: arm64.h:1111
@ ARM64_INS_LDURSB
Definition: arm64.h:852
@ ARM64_INS_REV
Definition: arm64.h:889
@ ARM64_INS_STLXRH
Definition: arm64.h:998
@ ARM64_INS_LDAXR
Definition: arm64.h:832
@ ARM64_INS_LDUR
Definition: arm64.h:850
@ ARM64_INS_HVC
Definition: arm64.h:813
@ ARM64_INS_BFM
Definition: arm64.h:690
@ ARM64_INS_STLXRB
Definition: arm64.h:997
@ ARM64_INS_UMNEGL
Definition: arm64.h:1097
@ ARM64_INS_LDXRB
Definition: arm64.h:856
@ ARM64_INS_UBFX
Definition: arm64.h:1109
@ ARM64_INS_ADR
Definition: arm64.h:681
@ ARM64_INS_SMULL
Definition: arm64.h:947
@ ARM64_INS_WFI
Definition: arm64.h:1102
@ ARM64_INS_CINV
Definition: arm64.h:1118
@ ARM64_INS_SMADDL
Definition: arm64.h:931
@ ARM64_INS_MSUB
Definition: arm64.h:870
@ ARM64_INS_LDTRB
Definition: arm64.h:842
@ ARM64_INS_UMSUBL
Definition: arm64.h:1058
@ ARM64_INS_ADRP
Definition: arm64.h:682
@ ARM64_INS_SMULH
Definition: arm64.h:945
@ ARM64_INS_STLRH
Definition: arm64.h:994
@ ARM64_INS_NGCS
Definition: arm64.h:1133
@ ARM64_INS_LDAXP
Definition: arm64.h:829
@ ARM64_INS_SBC
Definition: arm64.h:909
@ ARM64_INS_LDRSB
Definition: arm64.h:839
@ ARM64_INS_CNEG
Definition: arm64.h:1119
@ ARM64_INS_STRH
Definition: arm64.h:1004
@ ARM64_INS_MSR
Definition: arm64.h:869
@ ARM64_INS_CBNZ
Definition: arm64.h:699
@ ARM64_INS_STTRH
Definition: arm64.h:1006
@ ARM64_INS_LSL
Definition: arm64.h:859
@ ARM64_INS_LDR
Definition: arm64.h:837
@ ARM64_INS_PRFUM
Definition: arm64.h:881
@ ARM64_INS_STTR
Definition: arm64.h:1007
@ ARM64_INS_SDIV
Definition: arm64.h:912
@ ARM64_INS_UXTB
Definition: arm64.h:1124
@ ARM64_INS_MADD
Definition: arm64.h:861
@ ARM64_INS_SMNEGL
Definition: arm64.h:1098
@ ARM64_INS_LDRB
Definition: arm64.h:836
@ ARM64_INS_CLS
Definition: arm64.h:704
@ ARM64_INS_REV16
Definition: arm64.h:886
@ ARM64_INS_B
Definition: arm64.h:689
@ ARM64_INS_STR
Definition: arm64.h:1003
@ ARM64_INS_MOVZ
Definition: arm64.h:867
@ ARM64_INS_NEG
Definition: arm64.h:873
@ ARM64_INS_SXTB
Definition: arm64.h:1120
@ ARM64_INS_SBFIZ
Definition: arm64.h:1106
@ ARM64_INS_LDURSW
Definition: arm64.h:854
@ ARM64_INS_UMULH
Definition: arm64.h:1059
@ ARM64_INS_EXTR
Definition: arm64.h:738
@ ARM64_INS_UDIV
Definition: arm64.h:1043
@ ARM64_INS_STLR
Definition: arm64.h:995
@ ARM64_INS_ADD
Definition: arm64.h:679
@ ARM64_INS_SBFX
Definition: arm64.h:1108
@ ARM64_INS_HINT
Definition: arm64.h:811
@ ARM64_INS_STLRB
Definition: arm64.h:993
@ ARM64_INS_NGC
Definition: arm64.h:1105
@ ARM64_INS_MOV
Definition: arm64.h:715
@ ARM64_INS_YIELD
Definition: arm64.h:1100
@ ARM64_INS_LDRSH
Definition: arm64.h:840
@ ARM64_INS_CLZ
Definition: arm64.h:705
@ ARM64_INS_BR
Definition: arm64.h:696
@ ARM64_INS_LSR
Definition: arm64.h:860
@ ARM64_INS_LDP
Definition: arm64.h:834
@ ARM64_INS_BL
Definition: arm64.h:694
@ ARM64_INS_BIC
Definition: arm64.h:691
@ ARM64_INS_EOR
Definition: arm64.h:736
@ ARM64_INS_CMP
Definition: arm64.h:1123
@ ARM64_INS_MNEG
Definition: arm64.h:1096
@ ARM64_INS_STXRH
Definition: arm64.h:1013
@ ARM64_INS_MUL
Definition: arm64.h:871
@ ARM64_INS_STURB
Definition: arm64.h:1008
@ ARM64_INS_STTRB
Definition: arm64.h:1005
@ ARM64_INS_LDURSH
Definition: arm64.h:853
@ ARM64_INS_CBZ
Definition: arm64.h:700
@ ARM64_INS_ORR
Definition: arm64.h:876
@ ARM64_INS_LDTRSH
Definition: arm64.h:846
@ ARM64_INS_BLR
Definition: arm64.h:695
@ ARM64_INS_STRB
Definition: arm64.h:1002
@ ARM64_INS_SUB
Definition: arm64.h:1017
@ ARM64_INS_TST
Definition: arm64.h:1114
@ ARM64_INS_LDXR
Definition: arm64.h:858
@ ARM64_INS_STLXP
Definition: arm64.h:996
@ ARM64_INS_ASR
Definition: arm64.h:688
@ ARM64_INS_UBFIZ
Definition: arm64.h:1107
@ ARM64_INS_STP
Definition: arm64.h:1001
@ ARM64_INS_NEGS
Definition: arm64.h:1132
#define INV(x)
#define VARG(name)
#define SETG(name, v)

References add_sub(), adr(), ARM64_INS_ADC, ARM64_INS_ADD, ARM64_INS_ADR, ARM64_INS_ADRP, ARM64_INS_AND, ARM64_INS_ASR, ARM64_INS_B, ARM64_INS_BFI, ARM64_INS_BFM, ARM64_INS_BFXIL, ARM64_INS_BIC, ARM64_INS_BL, ARM64_INS_BLR, ARM64_INS_BR, ARM64_INS_CBNZ, ARM64_INS_CBZ, ARM64_INS_CCMN, ARM64_INS_CCMP, ARM64_INS_CINC, ARM64_INS_CINV, ARM64_INS_CLS, ARM64_INS_CLZ, ARM64_INS_CMN, ARM64_INS_CMP, ARM64_INS_CNEG, ARM64_INS_CSEL, ARM64_INS_CSET, ARM64_INS_CSETM, ARM64_INS_CSINC, ARM64_INS_CSINV, ARM64_INS_CSNEG, ARM64_INS_EON, ARM64_INS_EOR, ARM64_INS_EXTR, ARM64_INS_HINT, ARM64_INS_HVC, ARM64_INS_LDAR, ARM64_INS_LDARB, ARM64_INS_LDARH, ARM64_INS_LDAXP, ARM64_INS_LDAXR, ARM64_INS_LDAXRB, ARM64_INS_LDAXRH, ARM64_INS_LDNP, ARM64_INS_LDP, ARM64_INS_LDPSW, ARM64_INS_LDR, ARM64_INS_LDRB, ARM64_INS_LDRH, ARM64_INS_LDRSB, ARM64_INS_LDRSH, ARM64_INS_LDRSW, ARM64_INS_LDTR, ARM64_INS_LDTRB, ARM64_INS_LDTRH, ARM64_INS_LDTRSB, ARM64_INS_LDTRSH, ARM64_INS_LDTRSW, ARM64_INS_LDUR, ARM64_INS_LDURB, ARM64_INS_LDURH, ARM64_INS_LDURSB, ARM64_INS_LDURSH, ARM64_INS_LDURSW, ARM64_INS_LDXP, ARM64_INS_LDXR, ARM64_INS_LDXRB, ARM64_INS_LDXRH, ARM64_INS_LSL, ARM64_INS_LSR, ARM64_INS_MADD, ARM64_INS_MNEG, ARM64_INS_MOV, ARM64_INS_MOVK, ARM64_INS_MOVN, ARM64_INS_MOVZ, ARM64_INS_MRS, ARM64_INS_MSR, ARM64_INS_MSUB, ARM64_INS_MUL, ARM64_INS_MVN, ARM64_INS_NEG, ARM64_INS_NEGS, ARM64_INS_NGC, ARM64_INS_NGCS, ARM64_INS_NOP, ARM64_INS_ORN, ARM64_INS_ORR, ARM64_INS_PRFM, ARM64_INS_PRFUM, ARM64_INS_RBIT, ARM64_INS_RET, ARM64_INS_REV, ARM64_INS_REV16, ARM64_INS_REV32, ARM64_INS_ROR, ARM64_INS_SBC, ARM64_INS_SBFIZ, ARM64_INS_SBFX, ARM64_INS_SDIV, ARM64_INS_SEV, ARM64_INS_SEVL, ARM64_INS_SMADDL, ARM64_INS_SMNEGL, ARM64_INS_SMSUBL, ARM64_INS_SMULH, ARM64_INS_SMULL, ARM64_INS_STLR, ARM64_INS_STLRB, ARM64_INS_STLRH, ARM64_INS_STLXP, ARM64_INS_STLXR, ARM64_INS_STLXRB, ARM64_INS_STLXRH, ARM64_INS_STNP, ARM64_INS_STP, ARM64_INS_STR, ARM64_INS_STRB, ARM64_INS_STRH, ARM64_INS_STTR, ARM64_INS_STTRB, ARM64_INS_STTRH, ARM64_INS_STUR, ARM64_INS_STURB, ARM64_INS_STURH, ARM64_INS_STXP, ARM64_INS_STXR, ARM64_INS_STXRB, ARM64_INS_STXRH, ARM64_INS_SUB, ARM64_INS_SVC, ARM64_INS_SXTB, ARM64_INS_SXTH, ARM64_INS_SXTW, ARM64_INS_TBNZ, ARM64_INS_TBZ, ARM64_INS_TST, ARM64_INS_UBFIZ, ARM64_INS_UBFX, ARM64_INS_UDIV, ARM64_INS_UMADDL, ARM64_INS_UMNEGL, ARM64_INS_UMSUBL, ARM64_INS_UMULH, ARM64_INS_UMULL, ARM64_INS_UXTB, ARM64_INS_UXTH, ARM64_INS_WFE, ARM64_INS_WFI, ARM64_INS_YIELD, bfm(), bic(), bitwise(), bl(), branch(), cbz(), cls(), clz(), cmp(), cset(), csinc(), extr(), hvc(), INV, ldr(), madd(), mov(), movk(), movn(), mrs(), msr(), mul(), mvn(), NOP, NULL, rbit(), rev(), sbfx(), sdiv(), SETG, shift(), smaddl(), smulh(), smull(), str(), svc(), sxt(), tbz(), tst(), udiv(), and VARG.

Referenced by analysis_op().

◆ rz_arm_cs_64_il_config()

RZ_IPI RzAnalysisILConfig* rz_arm_cs_64_il_config ( bool  big_endian)

Definition at line 2762 of file arm_il64.c.

2762  {
2763  RzAnalysisILConfig *r = rz_analysis_il_config_new(64, big_endian, 64);
2764  r->reg_bindings = regs_bound;
2766  svc_label->hook = label_svc;
2767  rz_analysis_il_config_add_label(r, svc_label);
2769  hvc_label->hook = label_hvc;
2770  rz_analysis_il_config_add_label(r, hvc_label);
2771  return r;
2772 }
static void label_hvc(RzILVM *vm, RzILOpEffect *op)
Definition: arm_il64.c:1003
static void label_svc(RzILVM *vm, RzILOpEffect *op)
Definition: arm_il64.c:991
static const char * regs_bound[]
Definition: arm_il64.c:27

References EFFECT_LABEL_SYSCALL, rz_il_effect_label_t::hook, label_hvc(), label_svc(), r, regs_bound, rz_analysis_il_config_add_label(), rz_analysis_il_config_new(), and rz_il_effect_label_new().

Referenced by il_config().

◆ rz_arm_cs_analysis_op_32_esil()

RZ_IPI int rz_arm_cs_analysis_op_32_esil ( RzAnalysis a,
RzAnalysisOp op,
ut64  addr,
const ut8 buf,
int  len,
csh handle,
cs_insn *  insn,
bool  thumb 
)

Definition at line 239 of file arm_esil32.c.

239  {
240  int i;
241  const char *postfix = NULL;
242  char str[32][32];
243  int msr_flags;
244  int pcdelta = (thumb ? 4 : 8);
245  ut32 mask = UT32_MAX;
246  int str_ldr_bytes = 4;
247  unsigned int width = 0;
248 
249  rz_strbuf_init(&op->esil);
250  rz_strbuf_set(&op->esil, "");
251  postfix = rz_arm_cs_esil_prefix_cond(op, insn->detail->arm.cc);
252 
253  switch (insn->id) {
254  case ARM_INS_CLZ:
255  rz_strbuf_appendf(&op->esil, "%s,!,?{,32,%s,=,BREAK,},0,%s,=,%s,%s,<<,0x80000000,&,!,?{,1,%s,+=,11,GOTO,}", REG(1), REG(0), REG(0), REG(0), REG(1), REG(0));
256  break;
257  case ARM_INS_IT:
258  rz_strbuf_appendf(&op->esil, "2,$$,+,pc,=");
259  break;
260  case ARM_INS_BKPT:
261  rz_strbuf_setf(&op->esil, "%d,%d,TRAP", IMM(0), IMM(0));
262  break;
263  case ARM_INS_NOP:
264  rz_strbuf_setf(&op->esil, ",");
265  break;
266  case ARM_INS_BL:
267  case ARM_INS_BLX:
268  rz_strbuf_appendf(&op->esil, "pc,%d,+,lr,=,", thumb);
269  /* fallthrough */
270  case ARM_INS_BX:
271  case ARM_INS_BXJ:
272  case ARM_INS_B:
273  if (ISREG(0) && REGID(0) == ARM_REG_PC) {
274  rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",pc,=", (addr & ~3LL) + pcdelta);
275  } else {
276  if (ISIMM(0)) {
277  rz_strbuf_appendf(&op->esil, "%s,pc,=", ARG(0));
278  } else {
279  rz_strbuf_appendf(&op->esil, "%d,%s,-,pc,=", thumb, ARG(0));
280  }
281  }
282  break;
283  case ARM_INS_UDF:
284  rz_strbuf_setf(&op->esil, "%s,TRAP", ARG(0));
285  break;
286  case ARM_INS_SADD16:
287  case ARM_INS_SADD8:
288  MATH32AS("+");
289  break;
290  case ARM_INS_ADDW:
291  case ARM_INS_ADD:
292  MATH32("+");
293  break;
294  case ARM_INS_ADC:
295  if (OPCOUNT() == 2) {
296  rz_strbuf_appendf(&op->esil, "cf,%s,+=,%s,%s,+=", ARG(0), ARG(1), ARG(0));
297  } else {
298  rz_strbuf_appendf(&op->esil, "cf,%s,+=,%s,%s,+,%s,+=", ARG(0), ARG(2), ARG(1), ARG(0));
299  }
300  break;
301  case ARM_INS_SSUB16:
302  case ARM_INS_SSUB8:
303  MATH32AS("-");
304  break;
305  case ARM_INS_SUBW:
306  case ARM_INS_SUB:
307  MATH32("-");
308  break;
309  case ARM_INS_SBC:
310  if (OPCOUNT() == 2) {
311  rz_strbuf_appendf(&op->esil, "cf,%s,-=,%s,%s,-=", ARG(0), ARG(1), ARG(0));
312  } else {
313  rz_strbuf_appendf(&op->esil, "cf,%s,-=,%s,%s,+,%s,-=", ARG(0), ARG(2), ARG(1), ARG(0));
314  }
315  break;
316  case ARM_INS_MUL:
317  MATH32("*");
318  break;
319  case ARM_INS_AND:
320  MATH32("&");
321  break;
322  case ARM_INS_ORR:
323  MATH32("|");
324  break;
325  case ARM_INS_EOR:
326  MATH32("^");
327  break;
328  case ARM_INS_ORN:
329  MATH32_NEG("|");
330  break;
331  case ARM_INS_LSR:
332  if (insn->detail->arm.update_flags) {
333  if (OPCOUNT() == 2) {
334  rz_strbuf_appendf(&op->esil, "%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,},", ARG(1), ARG(0), ARG(1));
335  } else {
336  rz_strbuf_appendf(&op->esil, "%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,},", ARG(2), ARG(1), ARG(2));
337  }
338  }
339  MATH32(">>");
340  break;
341  case ARM_INS_LSL:
342  if (insn->detail->arm.update_flags) {
343  if (OPCOUNT() == 2) {
344  rz_strbuf_appendf(&op->esil, "%s,!,!,?{,%s,32,-,%s,>>,cf,:=,},", ARG(1), ARG(1), ARG(0));
345  } else {
346  rz_strbuf_appendf(&op->esil, "%s,!,!,?{,%s,32,-,%s,>>,cf,:=,},", ARG(2), ARG(2), ARG(1));
347  }
348  }
349  MATH32("<<");
350  break;
351  case ARM_INS_SVC:
352  rz_strbuf_setf(&op->esil, "%s,$", ARG(0));
353  break;
354  case ARM_INS_PUSH:
355 #if 0
356 PUSH { r4, r5, r6, r7, lr }
357 4,sp,-=,lr,sp,=[4],
358 4,sp,-=,r7,sp,=[4],
359 4,sp,-=,r6,sp,=[4],
360 4,sp,-=,r5,sp,=[4],
361 4,sp,-=,r4,sp,=[4]
362 
363 20,sp,-=,lr,r7,r6,r5,r4,5,sp,=[*]
364 #endif
365  rz_strbuf_appendf(&op->esil, "%d,sp,-=,",
366  4 * insn->detail->arm.op_count);
367  for (i = insn->detail->arm.op_count; i > 0; i--) {
368  rz_strbuf_appendf(&op->esil, "%s,", REG(i - 1));
369  }
370  rz_strbuf_appendf(&op->esil, "%d,sp,=[*]",
371  insn->detail->arm.op_count);
372  break;
373  case ARM_INS_STMDA:
374  case ARM_INS_STMDB:
375  case ARM_INS_STM:
376  case ARM_INS_STMIB: {
377  int direction = (insn->id == ARM_INS_STMDA || insn->id == ARM_INS_STMDB ? -1 : 1);
378  int offset = direction > 0 ? -1 : -insn->detail->arm.op_count;
379  if (insn->id == ARM_INS_STMDA || insn->id == ARM_INS_STMIB) {
380  offset++;
381  }
382  for (i = 1; i < insn->detail->arm.op_count; i++) {
383  rz_strbuf_appendf(&op->esil, "%s,%s,%d,+,=[4],",
384  REG(i), ARG(0), (i + offset) * 4);
385  }
386  if (insn->detail->arm.writeback == true) { // writeback, reg should be incremented
387  rz_strbuf_appendf(&op->esil, "%d,%s,+=,",
388  direction * (insn->detail->arm.op_count - 1) * 4, ARG(0));
389  }
390  break;
391  }
392  case ARM_INS_VSTMIA:
393  rz_strbuf_set(&op->esil, "");
394  width = 0;
395  for (i = 1; i < insn->detail->arm.op_count; i++) {
396  rz_strbuf_appendf(&op->esil, "%s,%d,%s,+,=[%d],",
397  REG(i), width, ARG(0), REGSIZE32(i));
398  width += REGSIZE32(i);
399  }
400  // increment if writeback
401  if (insn->detail->arm.writeback) {
402  rz_strbuf_appendf(&op->esil, "%d,%s,+=,", width, ARG(0));
403  }
404  break;
405  case ARM_INS_VSTMDB:
406  rz_strbuf_set(&op->esil, "");
407  width = 0;
408  for (i = insn->detail->arm.op_count - 1; i > 0; i--) {
409  width += REGSIZE32(i);
410  rz_strbuf_appendf(&op->esil, "%s,%d,%s,-,=[%d],",
411  REG(i), width, ARG(0), REGSIZE32(i));
412  }
413  // decrement writeback is mandatory for VSTMDB
414  rz_strbuf_appendf(&op->esil, "%d,%s,-=,", width, ARG(0));
415  break;
416  case ARM_INS_VLDMIA:
417  rz_strbuf_set(&op->esil, "");
418  width = 0;
419  for (i = 1; i < insn->detail->arm.op_count; i++) {
420  rz_strbuf_appendf(&op->esil, "%d,%s,+,[%d],%s,=,",
421  width, ARG(0), REGSIZE32(i), REG(i));
422  width += REGSIZE32(i);
423  }
424  // increment if writeback
425  if (insn->detail->arm.writeback) {
426  rz_strbuf_appendf(&op->esil, "%d,%s,+=,", width, ARG(0));
427  }
428  break;
429  case ARM_INS_VLDMDB:
430  rz_strbuf_set(&op->esil, "");
431  width = 0;
432  for (i = insn->detail->arm.op_count - 1; i > 0; i--) {
433  width += REGSIZE32(i);
434  rz_strbuf_appendf(&op->esil, "%d,%s,-,[%d],%s,=,",
435  width, ARG(0), REGSIZE32(i), REG(i));
436  }
437  // decrement writeback is mandatory for VLDMDB
438  rz_strbuf_appendf(&op->esil, "%d,%s,-=,", width, ARG(0));
439  break;
440  case ARM_INS_ASR:
441  // suffix 'S' forces conditional flag to be updated
442  if (insn->detail->arm.update_flags) {
443  if (OPCOUNT() == 2) {
444  rz_strbuf_appendf(&op->esil, "%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,},", ARG(1), ARG(0), ARG(1));
445  } else if (OPCOUNT() == 3) {
446  rz_strbuf_appendf(&op->esil, "%s,!,!,?{,%s,1,%s,-,0x1,<<,&,!,!,cf,:=,},", ARG(2), ARG(1), ARG(2));
447  }
448  }
449  if (OPCOUNT() == 2) {
450  if (ISSHIFTED(1)) {
451  rz_strbuf_appendf(&op->esil, "%s,%s,=", ARG(1), ARG(0));
452  } else {
453  rz_strbuf_appendf(&op->esil, "%s,%s,>>>>,%s,=", ARG(1), ARG(0), ARG(0));
454  }
455  } else if (OPCOUNT() == 3) {
456  rz_strbuf_appendf(&op->esil, "%s,%s,>>>>,%s,=", ARG(2), ARG(1), ARG(0));
457  }
458  break;
459  case ARM_INS_POP:
460 #if 0
461 POP { r4,r5, r6}
462 r6,r5,r4,3,sp,[*],12,sp,+=
463 #endif
464  for (i = insn->detail->arm.op_count; i > 0; i--) {
465  rz_strbuf_appendf(&op->esil, "%s,", REG(i - 1));
466  }
467  rz_strbuf_appendf(&op->esil, "%d,sp,[*],",
468  insn->detail->arm.op_count);
469  rz_strbuf_appendf(&op->esil, "%d,sp,+=",
470  4 * insn->detail->arm.op_count);
471  break;
472  case ARM_INS_LDMDA:
473  case ARM_INS_LDMDB:
474  case ARM_INS_LDM:
475  case ARM_INS_LDMIB: {
476  int direction = (insn->id == ARM_INS_LDMDA || insn->id == ARM_INS_LDMDB) ? -1 : 1;
477  int offset = direction > 0 ? -1 : -insn->detail->arm.op_count;
478  if (insn->id == ARM_INS_LDMDA || insn->id == ARM_INS_LDMIB) {
479  offset++;
480  }
481  for (i = 1; i < insn->detail->arm.op_count; i++) {
482  rz_strbuf_appendf(&op->esil, "%s,%d,+,[4],%s,=,", ARG(0), (i + offset) * 4, REG(i));
483  }
484  if (insn->detail->arm.writeback) {
485  rz_strbuf_appendf(&op->esil, "%d,%s,+=,",
486  direction * (insn->detail->arm.op_count - 1) * 4, ARG(0));
487  }
488  break;
489  }
490  case ARM_INS_CMP:
491  rz_strbuf_appendf(&op->esil, "%s,%s,==", ARG(1), ARG(0));
492  break;
493  case ARM_INS_CMN:
494  rz_strbuf_appendf(&op->esil, "%s,%s,^,!,!,zf,=", ARG(1), ARG(0));
495  break;
496  case ARM_INS_MOVT:
497  rz_strbuf_appendf(&op->esil, "16,%s,<<,%s,|=", ARG(1), REG(0));
498  break;
499  case ARM_INS_ADR:
500  rz_strbuf_appendf(&op->esil, "%d,$$,+,%s,+,0xfffffffc,&,%s,=",
501  pcdelta, ARG(1), REG(0));
502  break;
503  case ARM_INS_MOV:
504  case ARM_INS_VMOV:
505  case ARM_INS_MOVW:
506  rz_strbuf_appendf(&op->esil, "%s,%s,=", ARG(1), REG(0));
507  break;
508  case ARM_INS_CBZ:
509  rz_strbuf_appendf(&op->esil, "%s,!,?{,%" PFMT32u ",pc,=,}",
510  REG(0), IMM(1));
511  break;
512  case ARM_INS_CBNZ:
513  rz_strbuf_appendf(&op->esil, "%s,?{,%" PFMT32u ",pc,=,}",
514  REG(0), IMM(1));
515  break;
516  // Encapsulated STR/H/B into a code section
517  case ARM_INS_STRT:
518  case ARM_INS_STR:
519  case ARM_INS_STRHT:
520  case ARM_INS_STRH:
521  case ARM_INS_STRBT:
522  case ARM_INS_STRB:
523  case ARM_INS_STRD:
524  // case ARM_INS_STLXRB: // capstone has no STLXR?
525  switch (insn->id) {
526  case ARM_INS_STRD:
527  str_ldr_bytes = 8; // just an indication, won't be used in esil code
528  break;
529  case ARM_INS_STRHT:
530  case ARM_INS_STRH:
531  str_ldr_bytes = 2;
532  break;
533  case ARM_INS_STRBT:
534  case ARM_INS_STRB:
535  str_ldr_bytes = 1;
536  break;
537  default:
538  str_ldr_bytes = 4;
539  }
540  if (OPCOUNT() == 2) {
541  if (ISMEM(1) && !HASMEMINDEX(1)) {
542  int disp = MEMDISP(1);
543  char sign = disp >= 0 ? '+' : '-';
544  disp = disp >= 0 ? disp : -disp;
545  rz_strbuf_appendf(&op->esil, "%s,0x%x,%s,%c,0xffffffff,&,=[%d]",
546  REG(0), disp, MEMBASE(1), sign, str_ldr_bytes);
547  if (insn->detail->arm.writeback) {
548  rz_strbuf_appendf(&op->esil, ",%d,%s,%c,%s,=",
549  disp, MEMBASE(1), sign, MEMBASE(1));
550  }
551  }
552  if (HASMEMINDEX(1)) { // e.g. 'str r2, [r3, r1]'
553  if (ISSHIFTED(1)) { // e.g. 'str r2, [r3, r1, lsl 4]'
554  switch (SHIFTTYPE(1)) {
555  case ARM_SFT_LSL:
556  rz_strbuf_appendf(&op->esil, "%s,%s,%d,%s,<<,+,0xffffffff,&,=[%d]",
557  REG(0), MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), str_ldr_bytes);
558  if (insn->detail->arm.writeback) { // e.g. 'str r2, [r3, r1, lsl 4]!'
559  rz_strbuf_appendf(&op->esil, ",%s,%d,%s,<<,+,%s,=",
560  MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1));
561  }
562  break;
563  case ARM_SFT_LSR:
564  rz_strbuf_appendf(&op->esil, "%s,%s,%d,%s,>>,+,0xffffffff,&,=[%d]",
565  REG(0), MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), str_ldr_bytes);
566  if (insn->detail->arm.writeback) {
567  rz_strbuf_appendf(&op->esil, ",%s,%d,%s,>>,+,%s,=",
568  MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1));
569  }
570  break;
571  case ARM_SFT_ASR:
572  rz_strbuf_appendf(&op->esil, "%s,%s,%d,%s,>>>>,+,0xffffffff,&,=[%d]",
573  REG(0), MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), str_ldr_bytes);
574  if (insn->detail->arm.writeback) {
575  rz_strbuf_appendf(&op->esil, ",%s,%d,%s,>>>>,+,%s,=",
576  MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1));
577  }
578  break;
579  case ARM_SFT_ROR:
580  rz_strbuf_appendf(&op->esil, "%s,%s,%d,%s,>>>,+,0xffffffff,&,=[%d]",
581  REG(0), MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), str_ldr_bytes);
582  if (insn->detail->arm.writeback) {
583  rz_strbuf_appendf(&op->esil, ",%s,%d,%s,>>>,+,%s,=",
584  MEMBASE(1), SHIFTVALUE(1), MEMINDEX(1), MEMBASE(1));
585  }
586  break;
587  case ARM_SFT_RRX: // ROR with single bit shift, using previous cf rather than new cf
588  // TODO: r2 doesn't mark this as a shift, it falls through to no shift
589  break;
590  default:
591  // Hopefully nothing here
592  break;
593  }
594  } else { // No shift
595  rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,0xffffffff,&,=[%d]",
596  REG(0), MEMINDEX(1), MEMBASE(1), str_ldr_bytes);
597  if (insn->detail->arm.writeback) {
598  rz_strbuf_appendf(&op->esil, ",%s,%s,+,%s,=",
599  MEMINDEX(1), MEMBASE(1), MEMBASE(1));
600  }
601  }
602  }
603  }
604  if (OPCOUNT() == 3) { // e.g. 'str r2, [r3], 4
605  if (ISIMM(2)) { // e.g. 'str r2, [r3], 4
606  rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%d,%s,+=",
607  REG(0), MEMBASE(1), str_ldr_bytes, IMM(2), MEMBASE(1));
608  }
609  if (ISREG(2)) { // e.g. 'str r2, [r3], r1
610  if (ISSHIFTED(2)) { // e.g. 'str r2, [r3], r1, lsl 4'
611  switch (SHIFTTYPE(2)) {
612  case ARM_SFT_LSL:
613  rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,<<,+,%s,=",
614  REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), REG(2), MEMBASE(1));
615  break;
616  case ARM_SFT_LSR:
617  rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>,+,%s,=",
618  REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), REG(2), MEMBASE(1));
619  break;
620  case ARM_SFT_ASR:
621  rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>>>,+,%s,=",
622  REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), REG(2), MEMBASE(1));
623  break;
624  case ARM_SFT_ROR:
625  rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%d,%s,>>>,+,%s,=",
626  REG(0), MEMBASE(1), str_ldr_bytes, MEMBASE(1), SHIFTVALUE(2), REG(2), MEMBASE(1));
627  break;
628  case ARM_SFT_RRX:
629  // TODO
630  break;
631  default:
632  // Hopefully nothing here
633  break;
634  }
635  } else { // No shift
636  rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,%s,+=",
637  REG(0), MEMBASE(1), str_ldr_bytes, REG(2), MEMBASE(1));
638  }
639  }
640  if (ISREG(1) && str_ldr_bytes == 8) { // e.g. 'strd r2, r3, [r4]', normally should be the only case for ISREG(1).
641  if (!HASMEMINDEX(2)) {
642  int disp = MEMDISP(2);
643  char sign = disp >= 0 ? '+' : '-';
644  disp = disp >= 0 ? disp : -disp;
645  rz_strbuf_appendf(&op->esil, "%s,%d,%s,%c,0xffffffff,&,=[4],%s,4,%d,+,%s,%c,0xffffffff,&,=[4]",
646  REG(0), disp, MEMBASE(2), sign, REG(1), disp, MEMBASE(2), sign);
647  if (insn->detail->arm.writeback) {
648  rz_strbuf_appendf(&op->esil, ",%d,%s,%c,%s,=",
649  disp, MEMBASE(2), sign, MEMBASE(2));
650  }
651  } else {
652  if (ISSHIFTED(2)) {
653  // it seems strd does not support SHIFT which is good, but have a check nonetheless
654  } else {
655  rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,0xffffffff,&,=[4],%s,4,%s,+,%s,+,0xffffffff,&,=[4]",
656  REG(0), MEMINDEX(2), MEMBASE(2), REG(1), MEMINDEX(2), MEMBASE(2));
657  if (insn->detail->arm.writeback) {
658  rz_strbuf_appendf(&op->esil, ",%s,%s,+,%s,=",
659  MEMINDEX(2), MEMBASE(2), MEMBASE(2));
660  }
661  }
662  }
663  }
664  }
665  if (OPCOUNT() == 4) { // e.g. 'strd r2, r3, [r4], 4' or 'strd r2, r3, [r4], r5'
666  if (ISIMM(3)) { // e.g. 'strd r2, r3, [r4], 4'
667  rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,4,%s,+,0xffffffff,&,=[%d],%d,%s,+=,",
668  REG(0), MEMBASE(2), str_ldr_bytes, REG(1), MEMBASE(2), str_ldr_bytes, IMM(3), MEMBASE(2));
669  }
670  if (ISREG(3)) { // e.g. 'strd r2, r3, [r4], r5'
671  if (ISSHIFTED(3)) {
672  // same as above
673  } else {
674  rz_strbuf_appendf(&op->esil, "%s,%s,0xffffffff,&,=[%d],%s,4,%s,+,0xffffffff,&,=[%d],%s,%s,+=",
675  REG(0), MEMBASE(2), str_ldr_bytes, REG(1), MEMBASE(2), str_ldr_bytes, REG(3), MEMBASE(2));
676  }
677  }
678  }
679  break;
680  case ARM_INS_TST:
681  rz_strbuf_appendf(&op->esil, "0,%s,%s,&,==", ARG(1), ARG(0));
682  break;
683  case ARM_INS_LDRD:
684  addr &= ~3LL;
685  if (MEMDISP(2) < 0) {
686  const char *pc = "$$";
687  if (REGBASE(2) == ARM_REG_PC) {
688  op->refptr = 4;
689  op->ptr = addr + pcdelta + MEMDISP(2);
690  rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",2,2,%s,%d,+,>>,<<,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
691  (ut64)MEMDISP(2), pc, pcdelta, REG(0), REG(1));
692  } else {
693  int disp = MEMDISP(2);
694  // not refptr, because we can't grab the reg value statically op->refptr = 4;
695  if (disp < 0) {
696  rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,-,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
697  (ut64)-disp, MEMBASE(2), REG(0), REG(1));
698  } else {
699  rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
700  (ut64)disp, MEMBASE(2), REG(0), REG(1));
701  }
702  }
703  } else {
704  if (REGBASE(2) == ARM_REG_PC) {
705  const char *pc = "$$";
706  op->refptr = 4;
707  op->ptr = addr + pcdelta + MEMDISP(2);
708  if (HASMEMINDEX(2) || ISREG(2)) {
709  const char op_index = ISMEMINDEXSUB(2) ? '-' : '+';
710  rz_strbuf_appendf(&op->esil, "%s,2,2,%d,%s,+,>>,<<,%c,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
711  MEMINDEX(2), pcdelta, pc, op_index, REG(0), REG(1));
712  } else {
713  rz_strbuf_appendf(&op->esil, "2,2,%d,%s,+,>>,<<,%d,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
714  pcdelta, pc, MEMDISP(2), REG(0), REG(1));
715  }
716  } else {
717  if (HASMEMINDEX(2)) { // e.g. `ldrd r2, r3 [r4, r1]`
718  const char op_index = ISMEMINDEXSUB(2) ? '-' : '+';
719  rz_strbuf_appendf(&op->esil, "%s,%s,%c,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
720  MEMINDEX(2), MEMBASE(2), op_index, REG(0), REG(1));
721  } else {
722  rz_strbuf_appendf(&op->esil, "%d,%s,+,0xffffffff,&,DUP,[4],%s,=,4,+,[4],%s,=",
723  MEMDISP(2), MEMBASE(2), REG(0), REG(1));
724  }
725  if (insn->detail->arm.writeback) {
726  if (ISPOSTINDEX32()) {
727  if (ISIMM(3)) {
728  rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=",
729  MEMBASE(2), IMM(3), MEMBASE(2));
730  } else {
731  const char op_index = ISMEMINDEXSUB(3) ? '-' : '+';
732  rz_strbuf_appendf(&op->esil, ",%s,%s,%c,%s,=",
733  REG(3), MEMBASE(2), op_index, MEMBASE(2));
734  }
735  } else if (ISPREINDEX32()) {
736  if (HASMEMINDEX(2)) {
737  const char op_index = ISMEMINDEXSUB(2) ? '-' : '+';
738  rz_strbuf_appendf(&op->esil, ",%s,%s,%c,%s,=",
739  MEMINDEX(2), MEMBASE(2), op_index, MEMBASE(2));
740  } else {
741  rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=",
742  MEMBASE(2), MEMDISP(2), MEMBASE(2));
743  }
744  }
745  }
746  }
747  }
748  break;
749  case ARM_INS_LDRB:
750  if (ISMEM(1) && LSHIFT2(1)) {
751  rz_strbuf_appendf(&op->esil, "%s,%d,%s,<<,+,0xffffffff,&,[1],0x%x,&,%s,=",
752  MEMBASE(1), LSHIFT2(1), MEMINDEX(1), mask, REG(0));
753  } else if (HASMEMINDEX(1)) {
754  rz_strbuf_appendf(&op->esil, "%s,%s,+,0xffffffff,&,[1],%s,=",
755  MEMINDEX(1), MEMBASE(1), REG(0));
756  } else {
757  rz_strbuf_appendf(&op->esil, "%s,%d,+,[1],%s,=",
758  MEMBASE(1), MEMDISP(1), REG(0));
759  }
760  if (insn->detail->arm.writeback) {
761  if (ISIMM(2)) {
762  rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=",
763  MEMBASE(1), IMM(2), MEMBASE(1));
764  } else {
765  rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=",
766  MEMBASE(1), MEMDISP(1), MEMBASE(1));
767  }
768  }
769  break;
770  case ARM_INS_SXTH:
771  rz_strbuf_appendf(&op->esil,
772  "15,%s,>>,1,&,?{,15,-1,<<,%s,0xffff,&,|,%s,:=,}{,%s,0xffff,%s,:=,}",
773  REG(1), REG(1), REG(0), REG(1), REG(0));
774  break;
775  case ARM_INS_SXTB:
776  rz_strbuf_appendf(&op->esil,
777  "7,%s,>>,1,&,?{,7,-1,<<,%s,0xff,&,|,%s,:=,}{,%s,0xff,&,%s,:=,}",
778  REG(1), REG(1), REG(0), REG(1), REG(0));
779  break;
780  case ARM_INS_LDREX:
781  case ARM_INS_LDREXB:
782  case ARM_INS_LDREXD:
783  case ARM_INS_LDREXH:
785  // intentional fallthrough
786  case ARM_INS_LDRHT:
787  case ARM_INS_LDRH:
788  case ARM_INS_LDRT:
789  case ARM_INS_LDRBT:
790  case ARM_INS_LDRSB:
791  case ARM_INS_LDRSBT:
792  case ARM_INS_LDRSH:
793  case ARM_INS_LDRSHT:
794  case ARM_INS_LDR:
795  switch (insn->id) {
796  case ARM_INS_LDRHT:
797  case ARM_INS_LDRH:
798  case ARM_INS_LDRSH:
799  case ARM_INS_LDRSHT:
800  mask = UT16_MAX;
801  break;
802  default:
803  mask = UT32_MAX;
804  break;
805  }
806  addr &= ~3LL;
807  if (MEMDISP(1) < 0) {
808  const char *pc = "$$";
809  if (REGBASE(1) == ARM_REG_PC) {
810  op->refptr = 4;
811  op->ptr = addr + pcdelta + MEMDISP(1);
812  rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",2,2,%s,>>,<<,+,0xffffffff,&,[4],0x%x,&,%s,=",
813  (ut64)MEMDISP(1), pc, mask, REG(0));
814  } else {
815  int disp = MEMDISP(1);
816  // not refptr, because we can't grab the reg value statically op->refptr = 4;
817  if (disp < 0) {
818  rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,-,0xffffffff,&,[4],0x%x,&,%s,=",
819  (ut64)-disp, MEMBASE(1), mask, REG(0));
820  } else {
821  rz_strbuf_appendf(&op->esil, "0x%" PFMT64x ",%s,+,0xffffffff,&,[4],0x%x,&,%s,=",
822  (ut64)disp, MEMBASE(1), mask, REG(0));
823  }
824  }
825  } else {
826  if (ISMEM(1) && REGBASE(1) == ARM_REG_PC) {
827  const char *pc = "$$";
828  if (HASMEMINDEX(1)) {
829  if (LSHIFT2(1)) {
830  rz_strbuf_appendf(&op->esil, "2,2,%d,%s,+,>>,<<,%d,%s,<<,+,0xffffffff,&,[4],0x%x,&,%s,=",
831  pcdelta, pc, LSHIFT2(1), MEMINDEX(1), mask, REG(0));
832  } else {
833  rz_strbuf_appendf(&op->esil, "2,2,%d,%s,+,>>,<<,%s,+,0xffffffff,&,[4],0x%x,&,%s,=",
834  pcdelta, pc, MEMINDEX(1), mask, REG(0));
835  }
836  } else {
837  op->refptr = 4;
838  op->ptr = addr + pcdelta + MEMDISP(1);
839  rz_strbuf_appendf(&op->esil, "2,2,%d,%s,+,>>,<<,%d,+,0xffffffff,&,[4],0x%x,&,%s,=",
840  pcdelta, pc, MEMDISP(1), mask, REG(0));
841  }
842  } else {
843  if (ISMEM(1) && LSHIFT2(1)) {
844  rz_strbuf_appendf(&op->esil, "%s,%d,%s,<<,+,0xffffffff,&,[4],0x%x,&,%s,=",
845  MEMBASE(1), LSHIFT2(1), MEMINDEX(1), mask, REG(0));
846  } else if (HASMEMINDEX(1)) { // e.g. `ldr r2, [r3, r1]`
847  rz_strbuf_appendf(&op->esil, "%s,%s,+,0xffffffff,&,[4],0x%x,&,%s,=",
848  MEMINDEX(1), MEMBASE(1), mask, REG(0));
849  } else {
850  rz_strbuf_appendf(&op->esil, "%d,%s,+,0xffffffff,&,[4],0x%x,&,%s,=",
851  MEMDISP(1), MEMBASE(1), mask, REG(0));
852  }
853  if (insn->detail->arm.writeback) {
854  if (ISIMM(2)) {
855  rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=",
856  MEMBASE(1), IMM(2), MEMBASE(1));
857  } else {
858  rz_strbuf_appendf(&op->esil, ",%s,%d,+,%s,=",
859  MEMBASE(1), MEMDISP(1), MEMBASE(1));
860  }
861  }
862  }
863  }
864  break;
865  case ARM_INS_MRS:
866  // TODO: esil for MRS
867  break;
868  case ARM_INS_MSR:
869  msr_flags = insn->detail->arm.operands[0].reg >> 4;
870  rz_strbuf_appendf(&op->esil, "0,");
871  if (msr_flags & 1) {
872  rz_strbuf_appendf(&op->esil, "0xFF,|,");
873  }
874  if (msr_flags & 2) {
875  rz_strbuf_appendf(&op->esil, "0xFF00,|,");
876  }
877  if (msr_flags & 4) {
878  rz_strbuf_appendf(&op->esil, "0xFF0000,|,");
879  }
880  if (msr_flags & 8) {
881  rz_strbuf_appendf(&op->esil, "0xFF000000,|,");
882  }
883  rz_strbuf_appendf(&op->esil, "DUP,!,SWAP,&,%s,SWAP,cpsr,&,|,cpsr,=", REG(1));
884  break;
885  case ARM_INS_UBFX:
886  if (IMM(3) > 0 && IMM(3) <= 32 - IMM(2)) {
887  rz_strbuf_appendf(&op->esil, "%d,%s,%d,%" PFMT64u ",<<,&,>>,%s,=",
888  IMM(2), REG(1), IMM(2), rz_num_bitmask((ut8)IMM(3)), REG(0));
889  }
890  break;
891  case ARM_INS_UXTB:
892  rz_strbuf_appendf(&op->esil, "%s,0xff,&,%s,=", ARG(1), REG(0));
893  break;
894  case ARM_INS_RSB:
895  if (OPCOUNT() == 2) {
896  rz_strbuf_appendf(&op->esil, "%s,%s,-=", ARG(0), ARG(1));
897  } else if (OPCOUNT() == 3) {
898  rz_strbuf_appendf(&op->esil, "%s,%s,-,%s,=", ARG(1), ARG(2), ARG(0));
899  }
900  break;
901  case ARM_INS_BIC:
902  if (OPCOUNT() == 2) {
903  rz_strbuf_appendf(&op->esil, "%s,0xffffffff,^,%s,&=", ARG(1), ARG(0));
904  } else {
905  rz_strbuf_appendf(&op->esil, "%s,0xffffffff,^,%s,&,%s,=", ARG(2), ARG(1), ARG(0));
906  }
907  break;
908  case ARM_INS_SMMLA:
909  rz_strbuf_appendf(&op->esil, "32,%s,%s,*,>>,%s,+,0xffffffff,&,%s,=",
910  REG(1), REG(2), REG(3), REG(0));
911  break;
912  case ARM_INS_SMMLAR:
913  rz_strbuf_appendf(&op->esil, "32,0x80000000,%s,%s,*,+,>>,%s,+,0xffffffff,&,%s,=",
914  REG(1), REG(2), REG(3), REG(0));
915  break;
916  case ARM_INS_UMULL:
917  rz_strbuf_appendf(&op->esil, "32,%s,%s,*,DUP,0xffffffff,&,%s,=,>>,%s,=",
918  REG(2), REG(3), REG(0), REG(1));
919  break;
920  case ARM_INS_MLS:
921  rz_strbuf_appendf(&op->esil, "%s,%s,*,%s,-,0xffffffff,&,%s,=",
922  REG(1), REG(2), REG(3), REG(0));
923  break;
924  case ARM_INS_MLA:
925  rz_strbuf_appendf(&op->esil, "%s,%s,*,%s,+,0xffffffff,&,%s,=",
926  REG(1), REG(2), REG(3), REG(0));
927  break;
928  case ARM_INS_MVN:
929  rz_strbuf_appendf(&op->esil, "-1,%s,^,0xffffffff,&,%s,=",
930  ARG(1), REG(0));
931  break;
932  case ARM_INS_BFI: {
933  if (OPCOUNT() >= 3 && ISIMM(3) && IMM(3) > 0 && IMM(3) < 64) {
934  ut64 mask = rz_num_bitmask((ut8)IMM(3));
935  ut64 shift = IMM(2);
936  ut64 notmask = ~(mask << shift);
937  // notmask,dst,&,lsb,mask,src,&,<<,|,dst,=
938  rz_strbuf_setf(&op->esil, "%" PFMT64u ",%s,&,%" PFMT64u ",%" PFMT64u ",%s,&,<<,|,0xffffffff,&,%s,=",
939  notmask, REG(0), shift, mask, REG(1), REG(0));
940  }
941  break;
942  }
943  case ARM_INS_BFC: {
944  if (OPCOUNT() >= 2 && ISIMM(2) && IMM(2) > 0 && IMM(2) < 64) {
945  ut64 mask = rz_num_bitmask((ut8)IMM(2));
946  ut64 shift = IMM(1);
947  ut64 notmask = ~(mask << shift);
948  // notmask,dst,&,dst,=
949  rz_strbuf_setf(&op->esil, "%" PFMT64u ",%s,&,0xffffffff,&,%s,=",
950  notmask, REG(0), REG(0));
951  }
952  break;
953  }
954  case ARM_INS_REV: {
955  const char *r0 = REG(0);
956  const char *r1 = REG(1);
957  rz_strbuf_setf(&op->esil,
958  "24,0xff,%s,&,<<,%s,=,"
959  "16,0xff,8,%s,>>,&,<<,%s,|=,"
960  "8,0xff,16,%s,>>,&,<<,%s,|=,"
961  "0xff,24,%s,>>,&,%s,|=,",
962  r1, r0, r1, r0, r1, r0, r1, r0);
963  break;
964  }
965  case ARM_INS_REV16: {
966  const char *r0 = REG(0);
967  const char *r1 = REG(1);
968  rz_strbuf_setf(&op->esil,
969  "8,0xff00ff00,%s,&,>>,%s,=,"
970  "8,0x00ff00ff,%s,&,<<,%s,|=,",
971  r1, r0, r1, r0);
972  break;
973  }
974  case ARM_INS_REVSH: {
975  const char *r0 = REG(0);
976  const char *r1 = REG(1);
977  rz_strbuf_setf(&op->esil,
978  "8,0xff00,%s,&,>>,%s,=,"
979  "8,0x00ff,%s,&,<<,%s,|=,"
980  "0x8000,%s,&,?{,"
981  "0xffff0000,%s,|=,"
982  "}",
983  r1, r0, r1, r0, r0, r0);
984  break;
985  }
986  case ARM_INS_TBB:
987  rz_strbuf_appendf(&op->esil, "%s,%s,+,0xffffffff,&,DUP,[1],1,SWAP,<<,+,pc,+=",
988  MEMBASE(0), MEMINDEX(0));
989  break;
990  case ARM_INS_TBH:
991  rz_strbuf_appendf(&op->esil, "%s,%d,%s,<<,+,0xffffffff,&,[2],1,SWAP,<<,pc,+=",
992  MEMBASE(0), LSHIFT2(0), MEMINDEX(0));
993  break;
994  default:
995  break;
996  }
997  // Update flags if required...TODO different instructions update different flags, but this should fix
998  // many errors
999  if (insn->detail->arm.update_flags) {
1000  switch (insn->id) {
1001  case ARM_INS_CMP:
1002  rz_strbuf_appendf(&op->esil, ",$z,zf,:=,31,$s,nf,:=,32,$b,!,cf,:=,31,$o,vf,:=");
1003  break;
1004  case ARM_INS_ADD:
1005  case ARM_INS_RSB:
1006  case ARM_INS_SUB:
1007  case ARM_INS_SBC:
1008  case ARM_INS_ADC:
1009  case ARM_INS_CMN:
1010  rz_strbuf_appendf(&op->esil, ",$z,zf,:=,31,$s,nf,:=,31,$c,cf,:=,31,$o,vf,:=");
1011  break;
1012  default:
1013  rz_strbuf_appendf(&op->esil, ",$z,zf,:=,31,$s,nf,:=");
1014  }
1015  }
1016 
1017  rz_strbuf_append(&op->esil, postfix);
1018 
1019  return 0;
1020 }
#define mask()
lzma_index ** i
Definition: index.h:629
#define ISREG(x)
#define ISMEMINDEXSUB(x)
#define HASMEMINDEX(x)
#define OPCOUNT()
#define MEMDISP(x)
#define ISSHIFTED(x)
#define IMM(x)
#define REGBASE(x)
#define SHIFTVALUE(x)
#define SHIFTTYPE(x)
#define ISIMM(x)
#define LSHIFT2(x)
#define ISPREINDEX32()
#define ISMEM(x)
#define ISPOSTINDEX32()
#define REGID(x)
#define ARG(x)
Definition: arm_esil32.c:172
#define MEMINDEX(x)
Definition: arm_esil32.c:12
RZ_IPI const char * rz_arm_cs_esil_prefix_cond(RzAnalysisOp *op, int cond_type)
Definition: arm_esil32.c:63
#define REGSIZE32(x)
Definition: arm_esil32.c:60
#define MATH32_NEG(opchar)
Definition: arm_esil32.c:175
#define MATH32AS(opchar)
Definition: arm_esil32.c:176
#define MATH32(opchar)
Definition: arm_esil32.c:174
#define REG(x)
Definition: arm_esil32.c:10
#define MEMBASE(x)
Definition: arm_esil32.c:11
static RZ_NULLABLE RzILOpBitVector * shift(RzILOpBitVector *val, RZ_NULLABLE RzILOpBool **carry_out, arm_shifter type, RZ_OWN RzILOpBitVector *dist)
Definition: arm_il32.c:190
@ ARM_INS_TBH
Definition: arm.h:865
@ ARM_INS_ADR
Definition: arm.h:448
@ ARM_INS_VLDMIA
Definition: arm.h:755
@ ARM_INS_SADD16
Definition: arm.h:564
@ ARM_INS_LDRSH
Definition: arm.h:517
@ ARM_INS_STR
Definition: arm.h:659
@ ARM_INS_VMOV
Definition: arm.h:481
@ ARM_INS_LDRT
Definition: arm.h:519
@ ARM_INS_TBB
Definition: arm.h:864
@ ARM_INS_BXJ
Definition: arm.h:461
@ ARM_INS_VLDMDB
Definition: arm.h:754
@ ARM_INS_STRH
Definition: arm.h:656
@ ARM_INS_ADC
Definition: arm.h:446
@ ARM_INS_ORN
Definition: arm.h:860
@ ARM_INS_BX
Definition: arm.h:460
@ ARM_INS_LDRB
Definition: arm.h:507
@ ARM_INS_SUB
Definition: arm.h:660
@ ARM_INS_ASR
Definition: arm.h:853
@ ARM_INS_LDRHT
Definition: arm.h:514
@ ARM_INS_MLS
Definition: arm.h:526
@ ARM_INS_RSB
Definition: arm.h:562
@ ARM_INS_UXTB
Definition: arm.h:704
@ ARM_INS_AND
Definition: arm.h:453
@ ARM_INS_STRB
Definition: arm.h:650
@ ARM_INS_LDRSBT
Definition: arm.h:516
@ ARM_INS_SSUB16
Definition: arm.h:632
@ ARM_INS_TST
Definition: arm.h:672
@ ARM_INS_SXTH
Definition: arm.h:669
@ ARM_INS_PUSH
Definition: arm.h:869
@ ARM_INS_BKPT
Definition: arm.h:457
@ ARM_INS_MOVT
Definition: arm.h:528
@ ARM_INS_MOV
Definition: arm.h:527
@ ARM_INS_SADD8
Definition: arm.h:565
@ ARM_INS_LDRSB
Definition: arm.h:515
@ ARM_INS_LDRBT
Definition: arm.h:506
@ ARM_INS_LDM
Definition: arm.h:504
@ ARM_INS_SMMLA
Definition: arm.h:608
@ ARM_INS_STMDB
Definition: arm.h:646
@ ARM_INS_BFI
Definition: arm.h:455
@ ARM_INS_MRS
Definition: arm.h:534
@ ARM_INS_VSTMDB
Definition: arm.h:837
@ ARM_INS_UBFX
Definition: arm.h:676
@ ARM_INS_LSL
Definition: arm.h:858
@ ARM_INS_LSR
Definition: arm.h:859
@ ARM_INS_STRBT
Definition: arm.h:649
@ ARM_INS_UMULL
Definition: arm.h:687
@ ARM_INS_BIC
Definition: arm.h:456
@ ARM_INS_STMIB
Definition: arm.h:648
@ ARM_INS_REVSH
Definition: arm.h:557
@ ARM_INS_UDF
Definition: arm.h:677
@ ARM_INS_MUL
Definition: arm.h:536
@ ARM_INS_ADDW
Definition: arm.h:852
@ ARM_INS_LDRH
Definition: arm.h:513
@ ARM_INS_CBZ
Definition: arm.h:867
@ ARM_INS_REV16
Definition: arm.h:556
@ ARM_INS_LDREXD
Definition: arm.h:511
@ ARM_INS_EOR
Definition: arm.h:479
@ ARM_INS_NOP
Definition: arm.h:872
@ ARM_INS_LDMDA
Definition: arm.h:502
@ ARM_INS_STMDA
Definition: arm.h:645
@ ARM_INS_LDREX
Definition: arm.h:509
@ ARM_INS_ADD
Definition: arm.h:447
@ ARM_INS_LDRSHT
Definition: arm.h:518
@ ARM_INS_POP
Definition: arm.h:868
@ ARM_INS_BLX
Definition: arm.h:459
@ ARM_INS_STM
Definition: arm.h:647
@ ARM_INS_LDMIB
Definition: arm.h:505
@ ARM_INS_CMN
Definition: arm.h:467
@ ARM_INS_SMMLAR
Definition: arm.h:609
@ ARM_INS_LDR
Definition: arm.h:520
@ ARM_INS_STRT
Definition: arm.h:658
@ ARM_INS_REV
Definition: arm.h:555
@ ARM_INS_STRD
Definition: arm.h:651
@ ARM_INS_SBC
Definition: arm.h:567
@ ARM_INS_CBNZ
Definition: arm.h:866
@ ARM_INS_LDREXH
Definition: arm.h:512
@ ARM_INS_MVN
Definition: arm.h:537
@ ARM_INS_SVC
Definition: arm.h:661
@ ARM_INS_BFC
Definition: arm.h:454
@ ARM_INS_B
Definition: arm.h:462
@ ARM_INS_MLA
Definition: arm.h:525
@ ARM_INS_SUBW
Definition: arm.h:863
@ ARM_INS_BL
Definition: arm.h:458
@ ARM_INS_LDMDB
Definition: arm.h:503
@ ARM_INS_CMP
Definition: arm.h:468
@ ARM_INS_LDRD
Definition: arm.h:508
@ ARM_INS_MOVW
Definition: arm.h:529
@ ARM_INS_LDREXB
Definition: arm.h:510
@ ARM_INS_VSTMIA
Definition: arm.h:838
@ ARM_INS_STRHT
Definition: arm.h:657
@ ARM_INS_SSUB8
Definition: arm.h:633
@ ARM_INS_ORR
Definition: arm.h:538
@ ARM_INS_CLZ
Definition: arm.h:466
@ ARM_INS_MSR
Definition: arm.h:535
@ ARM_INS_SXTB
Definition: arm.h:667
@ ARM_SFT_ASR
shift with immediate const
Definition: arm.h:20
@ ARM_SFT_ROR
shift with immediate const
Definition: arm.h:23
@ ARM_SFT_LSL
shift with immediate const
Definition: arm.h:21
@ ARM_SFT_LSR
shift with immediate const
Definition: arm.h:22
@ ARM_SFT_RRX
shift with immediate const
Definition: arm.h:24
@ ARM_REG_PC
Definition: arm.h:264
uint32_t ut32
voidpf uLong offset
Definition: ioapi.h:144
uint8_t ut8
Definition: lh5801.h:11
@ RZ_ANALYSIS_OP_FAMILY_THREAD
Definition: rz_analysis.h:318
static ut64 rz_num_bitmask(ut8 width)
Get the 64-bit value that has exactly its width lowest bits set to 1. e.g. rz_num_bitmask(2) == 0b11 ...
Definition: rz_num.h:134
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API const char * rz_strbuf_setf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
#define PFMT32u
Definition: rz_types.h:409
#define PFMT64u
Definition: rz_types.h:395
#define PFMT64x
Definition: rz_types.h:393
#define UT32_MAX
Definition: rz_types_base.h:99
#define UT16_MAX
int width
Definition: main.c:10
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int sp
Definition: z80asm.c:91
static int addr
Definition: z80asm.c:58

References addr, ARG, ARM_INS_ADC, ARM_INS_ADD, ARM_INS_ADDW, ARM_INS_ADR, ARM_INS_AND, ARM_INS_ASR, ARM_INS_B, ARM_INS_BFC, ARM_INS_BFI, ARM_INS_BIC, ARM_INS_BKPT, ARM_INS_BL, ARM_INS_BLX, ARM_INS_BX, ARM_INS_BXJ, ARM_INS_CBNZ, ARM_INS_CBZ, ARM_INS_CLZ, ARM_INS_CMN, ARM_INS_CMP, ARM_INS_EOR, ARM_INS_IT, ARM_INS_LDM, ARM_INS_LDMDA, ARM_INS_LDMDB, ARM_INS_LDMIB, ARM_INS_LDR, ARM_INS_LDRB, ARM_INS_LDRBT, ARM_INS_LDRD, ARM_INS_LDREX, ARM_INS_LDREXB, ARM_INS_LDREXD, ARM_INS_LDREXH, ARM_INS_LDRH, ARM_INS_LDRHT, ARM_INS_LDRSB, ARM_INS_LDRSBT, ARM_INS_LDRSH, ARM_INS_LDRSHT, ARM_INS_LDRT, ARM_INS_LSL, ARM_INS_LSR, ARM_INS_MLA, ARM_INS_MLS, ARM_INS_MOV, ARM_INS_MOVT, ARM_INS_MOVW, ARM_INS_MRS, ARM_INS_MSR, ARM_INS_MUL, ARM_INS_MVN, ARM_INS_NOP, ARM_INS_ORN, ARM_INS_ORR, ARM_INS_POP, ARM_INS_PUSH, ARM_INS_REV, ARM_INS_REV16, ARM_INS_REVSH, ARM_INS_RSB, ARM_INS_SADD16, ARM_INS_SADD8, ARM_INS_SBC, ARM_INS_SMMLA, ARM_INS_SMMLAR, ARM_INS_SSUB16, ARM_INS_SSUB8, ARM_INS_STM, ARM_INS_STMDA, ARM_INS_STMDB, ARM_INS_STMIB, ARM_INS_STR, ARM_INS_STRB, ARM_INS_STRBT, ARM_INS_STRD, ARM_INS_STRH, ARM_INS_STRHT, ARM_INS_STRT, ARM_INS_SUB, ARM_INS_SUBW, ARM_INS_SVC, ARM_INS_SXTB, ARM_INS_SXTH, ARM_INS_TBB, ARM_INS_TBH, ARM_INS_TST, ARM_INS_UBFX, ARM_INS_UDF, ARM_INS_UMULL, ARM_INS_UXTB, ARM_INS_VLDMDB, ARM_INS_VLDMIA, ARM_INS_VMOV, ARM_INS_VSTMDB, ARM_INS_VSTMIA, ARM_REG_PC, ARM_SFT_ASR, ARM_SFT_LSL, ARM_SFT_LSR, ARM_SFT_ROR, ARM_SFT_RRX, HASMEMINDEX, i, IMM, ISIMM, ISMEM, ISMEMINDEXSUB, ISPOSTINDEX32, ISPREINDEX32, ISREG, ISSHIFTED, lr, LSHIFT2, mask, MATH32, MATH32_NEG, MATH32AS, MEMBASE, MEMDISP, MEMINDEX, NULL, OPCOUNT, pc, PFMT32u, PFMT64u, PFMT64x, r0, r1, r4, r5, r6, r7, REG, REGBASE, REGID, REGSIZE32, RZ_ANALYSIS_OP_FAMILY_THREAD, rz_arm_cs_esil_prefix_cond(), rz_num_bitmask(), rz_strbuf_append(), rz_strbuf_appendf(), rz_strbuf_init(), rz_strbuf_set(), rz_strbuf_setf(), shift(), SHIFTTYPE, SHIFTVALUE, sp, cmd_descs_generate::str, UT16_MAX, UT32_MAX, ut64(), and width.

Referenced by analysis_op().

◆ rz_arm_cs_analysis_op_64_esil()

RZ_IPI int rz_arm_cs_analysis_op_64_esil ( RzAnalysis a,
RzAnalysisOp op,
ut64  addr,
const ut8 buf,
int  len,
csh handle,
cs_insn *  insn 
)

Definition at line 202 of file arm_esil64.c.

202  {
203  const char *postfix = NULL;
204 
205  rz_strbuf_init(&op->esil);
206  rz_strbuf_set(&op->esil, "");
207 
208  postfix = rz_arm_cs_esil_prefix_cond(op, insn->detail->arm64.cc);
209 
210  switch (insn->id) {
211  case ARM64_INS_REV:
212  // these REV* instructions were almost right, except in the cases like rev x0, x0
213  // where the use of |= caused copies of the value to be erroneously present
214  {
215  const char *r0 = REG64(0);
216  const char *r1 = REG64(1);
217  int size = REGSIZE64(1);
218 #if 0
219  rz_strbuf_setf (&op->esil,
220  "0,%s,=," // dst = 0
221  "%d," // initial counter = size
222  "DUP," // counter: size -> 0 (repeat here)
223  "DUP,1,SWAP,-,8,*," // counter to bits in source
224  "DUP,0xff,<<,%s,&,>>," // src byte moved to LSB
225  "SWAP,%d,-,8,*," // invert counter, calc dst bit
226  "SWAP,<<,%s,|=," // shift left to there and insert
227  "4,REPEAT", // goto 5th instruction
228  r0, size, r1, size, r0);
229 #endif
230  if (size == 8) {
231  rz_strbuf_setf(&op->esil,
232  "56,0xff,%s,&,<<,tmp,=,"
233  "48,0xff,8,%s,>>,&,<<,tmp,|=,"
234  "40,0xff,16,%s,>>,&,<<,tmp,|=,"
235  "32,0xff,24,%s,>>,&,<<,tmp,|=,"
236  "24,0xff,32,%s,>>,&,<<,tmp,|=,"
237  "16,0xff,40,%s,>>,&,<<,tmp,|=,"
238  "8,0xff,48,%s,>>,&,<<,tmp,|=,"
239  "0xff,56,%s,>>,&,tmp,|=,tmp,%s,=",
240  r1, r1, r1, r1,
241  r1, r1, r1, r1, r0);
242  } else {
243  rz_strbuf_setf(&op->esil,
244  "24,0xff,%s,&,<<,tmp,=,"
245  "16,0xff,8,%s,>>,&,<<,tmp,|=,"
246  "8,0xff,16,%s,>>,&,<<,tmp,|=,"
247  "0xff,24,%s,>>,&,tmp,|=,tmp,%s,=",
248  r1, r1, r1, r1, r0);
249  }
250  break;
251  }
252  case ARM64_INS_REV32: {
253  const char *r0 = REG64(0);
254  const char *r1 = REG64(1);
255  rz_strbuf_setf(&op->esil,
256  "24,0x000000ff000000ff,%s,&,<<,tmp,=,"
257  "16,0x000000ff000000ff,8,%s,>>,&,<<,tmp,|=,"
258  "8,0x000000ff000000ff,16,%s,>>,&,<<,tmp,|=,"
259  "0x000000ff000000ff,24,%s,>>,&,tmp,|=,tmp,%s,=",
260  r1, r1, r1, r1, r0);
261  break;
262  }
263  case ARM64_INS_REV16: {
264  const char *r0 = REG64(0);
265  const char *r1 = REG64(1);
266  rz_strbuf_setf(&op->esil,
267  "8,0xff00ff00ff00ff00,%s,&,>>,tmp,=,"
268  "8,0x00ff00ff00ff00ff,%s,&,<<,tmp,|=,tmp,%s,=",
269  r1, r1, r0);
270  break;
271  }
272  case ARM64_INS_ADR:
273  // TODO: must be 21bit signed
274  rz_strbuf_setf(&op->esil,
275  "%" PFMT64d ",%s,=", IMM64(1), REG64(0));
276  break;
277  case ARM64_INS_SMADDL: {
278  int size = REGSIZE64(1) * 8;
279  rz_strbuf_setf(&op->esil, "%d,%s,~,%d,%s,~,*,%s,+,%s,=",
280  size, REG64(2), size, REG64(1), REG64(3), REG64(0));
281  break;
282  }
283  case ARM64_INS_UMADDL:
284  case ARM64_INS_FMADD:
285  case ARM64_INS_MADD:
286  rz_strbuf_setf(&op->esil, "%s,%s,*,%s,+,%s,=",
287  REG64(2), REG64(1), REG64(3), REG64(0));
288  break;
289  case ARM64_INS_MSUB:
290  rz_strbuf_setf(&op->esil, "%s,%s,*,%s,-,%s,=",
291  REG64(2), REG64(1), REG64(3), REG64(0));
292  break;
293  case ARM64_INS_MNEG:
294  rz_strbuf_setf(&op->esil, "%s,%s,*,0,-,%s,=",
295  REG64(2), REG64(1), REG64(0));
296  break;
297  case ARM64_INS_ADD:
298  case ARM64_INS_ADC: // Add with carry.
299  // case ARM64_INS_ADCS: // Add with carry.
300  OPCALL("+");
301  break;
302  case ARM64_INS_SUB:
303  OPCALL("-");
304  break;
305  case ARM64_INS_SBC:
306  // TODO have to check this more, VEX does not work
307  rz_strbuf_setf(&op->esil, "%s,cf,+,%s,-,%s,=",
308  REG64(2), REG64(1), REG64(0));
309  break;
310  case ARM64_INS_SMULL: {
311  int size = REGSIZE64(1) * 8;
312  rz_strbuf_setf(&op->esil, "%d,%s,~,%d,%s,~,*,%s,=",
313  size, REG64(2), size, REG64(1), REG64(0));
314  break;
315  }
316  case ARM64_INS_MUL:
317  OPCALL("*");
318  break;
319  case ARM64_INS_AND:
320  OPCALL("&");
321  break;
322  case ARM64_INS_ORR:
323  OPCALL("|");
324  break;
325  case ARM64_INS_EOR:
326  OPCALL("^");
327  break;
328  case ARM64_INS_ORN:
329  OPCALL_NEG("|");
330  break;
331  case ARM64_INS_EON:
332  OPCALL_NEG("^");
333  break;
334  case ARM64_INS_LSR: {
335  const char *r0 = REG64(0);
336  const char *r1 = REG64(1);
337  const int size = REGSIZE64(0) * 8;
338 
339  if (ISREG64(2)) {
340  if (LSHIFT2_64(2) || EXT64(2)) {
341  SHIFTED_REG64_APPEND(&op->esil, 2);
342  rz_strbuf_appendf(&op->esil, ",%d,%%,%s,>>,%s,=", size, r1, r0);
343  } else {
344  const char *r2 = REG64(2);
345  rz_strbuf_setf(&op->esil, "%d,%s,%%,%s,>>,%s,=", size, r2, r1, r0);
346  }
347  } else {
348  ut64 i2 = IMM64(2);
349  rz_strbuf_setf(&op->esil, "%" PFMT64d ",%s,>>,%s,=", i2 % (ut64)size, r1, r0);
350  }
351  break;
352  }
353  case ARM64_INS_LSL: {
354  const char *r0 = REG64(0);
355  const char *r1 = REG64(1);
356  const int size = REGSIZE64(0) * 8;
357 
358  if (ISREG64(2)) {
359  if (LSHIFT2_64(2) || EXT64(2)) {
360  SHIFTED_REG64_APPEND(&op->esil, 2);
361  rz_strbuf_appendf(&op->esil, ",%d,%%,%s,<<,%s,=", size, r1, r0);
362  } else {
363  const char *r2 = REG64(2);
364  rz_strbuf_setf(&op->esil, "%d,%s,%%,%s,<<,%s,=", size, r2, r1, r0);
365  }
366  } else {
367  ut64 i2 = IMM64(2);
368  rz_strbuf_setf(&op->esil, "%" PFMT64d ",%s,<<,%s,=", i2 % (ut64)size, r1, r0);
369  }
370  break;
371  }
372  case ARM64_INS_ROR:
373  OPCALL(">>>");
374  break;
375  case ARM64_INS_NOP:
376  rz_strbuf_setf(&op->esil, ",");
377  break;
378  case ARM64_INS_FDIV:
379  break;
380  case ARM64_INS_SDIV: {
381  /* TODO: support WZR XZR to specify 32, 64bit op */
382  int size = REGSIZE64(1) * 8;
383  if (ISREG64(2)) {
384  rz_strbuf_setf(&op->esil, "%d,%s,~,%d,%s,~,~/,%s,=", size, REG64(2), size, REG64(1), REG64(0));
385  } else {
386  rz_strbuf_setf(&op->esil, "%d,%s,~,%d,%s,~,~/,%s,=", size, REG64(1), size, REG64(0), REG64(0));
387  }
388  break;
389  }
390  case ARM64_INS_UDIV:
391  /* TODO: support WZR XZR to specify 32, 64bit op */
392  if ISREG64 (2) {
393  rz_strbuf_setf(&op->esil, "%s,%s,/,%s,=", REG64(2), REG64(1), REG64(0));
394  } else {
395  rz_strbuf_setf(&op->esil, "%s,%s,/=", REG64(1), REG64(0));
396  }
397  break;
398  case ARM64_INS_BR:
399  rz_strbuf_setf(&op->esil, "%s,pc,=", REG64(0));
400  break;
401  case ARM64_INS_B:
402  /* capstone precompute resulting address, using PC + IMM */
403  rz_strbuf_appendf(&op->esil, "%" PFMT64d ",pc,=", IMM64(0));
404  break;
405  case ARM64_INS_BL:
406  rz_strbuf_setf(&op->esil, "pc,lr,=,%" PFMT64d ",pc,=", IMM64(0));
407  break;
408  case ARM64_INS_BLR:
409  rz_strbuf_setf(&op->esil, "pc,lr,=,%s,pc,=", REG64(0));
410  break;
411  case ARM64_INS_CLZ:;
412  int size = 8 * REGSIZE64(0);
413 
414  // expression is much more concise with GOTO, but GOTOs should be minimized
415  // rz_strbuf_setf (&op->esil, "%s,%s,=,0,DUP,%d,1,<<,%s,&,%d,>,&,?{,%s,=,}{,1,%s,<<=,1,+,4,GOTO,}",
416  // REG64 (1), REG64 (0), size*8 - 1, REG64 (0), REG64 (0), REG64 (0));
417 
418  /*
419  from https://en.wikipedia.org/wiki/Find_first_set modified for up to size 64
420  function clz3 (x)
421  if x = 0 return 32
422  n ← 0
423  if (x & 0xFFFF0000) = 0: n ← n + 16, x ← x << 16
424  if (x & 0xFF000000) = 0: n ← n + 8, x ← x << 8
425  if (x & 0xF0000000) = 0: n ← n + 4, x ← x << 4
426  if (x & 0xC0000000) = 0: n ← n + 2, x ← x << 2
427  if (x & 0x80000000) = 0: n ← n + 1
428  return n
429  */
430 
431  const char *r0 = REG64(0);
432  const char *r1 = REG64(1);
433 
434  if (size == 32) {
435  rz_strbuf_setf(&op->esil,
436  "%s,tmp,=,0,"
437  "tmp,0xffff0000,&,!,?{,16,tmp,<<=,16,+,},"
438  "tmp,0xff000000,&,!,?{,8,tmp,<<=,8,+,},"
439  "tmp,0xf0000000,&,!,?{,4,tmp,<<=,4,+,},"
440  "tmp,0xc0000000,&,!,?{,2,tmp,<<=,2,+,},"
441  "tmp,0x80000000,&,!,?{,1,+,},"
442  "%s,!,?{,32,%s,=,}{,%s,=,}",
443  r1, r1, r0, r0);
444  } else {
445  rz_strbuf_setf(&op->esil,
446  "%s,tmp,=,0,"
447  "tmp,0xffffffff00000000,&,!,?{,32,tmp,<<=,32,+,},"
448  "tmp,0xffff000000000000,&,!,?{,16,tmp,<<=,16,+,},"
449  "tmp,0xff00000000000000,&,!,?{,8,tmp,<<=,8,+,},"
450  "tmp,0xf000000000000000,&,!,?{,4,tmp,<<=,4,+,},"
451  "tmp,0xc000000000000000,&,!,?{,2,tmp,<<=,2,+,},"
452  "tmp,0x8000000000000000,&,!,?{,1,+,},"
453  "%s,!,?{,64,%s,=,}{,%s,=,}",
454  r1, r1, r0, r0);
455  }
456 
457  break;
458  case ARM64_INS_LDRH:
459  case ARM64_INS_LDUR:
460  case ARM64_INS_LDURB:
461  case ARM64_INS_LDURH:
462  case ARM64_INS_LDR:
463  // case ARM64_INS_LDRSB:
464  // case ARM64_INS_LDRSH:
465  case ARM64_INS_LDRB:
466  // case ARM64_INS_LDRSW:
467  // case ARM64_INS_LDURSW:
468  case ARM64_INS_LDXR:
469  case ARM64_INS_LDXRB:
470  case ARM64_INS_LDXRH:
471  case ARM64_INS_LDAXR:
472  case ARM64_INS_LDAXRB:
473  case ARM64_INS_LDAXRH:
474  case ARM64_INS_LDAR:
475  case ARM64_INS_LDARB:
476  case ARM64_INS_LDARH: {
477  int size = REGSIZE64(0);
478  switch (insn->id) {
479  case ARM64_INS_LDRB:
480  case ARM64_INS_LDARB:
481  case ARM64_INS_LDAXRB:
482  case ARM64_INS_LDXRB:
483  case ARM64_INS_LDURB:
484  size = 1;
485  break;
486  case ARM64_INS_LDRH:
487  case ARM64_INS_LDARH:
488  case ARM64_INS_LDXRH:
489  case ARM64_INS_LDAXRH:
490  case ARM64_INS_LDURH:
491  size = 2;
492  break;
493  case ARM64_INS_LDRSW:
494  case ARM64_INS_LDURSW:
495  size = 4;
496  break;
497  default:
498  break;
499  }
500 
501  if (ISMEM64(1)) {
502  if (HASMEMINDEX64(1)) {
503  if (LSHIFT2_64(1) || EXT64(1)) {
504  SHIFTED_REG64_APPEND(&op->esil, 1);
505  rz_strbuf_appendf(&op->esil, ",%s,+,[%d],%s,=", MEMBASE64(1), size, REG64(0));
506  } else {
507  rz_strbuf_appendf(&op->esil, "%s,%s,+,[%d],%s,=",
508  MEMBASE64(1), MEMINDEX64(1), size, REG64(0));
509  }
510  } else {
511  // I really don't like the DUP / tmp approach but its better than doubling the calculation
512  if (LSHIFT2_64(1)) {
513  rz_strbuf_appendf(&op->esil, "%s,%d,%" PFMT64d ",%s,+",
515  } else if ((int)MEMDISP64(1) < 0) {
516  rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%s,-",
517  -(st64)MEMDISP64(1), MEMBASE64(1));
518  } else {
519  rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%s,+",
520  MEMDISP64(1), MEMBASE64(1));
521  }
522 
523  rz_strbuf_append(&op->esil, ",DUP,tmp,=");
524 
525  // I assume the DUPs here previously were to handle preindexing
526  // but it was never finished?
527  if (ISPREINDEX64()) {
528  rz_strbuf_appendf(&op->esil, ",tmp,%s,=", REG64(1));
529  }
530 
531  rz_strbuf_appendf(&op->esil, ",[%d],%s,=", size, REG64(0));
532 
533  if (ISPOSTINDEX64()) {
534  if (ISREG64(2)) { // not sure if register valued post indexing exists?
535  rz_strbuf_appendf(&op->esil, ",tmp,%s,+,%s,=", REG64(2), REG64(1));
536  } else {
537  rz_strbuf_appendf(&op->esil, ",tmp,%" PFMT64d ",+,%s,=", IMM64(2), REG64(1));
538  }
539  }
540  }
541  op->refptr = 4;
542  } else {
543  if (ISREG64(1)) {
544  if (OPCOUNT64() == 2) {
545  rz_strbuf_setf(&op->esil, "%s,[%d],%s,=",
546  REG64(1), size, REG64(0));
547  } else if (OPCOUNT64() == 3) {
548  /*
549  This seems like a capstone bug:
550  instructions like
551  ldr x16, [x13, x9]
552  ldrb w2, [x19, x23]
553  are not detected as ARM64_OP_MEM type and
554  fall in this case instead.
555  */
556  if (ISREG64(2)) {
557  rz_strbuf_setf(&op->esil, "%s,%s,+,[%d],%s,=",
558  REG64(1), REG64(2), size, REG64(0));
559  }
560  }
561  } else {
562  rz_strbuf_setf(&op->esil, "%" PFMT64d ",[%d],%s,=",
563  IMM64(1), size, REG64(0));
564  }
565  }
566  break;
567  }
568  case ARM64_INS_LDRSB:
569  case ARM64_INS_LDRSH:
570  case ARM64_INS_LDRSW:
571  case ARM64_INS_LDURSB:
572  case ARM64_INS_LDURSH:
573  case ARM64_INS_LDURSW: {
574  // handle the sign extended instrs here
575  int size = REGSIZE64(0);
576  switch (insn->id) {
577  case ARM64_INS_LDRSB:
578  case ARM64_INS_LDURSB:
579  size = 1;
580  break;
581  case ARM64_INS_LDRSH:
582  case ARM64_INS_LDURSH:
583  size = 2;
584  break;
585  case ARM64_INS_LDRSW:
586  case ARM64_INS_LDURSW:
587  size = 4;
588  break;
589  default:
590  break;
591  }
592 
593  if (ISMEM64(1)) {
594  if (HASMEMINDEX64(1)) {
595  if (LSHIFT2_64(1) || EXT64(1)) {
596  rz_strbuf_appendf(&op->esil, "%d,%s,", size * 8, MEMBASE64(1));
597  SHIFTED_REG64_APPEND(&op->esil, 1);
598  rz_strbuf_appendf(&op->esil, ",+,[%d],~,%s,=", size, REG64(0));
599  } else {
600  rz_strbuf_appendf(&op->esil, "%d,%s,%s,+,[%d],~,%s,=",
601  size * 8, MEMBASE64(1), MEMINDEX64(1), size, REG64(0));
602  }
603  } else {
604  if (LSHIFT2_64(1)) {
605  rz_strbuf_appendf(&op->esil, "%d,%s,%d,%" PFMT64d ",%s",
606  size * 8, MEMBASE64(1), LSHIFT2_64(1), MEMDISP64(1), DECODE_SHIFT64(1));
607  } else if ((int)MEMDISP64(1) < 0) {
608  rz_strbuf_appendf(&op->esil, "%d,%" PFMT64d ",%s,-",
609  size * 8, -(st64)MEMDISP64(1), MEMBASE64(1));
610  } else {
611  rz_strbuf_appendf(&op->esil, "%d,%" PFMT64d ",%s,+",
612  size * 8, MEMDISP64(1), MEMBASE64(1));
613  }
614 
615  rz_strbuf_append(&op->esil, ",DUP,tmp,=");
616 
617  // I assume the DUPs here previously were to handle preindexing
618  // but it was never finished?
619  if (ISPREINDEX64()) {
620  rz_strbuf_appendf(&op->esil, ",tmp,%s,=", REG64(1));
621  }
622 
623  rz_strbuf_appendf(&op->esil, ",[%d],~,%s,=", size, REG64(0));
624 
625  if (ISPOSTINDEX64()) {
626  if (ISREG64(2)) { // not sure if register valued post indexing exists?
627  rz_strbuf_appendf(&op->esil, ",tmp,%s,+,%s,=", REG64(2), REG64(1));
628  } else {
629  rz_strbuf_appendf(&op->esil, ",tmp,%" PFMT64d ",+,%s,=", IMM64(2), REG64(1));
630  }
631  }
632  }
633  op->refptr = 4;
634  } else {
635  if (ISREG64(1)) {
636  if (OPCOUNT64() == 2) {
637  rz_strbuf_setf(&op->esil, "%d,%s,[%d],~,%s,=",
638  size * 8, REG64(1), size, REG64(0));
639  } else if (OPCOUNT64() == 3) {
640  /*
641  This seems like a capstone bug:
642  instructions like
643  ldr x16, [x13, x9]
644  ldrb w2, [x19, x23]
645  are not detected as ARM64_OP_MEM type and
646  fall in this case instead.
647  */
648  if (ISREG64(2)) {
649  rz_strbuf_setf(&op->esil, "%d,%s,%s,+,[%d],~,%s,=",
650  size * 8, REG64(1), REG64(2), size, REG64(0));
651  }
652  }
653  } else {
654  rz_strbuf_setf(&op->esil, "%d,%" PFMT64d ",[%d],~,%s,=",
655  size * 8, IMM64(1), size, REG64(0));
656  }
657  }
658  break;
659  }
660  case ARM64_INS_FCMP:
661  case ARM64_INS_CCMP:
662  case ARM64_INS_CCMN:
663  case ARM64_INS_TST: // cmp w8, 0xd
664  case ARM64_INS_CMP: // cmp w8, 0xd
665  case ARM64_INS_CMN: // cmp w8, 0xd
666  {
667  // update esil, cpu flags
668  int bits = arm64_reg_width(REGID64(0));
669  if (ISIMM64(1)) {
670  rz_strbuf_setf(&op->esil, "%" PFMT64d ",%s,==,$z,zf,:=,%d,$s,nf,:=,%d,$b,!,cf,:=,%d,$o,vf,:=", IMM64(1) << LSHIFT2_64(1), REG64(0), bits - 1, bits, bits - 1);
671  } else {
672  // cmp w10, w11
673  SHIFTED_REG64_APPEND(&op->esil, 1);
674  rz_strbuf_appendf(&op->esil, ",%s,==,$z,zf,:=,%d,$s,nf,:=,%d,$b,!,cf,:=,%d,$o,vf,:=", REG64(0), bits - 1, bits, bits - 1);
675  }
676  break;
677  }
678  case ARM64_INS_FCSEL:
679  case ARM64_INS_CSEL: // csel Wd, Wn, Wm --> Wd := (cond) ? Wn : Wm
680  rz_strbuf_appendf(&op->esil, "%s,}{,%s,},%s,=", REG64(1), REG64(2), REG64(0));
681  postfix = "";
682  break;
683  case ARM64_INS_CSET: // cset Wd --> Wd := (cond) ? 1 : 0
684  rz_strbuf_appendf(&op->esil, "1,}{,0,},%s,=", REG64(0));
685  postfix = "";
686  break;
687  case ARM64_INS_CINC: // cinc Wd, Wn --> Wd := (cond) ? (Wn+1) : Wn
688  rz_strbuf_appendf(&op->esil, "1,%s,+,}{,%s,},%s,=", REG64(1), REG64(1), REG64(0));
689  postfix = "";
690  break;
691  case ARM64_INS_CSINC: // csinc Wd, Wn, Wm --> Wd := (cond) ? Wn : (Wm+1)
692  rz_strbuf_appendf(&op->esil, "%s,}{,1,%s,+,},%s,=", REG64(1), REG64(2), REG64(0));
693  postfix = "";
694  break;
695  case ARM64_INS_STXRB:
696  case ARM64_INS_STXRH:
697  case ARM64_INS_STXR: {
698  int size = REGSIZE64(1);
699  if (insn->id == ARM64_INS_STXRB) {
700  size = 1;
701  } else if (insn->id == ARM64_INS_STXRH) {
702  size = 2;
703  }
704  rz_strbuf_setf(&op->esil, "0,%s,=,%s,%s,%" PFMT64d ",+,=[%d]",
705  REG64(0), REG64(1), MEMBASE64(1), MEMDISP64(1), size);
706  break;
707  }
708  case ARM64_INS_STRB:
709  case ARM64_INS_STRH:
710  case ARM64_INS_STUR:
711  case ARM64_INS_STURB:
712  case ARM64_INS_STURH:
713  case ARM64_INS_STR: // str x6, [x6,0xf90]
714  {
715  int size = REGSIZE64(0);
716  if (insn->id == ARM64_INS_STRB || insn->id == ARM64_INS_STURB) {
717  size = 1;
718  } else if (insn->id == ARM64_INS_STRH || insn->id == ARM64_INS_STURH) {
719  size = 2;
720  }
721  if (ISMEM64(1)) {
722  if (HASMEMINDEX64(1)) {
723  if (LSHIFT2_64(1) || EXT64(1)) {
724  rz_strbuf_appendf(&op->esil, "%s,%s,", REG64(0), MEMBASE64(1));
725  SHIFTED_REG64_APPEND(&op->esil, 1);
726  rz_strbuf_appendf(&op->esil, ",+,=[%d]", size);
727  } else {
728  rz_strbuf_appendf(&op->esil, "%s,%s,%s,+,=[%d]",
729  REG64(0), MEMBASE64(1), MEMINDEX64(1), size);
730  }
731  } else {
732  if (LSHIFT2_64(1)) {
733  rz_strbuf_appendf(&op->esil, "%s,%s,%d,%" PFMT64d ",%s,+",
734  REG64(0), MEMBASE64(1), LSHIFT2_64(1), MEMDISP64(1), DECODE_SHIFT64(1));
735  } else if ((int)MEMDISP64(1) < 0) {
736  rz_strbuf_appendf(&op->esil, "%s,%" PFMT64d ",%s,-",
737  REG64(0), -(st64)MEMDISP64(1), MEMBASE64(1));
738  } else {
739  rz_strbuf_appendf(&op->esil, "%s,%" PFMT64d ",%s,+",
740  REG64(0), MEMDISP64(1), MEMBASE64(1));
741  }
742 
743  rz_strbuf_append(&op->esil, ",DUP,tmp,=");
744 
745  // I assume the DUPs here previously were to handle preindexing
746  // but it was never finished?
747  if (ISPREINDEX64()) {
748  rz_strbuf_appendf(&op->esil, ",tmp,%s,=", REG64(1));
749  }
750 
751  rz_strbuf_appendf(&op->esil, ",=[%d]", size);
752 
753  if (ISPOSTINDEX64()) {
754  if (ISREG64(2)) { // not sure if register valued post indexing exists?
755  rz_strbuf_appendf(&op->esil, ",tmp,%s,+,%s,=", REG64(2), REG64(1));
756  } else {
757  rz_strbuf_appendf(&op->esil, ",tmp,%" PFMT64d ",+,%s,=", IMM64(2), REG64(1));
758  }
759  }
760  }
761  op->refptr = 4;
762  } else {
763  if (ISREG64(1)) {
764  if (OPCOUNT64() == 2) {
765  rz_strbuf_setf(&op->esil, "%s,%s,=[%d]",
766  REG64(0), REG64(1), size);
767  } else if (OPCOUNT64() == 3) {
768  /*
769  This seems like a capstone bug:
770  instructions like
771  ldr x16, [x13, x9]
772  ldrb w2, [x19, x23]
773  are not detected as ARM64_OP_MEM type and
774  fall in this case instead.
775  */
776  if (ISREG64(2)) {
777  rz_strbuf_setf(&op->esil, "%s,%s,%s,+,=[%d]",
778  REG64(0), REG64(1), REG64(2), size);
779  }
780  }
781  } else {
782  rz_strbuf_setf(&op->esil, "%s,%" PFMT64d ",=[%d]",
783  REG64(0), IMM64(1), size);
784  }
785  }
786  break;
787  }
788  case ARM64_INS_BIC:
789  if (OPCOUNT64() == 2) {
790  if (REGSIZE64(0) == 4) {
791  rz_strbuf_appendf(&op->esil, "%s,0xffffffff,^,%s,&=", REG64(1), REG64(0));
792  } else {
793  rz_strbuf_appendf(&op->esil, "%s,0xffffffffffffffff,^,%s,&=", REG64(1), REG64(0));
794  }
795  } else {
796  if (REGSIZE64(0) == 4) {
797  rz_strbuf_appendf(&op->esil, "%s,0xffffffff,^,%s,&,%s,=", REG64(2), REG64(1), REG64(0));
798  } else {
799  rz_strbuf_appendf(&op->esil, "%s,0xffffffffffffffff,^,%s,&,%s,=", REG64(2), REG64(1), REG64(0));
800  }
801  }
802  break;
803  case ARM64_INS_CBZ:
804  rz_strbuf_setf(&op->esil, "%s,!,?{,%" PFMT64d ",pc,=,}",
805  REG64(0), IMM64(1));
806  break;
807  case ARM64_INS_CBNZ:
808  rz_strbuf_setf(&op->esil, "%s,?{,%" PFMT64d ",pc,=,}",
809  REG64(0), IMM64(1));
810  break;
811  case ARM64_INS_TBZ:
812  // tbnz x0, 4, label
813  // if ((1<<4) & x0) goto label;
814  rz_strbuf_setf(&op->esil, "%" PFMT64d ",1,<<,%s,&,!,?{,%" PFMT64d ",pc,=,}",
815  IMM64(1), REG64(0), IMM64(2));
816  break;
817  case ARM64_INS_TBNZ:
818  // tbnz x0, 4, label
819  // if ((1<<4) & x0) goto label;
820  rz_strbuf_setf(&op->esil, "%" PFMT64d ",1,<<,%s,&,?{,%" PFMT64d ",pc,=,}",
821  IMM64(1), REG64(0), IMM64(2));
822  break;
823  case ARM64_INS_STNP:
824  case ARM64_INS_STP: // stp x6, x7, [x6,0xf90]
825  {
826  int disp = (int)MEMDISP64(2);
827  char sign = disp >= 0 ? '+' : '-';
828  ut64 abs = disp >= 0 ? MEMDISP64(2) : -MEMDISP64(2);
829  int size = REGSIZE64(0);
830  // Pre-index case
831  if (ISPREINDEX64()) {
832  // "stp x2, x3, [x8, 0x20]!
833  // "32,x8,+=,x2,x8,=[8],x3,x8,8,+,=[8]",
834  rz_strbuf_setf(&op->esil,
835  "%" PFMT64d ",%s,%c=,%s,%s,=[%d],%s,%s,%d,+,=[%d]",
836  abs, MEMBASE64(2), sign,
837  REG64(0), MEMBASE64(2), size,
838  REG64(1), MEMBASE64(2), size, size);
839  // Post-index case
840  } else if (ISPOSTINDEX64()) {
841  int val = IMM64(3);
842  sign = val >= 0 ? '+' : '-';
843  abs = val >= 0 ? val : -val;
844  // "stp x4, x5, [x8], 0x10"
845  // "x4,x8,=[],x5,x8,8,+,=[],16,x8,+="
846  rz_strbuf_setf(&op->esil,
847  "%s,%s,=[%d],%s,%s,%d,+,=[%d],%" PFMT64d ",%s,%c=",
848  REG64(0), MEMBASE64(2), size,
849  REG64(1), MEMBASE64(2), size, size,
850  abs, MEMBASE64(2), sign);
851  // Everything else
852  } else {
853  rz_strbuf_setf(&op->esil,
854  "%s,%s,%" PFMT64d ",%c,=[%d],"
855  "%s,%s,%" PFMT64d ",%c,%d,+,=[%d]",
856  REG64(0), MEMBASE64(2), abs, sign, size,
857  REG64(1), MEMBASE64(2), abs, sign, size, size);
858  }
859  } break;
860  case ARM64_INS_LDP: // ldp x29, x30, [sp], 0x10
861  {
862  int disp = (int)MEMDISP64(2);
863  char sign = disp >= 0 ? '+' : '-';
864  ut64 abs = disp >= 0 ? MEMDISP64(2) : -MEMDISP64(2);
865  int size = REGSIZE64(0);
866  // Pre-index case
867  // x2,x8,32,+,=[8],x3,x8,32,+,8,+,=[8]
868  if (ISPREINDEX64()) {
869  // "ldp x0, x1, [x8, -0x10]!"
870  // 16,x8,-=,x8,[8],x0,=,x8,8,+,[8],x1,=
871  rz_strbuf_setf(&op->esil,
872  "%" PFMT64d ",%s,%c=,"
873  "%s,[%d],%s,=,"
874  "%d,%s,+,[%d],%s,=",
875  abs, MEMBASE64(2), sign,
876  MEMBASE64(2), size, REG64(0),
877  size, MEMBASE64(2), size, REG64(1));
878  // Post-index case
879  } else if (ISPOSTINDEX64()) {
880  int val = IMM64(3);
881  sign = val >= 0 ? '+' : '-';
882  abs = val >= 0 ? val : -val;
883  // ldp x4, x5, [x8], -0x10
884  // x8,[8],x4,=,x8,8,+,[8],x5,=,16,x8,+=
885  rz_strbuf_setf(&op->esil,
886  "%s,[%d],%s,=,"
887  "%s,%d,+,[%d],%s,=,"
888  "%" PFMT64d ",%s,%c=",
889  MEMBASE64(2), size, REG64(0),
890  MEMBASE64(2), size, size, REG64(1),
891  abs, MEMBASE64(2), sign);
892  } else {
893  rz_strbuf_setf(&op->esil,
894  "%" PFMT64d ",%s,%c,[%d],%s,=,"
895  "%d,%" PFMT64d ",%s,%c,+,[%d],%s,=",
896  abs, MEMBASE64(2), sign, size, REG64(0),
897  size, abs, MEMBASE64(2), sign, size, REG64(1));
898  }
899  } break;
900  case ARM64_INS_ADRP:
901  rz_strbuf_setf(&op->esil, "%" PFMT64d ",%s,=",
902  IMM64(1), REG64(0));
903  break;
904  case ARM64_INS_MOV:
905  if (ISREG64(1)) {
906  rz_strbuf_setf(&op->esil, "%s,%s,=", REG64(1), REG64(0));
907  } else {
908  rz_strbuf_setf(&op->esil, "%" PFMT64d ",%s,=", IMM64(1), REG64(0));
909  }
910  break;
911  case ARM64_INS_EXTR:
912  // from VEX
913  /*
914  01 | t0 = GET:I64(x4)
915  02 | t1 = GET:I64(x0)
916  03 | t4 = Shr64(t1,0x20)
917  04 | t5 = Shl64(t0,0x20)
918  05 | t3 = Or64(t5,t4)
919  06 | PUT(x4) = t3
920  */
921  rz_strbuf_setf(&op->esil, "%" PFMT64d ",%s,>>,%" PFMT64d ",%s,<<,|,%s,=",
922  IMM64(3), REG64(2), IMM64(3), REG64(1), REG64(0));
923  break;
924  case ARM64_INS_RBIT:
925  // this expression reverses the bits. it does. do not scroll right.
926  // Derived from VEX
927  rz_strbuf_setf(&op->esil, "0xffffffff00000000,0x20,0xffff0000ffff0000,0x10,0xff00ff00ff00ff00,0x8,0xf0f0f0f0f0f0f0f0,0x4,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,<<,&,0x4,0xf0f0f0f0f0f0f0f0,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,&,>>,|,<<,&,0x8,0xff00ff00ff00ff00,0xf0f0f0f0f0f0f0f0,0x4,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,<<,&,0x4,0xf0f0f0f0f0f0f0f0,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,&,>>,|,&,>>,|,<<,&,0x10,0xffff0000ffff0000,0xff00ff00ff00ff00,0x8,0xf0f0f0f0f0f0f0f0,0x4,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,<<,&,0x4,0xf0f0f0f0f0f0f0f0,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,&,>>,|,<<,&,0x8,0xff00ff00ff00ff00,0xf0f0f0f0f0f0f0f0,0x4,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,<<,&,0x4,0xf0f0f0f0f0f0f0f0,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,&,>>,|,&,>>,|,&,>>,|,<<,&,0x20,0xffffffff00000000,0xffff0000ffff0000,0x10,0xff00ff00ff00ff00,0x8,0xf0f0f0f0f0f0f0f0,0x4,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,<<,&,0x4,0xf0f0f0f0f0f0f0f0,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,&,>>,|,<<,&,0x8,0xff00ff00ff00ff00,0xf0f0f0f0f0f0f0f0,0x4,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,<<,&,0x4,0xf0f0f0f0f0f0f0f0,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,&,>>,|,&,>>,|,<<,&,0x10,0xffff0000ffff0000,0xff00ff00ff00ff00,0x8,0xf0f0f0f0f0f0f0f0,0x4,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,<<,&,0x4,0xf0f0f0f0f0f0f0f0,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,&,>>,|,<<,&,0x8,0xff00ff00ff00ff00,0xf0f0f0f0f0f0f0f0,0x4,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,<<,&,0x4,0xf0f0f0f0f0f0f0f0,0xcccccccccccccccc,0x2,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,<<,&,0x2,0xcccccccccccccccc,0xaaaaaaaaaaaaaaaa,0x1,%1$s,<<,&,0x1,0xaaaaaaaaaaaaaaaa,%1$s,&,>>,|,&,>>,|,&,>>,|,&,>>,|,&,>>,|,&,>>,|,%2$s,=",
928  REG64(1), REG64(0));
929  break;
930  case ARM64_INS_MVN:
931  case ARM64_INS_MOVN:
932  if (ISREG64(1)) {
933  rz_strbuf_setf(&op->esil, "%d,%s,-1,^,<<,%s,=", LSHIFT2_64(1), REG64(1), REG64(0));
934  } else {
935  rz_strbuf_setf(&op->esil, "%d,%" PFMT64d ",<<,-1,^,%s,=", LSHIFT2_64(1), IMM64(1), REG64(0));
936  }
937  break;
938  case ARM64_INS_MOVK: // movk w8, 0x1290
939  {
940  ut64 shift = LSHIFT2_64(1);
941  if (shift < 0) {
942  shift = 0;
943  } else if (shift > 48) {
944  shift = 48;
945  }
946  ut64 shifted_imm = IMM64(1) << shift;
947  ut64 mask = ~(0xffffLL << shift);
948 
949  rz_strbuf_setf(&op->esil, "0x%" PFMT64x ",%s,&,%" PFMT64u ",|,%s,=",
950  mask,
951  REG64(0),
952  shifted_imm,
953  REG64(0));
954 
955  break;
956  }
957  case ARM64_INS_MOVZ:
958  rz_strbuf_setf(&op->esil, "%" PFMT64u ",%s,=",
959  IMM64(1) << LSHIFT2_64(1),
960  REG64(0));
961  break;
962  /* ASR, SXTB, SXTH and SXTW are alias for SBFM */
963  case ARM64_INS_ASR: {
964  // OPCALL(">>>>");
965  const char *r0 = REG64(0);
966  const char *r1 = REG64(1);
967  const int size = REGSIZE64(0) * 8;
968 
969  if (ISREG64(2)) {
970  if (LSHIFT2_64(2)) {
971  SHIFTED_REG64_APPEND(&op->esil, 2);
972  rz_strbuf_appendf(&op->esil, ",%d,%%,%s,>>>>,%s,=", size, r1, r0);
973  } else {
974  const char *r2 = REG64(2);
975  rz_strbuf_setf(&op->esil, "%d,%s,%%,%s,>>>>,%s,=", size, r2, r1, r0);
976  }
977  } else {
978  ut64 i2 = IMM64(2);
979  rz_strbuf_setf(&op->esil, "%" PFMT64d ",%s,>>>>,%s,=", i2 % (ut64)size, r1, r0);
980  }
981  break;
982  }
983  case ARM64_INS_SXTB:
984  if (arm64_reg_width(REGID64(0)) == 32) {
985  rz_strbuf_setf(&op->esil, "0xffffffff,8,0xff,%s,&,~,&,%s,=",
986  REG64(1), REG64(0));
987  } else {
988  rz_strbuf_setf(&op->esil, "8,0xff,%s,&,~,%s,=",
989  REG64(1), REG64(0));
990  }
991  break;
992  case ARM64_INS_SXTH: /* halfword */
993  if (arm64_reg_width(REGID64(0)) == 32) {
994  rz_strbuf_setf(&op->esil, "0xffffffff,16,0xffff,%s,&,~,&,%s,=",
995  REG64(1), REG64(0));
996  } else {
997  rz_strbuf_setf(&op->esil, "16,0xffff,%s,&,~,%s,=",
998  REG64(1), REG64(0));
999  }
1000  break;
1001  case ARM64_INS_SXTW: /* word */
1002  rz_strbuf_setf(&op->esil, "32,0xffffffff,%s,&,~,%s,=",
1003  REG64(1), REG64(0));
1004  break;
1005  case ARM64_INS_UXTB:
1006  rz_strbuf_setf(&op->esil, "%s,0xff,&,%s,=", REG64(1), REG64(0));
1007  break;
1008  case ARM64_INS_UMULL:
1009  rz_strbuf_setf(&op->esil, "%s,%s,*,%s,=", REG64(1), REG64(2), REG64(0));
1010  break;
1011  case ARM64_INS_UXTH:
1012  rz_strbuf_setf(&op->esil, "%s,0xffff,&,%s,=", REG64(1), REG64(0));
1013  break;
1014  case ARM64_INS_RET:
1015  rz_strbuf_setf(&op->esil, "lr,pc,=");
1016  break;
1017  case ARM64_INS_ERET:
1018  rz_strbuf_setf(&op->esil, "lr,pc,=");
1019  break;
1020  case ARM64_INS_BFI: // bfi w8, w8, 2, 1
1021  case ARM64_INS_BFXIL: {
1022  if (OPCOUNT64() >= 3 && ISIMM64(3) && IMM64(3) > 0) {
1023  ut64 mask = rz_num_bitmask((ut8)IMM64(3));
1024  ut64 shift = IMM64(2);
1025  ut64 notmask = ~(mask << shift);
1026  // notmask,dst,&,lsb,mask,src,&,<<,|,dst,=
1027  rz_strbuf_setf(&op->esil, "%" PFMT64u ",%s,&,%" PFMT64u ",%" PFMT64u ",%s,&,<<,|,%s,=",
1028  notmask, REG64(0), shift, mask, REG64(1), REG64(0));
1029  }
1030  break;
1031  }
1032  case ARM64_INS_SBFIZ:
1033  if (IMM64(3) > 0 && IMM64(3) <= 64 - IMM64(2)) {
1034  rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%" PFMT64d ",%s,%" PFMT64u ",&,~,<<,%s,=",
1035  IMM64(2), IMM64(3), REG64(1), rz_num_bitmask((ut8)IMM64(3)), REG64(0));
1036  }
1037  break;
1038  case ARM64_INS_UBFIZ:
1039  if (IMM64(3) > 0 && IMM64(3) <= 64 - IMM64(2)) {
1040  rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%s,%" PFMT64u ",&,<<,%s,=",
1041  IMM64(2), REG64(1), rz_num_bitmask((ut8)IMM64(3)), REG64(0));
1042  }
1043  break;
1044  case ARM64_INS_SBFX:
1045  if (IMM64(3) > 0 && IMM64(3) <= 64 - IMM64(2)) {
1046  rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%" PFMT64d ",%s,%" PFMT64d ",%" PFMT64u ",<<,&,>>,~,%s,=",
1047  IMM64(3), IMM64(2), REG64(1), IMM64(2), rz_num_bitmask((ut8)IMM64(3)), REG64(0));
1048  }
1049  break;
1050  case ARM64_INS_UBFX:
1051  if (IMM64(3) > 0 && IMM64(3) <= 64 - IMM64(2)) {
1052  rz_strbuf_appendf(&op->esil, "%" PFMT64d ",%s,%" PFMT64d ",%" PFMT64u ",<<,&,>>,%s,=",
1053  IMM64(2), REG64(1), IMM64(2), rz_num_bitmask((ut8)IMM64(3)), REG64(0));
1054  }
1055  break;
1056  case ARM64_INS_NEG:
1057 #if CS_API_MAJOR > 3
1058  case ARM64_INS_NEGS:
1059 #endif
1060  if (LSHIFT2_64(1)) {
1061  SHIFTED_REG64_APPEND(&op->esil, 1);
1062  } else {
1063  rz_strbuf_appendf(&op->esil, "%s", REG64(1));
1064  }
1065  rz_strbuf_appendf(&op->esil, ",0,-,%s,=", REG64(0));
1066  break;
1067  case ARM64_INS_SVC:
1068  rz_strbuf_setf(&op->esil, "%" PFMT64u ",$", IMM64(0));
1069  break;
1070  }
1071 
1072  rz_strbuf_append(&op->esil, postfix);
1073 
1074  return 0;
1075 }
r2
Definition: arm-aliases.s.cs:2
#define OPCOUNT64()
#define IMM64(x)
#define REGID64(x)
#define LSHIFT2_64(x)
#define ISMEM64(x)
#define HASMEMINDEX64(x)
#define ISREG64(x)
#define MEMDISP64(x)
#define ISPREINDEX64()
#define ISIMM64(x)
#define ISPOSTINDEX64()
RZ_IPI const char * rz_arm_cs_esil_prefix_cond(RzAnalysisOp *op, int cond_type)
Definition: arm_esil32.c:63
#define OPCALL_NEG(opchar)
Definition: arm_esil64.c:169
#define OPCALL(opchar)
Definition: arm_esil64.c:168
#define MEMBASE64(x)
Definition: arm_esil64.c:11
#define DECODE_SHIFT64(x)
Definition: arm_esil64.c:103
#define REG64(x)
Definition: arm_esil64.c:10
#define MEMINDEX64(x)
Definition: arm_esil64.c:12
#define EXT64(x)
Definition: arm_esil64.c:77
#define SHIFTED_REG64_APPEND(sb, n)
Definition: arm_esil64.c:126
#define REGSIZE64(x)
Definition: arm_esil64.c:124
static int arm64_reg_width(int reg)
Definition: arm_esil64.c:14
ut16 val
Definition: armass64_const.h:6
int bits(struct state *s, int need)
Definition: blast.c:72
@ ARM64_INS_ERET
Definition: arm64.h:737
@ ARM64_INS_FMADD
Definition: arm64.h:774
@ ARM64_INS_FDIV
Definition: arm64.h:773
@ ARM64_INS_FCSEL
Definition: arm64.h:755
@ ARM64_INS_FCMP
Definition: arm64.h:753
voidpf void uLong size
Definition: ioapi.h:138
#define PFMT64d
Definition: rz_types.h:394
#define st64
Definition: rz_types_base.h:10
static int
Definition: sfsocketcall.h:114

References ARM64_INS_ADC, ARM64_INS_ADD, ARM64_INS_ADR, ARM64_INS_ADRP, ARM64_INS_AND, ARM64_INS_ASR, ARM64_INS_B, ARM64_INS_BFI, ARM64_INS_BFXIL, ARM64_INS_BIC, ARM64_INS_BL, ARM64_INS_BLR, ARM64_INS_BR, ARM64_INS_CBNZ, ARM64_INS_CBZ, ARM64_INS_CCMN, ARM64_INS_CCMP, ARM64_INS_CINC, ARM64_INS_CLZ, ARM64_INS_CMN, ARM64_INS_CMP, ARM64_INS_CSEL, ARM64_INS_CSET, ARM64_INS_CSINC, ARM64_INS_EON, ARM64_INS_EOR, ARM64_INS_ERET, ARM64_INS_EXTR, ARM64_INS_FCMP, ARM64_INS_FCSEL, ARM64_INS_FDIV, ARM64_INS_FMADD, ARM64_INS_LDAR, ARM64_INS_LDARB, ARM64_INS_LDARH, ARM64_INS_LDAXR, ARM64_INS_LDAXRB, ARM64_INS_LDAXRH, ARM64_INS_LDP, ARM64_INS_LDR, ARM64_INS_LDRB, ARM64_INS_LDRH, ARM64_INS_LDRSB, ARM64_INS_LDRSH, ARM64_INS_LDRSW, ARM64_INS_LDUR, ARM64_INS_LDURB, ARM64_INS_LDURH, ARM64_INS_LDURSB, ARM64_INS_LDURSH, ARM64_INS_LDURSW, ARM64_INS_LDXR, ARM64_INS_LDXRB, ARM64_INS_LDXRH, ARM64_INS_LSL, ARM64_INS_LSR, ARM64_INS_MADD, ARM64_INS_MNEG, ARM64_INS_MOV, ARM64_INS_MOVK, ARM64_INS_MOVN, ARM64_INS_MOVZ, ARM64_INS_MSUB, ARM64_INS_MUL, ARM64_INS_MVN, ARM64_INS_NEG, ARM64_INS_NEGS, ARM64_INS_NOP, ARM64_INS_ORN, ARM64_INS_ORR, ARM64_INS_RBIT, ARM64_INS_RET, ARM64_INS_REV, ARM64_INS_REV16, ARM64_INS_REV32, ARM64_INS_ROR, ARM64_INS_SBC, ARM64_INS_SBFIZ, ARM64_INS_SBFX, ARM64_INS_SDIV, ARM64_INS_SMADDL, ARM64_INS_SMULL, ARM64_INS_STNP, ARM64_INS_STP, ARM64_INS_STR, ARM64_INS_STRB, ARM64_INS_STRH, ARM64_INS_STUR, ARM64_INS_STURB, ARM64_INS_STURH, ARM64_INS_STXR, ARM64_INS_STXRB, ARM64_INS_STXRH, ARM64_INS_SUB, ARM64_INS_SVC, ARM64_INS_SXTB, ARM64_INS_SXTH, ARM64_INS_SXTW, ARM64_INS_TBNZ, ARM64_INS_TBZ, ARM64_INS_TST, ARM64_INS_UBFIZ, ARM64_INS_UBFX, ARM64_INS_UDIV, ARM64_INS_UMADDL, ARM64_INS_UMULL, ARM64_INS_UXTB, ARM64_INS_UXTH, arm64_reg_width(), bits(), DECODE_SHIFT64, EXT64, HASMEMINDEX64, i2, IMM64, int, ISIMM64, ISMEM64, ISPOSTINDEX64, ISPREINDEX64, ISREG64, LSHIFT2_64, mask, MEMBASE64, MEMDISP64, MEMINDEX64, NULL, OPCALL, OPCALL_NEG, OPCOUNT64, PFMT64d, PFMT64u, PFMT64x, r0, r1, r2, REG64, REGID64, REGSIZE64, rz_arm_cs_esil_prefix_cond(), rz_num_bitmask(), rz_strbuf_append(), rz_strbuf_appendf(), rz_strbuf_init(), rz_strbuf_set(), rz_strbuf_setf(), shift(), SHIFTED_REG64_APPEND, st64, ut64(), and val.

Referenced by analysis_op().

◆ rz_arm_cs_esil_prefix_cond()

RZ_IPI const char* rz_arm_cs_esil_prefix_cond ( RzAnalysisOp op,
int  cond_type 
)

Definition at line 63 of file arm_esil32.c.

63  {
64  const char *close_cond[2];
65  close_cond[0] = "\0";
66  close_cond[1] = ",}\0";
67  int close_type = 0;
68  switch (cond_type) {
69  case ARM_CC_EQ:
70  close_type = 1;
71  rz_strbuf_setf(&op->esil, "zf,?{,");
72  break;
73  case ARM_CC_NE:
74  close_type = 1;
75  rz_strbuf_setf(&op->esil, "zf,!,?{,");
76  break;
77  case ARM_CC_HS:
78  close_type = 1;
79  rz_strbuf_setf(&op->esil, "cf,?{,");
80  break;
81  case ARM_CC_LO:
82  close_type = 1;
83  rz_strbuf_setf(&op->esil, "cf,!,?{,");
84  break;
85  case ARM_CC_MI:
86  close_type = 1;
87  rz_strbuf_setf(&op->esil, "nf,?{,");
88  break;
89  case ARM_CC_PL:
90  close_type = 1;
91  rz_strbuf_setf(&op->esil, "nf,!,?{,");
92  break;
93  case ARM_CC_VS:
94  close_type = 1;
95  rz_strbuf_setf(&op->esil, "vf,?{,");
96  break;
97  case ARM_CC_VC:
98  close_type = 1;
99  rz_strbuf_setf(&op->esil, "vf,!,?{,");
100  break;
101  case ARM_CC_HI:
102  close_type = 1;
103  rz_strbuf_setf(&op->esil, "cf,zf,!,&,?{,");
104  break;
105  case ARM_CC_LS:
106  close_type = 1;
107  rz_strbuf_setf(&op->esil, "cf,!,zf,|,?{,");
108  break;
109  case ARM_CC_GE:
110  close_type = 1;
111  rz_strbuf_setf(&op->esil, "nf,vf,^,!,?{,");
112  break;
113  case ARM_CC_LT:
114  close_type = 1;
115  rz_strbuf_setf(&op->esil, "nf,vf,^,?{,");
116  break;
117  case ARM_CC_GT:
118  // zf == 0 && nf == vf
119  close_type = 1;
120  rz_strbuf_setf(&op->esil, "zf,!,nf,vf,^,!,&,?{,");
121  break;
122  case ARM_CC_LE:
123  // zf == 1 || nf != vf
124  close_type = 1;
125  rz_strbuf_setf(&op->esil, "zf,nf,vf,^,|,?{,");
126  break;
127  case ARM_CC_AL:
128  // always executed
129  break;
130  default:
131  break;
132  }
133  return close_cond[close_type];
134 }
@ ARM_CC_GT
Greater than Greater than.
Definition: arm.h:47
@ ARM_CC_LE
Less than or equal <, ==, or unordered.
Definition: arm.h:48
@ ARM_CC_AL
Always (unconditional) Always (unconditional)
Definition: arm.h:49
@ ARM_CC_HI
Unsigned higher Greater than, or unordered.
Definition: arm.h:43
@ ARM_CC_VC
No overflow Not unordered.
Definition: arm.h:42
@ ARM_CC_LS
Unsigned lower or same Less than or equal.
Definition: arm.h:44
@ ARM_CC_GE
Greater than or equal Greater than or equal.
Definition: arm.h:45
@ ARM_CC_VS
Overflow Unordered.
Definition: arm.h:41
@ ARM_CC_PL
Plus, positive or zero >, ==, or unordered.
Definition: arm.h:40
@ ARM_CC_NE
Not equal Not equal, or unordered.
Definition: arm.h:36
@ ARM_CC_LO
Carry clear Less than.
Definition: arm.h:38
@ ARM_CC_EQ
Equal Equal.
Definition: arm.h:35
@ ARM_CC_LT
Less than Less than, or unordered.
Definition: arm.h:46
@ ARM_CC_HS
Carry set >, ==, or unordered.
Definition: arm.h:37
@ ARM_CC_MI
Minus, negative Less than.
Definition: arm.h:39

References ARM_CC_AL, ARM_CC_EQ, ARM_CC_GE, ARM_CC_GT, ARM_CC_HI, ARM_CC_HS, ARM_CC_LE, ARM_CC_LO, ARM_CC_LS, ARM_CC_LT, ARM_CC_MI, ARM_CC_NE, ARM_CC_PL, ARM_CC_VC, ARM_CC_VS, and rz_strbuf_setf().

Referenced by rz_arm_cs_analysis_op_32_esil(), and rz_arm_cs_analysis_op_64_esil().