1 /* radare - LGPL - Copyright 2015-2016 - inisider */
2 
3 #include "microsoft_demangle.h"
4 #include <ctype.h>
5 #include <r_cons.h>
6 
7 #define _R_LIST_C
8 #include <r_list.h>
9 
10 #define MICROSOFT_NAME_LEN (256)
11 #define MICROSOFR_CLASS_NAMESPACE_LEN (256)
12 #define IMPOSSIBLE_LEN (MICROSOFT_NAME_LEN + MICROSOFR_CLASS_NAMESPACE_LEN)
13 
14 // TODO: it will be good to change this to some kind of map data structure
15 static RList *abbr_types = NULL;
16 static RList *abbr_names = NULL;
17 
18 typedef enum EObjectType {
19 	eObjectTypeStaticClassMember = 2,
20 	eObjectTypeGlobal = 3,
21 	eObjectTypeMax = 99
22 } EObjectType;
23 
24 ///////////////////////////////////////////////////////////////////////////////
25 // State machine for parsing type codes data types
26 ///////////////////////////////////////////////////////////////////////////////
27 typedef enum ETCStateMachineErr {
28 	eTCStateMachineErrOK,
29 	eTCStateMachineErrUncorrectTypeCode,
30 	eTCStateMachineErrUnsupportedTypeCode,
31 	eTCStateMachineErrAlloc,
32 	eTCStateMachineErrMax
33 } ETCStateMachineErr;
34 
35 typedef enum ETCState { // TC - type code
36 	eTCStateStart = 0, eTCStateEnd, eTCStateH, eTCStateX, eTCStateN, eTCStateD,
37 	eTCStateC, eTCStateE, eTCStateF, eTCStateG, eTCStateI, eTCStateJ, eTCStateK,
38 	eTCStateM, eTCStateZ, eTCState_, eTCStateT, eTCStateU, eTCStateW, eTCStateV,
39 	eTCStateO, eTCStateS, eTCStateP, eTCStateR, eTCStateQ, eTCStateA, eTCState$,
40 	eTCStateMax
41 } ETCState;
42 
43 typedef struct STypeCodeStr {
44 	char *type_str;
45 	size_t type_str_len;
46 	size_t curr_pos;
47 } STypeCodeStr;
48 
49 struct SStateInfo;
50 typedef void (*state_func)(struct SStateInfo *, STypeCodeStr *type_code_str);
51 
52 typedef struct SStateInfo {
53 	ETCState state;
54 	const char *buff_for_parsing;
55 	size_t amount_of_read_chars;
56 	ETCStateMachineErr err;
57 } SStateInfo;
58 
59 typedef struct SStrInfo {
60 	char *str_ptr;
61 	size_t len;
62 } SStrInfo;
63 
64 typedef struct SDataType {
65 	char *left;
66 	char *right;
67 } SDataType;
68 
sstrinfo_free(SStrInfo * sstrinfo)69 static void sstrinfo_free(SStrInfo *sstrinfo) {
70 	free (sstrinfo->str_ptr);
71 	free (sstrinfo);
72 }
73 
74 #define DECL_STATE_ACTION(action) static void tc_state_##action(SStateInfo *state, STypeCodeStr *type_code_str);
75 DECL_STATE_ACTION(start)
76 DECL_STATE_ACTION(end)
77 DECL_STATE_ACTION(X)
78 DECL_STATE_ACTION(N)
79 DECL_STATE_ACTION(D)
80 DECL_STATE_ACTION(C)
81 DECL_STATE_ACTION(E)
82 DECL_STATE_ACTION(F)
83 DECL_STATE_ACTION(G)
84 DECL_STATE_ACTION(H)
85 DECL_STATE_ACTION(I)
86 DECL_STATE_ACTION(J)
87 DECL_STATE_ACTION(K)
88 DECL_STATE_ACTION(M)
89 DECL_STATE_ACTION(Z)
90 DECL_STATE_ACTION(_)
91 DECL_STATE_ACTION(T)
92 DECL_STATE_ACTION(U)
93 DECL_STATE_ACTION(W)
94 DECL_STATE_ACTION(V)
95 DECL_STATE_ACTION(O)
96 DECL_STATE_ACTION(S)
97 DECL_STATE_ACTION(P)
98 DECL_STATE_ACTION(R)
99 DECL_STATE_ACTION(Q)
100 DECL_STATE_ACTION(A)
101 DECL_STATE_ACTION($)
102 #undef DECL_STATE_ACTION
103 
104 #define NAME(action) tc_state_##action
105 static state_func const state_table[eTCStateMax] = {
106 	NAME(start), NAME(end) , NAME(H), NAME(X), NAME(N), NAME(D), NAME(C), NAME(E),
107 	NAME(F), NAME(G), NAME(I), NAME(J), NAME(K), NAME(M), NAME(Z), NAME(_),
108 	NAME(T), NAME(U), NAME(W), NAME(V), NAME(O), NAME(S), NAME(P), NAME(R),
109 	NAME(Q), NAME(A), NAME($)
110 };
111 #undef NAME
112 ///////////////////////////////////////////////////////////////////////////////
113 // End of data types for state machine which parse type codes
114 ///////////////////////////////////////////////////////////////////////////////
115 
116 ///////////////////////////////////////////////////////////////////////////////
117 // State machine for parsing type codes functions
118 ///////////////////////////////////////////////////////////////////////////////
119 
120 static void init_state_struct(SStateInfo *state, const char *buff_for_parsing);
121 static EDemanglerErr get_type_code_string(const char *sym, size_t *amount_of_read_chars, char **str_type_code);
122 static bool init_type_code_str_struct(STypeCodeStr *type_coder_str);
123 static void free_type_code_str_struct(STypeCodeStr *type_code_str);
124 static size_t get_template(const char *buf, SStrInfo *str_info, bool memorize);
125 static char *get_num(SStateInfo *state);
126 static EDemanglerErr parse_data_type(const char *sym, SDataType *demangled_type, size_t *len);
127 static size_t get_namespace_and_name(const char *buf, STypeCodeStr *type_code_str, size_t *amount_of_names, bool memorize);
128 static inline EDemanglerErr get_storage_class(const char encoded, const char **storage_class);
129 static inline size_t get_ptr_modifier(const char encoded, SDataType *ptr_modifier);
130 static EDemanglerErr parse_function(const char *sym, STypeCodeStr *type_code_str, char **demangled_function, size_t *chars_read);
131 static EDemanglerErr parse_microsoft_mangled_name(const char *sym, char **demangled_name, size_t *chars_read);
132 static EDemanglerErr parse_microsoft_rtti_mangled_name(const char *sym, char **demangled_name, size_t *chars_read);
133 
run_state(SStateInfo * state_info,STypeCodeStr * type_code_str)134 static void run_state(SStateInfo *state_info, STypeCodeStr *type_code_str) {
135 	state_table[state_info->state](state_info, type_code_str);
136 }
137 
copy_string(STypeCodeStr * type_code_str,const char * str_for_copy,size_t copy_len)138 static int copy_string(STypeCodeStr *type_code_str, const char *str_for_copy, size_t copy_len) {
139 	int res = 1; // all is OK
140 	size_t str_for_copy_len = (copy_len == 0 && str_for_copy) ? strlen (str_for_copy) : copy_len;
141 	size_t free_space = type_code_str->type_str_len - type_code_str->curr_pos - 1;
142 
143 	if (free_space < str_for_copy_len) {
144 		int newlen = type_code_str->type_str_len + (str_for_copy_len << 1) + 1;
145 		if (newlen < 1) {
146 			R_FREE (type_code_str->type_str);
147 			goto copy_string_err;
148 		}
149 		type_code_str->type_str_len = newlen;
150 		char *type_str = (char *) realloc (type_code_str->type_str, newlen);
151 		if (!type_str) {
152 			R_FREE (type_code_str->type_str);
153 			goto copy_string_err;
154 		}
155 		type_code_str->type_str = type_str;
156 		if (!type_code_str->type_str) {
157 			res = 0;
158 			goto copy_string_err;
159 		}
160 	}
161 
162 	char *dst = type_code_str->type_str + type_code_str->curr_pos;
163 	if (!dst) {
164 		return 0;
165 	}
166 
167 	if (str_for_copy) {
168 		r_str_ncpy  (dst, str_for_copy, str_for_copy_len + 1);
169 	} else {
170 		memset (dst, 0, str_for_copy_len);
171 	}
172 	type_code_str->curr_pos += str_for_copy_len;
173 	if (type_code_str->type_str) {
174 		type_code_str->type_str[type_code_str->curr_pos] = '\0';
175 	}
176 
177 copy_string_err:
178 	return res;
179 }
180 
get_template_params(const char * sym,size_t * amount_of_read_chars,char ** str_type_code)181 static int get_template_params(const char *sym, size_t *amount_of_read_chars, char **str_type_code) {
182 	SStateInfo state;
183 	init_state_struct (&state, sym);
184 	const char template_param[] = "template-parameter-";
185 	char *tmp, *res = NULL;
186 	const char *const start_sym = sym;
187 	if (!strncmp (sym, "?", 1)) {
188 		// anonymous template param
189 		state.amount_of_read_chars += 1;
190 		state.buff_for_parsing += 1;
191 		res = get_num (&state);
192 		if (res) {
193 			tmp = r_str_newf("%s%s", template_param, res);
194 			free (res);
195 			res = tmp;
196 		}
197 	} else {
198 		if (strncmp (sym, "$", 1)) {
199 			return eDemanglerErrUncorrectMangledSymbol;
200 		}
201 		sym++;
202 		state.amount_of_read_chars += 2;
203 		state.buff_for_parsing += 2;
204 		char *a, *b, *c;
205 		switch (*sym) {
206 		case '0':
207 			// Signed integer
208 			a = get_num (&state);
209 			if (a) {
210 				int signed_a = atoi (a);
211 				res = r_str_newf ("%d", signed_a);
212 				free (a);
213 			}
214 			break;
215 		case '1': {
216 			STypeCodeStr str;
217 			EDemanglerErr err;
218 			if (!init_type_code_str_struct (&str)) {
219 				return eDemanglerErrMemoryAllocation;
220 			}
221 			sym += 2;
222 			size_t ret = get_namespace_and_name (sym, &str, NULL, true);
223 			if (!ret) {
224 				free_type_code_str_struct (&str);
225 				return eDemanglerErrUncorrectMangledSymbol;
226 			}
227 			sym += ret + 1;
228 			SDataType data_type;
229 			if (isdigit ((unsigned char)*sym)) {
230 				err = parse_data_type (sym, &data_type, &ret);
231 				*str_type_code = r_str_newf ("&%s %s%s", data_type.left, str.type_str, data_type.right);
232 				free (data_type.left);
233 				free (data_type.right);
234 			} else {
235 				char *tmp = NULL;
236 				err = parse_function (sym, &str, &tmp, &ret);
237 				*str_type_code = r_str_newf ("&%s", tmp);
238 				free (tmp);
239 			}
240 			sym += ret;
241 			*amount_of_read_chars = sym - start_sym;
242 			free_type_code_str_struct (&str);
243 			return err;
244 		}
245 		case '2':
246 			// real value a ^ b
247 			a = get_num (&state);
248 			b = get_num (&state);
249 			if (a && b) {
250 				int signed_b = atoi (b);
251 				res = r_str_newf ("%sE%d", a, signed_b);
252 			}
253 			free (a);
254 			free (b);
255 			break;
256 		case 'D':
257 			// anonymous template param
258 			res = get_num (&state);
259 			if (res) {
260 				tmp = r_str_newf ("%s%s", template_param, res);
261 				free (res);
262 				res = tmp;
263 			}
264 			break;
265 		case 'F':
266 			// Signed {a, b}
267 			a = get_num (&state);
268 			b = get_num (&state);
269 			if (a && b) {
270 				int signed_a = atoi (a);
271 				int signed_b = atoi (b);
272 				res = r_str_newf ("{%d, %d}", signed_a, signed_b);
273 			}
274 			free (a);
275 			free (b);
276 			break;
277 		case 'G':
278 			// Signed {a, b, c}
279 			a = get_num (&state);
280 			b = get_num (&state);
281 			c = get_num (&state);
282 			if (a && b && c) {
283 				int signed_a = atoi (a);
284 				int signed_b = atoi (b);
285 				int signed_c = atoi (c);
286 				res = r_str_newf ("{%d, %d, %d}", signed_a, signed_b, signed_c);
287 			}
288 			free (a);
289 			free (b);
290 			free (c);
291 			break;
292 		case 'H':
293 			// Unsigned integer
294 			res = get_num (&state);
295 			break;
296 		case 'I':
297 			// Unsigned {x, y}
298 			a = get_num (&state);
299 			b = get_num (&state);
300 			if (a && b) {
301 				res = r_str_newf ("{%s, %s}", a, b);
302 			}
303 			free (a);
304 			free (b);
305 			break;
306 		case 'J':
307 			// Unsigned {x, y, z}
308 			a = get_num (&state);
309 			b = get_num (&state);
310 			c = get_num (&state);
311 			if (a && b && c) {
312 				res = r_str_newf ("{%s, %s, %s}", a, b, c);
313 			}
314 			free (a);
315 			free (b);
316 			free (c);
317 			break;
318 		case 'Q':
319 			// anonymous non-type template parameter
320 			res = get_num (&state);
321 			if (res) {
322 				tmp = r_str_newf("non-type-%s%s", template_param, res);
323 				free (res);
324 				res = tmp;
325 			}
326 			break;
327 		default:
328 			break;
329 		}
330 	}
331 
332 	if (!res) {
333 		return eDemanglerErrUnsupportedMangling;
334 	}
335 
336 	*str_type_code = res;
337 	*amount_of_read_chars = state.amount_of_read_chars;
338 
339 	return eDemanglerErrOK;
340 }
341 
get_operator_code(const char * buf,RList * names_l,bool memorize)342 static size_t get_operator_code(const char *buf, RList *names_l, bool memorize) {
343 	// C++ operator code (one character, or two if the first is '_')
344 #define SET_OPERATOR_CODE(str) { \
345 	str_info = malloc (sizeof (SStrInfo)); \
346 	if (!str_info) break; \
347 	str_info->len = strlen (str); \
348 	str_info->str_ptr = strdup (str); \
349 	r_list_append (names_l, str_info); \
350 }
351 	SStrInfo *str_info;
352 	size_t read_len = 1;
353 	switch (*++buf) {
354 	case '0': SET_OPERATOR_CODE("constructor"); break;
355 	case '1': SET_OPERATOR_CODE("~destructor"); break;
356 	case '2': SET_OPERATOR_CODE("operator new"); break;
357 	case '3': SET_OPERATOR_CODE("operator delete"); break;
358 	case '4': SET_OPERATOR_CODE("operator="); break;
359 	case '5': SET_OPERATOR_CODE("operator>>"); break;
360 	case '6': SET_OPERATOR_CODE("operator<<"); break;
361 	case '7': SET_OPERATOR_CODE("operator!"); break;
362 	case '8': SET_OPERATOR_CODE("operator=="); break;
363 	case '9': SET_OPERATOR_CODE("operator!="); break;
364 	case 'A': SET_OPERATOR_CODE("operator[]"); break;
365 	case 'B': SET_OPERATOR_CODE("operator #{return_type}"); break;
366 	case 'C': SET_OPERATOR_CODE("operator->"); break;
367 	case 'D': SET_OPERATOR_CODE("operator*"); break;
368 	case 'E': SET_OPERATOR_CODE("operator++"); break;
369 	case 'F': SET_OPERATOR_CODE("operator--"); break;
370 	case 'G': SET_OPERATOR_CODE("operator-"); break;
371 	case 'H': SET_OPERATOR_CODE("operator+"); break;
372 	case 'I': SET_OPERATOR_CODE("operator&"); break;
373 	case 'J': SET_OPERATOR_CODE("operator->*"); break;
374 	case 'K': SET_OPERATOR_CODE("operator/"); break;
375 	case 'L': SET_OPERATOR_CODE("operator%"); break;
376 	case 'M': SET_OPERATOR_CODE("operator<"); break;
377 	case 'N': SET_OPERATOR_CODE("operator<="); break;
378 	case 'O': SET_OPERATOR_CODE("operator>"); break;
379 	case 'P': SET_OPERATOR_CODE("operator>="); break;
380 	case 'Q': SET_OPERATOR_CODE("operator,"); break;
381 	case 'R': SET_OPERATOR_CODE("operator()"); break;
382 	case 'S': SET_OPERATOR_CODE("operator~"); break;
383 	case 'T': SET_OPERATOR_CODE("operator^"); break;
384 	case 'U': SET_OPERATOR_CODE("operator|"); break;
385 	case 'V': SET_OPERATOR_CODE("operator&"); break;
386 	case 'W': SET_OPERATOR_CODE("operator||"); break;
387 	case 'X': SET_OPERATOR_CODE("operator*="); break;
388 	case 'Y': SET_OPERATOR_CODE("operator+="); break;
389 	case 'Z': SET_OPERATOR_CODE("operator-="); break;
390 	case '$':
391 	{
392 		str_info = malloc (sizeof (SStrInfo));
393 		if (!str_info) {
394 			break;
395 		}
396 		size_t i = get_template (buf + 1, str_info, memorize);
397 		if (!i) {
398 			R_FREE (str_info);
399 			return 0;
400 		}
401 		r_list_append (names_l, str_info);
402 		read_len += i;
403 		break;
404 	}
405 	case '_':
406 		switch (*++buf) {
407 		case '0': SET_OPERATOR_CODE ("operator/="); break;
408 		case '1': SET_OPERATOR_CODE ("operator%="); break;
409 		case '2': SET_OPERATOR_CODE ("operator>>="); break;
410 		case '3': SET_OPERATOR_CODE ("operator<<="); break;
411 		case '4': SET_OPERATOR_CODE ("operator&="); break;
412 		case '5': SET_OPERATOR_CODE ("operator|="); break;
413 		case '6': SET_OPERATOR_CODE ("operator^="); break;
414 		case '7': SET_OPERATOR_CODE ("vftable"); break;
415 		case '8': SET_OPERATOR_CODE ("vbtable"); break;
416 		case '9': SET_OPERATOR_CODE ("vcall"); break;
417 		case 'A': SET_OPERATOR_CODE ("typeof"); break;
418 		case 'B': SET_OPERATOR_CODE ("local_static_guard"); break;
419 		case 'C': SET_OPERATOR_CODE ("string"); break;
420 		case 'D': SET_OPERATOR_CODE ("vbase_dtor"); break;
421 		case 'E': SET_OPERATOR_CODE ("vector_dtor"); break;
422 		case 'G': SET_OPERATOR_CODE ("scalar_dtor"); break;
423 		case 'H': SET_OPERATOR_CODE ("vector_ctor_iter"); break;
424 		case 'I': SET_OPERATOR_CODE ("vector_dtor_iter"); break;
425 		case 'J': SET_OPERATOR_CODE ("vector_vbase_ctor_iter"); break;
426 		case 'L': SET_OPERATOR_CODE ("eh_vector_ctor_iter"); break;
427 		case 'M': SET_OPERATOR_CODE ("eh_vector_dtor_iter"); break;
428 		case 'N': SET_OPERATOR_CODE ("eh_vector_vbase_ctor_iter"); break;
429 		case 'O': SET_OPERATOR_CODE ("copy_ctor_closure"); break;
430 		case 'R':
431 			switch (*++buf) {
432 			case '0': {
433 				size_t len;
434 				char *str = NULL;
435 				if (parse_microsoft_rtti_mangled_name (buf + 2, &str, &len) != eDemanglerErrOK) {
436 					r_list_free (names_l);
437 					return 0;
438 				}
439 				read_len += len + 2;
440 				str = r_str_append (str, " `RTTI Type Descriptor'");
441 				SET_OPERATOR_CODE (str);
442 				free (str);
443 				break;
444 			}
445 			case '1': {
446 				SStateInfo state;
447 				init_state_struct (&state, buf + 1);
448 				char *a = get_num (&state);
449 				char *b = get_num (&state);
450 				char *c = get_num (&state);
451 				char *d = get_num (&state);
452 				if (!a || !b || !c || !d) {
453 					r_list_free (names_l);
454 					return 0;
455 				}
456 				read_len += state.amount_of_read_chars + 1;
457 				r_str_newf ("`RTTI Base Class Descriptor at (%s,%s,%s,%s)'", a, b, c, d);
458 				break;
459 			}
460 			case '2': SET_OPERATOR_CODE ("`RTTI Base Class Array'"); break;
461 			case '3': SET_OPERATOR_CODE ("`RTTI Class Hierarchy Descriptor'"); break;
462 			case '4': SET_OPERATOR_CODE ("`RTTI Complete Object Locator'"); break;
463 			default: return 0;
464 			}
465 			break;
466 		case 'S': SET_OPERATOR_CODE ("local_vftable"); break;
467 		case 'T': SET_OPERATOR_CODE ("local_vftable_ctor_closure"); break;
468 		case 'U': SET_OPERATOR_CODE ("operator new[]"); break;
469 		case 'V': SET_OPERATOR_CODE ("operator delete[]"); break;
470 		case 'X': SET_OPERATOR_CODE ("placement_new_closure"); break;
471 		case 'Y': SET_OPERATOR_CODE ("placement_delete_closure"); break;
472 		default:
473 			r_list_free (names_l);
474 			return 0;
475 		}
476 		read_len++;
477 		break;
478 	default:
479 		r_list_free (names_l);
480 		return 0;
481 	}
482 	read_len++;
483 	return read_len;
484 #undef SET_OPERATOR_CODE
485 }
486 
487 ///////////////////////////////////////////////////////////////////////////////
get_template(const char * buf,SStrInfo * str_info,bool memorize)488 static size_t get_template(const char *buf, SStrInfo *str_info, bool memorize) {
489 	size_t len = 0;
490 	char *str_type_code = NULL;
491 	STypeCodeStr type_code_str;
492 	// RListIter *it = NULL;
493 	RList *saved_abbr_names = abbr_names;	// save current abbr names, this
494 	RList *new_abbr_names = r_list_newf (free);
495 
496 	if (!init_type_code_str_struct(&type_code_str)) {
497 		goto get_template_err;
498 	}
499 
500 	if (*buf == '?') {
501 		RList *names_l = r_list_newf ((RListFree)sstrinfo_free);
502 		if (!names_l) {
503 			return 0;
504 		}
505 		size_t i = get_operator_code (buf, names_l, memorize);
506 		if (!i) {
507 			return 0;
508 		}
509 		len += i;
510 		buf += i;
511 		SStrInfo *name = r_list_head (names_l)->data;
512 		copy_string (&type_code_str, name->str_ptr, name->len);
513 		r_list_free (names_l);
514 	} else {
515 		char *tmp = strchr(buf, '@');
516 		if (!tmp) {
517 			goto get_template_err;
518 		}
519 
520 		// get/copy template len/name
521 		len += (tmp - buf + 1);
522 		copy_string (&type_code_str, buf, len - 1);
523 		r_list_append (new_abbr_names, r_str_ndup (buf, len - 1));
524 		buf += len;
525 	}
526 
527 	if (*buf != '@') {
528 		copy_string (&type_code_str, "<", 0);
529 	}
530 
531 	abbr_names = new_abbr_names;
532 
533 	// get identifier
534 	size_t i = 0;
535 	while (*buf != '@') {
536 		if (i) {
537 			copy_string (&type_code_str, ", ", 0);
538 		}
539 		if (get_type_code_string (buf, &i, &str_type_code) != eDemanglerErrOK) {
540 			if (get_template_params (buf, &i, &str_type_code) != eDemanglerErrOK) {
541 				len = 0;
542 				goto get_template_err;
543 			}
544 		}
545 		copy_string (&type_code_str, str_type_code, 0);
546 		buf += i;
547 		len += i;
548 		R_FREE (str_type_code);
549 	}
550 	if (*buf != '@') {
551 		len = 0;
552 		goto get_template_err;
553 	}
554 	if (i) {
555 		copy_string (&type_code_str, ">", 0);
556 	}
557 	buf++;
558 	len++;
559 
560 	str_info->str_ptr = type_code_str.type_str;
561 	str_info->len = type_code_str.curr_pos;
562 
563 get_template_err:
564 	r_list_free (new_abbr_names);
565 	abbr_names = saved_abbr_names; // restore global list with name abbr.
566 
567 	if (memorize) {
568 		r_list_append (abbr_names, strdup (type_code_str.type_str));
569 	}
570 
571 	//    will be free at a caller function
572 	//    free_type_code_str_struct(&type_code_str);
573 	return len;
574 }
575 
576 ///////////////////////////////////////////////////////////////////////////////
577 /// \brief get_namespace_and_name
578 /// \param buf Current buffer position with mangled name
579 /// \param type_code_str String with got name and namespaces
580 /// \param amount_of_names Amount of names that was in list
581 /// \return Return amount of processed chars
582 ///
get_namespace_and_name(const char * buf,STypeCodeStr * type_code_str,size_t * amount_of_names,bool memorize)583 static size_t get_namespace_and_name(const char *buf, STypeCodeStr *type_code_str, size_t *amount_of_names, bool memorize) {
584 	const char *curr_pos = NULL, *prev_pos = NULL, *tmp = NULL;
585 	RList /* <SStrInfo *> */ *names_l = NULL;
586 	RListIter *it = NULL;
587 	SStrInfo *str_info = NULL;
588 
589 	size_t len = 0, read_len = 0, tmp_len = 0;
590 
591 	names_l = r_list_newf ((RListFree)sstrinfo_free);
592 
593 	if (*buf == '?') {
594 		size_t res = get_operator_code (buf, names_l, memorize);
595 		if (!res) {
596 			return 0;
597 		}
598 		memorize = true;
599 		buf += res;
600 		read_len += res;
601 	}
602 
603 	prev_pos = buf;
604 	curr_pos = strchr (buf, '@');
605 
606 	// hack for nested templates
607 	// think about how better to fix this...
608 	len = curr_pos - prev_pos;
609 	if (len == 0) {
610 		goto get_namespace_and_name_err;
611 	}
612 
613 	while (curr_pos != NULL) {
614 		len = curr_pos - prev_pos;
615 		tmp = prev_pos;
616 
617 		if ((len == 0) && (*(curr_pos) == '@')) {
618 			break;
619 		}
620 
621 		// TODO:maybe add check of name correctness? like name can not start
622 		//		with number
623 		if ((len <= 0) || (len >= MICROSOFT_NAME_LEN)) {
624 			goto get_namespace_and_name_err;
625 		}
626 
627 		str_info = malloc (sizeof (SStrInfo));
628 		if (!str_info) {
629 			break;
630 		}
631 
632 		// check is it teamplate???
633 		if ((*tmp == '?') && (*(tmp + 1) == '$')) {
634 			size_t i = 0;
635 			i = get_template (tmp + 2, str_info, memorize);
636 			if (!i) {
637 				R_FREE (str_info);
638 				goto get_namespace_and_name_err;
639 			}
640 			r_list_append (names_l, str_info);
641 
642 			prev_pos = tmp + i + 2;
643 			curr_pos = strchr (prev_pos, '@');
644 			read_len += i + 2;
645 //			if (curr_pos)
646 //				read_len++;
647 			continue;
648 		}
649 
650 		if ((*tmp == '?') && (*(tmp + 1) == 'Q')) {
651 			STypeCodeStr str;
652 			if (!init_type_code_str_struct (&str)) {
653 				break;
654 			}
655 			size_t i = get_namespace_and_name (tmp + 2, &str, NULL, true);
656 			if (!i) {
657 				break;
658 			}
659 			prev_pos = tmp + i + 3;
660 			curr_pos = strchr (prev_pos, '@');
661 			read_len += i + 3;
662 			str_info->str_ptr = r_str_newf ("[%s]", str.type_str);
663 			str_info->len = strlen (str_info->str_ptr);
664 			r_list_append (names_l, str_info);
665 			free (str.type_str);
666 			continue;
667 		}
668 
669 		// Nested name
670 		if (*tmp == '?') {
671 			read_len++;
672 			// Optional sequence number
673 			char *num = NULL;
674 			if (*(tmp + 1) != '?') {
675 				SStateInfo state;
676 				init_state_struct (&state, tmp + 1);
677 				num = get_num (&state);
678 				tmp += state.amount_of_read_chars + 1;
679 				read_len += state.amount_of_read_chars + 1;
680 			}
681 			char *demangled;
682 			if (parse_microsoft_mangled_name (tmp + 2, &demangled, &len) != eDemanglerErrOK) {
683 				break;
684 			}
685 			read_len += len + 1;
686 			if (num) {
687 				str_info->str_ptr = r_str_newf ("`%s'::`%s'", demangled, num);
688 				free (num);
689 			} else {
690 				str_info->str_ptr = r_str_newf ("`%s'", demangled);
691 			}
692 
693 			str_info->len = strlen (str_info->str_ptr);
694 			r_list_append (names_l, str_info);
695 			r_list_append (abbr_names, strdup (str_info->str_ptr));
696 			free (demangled);
697 			break;
698 		}
699 
700 		if (isdigit ((ut8)*tmp)) {
701 			tmp = r_list_get_n (abbr_names, *tmp - '0');
702 			if (!tmp) {
703 				break;
704 			}
705 			len = 1;
706 		} else {
707 			char *tmpname = malloc (len + 1);
708 			memset (tmpname, 0, len + 1);
709 			memcpy (tmpname, prev_pos, len);
710 			r_list_append (abbr_names, tmpname);
711 			tmp = tmpname;
712 		}
713 
714 		str_info->str_ptr = strdup (tmp);
715 		str_info->len = strlen (tmp);
716 
717 		r_list_append (names_l, str_info);
718 
719 		memorize = true;
720 
721 		read_len += len;
722 		if (len == 1) {
723 			if (*(prev_pos + 1) == '@') {
724 				prev_pos = curr_pos;
725 			} else {
726 				prev_pos++;
727 			}
728 		} else {
729 			prev_pos = curr_pos + 1;
730 			curr_pos = strchr (curr_pos + 1, '@');
731 			if (curr_pos) {
732 				read_len++;
733 			}
734 		}
735 	}
736 
737 get_namespace_and_name_err:
738 	tmp_len = r_list_length (names_l);
739 	if (amount_of_names) {
740 		*amount_of_names = tmp_len;
741 	}
742 	r_list_foreach_prev (names_l, it, str_info) {
743 		copy_string (type_code_str, str_info->str_ptr, str_info->len);
744 
745 		if (--tmp_len) {
746 			copy_string (type_code_str, "::", 0);
747 		}
748 	}
749 	r_list_free (names_l);
750 	return read_len;
751 }
752 
753 #define SINGLEQUOTED_U 'U'
754 #define SINGLEQUOTED_X 'X'
755 #define SINGLEQUOTED_D 'D'
756 #define SINGLEQUOTED_C 'C'
757 #define SINGLEQUOTED_E 'E'
758 #define SINGLEQUOTED_F 'F'
759 #define SINGLEQUOTED_G 'G'
760 #define SINGLEQUOTED_H 'H'
761 #define SINGLEQUOTED_I 'I'
762 #define SINGLEQUOTED_J 'J'
763 #define SINGLEQUOTED_K 'K'
764 #define SINGLEQUOTED_M 'M'
765 #define SINGLEQUOTED_N 'N'
766 #define SINGLEQUOTED_T 'T'
767 #define SINGLEQUOTED_Z 'Z'
768 #define SINGLEQUOTED_W 'W'
769 #define SINGLEQUOTED_V 'V'
770 #define SINGLEQUOTED_O 'O'
771 #define SINGLEQUOTED_S 'S'
772 #define SINGLEQUOTED_P 'P'
773 #define SINGLEQUOTED_R 'R'
774 #define SINGLEQUOTED_Q 'Q'
775 #define SINGLEQUOTED_A 'A'
776 #define SINGLEQUOTED__ '_'
777 #define SINGLEQUOTED_$ '$'
778 #define CHAR_WITH_QUOTES(letter) (SINGLEQUOTED_##letter)
779 
780 #define DEF_STATE_ACTION(action) static void tc_state_##action(SStateInfo *state, STypeCodeStr *type_code_str)
781 #define GO_TO_NEXT_STATE(state, new_state) { \
782 	(state)->amount_of_read_chars++; \
783 	(state)->buff_for_parsing++; \
784 	(state)->state = eTCStateEnd; \
785 }
786 #define ONE_LETTER_ACTIION(action, type) \
787 	static void tc_state_##action(SStateInfo *state, STypeCodeStr *type_code_str) \
788 	{ \
789 		if (copy_string(type_code_str, type, 0) == 0) { \
790 			state->err = eTCStateMachineErrAlloc; \
791 		} \
792 		state->state = eTCStateEnd; \
793 	} \
794 
795 ONE_LETTER_ACTIION(X, "void")
796 ONE_LETTER_ACTIION(D, "char")
797 ONE_LETTER_ACTIION(C, "signed char")
798 ONE_LETTER_ACTIION(E, "unsigned char")
799 ONE_LETTER_ACTIION(F, "short int")
800 ONE_LETTER_ACTIION(G, "unsigned short int")
801 ONE_LETTER_ACTIION(H, "int")
802 ONE_LETTER_ACTIION(I, "unsigned int")
803 ONE_LETTER_ACTIION(J, "long int")
804 ONE_LETTER_ACTIION(K, "unsigned long int")
805 ONE_LETTER_ACTIION(M, "float")
806 ONE_LETTER_ACTIION(N, "double")
807 ONE_LETTER_ACTIION(Z, "varargs ...")
808 ONE_LETTER_ACTIION(O, "long double")
809 
DEF_STATE_ACTION(_)810 DEF_STATE_ACTION(_)
811 {
812 #define PROCESS_CASE(letter, type_str) \
813 	case CHAR_WITH_QUOTES(letter): \
814 		copy_string(type_code_str, type_str, 0); \
815 		break;
816 
817 	switch(*(state->buff_for_parsing)) {
818 		PROCESS_CASE (J, "long long(__int64)")
819 		PROCESS_CASE (K, "unsigned long long(unsigned __int64)")
820 		PROCESS_CASE (T, "long double(80 bit precision)")
821 		PROCESS_CASE (Z, "long double(64 bit precision)")
822 		PROCESS_CASE (W, "wchar_t")
823 		PROCESS_CASE (N, "bool")
824 		default:
825 			state->err = eTCStateMachineErrUncorrectTypeCode;
826 			break;
827 	}
828 
829 	state->amount_of_read_chars++;
830 	state->buff_for_parsing++;
831 	state->state = eTCStateEnd;
832 #undef PROCESS_CASE
833 }
834 
835 ///////////////////////////////////////////////////////////////////////////////
836 // isdigit need to check is it need to do deabbreviation of names
837 // +2 -> skipp @@  ( the end of class, union,...
838 // or +2 -> skip abbreviated_num + '@'
839 #define GET_USER_DEF_TYPE_NAME(data_struct_str) { \
840 	copy_string (type_code_str, data_struct_str, 0); \
841 \
842 	check_len = get_namespace_and_name (state->buff_for_parsing, type_code_str, NULL, true); \
843 	if (check_len) { \
844 		state->amount_of_read_chars += check_len; \
845 		state->buff_for_parsing += check_len; \
846 		if (*state->buff_for_parsing) { \
847 			state->buff_for_parsing++; \
848 			state->amount_of_read_chars++; \
849 		} \
850 	} else { \
851 		state->err = eTCStateMachineErrUncorrectTypeCode; \
852 	} \
853 }
854 
DEF_STATE_ACTION(T)855 DEF_STATE_ACTION(T)
856 {
857 #define PROCESS_CASE(case_string, type_str) { \
858 	check_len = strlen (case_string); \
859 	if ((check_len < buff_len) && \
860 		(strncmp (state->buff_for_parsing, case_string, check_len) == 0)) { \
861 		copy_string (type_code_str, type_str, 0); \
862 		state->buff_for_parsing += check_len; \
863 		state->amount_of_read_chars += check_len; \
864 		return; \
865 	} \
866 }
867 
868 	size_t buff_len = strlen (state->buff_for_parsing);
869 	size_t check_len = 0;
870 
871 	state->state = eTCStateEnd;
872 
873 	PROCESS_CASE ("__m64@@", "__m64");
874 	PROCESS_CASE ("__m128@@", "__m128");
875 	PROCESS_CASE ("__m128i@@", "__m128i");
876 	PROCESS_CASE ("__m256@@", "__m256");
877 	PROCESS_CASE ("__m256i@@", "__m256i");
878 	PROCESS_CASE ("__m512@@", "__m512");
879 	PROCESS_CASE ("__m512i@@", "__m512i");
880 
881 	GET_USER_DEF_TYPE_NAME ("union ");
882 #undef PROCESS_CASE
883 }
884 
DEF_STATE_ACTION(U)885 DEF_STATE_ACTION(U)
886 {
887 #define PROCESS_CASE(case_string, type_str) { \
888 	check_len = strlen (case_string); \
889 	if ((check_len < buff_len) && \
890 		(strncmp (state->buff_for_parsing, case_string, check_len) == 0)) { \
891 		copy_string (type_code_str, type_str, 0); \
892 		state->amount_of_read_chars += check_len; \
893 		state->buff_for_parsing += check_len; \
894 		return; \
895 	} \
896 }
897 
898 	size_t buff_len = strlen (state->buff_for_parsing);
899 	size_t check_len = 0;
900 
901 	state->state = eTCStateEnd;
902 
903 	PROCESS_CASE ("__m128d@@", "__m128d");
904 	PROCESS_CASE ("__m256d@@", "__m256d");
905 	PROCESS_CASE ("__m512d@@", "__m512d");
906 
907 	GET_USER_DEF_TYPE_NAME ("struct ");
908 #undef PROCESS_CASE
909 }
910 
DEF_STATE_ACTION(W)911 DEF_STATE_ACTION(W)
912 {
913 	//W4X@@ -> enum X, W4X@Y@@ -> enum Y::X
914 	size_t check_len = 0;
915 	state->state = eTCStateEnd;
916 
917 	if (*state->buff_for_parsing != '4') {
918 		state->err = eTCStateMachineErrUncorrectTypeCode;
919 	}
920 
921 	state->buff_for_parsing++;
922 	state->amount_of_read_chars++;
923 
924 	GET_USER_DEF_TYPE_NAME("enum ");
925 }
926 
DEF_STATE_ACTION(V)927 DEF_STATE_ACTION(V)
928 {
929 	// VX@@ -> class X
930 	size_t check_len = 0;
931 	state->state = eTCStateEnd;
932 
933 	GET_USER_DEF_TYPE_NAME("class ");
934 }
935 
936 #undef GET_USER_DEF_TYPE_NAME
937 
get_num(SStateInfo * state)938 static char *get_num(SStateInfo *state) {
939 	char *ptr = NULL;
940 	if (*state->buff_for_parsing >= '0' && *state->buff_for_parsing <= '8') {
941 		ptr = malloc (2);
942 		if (!ptr) {
943 			return NULL;
944 		}
945 		ptr[0] = *state->buff_for_parsing + 1;
946 		ptr[1] = '\0';
947 		state->buff_for_parsing++;
948 		state->amount_of_read_chars++;
949 	} else if (*state->buff_for_parsing == '9') {
950 		ptr = strdup ("10");
951 		state->buff_for_parsing++;
952 		state->amount_of_read_chars++;
953 	} else if (*state->buff_for_parsing >= 'A' && *state->buff_for_parsing <= 'P') {
954 		ut32 ret = 0;
955 
956 		while (*state->buff_for_parsing >= 'A' && *state->buff_for_parsing <= 'P') {
957 			ret *= 16;
958 			ret += *state->buff_for_parsing - 'A';
959 			state->buff_for_parsing++;
960 			state->amount_of_read_chars++;
961 		}
962 
963 		if (*state->buff_for_parsing != '@') {
964 			return NULL;
965 		}
966 
967 		ptr = r_str_newf ("%u", ret);
968 		state->buff_for_parsing++;
969 		state->amount_of_read_chars++;
970 	}
971 
972 	return ptr;
973 }
974 
parse_type_modifier(SStateInfo * state,STypeCodeStr * type_code_str,const char * modifier_str)975 static inline void parse_type_modifier(SStateInfo *state, STypeCodeStr *type_code_str, const char *modifier_str) {
976 	size_t i = 0;
977 	EDemanglerErr err = eDemanglerErrOK;
978 	char *tmp = NULL;
979 	STypeCodeStr tmp_str;
980 	STypeCodeStr modifier;
981 	bool is_pin_ptr = false;
982 	char clr_type = '\0';
983 
984 	state->state = eTCStateEnd;
985 
986 	if (!init_type_code_str_struct (&tmp_str)) {
987 		state->err = eTCStateMachineErrAlloc;
988 		return;
989 	}
990 	if (!init_type_code_str_struct (&modifier)) {
991 		free_type_code_str_struct (&tmp_str);
992 		state->err = eTCStateMachineErrAlloc;
993 		return;
994 	}
995 
996 	if (*state->buff_for_parsing == '$') {
997 		if (state->buff_for_parsing[1] == '0') {
998 			// TODO: no idea what this means
999 			state->buff_for_parsing += 3;
1000 			state->amount_of_read_chars += 3;
1001 		}
1002 	}
1003 
1004 	SDataType mod;
1005 	i = get_ptr_modifier (*state->buff_for_parsing, &mod);
1006 	state->buff_for_parsing += i;
1007 	state->amount_of_read_chars += i;
1008 
1009 	if (*state->buff_for_parsing == '$') {
1010 		state->buff_for_parsing++;
1011 		switch (*state->buff_for_parsing++) {
1012 		case 'A':
1013 			clr_type = '^';
1014 			break;
1015 		case 'B': // cli::pin_ptr<T>
1016 			is_pin_ptr = true;
1017 			break;
1018 		case 'C':
1019 			clr_type = '%';
1020 			break;
1021 		default:
1022 			state->err = eTCStateMachineErrUnsupportedTypeCode;
1023 			break;
1024 		}
1025 		state->amount_of_read_chars += 2;
1026 	}
1027 
1028 	SDataType mod2;
1029 	i = get_ptr_modifier (*state->buff_for_parsing, &mod2);
1030 	state->buff_for_parsing += i;
1031 	state->amount_of_read_chars += i;
1032 
1033 	const char *storage_class;
1034 	if (get_storage_class (*state->buff_for_parsing, &storage_class) != eDemanglerErrOK) {
1035 		state->err = eTCStateMachineErrUnsupportedTypeCode;
1036 		goto MODIFIER_err;
1037 	}
1038 	if (storage_class) {
1039 		copy_string (&modifier, storage_class, 0);
1040 		copy_string (&modifier, " ", 1);
1041 	}
1042 	copy_string (&modifier, mod2.left, 0);
1043 
1044 	state->buff_for_parsing++;
1045 	state->amount_of_read_chars++;
1046 
1047 	if (*state->buff_for_parsing == 'Y') {
1048 		char *n1;
1049 		int num;
1050 
1051 		state->buff_for_parsing++;
1052 		state->amount_of_read_chars++;
1053 		if (!(n1 = get_num (state))) {
1054 			goto MODIFIER_err;
1055 		}
1056 		num = atoi (n1);
1057 		R_FREE (n1);
1058 
1059 		copy_string (&tmp_str, " ", 0);
1060 		copy_string (&tmp_str, "(", 0);
1061 		copy_string (&tmp_str, modifier.type_str, modifier.curr_pos);
1062 		copy_string (&tmp_str, modifier_str, 0);
1063 		copy_string (&tmp_str, ")", 0);
1064 
1065 		while (num--) {
1066 			n1 = get_num (state);
1067 			copy_string (&tmp_str, "[", 0);
1068 			copy_string (&tmp_str, n1, 0);
1069 			copy_string (&tmp_str, "]", 0);
1070 			R_FREE (n1);
1071 		}
1072 	}
1073 
1074 	if (tmp_str.curr_pos == 0) {
1075 		copy_string (&tmp_str, " ", 0);
1076 		copy_string (&tmp_str, modifier.type_str, modifier.curr_pos);
1077 		copy_string (&tmp_str, mod.left, 0);
1078 		if (clr_type) {
1079 			char *str = strdup (modifier_str);
1080 			if (!str) {
1081 				state->err = eTCStateMachineErrAlloc;
1082 				goto MODIFIER_err;
1083 			}
1084 			*str = clr_type;
1085 			copy_string (&tmp_str, str, 0);
1086 			free (str);
1087 		} else {
1088 			if (is_pin_ptr) {
1089 				while (*++modifier_str == ' ') {};
1090 			}
1091 			copy_string (&tmp_str, modifier_str, 0);
1092 		}
1093 		copy_string (&tmp_str, mod2.right, 0);
1094 	}
1095 
1096 	if (!strncmp (state->buff_for_parsing, "__Z", 3)) {
1097 		// TODO: no idea what this means
1098 		state->buff_for_parsing += 3;
1099 		state->amount_of_read_chars += 3;
1100 	}
1101 
1102 	err = get_type_code_string (state->buff_for_parsing, &i, &tmp);
1103 	if (err != eDemanglerErrOK) {
1104 		state->err = eTCStateMachineErrUnsupportedTypeCode;
1105 		goto MODIFIER_err;
1106 	}
1107 
1108 	state->amount_of_read_chars += i;
1109 	state->buff_for_parsing += i;
1110 	if (is_pin_ptr) {
1111 		copy_string (type_code_str, "cli::pin_ptr<", 0);
1112 	}
1113 	copy_string (type_code_str, tmp, 0);
1114 	copy_string (type_code_str, tmp_str.type_str, tmp_str.curr_pos);
1115 	if (is_pin_ptr) {
1116 		copy_string (type_code_str, ">", 0);
1117 	}
1118 	copy_string (type_code_str, mod.right, 0);
1119 
1120 MODIFIER_err:
1121 	R_FREE (tmp);
1122 	free_type_code_str_struct (&tmp_str);
1123 	free_type_code_str_struct (&modifier);
1124 }
1125 
DEF_STATE_ACTION(S)1126 DEF_STATE_ACTION(S)
1127 {
1128 	parse_type_modifier (state, type_code_str, "* const volatile");
1129 }
1130 
get_calling_convention(char calling_convention)1131 static inline const char *get_calling_convention(char calling_convention) {
1132 	switch (calling_convention) {
1133 		case 'A': return "__cdecl";
1134 		case 'B': return "__cdecl __declspec(dllexport)";
1135 		case 'C': return "__pascal";
1136 		case 'D': return "__pascal __declspec(dllexport)";
1137 		case 'E': return "__thiscall";
1138 		case 'F': return "__thiscall __declspec(dllexport)";
1139 		case 'G': return "__stdcall";
1140 		case 'H': return "__stdcall __declspec(dllexport)";
1141 		case 'I': return "__fastcall";
1142 		case 'J': return "__fastcall __declspec(dllexport)";
1143 		case 'K': return "default (none given)";
1144 		case 'L': return "default (none given) __declspec(dllexport)";
1145 		case 'M': return "__clrcall";
1146 		default: return NULL;
1147 	}
1148 }
1149 
parse_function_args(const char * sym,char ** demangled_args,size_t * read_chars)1150 static EDemanglerErr parse_function_args(const char *sym, char **demangled_args, size_t *read_chars) {
1151 	EDemanglerErr err = eDemanglerErrOK;
1152 	const char *curr_pos = sym;
1153 	size_t len = 0;
1154 
1155 	STypeCodeStr func_str;
1156 	if (!init_type_code_str_struct (&func_str)) {
1157 		return eDemanglerErrMemoryAllocation;
1158 	}
1159 
1160 	copy_string (&func_str, "(", 0);
1161 
1162 	// Function arguments
1163 	while (*curr_pos && *curr_pos != 'Z') {
1164 		if (*curr_pos != '@') {
1165 			char *tmp;
1166 			bool is_abbr_type = false;
1167 			if (len) {
1168 				copy_string (&func_str, ", ", 0);
1169 			}
1170 			err = get_type_code_string (curr_pos, &len, &tmp);
1171 			if (err != eDemanglerErrOK) {
1172 				// abbreviation of type processing
1173 				if ((*curr_pos >= '0') && (*curr_pos <= '9')) {
1174 					free (tmp);
1175 					tmp = r_list_get_n (abbr_types, (ut32)(*curr_pos - '0'));
1176 					if (!tmp) {
1177 						err = eDemanglerErrUncorrectMangledSymbol;
1178 						break;
1179 					}
1180 					err = eDemanglerErrOK;
1181 					len = 1;
1182 					is_abbr_type = true;
1183 				} else {
1184 					err = eDemanglerErrUncorrectMangledSymbol;
1185 					free (tmp);
1186 					break;
1187 				}
1188 			}
1189 			curr_pos += len;
1190 
1191 			if (len > 1) {
1192 				r_list_append (abbr_types, strdup (tmp));
1193 			}
1194 
1195 			copy_string (&func_str, tmp, 0);
1196 
1197 			if (!strcmp (tmp, "void")) {
1198 				// arguments list is void
1199 				if (!is_abbr_type) {
1200 					free (tmp);
1201 				}
1202 				break;
1203 			}
1204 			if (!is_abbr_type) {
1205 				free (tmp);
1206 			}
1207 		} else {
1208 			curr_pos++;
1209 		}
1210 	}
1211 
1212 	while (*curr_pos == '@') {
1213 		curr_pos++;
1214 	}
1215 
1216 	if (*curr_pos != 'Z') {
1217 		err = eDemanglerErrUncorrectMangledSymbol;
1218 	}
1219 
1220 	copy_string (&func_str, ")", 0);
1221 
1222 	if (demangled_args) {
1223 		*demangled_args = strdup (func_str.type_str);
1224 	}
1225 
1226 	free_type_code_str_struct (&func_str);
1227 
1228 	if (read_chars) {
1229 		*read_chars = curr_pos - sym + 1;
1230 	}
1231 
1232 	return err;
1233 }
1234 
1235 // TODO: use parse_function() instead
pf(SStateInfo * state,STypeCodeStr * type_code_str,const char * pointer_str)1236 static void pf(SStateInfo *state, STypeCodeStr *type_code_str, const char *pointer_str) {
1237 	const char *call_conv = NULL;
1238 	const char *storage = NULL;
1239 	char *ret_type = NULL;
1240 	size_t i = 0;
1241 	EDemanglerErr err;
1242 
1243 	state->state = eTCStateEnd;
1244 
1245 	// Calling convention
1246 	call_conv = get_calling_convention (*state->buff_for_parsing++);
1247 	if (!call_conv) {
1248 		// XXX unify error messages into a single enum
1249 		state->err = (ETCStateMachineErr)eDemanglerErrUncorrectMangledSymbol;
1250 	}
1251 
1252 	state->amount_of_read_chars += 2; // '6' + call_conv
1253 
1254 	// return type
1255 	if (*state->buff_for_parsing == '?') {
1256 		err = get_storage_class (*++state->buff_for_parsing, &storage);
1257 		if (err != eDemanglerErrOK) {
1258 			state->err = eTCStateMachineErrUncorrectTypeCode;
1259 			return;
1260 		}
1261 		state->buff_for_parsing++;
1262 		state->amount_of_read_chars += 2;
1263 	}
1264 	err = get_type_code_string (state->buff_for_parsing, &i, &ret_type);
1265 	if (err != eDemanglerErrOK) {
1266 		state->err = eTCStateMachineErrUnsupportedTypeCode;
1267 		return;
1268 	}
1269 
1270 	copy_string (type_code_str, ret_type, 0);
1271 	if (storage) {
1272 		copy_string (type_code_str, " ", 1);
1273 		copy_string (type_code_str, storage, 0);
1274 	}
1275 	copy_string (type_code_str, " (", 0);
1276 	R_FREE (ret_type);
1277 
1278 	copy_string (type_code_str, call_conv, 0);
1279 	copy_string (type_code_str, " ", 1);
1280 	copy_string (type_code_str, pointer_str, 0);
1281 	copy_string (type_code_str, ")", 1);
1282 
1283 	state->amount_of_read_chars += i;
1284 	state->buff_for_parsing += i;
1285 
1286 	char *demangled_args;
1287 	if (parse_function_args (state->buff_for_parsing, &demangled_args, &i) != eDemanglerErrOK) {
1288 		state->err = eTCStateMachineErrUncorrectTypeCode;
1289 		return;
1290 	}
1291 	state->amount_of_read_chars += i;
1292 	state->buff_for_parsing += i;
1293 	copy_string (type_code_str, demangled_args, 0);
1294 	free (demangled_args);
1295 	return;
1296 }
1297 
parse_pointer(SStateInfo * state,STypeCodeStr * type_code_str,const char * pointer_str)1298 static void parse_pointer(SStateInfo *state, STypeCodeStr *type_code_str, const char *pointer_str) {
1299 	if (isdigit ((ut8)*state->buff_for_parsing)) {
1300 		ut8 digit = *state->buff_for_parsing++;
1301 		if (digit == '6' || digit == '7') {
1302 			pf (state, type_code_str, pointer_str);
1303 			return;
1304 		} else if (digit == '8' || digit == '9') {
1305 			STypeCodeStr func_str;
1306 			if (!init_type_code_str_struct (&func_str)) {
1307 				state->err = eTCStateMachineErrAlloc;
1308 				return;
1309 			};
1310 			size_t read = get_namespace_and_name (state->buff_for_parsing, &func_str, NULL, true) + 1;
1311 			state->amount_of_read_chars += read;
1312 			state->buff_for_parsing += read;
1313 			copy_string (&func_str, "::", 2);
1314 			copy_string (&func_str, pointer_str, 0);
1315 			pf (state, type_code_str, func_str.type_str);
1316 			free_type_code_str_struct (&func_str);
1317 			state->state = eTCStateEnd;
1318 			return;
1319 		}
1320 	}
1321 	parse_type_modifier (state, type_code_str, pointer_str);
1322 }
1323 
1324 #define PARSE_POINTER(pointer_str) parse_pointer (state, type_code_str, pointer_str)
1325 
1326 
DEF_STATE_ACTION(P)1327 DEF_STATE_ACTION(P) {
1328 	PARSE_POINTER ("*");
1329 }
1330 
DEF_STATE_ACTION(R)1331 DEF_STATE_ACTION(R) {
1332 	PARSE_POINTER ("* volatile");
1333 }
1334 
DEF_STATE_ACTION(Q)1335 DEF_STATE_ACTION(Q) {
1336 	PARSE_POINTER ("* const");
1337 }
1338 
DEF_STATE_ACTION(A)1339 DEF_STATE_ACTION(A) {
1340 	PARSE_POINTER ("&");
1341 }
1342 
DEF_STATE_ACTION($)1343 DEF_STATE_ACTION($) {
1344 	if (*(state->buff_for_parsing++) != '$') {
1345 		state->err = eTCStateMachineErrUncorrectTypeCode;
1346 		return;
1347 	}
1348 	state->amount_of_read_chars += 2;
1349 	switch (*state->buff_for_parsing++) {
1350 	case 'A':
1351 		state->state = eTCStateP;
1352 		break;
1353 	case 'B':
1354 		parse_type_modifier (state, type_code_str, "");
1355 		break;
1356 	case 'C':
1357 		parse_type_modifier (state, type_code_str, "");
1358 		break;
1359 	case 'F':
1360 		state->state = eTCStateP;
1361 		break;
1362 	case 'Q':
1363 		parse_type_modifier (state, type_code_str, "&&");
1364 		state->state = eTCStateEnd;
1365 		break;
1366 	case 'R':
1367 		parse_type_modifier (state, type_code_str, "&& volatile");
1368 		state->state = eTCStateEnd;
1369 		break;
1370 	case 'T':
1371 		copy_string (type_code_str, "std::nullptr_t", 15);
1372 		state->state = eTCStateEnd;
1373 		break;
1374 	case 'V':
1375 		state->state = eTCStateEnd;
1376 		break;
1377 	case 'Z':
1378 		state->state = eTCStateEnd;
1379 		break;
1380 	default:
1381 		state->err = eTCStateMachineErrUncorrectTypeCode;
1382 		break;
1383 	}
1384 }
1385 
1386 #undef ONE_LETTER_ACTION
1387 #undef GO_TO_NEXT_STATE
1388 #undef DEF_STATE_ACTION
1389 
tc_state_start(SStateInfo * state,STypeCodeStr * type_code_str)1390 static void tc_state_start(SStateInfo *state, STypeCodeStr *type_code_str) {
1391 #define ONE_LETTER_STATE(letter) \
1392 	case CHAR_WITH_QUOTES(letter): \
1393 		state->state = eTCState##letter; \
1394 		break; \
1395 
1396 	switch (*(state->buff_for_parsing)) {
1397 	ONE_LETTER_STATE (X)
1398 	ONE_LETTER_STATE (D)
1399 	ONE_LETTER_STATE (C)
1400 	ONE_LETTER_STATE (E)
1401 	ONE_LETTER_STATE (F)
1402 	ONE_LETTER_STATE (G)
1403 	ONE_LETTER_STATE (H)
1404 	ONE_LETTER_STATE (I)
1405 	ONE_LETTER_STATE (J)
1406 	ONE_LETTER_STATE (K)
1407 	ONE_LETTER_STATE (M)
1408 	ONE_LETTER_STATE (N)
1409 	ONE_LETTER_STATE (Z)
1410 	ONE_LETTER_STATE (_)
1411 	ONE_LETTER_STATE (T)
1412 	ONE_LETTER_STATE (U)
1413 	ONE_LETTER_STATE (W)
1414 	ONE_LETTER_STATE (V)
1415 	ONE_LETTER_STATE (O)
1416 	ONE_LETTER_STATE (S)
1417 	ONE_LETTER_STATE (P)
1418 	ONE_LETTER_STATE (R)
1419 	ONE_LETTER_STATE (Q)
1420 	ONE_LETTER_STATE (A)
1421 	ONE_LETTER_STATE ($)
1422 	default:
1423 		//eprintf("[uncorrect type] error while parsing type\n");
1424 
1425 		state->state = eTCStateEnd;
1426 		state->err = eTCStateMachineErrUncorrectTypeCode;
1427 		break;
1428 	}
1429 
1430 	state->amount_of_read_chars++;
1431 	state->buff_for_parsing++;
1432 #undef ONE_LETTER_STATE
1433 }
1434 
tc_state_end(SStateInfo * state,STypeCodeStr * type_code_str)1435 static void tc_state_end(SStateInfo *state, STypeCodeStr *type_code_str) {
1436 	return;
1437 }
1438 
init_state_struct(SStateInfo * state,const char * buff_for_parsing)1439 static void init_state_struct(SStateInfo *state, const char *buff_for_parsing) {
1440 	state->state = eTCStateStart;
1441 	state->buff_for_parsing = buff_for_parsing;
1442 	state->amount_of_read_chars = 0;
1443 	state->err = eTCStateMachineErrOK;
1444 }
1445 
init_type_code_str_struct(STypeCodeStr * type_coder_str)1446 static bool init_type_code_str_struct(STypeCodeStr *type_coder_str) {
1447 #define TYPE_STR_LEN 1024
1448 	// 1 - initialization finish with success, else - 0
1449 
1450 	type_coder_str->type_str_len = TYPE_STR_LEN;
1451 
1452 	type_coder_str->type_str = (char *) calloc (TYPE_STR_LEN, sizeof (char));
1453 	if (!type_coder_str->type_str) {
1454 		return false;
1455 	}
1456 	memset (type_coder_str->type_str, 0, TYPE_STR_LEN * sizeof(char));
1457 
1458 	type_coder_str->curr_pos = 0; // strlen ("unknown type");
1459 //	strncpy(type_coder_str->type_str, "unknown_type", type_coder_str->curr_pos);
1460 
1461 	return true;
1462 #undef TYPE_STR_LEN
1463 }
1464 
free_type_code_str_struct(STypeCodeStr * type_code_str)1465 static void free_type_code_str_struct(STypeCodeStr *type_code_str) {
1466 	if (type_code_str->type_str) {
1467 		R_FREE (type_code_str->type_str);
1468 	}
1469 	type_code_str->type_str_len = 0;
1470 }
1471 
1472 ///////////////////////////////////////////////////////////////////////////////
1473 // End of machine functions for parsing type codes
1474 ///////////////////////////////////////////////////////////////////////////////
1475 
get_type_code_string(const char * sym,size_t * amount_of_read_chars,char ** str_type_code)1476 static EDemanglerErr get_type_code_string(const char *sym, size_t *amount_of_read_chars, char **str_type_code) {
1477 	EDemanglerErr err = eDemanglerErrOK;
1478 	char *tmp_sym = strdup (sym);
1479 	STypeCodeStr type_code_str;
1480 	SStateInfo state;
1481 
1482 	if (!init_type_code_str_struct (&type_code_str)) {
1483 		err = eDemanglerErrMemoryAllocation;
1484 		goto get_type_code_string_err;
1485 	}
1486 
1487 	init_state_struct (&state, tmp_sym);
1488 
1489 	while (state.state != eTCStateEnd) {
1490 		run_state (&state, &type_code_str);
1491 		if (state.err != eTCStateMachineErrOK) {
1492 			*str_type_code = NULL;
1493 			*amount_of_read_chars = 0;
1494 			switch (state.err) {
1495 			case eTCStateMachineErrUncorrectTypeCode:
1496 				err = eDemanglerErrUncorrectMangledSymbol;
1497 				break;
1498 			case eTCStateMachineErrUnsupportedTypeCode:
1499 				err = eDemanglerErrUnsupportedMangling;
1500 			default:
1501 				break;
1502 			}
1503 			goto get_type_code_string_err;
1504 		}
1505 	}
1506 
1507 	*str_type_code = strdup (type_code_str.type_str);
1508 	*amount_of_read_chars = state.amount_of_read_chars;
1509 
1510 get_type_code_string_err:
1511 	R_FREE (tmp_sym);
1512 	free_type_code_str_struct (&type_code_str);
1513 	return err;
1514 }
1515 
get_ptr_modifier(const char encoded,SDataType * ptr_modifier)1516 static inline size_t get_ptr_modifier(const char encoded, SDataType *ptr_modifier) {
1517 	size_t read = 0;
1518 #define SET_PTR_MODIFIER(letter, modifier_left, modifier_right) \
1519 	case letter: \
1520 		ptr_modifier->left = modifier_left; \
1521 		ptr_modifier->right = modifier_right; \
1522 		read++; \
1523 		break;
1524 
1525 	switch (encoded) {
1526 	SET_PTR_MODIFIER ('E', "", " __ptr64")
1527 	SET_PTR_MODIFIER ('F', "__unaligned ", "")
1528 	SET_PTR_MODIFIER ('G', "", " &")
1529 	SET_PTR_MODIFIER ('H', "", " &&")
1530 	SET_PTR_MODIFIER ('I', "", " __restrict")
1531 	default:
1532 		ptr_modifier->left = ptr_modifier->right = "";
1533 	}
1534 #undef SET_PTR_MODIFIER
1535 	return read;
1536 }
1537 
get_storage_class(const char encoded,const char ** storage_class)1538 static inline EDemanglerErr get_storage_class(const char encoded, const char **storage_class) {
1539 	switch (encoded) {
1540 	case 'A':
1541 		*storage_class = NULL;
1542 		break; // non-const
1543 	case 'B':
1544 	case 'J':
1545 		*storage_class = "const";
1546 		break;
1547 	case 'C':
1548 	case 'G':
1549 	case 'K':
1550 		*storage_class = "volatile";
1551 		break;
1552 	case 'D':
1553 	case 'H':
1554 	case 'L':
1555 		*storage_class = "const volatile";
1556 		break;
1557 	default:
1558 		return eDemanglerErrUncorrectMangledSymbol;
1559 	}
1560 	return eDemanglerErrOK;
1561 }
1562 
parse_data_type(const char * sym,SDataType * data_type,size_t * len)1563 static EDemanglerErr parse_data_type(const char *sym, SDataType *data_type, size_t *len) {
1564 	EDemanglerErr err = eDemanglerErrOK;
1565 	size_t i;
1566 	const char *curr_pos = sym;
1567 	SDataType modifier;
1568 	const char *storage_class = NULL;
1569 	char *tmp;
1570 	if (len) {
1571 		*len = 0;
1572 	}
1573 	data_type->left = data_type->right = NULL;
1574 	// Data type and access level
1575 	switch (*curr_pos++) {
1576 	// Data
1577 	case '0': // Private static member
1578 	case '1': // Protected static member
1579 	case '2': // Public static member
1580 	case '3': // Normal variable
1581 	case '4': // Normal variable
1582 	case '5': // Normal variable
1583 		i = 0;
1584 		err = get_type_code_string (curr_pos, &i, &tmp);
1585 		if (err != eDemanglerErrOK) {
1586 			return err;
1587 		}
1588 
1589 		curr_pos += i;
1590 		curr_pos += get_ptr_modifier (*curr_pos, &modifier);
1591 		if (get_storage_class (*curr_pos, &storage_class) != eDemanglerErrOK) {
1592 			free (tmp);
1593 			return eDemanglerErrUncorrectMangledSymbol;
1594 		}
1595 		curr_pos++;
1596 
1597 		if (data_type) {
1598 			data_type->right = strdup ("");
1599 			if (!storage_class) {
1600 				data_type->left = r_str_newf ("%s%s%s", modifier.left, tmp, modifier.right);
1601 			} else {
1602 				data_type->left = r_str_newf ("%s%s %s%s", modifier.left, tmp, storage_class, modifier.right);
1603 			}
1604 			free (tmp);
1605 		}
1606 		break;
1607 	case '6': // compiler generated static
1608 	case '7': // compiler generated static
1609 		if (data_type) {
1610 			curr_pos += get_ptr_modifier (*curr_pos, &modifier);
1611 			if (get_storage_class (*curr_pos, &storage_class) != eDemanglerErrOK) {
1612 				return eDemanglerErrUncorrectMangledSymbol;
1613 			}
1614 			curr_pos++;
1615 
1616 			data_type->left = r_str_newf ("%s%s%s", storage_class, modifier.left , modifier.right);
1617 			if (*curr_pos != '@') {
1618 				STypeCodeStr str;
1619 				if (!init_type_code_str_struct (&str)) {
1620 					return eDemanglerErrMemoryAllocation;
1621 				}
1622 				size_t i = get_namespace_and_name (curr_pos, &str, NULL, true);
1623 				if (!i) {
1624 					free_type_code_str_struct (&str);
1625 					return eDemanglerErrUncorrectMangledSymbol;
1626 				}
1627 				curr_pos += i;
1628 				if (*(curr_pos + 1) != '@') {
1629 					STypeCodeStr str2;
1630 					if (!init_type_code_str_struct (&str2)) {
1631 						free_type_code_str_struct (&str);
1632 						return eDemanglerErrMemoryAllocation;
1633 					}
1634 					i = get_namespace_and_name (curr_pos + 1, &str2, NULL, true);
1635 					if (!i) {
1636 						free_type_code_str_struct (&str);
1637 						free_type_code_str_struct (&str2);
1638 						return eDemanglerErrUncorrectMangledSymbol;
1639 					}
1640 					curr_pos += i + 1;
1641 					data_type->right = r_str_newf ("{for `%s's `%s'}", str.type_str, str2.type_str);
1642 					free_type_code_str_struct (&str2);
1643 				} else {
1644 					data_type->right = r_str_newf ("{for `%s'}", str.type_str);
1645 				}
1646 				free_type_code_str_struct (&str);
1647 			} else {
1648 				data_type->right = strdup ("");
1649 			}
1650 		}
1651 		break;
1652 	}
1653 	if (len) {
1654 		*len = curr_pos - sym;
1655 	}
1656 	return eDemanglerErrOK;
1657 }
1658 
parse_function_type(const char * sym,SDataType * data_type,size_t * len,bool * is_static,bool * is_implicit_this_pointer)1659 static EDemanglerErr parse_function_type(const char *sym, SDataType *data_type,
1660 	size_t *len, bool *is_static, bool *is_implicit_this_pointer) {
1661 	const char *curr_pos = sym;
1662 	data_type->left = data_type->right = "";
1663 	*is_static = *is_implicit_this_pointer = false;
1664 	#define SET_THUNK_MODIFIER(letter, modifier_str) \
1665 	case letter: { \
1666 		SStateInfo state; \
1667 		init_state_struct (&state, curr_pos); \
1668 		char *num = get_num (&state); \
1669 		if (!num) {\
1670 			return eDemanglerErrUncorrectMangledSymbol; \
1671 		} \
1672 		data_type->left = modifier_str; \
1673 		data_type->right = r_str_newf ("`adjustor{%s}'", num); \
1674 		free (num);\
1675 		*is_implicit_this_pointer = true; \
1676 		curr_pos += state.amount_of_read_chars; \
1677 		break; \
1678 	}
1679 
1680 	#define SET_ACCESS_MODIFIER(letter, flag_set, modifier_str) \
1681 	case letter: \
1682 		data_type->left = modifier_str; \
1683 		*flag_set = true; \
1684 		break; \
1685 
1686 	/* Functions */
1687 	switch (*curr_pos++) {
1688 	SET_ACCESS_MODIFIER ('A', is_implicit_this_pointer, "private");
1689 	SET_ACCESS_MODIFIER ('B', is_implicit_this_pointer, "private");
1690 	SET_ACCESS_MODIFIER ('C', is_static, "private: static");
1691 	SET_ACCESS_MODIFIER ('D', is_static, "private: static");
1692 	SET_ACCESS_MODIFIER ('E', is_implicit_this_pointer, "private virtual");
1693 	SET_ACCESS_MODIFIER ('F', is_implicit_this_pointer, "private virtual");
1694 	SET_THUNK_MODIFIER ('G', "[thunk]:private virtual");
1695 	SET_THUNK_MODIFIER ('H', "[thunk]:private virtual");
1696 	SET_ACCESS_MODIFIER ('I', is_implicit_this_pointer, "protected");
1697 	SET_ACCESS_MODIFIER ('J', is_implicit_this_pointer, "protected");
1698 	SET_ACCESS_MODIFIER ('K', is_static, "protected: static");
1699 	SET_ACCESS_MODIFIER ('L', is_static, "protected: static");
1700 	SET_ACCESS_MODIFIER ('M', is_implicit_this_pointer, "protected virtual");
1701 	SET_ACCESS_MODIFIER ('N', is_implicit_this_pointer, "protected virtual");
1702 	SET_THUNK_MODIFIER ('O', "[thunk]:protected virtual");
1703 	SET_THUNK_MODIFIER ('P', "[thunk]:protected virtual");
1704 	SET_ACCESS_MODIFIER ('Q', is_implicit_this_pointer, "public");
1705 	SET_ACCESS_MODIFIER ('R', is_implicit_this_pointer, "public");
1706 	SET_ACCESS_MODIFIER ('S', is_static, "public: static");
1707 	SET_ACCESS_MODIFIER ('T', is_static, "public: static");
1708 	SET_ACCESS_MODIFIER ('U', is_implicit_this_pointer, "public virtual");
1709 	SET_ACCESS_MODIFIER ('V', is_implicit_this_pointer, "public virtual");
1710 	SET_THUNK_MODIFIER ('W', "[thunk]:public virtual");
1711 	SET_THUNK_MODIFIER ('X', "[thunk]:public virtual");
1712 	case 'Y': // near
1713 	case 'Z': // far
1714 		break;
1715 	default:
1716 		return eDemanglerErrUncorrectMangledSymbol;
1717 	}
1718 #undef SET_ACCESS_MODIFIER
1719 	if (len) {
1720 		*len = curr_pos - sym;
1721 	}
1722 	return eDemanglerErrOK;
1723 }
1724 
parse_function(const char * sym,STypeCodeStr * type_code_str,char ** demangled_function,size_t * chars_read)1725 static EDemanglerErr parse_function(const char *sym, STypeCodeStr *type_code_str, char **demangled_function, size_t *chars_read) {
1726 	EDemanglerErr err = eDemanglerErrOK;
1727 	bool is_implicit_this_pointer;
1728 	bool is_static;
1729 	const char *memb_func_access_code = NULL;
1730 	const char *call_conv = NULL;
1731 	const char *storage_class_code_for_ret = NULL;
1732 	char *demangled_args;
1733 	char *ret_type = NULL;
1734 	const char *curr_pos = sym;
1735 	SDataType data_type;
1736 	const char *__64ptr = NULL;
1737 	size_t len;
1738 
1739 	STypeCodeStr func_str;
1740 	if (!init_type_code_str_struct (&func_str)) {
1741 		err = eDemanglerErrMemoryAllocation;
1742 		goto parse_function_err;
1743 	}
1744 
1745 	if (!strncmp (curr_pos, "$$F", 3)) {
1746 		// Managed function (Managed C++ or C++/CLI)
1747 		curr_pos += 3;
1748 	}
1749 
1750 	err = parse_function_type (curr_pos, &data_type, &len, &is_static, &is_implicit_this_pointer);
1751 	if (err != eDemanglerErrOK) {
1752 		goto parse_function_err;
1753 	}
1754 
1755 	curr_pos += len;
1756 
1757 	if (*curr_pos == 'E') {
1758 		__64ptr = "__ptr64";
1759 		curr_pos++;
1760 	}
1761 
1762 	if (*curr_pos == '$') {
1763 		curr_pos += 2;
1764 	}
1765 
1766 	// member function access code
1767 	if (is_implicit_this_pointer) {
1768 		err = get_storage_class (*curr_pos++, &memb_func_access_code);
1769 		if (err != eDemanglerErrOK) {
1770 			goto parse_function_err;
1771 		}
1772 	}
1773 
1774 	// currently does not use because I can not find real example of
1775 	// where to use this
1776 	// just read in http://www.agner.org/optimize/calling_conventions.pdf
1777 	// that this is possible
1778 	// when some find the case where it is used please remove this (void)*
1779 	// lines
1780 	(void)is_static;
1781 
1782 	// Calling convention
1783 	call_conv = get_calling_convention (*curr_pos++);
1784 	if (!call_conv) {
1785 		err = eDemanglerErrUncorrectMangledSymbol;
1786 		goto parse_function_err;
1787 	}
1788 
1789 	// get storage class code for return
1790 	if (*curr_pos == '?') {
1791 		err = get_storage_class (*++curr_pos, &memb_func_access_code);
1792 		if (err != eDemanglerErrOK) {
1793 			goto parse_function_err;
1794 		}
1795 		curr_pos++;
1796 	}
1797 
1798 	// Return type, or @ if 'void'
1799 	if (*curr_pos == '@') {
1800 		ret_type = strdup ("void");
1801 		curr_pos++;
1802 	} else {
1803 		err = get_type_code_string (curr_pos, &len, &ret_type);
1804 		if (err != eDemanglerErrOK) {
1805 			err = eDemanglerErrUncorrectMangledSymbol;
1806 			goto parse_function_err;
1807 		}
1808 
1809 		curr_pos += len;
1810 	}
1811 
1812 	err = parse_function_args (curr_pos, &demangled_args, &len);
1813 	if (err != eDemanglerErrOK) {
1814 		goto parse_function_err;
1815 	}
1816 
1817 	curr_pos += len;
1818 
1819 	if (*data_type.left) {
1820 		copy_string (&func_str, data_type.left, 0);
1821 		if (!strstr (data_type.left, "static")) {
1822 			copy_string (&func_str, ": ", 0);
1823 		} else {
1824 			copy_string (&func_str, " ", 0);
1825 		}
1826 	}
1827 
1828 	if (storage_class_code_for_ret) {
1829 		copy_string (&func_str, storage_class_code_for_ret, 0);
1830 		copy_string (&func_str, " ", 0);
1831 	}
1832 
1833 	if (ret_type) {
1834 		copy_string (&func_str, ret_type, 0);
1835 		copy_string (&func_str, " ", 0);
1836 	}
1837 
1838 	if (call_conv) {
1839 		copy_string (&func_str, call_conv, 0);
1840 		copy_string (&func_str, " ", 0);
1841 	}
1842 
1843 	if (type_code_str->type_str) {
1844 		copy_string (&func_str, type_code_str->type_str, type_code_str->curr_pos);
1845 	}
1846 
1847 	if (*data_type.right) {
1848 		copy_string (&func_str, data_type.right, 0);
1849 		free (data_type.right);
1850 	}
1851 
1852 	copy_string (&func_str, demangled_args, 0);
1853 	free (demangled_args);
1854 
1855 	if (memb_func_access_code) {
1856 		copy_string (&func_str, memb_func_access_code, 0);
1857 	}
1858 
1859 	if (__64ptr) {
1860 		copy_string (&func_str, " ", 0);
1861 		copy_string (&func_str, __64ptr, 0);
1862 	}
1863 
1864 	if (ret_type) {
1865 		if (strstr (func_str.type_str, "#{return_type}")) {
1866 			func_str.type_str = r_str_replace (func_str.type_str, "#{return_type}", ret_type, 0);
1867 			func_str.curr_pos -= strlen ("#{return_type}") - strlen (ret_type);
1868 		}
1869 	}
1870 
1871 	// need to be free by user
1872 	if (func_str.type_str) {
1873 		*demangled_function = strdup (func_str.type_str);
1874 	}
1875 
1876 parse_function_err:
1877 	if (chars_read) {
1878 		*chars_read = curr_pos - sym;
1879 	}
1880 	free_type_code_str_struct (&func_str);
1881 	free (ret_type);
1882 	return err;
1883 }
1884 
1885 ///////////////////////////////////////////////////////////////////////////////
1886 /// public mangled name of global object:
1887 /// <public name> ::= ?<name>@[<namespace>@](0->inf)@3<type><storage class>
1888 /// mangled name of a static class member object:
1889 /// <public name> ::= ?<name>@[<classname>@](1->inf)@2<type><storage class>
1890 ///////////////////////////////////////////////////////////////////////////////
parse_microsoft_mangled_name(const char * sym,char ** demangled_name,size_t * chars_read)1891 static EDemanglerErr parse_microsoft_mangled_name(const char *sym, char **demangled_name, size_t *chars_read) {
1892 	STypeCodeStr type_code_str;
1893 	EDemanglerErr err = eDemanglerErrOK;
1894 
1895 	SDataType data_type;
1896 
1897 	const char *curr_pos = sym;
1898 
1899 	if (!init_type_code_str_struct (&type_code_str)) {
1900 		err = eDemanglerErrMemoryAllocation;
1901 		goto parse_microsoft_mangled_name_err;
1902 	}
1903 	size_t i;
1904 	size_t len = get_namespace_and_name (curr_pos, &type_code_str, &i, false);
1905 	if (!len) {
1906 		err = eDemanglerErrUncorrectMangledSymbol;
1907 		goto parse_microsoft_mangled_name_err;
1908 	}
1909 
1910 	curr_pos += len + 1;
1911 
1912 	if (!strncmp (curr_pos, "$$F", 3)) {
1913 		// Managed function (Managed C++ or C++/CLI)
1914 		curr_pos += 3;
1915 	}
1916 
1917 	if (curr_pos[0] == '_') {
1918 		// TODO: __based()
1919 		curr_pos++;
1920 	}
1921 
1922 	if (isdigit ((unsigned char)*curr_pos)) {
1923 		err = parse_data_type (curr_pos, &data_type, &len);
1924 		if (err != eDemanglerErrOK) {
1925 			goto parse_microsoft_mangled_name_err;
1926 		}
1927 		curr_pos += len;
1928 		*demangled_name = NULL;
1929 		if (data_type.left) {
1930 			*demangled_name = r_str_newf ("%s ", data_type.left);
1931 		}
1932 		*demangled_name = r_str_append (*demangled_name, type_code_str.type_str);
1933 		*demangled_name = r_str_append (*demangled_name, data_type.right);
1934 		free (data_type.left);
1935 		free (data_type.right);
1936 	} else if (isalpha ((unsigned char)*curr_pos)) {
1937 		err = parse_function (curr_pos, &type_code_str, demangled_name, &len);
1938 		curr_pos += len;
1939 	} else {
1940 		err = eDemanglerErrUncorrectMangledSymbol;
1941 	}
1942 
1943 parse_microsoft_mangled_name_err:
1944 	free_type_code_str_struct (&type_code_str);
1945 	if (chars_read) {
1946 		*chars_read = curr_pos - sym;
1947 	}
1948 	return err;
1949 }
1950 
parse_microsoft_rtti_mangled_name(const char * sym,char ** demangled_name,size_t * chars_read)1951 static EDemanglerErr parse_microsoft_rtti_mangled_name(const char *sym, char **demangled_name, size_t *chars_read) {
1952 	EDemanglerErr err = eDemanglerErrOK;
1953 	char *type = NULL;
1954 	const char *storage = NULL;
1955 	if (chars_read) {
1956 		*chars_read = 0;
1957 	}
1958 	err = get_storage_class (*sym++, &storage);
1959 	if (err != eDemanglerErrOK) {
1960 		return err;
1961 	}
1962 	size_t len;
1963 	err = get_type_code_string (sym, &len, &type);
1964 	if (err != eDemanglerErrOK) {
1965 		return err;
1966 	}
1967 	if (storage) {
1968 		*demangled_name = r_str_newf ("%s %s", type, storage);
1969 	} else {
1970 		*demangled_name = r_str_newf ("%s", type);
1971 	}
1972 	if (chars_read) {
1973 		*chars_read = len + 1;
1974 	}
1975 	free (type);
1976 	return err;
1977 }
1978 
1979 ///////////////////////////////////////////////////////////////////////////////
microsoft_demangle(SDemangler * demangler,char ** demangled_name)1980 EDemanglerErr microsoft_demangle(SDemangler *demangler, char **demangled_name) {
1981 	EDemanglerErr err = eDemanglerErrOK;
1982 //	RListIter *it = NULL;
1983 //	char *tmp = NULL;
1984 
1985 	// TODO: need refactor... maybe remove the static variable somewhere?
1986 	abbr_types = r_list_newf (free);
1987 	abbr_names = r_list_newf (free);
1988 
1989 	if (!demangler || !demangled_name) {
1990 		err = eDemanglerErrMemoryAllocation;
1991 		goto microsoft_demangle_err;
1992 	}
1993 
1994 	if (!strncmp (demangler->symbol, ".?", 2)) {
1995 		err = parse_microsoft_rtti_mangled_name (demangler->symbol + 2, demangled_name, NULL);
1996 	} else {
1997 		err = parse_microsoft_mangled_name (demangler->symbol + 1, demangled_name, NULL);
1998 	}
1999 
2000 microsoft_demangle_err:
2001 	r_list_free (abbr_names);
2002 	r_list_free (abbr_types);
2003 	return err;
2004 }
2005