Rizin
unix-like reverse engineering framework and cli tools
cs.c
Go to the documentation of this file.
1 /* Capstone Disassembly Engine */
2 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2015 */
3 #if defined (WIN32) || defined (WIN64) || defined (_WIN32) || defined (_WIN64)
4 #pragma warning(disable:4996) // disable MSVC's warning on strcpy()
5 #pragma warning(disable:28719) // disable MSVC's warning on strcpy()
6 #endif
7 #if defined(CAPSTONE_HAS_OSXKERNEL)
8 #include <Availability.h>
9 #include <libkern/libkern.h>
10 #else
11 #include <stddef.h>
12 #include <stdio.h>
13 #include <stdlib.h>
14 #endif
15 
16 #include <string.h>
17 #include <capstone/capstone.h>
18 
19 #include "utils.h"
20 #include "MCRegisterInfo.h"
21 
22 #if defined(_KERNEL_MODE)
23 #include "windows\winkernel_mm.h"
24 #endif
25 
26 // Issue #681: Windows kernel does not support formatting float point
27 #if defined(_KERNEL_MODE) && !defined(CAPSTONE_DIET)
28 #if defined(CAPSTONE_HAS_ARM) || defined(CAPSTONE_HAS_ARM64) || defined(CAPSTONE_HAS_M68K)
29 #define CAPSTONE_STR_INTERNAL(x) #x
30 #define CAPSTONE_STR(x) CAPSTONE_STR_INTERNAL(x)
31 #define CAPSTONE_MSVC_WRANING_PREFIX __FILE__ "("CAPSTONE_STR(__LINE__)") : warning message : "
32 
33 #pragma message(CAPSTONE_MSVC_WRANING_PREFIX "Windows driver does not support full features for selected architecture(s). Define CAPSTONE_DIET to compile Capstone with only supported features. See issue #681 for details.")
34 
35 #undef CAPSTONE_MSVC_WRANING_PREFIX
36 #undef CAPSTONE_STR
37 #undef CAPSTONE_STR_INTERNAL
38 #endif
39 #endif // defined(_KERNEL_MODE) && !defined(CAPSTONE_DIET)
40 
41 #if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(CAPSTONE_DIET) && !defined(_KERNEL_MODE)
42 #define INSN_CACHE_SIZE 32
43 #else
44 // reduce stack variable size for kernel/firmware
45 #define INSN_CACHE_SIZE 8
46 #endif
47 
48 // default SKIPDATA mnemonic
49 #ifndef CAPSTONE_DIET
50 #define SKIPDATA_MNEM ".byte"
51 #else // No printing is available in diet mode
52 #define SKIPDATA_MNEM NULL
53 #endif
54 
56 #include "arch/ARM/ARMModule.h"
57 #include "arch/EVM/EVMModule.h"
58 #include "arch/M680X/M680XModule.h"
59 #include "arch/M68K/M68KModule.h"
60 #include "arch/Mips/MipsModule.h"
61 #include "arch/PowerPC/PPCModule.h"
62 #include "arch/Sparc/SparcModule.h"
65 #include "arch/X86/X86Module.h"
66 #include "arch/XCore/XCoreModule.h"
67 
68 // constructor initialization for all archs
69 static cs_err (*cs_arch_init[MAX_ARCH])(cs_struct *) = {
70 #ifdef CAPSTONE_HAS_ARM
72 #else
73  NULL,
74 #endif
75 #ifdef CAPSTONE_HAS_ARM64
77 #else
78  NULL,
79 #endif
80 #ifdef CAPSTONE_HAS_MIPS
82 #else
83  NULL,
84 #endif
85 #ifdef CAPSTONE_HAS_X86
87 #else
88  NULL,
89 #endif
90 #ifdef CAPSTONE_HAS_POWERPC
92 #else
93  NULL,
94 #endif
95 #ifdef CAPSTONE_HAS_SPARC
97 #else
98  NULL,
99 #endif
100 #ifdef CAPSTONE_HAS_SYSZ
102 #else
103  NULL,
104 #endif
105 #ifdef CAPSTONE_HAS_XCORE
107 #else
108  NULL,
109 #endif
110 #ifdef CAPSTONE_HAS_M68K
112 #else
113  NULL,
114 #endif
115 #ifdef CAPSTONE_HAS_TMS320C64X
117 #else
118  NULL,
119 #endif
120 #ifdef CAPSTONE_HAS_M680X
122 #else
123  NULL,
124 #endif
125 #ifdef CAPSTONE_HAS_EVM
127 #else
128  NULL,
129 #endif
130 };
131 
132 // support cs_option() for all archs
133 static cs_err (*cs_arch_option[MAX_ARCH]) (cs_struct *, cs_opt_type, size_t value) = {
134 #ifdef CAPSTONE_HAS_ARM
135  ARM_option,
136 #else
137  NULL,
138 #endif
139 #ifdef CAPSTONE_HAS_ARM64
141 #else
142  NULL,
143 #endif
144 #ifdef CAPSTONE_HAS_MIPS
145  Mips_option,
146 #else
147  NULL,
148 #endif
149 #ifdef CAPSTONE_HAS_X86
150  X86_option,
151 #else
152  NULL,
153 #endif
154 #ifdef CAPSTONE_HAS_POWERPC
155  PPC_option,
156 #else
157  NULL,
158 #endif
159 #ifdef CAPSTONE_HAS_SPARC
160  Sparc_option,
161 #else
162  NULL,
163 #endif
164 #ifdef CAPSTONE_HAS_SYSZ
166 #else
167  NULL,
168 #endif
169 #ifdef CAPSTONE_HAS_XCORE
170  XCore_option,
171 #else
172  NULL,
173 #endif
174 #ifdef CAPSTONE_HAS_M68K
175  M68K_option,
176 #else
177  NULL,
178 #endif
179 #ifdef CAPSTONE_HAS_TMS320C64X
181 #else
182  NULL,
183 #endif
184 #ifdef CAPSTONE_HAS_M680X
185  M680X_option,
186 #else
187  NULL,
188 #endif
189 #ifdef CAPSTONE_HAS_EVM
190  EVM_option,
191 #else
192  NULL,
193 #endif
194 };
195 
196 // bitmask for finding disallowed modes for an arch:
197 // to be called in cs_open()/cs_option()
199 #ifdef CAPSTONE_HAS_ARM
202 #else
203  0,
204 #endif
205 #ifdef CAPSTONE_HAS_ARM64
207 #else
208  0,
209 #endif
210 #ifdef CAPSTONE_HAS_MIPS
213 #else
214  0,
215 #endif
216 #ifdef CAPSTONE_HAS_X86
218 #else
219  0,
220 #endif
221 #ifdef CAPSTONE_HAS_POWERPC
223  | CS_MODE_QPX),
224 #else
225  0,
226 #endif
227 #ifdef CAPSTONE_HAS_SPARC
229 #else
230  0,
231 #endif
232 #ifdef CAPSTONE_HAS_SYSZ
234 #else
235  0,
236 #endif
237 #ifdef CAPSTONE_HAS_XCORE
239 #else
240  0,
241 #endif
242 #ifdef CAPSTONE_HAS_M68K
245 #else
246  0,
247 #endif
250 #else
251  0,
252 #endif
253 #ifdef CAPSTONE_HAS_M680X
258 #else
259  0,
260 #endif
261 #ifdef CAPSTONE_HAS_EVM
262  0,
263 #else
264  0,
265 #endif
266 };
267 
268 // bitmask of enabled architectures
269 static uint32_t all_arch = 0
270 #ifdef CAPSTONE_HAS_ARM
271  | (1 << CS_ARCH_ARM)
272 #endif
273 #ifdef CAPSTONE_HAS_ARM64
274  | (1 << CS_ARCH_ARM64)
275 #endif
276 #ifdef CAPSTONE_HAS_MIPS
277  | (1 << CS_ARCH_MIPS)
278 #endif
279 #ifdef CAPSTONE_HAS_X86
280  | (1 << CS_ARCH_X86)
281 #endif
282 #ifdef CAPSTONE_HAS_POWERPC
283  | (1 << CS_ARCH_PPC)
284 #endif
285 #ifdef CAPSTONE_HAS_SPARC
286  | (1 << CS_ARCH_SPARC)
287 #endif
288 #ifdef CAPSTONE_HAS_SYSZ
289  | (1 << CS_ARCH_SYSZ)
290 #endif
291 #ifdef CAPSTONE_HAS_XCORE
292  | (1 << CS_ARCH_XCORE)
293 #endif
294 #ifdef CAPSTONE_HAS_M68K
295  | (1 << CS_ARCH_M68K)
296 #endif
298  | (1 << CS_ARCH_TMS320C64X)
299 #endif
300 #ifdef CAPSTONE_HAS_M680X
301  | (1 << CS_ARCH_M680X)
302 #endif
303 #ifdef CAPSTONE_HAS_EVM
304  | (1 << CS_ARCH_EVM)
305 #endif
306 ;
307 
308 
309 #if defined(CAPSTONE_USE_SYS_DYN_MEM)
310 #if !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE)
311 // default
316 #if defined(_WIN32_WCE)
317 cs_vsnprintf_t cs_vsnprintf = _vsnprintf;
318 #else
320 #endif // defined(_WIN32_WCE)
321 
322 #elif defined(_KERNEL_MODE)
323 // Windows driver
329 #else
330 // OSX kernel
331 extern void* kern_os_malloc(size_t size);
332 extern void kern_os_free(void* addr);
333 extern void* kern_os_realloc(void* addr, size_t nsize);
334 
335 static void* cs_kern_os_calloc(size_t num, size_t size)
336 {
337  return kern_os_malloc(num * size); // malloc bzeroes the buffer
338 }
339 
340 cs_malloc_t cs_mem_malloc = kern_os_malloc;
341 cs_calloc_t cs_mem_calloc = cs_kern_os_calloc;
342 cs_realloc_t cs_mem_realloc = kern_os_realloc;
343 cs_free_t cs_mem_free = kern_os_free;
345 #endif // !defined(CAPSTONE_HAS_OSXKERNEL) && !defined(_KERNEL_MODE)
346 #else
347 // User-defined
353 
354 #endif // defined(CAPSTONE_USE_SYS_DYN_MEM)
355 
357 unsigned int CAPSTONE_API cs_version(int *major, int *minor)
358 {
359  if (major != NULL && minor != NULL) {
360  *major = CS_API_MAJOR;
361  *minor = CS_API_MINOR;
362  }
363 
364  return (CS_API_MAJOR << 8) + CS_API_MINOR;
365 }
366 
368 bool CAPSTONE_API cs_support(int query)
369 {
370  if (query == CS_ARCH_ALL)
371  return all_arch == ((1 << CS_ARCH_ARM) | (1 << CS_ARCH_ARM64) |
372  (1 << CS_ARCH_MIPS) | (1 << CS_ARCH_X86) |
373  (1 << CS_ARCH_PPC) | (1 << CS_ARCH_SPARC) |
374  (1 << CS_ARCH_SYSZ) | (1 << CS_ARCH_XCORE) |
375  (1 << CS_ARCH_M68K) | (1 << CS_ARCH_TMS320C64X) |
376  (1 << CS_ARCH_M680X) | (1 << CS_ARCH_EVM));
377 
378  if ((unsigned int)query < CS_ARCH_MAX)
379  return all_arch & (1 << query);
380 
381  if (query == CS_SUPPORT_DIET) {
382 #ifdef CAPSTONE_DIET
383  return true;
384 #else
385  return false;
386 #endif
387  }
388 
389  if (query == CS_SUPPORT_X86_REDUCE) {
390 #if defined(CAPSTONE_HAS_X86) && defined(CAPSTONE_X86_REDUCE)
391  return true;
392 #else
393  return false;
394 #endif
395  }
396 
397  // unsupported query
398  return false;
399 }
400 
403 {
404  struct cs_struct *ud;
405  if (!handle)
406  return CS_ERR_CSH;
407 
408  ud = (struct cs_struct *)(uintptr_t)handle;
409 
410  return ud->errnum;
411 }
412 
414 const char * CAPSTONE_API cs_strerror(cs_err code)
415 {
416  switch(code) {
417  default:
418  return "Unknown error code";
419  case CS_ERR_OK:
420  return "OK (CS_ERR_OK)";
421  case CS_ERR_MEM:
422  return "Out of memory (CS_ERR_MEM)";
423  case CS_ERR_ARCH:
424  return "Invalid/unsupported architecture(CS_ERR_ARCH)";
425  case CS_ERR_HANDLE:
426  return "Invalid handle (CS_ERR_HANDLE)";
427  case CS_ERR_CSH:
428  return "Invalid csh (CS_ERR_CSH)";
429  case CS_ERR_MODE:
430  return "Invalid mode (CS_ERR_MODE)";
431  case CS_ERR_OPTION:
432  return "Invalid option (CS_ERR_OPTION)";
433  case CS_ERR_DETAIL:
434  return "Details are unavailable (CS_ERR_DETAIL)";
435  case CS_ERR_MEMSETUP:
436  return "Dynamic memory management uninitialized (CS_ERR_MEMSETUP)";
437  case CS_ERR_VERSION:
438  return "Different API version between core & binding (CS_ERR_VERSION)";
439  case CS_ERR_DIET:
440  return "Information irrelevant in diet engine (CS_ERR_DIET)";
441  case CS_ERR_SKIPDATA:
442  return "Information irrelevant for 'data' instruction in SKIPDATA mode (CS_ERR_SKIPDATA)";
443  case CS_ERR_X86_ATT:
444  return "AT&T syntax is unavailable (CS_ERR_X86_ATT)";
445  case CS_ERR_X86_INTEL:
446  return "INTEL syntax is unavailable (CS_ERR_X86_INTEL)";
447  case CS_ERR_X86_MASM:
448  return "MASM syntax is unavailable (CS_ERR_X86_MASM)";
449  }
450 }
451 
454 {
455  cs_err err;
456  struct cs_struct *ud;
458  // Error: before cs_open(), dynamic memory management must be initialized
459  // with cs_option(CS_OPT_MEM)
460  return CS_ERR_MEMSETUP;
461 
462  if (arch < CS_ARCH_MAX && cs_arch_init[arch]) {
463  // verify if requested mode is valid
465  *handle = 0;
466  return CS_ERR_MODE;
467  }
468 
469  ud = cs_mem_calloc(1, sizeof(*ud));
470  if (!ud) {
471  // memory insufficient
472  return CS_ERR_MEM;
473  }
474 
475  ud->errnum = CS_ERR_OK;
476  ud->arch = arch;
477  ud->mode = mode;
478  // by default, do not break instruction into details
479  ud->detail = CS_OPT_OFF;
480 
481  // default skipdata setup
482  ud->skipdata_setup.mnemonic = SKIPDATA_MNEM;
483 
484  err = cs_arch_init[ud->arch](ud);
485  if (err) {
486  cs_mem_free(ud);
487  *handle = 0;
488  return err;
489  }
490 
491  *handle = (uintptr_t)ud;
492 
493  return CS_ERR_OK;
494  } else {
495  *handle = 0;
496  return CS_ERR_ARCH;
497  }
498 }
499 
502 {
503  struct cs_struct *ud;
504  struct insn_mnem *next, *tmp;
505 
506  if (*handle == 0)
507  // invalid handle
508  return CS_ERR_CSH;
509 
510  ud = (struct cs_struct *)(*handle);
511 
512  if (ud->printer_info)
514 
515  // free the linked list of customized mnemonic
516  tmp = ud->mnem_list;
517  while(tmp) {
518  next = tmp->next;
519  cs_mem_free(tmp);
520  tmp = next;
521  }
522 
523  cs_mem_free(ud->insn_cache);
524 
525  memset(ud, 0, sizeof(*ud));
526  cs_mem_free(ud);
527 
528  // invalidate this handle by ZERO out its value.
529  // this is to make sure it is unusable after cs_close()
530  *handle = 0;
531 
532  return CS_ERR_OK;
533 }
534 
535 // fill insn with mnemonic & operands info
536 static void fill_insn(struct cs_struct *handle, cs_insn *insn, char *buffer, MCInst *mci,
537  PostPrinter_t postprinter, const uint8_t *code)
538 {
539 #ifndef CAPSTONE_DIET
540  char *sp, *mnem;
541 #endif
542  uint16_t copy_size = MIN(sizeof(insn->bytes), insn->size);
543 
544  // fill the instruction bytes.
545  // we might skip some redundant bytes in front in the case of X86
546  memcpy(insn->bytes, code + insn->size - copy_size, copy_size);
547  insn->size = copy_size;
548 
549  // alias instruction might have ID saved in OpcodePub
550  if (MCInst_getOpcodePub(mci))
551  insn->id = MCInst_getOpcodePub(mci);
552 
553  // post printer handles some corner cases (hacky)
554  if (postprinter)
555  postprinter((csh)handle, insn, buffer, mci);
556 
557 #ifndef CAPSTONE_DIET
558  // fill in mnemonic & operands
559  // find first space or tab
560  mnem = insn->mnemonic;
561  for (sp = buffer; *sp; sp++) {
562  if (*sp == ' '|| *sp == '\t')
563  break;
564  if (*sp == '|') // lock|rep prefix for x86
565  *sp = ' ';
566  // copy to @mnemonic
567  *mnem = *sp;
568  mnem++;
569  }
570 
571  *mnem = '\0';
572 
573  // we might have customized mnemonic
574  if (handle->mnem_list) {
575  struct insn_mnem *tmp = handle->mnem_list;
576  while(tmp) {
577  if (tmp->insn.id == insn->id) {
578  // found this instruction, so copy its mnemonic
579  (void)strncpy(insn->mnemonic, tmp->insn.mnemonic, sizeof(insn->mnemonic));
580  insn->mnemonic[sizeof(insn->mnemonic) - 1] = '\0';
581  break;
582  }
583  tmp = tmp->next;
584  }
585  }
586 
587  // copy @op_str
588  if (*sp) {
589  // find the next non-space char
590  sp++;
591  for (; ((*sp == ' ') || (*sp == '\t')); sp++);
592  strncpy(insn->op_str, sp, sizeof(insn->op_str) - 1);
593  insn->op_str[sizeof(insn->op_str) - 1] = '\0';
594  } else
595  insn->op_str[0] = '\0';
596 #endif
597 }
598 
599 // how many bytes will we skip when encountering data (CS_OPT_SKIPDATA)?
600 // this very much depends on instruction alignment requirement of each arch.
602 {
603  switch(handle->arch) {
604  default:
605  // should never reach
606  return (uint8_t)-1;
607  case CS_ARCH_ARM:
608  // skip 2 bytes on Thumb mode.
609  if (handle->mode & CS_MODE_THUMB)
610  return 2;
611  // otherwise, skip 4 bytes
612  return 4;
613  case CS_ARCH_ARM64:
614  case CS_ARCH_MIPS:
615  case CS_ARCH_PPC:
616  case CS_ARCH_SPARC:
617  // skip 4 bytes
618  return 4;
619  case CS_ARCH_SYSZ:
620  // SystemZ instruction's length can be 2, 4 or 6 bytes,
621  // so we just skip 2 bytes
622  return 2;
623  case CS_ARCH_X86:
624  // X86 has no restriction on instruction alignment
625  return 1;
626  case CS_ARCH_XCORE:
627  // XCore instruction's length can be 2 or 4 bytes,
628  // so we just skip 2 bytes
629  return 2;
630  case CS_ARCH_M68K:
631  // M68K has 2 bytes instruction alignment but contain multibyte instruction so we skip 2 bytes
632  return 2;
633  case CS_ARCH_TMS320C64X:
634  // TMS320C64x alignment is 4.
635  return 4;
636  case CS_ARCH_M680X:
637  // M680X alignment is 1.
638  return 1;
639  case CS_ARCH_EVM:
640  // EVM alignment is 1.
641  return 1;
642  }
643 }
644 
647 {
648  struct cs_struct *handle;
649  cs_opt_mnem *opt;
650 
651  // cs_option() can be called with NULL handle just for CS_OPT_MEM
652  // This is supposed to be executed before all other APIs (even cs_open())
653  if (type == CS_OPT_MEM) {
655 
656  cs_mem_malloc = mem->malloc;
657  cs_mem_calloc = mem->calloc;
658  cs_mem_realloc = mem->realloc;
659  cs_mem_free = mem->free;
660  cs_vsnprintf = mem->vsnprintf;
661 
662  return CS_ERR_OK;
663  }
664 
665  handle = (struct cs_struct *)(uintptr_t)ud;
666  if (!handle)
667  return CS_ERR_CSH;
668 
669  switch(type) {
670  default:
671  break;
672 
673  case CS_OPT_UNSIGNED:
674  handle->imm_unsigned = (cs_opt_value)value;
675  return CS_ERR_OK;
676 
677  case CS_OPT_DETAIL:
678  handle->detail = (cs_opt_value)value;
679  return CS_ERR_OK;
680 
681  case CS_OPT_SKIPDATA:
682  handle->skipdata = (value == CS_OPT_ON);
683  if (handle->skipdata) {
684  if (handle->skipdata_size == 0) {
685  // set the default skipdata size
686  handle->skipdata_size = skipdata_size(handle);
687  }
688  }
689  return CS_ERR_OK;
690 
692  if (value)
693  handle->skipdata_setup = *((cs_opt_skipdata *)value);
694  return CS_ERR_OK;
695 
696  case CS_OPT_MNEMONIC:
697  opt = (cs_opt_mnem *)value;
698  if (opt->id) {
699  if (opt->mnemonic) {
700  struct insn_mnem *tmp;
701 
702  // add new instruction, or replace existing instruction
703  // 1. find if we already had this insn in the linked list
704  tmp = handle->mnem_list;
705  while(tmp) {
706  if (tmp->insn.id == opt->id) {
707  // found this instruction, so replace its mnemonic
708  (void)strncpy(tmp->insn.mnemonic, opt->mnemonic, sizeof(tmp->insn.mnemonic) - 1);
709  tmp->insn.mnemonic[sizeof(tmp->insn.mnemonic) - 1] = '\0';
710  break;
711  }
712  tmp = tmp->next;
713  }
714 
715  // 2. add this instruction if we have not had it yet
716  if (!tmp) {
717  tmp = cs_mem_malloc(sizeof(*tmp));
718  tmp->insn.id = opt->id;
719  (void)strncpy(tmp->insn.mnemonic, opt->mnemonic, sizeof(tmp->insn.mnemonic) - 1);
720  tmp->insn.mnemonic[sizeof(tmp->insn.mnemonic) - 1] = '\0';
721  // this new instruction is heading the list
722  tmp->next = handle->mnem_list;
723  handle->mnem_list = tmp;
724  }
725  return CS_ERR_OK;
726  } else {
727  struct insn_mnem *prev, *tmp;
728 
729  // we want to delete an existing instruction
730  // iterate the list to find the instruction to remove it
731  tmp = handle->mnem_list;
732  prev = tmp;
733  while(tmp) {
734  if (tmp->insn.id == opt->id) {
735  // delete this instruction
736  if (tmp == prev) {
737  // head of the list
738  handle->mnem_list = tmp->next;
739  } else {
740  prev->next = tmp->next;
741  }
742  cs_mem_free(tmp);
743  break;
744  }
745  prev = tmp;
746  tmp = tmp->next;
747  }
748  }
749  }
750  return CS_ERR_OK;
751 
752  case CS_OPT_MODE:
753  // verify if requested mode is valid
755  return CS_ERR_OPTION;
756  }
757  break;
758  }
759 
760  return cs_arch_option[handle->arch](handle, type, value);
761 }
762 
763 // generate @op_str for data instruction of SKIPDATA
764 #ifndef CAPSTONE_DIET
765 static void skipdata_opstr(char *opstr, const uint8_t *buffer, size_t size)
766 {
767  char *p = opstr;
768  int len;
769  size_t i;
770  size_t available = sizeof(((cs_insn*)NULL)->op_str);
771 
772  if (!size) {
773  opstr[0] = '\0';
774  return;
775  }
776 
777  len = cs_snprintf(p, available, "0x%02x", buffer[0]);
778  p+= len;
779  available -= len;
780 
781  for(i = 1; i < size; i++) {
782  len = cs_snprintf(p, available, ", 0x%02x", buffer[i]);
783  if (len < 0) {
784  break;
785  }
786  if ((size_t)len > available - 1) {
787  break;
788  }
789  p+= len;
790  available -= len;
791  }
792 }
793 #endif
794 
795 // dynamicly allocate memory to contain disasm insn
796 // NOTE: caller must free() the allocated memory itself to avoid memory leaking
798 size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
799 {
800  struct cs_struct *handle;
801  MCInst mci;
802  uint16_t insn_size;
803  size_t c = 0, i;
804  unsigned int f = 0; // index of the next instruction in the cache
805  cs_insn *insn_cache; // cache contains disassembled instructions
806  void *total = NULL;
807  size_t total_size = 0; // total size of output buffer containing all insns
808  bool r;
809  void *tmp;
810  size_t skipdata_bytes;
811  uint64_t offset_org; // save all the original info of the buffer
812  size_t size_org;
813  const uint8_t *buffer_org;
814  unsigned int cache_size = INSN_CACHE_SIZE;
815  size_t next_offset;
816 
817  handle = (struct cs_struct *)(uintptr_t)ud;
818  if (!handle) {
819  // FIXME: how to handle this case:
820  // handle->errnum = CS_ERR_HANDLE;
821  return 0;
822  }
823 
824  handle->errnum = CS_ERR_OK;
825 
826  // reset IT block of ARM structure
827  if (handle->arch == CS_ARCH_ARM)
828  handle->ITBlock.size = 0;
829 
830 #ifdef CAPSTONE_USE_SYS_DYN_MEM
831  if (count > 0 && count <= INSN_CACHE_SIZE)
832  cache_size = (unsigned int) count;
833 #endif
834 
835  // save the original offset for SKIPDATA
836  buffer_org = buffer;
837  offset_org = offset;
838  size_org = size;
839 
840  total_size = sizeof(cs_insn) * cache_size;
841  total = cs_mem_calloc(1, total_size);
842  if (total == NULL) {
843  // insufficient memory
844  handle->errnum = CS_ERR_MEM;
845  return 0;
846  }
847 
848  insn_cache = total;
849 
850  while (size > 0) {
851  MCInst_Init(&mci);
852  mci.csh = handle;
853 
854  // relative branches need to know the address & size of current insn
855  mci.address = offset;
856 
857  if (handle->detail) {
858  // allocate memory for @detail pointer
859  insn_cache->detail = cs_mem_calloc(1, sizeof(cs_detail));
860  } else {
861  insn_cache->detail = NULL;
862  }
863 
864  // save all the information for non-detailed mode
865  mci.flat_insn = insn_cache;
866  mci.flat_insn->address = offset;
867 #ifdef CAPSTONE_DIET
868  // zero out mnemonic & op_str
869  mci.flat_insn->mnemonic[0] = '\0';
870  mci.flat_insn->op_str[0] = '\0';
871 #endif
872 
873  r = handle->disasm(ud, buffer, size, &mci, &insn_size, offset, handle->getinsn_info);
874  if (r) {
875  SStream ss;
876  SStream_Init(&ss);
877 
878  mci.flat_insn->size = insn_size;
879 
880  // map internal instruction opcode to public insn ID
881 
882  handle->insn_id(handle, insn_cache, mci.Opcode);
883 
884  handle->printer(&mci, &ss, handle->printer_info);
885  fill_insn(handle, insn_cache, ss.buffer, &mci, handle->post_printer, buffer);
886 
887  // adjust for pseudo opcode (X86)
888  if (handle->arch == CS_ARCH_X86)
889  insn_cache->id += mci.popcode_adjust;
890 
891  next_offset = insn_size;
892  } else {
893  // encounter a broken instruction
894 
895  // free memory of @detail pointer
896  if (handle->detail) {
897  cs_mem_free(insn_cache->detail);
898  }
899 
900  // if there is no request to skip data, or remaining data is too small,
901  // then bail out
902  if (!handle->skipdata || handle->skipdata_size > size)
903  break;
904 
905  if (handle->skipdata_setup.callback) {
906  skipdata_bytes = handle->skipdata_setup.callback(buffer_org, size_org,
907  (size_t)(offset - offset_org), handle->skipdata_setup.user_data);
908  if (skipdata_bytes > size)
909  // remaining data is not enough
910  break;
911 
912  if (!skipdata_bytes)
913  // user requested not to skip data, so bail out
914  break;
915  } else
916  skipdata_bytes = handle->skipdata_size;
917 
918  // we have to skip some amount of data, depending on arch & mode
919  insn_cache->id = 0; // invalid ID for this "data" instruction
920  insn_cache->address = offset;
921  insn_cache->size = (uint16_t)skipdata_bytes;
922  memcpy(insn_cache->bytes, buffer, skipdata_bytes);
923 #ifdef CAPSTONE_DIET
924  insn_cache->mnemonic[0] = '\0';
925  insn_cache->op_str[0] = '\0';
926 #else
927  strncpy(insn_cache->mnemonic, handle->skipdata_setup.mnemonic,
928  sizeof(insn_cache->mnemonic) - 1);
929  skipdata_opstr(insn_cache->op_str, buffer, skipdata_bytes);
930 #endif
931  insn_cache->detail = NULL;
932 
933  next_offset = skipdata_bytes;
934  }
935 
936  // one more instruction entering the cache
937  f++;
938 
939  // one more instruction disassembled
940  c++;
941  if (count > 0 && c == count)
942  // already got requested number of instructions
943  break;
944 
945  if (f == cache_size) {
946  // full cache, so expand the cache to contain incoming insns
947  cache_size = cache_size * 8 / 5; // * 1.6 ~ golden ratio
948  total_size += (sizeof(cs_insn) * cache_size);
949  unsigned int old_size = total_size;
950  tmp = cs_mem_realloc(total, total_size);
951  if (tmp == NULL) { // insufficient memory
952  if (handle->detail) {
953  insn_cache = (cs_insn *)total;
954  for (i = 0; i < c; i++, insn_cache++)
955  cs_mem_free(insn_cache->detail);
956  }
957 
958  cs_mem_free(total);
959  *insn = NULL;
960  handle->errnum = CS_ERR_MEM;
961  return 0;
962  }
963 
964  memset((char *)total + (sizeof(cs_insn) * old_size), 0, (total_size - old_size));
965  total = tmp;
966  // continue to fill in the cache after the last instruction
967  insn_cache = (cs_insn *)((char *)total + sizeof(cs_insn) * c);
968 
969  // reset f back to 0, so we fill in the cache from begining
970  f = 0;
971  } else
972  insn_cache++;
973 
974  buffer += next_offset;
975  size -= next_offset;
976  offset += next_offset;
977  }
978 
979  if (!c) {
980  // we did not disassemble any instruction
981  cs_mem_free(total);
982  total = NULL;
983  } else if (f != cache_size) {
984  // total did not fully use the last cache, so downsize it
985  tmp = cs_mem_realloc(total, total_size - (cache_size - f) * sizeof(*insn_cache));
986  if (tmp == NULL) { // insufficient memory
987  // free all detail pointers
988  if (handle->detail) {
989  insn_cache = (cs_insn *)total;
990  for (i = 0; i < c; i++, insn_cache++)
991  cs_mem_free(insn_cache->detail);
992  }
993 
994  cs_mem_free(total);
995  *insn = NULL;
996 
997  handle->errnum = CS_ERR_MEM;
998  return 0;
999  }
1000 
1001  total = tmp;
1002  }
1003 
1004  *insn = total;
1005 
1006  return c;
1007 }
1008 
1011 size_t CAPSTONE_API cs_disasm_ex(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
1012 {
1013  return cs_disasm(ud, buffer, size, offset, count, insn);
1014 }
1015 
1017 void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
1018 {
1019  size_t i;
1020 
1021  // free all detail pointers
1022  for (i = 0; i < count; i++)
1023  cs_mem_free(insn[i].detail);
1024 
1025  // then free pointer to cs_insn array
1026  cs_mem_free(insn);
1027 }
1028 
1031 {
1032  cs_insn *insn;
1033  struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
1034 
1035  insn = cs_mem_malloc(sizeof(cs_insn));
1036  if (!insn) {
1037  // insufficient memory
1038  handle->errnum = CS_ERR_MEM;
1039  return NULL;
1040  } else {
1041  if (handle->detail) {
1042  // allocate memory for @detail pointer
1043  insn->detail = cs_mem_malloc(sizeof(cs_detail));
1044  if (insn->detail == NULL) { // insufficient memory
1045  cs_mem_free(insn);
1046  handle->errnum = CS_ERR_MEM;
1047  return NULL;
1048  }
1049  } else
1050  insn->detail = NULL;
1051  }
1052 
1053  return insn;
1054 }
1055 
1056 // iterator for instruction "single-stepping"
1058 bool CAPSTONE_API cs_disasm_iter(csh ud, const uint8_t **code, size_t *size,
1059  uint64_t *address, cs_insn *insn)
1060 {
1061  struct cs_struct *handle;
1062  uint16_t insn_size;
1063  MCInst mci;
1064  bool r;
1065 
1066  handle = (struct cs_struct *)(uintptr_t)ud;
1067  if (!handle) {
1068  return false;
1069  }
1070 
1071  handle->errnum = CS_ERR_OK;
1072 
1073  MCInst_Init(&mci);
1074  mci.csh = handle;
1075 
1076  // relative branches need to know the address & size of current insn
1077  mci.address = *address;
1078 
1079  // save all the information for non-detailed mode
1080  mci.flat_insn = insn;
1081  mci.flat_insn->address = *address;
1082 #ifdef CAPSTONE_DIET
1083  // zero out mnemonic & op_str
1084  mci.flat_insn->mnemonic[0] = '\0';
1085  mci.flat_insn->op_str[0] = '\0';
1086 #endif
1087 
1088  r = handle->disasm(ud, *code, *size, &mci, &insn_size, *address, handle->getinsn_info);
1089  if (r) {
1090  SStream ss;
1091  SStream_Init(&ss);
1092 
1093  mci.flat_insn->size = insn_size;
1094 
1095  // map internal instruction opcode to public insn ID
1096  handle->insn_id(handle, insn, mci.Opcode);
1097 
1098  handle->printer(&mci, &ss, handle->printer_info);
1099 
1100  fill_insn(handle, insn, ss.buffer, &mci, handle->post_printer, *code);
1101 
1102  // adjust for pseudo opcode (X86)
1103  if (handle->arch == CS_ARCH_X86)
1104  insn->id += mci.popcode_adjust;
1105 
1106  *code += insn_size;
1107  *size -= insn_size;
1108  *address += insn_size;
1109  } else { // encounter a broken instruction
1110  size_t skipdata_bytes;
1111 
1112  // if there is no request to skip data, or remaining data is too small,
1113  // then bail out
1114  if (!handle->skipdata || handle->skipdata_size > *size)
1115  return false;
1116 
1117  if (handle->skipdata_setup.callback) {
1118  skipdata_bytes = handle->skipdata_setup.callback(*code, *size,
1119  0, handle->skipdata_setup.user_data);
1120  if (skipdata_bytes > *size)
1121  // remaining data is not enough
1122  return false;
1123 
1124  if (!skipdata_bytes)
1125  // user requested not to skip data, so bail out
1126  return false;
1127  } else
1128  skipdata_bytes = handle->skipdata_size;
1129 
1130  // we have to skip some amount of data, depending on arch & mode
1131  insn->id = 0; // invalid ID for this "data" instruction
1132  insn->address = *address;
1133  insn->size = (uint16_t)skipdata_bytes;
1134 #ifdef CAPSTONE_DIET
1135  insn->mnemonic[0] = '\0';
1136  insn->op_str[0] = '\0';
1137 #else
1138  memcpy(insn->bytes, *code, skipdata_bytes);
1139  strncpy(insn->mnemonic, handle->skipdata_setup.mnemonic,
1140  sizeof(insn->mnemonic) - 1);
1141  skipdata_opstr(insn->op_str, *code, skipdata_bytes);
1142 #endif
1143 
1144  *code += skipdata_bytes;
1145  *size -= skipdata_bytes;
1146  *address += skipdata_bytes;
1147  }
1148 
1149  return true;
1150 }
1151 
1152 // return friendly name of regiser in a string
1154 const char * CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
1155 {
1156  struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
1157 
1158  if (!handle || handle->reg_name == NULL) {
1159  return NULL;
1160  }
1161 
1162  return handle->reg_name(ud, reg);
1163 }
1164 
1166 const char * CAPSTONE_API cs_insn_name(csh ud, unsigned int insn)
1167 {
1168  struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
1169 
1170  if (!handle || handle->insn_name == NULL) {
1171  return NULL;
1172  }
1173 
1174  return handle->insn_name(ud, insn);
1175 }
1176 
1178 const char * CAPSTONE_API cs_group_name(csh ud, unsigned int group)
1179 {
1180  struct cs_struct *handle = (struct cs_struct *)(uintptr_t)ud;
1181 
1182  if (!handle || handle->group_name == NULL) {
1183  return NULL;
1184  }
1185 
1186  return handle->group_name(ud, group);
1187 }
1188 
1190 bool CAPSTONE_API cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id)
1191 {
1192  struct cs_struct *handle;
1193  if (!ud)
1194  return false;
1195 
1196  handle = (struct cs_struct *)(uintptr_t)ud;
1197 
1198  if (!handle->detail) {
1199  handle->errnum = CS_ERR_DETAIL;
1200  return false;
1201  }
1202 
1203  if (!insn->id) {
1204  handle->errnum = CS_ERR_SKIPDATA;
1205  return false;
1206  }
1207 
1208  if (!insn->detail) {
1209  handle->errnum = CS_ERR_DETAIL;
1210  return false;
1211  }
1212 
1213  return arr_exist8(insn->detail->groups, insn->detail->groups_count, group_id);
1214 }
1215 
1217 bool CAPSTONE_API cs_reg_read(csh ud, const cs_insn *insn, unsigned int reg_id)
1218 {
1219  struct cs_struct *handle;
1220  if (!ud)
1221  return false;
1222 
1223  handle = (struct cs_struct *)(uintptr_t)ud;
1224 
1225  if (!handle->detail) {
1226  handle->errnum = CS_ERR_DETAIL;
1227  return false;
1228  }
1229 
1230  if (!insn->id) {
1231  handle->errnum = CS_ERR_SKIPDATA;
1232  return false;
1233  }
1234 
1235  if (!insn->detail) {
1236  handle->errnum = CS_ERR_DETAIL;
1237  return false;
1238  }
1239 
1240  return arr_exist(insn->detail->regs_read, insn->detail->regs_read_count, reg_id);
1241 }
1242 
1244 bool CAPSTONE_API cs_reg_write(csh ud, const cs_insn *insn, unsigned int reg_id)
1245 {
1246  struct cs_struct *handle;
1247  if (!ud)
1248  return false;
1249 
1250  handle = (struct cs_struct *)(uintptr_t)ud;
1251 
1252  if (!handle->detail) {
1253  handle->errnum = CS_ERR_DETAIL;
1254  return false;
1255  }
1256 
1257  if (!insn->id) {
1258  handle->errnum = CS_ERR_SKIPDATA;
1259  return false;
1260  }
1261 
1262  if (!insn->detail) {
1263  handle->errnum = CS_ERR_DETAIL;
1264  return false;
1265  }
1266 
1267  return arr_exist(insn->detail->regs_write, insn->detail->regs_write_count, reg_id);
1268 }
1269 
1271 int CAPSTONE_API cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type)
1272 {
1273  struct cs_struct *handle;
1274  unsigned int count = 0, i;
1275  if (!ud)
1276  return -1;
1277 
1278  handle = (struct cs_struct *)(uintptr_t)ud;
1279 
1280  if (!handle->detail) {
1281  handle->errnum = CS_ERR_DETAIL;
1282  return -1;
1283  }
1284 
1285  if (!insn->id) {
1286  handle->errnum = CS_ERR_SKIPDATA;
1287  return -1;
1288  }
1289 
1290  if (!insn->detail) {
1291  handle->errnum = CS_ERR_DETAIL;
1292  return -1;
1293  }
1294 
1295  handle->errnum = CS_ERR_OK;
1296 
1297  switch (handle->arch) {
1298  default:
1299  handle->errnum = CS_ERR_HANDLE;
1300  return -1;
1301  case CS_ARCH_ARM:
1302  for (i = 0; i < insn->detail->arm.op_count; i++)
1303  if (insn->detail->arm.operands[i].type == (arm_op_type)op_type)
1304  count++;
1305  break;
1306  case CS_ARCH_ARM64:
1307  for (i = 0; i < insn->detail->arm64.op_count; i++)
1308  if (insn->detail->arm64.operands[i].type == (arm64_op_type)op_type)
1309  count++;
1310  break;
1311  case CS_ARCH_X86:
1312  for (i = 0; i < insn->detail->x86.op_count; i++)
1313  if (insn->detail->x86.operands[i].type == (x86_op_type)op_type)
1314  count++;
1315  break;
1316  case CS_ARCH_MIPS:
1317  for (i = 0; i < insn->detail->mips.op_count; i++)
1318  if (insn->detail->mips.operands[i].type == (mips_op_type)op_type)
1319  count++;
1320  break;
1321  case CS_ARCH_PPC:
1322  for (i = 0; i < insn->detail->ppc.op_count; i++)
1323  if (insn->detail->ppc.operands[i].type == (ppc_op_type)op_type)
1324  count++;
1325  break;
1326  case CS_ARCH_SPARC:
1327  for (i = 0; i < insn->detail->sparc.op_count; i++)
1328  if (insn->detail->sparc.operands[i].type == (sparc_op_type)op_type)
1329  count++;
1330  break;
1331  case CS_ARCH_SYSZ:
1332  for (i = 0; i < insn->detail->sysz.op_count; i++)
1333  if (insn->detail->sysz.operands[i].type == (sysz_op_type)op_type)
1334  count++;
1335  break;
1336  case CS_ARCH_XCORE:
1337  for (i = 0; i < insn->detail->xcore.op_count; i++)
1338  if (insn->detail->xcore.operands[i].type == (xcore_op_type)op_type)
1339  count++;
1340  break;
1341  case CS_ARCH_M68K:
1342  for (i = 0; i < insn->detail->m68k.op_count; i++)
1343  if (insn->detail->m68k.operands[i].type == (m68k_op_type)op_type)
1344  count++;
1345  break;
1346  case CS_ARCH_TMS320C64X:
1347  for (i = 0; i < insn->detail->tms320c64x.op_count; i++)
1348  if (insn->detail->tms320c64x.operands[i].type == (tms320c64x_op_type)op_type)
1349  count++;
1350  break;
1351  case CS_ARCH_M680X:
1352  for (i = 0; i < insn->detail->m680x.op_count; i++)
1353  if (insn->detail->m680x.operands[i].type == (m680x_op_type)op_type)
1354  count++;
1355  break;
1356  case CS_ARCH_EVM:
1357 #if 0
1358  for (i = 0; i < insn->detail->evm.op_count; i++)
1359  if (insn->detail->evm.operands[i].type == (evm_op_type)op_type)
1360  count++;
1361 #endif
1362  break;
1363  }
1364 
1365  return count;
1366 }
1367 
1369 int CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type,
1370  unsigned int post)
1371 {
1372  struct cs_struct *handle;
1373  unsigned int count = 0, i;
1374  if (!ud)
1375  return -1;
1376 
1377  handle = (struct cs_struct *)(uintptr_t)ud;
1378 
1379  if (!handle->detail) {
1380  handle->errnum = CS_ERR_DETAIL;
1381  return -1;
1382  }
1383 
1384  if (!insn->id) {
1385  handle->errnum = CS_ERR_SKIPDATA;
1386  return -1;
1387  }
1388 
1389  if (!insn->detail) {
1390  handle->errnum = CS_ERR_DETAIL;
1391  return -1;
1392  }
1393 
1394  handle->errnum = CS_ERR_OK;
1395 
1396  switch (handle->arch) {
1397  default:
1398  handle->errnum = CS_ERR_HANDLE;
1399  return -1;
1400  case CS_ARCH_ARM:
1401  for (i = 0; i < insn->detail->arm.op_count; i++) {
1402  if (insn->detail->arm.operands[i].type == (arm_op_type)op_type)
1403  count++;
1404  if (count == post)
1405  return i;
1406  }
1407  break;
1408  case CS_ARCH_ARM64:
1409  for (i = 0; i < insn->detail->arm64.op_count; i++) {
1410  if (insn->detail->arm64.operands[i].type == (arm64_op_type)op_type)
1411  count++;
1412  if (count == post)
1413  return i;
1414  }
1415  break;
1416  case CS_ARCH_X86:
1417  for (i = 0; i < insn->detail->x86.op_count; i++) {
1418  if (insn->detail->x86.operands[i].type == (x86_op_type)op_type)
1419  count++;
1420  if (count == post)
1421  return i;
1422  }
1423  break;
1424  case CS_ARCH_MIPS:
1425  for (i = 0; i < insn->detail->mips.op_count; i++) {
1426  if (insn->detail->mips.operands[i].type == (mips_op_type)op_type)
1427  count++;
1428  if (count == post)
1429  return i;
1430  }
1431  break;
1432  case CS_ARCH_PPC:
1433  for (i = 0; i < insn->detail->ppc.op_count; i++) {
1434  if (insn->detail->ppc.operands[i].type == (ppc_op_type)op_type)
1435  count++;
1436  if (count == post)
1437  return i;
1438  }
1439  break;
1440  case CS_ARCH_SPARC:
1441  for (i = 0; i < insn->detail->sparc.op_count; i++) {
1442  if (insn->detail->sparc.operands[i].type == (sparc_op_type)op_type)
1443  count++;
1444  if (count == post)
1445  return i;
1446  }
1447  break;
1448  case CS_ARCH_SYSZ:
1449  for (i = 0; i < insn->detail->sysz.op_count; i++) {
1450  if (insn->detail->sysz.operands[i].type == (sysz_op_type)op_type)
1451  count++;
1452  if (count == post)
1453  return i;
1454  }
1455  break;
1456  case CS_ARCH_XCORE:
1457  for (i = 0; i < insn->detail->xcore.op_count; i++) {
1458  if (insn->detail->xcore.operands[i].type == (xcore_op_type)op_type)
1459  count++;
1460  if (count == post)
1461  return i;
1462  }
1463  break;
1464  case CS_ARCH_M68K:
1465  for (i = 0; i < insn->detail->m68k.op_count; i++) {
1466  if (insn->detail->m68k.operands[i].type == (m68k_op_type)op_type)
1467  count++;
1468  if (count == post)
1469  return i;
1470  }
1471  break;
1472  case CS_ARCH_TMS320C64X:
1473  for (i = 0; i < insn->detail->tms320c64x.op_count; i++) {
1474  if (insn->detail->tms320c64x.operands[i].type == (tms320c64x_op_type)op_type)
1475  count++;
1476  if (count == post)
1477  return i;
1478  }
1479  break;
1480  case CS_ARCH_M680X:
1481  for (i = 0; i < insn->detail->m680x.op_count; i++) {
1482  if (insn->detail->m680x.operands[i].type == (m680x_op_type)op_type)
1483  count++;
1484  if (count == post)
1485  return i;
1486  }
1487  break;
1488  case CS_ARCH_EVM:
1489 #if 0
1490  for (i = 0; i < insn->detail->evm.op_count; i++) {
1491  if (insn->detail->evm.operands[i].type == (evm_op_type)op_type)
1492  count++;
1493  if (count == post)
1494  return i;
1495  }
1496 #endif
1497  break;
1498  }
1499 
1500  return -1;
1501 }
1502 
1504 cs_err CAPSTONE_API cs_regs_access(csh ud, const cs_insn *insn,
1505  cs_regs regs_read, uint8_t *regs_read_count,
1506  cs_regs regs_write, uint8_t *regs_write_count)
1507 {
1508  struct cs_struct *handle;
1509 
1510  if (!ud)
1511  return -1;
1512 
1513  handle = (struct cs_struct *)(uintptr_t)ud;
1514 
1515 #ifdef CAPSTONE_DIET
1516  // This API does not work in DIET mode
1517  handle->errnum = CS_ERR_DIET;
1518  return CS_ERR_DIET;
1519 #else
1520  if (!handle->detail) {
1521  handle->errnum = CS_ERR_DETAIL;
1522  return CS_ERR_DETAIL;
1523  }
1524 
1525  if (!insn->id) {
1526  handle->errnum = CS_ERR_SKIPDATA;
1527  return CS_ERR_SKIPDATA;
1528  }
1529 
1530  if (!insn->detail) {
1531  handle->errnum = CS_ERR_DETAIL;
1532  return CS_ERR_DETAIL;
1533  }
1534 
1535  if (handle->reg_access) {
1536  handle->reg_access(insn, regs_read, regs_read_count, regs_write, regs_write_count);
1537  } else {
1538  // this arch is unsupported yet
1539  handle->errnum = CS_ERR_ARCH;
1540  return CS_ERR_ARCH;
1541  }
1542 
1543  return CS_ERR_OK;
1544 #endif
1545 }
size_t len
Definition: 6502dis.c:15
#define mnem(n, mn)
cs_err AArch64_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err AArch64_global_init(cs_struct *ud)
cs_err ARM_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err ARM_global_init(cs_struct *ud)
cs_err EVM_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err EVM_global_init(cs_struct *ud)
cs_err M680X_global_init(cs_struct *ud)
cs_err M680X_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err M68K_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err M68K_global_init(cs_struct *ud)
unsigned MCInst_getOpcodePub(const MCInst *inst)
Definition: MCInst.c:73
void MCInst_Init(MCInst *inst)
Definition: MCInst.c:18
cs_err Mips_global_init(cs_struct *ud)
cs_err Mips_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err PPC_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err PPC_global_init(cs_struct *ud)
void SStream_Init(SStream *ss)
Definition: SStream.c:25
cs_err Sparc_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err Sparc_global_init(cs_struct *ud)
cs_err SystemZ_global_init(cs_struct *ud)
cs_err SystemZ_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err TMS320C64x_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err TMS320C64x_global_init(cs_struct *ud)
cs_err X86_option(cs_struct *handle, cs_opt_type type, size_t value)
cs_err X86_global_init(cs_struct *ud)
cs_err XCore_global_init(cs_struct *ud)
cs_err XCore_option(cs_struct *handle, cs_opt_type type, size_t value)
#define CAPSTONE_HAS_TMS320C64X
lzma_index ** i
Definition: index.h:629
static bool err
Definition: armass.c:435
static mcore_handle handle
Definition: asm_mcore.c:8
static int opstr(RzAsm *a, ut8 *data, const Opcode *op)
Definition: asm_x86_nz.c:4054
struct buffer buffer
arm64_op_type
Operand type for instruction's operands.
Definition: arm64.h:233
arm_op_type
Operand type for instruction's operands.
Definition: arm.h:161
#define CAPSTONE_EXPORT
Definition: capstone.h:36
cs_arch
Architecture type.
Definition: capstone.h:74
@ CS_ARCH_ARM64
ARM-64, also called AArch64.
Definition: capstone.h:76
@ CS_ARCH_SPARC
Sparc architecture.
Definition: capstone.h:80
@ CS_ARCH_XCORE
XCore architecture.
Definition: capstone.h:82
@ CS_ARCH_MAX
Definition: capstone.h:87
@ CS_ARCH_M68K
68K architecture
Definition: capstone.h:83
@ CS_ARCH_X86
X86 architecture (including x86 & x86-64)
Definition: capstone.h:78
@ CS_ARCH_ALL
Definition: capstone.h:88
@ CS_ARCH_M680X
680X architecture
Definition: capstone.h:85
@ CS_ARCH_ARM
ARM architecture (including Thumb, Thumb-2)
Definition: capstone.h:75
@ CS_ARCH_MIPS
Mips architecture.
Definition: capstone.h:77
@ CS_ARCH_SYSZ
SystemZ architecture.
Definition: capstone.h:81
@ CS_ARCH_TMS320C64X
TMS320C64x architecture.
Definition: capstone.h:84
@ CS_ARCH_EVM
Ethereum architecture.
Definition: capstone.h:86
@ CS_ARCH_PPC
PowerPC architecture.
Definition: capstone.h:79
#define CS_SUPPORT_X86_REDUCE
Definition: capstone.h:99
cs_mode
Mode type.
Definition: capstone.h:102
@ CS_MODE_M680X_6811
M680X Motorola/Freescale/NXP 68HC11 mode.
Definition: capstone.h:133
@ CS_MODE_M680X_6805
M680X Motorola/Freescale 6805 mode.
Definition: capstone.h:130
@ CS_MODE_MCLASS
ARM's Cortex-M series.
Definition: capstone.h:109
@ CS_MODE_M680X_HCS08
M680X Freescale/NXP HCS08 mode.
Definition: capstone.h:136
@ CS_MODE_64
64-bit mode (X86, PPC)
Definition: capstone.h:107
@ CS_MODE_M68K_040
M68K 68040 mode.
Definition: capstone.h:121
@ CS_MODE_M680X_6309
M680X Hitachi 6309 mode.
Definition: capstone.h:127
@ CS_MODE_M68K_000
M68K 68000 mode.
Definition: capstone.h:117
@ CS_MODE_32
32-bit mode (X86)
Definition: capstone.h:106
@ CS_MODE_ARM
32-bit ARM
Definition: capstone.h:104
@ CS_MODE_V8
ARMv8 A32 encodings for ARM.
Definition: capstone.h:110
@ CS_MODE_MICRO
MicroMips mode (MIPS)
Definition: capstone.h:111
@ CS_MODE_M680X_CPU12
used on M68HC12/HCS12
Definition: capstone.h:134
@ CS_MODE_M68K_060
M68K 68060 mode.
Definition: capstone.h:122
@ CS_MODE_MIPS3
Mips III ISA.
Definition: capstone.h:112
@ CS_MODE_M68K_010
M68K 68010 mode.
Definition: capstone.h:118
@ CS_MODE_M680X_6301
M680X Hitachi 6301,6303 mode.
Definition: capstone.h:126
@ CS_MODE_MIPS32R6
Mips32r6 ISA.
Definition: capstone.h:113
@ CS_MODE_M680X_6801
M680X Motorola 6801,6803 mode.
Definition: capstone.h:129
@ CS_MODE_BIG_ENDIAN
big-endian mode
Definition: capstone.h:123
@ CS_MODE_16
16-bit mode (X86)
Definition: capstone.h:105
@ CS_MODE_V9
SparcV9 mode (Sparc)
Definition: capstone.h:115
@ CS_MODE_M68K_020
M68K 68020 mode.
Definition: capstone.h:119
@ CS_MODE_THUMB
ARM's Thumb mode, including Thumb-2.
Definition: capstone.h:108
@ CS_MODE_M680X_6800
M680X Motorola 6800,6802 mode.
Definition: capstone.h:128
@ CS_MODE_M68K_030
M68K 68030 mode.
Definition: capstone.h:120
@ CS_MODE_M680X_6808
M680X Motorola/Freescale/NXP 68HC08 mode.
Definition: capstone.h:131
@ CS_MODE_QPX
Quad Processing eXtensions mode (PPC)
Definition: capstone.h:116
@ CS_MODE_LITTLE_ENDIAN
little-endian mode (default mode)
Definition: capstone.h:103
@ CS_MODE_MIPS2
Mips II ISA.
Definition: capstone.h:114
@ CS_MODE_M680X_6809
M680X Motorola 6809 mode.
Definition: capstone.h:132
cs_opt_type
Runtime option for the disassembled engine.
Definition: capstone.h:168
@ CS_OPT_SKIPDATA_SETUP
Setup user-defined function for SKIPDATA option.
Definition: capstone.h:175
@ CS_OPT_UNSIGNED
print immediate operands in unsigned form
Definition: capstone.h:177
@ CS_OPT_MEM
User-defined dynamic memory related functions.
Definition: capstone.h:173
@ CS_OPT_MODE
Change engine's mode at run-time.
Definition: capstone.h:172
@ CS_OPT_DETAIL
Break down instruction structure into details.
Definition: capstone.h:171
@ CS_OPT_SKIPDATA
Skip data when disassembling. Then engine is in SKIPDATA mode.
Definition: capstone.h:174
@ CS_OPT_MNEMONIC
Customize instruction mnemonic.
Definition: capstone.h:176
size_t csh
Definition: capstone.h:71
void(CAPSTONE_API * cs_free_t)(void *ptr)
Definition: capstone.h:142
cs_opt_value
Runtime option value (associated with option type above)
Definition: capstone.h:181
@ CS_OPT_ON
Turn ON an option (CS_OPT_DETAIL, CS_OPT_SKIPDATA).
Definition: capstone.h:183
@ CS_OPT_OFF
Turn OFF an option - default for CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED.
Definition: capstone.h:182
#define CS_SUPPORT_DIET
Definition: capstone.h:94
#define CAPSTONE_API
Definition: capstone.h:32
void *(CAPSTONE_API * cs_malloc_t)(size_t size)
Definition: capstone.h:139
void *(CAPSTONE_API * cs_calloc_t)(size_t nmemb, size_t size)
Definition: capstone.h:140
int(CAPSTONE_API * cs_vsnprintf_t)(char *str, size_t size, const char *format, va_list ap)
Definition: capstone.h:143
#define CAPSTONE_DEPRECATED
Definition: capstone.h:46
void *(CAPSTONE_API * cs_realloc_t)(void *ptr, size_t size)
Definition: capstone.h:141
#define CS_API_MINOR
Definition: capstone.h:51
#define CS_API_MAJOR
Definition: capstone.h:50
sysz_op_type
Operand type for instruction's operands.
Definition: systemz.h:38
x86_op_type
Operand type for instruction's operands.
Definition: x86.h:158
xcore_op_type
Operand type for instruction's operands.
Definition: xcore.h:18
static int value
Definition: cmd_api.c:93
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
cs_free_t cs_mem_free
Definition: cs.c:351
cs_malloc_t cs_mem_malloc
Definition: cs.c:348
CAPSTONE_EXPORT unsigned int CAPSTONE_API cs_version(int *major, int *minor)
Definition: cs.c:357
CAPSTONE_EXPORT bool CAPSTONE_API cs_support(int query)
Definition: cs.c:368
cs_realloc_t cs_mem_realloc
Definition: cs.c:350
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_regs_access(csh ud, const cs_insn *insn, cs_regs regs_read, uint8_t *regs_read_count, cs_regs regs_write, uint8_t *regs_write_count)
Definition: cs.c:1504
static cs_mode cs_arch_disallowed_mode_mask[MAX_ARCH]
Definition: cs.c:198
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_errno(csh handle)
Definition: cs.c:402
#define INSN_CACHE_SIZE
Definition: cs.c:42
CAPSTONE_EXPORT size_t CAPSTONE_API cs_disasm(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
Definition: cs.c:798
CAPSTONE_EXPORT const char *CAPSTONE_API cs_group_name(csh ud, unsigned int group)
Definition: cs.c:1178
static void skipdata_opstr(char *opstr, const uint8_t *buffer, size_t size)
Definition: cs.c:765
cs_vsnprintf_t cs_vsnprintf
Definition: cs.c:352
CAPSTONE_EXPORT bool CAPSTONE_API cs_reg_read(csh ud, const cs_insn *insn, unsigned int reg_id)
Definition: cs.c:1217
CAPSTONE_EXPORT const char *CAPSTONE_API cs_strerror(cs_err code)
Definition: cs.c:414
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_open(cs_arch arch, cs_mode mode, csh *handle)
Definition: cs.c:453
static cs_err(* cs_arch_init[MAX_ARCH])(cs_struct *)
Definition: cs.c:69
cs_calloc_t cs_mem_calloc
Definition: cs.c:349
CAPSTONE_EXPORT bool CAPSTONE_API cs_insn_group(csh ud, const cs_insn *insn, unsigned int group_id)
Definition: cs.c:1190
CAPSTONE_EXPORT int CAPSTONE_API cs_op_count(csh ud, const cs_insn *insn, unsigned int op_type)
Definition: cs.c:1271
CAPSTONE_EXPORT const char *CAPSTONE_API cs_insn_name(csh ud, unsigned int insn)
Definition: cs.c:1166
CAPSTONE_EXPORT void CAPSTONE_API cs_free(cs_insn *insn, size_t count)
Definition: cs.c:1017
static cs_err(* cs_arch_option[MAX_ARCH])(cs_struct *, cs_opt_type, size_t value)
Definition: cs.c:133
CAPSTONE_EXPORT const char *CAPSTONE_API cs_reg_name(csh ud, unsigned int reg)
Definition: cs.c:1154
CAPSTONE_EXPORT bool CAPSTONE_API cs_reg_write(csh ud, const cs_insn *insn, unsigned int reg_id)
Definition: cs.c:1244
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_close(csh *handle)
Definition: cs.c:501
static void fill_insn(struct cs_struct *handle, cs_insn *insn, char *buffer, MCInst *mci, PostPrinter_t postprinter, const uint8_t *code)
Definition: cs.c:536
CAPSTONE_EXPORT int CAPSTONE_API cs_op_index(csh ud, const cs_insn *insn, unsigned int op_type, unsigned int post)
Definition: cs.c:1369
static uint8_t skipdata_size(cs_struct *handle)
Definition: cs.c:601
static uint32_t all_arch
Definition: cs.c:269
#define SKIPDATA_MNEM
Definition: cs.c:50
CAPSTONE_EXPORT cs_insn *CAPSTONE_API cs_malloc(csh ud)
Definition: cs.c:1030
CAPSTONE_EXPORT bool CAPSTONE_API cs_disasm_iter(csh ud, const uint8_t **code, size_t *size, uint64_t *address, cs_insn *insn)
Definition: cs.c:1058
CAPSTONE_EXPORT CAPSTONE_DEPRECATED size_t CAPSTONE_API cs_disasm_ex(csh ud, const uint8_t *buffer, size_t size, uint64_t offset, size_t count, cs_insn **insn)
Definition: cs.c:1011
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_option(csh ud, cs_opt_type type, size_t value)
Definition: cs.c:646
void(* PostPrinter_t)(csh handle, cs_insn *, char *mnem, MCInst *mci)
Definition: cs_priv.h:19
#define MAX_ARCH
Definition: cs_priv.h:81
cs_arch arch
Definition: cstool.c:13
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
#define minor(dev)
Definition: fsmagic.c:57
#define major(dev)
Definition: fsmagic.c:56
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
const char int mode
Definition: ioapi.h:137
vsnprintf
Definition: kernel.h:366
#define reg(n)
return memset(p, 0, total)
void * p
Definition: libc.cpp:67
void * mem
Definition: libc.cpp:91
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
void * malloc(size_t size)
Definition: malloc.c:123
void * calloc(size_t number, size_t size)
Definition: malloc.c:102
static static fork const void static count static fd const char const char static newpath char char char static envp time_t static t const char static mode static whence const char static dir time_t static t unsigned static seconds const char struct utimbuf static buf static inc static sig const char static mode static oldfd struct tms static buf static getgid static geteuid const char static filename static arg static mask struct ustat static ubuf static getppid static setsid static egid sigset_t static set struct timeval struct timezone static tz fd_set fd_set fd_set struct timeval static timeout const char char static bufsiz const char static swapflags void static offset const char static length static mode static who const char struct statfs static buf unsigned unsigned num
Definition: sflib.h:126
m680x_op_type
Operand type for instruction's operands.
Definition: m680x.h:55
m68k_op_type
Operand type for instruction's operands.
Definition: m68k.h:112
int type
Definition: mipsasm.c:17
int CS_ERR_CSH
Definition: __init__.py:239
int CS_ERR_SKIPDATA
Definition: __init__.py:246
int CS_ERR_MEMSETUP
Definition: __init__.py:243
int CS_ERR_X86_MASM
Definition: __init__.py:249
int CS_ERR_MEM
Definition: __init__.py:236
int CS_ERR_DIET
Definition: __init__.py:245
int CS_ERR_X86_ATT
Definition: __init__.py:247
int CS_ERR_X86_INTEL
Definition: __init__.py:248
int CS_ERR_OPTION
Definition: __init__.py:241
int CS_ERR_VERSION
Definition: __init__.py:244
int CS_ERR_HANDLE
Definition: __init__.py:238
int CS_ERR_OK
Definition: __init__.py:235
int CS_ERR_ARCH
Definition: __init__.py:237
int CS_ERR_MODE
Definition: __init__.py:240
int CS_ERR_DETAIL
Definition: __init__.py:242
static int
Definition: sfsocketcall.h:114
unsigned short uint16_t
Definition: sftypes.h:30
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
#define f(i)
Definition: sha256.c:46
#define c(i)
Definition: sha256.c:43
_W64 unsigned int uintptr_t
Definition: MCInst.h:88
cs_insn * flat_insn
Definition: MCInst.h:95
cs_struct * csh
Definition: MCInst.h:97
unsigned Opcode
Definition: MCInst.h:93
uint8_t popcode_adjust
Definition: MCInst.h:108
uint64_t address
Definition: MCInst.h:96
Definition: SStream.h:9
char buffer[512]
Definition: SStream.h:10
Definition: buffer.h:15
Definition: inftree9.h:24
const char * mnemonic
Customized instruction mnemonic.
Definition: capstone.h:164
unsigned int id
ID of instruction to be customized.
Definition: capstone.h:162
cs_err errnum
Definition: cs_priv.h:66
void * printer_info
Definition: cs_priv.h:58
unsigned short * insn_cache
Definition: cs_priv.h:71
struct insn_mnem * mnem_list
Definition: cs_priv.h:78
cs_mode mode
Definition: cs_priv.h:56
cs_opt_skipdata skipdata_setup
Definition: cs_priv.h:75
cs_opt_value detail
Definition: cs_priv.h:68
cs_arch arch
Definition: cs_priv.h:55
char mnemonic[CS_MNEMONIC_SIZE]
Definition: cs_priv.h:46
unsigned int id
Definition: cs_priv.h:44
struct insn_mnem * next
Definition: cs_priv.h:51
struct customized_mnem insn
Definition: cs_priv.h:50
mips_op_type
Operand type for instruction's operands.
Definition: mips.h:22
ppc_op_type
Operand type for instruction's operands.
Definition: ppc.h:42
sparc_op_type
Operand type for instruction's operands.
Definition: sparc.h:70
int cs_snprintf(char *buffer, size_t size, const char *fmt,...)
Definition: utils.c:104
bool arr_exist8(unsigned char *arr, unsigned char max, unsigned int id)
Definition: utils.c:116
bool arr_exist(uint16_t *arr, unsigned char max, unsigned int id)
Definition: utils.c:128
#define MIN(x, y)
Definition: utils.h:59
static void post(QUEUE *q, enum uv__work_kind kind)
Definition: threadpool.c:142
tms320c64x_op_type
Definition: tms320c64x.h:18
void *CAPSTONE_API cs_winkernel_realloc(void *ptr, size_t size)
Definition: winkernel_mm.c:69
int CAPSTONE_API cs_winkernel_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr)
Definition: winkernel_mm.c:99
void CAPSTONE_API cs_winkernel_free(void *ptr)
Definition: winkernel_mm.c:21
void *CAPSTONE_API cs_winkernel_calloc(size_t n, size_t size)
Definition: winkernel_mm.c:56
void *CAPSTONE_API cs_winkernel_malloc(size_t size)
Definition: winkernel_mm.c:29
static int sp
Definition: z80asm.c:91
static int addr
Definition: z80asm.c:58