Rizin
unix-like reverse engineering framework and cli tools
cs.c File Reference
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <capstone/capstone.h>
#include "utils.h"
#include "MCRegisterInfo.h"
#include "arch/AArch64/AArch64Module.h"
#include "arch/ARM/ARMModule.h"
#include "arch/EVM/EVMModule.h"
#include "arch/M680X/M680XModule.h"
#include "arch/M68K/M68KModule.h"
#include "arch/Mips/MipsModule.h"
#include "arch/PowerPC/PPCModule.h"
#include "arch/Sparc/SparcModule.h"
#include "arch/SystemZ/SystemZModule.h"
#include "arch/TMS320C64x/TMS320C64xModule.h"
#include "arch/X86/X86Module.h"
#include "arch/XCore/XCoreModule.h"

Go to the source code of this file.

Macros

#define INSN_CACHE_SIZE   32
 
#define SKIPDATA_MNEM   ".byte"
 

Functions

CAPSTONE_EXPORT unsigned int CAPSTONE_API cs_version (int *major, int *minor)
 
CAPSTONE_EXPORT bool CAPSTONE_API cs_support (int query)
 
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_errno (csh handle)
 
CAPSTONE_EXPORT const char *CAPSTONE_API cs_strerror (cs_err code)
 
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_open (cs_arch arch, cs_mode mode, csh *handle)
 
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_close (csh *handle)
 
static void fill_insn (struct cs_struct *handle, cs_insn *insn, char *buffer, MCInst *mci, PostPrinter_t postprinter, const uint8_t *code)
 
static uint8_t skipdata_size (cs_struct *handle)
 
CAPSTONE_EXPORT cs_err CAPSTONE_API cs_option (csh ud, cs_opt_type type, size_t value)
 
static void skipdata_opstr (char *opstr, const uint8_t *buffer, size_t size)
 
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)
 
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)
 
CAPSTONE_EXPORT void CAPSTONE_API cs_free (cs_insn *insn, size_t count)
 
CAPSTONE_EXPORT cs_insn *CAPSTONE_API cs_malloc (csh ud)
 
CAPSTONE_EXPORT bool CAPSTONE_API cs_disasm_iter (csh ud, const uint8_t **code, size_t *size, uint64_t *address, cs_insn *insn)
 
CAPSTONE_EXPORT const char *CAPSTONE_API cs_reg_name (csh ud, unsigned int reg)
 
CAPSTONE_EXPORT const char *CAPSTONE_API cs_insn_name (csh ud, unsigned int insn)
 
CAPSTONE_EXPORT const char *CAPSTONE_API cs_group_name (csh ud, unsigned int group)
 
CAPSTONE_EXPORT bool CAPSTONE_API cs_insn_group (csh ud, const cs_insn *insn, unsigned int group_id)
 
CAPSTONE_EXPORT bool CAPSTONE_API cs_reg_read (csh ud, const cs_insn *insn, unsigned int reg_id)
 
CAPSTONE_EXPORT bool CAPSTONE_API cs_reg_write (csh ud, const cs_insn *insn, unsigned int reg_id)
 
CAPSTONE_EXPORT int CAPSTONE_API cs_op_count (csh ud, const cs_insn *insn, unsigned int op_type)
 
CAPSTONE_EXPORT int CAPSTONE_API cs_op_index (csh ud, const cs_insn *insn, unsigned int op_type, unsigned int post)
 
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)
 

Variables

static cs_err(* cs_arch_init [MAX_ARCH])(cs_struct *)
 
static cs_err(* cs_arch_option [MAX_ARCH])(cs_struct *, cs_opt_type, size_t value)
 
static cs_mode cs_arch_disallowed_mode_mask [MAX_ARCH]
 
static uint32_t all_arch = 0
 
cs_malloc_t cs_mem_malloc = NULL
 
cs_calloc_t cs_mem_calloc = NULL
 
cs_realloc_t cs_mem_realloc = NULL
 
cs_free_t cs_mem_free = NULL
 
cs_vsnprintf_t cs_vsnprintf = NULL
 

Macro Definition Documentation

◆ INSN_CACHE_SIZE

#define INSN_CACHE_SIZE   32

Definition at line 42 of file cs.c.

◆ SKIPDATA_MNEM

#define SKIPDATA_MNEM   ".byte"

