1 /*-
2  * Copyright (c) 2007 Hyogeol Lee <hyogeollee@gmail.com>
3  * Copyright (c) 2015-2017 Kai Wang <kaiwang27@gmail.com>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer
11  *    in this position and unchanged.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  */
27 #include <sys/types.h>
28 #include <assert.h>
29 #include <ctype.h>
30 #include <errno.h>
31 #include <limits.h>
32 #include <stdbool.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 /**
38  * @file cpp_demangle.c
39  * @brief Decode IA-64 C++ ABI style implementation.
40  *
41  * IA-64 standard ABI(Itanium C++ ABI) references.
42  *
43  * http://www.codesourcery.com/cxx-abi/abi.html#mangling \n
44  * http://www.codesourcery.com/cxx-abi/abi-mangling.html
45  */
46 
47 /** @brief Dynamic vector data for string. */
48 struct vector_str {
49           /** Current size */
50           size_t              size;
51           /** Total capacity */
52           size_t              capacity;
53           /** String array */
54           char                **container;
55 };
56 
57 #define BUFFER_GROWFACTOR     1.618
58 #define BUFFER_GROW(x)                  (((x)+0.5)*BUFFER_GROWFACTOR)
59 
60 #define   ELFTC_FAILURE                 0
61 #define   ELFTC_ISDIGIT(C)    (isdigit((C) & 0xFF))
62 #define   ELFTC_SUCCESS                 1
63 
64 #define VECTOR_DEF_CAPACITY   8
65 
66 enum type_qualifier {
67           TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT,
68           TYPE_CST, TYPE_VEC, TYPE_RREF
69 };
70 
71 struct vector_type_qualifier {
72           size_t size, capacity;
73           enum type_qualifier *q_container;
74           struct vector_str ext_name;
75 };
76 
77 enum read_cmd {
78           READ_FAIL, READ_NEST, READ_TMPL, READ_EXPR, READ_EXPL, READ_LOCAL,
79           READ_TYPE, READ_FUNC, READ_PTRMEM
80 };
81 
82 struct read_cmd_item {
83           enum read_cmd cmd;
84           void *data;
85 };
86 
87 struct vector_read_cmd {
88           size_t size, capacity;
89           struct read_cmd_item *r_container;
90 };
91 
92 enum push_qualifier {
93           PUSH_ALL_QUALIFIER,
94           PUSH_CV_QUALIFIER,
95           PUSH_NON_CV_QUALIFIER,
96 };
97 
98 struct cpp_demangle_data {
99           struct vector_str    output;  /* output string vector */
100           struct vector_str    subst;             /* substitution string vector */
101           struct vector_str    tmpl;
102           struct vector_str    class_type;
103           struct vector_str   *cur_output;        /* ptr to current output vec */
104           struct vector_read_cmd         cmd;
105           bool                           mem_rst; /* restrict member function */
106           bool                           mem_vat; /* volatile member function */
107           bool                           mem_cst; /* const member function */
108           bool                           mem_ref; /* lvalue-ref member func */
109           bool                           mem_rref;          /* rvalue-ref member func */
110           bool                           is_tmpl; /* template args */
111           bool                           is_functype;       /* function type */
112           bool                           ref_qualifier; /* ref qualifier */
113           enum type_qualifier  ref_qualifier_type; /* ref qualifier type */
114           enum push_qualifier  push_qualifier; /* which qualifiers to push */
115           int                            func_type;
116           const char                    *cur;               /* current mangled name ptr */
117           const char                    *last_sname;        /* last source name */
118 };
119 
120 struct type_delimit {
121           bool paren;
122           bool firstp;
123 };
124 
125 #define   CPP_DEMANGLE_TRY_LIMIT        128
126 #define   FLOAT_SPRINTF_TRY_LIMIT       5
127 #define   FLOAT_QUADRUPLE_BYTES         16
128 #define   FLOAT_EXTENED_BYTES 10
129 
130 #define SIMPLE_HASH(x,y)      (64 * x + y)
131 #define DEM_PUSH_STR(d,s)     cpp_demangle_push_str((d), (s), strlen((s)))
132 #define VEC_PUSH_STR(d,s)     vector_str_push((d), (s), strlen((s)))
133 
134 static size_t       get_strlen_sum(const struct vector_str *v);
135 static bool         vector_str_grow(struct vector_str *v);
136 
137 static size_t
get_strlen_sum(const struct vector_str * v)138 get_strlen_sum(const struct vector_str *v)
139 {
140           size_t i, len = 0;
141 
142           if (v == NULL)
143                     return (0);
144 
145           assert(v->size > 0);
146 
147           for (i = 0; i < v->size; ++i)
148                     len += strlen(v->container[i]);
149 
150           return (len);
151 }
152 
153 /**
154  * @brief Deallocate resource in vector_str.
155  */
156 static void
vector_str_dest(struct vector_str * v)157 vector_str_dest(struct vector_str *v)
158 {
159           size_t i;
160 
161           if (v == NULL)
162                     return;
163 
164           for (i = 0; i < v->size; ++i)
165                     free(v->container[i]);
166 
167           free(v->container);
168 }
169 
170 /**
171  * @brief Find string in vector_str.
172  * @param v Destination vector.
173  * @param o String to find.
174  * @param l Length of the string.
175  * @return -1 at failed, 0 at not found, 1 at found.
176  */
177 static int
vector_str_find(const struct vector_str * v,const char * o,size_t l)178 vector_str_find(const struct vector_str *v, const char *o, size_t l)
179 {
180           size_t i;
181 
182           if (v == NULL || o == NULL)
183                     return (-1);
184 
185           for (i = 0; i < v->size; ++i)
186                     if (strncmp(v->container[i], o, l) == 0)
187                               return (1);
188 
189           return (0);
190 }
191 
192 /**
193  * @brief Get new allocated flat string from vector.
194  *
195  * If l is not NULL, return length of the string.
196  * @param v Destination vector.
197  * @param l Length of the string.
198  * @return NULL at failed or NUL terminated new allocated string.
199  */
200 static char *
vector_str_get_flat(const struct vector_str * v,size_t * l)201 vector_str_get_flat(const struct vector_str *v, size_t *l)
202 {
203           ssize_t elem_pos, elem_size, rtn_size;
204           size_t i;
205           char *rtn;
206 
207           if (v == NULL || v->size == 0)
208                     return (NULL);
209 
210           if ((rtn_size = get_strlen_sum(v)) == 0)
211                     return (NULL);
212 
213           if ((rtn = malloc(sizeof(char) * (rtn_size + 1))) == NULL)
214                     return (NULL);
215 
216           elem_pos = 0;
217           for (i = 0; i < v->size; ++i) {
218                     elem_size = strlen(v->container[i]);
219 
220                     memcpy(rtn + elem_pos, v->container[i], elem_size);
221 
222                     elem_pos += elem_size;
223           }
224 
225           rtn[rtn_size] = '\0';
226 
227           if (l != NULL)
228                     *l = rtn_size;
229 
230           return (rtn);
231 }
232 
233 static bool
vector_str_grow(struct vector_str * v)234 vector_str_grow(struct vector_str *v)
235 {
236           size_t i, tmp_cap;
237           char **tmp_ctn;
238 
239           if (v == NULL)
240                     return (false);
241 
242           assert(v->capacity > 0);
243 
244           tmp_cap = BUFFER_GROW(v->capacity);
245 
246           assert(tmp_cap > v->capacity);
247 
248           if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)
249                     return (false);
250 
251           for (i = 0; i < v->size; ++i)
252                     tmp_ctn[i] = v->container[i];
253 
254           free(v->container);
255 
256           v->container = tmp_ctn;
257           v->capacity = tmp_cap;
258 
259           return (true);
260 }
261 
262 /**
263  * @brief Initialize vector_str.
264  * @return false at failed, true at success.
265  */
266 static bool
vector_str_init(struct vector_str * v)267 vector_str_init(struct vector_str *v)
268 {
269 
270           if (v == NULL)
271                     return (false);
272 
273           v->size = 0;
274           v->capacity = VECTOR_DEF_CAPACITY;
275 
276           assert(v->capacity > 0);
277 
278           if ((v->container = malloc(sizeof(char *) * v->capacity)) == NULL)
279                     return (false);
280 
281           assert(v->container != NULL);
282 
283           return (true);
284 }
285 
286 /**
287  * @brief Remove last element in vector_str.
288  * @return false at failed, true at success.
289  */
290 static bool
vector_str_pop(struct vector_str * v)291 vector_str_pop(struct vector_str *v)
292 {
293 
294           if (v == NULL)
295                     return (false);
296 
297           if (v->size == 0)
298                     return (true);
299 
300           --v->size;
301 
302           free(v->container[v->size]);
303           v->container[v->size] = NULL;
304 
305           return (true);
306 }
307 
308 /**
309  * @brief Push back string to vector.
310  * @return false at failed, true at success.
311  */
312 static bool
vector_str_push(struct vector_str * v,const char * str,size_t len)313 vector_str_push(struct vector_str *v, const char *str, size_t len)
314 {
315 
316           if (v == NULL || str == NULL)
317                     return (false);
318 
319           if (v->size == v->capacity && vector_str_grow(v) == false)
320                     return (false);
321 
322           if ((v->container[v->size] = malloc(sizeof(char) * (len + 1))) == NULL)
323                     return (false);
324 
325           snprintf(v->container[v->size], len + 1, "%s", str);
326 
327           ++v->size;
328 
329           return (true);
330 }
331 
332 /**
333  * @brief Push front org vector to det vector.
334  * @return false at failed, true at success.
335  */
336 static bool
vector_str_push_vector_head(struct vector_str * dst,struct vector_str * org)337 vector_str_push_vector_head(struct vector_str *dst, struct vector_str *org)
338 {
339           size_t i, j, tmp_cap;
340           char **tmp_ctn;
341 
342           if (dst == NULL || org == NULL)
343                     return (false);
344 
345           tmp_cap = BUFFER_GROW(dst->size + org->size);
346 
347           if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)
348                     return (false);
349 
350           for (i = 0; i < org->size; ++i)
351                     if ((tmp_ctn[i] = strdup(org->container[i])) == NULL) {
352                               for (j = 0; j < i; ++j)
353                                         free(tmp_ctn[j]);
354 
355                               free(tmp_ctn);
356 
357                               return (false);
358                     }
359 
360           for (i = 0; i < dst->size; ++i)
361                     tmp_ctn[i + org->size] = dst->container[i];
362 
363           free(dst->container);
364 
365           dst->container = tmp_ctn;
366           dst->capacity = tmp_cap;
367           dst->size += org->size;
368 
369           return (true);
370 }
371 
372 /**
373  * @brief Push org vector to the tail of det vector.
374  * @return false at failed, true at success.
375  */
376 static bool
vector_str_push_vector(struct vector_str * dst,struct vector_str * org)377 vector_str_push_vector(struct vector_str *dst, struct vector_str *org)
378 {
379           size_t i, j, tmp_cap;
380           char **tmp_ctn;
381 
382           if (dst == NULL || org == NULL)
383                     return (false);
384 
385           tmp_cap = BUFFER_GROW(dst->size + org->size);
386 
387           if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)
388                     return (false);
389 
390           for (i = 0; i < dst->size; ++i)
391                     tmp_ctn[i] = dst->container[i];
392 
393           for (i = 0; i < org->size; ++i)
394                     if ((tmp_ctn[i + dst->size] = strdup(org->container[i])) ==
395                         NULL) {
396                               for (j = 0; j < i + dst->size; ++j)
397                                         free(tmp_ctn[j]);
398 
399                               free(tmp_ctn);
400 
401                               return (false);
402                     }
403 
404           free(dst->container);
405 
406           dst->container = tmp_ctn;
407           dst->capacity = tmp_cap;
408           dst->size += org->size;
409 
410           return (true);
411 }
412 
413 /**
414  * @brief Get new allocated flat string from vector between begin and end.
415  *
416  * If r_len is not NULL, string length will be returned.
417  * @return NULL at failed or NUL terminated new allocated string.
418  */
419 static char *
vector_str_substr(const struct vector_str * v,size_t begin,size_t end,size_t * r_len)420 vector_str_substr(const struct vector_str *v, size_t begin, size_t end,
421     size_t *r_len)
422 {
423           size_t cur, i, len;
424           char *rtn;
425 
426           if (v == NULL || begin > end)
427                     return (NULL);
428 
429           len = 0;
430           for (i = begin; i < end + 1; ++i)
431                     len += strlen(v->container[i]);
432 
433           if ((rtn = malloc(sizeof(char) * (len + 1))) == NULL)
434                     return (NULL);
435 
436           if (r_len != NULL)
437                     *r_len = len;
438 
439           cur = 0;
440           for (i = begin; i < end + 1; ++i) {
441                     len = strlen(v->container[i]);
442                     memcpy(rtn + cur, v->container[i], len);
443                     cur += len;
444           }
445           rtn[cur] = '\0';
446 
447           return (rtn);
448 }
449 
450 static void         cpp_demangle_data_dest(struct cpp_demangle_data *);
451 static int          cpp_demangle_data_init(struct cpp_demangle_data *,
452                         const char *);
453 static int          cpp_demangle_get_subst(struct cpp_demangle_data *, size_t);
454 static int          cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t);
455 static int          cpp_demangle_push_fp(struct cpp_demangle_data *,
456                         char *(*)(const char *, size_t));
457 static int          cpp_demangle_push_str(struct cpp_demangle_data *, const char *,
458                         size_t);
459 static int          cpp_demangle_pop_str(struct cpp_demangle_data *);
460 static int          cpp_demangle_push_subst(struct cpp_demangle_data *,
461                         const char *, size_t);
462 static int          cpp_demangle_push_subst_v(struct cpp_demangle_data *,
463                         struct vector_str *);
464 static int          cpp_demangle_push_type_qualifier(struct cpp_demangle_data *,
465                         struct vector_type_qualifier *, const char *);
466 static int          cpp_demangle_read_array(struct cpp_demangle_data *);
467 static int          cpp_demangle_read_encoding(struct cpp_demangle_data *);
468 static int          cpp_demangle_read_expr_primary(struct cpp_demangle_data *);
469 static int          cpp_demangle_read_expression(struct cpp_demangle_data *);
470 static int          cpp_demangle_read_expression_flat(struct cpp_demangle_data *,
471                         char **);
472 static int          cpp_demangle_read_expression_binary(struct cpp_demangle_data *,
473                         const char *, size_t);
474 static int          cpp_demangle_read_expression_unary(struct cpp_demangle_data *,
475                         const char *, size_t);
476 static int          cpp_demangle_read_expression_trinary(struct cpp_demangle_data *,
477                         const char *, size_t, const char *, size_t);
478 static int          cpp_demangle_read_function(struct cpp_demangle_data *, int *,
479                         struct vector_type_qualifier *);
480 static int          cpp_demangle_local_source_name(struct cpp_demangle_data *ddata);
481 static int          cpp_demangle_read_local_name(struct cpp_demangle_data *);
482 static int          cpp_demangle_read_name(struct cpp_demangle_data *);
483 static int          cpp_demangle_read_name_flat(struct cpp_demangle_data *,
484                         char**);
485 static int          cpp_demangle_read_nested_name(struct cpp_demangle_data *);
486 static int          cpp_demangle_read_number(struct cpp_demangle_data *, long *);
487 static int          cpp_demangle_read_number_as_string(struct cpp_demangle_data *,
488                         char **);
489 static int          cpp_demangle_read_nv_offset(struct cpp_demangle_data *);
490 static int          cpp_demangle_read_offset(struct cpp_demangle_data *);
491 static int          cpp_demangle_read_offset_number(struct cpp_demangle_data *);
492 static int          cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *,
493                         struct vector_type_qualifier *);
494 static int          cpp_demangle_read_sname(struct cpp_demangle_data *);
495 static int          cpp_demangle_read_subst(struct cpp_demangle_data *);
496 static int          cpp_demangle_read_subst_std(struct cpp_demangle_data *);
497 static int          cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *,
498                         const char *);
499 static int          cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *);
500 static int          cpp_demangle_read_tmpl_args(struct cpp_demangle_data *);
501 static int          cpp_demangle_read_tmpl_param(struct cpp_demangle_data *);
502 static int          cpp_demangle_read_type(struct cpp_demangle_data *,
503                         struct type_delimit *);
504 static int          cpp_demangle_read_type_flat(struct cpp_demangle_data *,
505                         char **);
506 static int          cpp_demangle_read_uqname(struct cpp_demangle_data *);
507 static int          cpp_demangle_read_v_offset(struct cpp_demangle_data *);
508 static char         *decode_fp_to_double(const char *, size_t);
509 static char         *decode_fp_to_float(const char *, size_t);
510 static char         *decode_fp_to_float128(const char *, size_t);
511 static char         *decode_fp_to_float80(const char *, size_t);
512 static char         *decode_fp_to_long_double(const char *, size_t);
513 static int          hex_to_dec(char);
514 static void         vector_read_cmd_dest(struct vector_read_cmd *);
515 static struct read_cmd_item *vector_read_cmd_find(struct vector_read_cmd *,
516                         enum read_cmd);
517 static int          vector_read_cmd_init(struct vector_read_cmd *);
518 static int          vector_read_cmd_pop(struct vector_read_cmd *);
519 static int          vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd,
520                         void *);
521 static void         vector_type_qualifier_dest(struct vector_type_qualifier *);
522 static int          vector_type_qualifier_init(struct vector_type_qualifier *);
523 static int          vector_type_qualifier_push(struct vector_type_qualifier *,
524                         enum type_qualifier);
525 
526 /**
527  * @brief Decode the input string by IA-64 C++ ABI style.
528  *
529  * GNU GCC v3 use IA-64 standard ABI.
530  * @return New allocated demangled string or NULL if failed.
531  * @todo 1. Testing and more test case. 2. Code cleaning.
532  */
533 char *
__cxa_demangle_gnu3(const char * org)534 __cxa_demangle_gnu3(const char *org)
535 {
536           struct cpp_demangle_data ddata;
537           struct vector_str ret_type;
538           struct type_delimit td;
539           ssize_t org_len;
540           unsigned int limit;
541           char *rtn;
542           bool has_ret, more_type;
543 
544           if (org == NULL)
545                     return (NULL);
546 
547           org_len = strlen(org);
548           // Try demangling as a type for short encodings
549           if ((org_len < 2) || (org[0] != '_' || org[1] != 'Z' )) {
550                     if (!cpp_demangle_data_init(&ddata, org))
551                               return (NULL);
552                     if (!cpp_demangle_read_type(&ddata, 0))
553                               goto clean;
554                     rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);
555                     goto clean;
556           }
557           if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {
558                     if ((rtn = malloc(org_len + 19)) == NULL)
559                               return (NULL);
560                     snprintf(rtn, org_len + 19,
561                         "global constructors keyed to %s", org + 11);
562                     return (rtn);
563           }
564 
565 
566           if (!cpp_demangle_data_init(&ddata, org + 2))
567                     return (NULL);
568 
569           rtn = NULL;
570           has_ret = more_type = false;
571 
572           if (!cpp_demangle_read_encoding(&ddata))
573                     goto clean;
574 
575           /*
576            * Pop function name from substitution candidate list.
577            */
578           if (*ddata.cur != 0 && ddata.subst.size >= 1) {
579                     if (!vector_str_pop(&ddata.subst))
580                               goto clean;
581           }
582 
583           td.paren = false;
584           td.firstp = true;
585           limit = 0;
586 
587           /*
588            * The first type is a return type if we just demangled template
589            * args. (the template args is right next to the function name,
590            * which means it's a template function)
591            */
592           if (ddata.is_tmpl) {
593                     ddata.is_tmpl = false;
594                     if (!vector_str_init(&ret_type))
595                               goto clean;
596                     ddata.cur_output = &ret_type;
597                     has_ret = true;
598           }
599 
600           while (*ddata.cur != '\0') {
601                     /*
602                      * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4
603                      */
604                     if (*ddata.cur == '@' && *(ddata.cur + 1) == '@')
605                               break;
606 
607                     if (has_ret) {
608                               /* Read return type */
609                               if (!cpp_demangle_read_type(&ddata, NULL))
610                                         goto clean;
611                     } else {
612                               /* Read function arg type */
613                               if (!cpp_demangle_read_type(&ddata, &td))
614                                         goto clean;
615                     }
616 
617                     if (has_ret) {
618                               /* Push return type to the beginning */
619                               if (!VEC_PUSH_STR(&ret_type, " "))
620                                         goto clean;
621                               if (!vector_str_push_vector_head(&ddata.output,
622                                   &ret_type))
623                                         goto clean;
624                               ddata.cur_output = &ddata.output;
625                               vector_str_dest(&ret_type);
626                               has_ret = false;
627                               more_type = true;
628                     } else if (more_type)
629                               more_type = false;
630                     if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
631                               goto clean;
632           }
633           if (more_type)
634                     goto clean;
635 
636           if (ddata.output.size == 0)
637                     goto clean;
638           if (td.paren && !VEC_PUSH_STR(&ddata.output, ")"))
639                     goto clean;
640           if (ddata.mem_vat && !VEC_PUSH_STR(&ddata.output, " volatile"))
641                     goto clean;
642           if (ddata.mem_cst && !VEC_PUSH_STR(&ddata.output, " const"))
643                     goto clean;
644           if (ddata.mem_rst && !VEC_PUSH_STR(&ddata.output, " restrict"))
645                     goto clean;
646           if (ddata.mem_ref && !VEC_PUSH_STR(&ddata.output, " &"))
647                     goto clean;
648           if (ddata.mem_rref && !VEC_PUSH_STR(&ddata.output, " &&"))
649                     goto clean;
650 
651           rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);
652 
653 clean:
654           if (has_ret)
655                     vector_str_dest(&ret_type);
656 
657           cpp_demangle_data_dest(&ddata);
658 
659           return (rtn);
660 }
661 
662 static void
cpp_demangle_data_dest(struct cpp_demangle_data * d)663 cpp_demangle_data_dest(struct cpp_demangle_data *d)
664 {
665 
666           if (d == NULL)
667                     return;
668 
669           vector_read_cmd_dest(&d->cmd);
670           vector_str_dest(&d->class_type);
671           vector_str_dest(&d->tmpl);
672           vector_str_dest(&d->subst);
673           vector_str_dest(&d->output);
674 }
675 
676 static int
cpp_demangle_data_init(struct cpp_demangle_data * d,const char * cur)677 cpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur)
678 {
679 
680           if (d == NULL || cur == NULL)
681                     return (0);
682 
683           if (!vector_str_init(&d->output))
684                     return (0);
685           if (!vector_str_init(&d->subst))
686                     goto clean1;
687           if (!vector_str_init(&d->tmpl))
688                     goto clean2;
689           if (!vector_str_init(&d->class_type))
690                     goto clean3;
691           if (!vector_read_cmd_init(&d->cmd))
692                     goto clean4;
693 
694           assert(d->output.container != NULL);
695           assert(d->subst.container != NULL);
696           assert(d->tmpl.container != NULL);
697           assert(d->class_type.container != NULL);
698 
699           d->mem_rst = false;
700           d->mem_vat = false;
701           d->mem_cst = false;
702           d->mem_ref = false;
703           d->mem_rref = false;
704           d->is_tmpl = false;
705           d->is_functype = false;
706           d->ref_qualifier = false;
707           d->push_qualifier = PUSH_ALL_QUALIFIER;
708           d->func_type = 0;
709           d->cur = cur;
710           d->cur_output = &d->output;
711           d->last_sname = NULL;
712 
713           return (1);
714 
715 clean4:
716           vector_str_dest(&d->class_type);
717 clean3:
718           vector_str_dest(&d->tmpl);
719 clean2:
720           vector_str_dest(&d->subst);
721 clean1:
722           vector_str_dest(&d->output);
723 
724           return (0);
725 }
726 
727 static int
cpp_demangle_push_fp(struct cpp_demangle_data * ddata,char * (* decoder)(const char *,size_t))728 cpp_demangle_push_fp(struct cpp_demangle_data *ddata,
729     char *(*decoder)(const char *, size_t))
730 {
731           size_t len;
732           int rtn;
733           const char *fp;
734           char *f;
735 
736           if (ddata == NULL || decoder == NULL)
737                     return (0);
738 
739           fp = ddata->cur;
740           while (*ddata->cur != 'E')
741                     ++ddata->cur;
742 
743           if ((f = decoder(fp, ddata->cur - fp)) == NULL)
744                     return (0);
745 
746           rtn = 0;
747           if ((len = strlen(f)) > 0)
748                     rtn = cpp_demangle_push_str(ddata, f, len);
749 
750           free(f);
751 
752           ++ddata->cur;
753 
754           return (rtn);
755 }
756 
757 static int
cpp_demangle_push_str(struct cpp_demangle_data * ddata,const char * str,size_t len)758 cpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str,
759     size_t len)
760 {
761 
762           if (ddata == NULL || str == NULL || len == 0)
763                     return (0);
764 
765           /*
766            * is_tmpl is used to check if the type (function arg) is right next
767            * to template args, and should always be cleared whenever new string
768            * pushed.
769            */
770           ddata->is_tmpl = false;
771 
772           return (vector_str_push(ddata->cur_output, str, len));
773 }
774 
775 static int
cpp_demangle_pop_str(struct cpp_demangle_data * ddata)776 cpp_demangle_pop_str(struct cpp_demangle_data *ddata)
777 {
778 
779           if (ddata == NULL)
780                     return (0);
781 
782           return (vector_str_pop(ddata->cur_output));
783 }
784 
785 static int
cpp_demangle_push_subst(struct cpp_demangle_data * ddata,const char * str,size_t len)786 cpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str,
787     size_t len)
788 {
789 
790           if (ddata == NULL || str == NULL || len == 0)
791                     return (0);
792 
793           if (!vector_str_find(&ddata->subst, str, len))
794                     return (vector_str_push(&ddata->subst, str, len));
795 
796           return (1);
797 }
798 
799 static int
cpp_demangle_push_subst_v(struct cpp_demangle_data * ddata,struct vector_str * v)800 cpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v)
801 {
802           size_t str_len;
803           int rtn;
804           char *str;
805 
806           if (ddata == NULL || v == NULL)
807                     return (0);
808 
809           if ((str = vector_str_get_flat(v, &str_len)) == NULL)
810                     return (0);
811 
812           rtn = cpp_demangle_push_subst(ddata, str, str_len);
813 
814           free(str);
815 
816           return (rtn);
817 }
818 
819 static int
cpp_demangle_push_type_qualifier(struct cpp_demangle_data * ddata,struct vector_type_qualifier * v,const char * type_str)820 cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata,
821     struct vector_type_qualifier *v, const char *type_str)
822 {
823           struct vector_str subst_v;
824           enum type_qualifier t;
825           size_t idx, e_idx, e_len;
826           char *buf;
827           int rtn;
828           bool cv;
829 
830           if (ddata == NULL || v == NULL)
831                     return (0);
832 
833           if ((idx = v->size) == 0)
834                     return (1);
835 
836           rtn = 0;
837           if (type_str != NULL) {
838                     if (!vector_str_init(&subst_v))
839                               return (0);
840                     if (!VEC_PUSH_STR(&subst_v, type_str))
841                               goto clean;
842           }
843 
844           cv = true;
845           e_idx = 0;
846           while (idx > 0) {
847                     switch (v->q_container[idx - 1]) {
848                     case TYPE_PTR:
849                               cv = false;
850                               if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
851                                         break;
852                               if (!DEM_PUSH_STR(ddata, "*"))
853                                         goto clean;
854                               if (type_str != NULL) {
855                                         if (!VEC_PUSH_STR(&subst_v, "*"))
856                                                   goto clean;
857                                         if (!cpp_demangle_push_subst_v(ddata,
858                                             &subst_v))
859                                                   goto clean;
860                               }
861                               break;
862 
863                     case TYPE_REF:
864                               cv = false;
865                               if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
866                                         break;
867                               if (!DEM_PUSH_STR(ddata, "&"))
868                                         goto clean;
869                               if (type_str != NULL) {
870                                         if (!VEC_PUSH_STR(&subst_v, "&"))
871                                                   goto clean;
872                                         if (!cpp_demangle_push_subst_v(ddata,
873                                             &subst_v))
874                                                   goto clean;
875                               }
876                               break;
877 
878                     case TYPE_RREF:
879                               cv = false;
880                               if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
881                                         break;
882                               if (!DEM_PUSH_STR(ddata, "&&"))
883                                         goto clean;
884                               if (type_str != NULL) {
885                                         if (!VEC_PUSH_STR(&subst_v, "&&"))
886                                                   goto clean;
887                                         if (!cpp_demangle_push_subst_v(ddata,
888                                             &subst_v))
889                                                   goto clean;
890                               }
891                               break;
892 
893                     case TYPE_CMX:
894                               cv = false;
895                               if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
896                                         break;
897                               if (!DEM_PUSH_STR(ddata, " complex"))
898                                         goto clean;
899                               if (type_str != NULL) {
900                                         if (!VEC_PUSH_STR(&subst_v, " complex"))
901                                                   goto clean;
902                                         if (!cpp_demangle_push_subst_v(ddata,
903                                             &subst_v))
904                                                   goto clean;
905                               }
906                               break;
907 
908                     case TYPE_IMG:
909                               cv = false;
910                               if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
911                                         break;
912                               if (!DEM_PUSH_STR(ddata, " imaginary"))
913                                         goto clean;
914                               if (type_str != NULL) {
915                                         if (!VEC_PUSH_STR(&subst_v, " imaginary"))
916                                                   goto clean;
917                                         if (!cpp_demangle_push_subst_v(ddata,
918                                             &subst_v))
919                                                   goto clean;
920                               }
921                               break;
922 
923                     case TYPE_EXT:
924                               cv = false;
925                               if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
926                                         break;
927                               if (v->ext_name.size == 0 ||
928                                   e_idx > v->ext_name.size - 1)
929                                         goto clean;
930                               if ((e_len = strlen(v->ext_name.container[e_idx])) ==
931                                   0)
932                                         goto clean;
933                               if ((buf = malloc(e_len + 2)) == NULL)
934                                         goto clean;
935                               snprintf(buf, e_len + 2, " %s",
936                                   v->ext_name.container[e_idx]);
937 
938                               if (!DEM_PUSH_STR(ddata, buf)) {
939                                         free(buf);
940                                         goto clean;
941                               }
942 
943                               if (type_str != NULL) {
944                                         if (!VEC_PUSH_STR(&subst_v, buf)) {
945                                                   free(buf);
946                                                   goto clean;
947                                         }
948                                         if (!cpp_demangle_push_subst_v(ddata,
949                                             &subst_v)) {
950                                                   free(buf);
951                                                   goto clean;
952                                         }
953                               }
954                               free(buf);
955                               ++e_idx;
956                               break;
957 
958                     case TYPE_RST:
959                               if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
960                                   cv)
961                                         break;
962                               if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
963                                         break;
964                               if (!DEM_PUSH_STR(ddata, " restrict"))
965                                         goto clean;
966                               if (type_str != NULL) {
967                                         if (!VEC_PUSH_STR(&subst_v, " restrict"))
968                                                   goto clean;
969                                         if (idx - 1 > 0) {
970                                                   t = v->q_container[idx - 2];
971                                                   if (t == TYPE_RST || t == TYPE_VAT ||
972                                                       t == TYPE_CST)
973                                                             break;
974                                         }
975                                         if (!cpp_demangle_push_subst_v(ddata,
976                                             &subst_v))
977                                                   goto clean;
978                               }
979                               break;
980 
981                     case TYPE_VAT:
982                               if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
983                                   cv)
984                                         break;
985                               if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
986                                         break;
987                               if (!DEM_PUSH_STR(ddata, " volatile"))
988                                         goto clean;
989                               if (type_str != NULL) {
990                                         if (!VEC_PUSH_STR(&subst_v, " volatile"))
991                                                   goto clean;
992                                         if (idx - 1 > 0) {
993                                                   t = v->q_container[idx - 2];
994                                                   if (t == TYPE_RST || t == TYPE_VAT ||
995                                                       t == TYPE_CST)
996                                                             break;
997                                         }
998                                         if (!cpp_demangle_push_subst_v(ddata,
999                                             &subst_v))
1000                                                   goto clean;
1001                               }
1002                               break;
1003 
1004                     case TYPE_CST:
1005                               if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
1006                                   cv)
1007                                         break;
1008                               if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
1009                                         break;
1010                               if (!DEM_PUSH_STR(ddata, " const"))
1011                                         goto clean;
1012                               if (type_str != NULL) {
1013                                         if (!VEC_PUSH_STR(&subst_v, " const"))
1014                                                   goto clean;
1015                                         if (idx - 1 > 0) {
1016                                                   t = v->q_container[idx - 2];
1017                                                   if (t == TYPE_RST || t == TYPE_VAT ||
1018                                                       t == TYPE_CST)
1019                                                             break;
1020                                         }
1021                                         if (!cpp_demangle_push_subst_v(ddata,
1022                                             &subst_v))
1023                                                   goto clean;
1024                               }
1025                               break;
1026 
1027                     case TYPE_VEC:
1028                               cv = false;
1029                               if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
1030                                         break;
1031                               if (v->ext_name.size == 0 ||
1032                                   e_idx > v->ext_name.size - 1)
1033                                         goto clean;
1034                               if ((e_len = strlen(v->ext_name.container[e_idx])) ==
1035                                   0)
1036                                         goto clean;
1037                               if ((buf = malloc(e_len + 12)) == NULL)
1038                                         goto clean;
1039                               snprintf(buf, e_len + 12, " __vector(%s)",
1040                                   v->ext_name.container[e_idx]);
1041                               if (!DEM_PUSH_STR(ddata, buf)) {
1042                                         free(buf);
1043                                         goto clean;
1044                               }
1045                               if (type_str != NULL) {
1046                                         if (!VEC_PUSH_STR(&subst_v, buf)) {
1047                                                   free(buf);
1048                                                   goto clean;
1049                                         }
1050                                         if (!cpp_demangle_push_subst_v(ddata,
1051                                             &subst_v)) {
1052                                                   free(buf);
1053                                                   goto clean;
1054                                         }
1055                               }
1056                               free(buf);
1057                               ++e_idx;
1058                               break;
1059                     }
1060                     --idx;
1061           }
1062 
1063           rtn = 1;
1064 clean:
1065           if (type_str != NULL)
1066                     vector_str_dest(&subst_v);
1067 
1068           return (rtn);
1069 }
1070 
1071 static int
cpp_demangle_get_subst(struct cpp_demangle_data * ddata,size_t idx)1072 cpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx)
1073 {
1074           size_t len;
1075 
1076           if (ddata == NULL || ddata->subst.size <= idx)
1077                     return (0);
1078           if ((len = strlen(ddata->subst.container[idx])) == 0)
1079                     return (0);
1080           if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len))
1081                     return (0);
1082 
1083           /* skip '_' */
1084           ++ddata->cur;
1085 
1086           return (1);
1087 }
1088 
1089 static int
cpp_demangle_get_tmpl_param(struct cpp_demangle_data * ddata,size_t idx)1090 cpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx)
1091 {
1092           size_t len;
1093 
1094           if (ddata == NULL || ddata->tmpl.size <= idx)
1095                     return (0);
1096           if ((len = strlen(ddata->tmpl.container[idx])) == 0)
1097                     return (0);
1098           if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len))
1099                     return (0);
1100 
1101           ++ddata->cur;
1102 
1103           return (1);
1104 }
1105 
1106 static int
cpp_demangle_read_array(struct cpp_demangle_data * ddata)1107 cpp_demangle_read_array(struct cpp_demangle_data *ddata)
1108 {
1109           size_t i, num_len, exp_len, p_idx, idx;
1110           const char *num;
1111           char *exp;
1112 
1113           if (ddata == NULL || *(++ddata->cur) == '\0')
1114                     return (0);
1115 
1116           if (*ddata->cur == '_') {
1117                     if (*(++ddata->cur) == '\0')
1118                               return (0);
1119 
1120                     if (!cpp_demangle_read_type(ddata, NULL))
1121                               return (0);
1122 
1123                     if (!DEM_PUSH_STR(ddata, " []"))
1124                               return (0);
1125           } else {
1126                     if (ELFTC_ISDIGIT(*ddata->cur) != 0) {
1127                               num = ddata->cur;
1128                               while (ELFTC_ISDIGIT(*ddata->cur) != 0)
1129                                         ++ddata->cur;
1130                               if (*ddata->cur != '_')
1131                                         return (0);
1132                               num_len = ddata->cur - num;
1133                               assert(num_len > 0);
1134                               if (*(++ddata->cur) == '\0')
1135                                         return (0);
1136                               if (!cpp_demangle_read_type(ddata, NULL))
1137                                         return (0);
1138                               if (!DEM_PUSH_STR(ddata, " ["))
1139                                         return (0);
1140                               if (!cpp_demangle_push_str(ddata, num, num_len))
1141                                         return (0);
1142                               if (!DEM_PUSH_STR(ddata, "]"))
1143                                         return (0);
1144                     } else {
1145                               p_idx = ddata->output.size;
1146                               if (!cpp_demangle_read_expression(ddata))
1147                                         return (0);
1148                               if ((exp = vector_str_substr(&ddata->output, p_idx,
1149                                          ddata->output.size - 1, &exp_len)) == NULL)
1150                                         return (0);
1151                               idx = ddata->output.size;
1152                               for (i = p_idx; i < idx; ++i)
1153                                         if (!vector_str_pop(&ddata->output)) {
1154                                                   free(exp);
1155                                                   return (0);
1156                                         }
1157                               if (*ddata->cur != '_') {
1158                                         free(exp);
1159                                         return (0);
1160                               }
1161                               ++ddata->cur;
1162                               if (*ddata->cur == '\0') {
1163                                         free(exp);
1164                                         return (0);
1165                               }
1166                               if (!cpp_demangle_read_type(ddata, NULL)) {
1167                                         free(exp);
1168                                         return (0);
1169                               }
1170                               if (!DEM_PUSH_STR(ddata, " [")) {
1171                                         free(exp);
1172                                         return (0);
1173                               }
1174                               if (!cpp_demangle_push_str(ddata, exp, exp_len)) {
1175                                         free(exp);
1176                                         return (0);
1177                               }
1178                               if (!DEM_PUSH_STR(ddata, "]")) {
1179                                         free(exp);
1180                                         return (0);
1181                               }
1182                               free(exp);
1183                     }
1184           }
1185 
1186           return (1);
1187 }
1188 
1189 static int
cpp_demangle_read_expr_primary(struct cpp_demangle_data * ddata)1190 cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata)
1191 {
1192           const char *num;
1193 
1194           if (ddata == NULL || *(++ddata->cur) == '\0')
1195                     return (0);
1196 
1197           if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') {
1198                     ddata->cur += 2;
1199                     if (*ddata->cur == '\0')
1200                               return (0);
1201                     if (!cpp_demangle_read_encoding(ddata))
1202                               return (0);
1203                     ++ddata->cur;
1204                     return (1);
1205           }
1206 
1207           switch (*ddata->cur) {
1208           case 'b':
1209                     if (*(ddata->cur + 2) != 'E')
1210                               return (0);
1211                     switch (*(++ddata->cur)) {
1212                     case '0':
1213                               ddata->cur += 2;
1214                               return (DEM_PUSH_STR(ddata, "false"));
1215                     case '1':
1216                               ddata->cur += 2;
1217                               return (DEM_PUSH_STR(ddata, "true"));
1218                     default:
1219                               return (0);
1220                     }
1221 
1222           case 'd':
1223                     ++ddata->cur;
1224                     return (cpp_demangle_push_fp(ddata, decode_fp_to_double));
1225 
1226           case 'e':
1227                     ++ddata->cur;
1228                     if (sizeof(long double) == 10)
1229                               return (cpp_demangle_push_fp(ddata,
1230                                   decode_fp_to_double));
1231                     return (cpp_demangle_push_fp(ddata, decode_fp_to_float80));
1232 
1233           case 'f':
1234                     ++ddata->cur;
1235                     return (cpp_demangle_push_fp(ddata, decode_fp_to_float));
1236 
1237           case 'g':
1238                     ++ddata->cur;
1239                     if (sizeof(long double) == 16)
1240                               return (cpp_demangle_push_fp(ddata,
1241                                   decode_fp_to_double));
1242                     return (cpp_demangle_push_fp(ddata, decode_fp_to_float128));
1243 
1244           case 'i':
1245           case 'j':
1246           case 'l':
1247           case 'm':
1248           case 'n':
1249           case 's':
1250           case 't':
1251           case 'x':
1252           case 'y':
1253                     if (*(++ddata->cur) == 'n') {
1254                               if (!DEM_PUSH_STR(ddata, "-"))
1255                                         return (0);
1256                               ++ddata->cur;
1257                     }
1258                     num = ddata->cur;
1259                     while (*ddata->cur != 'E') {
1260                               if (!ELFTC_ISDIGIT(*ddata->cur))
1261                                         return (0);
1262                               ++ddata->cur;
1263                     }
1264                     ++ddata->cur;
1265                     return (cpp_demangle_push_str(ddata, num,
1266                         ddata->cur - num - 1));
1267 
1268           default:
1269                     return (0);
1270           }
1271 }
1272 
1273 static int
cpp_demangle_read_expression(struct cpp_demangle_data * ddata)1274 cpp_demangle_read_expression(struct cpp_demangle_data *ddata)
1275 {
1276 
1277           if (ddata == NULL || *ddata->cur == '\0')
1278                     return (0);
1279 
1280           switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
1281           case SIMPLE_HASH('s', 't'):
1282                     ddata->cur += 2;
1283                     return (cpp_demangle_read_type(ddata, NULL));
1284 
1285           case SIMPLE_HASH('s', 'r'):
1286                     ddata->cur += 2;
1287                     if (!cpp_demangle_read_type(ddata, NULL))
1288                               return (0);
1289                     if (!cpp_demangle_read_uqname(ddata))
1290                               return (0);
1291                     if (*ddata->cur == 'I')
1292                               return (cpp_demangle_read_tmpl_args(ddata));
1293                     return (1);
1294 
1295           case SIMPLE_HASH('a', 'a'):
1296                     /* operator && */
1297                     ddata->cur += 2;
1298                     return (cpp_demangle_read_expression_binary(ddata, "&&", 2));
1299 
1300           case SIMPLE_HASH('a', 'd'):
1301                     /* operator & (unary) */
1302                     ddata->cur += 2;
1303                     return (cpp_demangle_read_expression_unary(ddata, "&", 1));
1304 
1305           case SIMPLE_HASH('a', 'n'):
1306                     /* operator & */
1307                     ddata->cur += 2;
1308                     return (cpp_demangle_read_expression_binary(ddata, "&", 1));
1309 
1310           case SIMPLE_HASH('a', 'N'):
1311                     /* operator &= */
1312                     ddata->cur += 2;
1313                     return (cpp_demangle_read_expression_binary(ddata, "&=", 2));
1314 
1315           case SIMPLE_HASH('a', 'S'):
1316                     /* operator = */
1317                     ddata->cur += 2;
1318                     return (cpp_demangle_read_expression_binary(ddata, "=", 1));
1319 
1320           case SIMPLE_HASH('c', 'l'):
1321                     /* operator () */
1322                     ddata->cur += 2;
1323                     return (cpp_demangle_read_expression_binary(ddata, "()", 2));
1324 
1325           case SIMPLE_HASH('c', 'm'):
1326                     /* operator , */
1327                     ddata->cur += 2;
1328                     return (cpp_demangle_read_expression_binary(ddata, ",", 1));
1329 
1330           case SIMPLE_HASH('c', 'o'):
1331                     /* operator ~ */
1332                     ddata->cur += 2;
1333                     return (cpp_demangle_read_expression_binary(ddata, "~", 1));
1334 
1335           case SIMPLE_HASH('c', 'v'):
1336                     /* operator (cast) */
1337                     ddata->cur += 2;
1338                     return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6));
1339 
1340           case SIMPLE_HASH('d', 'a'):
1341                     /* operator delete [] */
1342                     ddata->cur += 2;
1343                     return (cpp_demangle_read_expression_unary(ddata, "delete []", 9));
1344 
1345           case SIMPLE_HASH('d', 'e'):
1346                     /* operator * (unary) */
1347                     ddata->cur += 2;
1348                     return (cpp_demangle_read_expression_unary(ddata, "*", 1));
1349 
1350           case SIMPLE_HASH('d', 'l'):
1351                     /* operator delete */
1352                     ddata->cur += 2;
1353                     return (cpp_demangle_read_expression_unary(ddata, "delete", 6));
1354 
1355           case SIMPLE_HASH('d', 'v'):
1356                     /* operator / */
1357                     ddata->cur += 2;
1358                     return (cpp_demangle_read_expression_binary(ddata, "/", 1));
1359 
1360           case SIMPLE_HASH('d', 'V'):
1361                     /* operator /= */
1362                     ddata->cur += 2;
1363                     return (cpp_demangle_read_expression_binary(ddata, "/=", 2));
1364 
1365           case SIMPLE_HASH('e', 'o'):
1366                     /* operator ^ */
1367                     ddata->cur += 2;
1368                     return (cpp_demangle_read_expression_binary(ddata, "^", 1));
1369 
1370           case SIMPLE_HASH('e', 'O'):
1371                     /* operator ^= */
1372                     ddata->cur += 2;
1373                     return (cpp_demangle_read_expression_binary(ddata, "^=", 2));
1374 
1375           case SIMPLE_HASH('e', 'q'):
1376                     /* operator == */
1377                     ddata->cur += 2;
1378                     return (cpp_demangle_read_expression_binary(ddata, "==", 2));
1379 
1380           case SIMPLE_HASH('g', 'e'):
1381                     /* operator >= */
1382                     ddata->cur += 2;
1383                     return (cpp_demangle_read_expression_binary(ddata, ">=", 2));
1384 
1385           case SIMPLE_HASH('g', 't'):
1386                     /* operator > */
1387                     ddata->cur += 2;
1388                     return (cpp_demangle_read_expression_binary(ddata, ">", 1));
1389 
1390           case SIMPLE_HASH('i', 'x'):
1391                     /* operator [] */
1392                     ddata->cur += 2;
1393                     return (cpp_demangle_read_expression_binary(ddata, "[]", 2));
1394 
1395           case SIMPLE_HASH('l', 'e'):
1396                     /* operator <= */
1397                     ddata->cur += 2;
1398                     return (cpp_demangle_read_expression_binary(ddata, "<=", 2));
1399 
1400           case SIMPLE_HASH('l', 's'):
1401                     /* operator << */
1402                     ddata->cur += 2;
1403                     return (cpp_demangle_read_expression_binary(ddata, "<<", 2));
1404 
1405           case SIMPLE_HASH('l', 'S'):
1406                     /* operator <<= */
1407                     ddata->cur += 2;
1408                     return (cpp_demangle_read_expression_binary(ddata, "<<=", 3));
1409 
1410           case SIMPLE_HASH('l', 't'):
1411                     /* operator < */
1412                     ddata->cur += 2;
1413                     return (cpp_demangle_read_expression_binary(ddata, "<", 1));
1414 
1415           case SIMPLE_HASH('m', 'i'):
1416                     /* operator - */
1417                     ddata->cur += 2;
1418                     return (cpp_demangle_read_expression_binary(ddata, "-", 1));
1419 
1420           case SIMPLE_HASH('m', 'I'):
1421                     /* operator -= */
1422                     ddata->cur += 2;
1423                     return (cpp_demangle_read_expression_binary(ddata, "-=", 2));
1424 
1425           case SIMPLE_HASH('m', 'l'):
1426                     /* operator * */
1427                     ddata->cur += 2;
1428                     return (cpp_demangle_read_expression_binary(ddata, "*", 1));
1429 
1430           case SIMPLE_HASH('m', 'L'):
1431                     /* operator *= */
1432                     ddata->cur += 2;
1433                     return (cpp_demangle_read_expression_binary(ddata, "*=", 2));
1434 
1435           case SIMPLE_HASH('m', 'm'):
1436                     /* operator -- */
1437                     ddata->cur += 2;
1438                     return (cpp_demangle_read_expression_binary(ddata, "--", 2));
1439 
1440           case SIMPLE_HASH('n', 'a'):
1441                     /* operator new[] */
1442                     ddata->cur += 2;
1443                     return (cpp_demangle_read_expression_unary(ddata, "new []", 6));
1444 
1445           case SIMPLE_HASH('n', 'e'):
1446                     /* operator != */
1447                     ddata->cur += 2;
1448                     return (cpp_demangle_read_expression_binary(ddata, "!=", 2));
1449 
1450           case SIMPLE_HASH('n', 'g'):
1451                     /* operator - (unary) */
1452                     ddata->cur += 2;
1453                     return (cpp_demangle_read_expression_unary(ddata, "-", 1));
1454 
1455           case SIMPLE_HASH('n', 't'):
1456                     /* operator ! */
1457                     ddata->cur += 2;
1458                     return (cpp_demangle_read_expression_binary(ddata, "!", 1));
1459 
1460           case SIMPLE_HASH('n', 'w'):
1461                     /* operator new */
1462                     ddata->cur += 2;
1463                     return (cpp_demangle_read_expression_unary(ddata, "new", 3));
1464 
1465           case SIMPLE_HASH('o', 'o'):
1466                     /* operator || */
1467                     ddata->cur += 2;
1468                     return (cpp_demangle_read_expression_binary(ddata, "||", 2));
1469 
1470           case SIMPLE_HASH('o', 'r'):
1471                     /* operator | */
1472                     ddata->cur += 2;
1473                     return (cpp_demangle_read_expression_binary(ddata, "|", 1));
1474 
1475           case SIMPLE_HASH('o', 'R'):
1476                     /* operator |= */
1477                     ddata->cur += 2;
1478                     return (cpp_demangle_read_expression_binary(ddata, "|=", 2));
1479 
1480           case SIMPLE_HASH('p', 'l'):
1481                     /* operator + */
1482                     ddata->cur += 2;
1483                     return (cpp_demangle_read_expression_binary(ddata, "+", 1));
1484 
1485           case SIMPLE_HASH('p', 'L'):
1486                     /* operator += */
1487                     ddata->cur += 2;
1488                     return (cpp_demangle_read_expression_binary(ddata, "+=", 2));
1489 
1490           case SIMPLE_HASH('p', 'm'):
1491                     /* operator ->* */
1492                     ddata->cur += 2;
1493                     return (cpp_demangle_read_expression_binary(ddata, "->*", 3));
1494 
1495           case SIMPLE_HASH('p', 'p'):
1496                     /* operator ++ */
1497                     ddata->cur += 2;
1498                     return (cpp_demangle_read_expression_binary(ddata, "++", 2));
1499 
1500           case SIMPLE_HASH('p', 's'):
1501                     /* operator + (unary) */
1502                     ddata->cur += 2;
1503                     return (cpp_demangle_read_expression_unary(ddata, "+", 1));
1504 
1505           case SIMPLE_HASH('p', 't'):
1506                     /* operator -> */
1507                     ddata->cur += 2;
1508                     return (cpp_demangle_read_expression_binary(ddata, "->", 2));
1509 
1510           case SIMPLE_HASH('q', 'u'):
1511                     /* operator ? */
1512                     ddata->cur += 2;
1513                     return (cpp_demangle_read_expression_trinary(ddata, "?", 1,
1514                         ":", 1));
1515 
1516           case SIMPLE_HASH('r', 'm'):
1517                     /* operator % */
1518                     ddata->cur += 2;
1519                     return (cpp_demangle_read_expression_binary(ddata, "%", 1));
1520 
1521           case SIMPLE_HASH('r', 'M'):
1522                     /* operator %= */
1523                     ddata->cur += 2;
1524                     return (cpp_demangle_read_expression_binary(ddata, "%=", 2));
1525 
1526           case SIMPLE_HASH('r', 's'):
1527                     /* operator >> */
1528                     ddata->cur += 2;
1529                     return (cpp_demangle_read_expression_binary(ddata, ">>", 2));
1530 
1531           case SIMPLE_HASH('r', 'S'):
1532                     /* operator >>= */
1533                     ddata->cur += 2;
1534                     return (cpp_demangle_read_expression_binary(ddata, ">>=", 3));
1535 
1536           case SIMPLE_HASH('r', 'z'):
1537                     /* operator sizeof */
1538                     ddata->cur += 2;
1539                     return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6));
1540 
1541           case SIMPLE_HASH('s', 'v'):
1542                     /* operator sizeof */
1543                     ddata->cur += 2;
1544                     return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6));
1545           }
1546 
1547           switch (*ddata->cur) {
1548           case 'L':
1549                     return (cpp_demangle_read_expr_primary(ddata));
1550           case 'T':
1551                     return (cpp_demangle_read_tmpl_param(ddata));
1552           }
1553 
1554           return (0);
1555 }
1556 
1557 static int
cpp_demangle_read_expression_flat(struct cpp_demangle_data * ddata,char ** str)1558 cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str)
1559 {
1560           struct vector_str *output;
1561           size_t i, p_idx, idx, exp_len;
1562           char *exp;
1563 
1564           output = &ddata->output;
1565 
1566           p_idx = output->size;
1567 
1568           if (!cpp_demangle_read_expression(ddata))
1569                     return (0);
1570 
1571           if ((exp = vector_str_substr(output, p_idx, output->size - 1,
1572               &exp_len)) == NULL)
1573                     return (0);
1574 
1575           idx = output->size;
1576           for (i = p_idx; i < idx; ++i) {
1577                     if (!vector_str_pop(output)) {
1578                               free(exp);
1579                               return (0);
1580                     }
1581           }
1582 
1583           *str = exp;
1584 
1585           return (1);
1586 }
1587 
1588 static int
cpp_demangle_read_expression_binary(struct cpp_demangle_data * ddata,const char * name,size_t len)1589 cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata,
1590     const char *name, size_t len)
1591 {
1592 
1593           if (ddata == NULL || name == NULL || len == 0)
1594                     return (0);
1595           if (!cpp_demangle_read_expression(ddata))
1596                     return (0);
1597           if (!cpp_demangle_push_str(ddata, name, len))
1598                     return (0);
1599 
1600           return (cpp_demangle_read_expression(ddata));
1601 }
1602 
1603 static int
cpp_demangle_read_expression_unary(struct cpp_demangle_data * ddata,const char * name,size_t len)1604 cpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata,
1605     const char *name, size_t len)
1606 {
1607 
1608           if (ddata == NULL || name == NULL || len == 0)
1609                     return (0);
1610           if (!cpp_demangle_read_expression(ddata))
1611                     return (0);
1612 
1613           return (cpp_demangle_push_str(ddata, name, len));
1614 }
1615 
1616 static int
cpp_demangle_read_expression_trinary(struct cpp_demangle_data * ddata,const char * name1,size_t len1,const char * name2,size_t len2)1617 cpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata,
1618     const char *name1, size_t len1, const char *name2, size_t len2)
1619 {
1620 
1621           if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL ||
1622               len2 == 0)
1623                     return (0);
1624 
1625           if (!cpp_demangle_read_expression(ddata))
1626                     return (0);
1627           if (!cpp_demangle_push_str(ddata, name1, len1))
1628                     return (0);
1629           if (!cpp_demangle_read_expression(ddata))
1630                     return (0);
1631           if (!cpp_demangle_push_str(ddata, name2, len2))
1632                     return (0);
1633 
1634           return (cpp_demangle_read_expression(ddata));
1635 }
1636 
1637 static int
cpp_demangle_read_function(struct cpp_demangle_data * ddata,int * ext_c,struct vector_type_qualifier * v)1638 cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c,
1639     struct vector_type_qualifier *v)
1640 {
1641           struct type_delimit td;
1642           struct read_cmd_item *rc;
1643           size_t class_type_size, class_type_len, limit;
1644           const char *class_type;
1645           int i;
1646           bool paren, non_cv_qualifier;
1647 
1648           if (ddata == NULL || *ddata->cur != 'F' || v == NULL)
1649                     return (0);
1650 
1651           ++ddata->cur;
1652           if (*ddata->cur == 'Y') {
1653                     if (ext_c != NULL)
1654                               *ext_c = 1;
1655                     ++ddata->cur;
1656           }
1657 
1658           /* Return type */
1659           if (!cpp_demangle_read_type(ddata, NULL))
1660                     return (0);
1661 
1662           if (*ddata->cur != 'E') {
1663                     if (!DEM_PUSH_STR(ddata, " "))
1664                               return (0);
1665 
1666                     non_cv_qualifier = false;
1667                     if (v->size > 0) {
1668                               for (i = 0; (size_t) i < v->size; i++) {
1669                                         if (v->q_container[i] != TYPE_RST &&
1670                                             v->q_container[i] != TYPE_VAT &&
1671                                             v->q_container[i] != TYPE_CST) {
1672                                                   non_cv_qualifier = true;
1673                                                   break;
1674                                         }
1675                               }
1676                     }
1677 
1678                     paren = false;
1679                     rc = vector_read_cmd_find(&ddata->cmd, READ_PTRMEM);
1680                     if (non_cv_qualifier || rc != NULL) {
1681                               if (!DEM_PUSH_STR(ddata, "("))
1682                                         return (0);
1683                               paren = true;
1684                     }
1685 
1686                     /* Push non-cv qualifiers. */
1687                     ddata->push_qualifier = PUSH_NON_CV_QUALIFIER;
1688                     if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))
1689                               return (0);
1690 
1691                     if (rc) {
1692                               if (non_cv_qualifier && !DEM_PUSH_STR(ddata, " "))
1693                                         return (0);
1694                               if ((class_type_size = ddata->class_type.size) == 0)
1695                                         return (0);
1696                               class_type =
1697                                   ddata->class_type.container[class_type_size - 1];
1698                               if (class_type == NULL)
1699                                         return (0);
1700                               if ((class_type_len = strlen(class_type)) == 0)
1701                                         return (0);
1702                               if (!cpp_demangle_push_str(ddata, class_type,
1703                                   class_type_len))
1704                                         return (0);
1705                               if (!DEM_PUSH_STR(ddata, "::*"))
1706                                         return (0);
1707                               /* Push pointer-to-member qualifiers. */
1708                               ddata->push_qualifier = PUSH_ALL_QUALIFIER;
1709                               if (!cpp_demangle_push_type_qualifier(ddata, rc->data,
1710                                   NULL))
1711                                         return (0);
1712                               ++ddata->func_type;
1713                     }
1714 
1715                     if (paren) {
1716                               if (!DEM_PUSH_STR(ddata, ")"))
1717                                         return (0);
1718                               paren = false;
1719                     }
1720 
1721                     td.paren = false;
1722                     td.firstp = true;
1723                     limit = 0;
1724                     ddata->is_functype = true;
1725                     for (;;) {
1726                               if (!cpp_demangle_read_type(ddata, &td))
1727                                         return (0);
1728                               if (*ddata->cur == 'E')
1729                                         break;
1730                               if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
1731                                         return (0);
1732                     }
1733                     ddata->is_functype = false;
1734                     if (td.paren) {
1735                               if (!DEM_PUSH_STR(ddata, ")"))
1736                                         return (0);
1737                               td.paren = false;
1738                     }
1739 
1740                     /* Push CV qualifiers. */
1741                     ddata->push_qualifier = PUSH_CV_QUALIFIER;
1742                     if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))
1743                               return (0);
1744 
1745                     ddata->push_qualifier = PUSH_ALL_QUALIFIER;
1746 
1747                     /* Release type qualifier vector. */
1748                     vector_type_qualifier_dest(v);
1749                     if (!vector_type_qualifier_init(v))
1750                               return (0);
1751 
1752                     /* Push ref-qualifiers. */
1753                     if (ddata->ref_qualifier) {
1754                               switch (ddata->ref_qualifier_type) {
1755                               case TYPE_REF:
1756                                         if (!DEM_PUSH_STR(ddata, " &"))
1757                                                   return (0);
1758                                         break;
1759                               case TYPE_RREF:
1760                                         if (!DEM_PUSH_STR(ddata, " &&"))
1761                                                   return (0);
1762                                         break;
1763                               default:
1764                                         return (0);
1765                               }
1766                               ddata->ref_qualifier = false;
1767                     }
1768           }
1769 
1770           ++ddata->cur;
1771 
1772           return (1);
1773 }
1774 
1775 /* read encoding, encoding are function name, data name, special-name */
1776 static int
cpp_demangle_read_encoding(struct cpp_demangle_data * ddata)1777 cpp_demangle_read_encoding(struct cpp_demangle_data *ddata)
1778 {
1779           char *name, *type, *num_str;
1780           long offset;
1781           int rtn;
1782 
1783           if (ddata == NULL || *ddata->cur == '\0')
1784                     return (0);
1785 
1786           /* special name */
1787           switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
1788           case SIMPLE_HASH('G', 'A'):
1789                     if (!DEM_PUSH_STR(ddata, "hidden alias for "))
1790                               return (0);
1791                     ddata->cur += 2;
1792                     if (*ddata->cur == '\0')
1793                               return (0);
1794                     return (cpp_demangle_read_encoding(ddata));
1795 
1796           case SIMPLE_HASH('G', 'R'):
1797                     if (!DEM_PUSH_STR(ddata, "reference temporary #"))
1798                               return (0);
1799                     ddata->cur += 2;
1800                     if (*ddata->cur == '\0')
1801                               return (0);
1802                     if (!cpp_demangle_read_name_flat(ddata, &name))
1803                               return (0);
1804                     rtn = 0;
1805                     if (!cpp_demangle_read_number_as_string(ddata, &num_str))
1806                               goto clean1;
1807                     if (!DEM_PUSH_STR(ddata, num_str))
1808                               goto clean2;
1809                     if (!DEM_PUSH_STR(ddata, " for "))
1810                               goto clean2;
1811                     if (!DEM_PUSH_STR(ddata, name))
1812                               goto clean2;
1813                     rtn = 1;
1814           clean2:
1815                     free(num_str);
1816           clean1:
1817                     free(name);
1818                     return (rtn);
1819 
1820           case SIMPLE_HASH('G', 'T'):
1821                     ddata->cur += 2;
1822                     if (*ddata->cur == '\0')
1823                               return (0);
1824                     switch (*ddata->cur) {
1825                     case 'n':
1826                               if (!DEM_PUSH_STR(ddata, "non-transaction clone for "))
1827                                         return (0);
1828                               break;
1829                     case 't':
1830                     default:
1831                               if (!DEM_PUSH_STR(ddata, "transaction clone for "))
1832                                         return (0);
1833                               break;
1834                     }
1835                     ++ddata->cur;
1836                     return (cpp_demangle_read_encoding(ddata));
1837 
1838           case SIMPLE_HASH('G', 'V'):
1839                     /* sentry object for 1 time init */
1840                     if (!DEM_PUSH_STR(ddata, "guard variable for "))
1841                               return (0);
1842                     ddata->cur += 2;
1843                     break;
1844 
1845           case SIMPLE_HASH('T', 'c'):
1846                     /* virtual function covariant override thunk */
1847                     if (!DEM_PUSH_STR(ddata,
1848                         "virtual function covariant override "))
1849                               return (0);
1850                     ddata->cur += 2;
1851                     if (*ddata->cur == '\0')
1852                               return (0);
1853                     if (!cpp_demangle_read_offset(ddata))
1854                               return (0);
1855                     if (!cpp_demangle_read_offset(ddata))
1856                               return (0);
1857                     return (cpp_demangle_read_encoding(ddata));
1858 
1859           case SIMPLE_HASH('T', 'C'):
1860                     /* construction vtable */
1861                     if (!DEM_PUSH_STR(ddata, "construction vtable for "))
1862                               return (0);
1863                     ddata->cur += 2;
1864                     if (*ddata->cur == '\0')
1865                               return (0);
1866                     if (!cpp_demangle_read_type_flat(ddata, &type))
1867                               return (0);
1868                     rtn = 0;
1869                     if (!cpp_demangle_read_number(ddata, &offset))
1870                               goto clean3;
1871                     if (*ddata->cur++ != '_')
1872                               goto clean3;
1873                     if (!cpp_demangle_read_type(ddata, NULL))
1874                               goto clean3;
1875                     if (!DEM_PUSH_STR(ddata, "-in-"))
1876                               goto clean3;
1877                     if (!DEM_PUSH_STR(ddata, type))
1878                               goto clean3;
1879                     rtn = 1;
1880           clean3:
1881                     free(type);
1882                     return (rtn);
1883 
1884           case SIMPLE_HASH('T', 'D'):
1885                     /* typeinfo common proxy */
1886                     break;
1887 
1888           case SIMPLE_HASH('T', 'F'):
1889                     /* typeinfo fn */
1890                     if (!DEM_PUSH_STR(ddata, "typeinfo fn for "))
1891                               return (0);
1892                     ddata->cur += 2;
1893                     if (*ddata->cur == '\0')
1894                               return (0);
1895                     return (cpp_demangle_read_type(ddata, NULL));
1896 
1897           case SIMPLE_HASH('T', 'h'):
1898                     /* virtual function non-virtual override thunk */
1899                     if (!DEM_PUSH_STR(ddata,
1900                         "virtual function non-virtual override "))
1901                               return (0);
1902                     ddata->cur += 2;
1903                     if (*ddata->cur == '\0')
1904                               return (0);
1905                     if (!cpp_demangle_read_nv_offset(ddata))
1906                               return (0);
1907                     return (cpp_demangle_read_encoding(ddata));
1908 
1909           case SIMPLE_HASH('T', 'H'):
1910                     /* TLS init function */
1911                     if (!DEM_PUSH_STR(ddata, "TLS init function for "))
1912                               return (0);
1913                     ddata->cur += 2;
1914                     if (*ddata->cur == '\0')
1915                               return (0);
1916                     break;
1917 
1918           case SIMPLE_HASH('T', 'I'):
1919                     /* typeinfo structure */
1920                     if (!DEM_PUSH_STR(ddata, "typeinfo for "))
1921                               return (0);
1922                     ddata->cur += 2;
1923                     if (*ddata->cur == '\0')
1924                               return (0);
1925                     return (cpp_demangle_read_type(ddata, NULL));
1926 
1927           case SIMPLE_HASH('T', 'J'):
1928                     /* java class */
1929                     if (!DEM_PUSH_STR(ddata, "java Class for "))
1930                               return (0);
1931                     ddata->cur += 2;
1932                     if (*ddata->cur == '\0')
1933                               return (0);
1934                     return (cpp_demangle_read_type(ddata, NULL));
1935 
1936           case SIMPLE_HASH('T', 'S'):
1937                     /* RTTI name (NTBS) */
1938                     if (!DEM_PUSH_STR(ddata, "typeinfo name for "))
1939                               return (0);
1940                     ddata->cur += 2;
1941                     if (*ddata->cur == '\0')
1942                               return (0);
1943                     return (cpp_demangle_read_type(ddata, NULL));
1944 
1945           case SIMPLE_HASH('T', 'T'):
1946                     /* VTT table */
1947                     if (!DEM_PUSH_STR(ddata, "VTT for "))
1948                               return (0);
1949                     ddata->cur += 2;
1950                     if (*ddata->cur == '\0')
1951                               return (0);
1952                     return (cpp_demangle_read_type(ddata, NULL));
1953 
1954           case SIMPLE_HASH('T', 'v'):
1955                     /* virtual function virtual override thunk */
1956                     if (!DEM_PUSH_STR(ddata, "virtual function virtual override "))
1957                               return (0);
1958                     ddata->cur += 2;
1959                     if (*ddata->cur == '\0')
1960                               return (0);
1961                     if (!cpp_demangle_read_v_offset(ddata))
1962                               return (0);
1963                     return (cpp_demangle_read_encoding(ddata));
1964 
1965           case SIMPLE_HASH('T', 'V'):
1966                     /* virtual table */
1967                     if (!DEM_PUSH_STR(ddata, "vtable for "))
1968                               return (0);
1969                     ddata->cur += 2;
1970                     if (*ddata->cur == '\0')
1971                               return (0);
1972                     return (cpp_demangle_read_type(ddata, NULL));
1973 
1974           case SIMPLE_HASH('T', 'W'):
1975                     /* TLS wrapper function */
1976                     if (!DEM_PUSH_STR(ddata, "TLS wrapper function for "))
1977                               return (0);
1978                     ddata->cur += 2;
1979                     if (*ddata->cur == '\0')
1980                               return (0);
1981                     break;
1982           }
1983 
1984           return (cpp_demangle_read_name(ddata));
1985 }
1986 
1987 static int
cpp_demangle_read_local_name(struct cpp_demangle_data * ddata)1988 cpp_demangle_read_local_name(struct cpp_demangle_data *ddata)
1989 {
1990           struct vector_str local_name;
1991           struct type_delimit td;
1992           size_t limit;
1993           bool  more_type;
1994 
1995           if (ddata == NULL)
1996                     return (0);
1997           if (*(++ddata->cur) == '\0')
1998                     return (0);
1999 
2000           if (!vector_str_init(&local_name))
2001                     return (0);
2002           ddata->cur_output = &local_name;
2003 
2004           if (!cpp_demangle_read_encoding(ddata)) {
2005                     vector_str_dest(&local_name);
2006                     return (0);
2007           }
2008 
2009           ddata->cur_output = &ddata->output;
2010 
2011           td.paren = false;
2012           td.firstp = true;
2013           more_type = false;
2014           limit = 0;
2015 
2016           /*
2017            * The first type is a return type if we just demangled template
2018            * args. (the template args is right next to the function name,
2019            * which means it's a template function)
2020            */
2021           if (ddata->is_tmpl) {
2022                     ddata->is_tmpl = false;
2023 
2024                     /* Read return type */
2025                     if (!cpp_demangle_read_type(ddata, NULL)) {
2026                               vector_str_dest(&local_name);
2027                               return (0);
2028                     }
2029 
2030                     more_type = true;
2031           }
2032 
2033           /* Now we can push the name after possible return type is handled. */
2034           if (!vector_str_push_vector(&ddata->output, &local_name)) {
2035                     vector_str_dest(&local_name);
2036                     return (0);
2037           }
2038           vector_str_dest(&local_name);
2039 
2040           while (*ddata->cur != '\0') {
2041                     if (!cpp_demangle_read_type(ddata, &td))
2042                               return (0);
2043                     if (more_type)
2044                               more_type = false;
2045                     if (*ddata->cur == 'E')
2046                               break;
2047                     if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
2048                               return (0);
2049           }
2050           if (more_type)
2051                     return (0);
2052 
2053           if (*(++ddata->cur) == '\0')
2054                     return (0);
2055           if (td.paren == true) {
2056                     if (!DEM_PUSH_STR(ddata, ")"))
2057                               return (0);
2058                     td.paren = false;
2059           }
2060           if (*ddata->cur == 's')
2061                     ++ddata->cur;
2062           else {
2063                     if (!DEM_PUSH_STR(ddata, "::"))
2064                               return (0);
2065                     if (!cpp_demangle_read_name(ddata))
2066                               return (0);
2067           }
2068           if (*ddata->cur == '_') {
2069                     ++ddata->cur;
2070                     while (ELFTC_ISDIGIT(*ddata->cur) != 0)
2071                               ++ddata->cur;
2072           }
2073 
2074           return (1);
2075 }
2076 
2077 static int
cpp_demangle_read_name(struct cpp_demangle_data * ddata)2078 cpp_demangle_read_name(struct cpp_demangle_data *ddata)
2079 {
2080           struct vector_str *output, v;
2081           size_t p_idx, subst_str_len;
2082           int rtn;
2083           char *subst_str;
2084 
2085           if (ddata == NULL || *ddata->cur == '\0')
2086                     return (0);
2087 
2088           output = ddata->cur_output;
2089 
2090           subst_str = NULL;
2091 
2092           switch (*ddata->cur) {
2093           case 'S':
2094                     return (cpp_demangle_read_subst(ddata));
2095           case 'N':
2096                     return (cpp_demangle_read_nested_name(ddata));
2097           case 'Z':
2098                     return (cpp_demangle_read_local_name(ddata));
2099           }
2100 
2101           if (!vector_str_init(&v))
2102                     return (0);
2103 
2104           p_idx = output->size;
2105           rtn = 0;
2106           if (!cpp_demangle_read_uqname(ddata))
2107                     goto clean;
2108           if ((subst_str = vector_str_substr(output, p_idx, output->size - 1,
2109               &subst_str_len)) == NULL)
2110                     goto clean;
2111           if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) {
2112                     rtn = 1;
2113                     goto clean;
2114           }
2115           if (!vector_str_push(&v, subst_str, subst_str_len))
2116                     goto clean;
2117           if (!cpp_demangle_push_subst_v(ddata, &v))
2118                     goto clean;
2119 
2120           if (*ddata->cur == 'I') {
2121                     p_idx = output->size;
2122                     if (!cpp_demangle_read_tmpl_args(ddata))
2123                               goto clean;
2124                     free(subst_str);
2125                     if ((subst_str = vector_str_substr(output, p_idx,
2126                         output->size - 1, &subst_str_len)) == NULL)
2127                               goto clean;
2128                     if (!vector_str_push(&v, subst_str, subst_str_len))
2129                               goto clean;
2130                     if (!cpp_demangle_push_subst_v(ddata, &v))
2131                               goto clean;
2132           }
2133 
2134           rtn = 1;
2135 
2136 clean:
2137           free(subst_str);
2138           vector_str_dest(&v);
2139 
2140           return (rtn);
2141 }
2142 
2143 static int
cpp_demangle_read_name_flat(struct cpp_demangle_data * ddata,char ** str)2144 cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str)
2145 {
2146           struct vector_str *output;
2147           size_t i, p_idx, idx, name_len;
2148           char *name;
2149 
2150           output = ddata->cur_output;
2151 
2152           p_idx = output->size;
2153 
2154           if (!cpp_demangle_read_name(ddata))
2155                     return (0);
2156 
2157           if ((name = vector_str_substr(output, p_idx, output->size - 1,
2158               &name_len)) == NULL)
2159                     return (0);
2160 
2161           idx = output->size;
2162           for (i = p_idx; i < idx; ++i) {
2163                     if (!vector_str_pop(output)) {
2164                               free(name);
2165                               return (0);
2166                     }
2167           }
2168 
2169           *str = name;
2170 
2171           return (1);
2172 }
2173 
2174 static int
cpp_demangle_read_nested_name(struct cpp_demangle_data * ddata)2175 cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata)
2176 {
2177           struct vector_str *output, v;
2178           size_t limit, p_idx, subst_str_len;
2179           int rtn;
2180           char *subst_str;
2181 
2182           if (ddata == NULL || *ddata->cur != 'N')
2183                     return (0);
2184           if (*(++ddata->cur) == '\0')
2185                     return (0);
2186 
2187           do {
2188                     switch (*ddata->cur) {
2189                     case 'r':
2190                               ddata->mem_rst = true;
2191                               break;
2192                     case 'V':
2193                               ddata->mem_vat = true;
2194                               break;
2195                     case 'K':
2196                               ddata->mem_cst = true;
2197                               break;
2198                     case 'R':
2199                               ddata->mem_ref = true;
2200                               break;
2201                     case 'O':
2202                               ddata->mem_rref = true;
2203                               break;
2204                     default:
2205                               goto next;
2206                     }
2207           } while (*(++ddata->cur));
2208 
2209 next:
2210           output = ddata->cur_output;
2211           if (!vector_str_init(&v))
2212                     return (0);
2213 
2214           rtn = 0;
2215           limit = 0;
2216           for (;;) {
2217                     p_idx = output->size;
2218                     switch (*ddata->cur) {
2219                     case 'I':
2220                               if (!cpp_demangle_read_tmpl_args(ddata))
2221                                         goto clean;
2222                               break;
2223                     case 'S':
2224                               if (!cpp_demangle_read_subst(ddata))
2225                                         goto clean;
2226                               break;
2227                     case 'T':
2228                               if (!cpp_demangle_read_tmpl_param(ddata))
2229                                         goto clean;
2230                               break;
2231                     default:
2232                               if (!cpp_demangle_read_uqname(ddata))
2233                                         goto clean;
2234                     }
2235 
2236                     if (p_idx == output->size)
2237                               goto next_comp;
2238                     if ((subst_str = vector_str_substr(output, p_idx,
2239                         output->size - 1, &subst_str_len)) == NULL)
2240                               goto clean;
2241                     if (!vector_str_push(&v, subst_str, subst_str_len)) {
2242                               free(subst_str);
2243                               goto clean;
2244                     }
2245                     free(subst_str);
2246 
2247                     if (!cpp_demangle_push_subst_v(ddata, &v))
2248                               goto clean;
2249 
2250           next_comp:
2251                     if (*ddata->cur == 'E')
2252                               break;
2253                     else if (*ddata->cur != 'I' && *ddata->cur != 'C' &&
2254                         *ddata->cur != 'D' && p_idx != output->size) {
2255                               if (!DEM_PUSH_STR(ddata, "::"))
2256                                         goto clean;
2257                               if (!VEC_PUSH_STR(&v, "::"))
2258                                         goto clean;
2259                     }
2260                     if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
2261                               goto clean;
2262           }
2263 
2264           ++ddata->cur;
2265           rtn = 1;
2266 
2267 clean:
2268           vector_str_dest(&v);
2269 
2270           return (rtn);
2271 }
2272 
2273 /*
2274  * read number
2275  * number ::= [n] <decimal>
2276  */
2277 static int
cpp_demangle_read_number(struct cpp_demangle_data * ddata,long * rtn)2278 cpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn)
2279 {
2280           long len, negative_factor;
2281 
2282           if (ddata == NULL || rtn == NULL)
2283                     return (0);
2284 
2285           negative_factor = 1;
2286           if (*ddata->cur == 'n') {
2287                     negative_factor = -1;
2288 
2289                     ++ddata->cur;
2290           }
2291           if (ELFTC_ISDIGIT(*ddata->cur) == 0)
2292                     return (0);
2293 
2294           errno = 0;
2295           if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 &&
2296               errno != 0)
2297                     return (0);
2298 
2299           while (ELFTC_ISDIGIT(*ddata->cur) != 0)
2300                     ++ddata->cur;
2301 
2302           assert(len >= 0);
2303           assert(negative_factor == 1 || negative_factor == -1);
2304 
2305           *rtn = len * negative_factor;
2306 
2307           return (1);
2308 }
2309 
2310 static int
cpp_demangle_read_number_as_string(struct cpp_demangle_data * ddata,char ** str)2311 cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str)
2312 {
2313           long n;
2314 
2315           if (!cpp_demangle_read_number(ddata, &n)) {
2316                     *str = NULL;
2317                     return (0);
2318           }
2319 
2320           if (asprintf(str, "%ld", n) < 0) {
2321                     *str = NULL;
2322                     return (0);
2323           }
2324 
2325           return (1);
2326 }
2327 
2328 static int
cpp_demangle_read_nv_offset(struct cpp_demangle_data * ddata)2329 cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata)
2330 {
2331 
2332           if (ddata == NULL)
2333                     return (0);
2334 
2335           if (!DEM_PUSH_STR(ddata, "offset : "))
2336                     return (0);
2337 
2338           return (cpp_demangle_read_offset_number(ddata));
2339 }
2340 
2341 /* read offset, offset are nv-offset, v-offset */
2342 static int
cpp_demangle_read_offset(struct cpp_demangle_data * ddata)2343 cpp_demangle_read_offset(struct cpp_demangle_data *ddata)
2344 {
2345 
2346           if (ddata == NULL)
2347                     return (0);
2348 
2349           if (*ddata->cur == 'h') {
2350                     ++ddata->cur;
2351                     return (cpp_demangle_read_nv_offset(ddata));
2352           } else if (*ddata->cur == 'v') {
2353                     ++ddata->cur;
2354                     return (cpp_demangle_read_v_offset(ddata));
2355           }
2356 
2357           return (0);
2358 }
2359 
2360 static int
cpp_demangle_read_offset_number(struct cpp_demangle_data * ddata)2361 cpp_demangle_read_offset_number(struct cpp_demangle_data *ddata)
2362 {
2363           bool negative;
2364           const char *start;
2365 
2366           if (ddata == NULL || *ddata->cur == '\0')
2367                     return (0);
2368 
2369           /* offset could be negative */
2370           if (*ddata->cur == 'n') {
2371                     negative = true;
2372                     start = ddata->cur + 1;
2373           } else {
2374                     negative = false;
2375                     start = ddata->cur;
2376           }
2377 
2378           while (*ddata->cur != '_')
2379                     ++ddata->cur;
2380 
2381           if (negative && !DEM_PUSH_STR(ddata, "-"))
2382                     return (0);
2383 
2384           assert(start != NULL);
2385 
2386           if (!cpp_demangle_push_str(ddata, start, ddata->cur - start))
2387                     return (0);
2388           if (!DEM_PUSH_STR(ddata, " "))
2389                     return (0);
2390 
2391           ++ddata->cur;
2392 
2393           return (1);
2394 }
2395 
2396 static int
cpp_demangle_read_pointer_to_member(struct cpp_demangle_data * ddata,struct vector_type_qualifier * v)2397 cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata,
2398     struct vector_type_qualifier *v)
2399 {
2400           size_t class_type_len, i, idx, p_idx;
2401           int p_func_type, rtn;
2402           char *class_type;
2403 
2404           if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0')
2405                     return (0);
2406 
2407           p_idx = ddata->output.size;
2408           if (!cpp_demangle_read_type(ddata, NULL))
2409                     return (0);
2410 
2411           if ((class_type = vector_str_substr(&ddata->output, p_idx,
2412               ddata->output.size - 1, &class_type_len)) == NULL)
2413                     return (0);
2414 
2415           rtn = 0;
2416           idx = ddata->output.size;
2417           for (i = p_idx; i < idx; ++i)
2418                     if (!vector_str_pop(&ddata->output))
2419                               goto clean1;
2420 
2421           if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM, v))
2422                     goto clean1;
2423 
2424           if (!vector_str_push(&ddata->class_type, class_type, class_type_len))
2425                     goto clean2;
2426 
2427           p_func_type = ddata->func_type;
2428           if (!cpp_demangle_read_type(ddata, NULL))
2429                     goto clean3;
2430 
2431           if (p_func_type == ddata->func_type) {
2432                     if (!DEM_PUSH_STR(ddata, " "))
2433                               goto clean3;
2434                     if (!cpp_demangle_push_str(ddata, class_type, class_type_len))
2435                               goto clean3;
2436                     if (!DEM_PUSH_STR(ddata, "::*"))
2437                               goto clean3;
2438           }
2439 
2440           rtn = 1;
2441 clean3:
2442           if (!vector_str_pop(&ddata->class_type))
2443                     rtn = 0;
2444 clean2:
2445           if (!vector_read_cmd_pop(&ddata->cmd))
2446                     rtn = 0;
2447 clean1:
2448           free(class_type);
2449 
2450           vector_type_qualifier_dest(v);
2451           if (!vector_type_qualifier_init(v))
2452                     return (0);
2453 
2454           return (rtn);
2455 }
2456 
2457 /* read source-name, source-name is <len> <ID> */
2458 static int
cpp_demangle_read_sname(struct cpp_demangle_data * ddata)2459 cpp_demangle_read_sname(struct cpp_demangle_data *ddata)
2460 {
2461           long len;
2462           int err;
2463 
2464           if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 ||
2465               len <= 0)
2466                     return (0);
2467 
2468           if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0))
2469                     err = DEM_PUSH_STR(ddata, "(anonymous namespace)");
2470           else
2471                     err = cpp_demangle_push_str(ddata, ddata->cur, len);
2472 
2473           if (err == 0)
2474                     return (0);
2475 
2476           assert(ddata->cur_output->size > 0);
2477           if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == NULL)
2478                     ddata->last_sname =
2479                         ddata->cur_output->container[ddata->output.size - 1];
2480 
2481           ddata->cur += len;
2482 
2483           return (1);
2484 }
2485 
2486 static int
cpp_demangle_read_subst(struct cpp_demangle_data * ddata)2487 cpp_demangle_read_subst(struct cpp_demangle_data *ddata)
2488 {
2489           long nth;
2490 
2491           if (ddata == NULL || *ddata->cur == '\0')
2492                     return (0);
2493 
2494           /* abbreviations of the form Sx */
2495           switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
2496           case SIMPLE_HASH('S', 'a'):
2497                     /* std::allocator */
2498                     if (!DEM_PUSH_STR(ddata, "std::allocator"))
2499                               return (0);
2500                     ddata->cur += 2;
2501                     if (*ddata->cur == 'I')
2502                               return (cpp_demangle_read_subst_stdtmpl(ddata,
2503                                   "std::allocator"));
2504                     return (1);
2505 
2506           case SIMPLE_HASH('S', 'b'):
2507                     /* std::basic_string */
2508                     if (!DEM_PUSH_STR(ddata, "std::basic_string"))
2509                               return (0);
2510                     ddata->cur += 2;
2511                     if (*ddata->cur == 'I')
2512                               return (cpp_demangle_read_subst_stdtmpl(ddata,
2513                                   "std::basic_string"));
2514                     return (1);
2515 
2516           case SIMPLE_HASH('S', 'd'):
2517                     /* std::basic_iostream<char, std::char_traits<char> > */
2518                     if (!DEM_PUSH_STR(ddata, "std::basic_iostream<char, "
2519                         "std::char_traits<char> >"))
2520                               return (0);
2521                     ddata->last_sname = "basic_iostream";
2522                     ddata->cur += 2;
2523                     if (*ddata->cur == 'I')
2524                               return (cpp_demangle_read_subst_stdtmpl(ddata,
2525                                   "std::basic_iostream<char, std::char_traits"
2526                                         "<char> >"));
2527                     return (1);
2528 
2529           case SIMPLE_HASH('S', 'i'):
2530                     /* std::basic_istream<char, std::char_traits<char> > */
2531                     if (!DEM_PUSH_STR(ddata, "std::basic_istream<char, "
2532                         "std::char_traits<char> >"))
2533                               return (0);
2534                     ddata->last_sname = "basic_istream";
2535                     ddata->cur += 2;
2536                     if (*ddata->cur == 'I')
2537                               return (cpp_demangle_read_subst_stdtmpl(ddata,
2538                                   "std::basic_istream<char, std::char_traits"
2539                                         "<char> >"));
2540                     return (1);
2541 
2542           case SIMPLE_HASH('S', 'o'):
2543                     /* std::basic_ostream<char, std::char_traits<char> > */
2544                     if (!DEM_PUSH_STR(ddata, "std::basic_ostream<char, "
2545                         "std::char_traits<char> >"))
2546                               return (0);
2547                     ddata->last_sname = "basic_ostream";
2548                     ddata->cur += 2;
2549                     if (*ddata->cur == 'I')
2550                               return (cpp_demangle_read_subst_stdtmpl(ddata,
2551                                   "std::basic_ostream<char, std::char_traits"
2552                                         "<char> >"));
2553                     return (1);
2554 
2555           case SIMPLE_HASH('S', 's'):
2556                     /*
2557                      * std::basic_string<char, std::char_traits<char>,
2558                      * std::allocator<char> >
2559                      *
2560                      * a.k.a std::string
2561                      */
2562                     if (!DEM_PUSH_STR(ddata, "std::basic_string<char, "
2563                         "std::char_traits<char>, std::allocator<char> >"))
2564                               return (0);
2565                     ddata->last_sname = "string";
2566                     ddata->cur += 2;
2567                     if (*ddata->cur == 'I')
2568                               return (cpp_demangle_read_subst_stdtmpl(ddata,
2569                                   "std::basic_string<char, std::char_traits<char>,"
2570                                         " std::allocator<char> >"));
2571                     return (1);
2572 
2573           case SIMPLE_HASH('S', 't'):
2574                     /* std:: */
2575                     return (cpp_demangle_read_subst_std(ddata));
2576           }
2577 
2578           if (*(++ddata->cur) == '\0')
2579                     return (0);
2580 
2581           /* Skip unknown substitution abbreviations. */
2582           if (!(*ddata->cur >= '0' && *ddata->cur <= '9') &&
2583               !(*ddata->cur >= 'A' && *ddata->cur <= 'Z') &&
2584               *ddata->cur != '_') {
2585                     ++ddata->cur;
2586                     return (1);
2587           }
2588 
2589           /* substitution */
2590           if (*ddata->cur == '_')
2591                     return (cpp_demangle_get_subst(ddata, 0));
2592           else {
2593                     errno = 0;
2594                     /* substitution number is base 36 */
2595                     if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 &&
2596                         errno != 0)
2597                               return (0);
2598 
2599                     /* first was '_', so increase one */
2600                     ++nth;
2601 
2602                     while (*ddata->cur != '_')
2603                               ++ddata->cur;
2604 
2605                     assert(nth > 0);
2606 
2607                     return (cpp_demangle_get_subst(ddata, nth));
2608           }
2609 
2610           /* NOTREACHED */
2611           return (0);
2612 }
2613 
2614 static int
cpp_demangle_read_subst_std(struct cpp_demangle_data * ddata)2615 cpp_demangle_read_subst_std(struct cpp_demangle_data *ddata)
2616 {
2617           struct vector_str *output, v;
2618           size_t p_idx, subst_str_len;
2619           int rtn;
2620           char *subst_str;
2621 
2622           if (ddata == NULL)
2623                     return (0);
2624 
2625           if (!vector_str_init(&v))
2626                     return (0);
2627 
2628           subst_str = NULL;
2629           rtn = 0;
2630           if (!DEM_PUSH_STR(ddata, "std::"))
2631                     goto clean;
2632 
2633           if (!VEC_PUSH_STR(&v, "std::"))
2634                     goto clean;
2635 
2636           ddata->cur += 2;
2637 
2638           output = ddata->cur_output;
2639 
2640           p_idx = output->size;
2641           if (!cpp_demangle_read_uqname(ddata))
2642                     goto clean;
2643 
2644           if ((subst_str = vector_str_substr(output, p_idx, output->size - 1,
2645               &subst_str_len)) == NULL)
2646                     goto clean;
2647 
2648           if (!vector_str_push(&v, subst_str, subst_str_len))
2649                     goto clean;
2650 
2651           if (!cpp_demangle_push_subst_v(ddata, &v))
2652                     goto clean;
2653 
2654           if (*ddata->cur == 'I') {
2655                     p_idx = output->size;
2656                     if (!cpp_demangle_read_tmpl_args(ddata))
2657                               goto clean;
2658                     free(subst_str);
2659                     if ((subst_str = vector_str_substr(output, p_idx,
2660                         output->size - 1, &subst_str_len)) == NULL)
2661                               goto clean;
2662                     if (!vector_str_push(&v, subst_str, subst_str_len))
2663                               goto clean;
2664                     if (!cpp_demangle_push_subst_v(ddata, &v))
2665                               goto clean;
2666           }
2667 
2668           rtn = 1;
2669 clean:
2670           free(subst_str);
2671           vector_str_dest(&v);
2672 
2673           return (rtn);
2674 }
2675 
2676 static int
cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data * ddata,const char * str)2677 cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata,
2678     const char *str)
2679 {
2680           struct vector_str *output;
2681           size_t p_idx, substr_len, len;
2682           int rtn;
2683           char *subst_str, *substr;
2684 
2685           if (ddata == NULL || str == NULL)
2686                     return (0);
2687 
2688           if ((len = strlen(str)) == 0)
2689                     return (0);
2690 
2691           output = ddata->cur_output;
2692 
2693           p_idx = output->size;
2694           substr = NULL;
2695           subst_str = NULL;
2696 
2697           if (!cpp_demangle_read_tmpl_args(ddata))
2698                     return (0);
2699           if ((substr = vector_str_substr(output, p_idx, output->size - 1,
2700               &substr_len)) == NULL)
2701                     return (0);
2702 
2703           rtn = 0;
2704           if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) ==
2705               NULL)
2706                     goto clean;
2707 
2708           memcpy(subst_str, str, len);
2709           memcpy(subst_str + len, substr, substr_len);
2710           subst_str[substr_len + len] = '\0';
2711 
2712           if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len))
2713                     goto clean;
2714 
2715           rtn = 1;
2716 clean:
2717           free(subst_str);
2718           free(substr);
2719 
2720           return (rtn);
2721 }
2722 
2723 static int
cpp_demangle_read_tmpl_arg(struct cpp_demangle_data * ddata)2724 cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata)
2725 {
2726 
2727           if (ddata == NULL || *ddata->cur == '\0')
2728                     return (0);
2729 
2730           switch (*ddata->cur) {
2731           case 'L':
2732                     return (cpp_demangle_read_expr_primary(ddata));
2733           case 'X':
2734                     ++ddata->cur;
2735                     if (!cpp_demangle_read_expression(ddata))
2736                               return (0);
2737                     return (*ddata->cur++ == 'E');
2738           }
2739 
2740           return (cpp_demangle_read_type(ddata, NULL));
2741 }
2742 
2743 static int
cpp_demangle_read_tmpl_args(struct cpp_demangle_data * ddata)2744 cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata)
2745 {
2746           struct vector_str *v;
2747           size_t arg_len, idx, limit, size;
2748           char *arg;
2749 
2750           if (ddata == NULL || *ddata->cur == '\0')
2751                     return (0);
2752 
2753           ++ddata->cur;
2754 
2755           if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL, NULL))
2756                     return (0);
2757 
2758           if (!DEM_PUSH_STR(ddata, "<"))
2759                     return (0);
2760 
2761           limit = 0;
2762           v = ddata->cur_output;
2763           for (;;) {
2764                     idx = v->size;
2765                     if (!cpp_demangle_read_tmpl_arg(ddata))
2766                               return (0);
2767                     if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) ==
2768                         NULL)
2769                               return (0);
2770                     if (!vector_str_find(&ddata->tmpl, arg, arg_len) &&
2771                         !vector_str_push(&ddata->tmpl, arg, arg_len)) {
2772                               free(arg);
2773                               return (0);
2774                     }
2775 
2776                     free(arg);
2777 
2778                     if (*ddata->cur == 'E') {
2779                               ++ddata->cur;
2780                               size = v->size;
2781                               assert(size > 0);
2782                               if (!strncmp(v->container[size - 1], ">", 1)) {
2783                                         if (!DEM_PUSH_STR(ddata, " >"))
2784                                                   return (0);
2785                               } else if (!DEM_PUSH_STR(ddata, ">"))
2786                                         return (0);
2787                               ddata->is_tmpl = true;
2788                               break;
2789                     } else if (*ddata->cur != 'I' &&
2790                         !DEM_PUSH_STR(ddata, ", "))
2791                               return (0);
2792 
2793                     if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
2794                               return (0);
2795           }
2796 
2797           return (vector_read_cmd_pop(&ddata->cmd));
2798 }
2799 
2800 /*
2801  * Read template parameter that forms in 'T[number]_'.
2802  * This function much like to read_subst but only for types.
2803  */
2804 static int
cpp_demangle_read_tmpl_param(struct cpp_demangle_data * ddata)2805 cpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata)
2806 {
2807           long nth;
2808 
2809           if (ddata == NULL || *ddata->cur != 'T')
2810                     return (0);
2811 
2812           ++ddata->cur;
2813 
2814           if (*ddata->cur == '_')
2815                     return (cpp_demangle_get_tmpl_param(ddata, 0));
2816           else {
2817 
2818                     errno = 0;
2819                     if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 &&
2820                         errno != 0)
2821                               return (0);
2822 
2823                     /* T_ is first */
2824                     ++nth;
2825 
2826                     while (*ddata->cur != '_')
2827                               ++ddata->cur;
2828 
2829                     assert(nth > 0);
2830 
2831                     return (cpp_demangle_get_tmpl_param(ddata, nth));
2832           }
2833 
2834           /* NOTREACHED */
2835           return (0);
2836 }
2837 
2838 static int
cpp_demangle_read_type(struct cpp_demangle_data * ddata,struct type_delimit * td)2839 cpp_demangle_read_type(struct cpp_demangle_data *ddata,
2840     struct type_delimit *td)
2841 {
2842           struct vector_type_qualifier v;
2843           struct vector_str *output, sv;
2844           size_t p_idx, type_str_len, subst_str_len;
2845           int extern_c, is_builtin;
2846           long len;
2847           const char *p;
2848           char *type_str, *exp_str, *num_str, *subst_str;
2849           bool skip_ref_qualifier, omit_void;
2850 
2851           if (ddata == NULL)
2852                     return (0);
2853 
2854           output = ddata->cur_output;
2855           if (td) {
2856                     if (td->paren == false) {
2857                               if (!DEM_PUSH_STR(ddata, "("))
2858                                         return (0);
2859                               if (ddata->output.size < 2)
2860                                         return (0);
2861                               td->paren = true;
2862                     }
2863 
2864                     if (!td->firstp) {
2865                               if (*ddata->cur != 'I') {
2866                                         if (!DEM_PUSH_STR(ddata, ", "))
2867                                                   return (0);
2868                               }
2869                     }
2870           }
2871 
2872           assert(output != NULL);
2873           /*
2874            * [r, V, K] [P, R, O, C, G, U] builtin, function, class-enum, array
2875            * pointer-to-member, template-param, template-template-param, subst
2876            */
2877 
2878           if (!vector_type_qualifier_init(&v))
2879                     return (0);
2880 
2881           extern_c = 0;
2882           is_builtin = 1;
2883           p_idx = output->size;
2884           type_str = exp_str = num_str = NULL;
2885           skip_ref_qualifier = false;
2886 
2887 again:
2888 
2889           /* Clear ref-qualifier flag */
2890           if (*ddata->cur != 'R' && *ddata->cur != 'O' && *ddata->cur != 'E')
2891                     ddata->ref_qualifier = false;
2892 
2893           /* builtin type */
2894           switch (*ddata->cur) {
2895           case 'a':
2896                     /* signed char */
2897                     if (!DEM_PUSH_STR(ddata, "signed char"))
2898                               goto clean;
2899                     ++ddata->cur;
2900                     goto rtn;
2901 
2902           case 'A':
2903                     /* array type */
2904                     if (!cpp_demangle_read_array(ddata))
2905                               goto clean;
2906                     is_builtin = 0;
2907                     goto rtn;
2908 
2909           case 'b':
2910                     /* bool */
2911                     if (!DEM_PUSH_STR(ddata, "bool"))
2912                               goto clean;
2913                     ++ddata->cur;
2914                     goto rtn;
2915 
2916           case 'C':
2917                     /* complex pair */
2918                     if (!vector_type_qualifier_push(&v, TYPE_CMX))
2919                               goto clean;
2920                     ++ddata->cur;
2921                     if (td)
2922                               td->firstp = false;
2923                     goto again;
2924 
2925           case 'c':
2926                     /* char */
2927                     if (!DEM_PUSH_STR(ddata, "char"))
2928                               goto clean;
2929                     ++ddata->cur;
2930                     goto rtn;
2931 
2932           case 'd':
2933                     /* double */
2934                     if (!DEM_PUSH_STR(ddata, "double"))
2935                               goto clean;
2936                     ++ddata->cur;
2937                     goto rtn;
2938 
2939           case 'D':
2940                     ++ddata->cur;
2941                     switch (*ddata->cur) {
2942                     case 'a':
2943                               /* auto */
2944                               if (!DEM_PUSH_STR(ddata, "auto"))
2945                                         goto clean;
2946                               ++ddata->cur;
2947                               break;
2948                     case 'c':
2949                               /* decltype(auto) */
2950                               if (!DEM_PUSH_STR(ddata, "decltype(auto)"))
2951                                         goto clean;
2952                               ++ddata->cur;
2953                               break;
2954                     case 'd':
2955                               /* IEEE 754r decimal floating point (64 bits) */
2956                               if (!DEM_PUSH_STR(ddata, "decimal64"))
2957                                         goto clean;
2958                               ++ddata->cur;
2959                               break;
2960                     case 'e':
2961                               /* IEEE 754r decimal floating point (128 bits) */
2962                               if (!DEM_PUSH_STR(ddata, "decimal128"))
2963                                         goto clean;
2964                               ++ddata->cur;
2965                               break;
2966                     case 'f':
2967                               /* IEEE 754r decimal floating point (32 bits) */
2968                               if (!DEM_PUSH_STR(ddata, "decimal32"))
2969                                         goto clean;
2970                               ++ddata->cur;
2971                               break;
2972                     case 'h':
2973                               /* IEEE 754r half-precision floating point (16 bits) */
2974                               if (!DEM_PUSH_STR(ddata, "half"))
2975                                         goto clean;
2976                               ++ddata->cur;
2977                               break;
2978                     case 'i':
2979                               /* char32_t */
2980                               if (!DEM_PUSH_STR(ddata, "char32_t"))
2981                                         goto clean;
2982                               ++ddata->cur;
2983                               break;
2984                     case 'n':
2985                               /* std::nullptr_t (i.e., decltype(nullptr)) */
2986                               if (!DEM_PUSH_STR(ddata, "decltype(nullptr)"))
2987                                         goto clean;
2988                               ++ddata->cur;
2989                               break;
2990                     case 's':
2991                               /* char16_t */
2992                               if (!DEM_PUSH_STR(ddata, "char16_t"))
2993                                         goto clean;
2994                               ++ddata->cur;
2995                               break;
2996                     case 'v':
2997                               /* gcc vector_size extension. */
2998                               ++ddata->cur;
2999                               if (*ddata->cur == '_') {
3000                                         ++ddata->cur;
3001                                         if (!cpp_demangle_read_expression_flat(ddata,
3002                                             &exp_str))
3003                                                   goto clean;
3004                                         if (!VEC_PUSH_STR(&v.ext_name, exp_str))
3005                                                   goto clean;
3006                               } else {
3007                                         if (!cpp_demangle_read_number_as_string(ddata,
3008                                             &num_str))
3009                                                   goto clean;
3010                                         if (!VEC_PUSH_STR(&v.ext_name, num_str))
3011                                                   goto clean;
3012                               }
3013                               if (*ddata->cur != '_')
3014                                         goto clean;
3015                               ++ddata->cur;
3016                               if (!vector_type_qualifier_push(&v, TYPE_VEC))
3017                                         goto clean;
3018                               if (td)
3019                                         td->firstp = false;
3020                               goto again;
3021                     default:
3022                               goto clean;
3023                     }
3024                     goto rtn;
3025 
3026           case 'e':
3027                     /* long double */
3028                     if (!DEM_PUSH_STR(ddata, "long double"))
3029                               goto clean;
3030                     ++ddata->cur;
3031                     goto rtn;
3032 
3033           case 'E':
3034                     /* unexpected end except ref-qualifiers */
3035                     if (ddata->ref_qualifier && ddata->is_functype) {
3036                               skip_ref_qualifier = true;
3037                               /* Pop the delimiter. */
3038                               cpp_demangle_pop_str(ddata);
3039                               goto rtn;
3040                     }
3041                     goto clean;
3042 
3043           case 'f':
3044                     /* float */
3045                     if (!DEM_PUSH_STR(ddata, "float"))
3046                               goto clean;
3047                     ++ddata->cur;
3048                     goto rtn;
3049 
3050           case 'F':
3051                     /* function */
3052                     if (!cpp_demangle_read_function(ddata, &extern_c, &v))
3053                               goto clean;
3054                     is_builtin = 0;
3055                     goto rtn;
3056 
3057           case 'g':
3058                     /* __float128 */
3059                     if (!DEM_PUSH_STR(ddata, "__float128"))
3060                               goto clean;
3061                     ++ddata->cur;
3062                     goto rtn;
3063 
3064           case 'G':
3065                     /* imaginary */
3066                     if (!vector_type_qualifier_push(&v, TYPE_IMG))
3067                               goto clean;
3068                     ++ddata->cur;
3069                     if (td)
3070                               td->firstp = false;
3071                     goto again;
3072 
3073           case 'h':
3074                     /* unsigned char */
3075                     if (!DEM_PUSH_STR(ddata, "unsigned char"))
3076                               goto clean;
3077                     ++ddata->cur;
3078                     goto rtn;
3079 
3080           case 'i':
3081                     /* int */
3082                     if (!DEM_PUSH_STR(ddata, "int"))
3083                               goto clean;
3084                     ++ddata->cur;
3085                     goto rtn;
3086 
3087           case 'I':
3088                     /* template args. */
3089                     /* handles <substitute><template-args> */
3090                     p_idx = output->size;
3091                     if (!cpp_demangle_read_tmpl_args(ddata))
3092                               goto clean;
3093                     if ((subst_str = vector_str_substr(output, p_idx,
3094                         output->size - 1, &subst_str_len)) == NULL)
3095                               goto clean;
3096                     if (!vector_str_init(&sv)) {
3097                               free(subst_str);
3098                               goto clean;
3099                     }
3100                     if (!vector_str_push(&sv, subst_str, subst_str_len)) {
3101                               free(subst_str);
3102                               vector_str_dest(&sv);
3103                               goto clean;
3104                     }
3105                     free(subst_str);
3106                     if (!cpp_demangle_push_subst_v(ddata, &sv)) {
3107                               vector_str_dest(&sv);
3108                               goto clean;
3109                     }
3110                     vector_str_dest(&sv);
3111                     goto rtn;
3112 
3113           case 'j':
3114                     /* unsigned int */
3115                     if (!DEM_PUSH_STR(ddata, "unsigned int"))
3116                               goto clean;
3117                     ++ddata->cur;
3118                     goto rtn;
3119 
3120           case 'K':
3121                     /* const */
3122                     if (!vector_type_qualifier_push(&v, TYPE_CST))
3123                               goto clean;
3124                     ++ddata->cur;
3125                     if (td)
3126                               td->firstp = false;
3127                     goto again;
3128 
3129           case 'l':
3130                     /* long */
3131                     if (!DEM_PUSH_STR(ddata, "long"))
3132                               goto clean;
3133                     ++ddata->cur;
3134                     goto rtn;
3135 
3136           case 'm':
3137                     /* unsigned long */
3138                     if (!DEM_PUSH_STR(ddata, "unsigned long"))
3139                               goto clean;
3140 
3141                     ++ddata->cur;
3142 
3143                     goto rtn;
3144           case 'M':
3145                     /* pointer to member */
3146                     if (!cpp_demangle_read_pointer_to_member(ddata, &v))
3147                               goto clean;
3148                     is_builtin = 0;
3149                     goto rtn;
3150 
3151           case 'n':
3152                     /* __int128 */
3153                     if (!DEM_PUSH_STR(ddata, "__int128"))
3154                               goto clean;
3155                     ++ddata->cur;
3156                     goto rtn;
3157 
3158           case 'o':
3159                     /* unsigned __int128 */
3160                     if (!DEM_PUSH_STR(ddata, "unsigned __int128"))
3161                               goto clean;
3162                     ++ddata->cur;
3163                     goto rtn;
3164 
3165           case 'O':
3166                     /* rvalue reference */
3167                     if (ddata->ref_qualifier)
3168                               goto clean;
3169                     if (!vector_type_qualifier_push(&v, TYPE_RREF))
3170                               goto clean;
3171                     ddata->ref_qualifier = true;
3172                     ddata->ref_qualifier_type = TYPE_RREF;
3173                     ++ddata->cur;
3174                     if (td)
3175                               td->firstp = false;
3176                     goto again;
3177 
3178           case 'P':
3179                     /* pointer */
3180                     if (!vector_type_qualifier_push(&v, TYPE_PTR))
3181                               goto clean;
3182                     ++ddata->cur;
3183                     if (td)
3184                               td->firstp = false;
3185                     goto again;
3186 
3187           case 'r':
3188                     /* restrict */
3189                     if (!vector_type_qualifier_push(&v, TYPE_RST))
3190                               goto clean;
3191                     ++ddata->cur;
3192                     if (td)
3193                               td->firstp = false;
3194                     goto again;
3195 
3196           case 'R':
3197                     /* reference */
3198                     if (ddata->ref_qualifier)
3199                               goto clean;
3200                     if (!vector_type_qualifier_push(&v, TYPE_REF))
3201                               goto clean;
3202                     ddata->ref_qualifier = true;
3203                     ddata->ref_qualifier_type = TYPE_REF;
3204                     ++ddata->cur;
3205                     if (td)
3206                               td->firstp = false;
3207                     goto again;
3208 
3209           case 's':
3210                     /* short, local string */
3211                     if (!DEM_PUSH_STR(ddata, "short"))
3212                               goto clean;
3213                     ++ddata->cur;
3214                     goto rtn;
3215 
3216           case 'S':
3217                     /* substitution */
3218                     if (!cpp_demangle_read_subst(ddata))
3219                               goto clean;
3220                     is_builtin = 0;
3221                     goto rtn;
3222 
3223           case 't':
3224                     /* unsigned short */
3225                     if (!DEM_PUSH_STR(ddata, "unsigned short"))
3226                               goto clean;
3227                     ++ddata->cur;
3228                     goto rtn;
3229 
3230           case 'T':
3231                     /* template parameter */
3232                     if (!cpp_demangle_read_tmpl_param(ddata))
3233                               goto clean;
3234                     is_builtin = 0;
3235                     goto rtn;
3236 
3237           case 'u':
3238                     /* vendor extended builtin */
3239                     ++ddata->cur;
3240                     if (!cpp_demangle_read_sname(ddata))
3241                               goto clean;
3242                     is_builtin = 0;
3243                     goto rtn;
3244 
3245           case 'U':
3246                     /* vendor extended type qualifier */
3247                     ++ddata->cur;
3248                     if (!cpp_demangle_read_number(ddata, &len))
3249                               goto clean;
3250                     if (len <= 0)
3251                               goto clean;
3252                     if (!vector_str_push(&v.ext_name, ddata->cur, len))
3253                               goto clean;
3254                     ddata->cur += len;
3255                     if (!vector_type_qualifier_push(&v, TYPE_EXT))
3256                               goto clean;
3257                     if (td)
3258                               td->firstp = false;
3259                     goto again;
3260 
3261           case 'v':
3262                     /* void */
3263                     omit_void = false;
3264                     if (td && td->firstp) {
3265                               /*
3266                                * peek into next bytes and see if we should omit
3267                                * the "void".
3268                                */
3269                               omit_void = true;
3270                               for (p = ddata->cur + 1; *p != '\0'; p++) {
3271                                         if (*p == 'E')
3272                                                   break;
3273                                         if (*p != 'R' && *p != 'O') {
3274                                                   omit_void = false;
3275                                                   break;
3276                                         }
3277                               }
3278                     }
3279                     if (!omit_void && !DEM_PUSH_STR(ddata, "void"))
3280                               goto clean;
3281                     ++ddata->cur;
3282                     goto rtn;
3283 
3284           case 'V':
3285                     /* volatile */
3286                     if (!vector_type_qualifier_push(&v, TYPE_VAT))
3287                               goto clean;
3288                     ++ddata->cur;
3289                     if (td)
3290                               td->firstp = false;
3291                     goto again;
3292 
3293           case 'w':
3294                     /* wchar_t */
3295                     if (!DEM_PUSH_STR(ddata, "wchar_t"))
3296                               goto clean;
3297                     ++ddata->cur;
3298                     goto rtn;
3299 
3300           case 'x':
3301                     /* long long */
3302                     if (!DEM_PUSH_STR(ddata, "long long"))
3303                               goto clean;
3304                     ++ddata->cur;
3305                     goto rtn;
3306 
3307           case 'y':
3308                     /* unsigned long long */
3309                     if (!DEM_PUSH_STR(ddata, "unsigned long long"))
3310                               goto clean;
3311                     ++ddata->cur;
3312                     goto rtn;
3313 
3314           case 'z':
3315                     /* ellipsis */
3316                     if (!DEM_PUSH_STR(ddata, "..."))
3317                               goto clean;
3318                     ++ddata->cur;
3319                     goto rtn;
3320           }
3321 
3322           if (!cpp_demangle_read_name(ddata))
3323                     goto clean;
3324 
3325           is_builtin = 0;
3326 rtn:
3327 
3328           type_str = vector_str_substr(output, p_idx, output->size - 1,
3329               &type_str_len);
3330 
3331           if (is_builtin == 0) {
3332                     if (!vector_str_find(&ddata->subst, type_str, type_str_len) &&
3333                         !vector_str_push(&ddata->subst, type_str, type_str_len))
3334                               goto clean;
3335           }
3336 
3337           if (!skip_ref_qualifier &&
3338               !cpp_demangle_push_type_qualifier(ddata, &v, type_str))
3339                     goto clean;
3340 
3341           if (td)
3342                     td->firstp = false;
3343 
3344           free(type_str);
3345           free(exp_str);
3346           free(num_str);
3347           vector_type_qualifier_dest(&v);
3348 
3349           return (1);
3350 clean:
3351           free(type_str);
3352           free(exp_str);
3353           free(num_str);
3354           vector_type_qualifier_dest(&v);
3355 
3356           return (0);
3357 }
3358 
3359 static int
cpp_demangle_read_type_flat(struct cpp_demangle_data * ddata,char ** str)3360 cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str)
3361 {
3362           struct vector_str *output;
3363           size_t i, p_idx, idx, type_len;
3364           char *type;
3365 
3366           output = ddata->cur_output;
3367 
3368           p_idx = output->size;
3369 
3370           if (!cpp_demangle_read_type(ddata, NULL))
3371                     return (0);
3372 
3373           if ((type = vector_str_substr(output, p_idx, output->size - 1,
3374               &type_len)) == NULL)
3375                     return (0);
3376 
3377           idx = output->size;
3378           for (i = p_idx; i < idx; ++i) {
3379                     if (!vector_str_pop(output)) {
3380                               free(type);
3381                               return (0);
3382                     }
3383           }
3384 
3385           *str = type;
3386 
3387           return (1);
3388 }
3389 
3390 /*
3391  * read unqualified-name, unqualified name are operator-name, ctor-dtor-name,
3392  * source-name
3393  */
3394 static int
cpp_demangle_read_uqname(struct cpp_demangle_data * ddata)3395 cpp_demangle_read_uqname(struct cpp_demangle_data *ddata)
3396 {
3397           size_t len;
3398 
3399           if (ddata == NULL || *ddata->cur == '\0')
3400                     return (0);
3401 
3402           /* operator name */
3403           switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
3404           case SIMPLE_HASH('a', 'a'):
3405                     /* operator && */
3406                     if (!DEM_PUSH_STR(ddata, "operator&&"))
3407                               return (0);
3408                     ddata->cur += 2;
3409                     return (1);
3410 
3411           case SIMPLE_HASH('a', 'd'):
3412                     /* operator & (unary) */
3413                     if (!DEM_PUSH_STR(ddata, "operator&"))
3414                               return (0);
3415                     ddata->cur += 2;
3416                     return (1);
3417 
3418           case SIMPLE_HASH('a', 'n'):
3419                     /* operator & */
3420                     if (!DEM_PUSH_STR(ddata, "operator&"))
3421                               return (0);
3422                     ddata->cur += 2;
3423                     return (1);
3424 
3425           case SIMPLE_HASH('a', 'N'):
3426                     /* operator &= */
3427                     if (!DEM_PUSH_STR(ddata, "operator&="))
3428                               return (0);
3429                     ddata->cur += 2;
3430                     return (1);
3431 
3432           case SIMPLE_HASH('a', 'S'):
3433                     /* operator = */
3434                     if (!DEM_PUSH_STR(ddata, "operator="))
3435                               return (0);
3436                     ddata->cur += 2;
3437                     return (1);
3438 
3439           case SIMPLE_HASH('c', 'l'):
3440                     /* operator () */
3441                     if (!DEM_PUSH_STR(ddata, "operator()"))
3442                               return (0);
3443                     ddata->cur += 2;
3444                     return (1);
3445 
3446           case SIMPLE_HASH('c', 'm'):
3447                     /* operator , */
3448                     if (!DEM_PUSH_STR(ddata, "operator,"))
3449                               return (0);
3450                     ddata->cur += 2;
3451                     return (1);
3452 
3453           case SIMPLE_HASH('c', 'o'):
3454                     /* operator ~ */
3455                     if (!DEM_PUSH_STR(ddata, "operator~"))
3456                               return (0);
3457                     ddata->cur += 2;
3458                     return (1);
3459 
3460           case SIMPLE_HASH('c', 'v'):
3461                     /* operator (cast) */
3462                     if (!DEM_PUSH_STR(ddata, "operator(cast)"))
3463                               return (0);
3464                     ddata->cur += 2;
3465                     return (cpp_demangle_read_type(ddata, NULL));
3466 
3467           case SIMPLE_HASH('d', 'a'):
3468                     /* operator delete [] */
3469                     if (!DEM_PUSH_STR(ddata, "operator delete []"))
3470                               return (0);
3471                     ddata->cur += 2;
3472                     return (1);
3473 
3474           case SIMPLE_HASH('d', 'e'):
3475                     /* operator * (unary) */
3476                     if (!DEM_PUSH_STR(ddata, "operator*"))
3477                               return (0);
3478                     ddata->cur += 2;
3479                     return (1);
3480 
3481           case SIMPLE_HASH('d', 'l'):
3482                     /* operator delete */
3483                     if (!DEM_PUSH_STR(ddata, "operator delete"))
3484                               return (0);
3485                     ddata->cur += 2;
3486                     return (1);
3487 
3488           case SIMPLE_HASH('d', 'v'):
3489                     /* operator / */
3490                     if (!DEM_PUSH_STR(ddata, "operator/"))
3491                               return (0);
3492                     ddata->cur += 2;
3493                     return (1);
3494 
3495           case SIMPLE_HASH('d', 'V'):
3496                     /* operator /= */
3497                     if (!DEM_PUSH_STR(ddata, "operator/="))
3498                               return (0);
3499                     ddata->cur += 2;
3500                     return (1);
3501 
3502           case SIMPLE_HASH('e', 'o'):
3503                     /* operator ^ */
3504                     if (!DEM_PUSH_STR(ddata, "operator^"))
3505                               return (0);
3506                     ddata->cur += 2;
3507                     return (1);
3508 
3509           case SIMPLE_HASH('e', 'O'):
3510                     /* operator ^= */
3511                     if (!DEM_PUSH_STR(ddata, "operator^="))
3512                               return (0);
3513                     ddata->cur += 2;
3514                     return (1);
3515 
3516           case SIMPLE_HASH('e', 'q'):
3517                     /* operator == */
3518                     if (!DEM_PUSH_STR(ddata, "operator=="))
3519                               return (0);
3520                     ddata->cur += 2;
3521                     return (1);
3522 
3523           case SIMPLE_HASH('g', 'e'):
3524                     /* operator >= */
3525                     if (!DEM_PUSH_STR(ddata, "operator>="))
3526                               return (0);
3527                     ddata->cur += 2;
3528                     return (1);
3529 
3530           case SIMPLE_HASH('g', 't'):
3531                     /* operator > */
3532                     if (!DEM_PUSH_STR(ddata, "operator>"))
3533                               return (0);
3534                     ddata->cur += 2;
3535                     return (1);
3536 
3537           case SIMPLE_HASH('i', 'x'):
3538                     /* operator [] */
3539                     if (!DEM_PUSH_STR(ddata, "operator[]"))
3540                               return (0);
3541                     ddata->cur += 2;
3542                     return (1);
3543 
3544           case SIMPLE_HASH('l', 'e'):
3545                     /* operator <= */
3546                     if (!DEM_PUSH_STR(ddata, "operator<="))
3547                               return (0);
3548                     ddata->cur += 2;
3549                     return (1);
3550 
3551           case SIMPLE_HASH('l', 's'):
3552                     /* operator << */
3553                     if (!DEM_PUSH_STR(ddata, "operator<<"))
3554                               return (0);
3555                     ddata->cur += 2;
3556                     return (1);
3557 
3558           case SIMPLE_HASH('l', 'S'):
3559                     /* operator <<= */
3560                     if (!DEM_PUSH_STR(ddata, "operator<<="))
3561                               return (0);
3562                     ddata->cur += 2;
3563                     return (1);
3564 
3565           case SIMPLE_HASH('l', 't'):
3566                     /* operator < */
3567                     if (!DEM_PUSH_STR(ddata, "operator<"))
3568                               return (0);
3569                     ddata->cur += 2;
3570                     return (1);
3571 
3572           case SIMPLE_HASH('m', 'i'):
3573                     /* operator - */
3574                     if (!DEM_PUSH_STR(ddata, "operator-"))
3575                               return (0);
3576                     ddata->cur += 2;
3577                     return (1);
3578 
3579           case SIMPLE_HASH('m', 'I'):
3580                     /* operator -= */
3581                     if (!DEM_PUSH_STR(ddata, "operator-="))
3582                               return (0);
3583                     ddata->cur += 2;
3584                     return (1);
3585 
3586           case SIMPLE_HASH('m', 'l'):
3587                     /* operator * */
3588                     if (!DEM_PUSH_STR(ddata, "operator*"))
3589                               return (0);
3590                     ddata->cur += 2;
3591                     return (1);
3592 
3593           case SIMPLE_HASH('m', 'L'):
3594                     /* operator *= */
3595                     if (!DEM_PUSH_STR(ddata, "operator*="))
3596                               return (0);
3597                     ddata->cur += 2;
3598                     return (1);
3599 
3600           case SIMPLE_HASH('m', 'm'):
3601                     /* operator -- */
3602                     if (!DEM_PUSH_STR(ddata, "operator--"))
3603                               return (0);
3604                     ddata->cur += 2;
3605                     return (1);
3606 
3607           case SIMPLE_HASH('n', 'a'):
3608                     /* operator new[] */
3609                     if (!DEM_PUSH_STR(ddata, "operator new []"))
3610                               return (0);
3611                     ddata->cur += 2;
3612                     return (1);
3613 
3614           case SIMPLE_HASH('n', 'e'):
3615                     /* operator != */
3616                     if (!DEM_PUSH_STR(ddata, "operator!="))
3617                               return (0);
3618                     ddata->cur += 2;
3619                     return (1);
3620 
3621           case SIMPLE_HASH('n', 'g'):
3622                     /* operator - (unary) */
3623                     if (!DEM_PUSH_STR(ddata, "operator-"))
3624                               return (0);
3625                     ddata->cur += 2;
3626                     return (1);
3627 
3628           case SIMPLE_HASH('n', 't'):
3629                     /* operator ! */
3630                     if (!DEM_PUSH_STR(ddata, "operator!"))
3631                               return (0);
3632                     ddata->cur += 2;
3633                     return (1);
3634 
3635           case SIMPLE_HASH('n', 'w'):
3636                     /* operator new */
3637                     if (!DEM_PUSH_STR(ddata, "operator new"))
3638                               return (0);
3639                     ddata->cur += 2;
3640                     return (1);
3641 
3642           case SIMPLE_HASH('o', 'o'):
3643                     /* operator || */
3644                     if (!DEM_PUSH_STR(ddata, "operator||"))
3645                               return (0);
3646                     ddata->cur += 2;
3647                     return (1);
3648 
3649           case SIMPLE_HASH('o', 'r'):
3650                     /* operator | */
3651                     if (!DEM_PUSH_STR(ddata, "operator|"))
3652                               return (0);
3653                     ddata->cur += 2;
3654                     return (1);
3655 
3656           case SIMPLE_HASH('o', 'R'):
3657                     /* operator |= */
3658                     if (!DEM_PUSH_STR(ddata, "operator|="))
3659                               return (0);
3660                     ddata->cur += 2;
3661                     return (1);
3662 
3663           case SIMPLE_HASH('p', 'l'):
3664                     /* operator + */
3665                     if (!DEM_PUSH_STR(ddata, "operator+"))
3666                               return (0);
3667                     ddata->cur += 2;
3668                     return (1);
3669 
3670           case SIMPLE_HASH('p', 'L'):
3671                     /* operator += */
3672                     if (!DEM_PUSH_STR(ddata, "operator+="))
3673                               return (0);
3674                     ddata->cur += 2;
3675                     return (1);
3676 
3677           case SIMPLE_HASH('p', 'm'):
3678                     /* operator ->* */
3679                     if (!DEM_PUSH_STR(ddata, "operator->*"))
3680                               return (0);
3681                     ddata->cur += 2;
3682                     return (1);
3683 
3684           case SIMPLE_HASH('p', 'p'):
3685                     /* operator ++ */
3686                     if (!DEM_PUSH_STR(ddata, "operator++"))
3687                               return (0);
3688                     ddata->cur += 2;
3689                     return (1);
3690 
3691           case SIMPLE_HASH('p', 's'):
3692                     /* operator + (unary) */
3693                     if (!DEM_PUSH_STR(ddata, "operator+"))
3694                               return (0);
3695                     ddata->cur += 2;
3696                     return (1);
3697 
3698           case SIMPLE_HASH('p', 't'):
3699                     /* operator -> */
3700                     if (!DEM_PUSH_STR(ddata, "operator->"))
3701                               return (0);
3702                     ddata->cur += 2;
3703                     return (1);
3704 
3705           case SIMPLE_HASH('q', 'u'):
3706                     /* operator ? */
3707                     if (!DEM_PUSH_STR(ddata, "operator?"))
3708                               return (0);
3709                     ddata->cur += 2;
3710                     return (1);
3711 
3712           case SIMPLE_HASH('r', 'm'):
3713                     /* operator % */
3714                     if (!DEM_PUSH_STR(ddata, "operator%"))
3715                               return (0);
3716                     ddata->cur += 2;
3717                     return (1);
3718 
3719           case SIMPLE_HASH('r', 'M'):
3720                     /* operator %= */
3721                     if (!DEM_PUSH_STR(ddata, "operator%="))
3722                               return (0);
3723                     ddata->cur += 2;
3724                     return (1);
3725 
3726           case SIMPLE_HASH('r', 's'):
3727                     /* operator >> */
3728                     if (!DEM_PUSH_STR(ddata, "operator>>"))
3729                               return (0);
3730                     ddata->cur += 2;
3731                     return (1);
3732 
3733           case SIMPLE_HASH('r', 'S'):
3734                     /* operator >>= */
3735                     if (!DEM_PUSH_STR(ddata, "operator>>="))
3736                               return (0);
3737                     ddata->cur += 2;
3738                     return (1);
3739 
3740           case SIMPLE_HASH('r', 'z'):
3741                     /* operator sizeof */
3742                     if (!DEM_PUSH_STR(ddata, "operator sizeof "))
3743                               return (0);
3744                     ddata->cur += 2;
3745                     return (1);
3746 
3747           case SIMPLE_HASH('s', 'r'):
3748                     /* scope resolution operator */
3749                     if (!DEM_PUSH_STR(ddata, "scope resolution operator "))
3750                               return (0);
3751                     ddata->cur += 2;
3752                     return (1);
3753 
3754           case SIMPLE_HASH('s', 'v'):
3755                     /* operator sizeof */
3756                     if (!DEM_PUSH_STR(ddata, "operator sizeof "))
3757                               return (0);
3758                     ddata->cur += 2;
3759                     return (1);
3760           }
3761 
3762           /* vendor extened operator */
3763           if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) {
3764                     if (!DEM_PUSH_STR(ddata, "vendor extened operator "))
3765                               return (0);
3766                     if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1))
3767                               return (0);
3768                     ddata->cur += 2;
3769                     return (cpp_demangle_read_sname(ddata));
3770           }
3771 
3772           /* ctor-dtor-name */
3773           switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
3774           case SIMPLE_HASH('C', '1'):
3775           case SIMPLE_HASH('C', '2'):
3776           case SIMPLE_HASH('C', '3'):
3777                     if (ddata->last_sname == NULL)
3778                               return (0);
3779                     if ((len = strlen(ddata->last_sname)) == 0)
3780                               return (0);
3781                     if (!DEM_PUSH_STR(ddata, "::"))
3782                               return (0);
3783                     if (!cpp_demangle_push_str(ddata, ddata->last_sname, len))
3784                               return (0);
3785                     ddata->cur +=2;
3786                     return (1);
3787 
3788           case SIMPLE_HASH('D', '0'):
3789           case SIMPLE_HASH('D', '1'):
3790           case SIMPLE_HASH('D', '2'):
3791                     if (ddata->last_sname == NULL)
3792                               return (0);
3793                     if ((len = strlen(ddata->last_sname)) == 0)
3794                               return (0);
3795                     if (!DEM_PUSH_STR(ddata, "::~"))
3796                               return (0);
3797                     if (!cpp_demangle_push_str(ddata, ddata->last_sname, len))
3798                               return (0);
3799                     ddata->cur +=2;
3800                     return (1);
3801           }
3802 
3803           /* source name */
3804           if (ELFTC_ISDIGIT(*ddata->cur) != 0)
3805                     return (cpp_demangle_read_sname(ddata));
3806 
3807           /* local source name */
3808           if (*ddata->cur == 'L')
3809                     return (cpp_demangle_local_source_name(ddata));
3810 
3811           return (1);
3812 }
3813 
3814 /*
3815  * Read local source name.
3816  *
3817  * References:
3818  *   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
3819  *   http://gcc.gnu.org/viewcvs?view=rev&revision=124467
3820  */
3821 static int
cpp_demangle_local_source_name(struct cpp_demangle_data * ddata)3822 cpp_demangle_local_source_name(struct cpp_demangle_data *ddata)
3823 {
3824           /* L */
3825           if (ddata == NULL || *ddata->cur != 'L')
3826                     return (0);
3827           ++ddata->cur;
3828 
3829           /* source name */
3830           if (!cpp_demangle_read_sname(ddata))
3831                     return (0);
3832 
3833           /* discriminator */
3834           if (*ddata->cur == '_') {
3835                     ++ddata->cur;
3836                     while (ELFTC_ISDIGIT(*ddata->cur) != 0)
3837                               ++ddata->cur;
3838           }
3839 
3840           return (1);
3841 }
3842 
3843 static int
cpp_demangle_read_v_offset(struct cpp_demangle_data * ddata)3844 cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata)
3845 {
3846 
3847           if (ddata == NULL)
3848                     return (0);
3849 
3850           if (!DEM_PUSH_STR(ddata, "offset : "))
3851                     return (0);
3852 
3853           if (!cpp_demangle_read_offset_number(ddata))
3854                     return (0);
3855 
3856           if (!DEM_PUSH_STR(ddata, "virtual offset : "))
3857                     return (0);
3858 
3859           return (!cpp_demangle_read_offset_number(ddata));
3860 }
3861 
3862 /*
3863  * Decode floating point representation to string
3864  * Return new allocated string or NULL
3865  *
3866  * Todo
3867  * Replace these functions to macro.
3868  */
3869 static char *
decode_fp_to_double(const char * p,size_t len)3870 decode_fp_to_double(const char *p, size_t len)
3871 {
3872           double f;
3873           size_t rtn_len, limit, i;
3874           int byte;
3875           char *rtn;
3876 
3877           if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double))
3878                     return (NULL);
3879 
3880           memset(&f, 0, sizeof(double));
3881 
3882           for (i = 0; i < len / 2; ++i) {
3883                     byte = hex_to_dec(p[len - i * 2 - 1]) +
3884                         hex_to_dec(p[len - i * 2 - 2]) * 16;
3885 
3886                     if (byte < 0 || byte > 255)
3887                               return (NULL);
3888 
3889 #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
3890                     ((unsigned char *)&f)[i] = (unsigned char)(byte);
3891 #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
3892                     ((unsigned char *)&f)[sizeof(double) - i - 1] =
3893                         (unsigned char)(byte);
3894 #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
3895           }
3896 
3897           rtn_len = 64;
3898           limit = 0;
3899 again:
3900           if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)
3901                     return (NULL);
3902 
3903           if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) {
3904                     free(rtn);
3905                     if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
3906                               return (NULL);
3907                     rtn_len *= BUFFER_GROWFACTOR;
3908                     goto again;
3909           }
3910 
3911           return rtn;
3912 }
3913 
3914 static char *
decode_fp_to_float(const char * p,size_t len)3915 decode_fp_to_float(const char *p, size_t len)
3916 {
3917           size_t i, rtn_len, limit;
3918           float f;
3919           int byte;
3920           char *rtn;
3921 
3922           if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float))
3923                     return (NULL);
3924 
3925           memset(&f, 0, sizeof(float));
3926 
3927           for (i = 0; i < len / 2; ++i) {
3928                     byte = hex_to_dec(p[len - i * 2 - 1]) +
3929                         hex_to_dec(p[len - i * 2 - 2]) * 16;
3930                     if (byte < 0 || byte > 255)
3931                               return (NULL);
3932 #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
3933                     ((unsigned char *)&f)[i] = (unsigned char)(byte);
3934 #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
3935                     ((unsigned char *)&f)[sizeof(float) - i - 1] =
3936                         (unsigned char)(byte);
3937 #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
3938           }
3939 
3940           rtn_len = 64;
3941           limit = 0;
3942 again:
3943           if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)
3944                     return (NULL);
3945 
3946           if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) {
3947                     free(rtn);
3948                     if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
3949                               return (NULL);
3950                     rtn_len *= BUFFER_GROWFACTOR;
3951                     goto again;
3952           }
3953 
3954           return rtn;
3955 }
3956 
3957 static char *
decode_fp_to_float128(const char * p,size_t len)3958 decode_fp_to_float128(const char *p, size_t len)
3959 {
3960           long double f;
3961           size_t rtn_len, limit, i;
3962           int byte;
3963           unsigned char buf[FLOAT_QUADRUPLE_BYTES];
3964           char *rtn;
3965 
3966           switch(sizeof(long double)) {
3967           case FLOAT_QUADRUPLE_BYTES:
3968                     return (decode_fp_to_long_double(p, len));
3969           case FLOAT_EXTENED_BYTES:
3970                     if (p == NULL || len == 0 || len % 2 != 0 ||
3971                         len / 2 > FLOAT_QUADRUPLE_BYTES)
3972                               return (NULL);
3973 
3974                     memset(buf, 0, FLOAT_QUADRUPLE_BYTES);
3975 
3976                     for (i = 0; i < len / 2; ++i) {
3977                               byte = hex_to_dec(p[len - i * 2 - 1]) +
3978                                   hex_to_dec(p[len - i * 2 - 2]) * 16;
3979                               if (byte < 0 || byte > 255)
3980                                         return (NULL);
3981 #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
3982                               buf[i] = (unsigned char)(byte);
3983 #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
3984                               buf[FLOAT_QUADRUPLE_BYTES - i -1] =
3985                                   (unsigned char)(byte);
3986 #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
3987                     }
3988                     memset(&f, 0, FLOAT_EXTENED_BYTES);
3989 
3990 #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
3991                     memcpy(&f, buf, FLOAT_EXTENED_BYTES);
3992 #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
3993                     memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES);
3994 #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
3995 
3996                     rtn_len = 256;
3997                     limit = 0;
3998 again:
3999                     if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)
4000                               return (NULL);
4001 
4002                     if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {
4003                               free(rtn);
4004                               if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
4005                                         return (NULL);
4006                               rtn_len *= BUFFER_GROWFACTOR;
4007                               goto again;
4008                     }
4009 
4010                     return (rtn);
4011           default:
4012                     return (NULL);
4013           }
4014 }
4015 
4016 static char *
decode_fp_to_float80(const char * p,size_t len)4017 decode_fp_to_float80(const char *p, size_t len)
4018 {
4019           long double f;
4020           size_t rtn_len, limit, i;
4021           int byte;
4022           unsigned char buf[FLOAT_EXTENED_BYTES];
4023           char *rtn;
4024 
4025           switch(sizeof(long double)) {
4026           case FLOAT_QUADRUPLE_BYTES:
4027                     if (p == NULL || len == 0 || len % 2 != 0 ||
4028                         len / 2 > FLOAT_EXTENED_BYTES)
4029                               return (NULL);
4030 
4031                     memset(buf, 0, FLOAT_EXTENED_BYTES);
4032 
4033                     for (i = 0; i < len / 2; ++i) {
4034                               byte = hex_to_dec(p[len - i * 2 - 1]) +
4035                                   hex_to_dec(p[len - i * 2 - 2]) * 16;
4036 
4037                               if (byte < 0 || byte > 255)
4038                                         return (NULL);
4039 
4040 #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
4041                               buf[i] = (unsigned char)(byte);
4042 #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
4043                               buf[FLOAT_EXTENED_BYTES - i -1] =
4044                                   (unsigned char)(byte);
4045 #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
4046                     }
4047 
4048                     memset(&f, 0, FLOAT_QUADRUPLE_BYTES);
4049 
4050 #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
4051                     memcpy(&f, buf, FLOAT_EXTENED_BYTES);
4052 #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
4053                     memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENED_BYTES);
4054 #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
4055 
4056                     rtn_len = 256;
4057                     limit = 0;
4058 again:
4059                     if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)
4060                               return (NULL);
4061 
4062                     if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {
4063                               free(rtn);
4064                               if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
4065                                         return (NULL);
4066                               rtn_len *= BUFFER_GROWFACTOR;
4067                               goto again;
4068                     }
4069 
4070                     return (rtn);
4071           case FLOAT_EXTENED_BYTES:
4072                     return (decode_fp_to_long_double(p, len));
4073           default:
4074                     return (NULL);
4075           }
4076 }
4077 
4078 static char *
decode_fp_to_long_double(const char * p,size_t len)4079 decode_fp_to_long_double(const char *p, size_t len)
4080 {
4081           long double f;
4082           size_t rtn_len, limit, i;
4083           int byte;
4084           char *rtn;
4085 
4086           if (p == NULL || len == 0 || len % 2 != 0 ||
4087               len / 2 > sizeof(long double))
4088                     return (NULL);
4089 
4090           memset(&f, 0, sizeof(long double));
4091 
4092           for (i = 0; i < len / 2; ++i) {
4093                     byte = hex_to_dec(p[len - i * 2 - 1]) +
4094                         hex_to_dec(p[len - i * 2 - 2]) * 16;
4095 
4096                     if (byte < 0 || byte > 255)
4097                               return (NULL);
4098 
4099 #if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
4100                     ((unsigned char *)&f)[i] = (unsigned char)(byte);
4101 #else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
4102                     ((unsigned char *)&f)[sizeof(long double) - i - 1] =
4103                         (unsigned char)(byte);
4104 #endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
4105           }
4106 
4107           rtn_len = 256;
4108           limit = 0;
4109 again:
4110           if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)
4111                     return (NULL);
4112 
4113           if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {
4114                     free(rtn);
4115                     if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
4116                               return (NULL);
4117                     rtn_len *= BUFFER_GROWFACTOR;
4118                     goto again;
4119           }
4120 
4121           return (rtn);
4122 }
4123 
4124 /* Simple hex to integer function used by decode_to_* function. */
4125 static int
hex_to_dec(char c)4126 hex_to_dec(char c)
4127 {
4128 
4129           switch (c) {
4130           case '0':
4131                     return (0);
4132           case '1':
4133                     return (1);
4134           case '2':
4135                     return (2);
4136           case '3':
4137                     return (3);
4138           case '4':
4139                     return (4);
4140           case '5':
4141                     return (5);
4142           case '6':
4143                     return (6);
4144           case '7':
4145                     return (7);
4146           case '8':
4147                     return (8);
4148           case '9':
4149                     return (9);
4150           case 'a':
4151                     return (10);
4152           case 'b':
4153                     return (11);
4154           case 'c':
4155                     return (12);
4156           case 'd':
4157                     return (13);
4158           case 'e':
4159                     return (14);
4160           case 'f':
4161                     return (15);
4162           default:
4163                     return (-1);
4164           }
4165 }
4166 
4167 /**
4168  * @brief Test input string is mangled by IA-64 C++ ABI style.
4169  *
4170  * Test string heads with "_Z" or "_GLOBAL__I_".
4171  * @return Return 0 at false.
4172  */
4173 bool
is_cpp_mangled_gnu3(const char * org)4174 is_cpp_mangled_gnu3(const char *org)
4175 {
4176           size_t len;
4177 
4178           len = strlen(org);
4179           return ((len > 2 && *org == '_' && *(org + 1) == 'Z') ||
4180               (len > 11 && !strncmp(org, "_GLOBAL__I_", 11)));
4181 }
4182 
4183 static void
vector_read_cmd_dest(struct vector_read_cmd * v)4184 vector_read_cmd_dest(struct vector_read_cmd *v)
4185 {
4186 
4187           if (v == NULL)
4188                     return;
4189 
4190           free(v->r_container);
4191 }
4192 
4193 static struct read_cmd_item *
vector_read_cmd_find(struct vector_read_cmd * v,enum read_cmd dst)4194 vector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst)
4195 {
4196           int i;
4197 
4198           if (v == NULL || dst == READ_FAIL)
4199                     return (NULL);
4200 
4201           for (i = (int) v->size - 1; i >= 0; i--)
4202                     if (v->r_container[i].cmd == dst)
4203                               return (&v->r_container[i]);
4204 
4205           return (NULL);
4206 }
4207 
4208 static int
vector_read_cmd_init(struct vector_read_cmd * v)4209 vector_read_cmd_init(struct vector_read_cmd *v)
4210 {
4211 
4212           if (v == NULL)
4213                     return (0);
4214 
4215           v->size = 0;
4216           v->capacity = VECTOR_DEF_CAPACITY;
4217 
4218           if ((v->r_container = malloc(sizeof(*v->r_container) * v->capacity))
4219               == NULL)
4220                     return (0);
4221 
4222           return (1);
4223 }
4224 
4225 static int
vector_read_cmd_pop(struct vector_read_cmd * v)4226 vector_read_cmd_pop(struct vector_read_cmd *v)
4227 {
4228 
4229           if (v == NULL || v->size == 0)
4230                     return (0);
4231 
4232           --v->size;
4233           v->r_container[v->size].cmd = READ_FAIL;
4234           v->r_container[v->size].data = NULL;
4235 
4236           return (1);
4237 }
4238 
4239 static int
vector_read_cmd_push(struct vector_read_cmd * v,enum read_cmd cmd,void * data)4240 vector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd, void *data)
4241 {
4242           struct read_cmd_item *tmp_r_ctn;
4243           size_t tmp_cap;
4244           size_t i;
4245 
4246           if (v == NULL)
4247                     return (0);
4248 
4249           if (v->size == v->capacity) {
4250                     tmp_cap = BUFFER_GROW(v->capacity);
4251                     if ((tmp_r_ctn = malloc(sizeof(*tmp_r_ctn) * tmp_cap)) == NULL)
4252                               return (0);
4253                     for (i = 0; i < v->size; ++i)
4254                               tmp_r_ctn[i] = v->r_container[i];
4255                     free(v->r_container);
4256                     v->r_container = tmp_r_ctn;
4257                     v->capacity = tmp_cap;
4258           }
4259 
4260           v->r_container[v->size].cmd = cmd;
4261           v->r_container[v->size].data = data;
4262           ++v->size;
4263 
4264           return (1);
4265 }
4266 
4267 static void
vector_type_qualifier_dest(struct vector_type_qualifier * v)4268 vector_type_qualifier_dest(struct vector_type_qualifier *v)
4269 {
4270 
4271           if (v == NULL)
4272                     return;
4273 
4274           free(v->q_container);
4275           vector_str_dest(&v->ext_name);
4276 }
4277 
4278 /* size, capacity, ext_name */
4279 static int
vector_type_qualifier_init(struct vector_type_qualifier * v)4280 vector_type_qualifier_init(struct vector_type_qualifier *v)
4281 {
4282 
4283           if (v == NULL)
4284                     return (0);
4285 
4286           v->size = 0;
4287           v->capacity = VECTOR_DEF_CAPACITY;
4288 
4289           if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity))
4290               == NULL)
4291                     return (0);
4292 
4293           assert(v->q_container != NULL);
4294 
4295           if (!vector_str_init(&v->ext_name)) {
4296                     free(v->q_container);
4297                     return (0);
4298           }
4299 
4300           return (1);
4301 }
4302 
4303 static int
vector_type_qualifier_push(struct vector_type_qualifier * v,enum type_qualifier t)4304 vector_type_qualifier_push(struct vector_type_qualifier *v,
4305     enum type_qualifier t)
4306 {
4307           enum type_qualifier *tmp_ctn;
4308           size_t tmp_cap;
4309           size_t i;
4310 
4311           if (v == NULL)
4312                     return (0);
4313 
4314           if (v->size == v->capacity) {
4315                     tmp_cap = BUFFER_GROW(v->capacity);
4316                     if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap))
4317                         == NULL)
4318                               return (0);
4319                     for (i = 0; i < v->size; ++i)
4320                               tmp_ctn[i] = v->q_container[i];
4321                     free(v->q_container);
4322                     v->q_container = tmp_ctn;
4323                     v->capacity = tmp_cap;
4324           }
4325 
4326           v->q_container[v->size] = t;
4327           ++v->size;
4328 
4329           return (1);
4330 }
4331