1a85fe12eSEd Maste /*- 2a85fe12eSEd Maste * Copyright (c) 2008 Hyogeol Lee <hyogeollee@gmail.com> 3a85fe12eSEd Maste * All rights reserved. 4a85fe12eSEd Maste * 5a85fe12eSEd Maste * Redistribution and use in source and binary forms, with or without 6a85fe12eSEd Maste * modification, are permitted provided that the following conditions 7a85fe12eSEd Maste * are met: 8a85fe12eSEd Maste * 1. Redistributions of source code must retain the above copyright 9a85fe12eSEd Maste * notice, this list of conditions and the following disclaimer 10a85fe12eSEd Maste * in this position and unchanged. 11a85fe12eSEd Maste * 2. Redistributions in binary form must reproduce the above copyright 12a85fe12eSEd Maste * notice, this list of conditions and the following disclaimer in the 13a85fe12eSEd Maste * documentation and/or other materials provided with the distribution. 14a85fe12eSEd Maste * 15a85fe12eSEd Maste * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16a85fe12eSEd Maste * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17a85fe12eSEd Maste * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18a85fe12eSEd Maste * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19a85fe12eSEd Maste * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20a85fe12eSEd Maste * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21a85fe12eSEd Maste * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22a85fe12eSEd Maste * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23a85fe12eSEd Maste * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24a85fe12eSEd Maste * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25a85fe12eSEd Maste */ 26a85fe12eSEd Maste 27a85fe12eSEd Maste #include <sys/types.h> 28a85fe12eSEd Maste #include <assert.h> 29a85fe12eSEd Maste #include <ctype.h> 30a85fe12eSEd Maste #include <errno.h> 31a85fe12eSEd Maste #include <libelftc.h> 32a85fe12eSEd Maste #include <limits.h> 33a85fe12eSEd Maste #include <stdbool.h> 34a85fe12eSEd Maste #include <stdio.h> 35a85fe12eSEd Maste #include <stdlib.h> 36a85fe12eSEd Maste #include <string.h> 37a85fe12eSEd Maste 38a85fe12eSEd Maste #include "_libelftc.h" 39a85fe12eSEd Maste 40*bee2765cSEd Maste ELFTC_VCSID("$Id: libelftc_dem_gnu2.c 3513 2016-12-29 07:04:22Z kaiwang27 $"); 41a85fe12eSEd Maste 42a85fe12eSEd Maste /** 43a85fe12eSEd Maste * @file cpp_demangle_gnu2.c 44a85fe12eSEd Maste * @brief Decode function name encoding in GNU 2. 45a85fe12eSEd Maste * 46a85fe12eSEd Maste * Function name encoding in GNU 2 based on ARM style. 47a85fe12eSEd Maste */ 48a85fe12eSEd Maste 49a85fe12eSEd Maste enum encode_type { 50a85fe12eSEd Maste ENCODE_FUNC, ENCODE_OP, ENCODE_OP_CT, ENCODE_OP_DT, ENCODE_OP_USER, 51a85fe12eSEd Maste ENCODE_OP_TF, ENCODE_OP_TI, ENCODE_OP_VT 52a85fe12eSEd Maste }; 53a85fe12eSEd Maste 54a85fe12eSEd Maste struct cstring { 55a85fe12eSEd Maste char *buf; 56a85fe12eSEd Maste size_t size; 57a85fe12eSEd Maste }; 58a85fe12eSEd Maste 59a85fe12eSEd Maste struct demangle_data { 60a85fe12eSEd Maste bool ptr, ref, cnst, array, cnst_fn, class_name; 61a85fe12eSEd Maste struct cstring array_str; 62a85fe12eSEd Maste const char *p; 63a85fe12eSEd Maste enum encode_type type; 64a85fe12eSEd Maste struct vector_str vec; 65a85fe12eSEd Maste struct vector_str arg; 66a85fe12eSEd Maste }; 67a85fe12eSEd Maste 68a85fe12eSEd Maste #define SIMPLE_HASH(x,y) (64 * x + y) 69*bee2765cSEd Maste #define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s))) 70a85fe12eSEd Maste #define CPP_DEMANGLE_GNU2_TRY 128 71a85fe12eSEd Maste 72a85fe12eSEd Maste static void dest_cstring(struct cstring *); 73a85fe12eSEd Maste static void dest_demangle_data(struct demangle_data *); 74a85fe12eSEd Maste static bool init_cstring(struct cstring *, size_t); 75a85fe12eSEd Maste static bool init_demangle_data(struct demangle_data *); 76a85fe12eSEd Maste static bool push_CTDT(const char *, size_t, struct vector_str *); 77a85fe12eSEd Maste static bool read_array(struct demangle_data *); 78a85fe12eSEd Maste static bool read_class(struct demangle_data *); 79a85fe12eSEd Maste static bool read_func(struct demangle_data *); 80a85fe12eSEd Maste static bool read_func_name(struct demangle_data *); 81a85fe12eSEd Maste static bool read_func_ptr(struct demangle_data *); 82a85fe12eSEd Maste static bool read_memptr(struct demangle_data *); 83a85fe12eSEd Maste static bool read_op(struct demangle_data *); 84a85fe12eSEd Maste static bool read_op_user(struct demangle_data *); 85a85fe12eSEd Maste static bool read_qual_name(struct demangle_data *); 86a85fe12eSEd Maste static int read_subst(struct demangle_data *); 87a85fe12eSEd Maste static int read_subst_iter(struct demangle_data *); 88a85fe12eSEd Maste static bool read_type(struct demangle_data *); 89a85fe12eSEd Maste 90a85fe12eSEd Maste /** 91a85fe12eSEd Maste * @brief Decode the input string by the GNU 2 style. 92a85fe12eSEd Maste * 93a85fe12eSEd Maste * @return New allocated demangled string or NULL if failed. 94a85fe12eSEd Maste */ 95a85fe12eSEd Maste char * 96a85fe12eSEd Maste cpp_demangle_gnu2(const char *org) 97a85fe12eSEd Maste { 98a85fe12eSEd Maste struct demangle_data d; 99a85fe12eSEd Maste size_t arg_begin, arg_len; 100a85fe12eSEd Maste unsigned int try; 101a85fe12eSEd Maste char *rtn, *arg; 102a85fe12eSEd Maste 103a85fe12eSEd Maste if (org == NULL) 104a85fe12eSEd Maste return (NULL); 105a85fe12eSEd Maste 106a85fe12eSEd Maste if (init_demangle_data(&d) == false) 107a85fe12eSEd Maste return (NULL); 108a85fe12eSEd Maste 109a85fe12eSEd Maste try = 0; 110a85fe12eSEd Maste rtn = NULL; 111a85fe12eSEd Maste 112a85fe12eSEd Maste d.p = org; 113a85fe12eSEd Maste if (read_func_name(&d) == false) 114a85fe12eSEd Maste goto clean; 115a85fe12eSEd Maste 116a85fe12eSEd Maste switch (d.type) { 117a85fe12eSEd Maste case ENCODE_FUNC : 118a85fe12eSEd Maste case ENCODE_OP : 119a85fe12eSEd Maste break; 120a85fe12eSEd Maste 121a85fe12eSEd Maste case ENCODE_OP_CT : 122a85fe12eSEd Maste if (push_CTDT("::", 2, &d.vec) == false) 123a85fe12eSEd Maste goto clean; 124a85fe12eSEd Maste 125a85fe12eSEd Maste break; 126a85fe12eSEd Maste case ENCODE_OP_DT : 127a85fe12eSEd Maste if (push_CTDT("::~", 3, &d.vec) == false) 128a85fe12eSEd Maste goto clean; 129a85fe12eSEd Maste 130*bee2765cSEd Maste if (VEC_PUSH_STR(&d.vec, "(void)") == false) 131a85fe12eSEd Maste goto clean; 132a85fe12eSEd Maste 133a85fe12eSEd Maste goto flat; 134a85fe12eSEd Maste case ENCODE_OP_USER : 135a85fe12eSEd Maste case ENCODE_OP_TF : 136a85fe12eSEd Maste case ENCODE_OP_TI : 137a85fe12eSEd Maste case ENCODE_OP_VT : 138a85fe12eSEd Maste goto flat; 139b6b6f9ccSEd Maste } 140a85fe12eSEd Maste 141a85fe12eSEd Maste if (*d.p == 'F') 142a85fe12eSEd Maste ++d.p; 143a85fe12eSEd Maste else if (*d.p == '\0') { 144a85fe12eSEd Maste if (d.class_name == true) { 145*bee2765cSEd Maste if (VEC_PUSH_STR(&d.vec, "(void)") == false) 146a85fe12eSEd Maste goto clean; 147a85fe12eSEd Maste 148a85fe12eSEd Maste goto flat; 149a85fe12eSEd Maste } else 150a85fe12eSEd Maste goto clean; 151a85fe12eSEd Maste } 152a85fe12eSEd Maste 153a85fe12eSEd Maste /* start argument types */ 154*bee2765cSEd Maste if (VEC_PUSH_STR(&d.vec, "(") == false) 155a85fe12eSEd Maste goto clean; 156a85fe12eSEd Maste 157a85fe12eSEd Maste for (;;) { 158a85fe12eSEd Maste if (*d.p == 'T') { 159a85fe12eSEd Maste const int rtn_subst = read_subst(&d); 160a85fe12eSEd Maste 161a85fe12eSEd Maste if (rtn_subst == -1) 162a85fe12eSEd Maste goto clean; 163a85fe12eSEd Maste else if (rtn_subst == 1) 164a85fe12eSEd Maste break; 165a85fe12eSEd Maste 166a85fe12eSEd Maste continue; 167a85fe12eSEd Maste } 168a85fe12eSEd Maste 169a85fe12eSEd Maste if (*d.p == 'N') { 170a85fe12eSEd Maste const int rtn_subst_iter = read_subst_iter(&d); 171a85fe12eSEd Maste 172a85fe12eSEd Maste if (rtn_subst_iter == -1) 173a85fe12eSEd Maste goto clean; 174a85fe12eSEd Maste else if(rtn_subst_iter == 1) 175a85fe12eSEd Maste break; 176a85fe12eSEd Maste 177a85fe12eSEd Maste continue; 178a85fe12eSEd Maste } 179a85fe12eSEd Maste 180a85fe12eSEd Maste arg_begin = d.vec.size; 181a85fe12eSEd Maste 182a85fe12eSEd Maste if (read_type(&d) == false) 183a85fe12eSEd Maste goto clean; 184a85fe12eSEd Maste 185a85fe12eSEd Maste if (d.ptr == true) { 186*bee2765cSEd Maste if (VEC_PUSH_STR(&d.vec, "*") == false) 187a85fe12eSEd Maste goto clean; 188a85fe12eSEd Maste 189a85fe12eSEd Maste d.ptr = false; 190a85fe12eSEd Maste } 191a85fe12eSEd Maste 192a85fe12eSEd Maste if (d.ref == true) { 193*bee2765cSEd Maste if (VEC_PUSH_STR(&d.vec, "&") == false) 194a85fe12eSEd Maste goto clean; 195a85fe12eSEd Maste 196a85fe12eSEd Maste d.ref = false; 197a85fe12eSEd Maste } 198a85fe12eSEd Maste 199a85fe12eSEd Maste if (d.cnst == true) { 200*bee2765cSEd Maste if (VEC_PUSH_STR(&d.vec, " const") == false) 201a85fe12eSEd Maste goto clean; 202a85fe12eSEd Maste 203a85fe12eSEd Maste d.cnst = false; 204a85fe12eSEd Maste } 205a85fe12eSEd Maste 206a85fe12eSEd Maste if (d.array == true) { 207a85fe12eSEd Maste if (vector_str_push(&d.vec, d.array_str.buf, 208a85fe12eSEd Maste d.array_str.size) == false) 209a85fe12eSEd Maste goto clean; 210a85fe12eSEd Maste 211a85fe12eSEd Maste dest_cstring(&d.array_str); 212a85fe12eSEd Maste d.array = false; 213a85fe12eSEd Maste } 214a85fe12eSEd Maste 215a85fe12eSEd Maste if (*d.p == '\0') 216a85fe12eSEd Maste break; 217a85fe12eSEd Maste 218a85fe12eSEd Maste if ((arg = vector_str_substr(&d.vec, arg_begin, d.vec.size - 1, 219a85fe12eSEd Maste &arg_len)) == NULL) 220a85fe12eSEd Maste goto clean; 221a85fe12eSEd Maste 222a85fe12eSEd Maste if (vector_str_push(&d.arg, arg, arg_len) == false) 223a85fe12eSEd Maste goto clean; 224a85fe12eSEd Maste 225a85fe12eSEd Maste free(arg); 226a85fe12eSEd Maste 227*bee2765cSEd Maste if (VEC_PUSH_STR(&d.vec, ", ") == false) 228a85fe12eSEd Maste goto clean; 229a85fe12eSEd Maste 230a85fe12eSEd Maste if (++try > CPP_DEMANGLE_GNU2_TRY) 231a85fe12eSEd Maste goto clean; 232a85fe12eSEd Maste } 233a85fe12eSEd Maste 234a85fe12eSEd Maste /* end argument types */ 235*bee2765cSEd Maste if (VEC_PUSH_STR(&d.vec, ")") == false) 236a85fe12eSEd Maste goto clean; 237a85fe12eSEd Maste flat: 238*bee2765cSEd Maste if (d.cnst_fn == true && VEC_PUSH_STR(&d.vec, " const") == false) 239a85fe12eSEd Maste goto clean; 240a85fe12eSEd Maste 241a85fe12eSEd Maste rtn = vector_str_get_flat(&d.vec, NULL); 242a85fe12eSEd Maste clean: 243a85fe12eSEd Maste dest_demangle_data(&d); 244a85fe12eSEd Maste 245a85fe12eSEd Maste return (rtn); 246a85fe12eSEd Maste } 247a85fe12eSEd Maste 248a85fe12eSEd Maste /** 249a85fe12eSEd Maste * @brief Test input string is encoded by the GNU 2 style. 250a85fe12eSEd Maste * 251a85fe12eSEd Maste * @return True if input string is encoded by the GNU 2 style. 252a85fe12eSEd Maste */ 253a85fe12eSEd Maste bool 254a85fe12eSEd Maste is_cpp_mangled_gnu2(const char *org) 255a85fe12eSEd Maste { 256a85fe12eSEd Maste char *str; 257a85fe12eSEd Maste bool rtn = false; 258a85fe12eSEd Maste 259a85fe12eSEd Maste if (org == NULL) 260a85fe12eSEd Maste return (false); 261a85fe12eSEd Maste 262a85fe12eSEd Maste /* search valid text to end */ 263a85fe12eSEd Maste str = strstr(org, "__"); 264a85fe12eSEd Maste while (str != NULL) { 265a85fe12eSEd Maste if (*(str + 2) != '\0') { 266a85fe12eSEd Maste if (*(str + 2) == 'C' || 267a85fe12eSEd Maste *(str + 2) == 'F' || 268a85fe12eSEd Maste *(str + 2) == 'Q' || 269a85fe12eSEd Maste ELFTC_ISDIGIT(*(str + 2))) { 270a85fe12eSEd Maste rtn |= true; 271a85fe12eSEd Maste 272a85fe12eSEd Maste break; 273a85fe12eSEd Maste } 274a85fe12eSEd Maste 275a85fe12eSEd Maste if (*(str + 3) != '\0') { 276a85fe12eSEd Maste switch (SIMPLE_HASH(*(str + 2), *(str + 3))) { 277a85fe12eSEd Maste case SIMPLE_HASH('m', 'l') : 278a85fe12eSEd Maste case SIMPLE_HASH('d', 'v') : 279a85fe12eSEd Maste case SIMPLE_HASH('m', 'd') : 280a85fe12eSEd Maste case SIMPLE_HASH('p', 'l') : 281a85fe12eSEd Maste case SIMPLE_HASH('m', 'i') : 282a85fe12eSEd Maste case SIMPLE_HASH('l', 's') : 283a85fe12eSEd Maste case SIMPLE_HASH('r', 's') : 284a85fe12eSEd Maste case SIMPLE_HASH('e', 'q') : 285a85fe12eSEd Maste case SIMPLE_HASH('n', 'e') : 286a85fe12eSEd Maste case SIMPLE_HASH('l', 't') : 287a85fe12eSEd Maste case SIMPLE_HASH('g', 't') : 288a85fe12eSEd Maste case SIMPLE_HASH('l', 'e') : 289a85fe12eSEd Maste case SIMPLE_HASH('g', 'e') : 290a85fe12eSEd Maste case SIMPLE_HASH('a', 'd') : 291a85fe12eSEd Maste case SIMPLE_HASH('o', 'r') : 292a85fe12eSEd Maste case SIMPLE_HASH('e', 'r') : 293a85fe12eSEd Maste case SIMPLE_HASH('a', 'a') : 294a85fe12eSEd Maste case SIMPLE_HASH('o', 'o') : 295a85fe12eSEd Maste case SIMPLE_HASH('n', 't') : 296a85fe12eSEd Maste case SIMPLE_HASH('c', 'o') : 297a85fe12eSEd Maste case SIMPLE_HASH('p', 'p') : 298a85fe12eSEd Maste case SIMPLE_HASH('m', 'm') : 299a85fe12eSEd Maste case SIMPLE_HASH('a', 's') : 300a85fe12eSEd Maste case SIMPLE_HASH('r', 'f') : 301a85fe12eSEd Maste case SIMPLE_HASH('a', 'p') : 302a85fe12eSEd Maste case SIMPLE_HASH('a', 'm') : 303a85fe12eSEd Maste case SIMPLE_HASH('a', 'l') : 304a85fe12eSEd Maste case SIMPLE_HASH('a', 'r') : 305a85fe12eSEd Maste case SIMPLE_HASH('a', 'o') : 306a85fe12eSEd Maste case SIMPLE_HASH('a', 'e') : 307a85fe12eSEd Maste case SIMPLE_HASH('c', 'm') : 308a85fe12eSEd Maste case SIMPLE_HASH('r', 'm') : 309a85fe12eSEd Maste case SIMPLE_HASH('c', 'l') : 310a85fe12eSEd Maste case SIMPLE_HASH('v', 'c') : 311a85fe12eSEd Maste case SIMPLE_HASH('n', 'w') : 312a85fe12eSEd Maste case SIMPLE_HASH('d', 'l') : 313a85fe12eSEd Maste case SIMPLE_HASH('o', 'p') : 314a85fe12eSEd Maste case SIMPLE_HASH('t', 'f') : 315a85fe12eSEd Maste case SIMPLE_HASH('t', 'i') : 316a85fe12eSEd Maste rtn |= true; 317a85fe12eSEd Maste 318a85fe12eSEd Maste break; 319b6b6f9ccSEd Maste } 320a85fe12eSEd Maste } 321a85fe12eSEd Maste } 322a85fe12eSEd Maste 323a85fe12eSEd Maste str = strstr(str + 2, "__"); 324a85fe12eSEd Maste } 325a85fe12eSEd Maste 326a85fe12eSEd Maste rtn |= strstr(org, "_$_") != NULL; 327a85fe12eSEd Maste rtn |= strstr(org, "_vt$") != NULL; 328a85fe12eSEd Maste 329a85fe12eSEd Maste return (rtn); 330a85fe12eSEd Maste } 331a85fe12eSEd Maste 332a85fe12eSEd Maste static void 333a85fe12eSEd Maste dest_cstring(struct cstring *s) 334a85fe12eSEd Maste { 335a85fe12eSEd Maste 336a85fe12eSEd Maste if (s == NULL) 337a85fe12eSEd Maste return; 338a85fe12eSEd Maste 339a85fe12eSEd Maste free(s->buf); 340a85fe12eSEd Maste s->buf = NULL; 341a85fe12eSEd Maste s->size = 0; 342a85fe12eSEd Maste } 343a85fe12eSEd Maste 344a85fe12eSEd Maste static void 345a85fe12eSEd Maste dest_demangle_data(struct demangle_data *d) 346a85fe12eSEd Maste { 347a85fe12eSEd Maste 348a85fe12eSEd Maste if (d != NULL) { 349a85fe12eSEd Maste vector_str_dest(&d->arg); 350a85fe12eSEd Maste vector_str_dest(&d->vec); 351a85fe12eSEd Maste 352a85fe12eSEd Maste dest_cstring(&d->array_str); 353a85fe12eSEd Maste } 354a85fe12eSEd Maste } 355a85fe12eSEd Maste 356a85fe12eSEd Maste static bool 357a85fe12eSEd Maste init_cstring(struct cstring *s, size_t len) 358a85fe12eSEd Maste { 359a85fe12eSEd Maste 360a85fe12eSEd Maste if (s == NULL || len <= 1) 361a85fe12eSEd Maste return (false); 362a85fe12eSEd Maste 363a85fe12eSEd Maste if ((s->buf = malloc(sizeof(char) * len)) == NULL) 364a85fe12eSEd Maste return (false); 365a85fe12eSEd Maste 366a85fe12eSEd Maste s->size = len - 1; 367a85fe12eSEd Maste 368a85fe12eSEd Maste return (true); 369a85fe12eSEd Maste } 370a85fe12eSEd Maste 371a85fe12eSEd Maste static bool 372a85fe12eSEd Maste init_demangle_data(struct demangle_data *d) 373a85fe12eSEd Maste { 374a85fe12eSEd Maste 375a85fe12eSEd Maste if (d == NULL) 376a85fe12eSEd Maste return (false); 377a85fe12eSEd Maste 378a85fe12eSEd Maste d->ptr = false; 379a85fe12eSEd Maste d->ref = false; 380a85fe12eSEd Maste d->cnst = false; 381a85fe12eSEd Maste d->array = false; 382a85fe12eSEd Maste d->cnst_fn = false; 383a85fe12eSEd Maste d->class_name = false; 384a85fe12eSEd Maste 385a85fe12eSEd Maste d->array_str.buf = NULL; 386a85fe12eSEd Maste d->array_str.size = 0; 387a85fe12eSEd Maste 388a85fe12eSEd Maste d->type = ENCODE_FUNC; 389a85fe12eSEd Maste 390a85fe12eSEd Maste if (vector_str_init(&d->vec) == false) 391a85fe12eSEd Maste return (false); 392a85fe12eSEd Maste 393a85fe12eSEd Maste if (vector_str_init(&d->arg) == false) { 394a85fe12eSEd Maste vector_str_dest(&d->vec); 395a85fe12eSEd Maste 396a85fe12eSEd Maste return (false); 397a85fe12eSEd Maste } 398a85fe12eSEd Maste 399a85fe12eSEd Maste return (true); 400a85fe12eSEd Maste } 401a85fe12eSEd Maste 402a85fe12eSEd Maste static bool 403a85fe12eSEd Maste push_CTDT(const char *s, size_t l, struct vector_str *v) 404a85fe12eSEd Maste { 405a85fe12eSEd Maste 406a85fe12eSEd Maste if (s == NULL || l == 0 || v == NULL) 407a85fe12eSEd Maste return (false); 408a85fe12eSEd Maste 409a85fe12eSEd Maste if (vector_str_push(v, s, l) == false) 410a85fe12eSEd Maste return (false); 411a85fe12eSEd Maste 412a85fe12eSEd Maste assert(v->size > 1); 413a85fe12eSEd Maste 414*bee2765cSEd Maste return (VEC_PUSH_STR(v, v->container[v->size - 2])); 415a85fe12eSEd Maste } 416a85fe12eSEd Maste 417a85fe12eSEd Maste static bool 418a85fe12eSEd Maste read_array(struct demangle_data *d) 419a85fe12eSEd Maste { 420a85fe12eSEd Maste size_t len; 421a85fe12eSEd Maste const char *end; 422a85fe12eSEd Maste 423a85fe12eSEd Maste if (d == NULL || d->p == NULL) 424a85fe12eSEd Maste return (false); 425a85fe12eSEd Maste 426a85fe12eSEd Maste end = d->p; 427a85fe12eSEd Maste assert(end != NULL); 428a85fe12eSEd Maste 429a85fe12eSEd Maste for (;;) { 430a85fe12eSEd Maste if (*end == '\0') 431a85fe12eSEd Maste return (false); 432a85fe12eSEd Maste 433a85fe12eSEd Maste if (ELFTC_ISDIGIT(*end) == 0) 434a85fe12eSEd Maste break; 435a85fe12eSEd Maste 436a85fe12eSEd Maste ++end; 437a85fe12eSEd Maste } 438a85fe12eSEd Maste 439a85fe12eSEd Maste if (*end != '_') 440a85fe12eSEd Maste return (false); 441a85fe12eSEd Maste 442a85fe12eSEd Maste len = end - d->p; 443a85fe12eSEd Maste assert(len > 0); 444a85fe12eSEd Maste 445a85fe12eSEd Maste dest_cstring(&d->array_str); 446a85fe12eSEd Maste if (init_cstring(&d->array_str, len + 3) == false) 447a85fe12eSEd Maste return (false); 448a85fe12eSEd Maste 449a85fe12eSEd Maste strncpy(d->array_str.buf + 1, d->p, len); 450a85fe12eSEd Maste *d->array_str.buf = '['; 451a85fe12eSEd Maste *(d->array_str.buf + len + 1) = ']'; 452a85fe12eSEd Maste 453a85fe12eSEd Maste d->array = true; 454a85fe12eSEd Maste d->p = end + 1; 455a85fe12eSEd Maste 456a85fe12eSEd Maste return (true); 457a85fe12eSEd Maste } 458a85fe12eSEd Maste 459a85fe12eSEd Maste static bool 460a85fe12eSEd Maste read_class(struct demangle_data *d) 461a85fe12eSEd Maste { 462a85fe12eSEd Maste size_t len; 463a85fe12eSEd Maste char *str; 464a85fe12eSEd Maste 465a85fe12eSEd Maste if (d == NULL) 466a85fe12eSEd Maste return (false); 467a85fe12eSEd Maste 468a85fe12eSEd Maste len = strtol(d->p, &str, 10); 469a85fe12eSEd Maste if (len == 0 && (errno == EINVAL || errno == ERANGE)) 470a85fe12eSEd Maste return (false); 471a85fe12eSEd Maste 472a85fe12eSEd Maste assert(len > 0); 473a85fe12eSEd Maste assert(str != NULL); 474a85fe12eSEd Maste 475a85fe12eSEd Maste if (vector_str_push(&d->vec, str, len) == false) 476a85fe12eSEd Maste return (false); 477a85fe12eSEd Maste 478a85fe12eSEd Maste d->p = str + len; 479a85fe12eSEd Maste 480a85fe12eSEd Maste d->class_name = true; 481a85fe12eSEd Maste 482a85fe12eSEd Maste return (true); 483a85fe12eSEd Maste } 484a85fe12eSEd Maste 485a85fe12eSEd Maste static bool 486a85fe12eSEd Maste read_func(struct demangle_data *d) 487a85fe12eSEd Maste { 488a85fe12eSEd Maste size_t len; 489a85fe12eSEd Maste const char *name; 490a85fe12eSEd Maste char *delim; 491a85fe12eSEd Maste 492a85fe12eSEd Maste if (d == NULL) 493a85fe12eSEd Maste return (false); 494a85fe12eSEd Maste 495a85fe12eSEd Maste assert(d->p != NULL && "d->p (org str) is NULL"); 496a85fe12eSEd Maste if ((delim = strstr(d->p, "__")) == NULL) 497a85fe12eSEd Maste return (false); 498a85fe12eSEd Maste 499a85fe12eSEd Maste len = delim - d->p; 500a85fe12eSEd Maste assert(len != 0); 501a85fe12eSEd Maste 502a85fe12eSEd Maste name = d->p; 503a85fe12eSEd Maste 504a85fe12eSEd Maste d->p = delim + 2; 505a85fe12eSEd Maste 506a85fe12eSEd Maste if (*d->p == 'C') { 507a85fe12eSEd Maste ++d->p; 508a85fe12eSEd Maste 509a85fe12eSEd Maste d->cnst_fn = true; 510a85fe12eSEd Maste } 511a85fe12eSEd Maste 512a85fe12eSEd Maste if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { 513a85fe12eSEd Maste ++d->p; 514a85fe12eSEd Maste 515a85fe12eSEd Maste if (read_qual_name(d) == false) 516a85fe12eSEd Maste return (false); 517a85fe12eSEd Maste } else if (ELFTC_ISDIGIT(*d->p)) { 518a85fe12eSEd Maste if (read_class(d) == false) 519a85fe12eSEd Maste return (false); 520a85fe12eSEd Maste 521*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "::") == false) 522a85fe12eSEd Maste return (false); 523a85fe12eSEd Maste } 524a85fe12eSEd Maste 525a85fe12eSEd Maste return (vector_str_push(&d->vec, name, len)); 526a85fe12eSEd Maste } 527a85fe12eSEd Maste 528a85fe12eSEd Maste static bool 529a85fe12eSEd Maste read_func_name(struct demangle_data *d) 530a85fe12eSEd Maste { 531a85fe12eSEd Maste size_t len; 532a85fe12eSEd Maste bool rtn; 533a85fe12eSEd Maste char *op_name; 534a85fe12eSEd Maste 535a85fe12eSEd Maste if (d == NULL) 536a85fe12eSEd Maste return (false); 537a85fe12eSEd Maste 538a85fe12eSEd Maste rtn = false; 539a85fe12eSEd Maste op_name = NULL; 540a85fe12eSEd Maste 541a85fe12eSEd Maste assert(d->p != NULL && "d->p (org str) is NULL"); 542a85fe12eSEd Maste 543a85fe12eSEd Maste if (*d->p == '_' && *(d->p + 1) == '_') { 544a85fe12eSEd Maste d->p += 2; 545a85fe12eSEd Maste 546a85fe12eSEd Maste /* CTOR */ 547a85fe12eSEd Maste if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { 548a85fe12eSEd Maste ++d->p; 549a85fe12eSEd Maste d->type = ENCODE_OP_CT; 550a85fe12eSEd Maste 551a85fe12eSEd Maste if (read_qual_name(d) == false) 552a85fe12eSEd Maste return (false); 553a85fe12eSEd Maste 554a85fe12eSEd Maste return (vector_str_pop(&d->vec)); 555a85fe12eSEd Maste } else if (ELFTC_ISDIGIT(*d->p)) { 556a85fe12eSEd Maste d->type = ENCODE_OP_CT; 557a85fe12eSEd Maste 558a85fe12eSEd Maste return (read_class(d)); 559a85fe12eSEd Maste } 560a85fe12eSEd Maste 561a85fe12eSEd Maste d->type = ENCODE_OP; 562a85fe12eSEd Maste if (read_op(d) == false) { 563a85fe12eSEd Maste /* not good condition, start function name with '__' */ 564a85fe12eSEd Maste d->type = ENCODE_FUNC; 565a85fe12eSEd Maste 566*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "__") == false) 567a85fe12eSEd Maste return (false); 568a85fe12eSEd Maste 569a85fe12eSEd Maste return (read_func(d)); 570a85fe12eSEd Maste } 571a85fe12eSEd Maste 572a85fe12eSEd Maste if (d->type == ENCODE_OP_USER || 573a85fe12eSEd Maste d->type == ENCODE_OP_TF || 574a85fe12eSEd Maste d->type == ENCODE_OP_TI) 575a85fe12eSEd Maste return (true); 576a85fe12eSEd Maste 577a85fe12eSEd Maste /* skip "__" */ 578a85fe12eSEd Maste d->p += 2; 579a85fe12eSEd Maste 580a85fe12eSEd Maste if (*d->p == 'C') { 581a85fe12eSEd Maste ++d->p; 582a85fe12eSEd Maste 583a85fe12eSEd Maste d->cnst_fn = true; 584a85fe12eSEd Maste } 585a85fe12eSEd Maste 586a85fe12eSEd Maste /* assume delimiter is removed */ 587a85fe12eSEd Maste if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { 588a85fe12eSEd Maste ++d->p; 589a85fe12eSEd Maste 590a85fe12eSEd Maste assert(d->vec.size > 0); 591a85fe12eSEd Maste 592a85fe12eSEd Maste len = strlen(d->vec.container[d->vec.size - 1]); 593a85fe12eSEd Maste if ((op_name = malloc(sizeof(char) * (len + 1))) 594a85fe12eSEd Maste == NULL) 595a85fe12eSEd Maste return (false); 596a85fe12eSEd Maste 597a85fe12eSEd Maste snprintf(op_name, len + 1, "%s", 598a85fe12eSEd Maste d->vec.container[d->vec.size - 1]); 599a85fe12eSEd Maste vector_str_pop(&d->vec); 600a85fe12eSEd Maste 601a85fe12eSEd Maste if (read_qual_name(d) == false) 602a85fe12eSEd Maste goto clean; 603a85fe12eSEd Maste 604*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "::") == false) 605a85fe12eSEd Maste goto clean; 606a85fe12eSEd Maste 607a85fe12eSEd Maste if (vector_str_push(&d->vec, op_name, len) == false) 608a85fe12eSEd Maste goto clean; 609a85fe12eSEd Maste 610a85fe12eSEd Maste rtn = true; 611a85fe12eSEd Maste } else if (ELFTC_ISDIGIT(*d->p)) { 612a85fe12eSEd Maste assert(d->vec.size > 0); 613a85fe12eSEd Maste 614a85fe12eSEd Maste len = strlen(d->vec.container[d->vec.size - 1]); 615a85fe12eSEd Maste if ((op_name = malloc(sizeof(char) * (len + 1))) 616a85fe12eSEd Maste == NULL) 617a85fe12eSEd Maste return (false); 618a85fe12eSEd Maste 619a85fe12eSEd Maste snprintf(op_name, len + 1, "%s", 620a85fe12eSEd Maste d->vec.container[d->vec.size - 1]); 621a85fe12eSEd Maste vector_str_pop(&d->vec); 622a85fe12eSEd Maste 623a85fe12eSEd Maste if (read_class(d) == false) 624a85fe12eSEd Maste goto clean; 625a85fe12eSEd Maste 626*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "::") == false) 627a85fe12eSEd Maste goto clean; 628a85fe12eSEd Maste 629a85fe12eSEd Maste if (vector_str_push(&d->vec, op_name, len) == false) 630a85fe12eSEd Maste goto clean; 631a85fe12eSEd Maste 632a85fe12eSEd Maste rtn = true; 633a85fe12eSEd Maste } 634a85fe12eSEd Maste } else if (memcmp(d->p, "_$_", 3) == 0) { 635a85fe12eSEd Maste /* DTOR */ 636a85fe12eSEd Maste d->p += 3; 637a85fe12eSEd Maste d->type = ENCODE_OP_DT; 638a85fe12eSEd Maste 639a85fe12eSEd Maste if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { 640a85fe12eSEd Maste ++d->p; 641a85fe12eSEd Maste 642a85fe12eSEd Maste if (read_qual_name(d) == false) 643a85fe12eSEd Maste return (false); 644a85fe12eSEd Maste 645a85fe12eSEd Maste return (vector_str_pop(&d->vec)); 646a85fe12eSEd Maste } else if (ELFTC_ISDIGIT(*d->p)) 647a85fe12eSEd Maste return (read_class(d)); 648a85fe12eSEd Maste 649a85fe12eSEd Maste return (false); 650a85fe12eSEd Maste } else if (memcmp(d->p, "_vt$", 4) == 0) { 651a85fe12eSEd Maste /* vtable */ 652a85fe12eSEd Maste d->p += 4; 653a85fe12eSEd Maste d->type = ENCODE_OP_VT; 654a85fe12eSEd Maste 655a85fe12eSEd Maste if (*d->p == 'Q' && ELFTC_ISDIGIT(*(d->p + 1))) { 656a85fe12eSEd Maste ++d->p; 657a85fe12eSEd Maste 658a85fe12eSEd Maste if (read_qual_name(d) == false) 659a85fe12eSEd Maste return (false); 660a85fe12eSEd Maste 661a85fe12eSEd Maste if (vector_str_pop(&d->vec) == false) 662a85fe12eSEd Maste return (false); 663a85fe12eSEd Maste } else if (ELFTC_ISDIGIT(*d->p)) { 664a85fe12eSEd Maste if (read_class(d) == false) 665a85fe12eSEd Maste return (false); 666a85fe12eSEd Maste } 667a85fe12eSEd Maste 668*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, " virtual table")); 669a85fe12eSEd Maste } else 670a85fe12eSEd Maste return (read_func(d)); 671a85fe12eSEd Maste clean: 672a85fe12eSEd Maste free(op_name); 673a85fe12eSEd Maste 674a85fe12eSEd Maste return (rtn); 675a85fe12eSEd Maste } 676a85fe12eSEd Maste 677a85fe12eSEd Maste /* Read function ptr type */ 678a85fe12eSEd Maste static bool 679a85fe12eSEd Maste read_func_ptr(struct demangle_data *d) 680a85fe12eSEd Maste { 681a85fe12eSEd Maste struct demangle_data fptr; 682a85fe12eSEd Maste size_t arg_len, rtn_len; 683a85fe12eSEd Maste char *arg_type, *rtn_type; 684a85fe12eSEd Maste int lim; 685a85fe12eSEd Maste 686a85fe12eSEd Maste if (d == NULL) 687a85fe12eSEd Maste return (false); 688a85fe12eSEd Maste 689a85fe12eSEd Maste if (init_demangle_data(&fptr) == false) 690a85fe12eSEd Maste return (false); 691a85fe12eSEd Maste 692a85fe12eSEd Maste fptr.p = d->p + 1; 693a85fe12eSEd Maste lim = 0; 694a85fe12eSEd Maste arg_type = NULL; 695a85fe12eSEd Maste rtn_type = NULL; 696a85fe12eSEd Maste 697a85fe12eSEd Maste for (;;) { 698a85fe12eSEd Maste if (read_type(&fptr) == false) { 699a85fe12eSEd Maste dest_demangle_data(&fptr); 700a85fe12eSEd Maste 701a85fe12eSEd Maste return (false); 702a85fe12eSEd Maste } 703a85fe12eSEd Maste 704a85fe12eSEd Maste if (fptr.ptr == true) { 705*bee2765cSEd Maste if (VEC_PUSH_STR(&fptr.vec, "*") == false) { 706a85fe12eSEd Maste dest_demangle_data(&fptr); 707a85fe12eSEd Maste 708a85fe12eSEd Maste return (false); 709a85fe12eSEd Maste } 710a85fe12eSEd Maste 711a85fe12eSEd Maste fptr.ptr = false; 712a85fe12eSEd Maste } 713a85fe12eSEd Maste 714a85fe12eSEd Maste if (fptr.ref == true) { 715*bee2765cSEd Maste if (VEC_PUSH_STR(&fptr.vec, "&") == false) { 716a85fe12eSEd Maste dest_demangle_data(&fptr); 717a85fe12eSEd Maste 718a85fe12eSEd Maste return (false); 719a85fe12eSEd Maste } 720a85fe12eSEd Maste 721a85fe12eSEd Maste fptr.ref = false; 722a85fe12eSEd Maste } 723a85fe12eSEd Maste 724a85fe12eSEd Maste if (fptr.cnst == true) { 725*bee2765cSEd Maste if (VEC_PUSH_STR(&fptr.vec, " const") == false) { 726a85fe12eSEd Maste dest_demangle_data(&fptr); 727a85fe12eSEd Maste 728a85fe12eSEd Maste return (false); 729a85fe12eSEd Maste } 730a85fe12eSEd Maste 731a85fe12eSEd Maste fptr.cnst = false; 732a85fe12eSEd Maste } 733a85fe12eSEd Maste 734a85fe12eSEd Maste if (*fptr.p == '_') 735a85fe12eSEd Maste break; 736a85fe12eSEd Maste 737*bee2765cSEd Maste if (VEC_PUSH_STR(&fptr.vec, ", ") == false) { 738a85fe12eSEd Maste dest_demangle_data(&fptr); 739a85fe12eSEd Maste 740a85fe12eSEd Maste return (false); 741a85fe12eSEd Maste } 742a85fe12eSEd Maste 743a85fe12eSEd Maste if (++lim > CPP_DEMANGLE_GNU2_TRY) { 744a85fe12eSEd Maste 745a85fe12eSEd Maste dest_demangle_data(&fptr); 746a85fe12eSEd Maste 747a85fe12eSEd Maste return (false); 748a85fe12eSEd Maste } 749a85fe12eSEd Maste } 750a85fe12eSEd Maste 751a85fe12eSEd Maste arg_type = vector_str_get_flat(&fptr.vec, &arg_len); 752a85fe12eSEd Maste /* skip '_' */ 753a85fe12eSEd Maste d->p = fptr.p + 1; 754a85fe12eSEd Maste 755a85fe12eSEd Maste dest_demangle_data(&fptr); 756a85fe12eSEd Maste 757a85fe12eSEd Maste if (init_demangle_data(&fptr) == false) { 758a85fe12eSEd Maste free(arg_type); 759a85fe12eSEd Maste 760a85fe12eSEd Maste return (false); 761a85fe12eSEd Maste } 762a85fe12eSEd Maste 763a85fe12eSEd Maste fptr.p = d->p; 764a85fe12eSEd Maste lim = 0; 765a85fe12eSEd Maste 766a85fe12eSEd Maste if (read_type(&fptr) == false) { 767a85fe12eSEd Maste free(arg_type); 768a85fe12eSEd Maste dest_demangle_data(&fptr); 769a85fe12eSEd Maste 770a85fe12eSEd Maste return (false); 771a85fe12eSEd Maste } 772a85fe12eSEd Maste 773a85fe12eSEd Maste rtn_type = vector_str_get_flat(&fptr.vec, &rtn_len); 774a85fe12eSEd Maste d->p = fptr.p; 775a85fe12eSEd Maste 776a85fe12eSEd Maste 777a85fe12eSEd Maste dest_demangle_data(&fptr); 778a85fe12eSEd Maste 779a85fe12eSEd Maste if (vector_str_push(&d->vec, rtn_type, rtn_len) == false) { 780a85fe12eSEd Maste free(rtn_type); 781a85fe12eSEd Maste free(arg_type); 782a85fe12eSEd Maste 783a85fe12eSEd Maste return (false); 784a85fe12eSEd Maste } 785a85fe12eSEd Maste 786a85fe12eSEd Maste free(rtn_type); 787a85fe12eSEd Maste 788*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, " (*)(") == false) { 789a85fe12eSEd Maste free(arg_type); 790a85fe12eSEd Maste 791a85fe12eSEd Maste return (false); 792a85fe12eSEd Maste } 793a85fe12eSEd Maste 794a85fe12eSEd Maste if (vector_str_push(&d->vec, arg_type, arg_len) == false) { 795a85fe12eSEd Maste free(arg_type); 796a85fe12eSEd Maste 797a85fe12eSEd Maste return (false); 798a85fe12eSEd Maste } 799a85fe12eSEd Maste 800a85fe12eSEd Maste free(arg_type); 801a85fe12eSEd Maste 802*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, ")")); 803a85fe12eSEd Maste } 804a85fe12eSEd Maste 805a85fe12eSEd Maste static bool 806a85fe12eSEd Maste read_memptr(struct demangle_data *d) 807a85fe12eSEd Maste { 808a85fe12eSEd Maste struct demangle_data mptr; 809a85fe12eSEd Maste size_t len; 810a85fe12eSEd Maste bool rtn; 811a85fe12eSEd Maste char *mptr_str; 812a85fe12eSEd Maste 813a85fe12eSEd Maste if (d == NULL || d->p == NULL) 814a85fe12eSEd Maste return (false); 815a85fe12eSEd Maste 816a85fe12eSEd Maste if (init_demangle_data(&mptr) == false) 817a85fe12eSEd Maste return (false); 818a85fe12eSEd Maste 819a85fe12eSEd Maste rtn = false; 820a85fe12eSEd Maste mptr_str = NULL; 821a85fe12eSEd Maste 822a85fe12eSEd Maste mptr.p = d->p; 823a85fe12eSEd Maste if (*mptr.p == 'Q') { 824a85fe12eSEd Maste ++mptr.p; 825a85fe12eSEd Maste 826a85fe12eSEd Maste if (read_qual_name(&mptr) == false) 827a85fe12eSEd Maste goto clean; 828a85fe12eSEd Maste } else if (read_class(&mptr) == false) 829a85fe12eSEd Maste goto clean; 830a85fe12eSEd Maste 831a85fe12eSEd Maste d->p = mptr.p; 832a85fe12eSEd Maste 833a85fe12eSEd Maste if ((mptr_str = vector_str_get_flat(&mptr.vec, &len)) == NULL) 834a85fe12eSEd Maste goto clean; 835a85fe12eSEd Maste 836a85fe12eSEd Maste if (vector_str_push(&d->vec, mptr_str, len) == false) 837a85fe12eSEd Maste goto clean; 838a85fe12eSEd Maste 839*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "::*") == false) 840a85fe12eSEd Maste goto clean; 841a85fe12eSEd Maste 842a85fe12eSEd Maste rtn = true; 843a85fe12eSEd Maste clean: 844a85fe12eSEd Maste free(mptr_str); 845a85fe12eSEd Maste dest_demangle_data(&mptr); 846a85fe12eSEd Maste 847a85fe12eSEd Maste return (rtn); 848a85fe12eSEd Maste } 849a85fe12eSEd Maste 850a85fe12eSEd Maste static bool 851a85fe12eSEd Maste read_op(struct demangle_data *d) 852a85fe12eSEd Maste { 853a85fe12eSEd Maste 854a85fe12eSEd Maste if (d == NULL) 855a85fe12eSEd Maste return (false); 856a85fe12eSEd Maste 857a85fe12eSEd Maste assert(d->p != NULL && "d->p (org str) is NULL"); 858a85fe12eSEd Maste 859a85fe12eSEd Maste switch (SIMPLE_HASH(*(d->p), *(d->p+1))) { 860a85fe12eSEd Maste case SIMPLE_HASH('m', 'l') : 861a85fe12eSEd Maste d->p += 2; 862*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator*")); 863a85fe12eSEd Maste case SIMPLE_HASH('d', 'v') : 864a85fe12eSEd Maste d->p += 2; 865*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator/")); 866a85fe12eSEd Maste case SIMPLE_HASH('m', 'd') : 867a85fe12eSEd Maste d->p += 2; 868*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator%")); 869a85fe12eSEd Maste case SIMPLE_HASH('p', 'l') : 870a85fe12eSEd Maste d->p += 2; 871*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator+")); 872a85fe12eSEd Maste case SIMPLE_HASH('m', 'i') : 873a85fe12eSEd Maste d->p += 2; 874*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator-")); 875a85fe12eSEd Maste case SIMPLE_HASH('l', 's') : 876a85fe12eSEd Maste d->p += 2; 877*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator<<")); 878a85fe12eSEd Maste case SIMPLE_HASH('r', 's') : 879a85fe12eSEd Maste d->p += 2; 880*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator>>")); 881a85fe12eSEd Maste case SIMPLE_HASH('e', 'q') : 882a85fe12eSEd Maste d->p += 2; 883*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator==")); 884a85fe12eSEd Maste case SIMPLE_HASH('n', 'e') : 885a85fe12eSEd Maste d->p += 2; 886*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator!=")); 887a85fe12eSEd Maste case SIMPLE_HASH('l', 't') : 888a85fe12eSEd Maste d->p += 2; 889*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator<")); 890a85fe12eSEd Maste case SIMPLE_HASH('g', 't') : 891a85fe12eSEd Maste d->p += 2; 892*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator>")); 893a85fe12eSEd Maste case SIMPLE_HASH('l', 'e') : 894a85fe12eSEd Maste d->p += 2; 895*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator<=")); 896a85fe12eSEd Maste case SIMPLE_HASH('g', 'e') : 897a85fe12eSEd Maste d->p += 2; 898*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator>=")); 899a85fe12eSEd Maste case SIMPLE_HASH('a', 'd') : 900a85fe12eSEd Maste d->p += 2; 901a85fe12eSEd Maste if (*d->p == 'v') { 902a85fe12eSEd Maste ++d->p; 903*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator/=")); 904a85fe12eSEd Maste } else 905*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator&")); 906a85fe12eSEd Maste case SIMPLE_HASH('o', 'r') : 907a85fe12eSEd Maste d->p += 2; 908*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator|")); 909a85fe12eSEd Maste case SIMPLE_HASH('e', 'r') : 910a85fe12eSEd Maste d->p += 2; 911*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator^")); 912a85fe12eSEd Maste case SIMPLE_HASH('a', 'a') : 913a85fe12eSEd Maste d->p += 2; 914a85fe12eSEd Maste if (*d->p == 'd') { 915a85fe12eSEd Maste ++d->p; 916*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator&=")); 917a85fe12eSEd Maste } else 918*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator&&")); 919a85fe12eSEd Maste case SIMPLE_HASH('o', 'o') : 920a85fe12eSEd Maste d->p += 2; 921*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator||")); 922a85fe12eSEd Maste case SIMPLE_HASH('n', 't') : 923a85fe12eSEd Maste d->p += 2; 924*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator!")); 925a85fe12eSEd Maste case SIMPLE_HASH('c', 'o') : 926a85fe12eSEd Maste d->p += 2; 927*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator~")); 928a85fe12eSEd Maste case SIMPLE_HASH('p', 'p') : 929a85fe12eSEd Maste d->p += 2; 930*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator++")); 931a85fe12eSEd Maste case SIMPLE_HASH('m', 'm') : 932a85fe12eSEd Maste d->p += 2; 933*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator--")); 934a85fe12eSEd Maste case SIMPLE_HASH('a', 's') : 935a85fe12eSEd Maste d->p += 2; 936*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator=")); 937a85fe12eSEd Maste case SIMPLE_HASH('r', 'f') : 938a85fe12eSEd Maste d->p += 2; 939*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator->")); 940a85fe12eSEd Maste case SIMPLE_HASH('a', 'p') : 941a85fe12eSEd Maste /* apl */ 942a85fe12eSEd Maste if (*(d->p + 2) != 'l') 943a85fe12eSEd Maste return (false); 944a85fe12eSEd Maste 945a85fe12eSEd Maste d->p += 3; 946*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator+=")); 947a85fe12eSEd Maste case SIMPLE_HASH('a', 'm') : 948a85fe12eSEd Maste d->p += 2; 949a85fe12eSEd Maste if (*d->p == 'i') { 950a85fe12eSEd Maste ++d->p; 951*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator-=")); 952a85fe12eSEd Maste } else if (*d->p == 'u') { 953a85fe12eSEd Maste ++d->p; 954*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator*=")); 955a85fe12eSEd Maste } else if (*d->p == 'd') { 956a85fe12eSEd Maste ++d->p; 957*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator%=")); 958a85fe12eSEd Maste } 959a85fe12eSEd Maste 960a85fe12eSEd Maste return (false); 961a85fe12eSEd Maste case SIMPLE_HASH('a', 'l') : 962a85fe12eSEd Maste /* als */ 963a85fe12eSEd Maste if (*(d->p + 2) != 's') 964a85fe12eSEd Maste return (false); 965a85fe12eSEd Maste 966a85fe12eSEd Maste d->p += 3; 967*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator<<=")); 968a85fe12eSEd Maste case SIMPLE_HASH('a', 'r') : 969a85fe12eSEd Maste /* ars */ 970a85fe12eSEd Maste if (*(d->p + 2) != 's') 971a85fe12eSEd Maste return (false); 972a85fe12eSEd Maste 973a85fe12eSEd Maste d->p += 3; 974*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator>>=")); 975a85fe12eSEd Maste case SIMPLE_HASH('a', 'o') : 976a85fe12eSEd Maste /* aor */ 977a85fe12eSEd Maste if (*(d->p + 2) != 'r') 978a85fe12eSEd Maste return (false); 979a85fe12eSEd Maste 980a85fe12eSEd Maste d->p += 3; 981*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator|=")); 982a85fe12eSEd Maste case SIMPLE_HASH('a', 'e') : 983a85fe12eSEd Maste /* aer */ 984a85fe12eSEd Maste if (*(d->p + 2) != 'r') 985a85fe12eSEd Maste return (false); 986a85fe12eSEd Maste 987a85fe12eSEd Maste d->p += 3; 988*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator^=")); 989a85fe12eSEd Maste case SIMPLE_HASH('c', 'm') : 990a85fe12eSEd Maste d->p += 2; 991*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator,")); 992a85fe12eSEd Maste case SIMPLE_HASH('r', 'm') : 993a85fe12eSEd Maste d->p += 2; 994*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator->*")); 995a85fe12eSEd Maste case SIMPLE_HASH('c', 'l') : 996a85fe12eSEd Maste d->p += 2; 997*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "()")); 998a85fe12eSEd Maste case SIMPLE_HASH('v', 'c') : 999a85fe12eSEd Maste d->p += 2; 1000*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "[]")); 1001a85fe12eSEd Maste case SIMPLE_HASH('n', 'w') : 1002a85fe12eSEd Maste d->p += 2; 1003*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator new()")); 1004a85fe12eSEd Maste case SIMPLE_HASH('d', 'l') : 1005a85fe12eSEd Maste d->p += 2; 1006*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "operator delete()")); 1007a85fe12eSEd Maste case SIMPLE_HASH('o', 'p') : 1008a85fe12eSEd Maste /* __op<TO_TYPE>__<FROM_TYPE> */ 1009a85fe12eSEd Maste d->p += 2; 1010a85fe12eSEd Maste 1011a85fe12eSEd Maste d->type = ENCODE_OP_USER; 1012a85fe12eSEd Maste 1013a85fe12eSEd Maste return (read_op_user(d)); 1014a85fe12eSEd Maste case SIMPLE_HASH('t', 'f') : 1015a85fe12eSEd Maste d->p += 2; 1016a85fe12eSEd Maste d->type = ENCODE_OP_TF; 1017a85fe12eSEd Maste 1018a85fe12eSEd Maste if (read_type(d) == false) 1019a85fe12eSEd Maste return (false); 1020a85fe12eSEd Maste 1021*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, " type_info function")); 1022a85fe12eSEd Maste case SIMPLE_HASH('t', 'i') : 1023a85fe12eSEd Maste d->p += 2; 1024a85fe12eSEd Maste d->type = ENCODE_OP_TI; 1025a85fe12eSEd Maste 1026a85fe12eSEd Maste if (read_type(d) == false) 1027a85fe12eSEd Maste return (false); 1028a85fe12eSEd Maste 1029*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, " type_info node")); 1030a85fe12eSEd Maste default : 1031a85fe12eSEd Maste return (false); 1032a85fe12eSEd Maste }; 1033a85fe12eSEd Maste } 1034a85fe12eSEd Maste 1035a85fe12eSEd Maste static bool 1036a85fe12eSEd Maste read_op_user(struct demangle_data *d) 1037a85fe12eSEd Maste { 1038a85fe12eSEd Maste struct demangle_data from, to; 1039a85fe12eSEd Maste size_t from_len, to_len; 1040a85fe12eSEd Maste bool rtn; 1041a85fe12eSEd Maste char *from_str, *to_str; 1042a85fe12eSEd Maste 1043a85fe12eSEd Maste if (d == NULL) 1044a85fe12eSEd Maste return (false); 1045a85fe12eSEd Maste 1046a85fe12eSEd Maste if (init_demangle_data(&from) == false) 1047a85fe12eSEd Maste return (false); 1048a85fe12eSEd Maste 1049a85fe12eSEd Maste rtn = false; 1050a85fe12eSEd Maste from_str = NULL; 1051a85fe12eSEd Maste to_str = NULL; 1052a85fe12eSEd Maste if (init_demangle_data(&to) == false) 1053a85fe12eSEd Maste goto clean; 1054a85fe12eSEd Maste 1055a85fe12eSEd Maste to.p = d->p; 1056a85fe12eSEd Maste if (*to.p == 'Q') { 1057a85fe12eSEd Maste ++to.p; 1058a85fe12eSEd Maste 1059a85fe12eSEd Maste if (read_qual_name(&to) == false) 1060a85fe12eSEd Maste goto clean; 1061a85fe12eSEd Maste 1062a85fe12eSEd Maste /* pop last '::' */ 1063a85fe12eSEd Maste if (vector_str_pop(&to.vec) == false) 1064a85fe12eSEd Maste goto clean; 1065a85fe12eSEd Maste } else { 1066a85fe12eSEd Maste if (read_class(&to) == false) 1067a85fe12eSEd Maste goto clean; 1068a85fe12eSEd Maste 1069a85fe12eSEd Maste /* skip '__' */ 1070a85fe12eSEd Maste to.p += 2; 1071a85fe12eSEd Maste } 1072a85fe12eSEd Maste 1073a85fe12eSEd Maste if ((to_str = vector_str_get_flat(&to.vec, &to_len)) == NULL) 1074a85fe12eSEd Maste goto clean; 1075a85fe12eSEd Maste 1076a85fe12eSEd Maste from.p = to.p; 1077a85fe12eSEd Maste if (*from.p == 'Q') { 1078a85fe12eSEd Maste ++from.p; 1079a85fe12eSEd Maste 1080a85fe12eSEd Maste if (read_qual_name(&from) == false) 1081a85fe12eSEd Maste goto clean; 1082a85fe12eSEd Maste 1083a85fe12eSEd Maste /* pop last '::' */ 1084a85fe12eSEd Maste if (vector_str_pop(&from.vec) == false) 1085a85fe12eSEd Maste goto clean; 1086a85fe12eSEd Maste } else if (read_class(&from) == false) 1087a85fe12eSEd Maste goto clean; 1088a85fe12eSEd Maste 1089a85fe12eSEd Maste if ((from_str = vector_str_get_flat(&from.vec, &from_len)) == NULL) 1090a85fe12eSEd Maste goto clean; 1091a85fe12eSEd Maste 1092a85fe12eSEd Maste if (vector_str_push(&d->vec, from_str, from_len) == false) 1093a85fe12eSEd Maste goto clean; 1094a85fe12eSEd Maste 1095*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "::operator ") == false) 1096a85fe12eSEd Maste goto clean; 1097a85fe12eSEd Maste 1098a85fe12eSEd Maste if (vector_str_push(&d->vec, to_str, to_len) == false) 1099a85fe12eSEd Maste goto clean; 1100a85fe12eSEd Maste 1101*bee2765cSEd Maste rtn = VEC_PUSH_STR(&d->vec, "()"); 1102a85fe12eSEd Maste clean: 1103a85fe12eSEd Maste free(to_str); 1104a85fe12eSEd Maste free(from_str); 1105a85fe12eSEd Maste dest_demangle_data(&to); 1106a85fe12eSEd Maste dest_demangle_data(&from); 1107a85fe12eSEd Maste 1108a85fe12eSEd Maste return (rtn); 1109a85fe12eSEd Maste } 1110a85fe12eSEd Maste 1111a85fe12eSEd Maste /* single digit + class names */ 1112a85fe12eSEd Maste static bool 1113a85fe12eSEd Maste read_qual_name(struct demangle_data *d) 1114a85fe12eSEd Maste { 1115a85fe12eSEd Maste int i; 1116a85fe12eSEd Maste char num; 1117a85fe12eSEd Maste 1118a85fe12eSEd Maste if (d == NULL) 1119a85fe12eSEd Maste return (false); 1120a85fe12eSEd Maste 1121a85fe12eSEd Maste assert(d->p != NULL && "d->p (org str) is NULL"); 1122a85fe12eSEd Maste assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range"); 1123a85fe12eSEd Maste 1124a85fe12eSEd Maste num = *d->p - 48; 1125a85fe12eSEd Maste 1126a85fe12eSEd Maste assert(num > 0); 1127a85fe12eSEd Maste 1128a85fe12eSEd Maste ++d->p; 1129a85fe12eSEd Maste for (i = 0; i < num ; ++i) { 1130a85fe12eSEd Maste if (read_class(d) == false) 1131a85fe12eSEd Maste return (false); 1132a85fe12eSEd Maste 1133*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "::") == false) 1134a85fe12eSEd Maste return (false); 1135a85fe12eSEd Maste } 1136a85fe12eSEd Maste 1137a85fe12eSEd Maste if (*d->p != '\0') 1138a85fe12eSEd Maste d->p = d->p + 2; 1139a85fe12eSEd Maste 1140a85fe12eSEd Maste return (true); 1141a85fe12eSEd Maste } 1142a85fe12eSEd Maste 1143a85fe12eSEd Maste /* Return -1 at fail, 0 at success, and 1 at end */ 1144a85fe12eSEd Maste static int 1145a85fe12eSEd Maste read_subst(struct demangle_data *d) 1146a85fe12eSEd Maste { 1147a85fe12eSEd Maste size_t idx; 1148a85fe12eSEd Maste char *str; 1149a85fe12eSEd Maste 1150a85fe12eSEd Maste if (d == NULL) 1151a85fe12eSEd Maste return (-1); 1152a85fe12eSEd Maste 1153a85fe12eSEd Maste idx = strtol(d->p + 1, &str, 10); 1154a85fe12eSEd Maste if (idx == 0 && (errno == EINVAL || errno == ERANGE)) 1155a85fe12eSEd Maste return (-1); 1156a85fe12eSEd Maste 1157a85fe12eSEd Maste assert(idx > 0); 1158a85fe12eSEd Maste assert(str != NULL); 1159a85fe12eSEd Maste 1160a85fe12eSEd Maste d->p = str; 1161a85fe12eSEd Maste 1162*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false) 1163a85fe12eSEd Maste return (-1); 1164a85fe12eSEd Maste 1165*bee2765cSEd Maste if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false) 1166a85fe12eSEd Maste return (-1); 1167a85fe12eSEd Maste 1168a85fe12eSEd Maste if (*d->p == '\0') 1169a85fe12eSEd Maste return (1); 1170a85fe12eSEd Maste 1171a85fe12eSEd Maste return (0); 1172a85fe12eSEd Maste } 1173a85fe12eSEd Maste 1174a85fe12eSEd Maste static int 1175a85fe12eSEd Maste read_subst_iter(struct demangle_data *d) 1176a85fe12eSEd Maste { 1177a85fe12eSEd Maste int i; 1178a85fe12eSEd Maste size_t idx; 1179a85fe12eSEd Maste char repeat; 1180a85fe12eSEd Maste char *str; 1181a85fe12eSEd Maste 1182a85fe12eSEd Maste if (d == NULL) 1183a85fe12eSEd Maste return (-1); 1184a85fe12eSEd Maste 1185a85fe12eSEd Maste ++d->p; 1186a85fe12eSEd Maste assert(*d->p > 48 && *d->p < 58 && "*d->p not in ASCII numeric range"); 1187a85fe12eSEd Maste 1188a85fe12eSEd Maste repeat = *d->p - 48; 1189a85fe12eSEd Maste 1190a85fe12eSEd Maste assert(repeat > 1); 1191a85fe12eSEd Maste 1192a85fe12eSEd Maste ++d->p; 1193a85fe12eSEd Maste 1194a85fe12eSEd Maste idx = strtol(d->p, &str, 10); 1195a85fe12eSEd Maste if (idx == 0 && (errno == EINVAL || errno == ERANGE)) 1196a85fe12eSEd Maste return (-1); 1197a85fe12eSEd Maste 1198a85fe12eSEd Maste assert(idx > 0); 1199a85fe12eSEd Maste assert(str != NULL); 1200a85fe12eSEd Maste 1201a85fe12eSEd Maste d->p = str; 1202a85fe12eSEd Maste 1203a85fe12eSEd Maste for (i = 0; i < repeat ; ++i) { 1204*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, d->arg.container[idx - 1]) == false) 1205a85fe12eSEd Maste return (-1); 1206a85fe12eSEd Maste 1207*bee2765cSEd Maste if (VEC_PUSH_STR(&d->arg, d->arg.container[idx - 1]) == false) 1208a85fe12eSEd Maste return (-1); 1209a85fe12eSEd Maste 1210a85fe12eSEd Maste if (i != repeat - 1 && 1211*bee2765cSEd Maste VEC_PUSH_STR(&d->vec, ", ") == false) 1212a85fe12eSEd Maste return (-1); 1213a85fe12eSEd Maste } 1214a85fe12eSEd Maste 1215a85fe12eSEd Maste if (*d->p == '\0') 1216a85fe12eSEd Maste return (1); 1217a85fe12eSEd Maste 1218a85fe12eSEd Maste return (0); 1219a85fe12eSEd Maste } 1220a85fe12eSEd Maste 1221a85fe12eSEd Maste static bool 1222a85fe12eSEd Maste read_type(struct demangle_data *d) 1223a85fe12eSEd Maste { 1224a85fe12eSEd Maste 1225a85fe12eSEd Maste if (d == NULL) 1226a85fe12eSEd Maste return (false); 1227a85fe12eSEd Maste 1228a85fe12eSEd Maste assert(d->p != NULL && "d->p (org str) is NULL"); 1229a85fe12eSEd Maste 1230a85fe12eSEd Maste while (*d->p == 'U' || *d->p == 'C' || *d->p == 'V' || *d->p == 'S' || 1231a85fe12eSEd Maste *d->p == 'P' || *d->p == 'R' || *d->p == 'A' || *d->p == 'F' || 1232a85fe12eSEd Maste *d->p == 'M') { 1233a85fe12eSEd Maste switch (*d->p) { 1234a85fe12eSEd Maste case 'U' : 1235a85fe12eSEd Maste ++d->p; 1236a85fe12eSEd Maste 1237*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "unsigned ") == false) 1238a85fe12eSEd Maste return (false); 1239a85fe12eSEd Maste 1240a85fe12eSEd Maste break; 1241a85fe12eSEd Maste case 'C' : 1242a85fe12eSEd Maste ++d->p; 1243a85fe12eSEd Maste 1244a85fe12eSEd Maste if (*d->p == 'P') 1245a85fe12eSEd Maste d->cnst = true; 1246a85fe12eSEd Maste else { 1247*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "const ") == 1248a85fe12eSEd Maste false) 1249a85fe12eSEd Maste return (false); 1250a85fe12eSEd Maste } 1251a85fe12eSEd Maste 1252a85fe12eSEd Maste break; 1253a85fe12eSEd Maste case 'V' : 1254a85fe12eSEd Maste ++d->p; 1255a85fe12eSEd Maste 1256*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "volatile ") == false) 1257a85fe12eSEd Maste return (false); 1258a85fe12eSEd Maste 1259a85fe12eSEd Maste break; 1260a85fe12eSEd Maste case 'S' : 1261a85fe12eSEd Maste ++d->p; 1262a85fe12eSEd Maste 1263*bee2765cSEd Maste if (VEC_PUSH_STR(&d->vec, "signed ") == false) 1264a85fe12eSEd Maste return (false); 1265a85fe12eSEd Maste 1266a85fe12eSEd Maste break; 1267a85fe12eSEd Maste case 'P' : 1268a85fe12eSEd Maste ++d->p; 1269a85fe12eSEd Maste 1270a85fe12eSEd Maste if (*d->p == 'F') 1271a85fe12eSEd Maste return (read_func_ptr(d)); 1272a85fe12eSEd Maste else 1273a85fe12eSEd Maste d->ptr = true; 1274a85fe12eSEd Maste 1275a85fe12eSEd Maste break; 1276a85fe12eSEd Maste case 'R' : 1277a85fe12eSEd Maste ++d->p; 1278a85fe12eSEd Maste 1279a85fe12eSEd Maste d->ref = true; 1280a85fe12eSEd Maste 1281a85fe12eSEd Maste break; 1282a85fe12eSEd Maste case 'F' : 1283a85fe12eSEd Maste break; 1284a85fe12eSEd Maste case 'A' : 1285a85fe12eSEd Maste ++d->p; 1286a85fe12eSEd Maste 1287a85fe12eSEd Maste if (read_array(d) == false) 1288a85fe12eSEd Maste return (false); 1289a85fe12eSEd Maste 1290a85fe12eSEd Maste break; 1291a85fe12eSEd Maste case 'M' : 1292a85fe12eSEd Maste ++d->p; 1293a85fe12eSEd Maste 1294a85fe12eSEd Maste if (read_memptr(d) == false) 1295a85fe12eSEd Maste return (false); 1296a85fe12eSEd Maste 1297a85fe12eSEd Maste break; 1298a85fe12eSEd Maste default : 1299a85fe12eSEd Maste break; 1300b6b6f9ccSEd Maste } 1301b6b6f9ccSEd Maste } 1302a85fe12eSEd Maste 1303a85fe12eSEd Maste if (ELFTC_ISDIGIT(*d->p)) 1304a85fe12eSEd Maste return (read_class(d)); 1305a85fe12eSEd Maste 1306a85fe12eSEd Maste switch (*d->p) { 1307a85fe12eSEd Maste case 'Q' : 1308a85fe12eSEd Maste ++d->p; 1309a85fe12eSEd Maste 1310a85fe12eSEd Maste return (read_qual_name(d)); 1311a85fe12eSEd Maste case 'v' : 1312a85fe12eSEd Maste ++d->p; 1313a85fe12eSEd Maste 1314*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "void")); 1315a85fe12eSEd Maste case 'b': 1316a85fe12eSEd Maste ++d->p; 1317a85fe12eSEd Maste 1318*bee2765cSEd Maste return(VEC_PUSH_STR(&d->vec, "bool")); 1319a85fe12eSEd Maste case 'c' : 1320a85fe12eSEd Maste ++d->p; 1321a85fe12eSEd Maste 1322*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "char")); 1323a85fe12eSEd Maste case 's' : 1324a85fe12eSEd Maste ++d->p; 1325a85fe12eSEd Maste 1326*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "short")); 1327a85fe12eSEd Maste case 'i' : 1328a85fe12eSEd Maste ++d->p; 1329a85fe12eSEd Maste 1330*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "int")); 1331a85fe12eSEd Maste case 'l' : 1332a85fe12eSEd Maste ++d->p; 1333a85fe12eSEd Maste 1334*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "long")); 1335a85fe12eSEd Maste case 'f' : 1336a85fe12eSEd Maste ++d->p; 1337a85fe12eSEd Maste 1338*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "float")); 1339a85fe12eSEd Maste case 'd': 1340a85fe12eSEd Maste ++d->p; 1341a85fe12eSEd Maste 1342*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "double")); 1343a85fe12eSEd Maste case 'r': 1344a85fe12eSEd Maste ++d->p; 1345a85fe12eSEd Maste 1346*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "long double")); 1347a85fe12eSEd Maste case 'e': 1348a85fe12eSEd Maste ++d->p; 1349a85fe12eSEd Maste 1350*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "...")); 1351a85fe12eSEd Maste case 'w': 1352a85fe12eSEd Maste ++d->p; 1353a85fe12eSEd Maste 1354*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "wchar_t")); 1355a85fe12eSEd Maste case 'x': 1356a85fe12eSEd Maste ++d->p; 1357a85fe12eSEd Maste 1358*bee2765cSEd Maste return (VEC_PUSH_STR(&d->vec, "long long")); 1359a85fe12eSEd Maste default: 1360a85fe12eSEd Maste return (false); 1361a85fe12eSEd Maste }; 1362a85fe12eSEd Maste 1363a85fe12eSEd Maste /* NOTREACHED */ 1364a85fe12eSEd Maste return (false); 1365a85fe12eSEd Maste } 1366