Definition at line 50 of file cs.c.

Function Documentation

◆ cs_close()

CAPSTONE_EXPORT cs_err CAPSTONE_API cs_close ( csh handle)

Definition at line 501 of file cs.c.

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 }
static mcore_handle handle
Definition: asm_mcore.c:8
cs_free_t cs_mem_free
Definition: cs.c:351
return memset(p, 0, total)
int CS_ERR_CSH
Definition: __init__.py:239
int CS_ERR_OK
Definition: __init__.py:235
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
struct insn_mnem * next
Definition: cs_priv.h:51

References capstone::CS_ERR_CSH, capstone::CS_ERR_OK, cs_mem_free, handle, cs_struct::insn_cache, memset(), cs_struct::mnem_list, insn_mnem::next, cs_struct::printer_info, and autogen_x86imm::tmp.

Referenced by analop(), analysis_op(), arm_fini(), bs_close(), cs_driver_hello(), disassemble(), fini(), LLVMFuzzerTestOneInput(), main(), ocaml_close(), test(), test_invalids(), test_valids(), the_end(), tms320_fini(), and x86_fini().

◆ cs_disasm()

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 at line 798 of file cs.c.

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 }
void MCInst_Init(MCInst *inst)
Definition: MCInst.c:18
void SStream_Init(SStream *ss)
Definition: SStream.c:25
lzma_index ** i
Definition: index.h:629
struct buffer buffer
@ CS_ARCH_X86
X86 architecture (including x86 & x86-64)
Definition: capstone.h:78
@ CS_ARCH_ARM
ARM architecture (including Thumb, Thumb-2)
Definition: capstone.h:75
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
cs_realloc_t cs_mem_realloc
Definition: cs.c:350
#define INSN_CACHE_SIZE
Definition: cs.c:42
static void skipdata_opstr(char *opstr, const uint8_t *buffer, size_t size)
Definition: cs.c:765
cs_calloc_t cs_mem_calloc
Definition: cs.c:349
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
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
voidpf void uLong size
Definition: ioapi.h:138
voidpf uLong offset
Definition: ioapi.h:144
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
int CS_ERR_MEM
Definition: __init__.py:236
static int
Definition: sfsocketcall.h:114
unsigned short uint16_t
Definition: sftypes.h:30
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

References MCInst::address, SStream::buffer, c, count, CS_ARCH_ARM, CS_ARCH_X86, capstone::CS_ERR_MEM, capstone::CS_ERR_OK, cs_mem_calloc, cs_mem_free, cs_mem_realloc, MCInst::csh, f, fill_insn(), MCInst::flat_insn, handle, i, cs_struct::insn_cache, INSN_CACHE_SIZE, int, MCInst_Init(), memcpy(), memset(), NULL, MCInst::Opcode, MCInst::popcode_adjust, r, skipdata_opstr(), SStream_Init(), and autogen_x86imm::tmp.

Referenced by _cs_disasm(), analop(), analysis_op(), bs_disasm(), cs_disasm_ex(), cs_driver_hello(), disassemble(), LLVMFuzzerTestOneInput(), main(), print_insn(), test(), test_invalids(), and test_valids().

◆ cs_disasm_ex()

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 at line 1011 of file cs.c.

1012 {
1013  return cs_disasm(ud, buffer, size, offset, count, insn);
1014 }
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

References count, and cs_disasm().

◆ cs_disasm_iter()

CAPSTONE_EXPORT bool CAPSTONE_API cs_disasm_iter ( csh  ud,
const uint8_t **  code,
size_t size,
uint64_t address,
cs_insn *  insn 
)

Definition at line 1058 of file cs.c.

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 }
Definition: inftree9.h:24

References MCInst::address, SStream::buffer, CS_ARCH_X86, capstone::CS_ERR_OK, MCInst::csh, fill_insn(), MCInst::flat_insn, handle, MCInst_Init(), memcpy(), MCInst::Opcode, MCInst::popcode_adjust, r, skipdata_opstr(), and SStream_Init().

Referenced by bs_disasm_iter(), LLVMFuzzerTestOneInput(), and test().

◆ cs_errno()

CAPSTONE_EXPORT cs_err CAPSTONE_API cs_errno ( csh  handle)

