1 /* Capstone Disassembly Engine */
2 /* By Nguyen Anh Quynh <aquynh@gmail.com>, 2013-2019 */
3 
4 #if defined(CAPSTONE_HAS_OSXKERNEL)
5 #include <Availability.h>
6 #include <libkern/libkern.h>
7 #else
8 #include <stdlib.h>
9 #endif
10 #include <string.h>
11 
12 #include "utils.h"
13 
14 // create a cache for fast id lookup
make_id2insn(const insn_map * insns,unsigned int size)15 static unsigned short *make_id2insn(const insn_map *insns, unsigned int size)
16 {
17 	// NOTE: assume that the max id is always put at the end of insns array
18 	unsigned short max_id = insns[size - 1].id;
19 	unsigned short i;
20 
21 	unsigned short *cache = (unsigned short *)cs_mem_calloc(max_id + 1, sizeof(*cache));
22 
23 	for (i = 1; i < size; i++)
24 		cache[insns[i].id] = i;
25 
26 	return cache;
27 }
28 
29 // look for @id in @insns, given its size in @max. first time call will update @cache.
30 // return 0 if not found
insn_find(const insn_map * insns,unsigned int max,unsigned int id,unsigned short ** cache)31 unsigned short insn_find(const insn_map *insns, unsigned int max, unsigned int id, unsigned short **cache)
32 {
33 	if (id > insns[max - 1].id)
34 		return 0;
35 
36 	if (*cache == NULL)
37 		*cache = make_id2insn(insns, max);
38 
39 	return (*cache)[id];
40 }
41 
name2id(const name_map * map,int max,const char * name)42 int name2id(const name_map* map, int max, const char *name)
43 {
44 	int i;
45 
46 	for (i = 0; i < max; i++) {
47 		if (!strcmp(map[i].name, name)) {
48 			return map[i].id;
49 		}
50 	}
51 
52 	// nothing match
53 	return -1;
54 }
55 
id2name(const name_map * map,int max,const unsigned int id)56 const char *id2name(const name_map* map, int max, const unsigned int id)
57 {
58 	int i;
59 
60 	for (i = 0; i < max; i++) {
61 		if (map[i].id == id) {
62 			return map[i].name;
63 		}
64 	}
65 
66 	// nothing match
67 	return NULL;
68 }
69 
70 // count number of positive members in a list.
71 // NOTE: list must be guaranteed to end in 0
count_positive(const uint16_t * list)72 unsigned int count_positive(const uint16_t *list)
73 {
74 	unsigned int c;
75 
76 	for (c = 0; list[c] > 0; c++);
77 
78 	return c;
79 }
80 
81 // count number of positive members in a list.
82 // NOTE: list must be guaranteed to end in 0
count_positive8(const unsigned char * list)83 unsigned int count_positive8(const unsigned char *list)
84 {
85 	unsigned int c;
86 
87 	for (c = 0; list[c] > 0; c++);
88 
89 	return c;
90 }
91 
cs_strdup(const char * str)92 char *cs_strdup(const char *str)
93 {
94 	size_t len = strlen(str)+ 1;
95 	void *new = cs_mem_malloc(len);
96 
97 	if (new == NULL)
98 		return NULL;
99 
100 	return (char *)memmove(new, str, len);
101 }
102 
103 // we need this since Windows doesn't have snprintf()
cs_snprintf(char * buffer,size_t size,const char * fmt,...)104 int cs_snprintf(char *buffer, size_t size, const char *fmt, ...)
105 {
106 	int ret;
107 
108 	va_list ap;
109 	va_start(ap, fmt);
110 	ret = cs_vsnprintf(buffer, size, fmt, ap);
111 	va_end(ap);
112 
113 	return ret;
114 }
115 
arr_exist8(unsigned char * arr,unsigned char max,unsigned int id)116 bool arr_exist8(unsigned char *arr, unsigned char max, unsigned int id)
117 {
118 	int i;
119 
120 	for (i = 0; i < max; i++) {
121 		if (arr[i] == id)
122 			return true;
123 	}
124 
125 	return false;
126 }
127 
arr_exist(uint16_t * arr,unsigned char max,unsigned int id)128 bool arr_exist(uint16_t *arr, unsigned char max, unsigned int id)
129 {
130 	int i;
131 
132 	for (i = 0; i < max; i++) {
133 		if (arr[i] == id)
134 			return true;
135 	}
136 
137 	return false;
138 }
139 
140 // binary search for encoding in IndexType array
141 // return -1 if not found, or index if found
binsearch_IndexTypeEncoding(const struct IndexType * index,size_t size,uint16_t encoding)142 unsigned int binsearch_IndexTypeEncoding(const struct IndexType *index, size_t size, uint16_t encoding)
143 {
144 	// binary searching since the index is sorted in encoding order
145 	size_t left, right, m;
146 
147 	right = size - 1;
148 
149 	if (encoding < index[0].encoding || encoding > index[right].encoding)
150 		// not found
151 		return -1;
152 
153 	left = 0;
154 
155 	while(left <= right) {
156 		m = (left + right) / 2;
157 		if (encoding == index[m].encoding) {
158 			return m;
159 		}
160 
161 		if (encoding < index[m].encoding)
162 			right = m - 1;
163 		else
164 			left = m + 1;
165 	}
166 
167 	// not found
168 	return -1;
169 }
170