Definition at line 402 of file cs.c.

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 }
cs_err errnum
Definition: cs_priv.h:66

References capstone::CS_ERR_CSH, cs_struct::errnum, and handle.

Referenced by bs_errno().

◆ cs_free()

CAPSTONE_EXPORT void CAPSTONE_API cs_free ( cs_insn *  insn,
size_t  count 
)

Definition at line 1017 of file cs.c.

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 }

References count, cs_mem_free, and i.

Referenced by _cs_disasm(), analop(), analysis_op(), bs_free(), cs_driver_hello(), disassemble(), LLVMFuzzerTestOneInput(), main(), print_insn(), test(), test_invalids(), and test_valids().

◆ cs_group_name()

CAPSTONE_EXPORT const char* CAPSTONE_API cs_group_name ( csh  ud,
unsigned int  group 
)

Definition at line 1178 of file cs.c.

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 }

References handle, and NULL.

Referenced by bcs_group_name(), check_features(), LLVMFuzzerTestOneInput(), main(), ocaml_group_name(), print_details(), print_insn_detail(), and test().

◆ cs_insn_group()

CAPSTONE_EXPORT bool CAPSTONE_API cs_insn_group ( csh  ud,
const cs_insn *  insn,
unsigned int  group_id 
)

Definition at line 1190 of file cs.c.

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 }
int CS_ERR_SKIPDATA
Definition: __init__.py:246
int CS_ERR_DETAIL
Definition: __init__.py:242
bool arr_exist8(unsigned char *arr, unsigned char max, unsigned int id)
Definition: utils.c:116

References arr_exist8(), capstone::CS_ERR_DETAIL, capstone::CS_ERR_SKIPDATA, and handle.

Referenced by analop(), anop(), anop32(), anop64(), and bs_insn_group().

◆ cs_insn_name()

CAPSTONE_EXPORT const char* CAPSTONE_API cs_insn_name ( csh  ud,
unsigned int  insn 
)

Definition at line 1166 of file cs.c.

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 }

References handle, and NULL.

Referenced by bs_insn_name(), disassemble(), LLVMFuzzerTestOneInput(), main(), mnemonics(), ocaml_instruction_name(), print_details(), and test().

◆ cs_malloc()

CAPSTONE_EXPORT cs_insn* CAPSTONE_API cs_malloc ( csh  ud)

Definition at line 1030 of file cs.c.

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 }
cs_malloc_t cs_mem_malloc
Definition: cs.c:348

References capstone::CS_ERR_MEM, cs_mem_free, cs_mem_malloc, handle, and NULL.

Referenced by bs_malloc(), LLVMFuzzerTestOneInput(), and test().

◆ cs_op_count()

CAPSTONE_EXPORT int CAPSTONE_API cs_op_count ( csh  ud,
const cs_insn *  insn,
unsigned int  op_type 
)

Definition at line 1271 of file cs.c.

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 }
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
@ 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_M68K
68K architecture
Definition: capstone.h:83
@ CS_ARCH_M680X
680X architecture
Definition: capstone.h:85
@ 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
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
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 CS_ERR_HANDLE
Definition: __init__.py:238
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
tms320c64x_op_type
Definition: tms320c64x.h:18

References count, CS_ARCH_ARM, CS_ARCH_ARM64, CS_ARCH_EVM, CS_ARCH_M680X, CS_ARCH_M68K, CS_ARCH_MIPS, CS_ARCH_PPC, CS_ARCH_SPARC, CS_ARCH_SYSZ, CS_ARCH_TMS320C64X, CS_ARCH_X86, CS_ARCH_XCORE, capstone::CS_ERR_DETAIL, capstone::CS_ERR_HANDLE, capstone::CS_ERR_OK, capstone::CS_ERR_SKIPDATA, handle, and i.

Referenced by bs_op_count(), print_insn_detail(), and print_insn_detail_x86().

◆ cs_op_index()

CAPSTONE_EXPORT int CAPSTONE_API cs_op_index ( csh  ud,
const cs_insn *  insn,
unsigned int  op_type,
unsigned int  post 
)

Definition at line 1369 of file cs.c.

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 }
static void post(QUEUE *q, enum uv__work_kind kind)
Definition: threadpool.c:142

References count, CS_ARCH_ARM, CS_ARCH_ARM64, CS_ARCH_EVM, CS_ARCH_M680X, CS_ARCH_M68K, CS_ARCH_MIPS, CS_ARCH_PPC, CS_ARCH_SPARC, CS_ARCH_SYSZ, CS_ARCH_TMS320C64X, CS_ARCH_X86, CS_ARCH_XCORE, capstone::CS_ERR_DETAIL, capstone::CS_ERR_HANDLE, capstone::CS_ERR_OK, capstone::CS_ERR_SKIPDATA, handle, i, and post().

Referenced by bs_op_index(), print_insn_detail(), and print_insn_detail_x86().

◆ cs_open()

CAPSTONE_EXPORT cs_err CAPSTONE_API cs_open ( cs_arch  arch,
cs_mode  mode,
csh handle 
)

Definition at line 453 of file cs.c.

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 }
static bool err
Definition: armass.c:435
@ CS_ARCH_MAX
Definition: capstone.h:87
@ CS_OPT_OFF
Turn OFF an option - default for CS_OPT_DETAIL, CS_OPT_SKIPDATA, CS_OPT_UNSIGNED.
Definition: capstone.h:182
static cs_mode cs_arch_disallowed_mode_mask[MAX_ARCH]
Definition: cs.c:198
cs_vsnprintf_t cs_vsnprintf
Definition: cs.c:352
static cs_err(* cs_arch_init[MAX_ARCH])(cs_struct *)
Definition: cs.c:69
#define SKIPDATA_MNEM
Definition: cs.c:50
cs_arch arch
Definition: cstool.c:13
const char int mode
Definition: ioapi.h:137
int CS_ERR_MEMSETUP
Definition: __init__.py:243
int CS_ERR_ARCH
Definition: __init__.py:237
int CS_ERR_MODE
Definition: __init__.py:240
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

References cs_struct::arch, arch, cs_arch_disallowed_mode_mask, cs_arch_init, CS_ARCH_MAX, capstone::CS_ERR_ARCH, capstone::CS_ERR_MEM, capstone::CS_ERR_MEMSETUP, capstone::CS_ERR_MODE, capstone::CS_ERR_OK, cs_mem_calloc, cs_mem_free, cs_mem_malloc, cs_mem_realloc, CS_OPT_OFF, cs_vsnprintf, cs_struct::detail, err, cs_struct::errnum, handle, cs_struct::mode, SKIPDATA_MNEM, and cs_struct::skipdata_setup.

Referenced by analop(), analysis_op(), bs_open(), cs_driver_hello(), disassemble(), LLVMFuzzerTestOneInput(), main(), ocaml_cs_disasm(), ocaml_open(), test(), test_invalids(), and test_valids().

◆ cs_option()

CAPSTONE_EXPORT cs_err CAPSTONE_API cs_option ( csh  ud,
cs_opt_type  type,
size_t  value 
)

Definition at line 646 of file cs.c.

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 }
@ 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
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
static int value
Definition: cmd_api.c:93
static cs_err(* cs_arch_option[MAX_ARCH])(cs_struct *, cs_opt_type, size_t value)
Definition: cs.c:133
static uint8_t skipdata_size(cs_struct *handle)
Definition: cs.c:601
void * mem
Definition: libc.cpp:91
int type
Definition: mipsasm.c:17
int CS_ERR_OPTION
Definition: __init__.py:241
const char * mnemonic
Customized instruction mnemonic.
Definition: capstone.h:164
unsigned int id
ID of instruction to be customized.
Definition: capstone.h:162

References cs_arch_disallowed_mode_mask, cs_arch_option, capstone::CS_ERR_CSH, capstone::CS_ERR_OK, capstone::CS_ERR_OPTION, cs_mem_calloc, cs_mem_free, cs_mem_malloc, cs_mem_realloc, CS_OPT_DETAIL, CS_OPT_MEM, CS_OPT_MNEMONIC, CS_OPT_MODE, CS_OPT_ON, CS_OPT_SKIPDATA, CS_OPT_SKIPDATA_SETUP, CS_OPT_UNSIGNED, cs_vsnprintf, handle, cs_opt_mnem::id, mem, cs_opt_mnem::mnemonic, insn_mnem::next, skipdata_size(), autogen_x86imm::tmp, type, and value.

Referenced by analop(), analysis_op(), bs_option(), disassemble(), LLVMFuzzerTestOneInput(), main(), ocaml_option(), test(), test_invalids(), and test_valids().

◆ cs_reg_name()

◆ cs_reg_read()

CAPSTONE_EXPORT bool CAPSTONE_API cs_reg_read ( csh  ud,
const cs_insn *  insn,
unsigned int  reg_id 
)

Definition at line 1217 of file cs.c.

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 }
bool arr_exist(uint16_t *arr, unsigned char max, unsigned int id)
Definition: utils.c:128

References arr_exist(), capstone::CS_ERR_DETAIL, capstone::CS_ERR_SKIPDATA, and handle.

Referenced by bs_reg_read().

◆ cs_reg_write()

CAPSTONE_EXPORT bool CAPSTONE_API cs_reg_write ( csh  ud,
const cs_insn *  insn,
unsigned int  reg_id 
)

Definition at line 1244 of file cs.c.

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 }

References arr_exist(), capstone::CS_ERR_DETAIL, capstone::CS_ERR_SKIPDATA, and handle.

Referenced by bs_reg_write().

◆ cs_regs_access()

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 at line 1504 of file cs.c.

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 }
int CS_ERR_DIET
Definition: __init__.py:245

References capstone::CS_ERR_ARCH, capstone::CS_ERR_DETAIL, capstone::CS_ERR_DIET, capstone::CS_ERR_OK, capstone::CS_ERR_SKIPDATA, and handle.

Referenced by print_insn_detail(), print_insn_detail_arm(), print_insn_detail_arm64(), print_insn_detail_x86(), and set_access_info().

◆ cs_strerror()

CAPSTONE_EXPORT const char* CAPSTONE_API cs_strerror ( cs_err  code)

Definition at line 414 of file cs.c.

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 }
int CS_ERR_X86_MASM
Definition: __init__.py:249
int CS_ERR_X86_ATT
Definition: __init__.py:247
int CS_ERR_X86_INTEL
Definition: __init__.py:248
int CS_ERR_VERSION
Definition: __init__.py:244

References capstone::CS_ERR_ARCH, capstone::CS_ERR_CSH, capstone::CS_ERR_DETAIL, capstone::CS_ERR_DIET, capstone::CS_ERR_HANDLE, capstone::CS_ERR_MEM, capstone::CS_ERR_MEMSETUP, capstone::CS_ERR_MODE, capstone::CS_ERR_OK, capstone::CS_ERR_OPTION, capstone::CS_ERR_SKIPDATA, capstone::CS_ERR_VERSION, capstone::CS_ERR_X86_ATT, capstone::CS_ERR_X86_INTEL, and capstone::CS_ERR_X86_MASM.

Referenced by bs_strerror().

◆ cs_support()

CAPSTONE_EXPORT bool CAPSTONE_API cs_support ( int  query)

Definition at line 368 of file cs.c.

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 }
@ CS_ARCH_ALL
Definition: capstone.h:88
#define CS_SUPPORT_X86_REDUCE
Definition: capstone.h:99
#define CS_SUPPORT_DIET
Definition: capstone.h:94
static uint32_t all_arch
Definition: cs.c:269

References all_arch, CS_ARCH_ALL, CS_ARCH_ARM, CS_ARCH_ARM64, CS_ARCH_EVM, CS_ARCH_M680X, CS_ARCH_M68K, CS_ARCH_MAX, CS_ARCH_MIPS, CS_ARCH_PPC, CS_ARCH_SPARC, CS_ARCH_SYSZ, CS_ARCH_TMS320C64X, CS_ARCH_X86, CS_ARCH_XCORE, CS_SUPPORT_DIET, and CS_SUPPORT_X86_REDUCE.

Referenced by bs_support(), main(), and usage().

◆ cs_version()

CAPSTONE_EXPORT unsigned int CAPSTONE_API cs_version ( int major,
int minor 
)

Definition at line 357 of file cs.c.

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 }
#define CS_API_MINOR
Definition: capstone.h:51
#define CS_API_MAJOR
Definition: capstone.h:50
#define minor(dev)
Definition: fsmagic.c:57
#define major(dev)
Definition: fsmagic.c:56

References CS_API_MAJOR, CS_API_MINOR, major, minor, and NULL.

Referenced by bs_version(), and ocaml_version().

◆ fill_insn()

static void fill_insn ( struct cs_struct handle,
cs_insn *  insn,
char *  buffer,
MCInst mci,
PostPrinter_t  postprinter,
const uint8_t code 
)
static

Definition at line 536 of file cs.c.

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 }
#define mnem(n, mn)
unsigned MCInst_getOpcodePub(const MCInst *inst)
Definition: MCInst.c:73
size_t csh
Definition: capstone.h:71
char mnemonic[CS_MNEMONIC_SIZE]
Definition: cs_priv.h:46
unsigned int id
Definition: cs_priv.h:44
struct customized_mnem insn
Definition: cs_priv.h:50
#define MIN(x, y)
Definition: utils.h:59
static int sp
Definition: z80asm.c:91

References handle, customized_mnem::id, insn_mnem::insn, MCInst_getOpcodePub(), memcpy(), MIN, mnem, customized_mnem::mnemonic, sp, and autogen_x86imm::tmp.

Referenced by cs_disasm(), and cs_disasm_iter().

◆ skipdata_opstr()

static void skipdata_opstr ( char *  opstr,
const uint8_t buffer,
size_t  size 
)
static

Definition at line 765 of file cs.c.

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 }
size_t len
Definition: 6502dis.c:15
static int opstr(RzAsm *a, ut8 *data, const Opcode *op)
Definition: asm_x86_nz.c:4054
void * p
Definition: libc.cpp:67
int cs_snprintf(char *buffer, size_t size, const char *fmt,...)
Definition: utils.c:104

References cs_snprintf(), i, len, NULL, opstr(), and p.

Referenced by cs_disasm(), and cs_disasm_iter().

◆ skipdata_size()

static uint8_t skipdata_size ( cs_struct handle)
static

Definition at line 601 of file cs.c.

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 }
@ CS_MODE_THUMB
ARM's Thumb mode, including Thumb-2.
Definition: capstone.h:108

References CS_ARCH_ARM, CS_ARCH_ARM64, CS_ARCH_EVM, CS_ARCH_M680X, CS_ARCH_M68K, CS_ARCH_MIPS, CS_ARCH_PPC, CS_ARCH_SPARC, CS_ARCH_SYSZ, CS_ARCH_TMS320C64X, CS_ARCH_X86, CS_ARCH_XCORE, CS_MODE_THUMB, and handle.

Referenced by cs_option().

Variable Documentation

◆ all_arch

uint32_t all_arch = 0
static

Definition at line 269 of file cs.c.

Referenced by cs_support().

◆ cs_arch_disallowed_mode_mask

cs_mode cs_arch_disallowed_mode_mask[MAX_ARCH]
static

Definition at line 198 of file cs.c.

Referenced by cs_open(), and cs_option().

◆ cs_arch_init

cs_err(* cs_arch_init[MAX_ARCH])(cs_struct *) ( cs_struct )
static

Definition at line 69 of file cs.c.

Referenced by cs_open().

◆ cs_arch_option

cs_err(* cs_arch_option[MAX_ARCH])(cs_struct *, cs_opt_type, size_t value) ( cs_struct ,
cs_opt_type  ,
size_t  value 
)
static

Definition at line 133 of file cs.c.

Referenced by cs_option().

◆ cs_mem_calloc

cs_calloc_t cs_mem_calloc = NULL

Definition at line 349 of file cs.c.

Referenced by cs_disasm(), cs_open(), cs_option(), and make_id2insn().

◆ cs_mem_free

cs_free_t cs_mem_free = NULL

Definition at line 351 of file cs.c.

Referenced by cs_close(), cs_disasm(), cs_free(), cs_malloc(), cs_open(), and cs_option().

◆ cs_mem_malloc

cs_malloc_t cs_mem_malloc = NULL

Definition at line 348 of file cs.c.

Referenced by cs_malloc(), cs_open(), cs_option(), and cs_strdup().

◆ cs_mem_realloc

cs_realloc_t cs_mem_realloc = NULL

Definition at line 350 of file cs.c.

Referenced by cs_disasm(), cs_open(), and cs_option().

◆ cs_vsnprintf

cs_vsnprintf_t cs_vsnprintf = NULL

Definition at line 352 of file cs.c.

Referenced by cs_open(), cs_option(), cs_snprintf(), and SStream_concat().