1227825Stheraven/*- 2227825Stheraven * Copyright (c) 2007, 2008 Hyogeol Lee <hyogeollee@gmail.com> 3227825Stheraven * All rights reserved. 4227825Stheraven * 5227825Stheraven * Redistribution and use in source and binary forms, with or without 6227825Stheraven * modification, are permitted provided that the following conditions 7227825Stheraven * are met: 8227825Stheraven * 1. Redistributions of source code must retain the above copyright 9227825Stheraven * notice, this list of conditions and the following disclaimer 10227825Stheraven * in this position and unchanged. 11227825Stheraven * 2. Redistributions in binary form must reproduce the above copyright 12227825Stheraven * notice, this list of conditions and the following disclaimer in the 13227825Stheraven * documentation and/or other materials provided with the distribution. 14227825Stheraven * 15227825Stheraven * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16227825Stheraven * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17227825Stheraven * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18227825Stheraven * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19227825Stheraven * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20227825Stheraven * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21227825Stheraven * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22227825Stheraven * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23227825Stheraven * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24227825Stheraven * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25227825Stheraven */ 26227825Stheraven#include <sys/types.h> 27227825Stheraven#include <assert.h> 28227825Stheraven#include <ctype.h> 29227825Stheraven#include <errno.h> 30227825Stheraven#include <limits.h> 31227825Stheraven#include <stdbool.h> 32227825Stheraven#include <stdio.h> 33227825Stheraven#include <stdlib.h> 34227825Stheraven#include <string.h> 35227825Stheraven 36227825Stheraven/** 37227825Stheraven * @file cpp_demangle.c 38227825Stheraven * @brief Decode IA-64 C++ ABI style implementation. 39227825Stheraven * 40227825Stheraven * IA-64 standard ABI(Itanium C++ ABI) references. 41227825Stheraven * 42227825Stheraven * http://www.codesourcery.com/cxx-abi/abi.html#mangling \n 43227825Stheraven * http://www.codesourcery.com/cxx-abi/abi-mangling.html 44227825Stheraven */ 45227825Stheraven 46227825Stheraven/** @brief Dynamic vector data for string. */ 47227825Stheravenstruct vector_str { 48227825Stheraven /** Current size */ 49227825Stheraven size_t size; 50227825Stheraven /** Total capacity */ 51227825Stheraven size_t capacity; 52227825Stheraven /** String array */ 53227825Stheraven char **container; 54227825Stheraven}; 55227825Stheraven 56227825Stheraven#define BUFFER_GROWFACTOR 1.618 57227825Stheraven#define VECTOR_DEF_CAPACITY 8 58227825Stheraven#define ELFTC_ISDIGIT(C) (isdigit((C) & 0xFF)) 59227825Stheraven 60227825Stheravenenum type_qualifier { 61227825Stheraven TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT, 62227825Stheraven TYPE_CST 63227825Stheraven}; 64227825Stheraven 65227825Stheravenstruct vector_type_qualifier { 66227825Stheraven size_t size, capacity; 67227825Stheraven enum type_qualifier *q_container; 68227825Stheraven struct vector_str ext_name; 69227825Stheraven}; 70227825Stheraven 71227825Stheravenenum read_cmd { 72227825Stheraven READ_FAIL, READ_NEST, READ_TMPL, READ_EXPR, READ_EXPL, READ_LOCAL, 73227825Stheraven READ_TYPE, READ_FUNC, READ_PTRMEM 74227825Stheraven}; 75227825Stheraven 76227825Stheravenstruct vector_read_cmd { 77227825Stheraven size_t size, capacity; 78227825Stheraven enum read_cmd *r_container; 79227825Stheraven}; 80227825Stheraven 81227825Stheravenstruct cpp_demangle_data { 82227825Stheraven struct vector_str output; /* output string vector */ 83227825Stheraven struct vector_str output_tmp; 84227825Stheraven struct vector_str subst; /* substitution string vector */ 85227825Stheraven struct vector_str tmpl; 86227825Stheraven struct vector_str class_type; 87227825Stheraven struct vector_read_cmd cmd; 88227825Stheraven bool paren; /* parenthesis opened */ 89227825Stheraven bool pfirst; /* first element of parameter */ 90227825Stheraven bool mem_rst; /* restrict member function */ 91227825Stheraven bool mem_vat; /* volatile member function */ 92227825Stheraven bool mem_cst; /* const member function */ 93227825Stheraven int func_type; 94227825Stheraven const char *cur; /* current mangled name ptr */ 95227825Stheraven const char *last_sname; /* last source name */ 96227825Stheraven int push_head; 97227825Stheraven}; 98227825Stheraven 99227825Stheraven#define CPP_DEMANGLE_TRY_LIMIT 128 100227825Stheraven#define FLOAT_SPRINTF_TRY_LIMIT 5 101227825Stheraven#define FLOAT_QUADRUPLE_BYTES 16 102227825Stheraven#define FLOAT_EXTENED_BYTES 10 103227825Stheraven 104227825Stheraven#define SIMPLE_HASH(x,y) (64 * x + y) 105227825Stheraven 106227825Stheravenstatic size_t get_strlen_sum(const struct vector_str *v); 107227825Stheravenstatic bool vector_str_grow(struct vector_str *v); 108227825Stheraven 109227825Stheravenstatic size_t 110227825Stheravenget_strlen_sum(const struct vector_str *v) 111227825Stheraven{ 112227825Stheraven size_t i, len = 0; 113227825Stheraven 114227825Stheraven if (v == NULL) 115227825Stheraven return (0); 116227825Stheraven 117227825Stheraven assert(v->size > 0); 118227825Stheraven 119227825Stheraven for (i = 0; i < v->size; ++i) 120227825Stheraven len += strlen(v->container[i]); 121227825Stheraven 122227825Stheraven return (len); 123227825Stheraven} 124227825Stheraven 125227825Stheraven/** 126227825Stheraven * @brief Deallocate resource in vector_str. 127227825Stheraven */ 128227825Stheravenstatic void 129227825Stheravenvector_str_dest(struct vector_str *v) 130227825Stheraven{ 131227825Stheraven size_t i; 132227825Stheraven 133227825Stheraven if (v == NULL) 134227825Stheraven return; 135227825Stheraven 136227825Stheraven for (i = 0; i < v->size; ++i) 137227825Stheraven free(v->container[i]); 138227825Stheraven 139227825Stheraven free(v->container); 140227825Stheraven} 141227825Stheraven 142227825Stheraven/** 143227825Stheraven * @brief Find string in vector_str. 144227825Stheraven * @param v Destination vector. 145227825Stheraven * @param o String to find. 146227825Stheraven * @param l Length of the string. 147227825Stheraven * @return -1 at failed, 0 at not found, 1 at found. 148227825Stheraven */ 149227825Stheravenstatic int 150227825Stheravenvector_str_find(const struct vector_str *v, const char *o, size_t l) 151227825Stheraven{ 152227825Stheraven size_t i; 153227825Stheraven 154227825Stheraven if (v == NULL || o == NULL) 155227825Stheraven return (-1); 156227825Stheraven 157227825Stheraven for (i = 0; i < v->size; ++i) 158227825Stheraven if (strncmp(v->container[i], o, l) == 0) 159227825Stheraven return (1); 160227825Stheraven 161227825Stheraven return (0); 162227825Stheraven} 163227825Stheraven 164227825Stheraven/** 165227825Stheraven * @brief Get new allocated flat string from vector. 166227825Stheraven * 167227825Stheraven * If l is not NULL, return length of the string. 168227825Stheraven * @param v Destination vector. 169227825Stheraven * @param l Length of the string. 170227825Stheraven * @return NULL at failed or NUL terminated new allocated string. 171227825Stheraven */ 172227825Stheravenstatic char * 173227825Stheravenvector_str_get_flat(const struct vector_str *v, size_t *l) 174227825Stheraven{ 175227825Stheraven ssize_t elem_pos, elem_size, rtn_size; 176227825Stheraven size_t i; 177227825Stheraven char *rtn; 178227825Stheraven 179227825Stheraven if (v == NULL || v->size == 0) 180227825Stheraven return (NULL); 181227825Stheraven 182227825Stheraven if ((rtn_size = get_strlen_sum(v)) == 0) 183227825Stheraven return (NULL); 184227825Stheraven 185227825Stheraven if ((rtn = malloc(sizeof(char) * (rtn_size + 1))) == NULL) 186227825Stheraven return (NULL); 187227825Stheraven 188227825Stheraven elem_pos = 0; 189227825Stheraven for (i = 0; i < v->size; ++i) { 190227825Stheraven elem_size = strlen(v->container[i]); 191227825Stheraven 192227825Stheraven memcpy(rtn + elem_pos, v->container[i], elem_size); 193227825Stheraven 194227825Stheraven elem_pos += elem_size; 195227825Stheraven } 196227825Stheraven 197227825Stheraven rtn[rtn_size] = '\0'; 198227825Stheraven 199227825Stheraven if (l != NULL) 200227825Stheraven *l = rtn_size; 201227825Stheraven 202227825Stheraven return (rtn); 203227825Stheraven} 204227825Stheraven 205227825Stheravenstatic bool 206227825Stheravenvector_str_grow(struct vector_str *v) 207227825Stheraven{ 208227825Stheraven size_t i, tmp_cap; 209227825Stheraven char **tmp_ctn; 210227825Stheraven 211227825Stheraven if (v == NULL) 212227825Stheraven return (false); 213227825Stheraven 214227825Stheraven assert(v->capacity > 0); 215227825Stheraven 216227825Stheraven tmp_cap = v->capacity * BUFFER_GROWFACTOR; 217227825Stheraven 218227825Stheraven assert(tmp_cap > v->capacity); 219227825Stheraven 220227825Stheraven if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL) 221227825Stheraven return (false); 222227825Stheraven 223227825Stheraven for (i = 0; i < v->size; ++i) 224227825Stheraven tmp_ctn[i] = v->container[i]; 225227825Stheraven 226227825Stheraven free(v->container); 227227825Stheraven 228227825Stheraven v->container = tmp_ctn; 229227825Stheraven v->capacity = tmp_cap; 230227825Stheraven 231227825Stheraven return (true); 232227825Stheraven} 233227825Stheraven 234227825Stheraven/** 235227825Stheraven * @brief Initialize vector_str. 236227825Stheraven * @return false at failed, true at success. 237227825Stheraven */ 238227825Stheravenstatic bool 239227825Stheravenvector_str_init(struct vector_str *v) 240227825Stheraven{ 241227825Stheraven 242227825Stheraven if (v == NULL) 243227825Stheraven return (false); 244227825Stheraven 245227825Stheraven v->size = 0; 246227825Stheraven v->capacity = VECTOR_DEF_CAPACITY; 247227825Stheraven 248227825Stheraven assert(v->capacity > 0); 249227825Stheraven 250227825Stheraven if ((v->container = malloc(sizeof(char *) * v->capacity)) == NULL) 251227825Stheraven return (false); 252227825Stheraven 253227825Stheraven assert(v->container != NULL); 254227825Stheraven 255227825Stheraven return (true); 256227825Stheraven} 257227825Stheraven 258227825Stheraven/** 259227825Stheraven * @brief Remove last element in vector_str. 260227825Stheraven * @return false at failed, true at success. 261227825Stheraven */ 262227825Stheravenstatic bool 263227825Stheravenvector_str_pop(struct vector_str *v) 264227825Stheraven{ 265227825Stheraven 266227825Stheraven if (v == NULL) 267227825Stheraven return (false); 268227825Stheraven 269227825Stheraven if (v->size == 0) 270227825Stheraven return (true); 271227825Stheraven 272227825Stheraven --v->size; 273227825Stheraven 274227825Stheraven free(v->container[v->size]); 275227825Stheraven v->container[v->size] = NULL; 276227825Stheraven 277227825Stheraven return (true); 278227825Stheraven} 279227825Stheraven 280227825Stheraven/** 281227825Stheraven * @brief Push back string to vector. 282227825Stheraven * @return false at failed, true at success. 283227825Stheraven */ 284227825Stheravenstatic bool 285227825Stheravenvector_str_push(struct vector_str *v, const char *str, size_t len) 286227825Stheraven{ 287227825Stheraven 288227825Stheraven if (v == NULL || str == NULL) 289227825Stheraven return (false); 290227825Stheraven 291227825Stheraven if (v->size == v->capacity && vector_str_grow(v) == false) 292227825Stheraven return (false); 293227825Stheraven 294227825Stheraven if ((v->container[v->size] = malloc(sizeof(char) * (len + 1))) == NULL) 295227825Stheraven return (false); 296227825Stheraven 297227825Stheraven snprintf(v->container[v->size], len + 1, "%s", str); 298227825Stheraven 299227825Stheraven ++v->size; 300227825Stheraven 301227825Stheraven return (true); 302227825Stheraven} 303227825Stheraven 304227825Stheraven/** 305227825Stheraven * @brief Push front org vector to det vector. 306227825Stheraven * @return false at failed, true at success. 307227825Stheraven */ 308227825Stheravenstatic bool 309227825Stheravenvector_str_push_vector_head(struct vector_str *dst, struct vector_str *org) 310227825Stheraven{ 311227825Stheraven size_t i, j, tmp_cap; 312227825Stheraven char **tmp_ctn; 313227825Stheraven 314227825Stheraven if (dst == NULL || org == NULL) 315227825Stheraven return (false); 316227825Stheraven 317227825Stheraven tmp_cap = (dst->size + org->size) * BUFFER_GROWFACTOR; 318227825Stheraven 319227825Stheraven if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL) 320227825Stheraven return (false); 321227825Stheraven 322227825Stheraven for (i = 0; i < org->size; ++i) 323227825Stheraven if ((tmp_ctn[i] = strdup(org->container[i])) == NULL) { 324227825Stheraven for (j = 0; j < i; ++j) 325227825Stheraven free(tmp_ctn[j]); 326227825Stheraven 327227825Stheraven free(tmp_ctn); 328227825Stheraven 329227825Stheraven return (false); 330227825Stheraven } 331227825Stheraven 332227825Stheraven for (i = 0; i < dst->size; ++i) 333227825Stheraven tmp_ctn[i + org->size] = dst->container[i]; 334227825Stheraven 335227825Stheraven free(dst->container); 336227825Stheraven 337227825Stheraven dst->container = tmp_ctn; 338227825Stheraven dst->capacity = tmp_cap; 339227825Stheraven dst->size += org->size; 340227825Stheraven 341227825Stheraven return (true); 342227825Stheraven} 343227825Stheraven 344227825Stheraven/** 345227825Stheraven * @brief Get new allocated flat string from vector between begin and end. 346227825Stheraven * 347227825Stheraven * If r_len is not NULL, string length will be returned. 348227825Stheraven * @return NULL at failed or NUL terminated new allocated string. 349227825Stheraven */ 350227825Stheravenstatic char * 351227825Stheravenvector_str_substr(const struct vector_str *v, size_t begin, size_t end, 352227825Stheraven size_t *r_len) 353227825Stheraven{ 354227825Stheraven size_t cur, i, len; 355227825Stheraven char *rtn; 356227825Stheraven 357227825Stheraven if (v == NULL || begin > end) 358227825Stheraven return (NULL); 359227825Stheraven 360227825Stheraven len = 0; 361227825Stheraven for (i = begin; i < end + 1; ++i) 362227825Stheraven len += strlen(v->container[i]); 363227825Stheraven 364227825Stheraven if ((rtn = malloc(sizeof(char) * (len + 1))) == NULL) 365227825Stheraven return (NULL); 366227825Stheraven 367227825Stheraven if (r_len != NULL) 368227825Stheraven *r_len = len; 369227825Stheraven 370227825Stheraven cur = 0; 371227825Stheraven for (i = begin; i < end + 1; ++i) { 372227825Stheraven len = strlen(v->container[i]); 373227825Stheraven memcpy(rtn + cur, v->container[i], len); 374227825Stheraven cur += len; 375227825Stheraven } 376227825Stheraven rtn[cur] = '\0'; 377227825Stheraven 378227825Stheraven return (rtn); 379227825Stheraven} 380227825Stheraven 381227825Stheravenstatic void cpp_demangle_data_dest(struct cpp_demangle_data *); 382227825Stheravenstatic int cpp_demangle_data_init(struct cpp_demangle_data *, 383227825Stheraven const char *); 384227825Stheravenstatic int cpp_demangle_get_subst(struct cpp_demangle_data *, size_t); 385227825Stheravenstatic int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t); 386227825Stheravenstatic int cpp_demangle_push_fp(struct cpp_demangle_data *, 387227825Stheraven char *(*)(const char *, size_t)); 388227825Stheravenstatic int cpp_demangle_push_str(struct cpp_demangle_data *, const char *, 389227825Stheraven size_t); 390227825Stheravenstatic int cpp_demangle_push_subst(struct cpp_demangle_data *, 391227825Stheraven const char *, size_t); 392227825Stheravenstatic int cpp_demangle_push_subst_v(struct cpp_demangle_data *, 393227825Stheraven struct vector_str *); 394227825Stheravenstatic int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *, 395227825Stheraven struct vector_type_qualifier *, const char *); 396227825Stheravenstatic int cpp_demangle_read_array(struct cpp_demangle_data *); 397227825Stheravenstatic int cpp_demangle_read_encoding(struct cpp_demangle_data *); 398227825Stheravenstatic int cpp_demangle_read_expr_primary(struct cpp_demangle_data *); 399227825Stheravenstatic int cpp_demangle_read_expression(struct cpp_demangle_data *); 400227825Stheravenstatic int cpp_demangle_read_expression_binary(struct cpp_demangle_data *, 401227825Stheraven const char *, size_t); 402227825Stheravenstatic int cpp_demangle_read_expression_unary(struct cpp_demangle_data *, 403227825Stheraven const char *, size_t); 404227825Stheravenstatic int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *, 405227825Stheraven const char *, size_t, const char *, size_t); 406227825Stheravenstatic int cpp_demangle_read_function(struct cpp_demangle_data *, int *, 407227825Stheraven struct vector_type_qualifier *); 408255815Stheravenstatic int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata); 409227825Stheravenstatic int cpp_demangle_read_local_name(struct cpp_demangle_data *); 410227825Stheravenstatic int cpp_demangle_read_name(struct cpp_demangle_data *); 411227825Stheravenstatic int cpp_demangle_read_nested_name(struct cpp_demangle_data *); 412227825Stheravenstatic int cpp_demangle_read_number(struct cpp_demangle_data *, long *); 413227825Stheravenstatic int cpp_demangle_read_nv_offset(struct cpp_demangle_data *); 414227825Stheravenstatic int cpp_demangle_read_offset(struct cpp_demangle_data *); 415227825Stheravenstatic int cpp_demangle_read_offset_number(struct cpp_demangle_data *); 416227825Stheravenstatic int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *); 417227825Stheravenstatic int cpp_demangle_read_sname(struct cpp_demangle_data *); 418227825Stheravenstatic int cpp_demangle_read_subst(struct cpp_demangle_data *); 419227825Stheravenstatic int cpp_demangle_read_subst_std(struct cpp_demangle_data *); 420227825Stheravenstatic int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *, 421227825Stheraven const char *, size_t); 422227825Stheravenstatic int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *); 423227825Stheravenstatic int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *); 424227825Stheravenstatic int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *); 425227825Stheravenstatic int cpp_demangle_read_type(struct cpp_demangle_data *, int); 426227825Stheravenstatic int cpp_demangle_read_uqname(struct cpp_demangle_data *); 427227825Stheravenstatic int cpp_demangle_read_v_offset(struct cpp_demangle_data *); 428227825Stheravenstatic char *decode_fp_to_double(const char *, size_t); 429227825Stheravenstatic char *decode_fp_to_float(const char *, size_t); 430227825Stheravenstatic char *decode_fp_to_float128(const char *, size_t); 431227825Stheravenstatic char *decode_fp_to_float80(const char *, size_t); 432227825Stheravenstatic char *decode_fp_to_long_double(const char *, size_t); 433227825Stheravenstatic int hex_to_dec(char); 434227825Stheravenstatic void vector_read_cmd_dest(struct vector_read_cmd *); 435227825Stheravenstatic int vector_read_cmd_find(struct vector_read_cmd *, enum read_cmd); 436227825Stheravenstatic int vector_read_cmd_init(struct vector_read_cmd *); 437227825Stheravenstatic int vector_read_cmd_pop(struct vector_read_cmd *); 438227825Stheravenstatic int vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd); 439227825Stheravenstatic void vector_type_qualifier_dest(struct vector_type_qualifier *); 440227825Stheravenstatic int vector_type_qualifier_init(struct vector_type_qualifier *); 441227825Stheravenstatic int vector_type_qualifier_push(struct vector_type_qualifier *, 442227825Stheraven enum type_qualifier); 443227825Stheraven 444227825Stheraven/** 445227825Stheraven * @brief Decode the input string by IA-64 C++ ABI style. 446227825Stheraven * 447227825Stheraven * GNU GCC v3 use IA-64 standard ABI. 448227825Stheraven * @return New allocated demangled string or NULL if failed. 449227825Stheraven * @todo 1. Testing and more test case. 2. Code cleaning. 450227825Stheraven */ 451227825Stheravenchar * 452227825Stheraven__cxa_demangle_gnu3(const char *org) 453227825Stheraven{ 454227825Stheraven struct cpp_demangle_data ddata; 455227825Stheraven ssize_t org_len; 456227825Stheraven unsigned int limit; 457255815Stheraven char *rtn = NULL; 458227825Stheraven 459227825Stheraven if (org == NULL) 460227825Stheraven return (NULL); 461227825Stheraven 462255815Stheraven org_len = strlen(org); 463255815Stheraven if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) { 464255815Stheraven if ((rtn = malloc(org_len + 19)) == NULL) 465255815Stheraven return (NULL); 466255815Stheraven snprintf(rtn, org_len + 19, 467255815Stheraven "global constructors keyed to %s", org + 11); 468255815Stheraven return (rtn); 469255815Stheraven } 470255815Stheraven 471227825Stheraven // Try demangling as a type for short encodings 472255815Stheraven if ((org_len < 2) || (org[0] != '_' || org[1] != 'Z' )) { 473227825Stheraven if (!cpp_demangle_data_init(&ddata, org)) 474227825Stheraven return (NULL); 475227825Stheraven if (!cpp_demangle_read_type(&ddata, 0)) 476227825Stheraven goto clean; 477227825Stheraven rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); 478227825Stheraven goto clean; 479227825Stheraven } 480227825Stheraven 481227825Stheraven 482227825Stheraven if (!cpp_demangle_data_init(&ddata, org + 2)) 483227825Stheraven return (NULL); 484227825Stheraven 485227825Stheraven rtn = NULL; 486227825Stheraven 487227825Stheraven if (!cpp_demangle_read_encoding(&ddata)) 488227825Stheraven goto clean; 489227825Stheraven 490227825Stheraven limit = 0; 491227825Stheraven while (*ddata.cur != '\0') { 492227825Stheraven /* 493227825Stheraven * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4 494227825Stheraven */ 495227825Stheraven if (*ddata.cur == '@' && *(ddata.cur + 1) == '@') 496227825Stheraven break; 497227825Stheraven if (!cpp_demangle_read_type(&ddata, 1)) 498227825Stheraven goto clean; 499227825Stheraven if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 500227825Stheraven goto clean; 501227825Stheraven } 502227825Stheraven 503227825Stheraven if (ddata.output.size == 0) 504227825Stheraven goto clean; 505227825Stheraven if (ddata.paren && !vector_str_push(&ddata.output, ")", 1)) 506227825Stheraven goto clean; 507227825Stheraven if (ddata.mem_vat && !vector_str_push(&ddata.output, " volatile", 9)) 508227825Stheraven goto clean; 509227825Stheraven if (ddata.mem_cst && !vector_str_push(&ddata.output, " const", 6)) 510227825Stheraven goto clean; 511227825Stheraven if (ddata.mem_rst && !vector_str_push(&ddata.output, " restrict", 9)) 512227825Stheraven goto clean; 513227825Stheraven 514227825Stheraven rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); 515227825Stheraven 516227825Stheravenclean: 517227825Stheraven cpp_demangle_data_dest(&ddata); 518227825Stheraven 519227825Stheraven return (rtn); 520227825Stheraven} 521227825Stheraven 522227825Stheravenstatic void 523227825Stheravencpp_demangle_data_dest(struct cpp_demangle_data *d) 524227825Stheraven{ 525227825Stheraven 526227825Stheraven if (d == NULL) 527227825Stheraven return; 528227825Stheraven 529227825Stheraven vector_read_cmd_dest(&d->cmd); 530227825Stheraven vector_str_dest(&d->class_type); 531227825Stheraven vector_str_dest(&d->tmpl); 532227825Stheraven vector_str_dest(&d->subst); 533227825Stheraven vector_str_dest(&d->output_tmp); 534227825Stheraven vector_str_dest(&d->output); 535227825Stheraven} 536227825Stheraven 537227825Stheravenstatic int 538227825Stheravencpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur) 539227825Stheraven{ 540227825Stheraven 541227825Stheraven if (d == NULL || cur == NULL) 542227825Stheraven return (0); 543227825Stheraven 544227825Stheraven if (!vector_str_init(&d->output)) 545227825Stheraven return (0); 546227825Stheraven if (!vector_str_init(&d->output_tmp)) 547227825Stheraven goto clean1; 548227825Stheraven if (!vector_str_init(&d->subst)) 549227825Stheraven goto clean2; 550227825Stheraven if (!vector_str_init(&d->tmpl)) 551227825Stheraven goto clean3; 552227825Stheraven if (!vector_str_init(&d->class_type)) 553227825Stheraven goto clean4; 554227825Stheraven if (!vector_read_cmd_init(&d->cmd)) 555227825Stheraven goto clean5; 556227825Stheraven 557227825Stheraven assert(d->output.container != NULL); 558227825Stheraven assert(d->output_tmp.container != NULL); 559227825Stheraven assert(d->subst.container != NULL); 560227825Stheraven assert(d->tmpl.container != NULL); 561227825Stheraven assert(d->class_type.container != NULL); 562227825Stheraven 563227825Stheraven d->paren = false; 564227825Stheraven d->pfirst = false; 565227825Stheraven d->mem_rst = false; 566227825Stheraven d->mem_vat = false; 567227825Stheraven d->mem_cst = false; 568227825Stheraven d->func_type = 0; 569227825Stheraven d->cur = cur; 570227825Stheraven d->last_sname = NULL; 571227825Stheraven d->push_head = 0; 572227825Stheraven 573227825Stheraven return (1); 574227825Stheraven 575227825Stheravenclean5: 576227825Stheraven vector_str_dest(&d->class_type); 577227825Stheravenclean4: 578227825Stheraven vector_str_dest(&d->tmpl); 579227825Stheravenclean3: 580227825Stheraven vector_str_dest(&d->subst); 581227825Stheravenclean2: 582227825Stheraven vector_str_dest(&d->output_tmp); 583227825Stheravenclean1: 584227825Stheraven vector_str_dest(&d->output); 585227825Stheraven 586227825Stheraven return (0); 587227825Stheraven} 588227825Stheraven 589227825Stheravenstatic int 590227825Stheravencpp_demangle_push_fp(struct cpp_demangle_data *ddata, 591227825Stheraven char *(*decoder)(const char *, size_t)) 592227825Stheraven{ 593227825Stheraven size_t len; 594227825Stheraven int rtn; 595227825Stheraven const char *fp; 596227825Stheraven char *f; 597227825Stheraven 598227825Stheraven if (ddata == NULL || decoder == NULL) 599227825Stheraven return (0); 600227825Stheraven 601227825Stheraven fp = ddata->cur; 602227825Stheraven while (*ddata->cur != 'E') 603227825Stheraven ++ddata->cur; 604227825Stheraven ++ddata->cur; 605227825Stheraven 606227825Stheraven if ((f = decoder(fp, ddata->cur - fp)) == NULL) 607227825Stheraven return (0); 608227825Stheraven 609227825Stheraven rtn = 0; 610255815Stheraven if ((len = strlen(f)) > 0) 611255815Stheraven rtn = cpp_demangle_push_str(ddata, f, len); 612227825Stheraven 613227825Stheraven free(f); 614227825Stheraven 615255815Stheraven return (rtn); 616227825Stheraven} 617227825Stheraven 618227825Stheravenstatic int 619227825Stheravencpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str, 620227825Stheraven size_t len) 621227825Stheraven{ 622227825Stheraven 623227825Stheraven if (ddata == NULL || str == NULL || len == 0) 624227825Stheraven return (0); 625227825Stheraven 626227825Stheraven if (ddata->push_head > 0) 627227825Stheraven return (vector_str_push(&ddata->output_tmp, str, len)); 628227825Stheraven 629227825Stheraven return (vector_str_push(&ddata->output, str, len)); 630227825Stheraven} 631227825Stheraven 632227825Stheravenstatic int 633227825Stheravencpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str, 634227825Stheraven size_t len) 635227825Stheraven{ 636227825Stheraven 637227825Stheraven if (ddata == NULL || str == NULL || len == 0) 638227825Stheraven return (0); 639227825Stheraven 640227825Stheraven if (!vector_str_find(&ddata->subst, str, len)) 641227825Stheraven return (vector_str_push(&ddata->subst, str, len)); 642227825Stheraven 643227825Stheraven return (1); 644227825Stheraven} 645227825Stheraven 646227825Stheravenstatic int 647227825Stheravencpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v) 648227825Stheraven{ 649227825Stheraven size_t str_len; 650227825Stheraven int rtn; 651227825Stheraven char *str; 652227825Stheraven 653227825Stheraven if (ddata == NULL || v == NULL) 654227825Stheraven return (0); 655227825Stheraven 656227825Stheraven if ((str = vector_str_get_flat(v, &str_len)) == NULL) 657227825Stheraven return (0); 658227825Stheraven 659227825Stheraven rtn = cpp_demangle_push_subst(ddata, str, str_len); 660255815Stheraven 661227825Stheraven free(str); 662227825Stheraven 663227825Stheraven return (rtn); 664227825Stheraven} 665227825Stheraven 666227825Stheravenstatic int 667227825Stheravencpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, 668227825Stheraven struct vector_type_qualifier *v, const char *type_str) 669227825Stheraven{ 670227825Stheraven struct vector_str subst_v; 671227825Stheraven size_t idx, e_idx, e_len; 672227825Stheraven int rtn; 673227825Stheraven char *buf; 674227825Stheraven 675227825Stheraven if (ddata == NULL || v == NULL) 676227825Stheraven return (0); 677227825Stheraven 678227825Stheraven if ((idx = v->size) == 0) 679227825Stheraven return (1); 680227825Stheraven 681227825Stheraven rtn = 0; 682227825Stheraven if (type_str != NULL) { 683227825Stheraven if (!vector_str_init(&subst_v)) 684227825Stheraven return (0); 685227825Stheraven if (!vector_str_push(&subst_v, type_str, strlen(type_str))) 686227825Stheraven goto clean; 687227825Stheraven } 688227825Stheraven 689227825Stheraven e_idx = 0; 690227825Stheraven while (idx > 0) { 691227825Stheraven switch (v->q_container[idx - 1]) { 692227825Stheraven case TYPE_PTR: 693227825Stheraven if (!cpp_demangle_push_str(ddata, "*", 1)) 694227825Stheraven goto clean; 695227825Stheraven if (type_str != NULL) { 696227825Stheraven if (!vector_str_push(&subst_v, "*", 1)) 697227825Stheraven goto clean; 698227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 699227825Stheraven goto clean; 700227825Stheraven } 701227825Stheraven break; 702227825Stheraven 703227825Stheraven case TYPE_REF: 704227825Stheraven if (!cpp_demangle_push_str(ddata, "&", 1)) 705227825Stheraven goto clean; 706227825Stheraven if (type_str != NULL) { 707227825Stheraven if (!vector_str_push(&subst_v, "&", 1)) 708227825Stheraven goto clean; 709227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 710227825Stheraven goto clean; 711227825Stheraven } 712227825Stheraven break; 713227825Stheraven 714227825Stheraven case TYPE_CMX: 715227825Stheraven if (!cpp_demangle_push_str(ddata, " complex", 8)) 716227825Stheraven goto clean; 717227825Stheraven if (type_str != NULL) { 718227825Stheraven if (!vector_str_push(&subst_v, " complex", 8)) 719227825Stheraven goto clean; 720227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 721227825Stheraven goto clean; 722227825Stheraven } 723227825Stheraven break; 724227825Stheraven 725227825Stheraven case TYPE_IMG: 726227825Stheraven if (!cpp_demangle_push_str(ddata, " imaginary", 10)) 727227825Stheraven goto clean; 728227825Stheraven if (type_str != NULL) { 729227825Stheraven if (!vector_str_push(&subst_v, " imaginary", 10)) 730227825Stheraven goto clean; 731227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 732227825Stheraven goto clean; 733227825Stheraven } 734227825Stheraven break; 735227825Stheraven 736227825Stheraven case TYPE_EXT: 737227825Stheraven if (e_idx > v->ext_name.size - 1) 738227825Stheraven goto clean; 739227825Stheraven if ((e_len = strlen(v->ext_name.container[e_idx])) == 0) 740227825Stheraven goto clean; 741227825Stheraven if ((buf = malloc(sizeof(char) * (e_len + 1))) == NULL) 742227825Stheraven goto clean; 743227825Stheraven 744227825Stheraven memcpy(buf, " ", 1); 745227825Stheraven memcpy(buf + 1, v->ext_name.container[e_idx], e_len); 746227825Stheraven 747227825Stheraven if (!cpp_demangle_push_str(ddata, buf, e_len + 1)) { 748227825Stheraven free(buf); 749227825Stheraven goto clean; 750227825Stheraven } 751227825Stheraven 752227825Stheraven if (type_str != NULL) { 753227825Stheraven if (!vector_str_push(&subst_v, buf, 754227825Stheraven e_len + 1)) { 755227825Stheraven free(buf); 756227825Stheraven goto clean; 757227825Stheraven } 758227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &subst_v)) { 759227825Stheraven free(buf); 760227825Stheraven goto clean; 761227825Stheraven } 762227825Stheraven } 763227825Stheraven free(buf); 764227825Stheraven ++e_idx; 765227825Stheraven break; 766227825Stheraven 767227825Stheraven case TYPE_RST: 768227825Stheraven if (!cpp_demangle_push_str(ddata, " restrict", 9)) 769227825Stheraven goto clean; 770227825Stheraven if (type_str != NULL) { 771227825Stheraven if (!vector_str_push(&subst_v, " restrict", 9)) 772227825Stheraven goto clean; 773227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 774227825Stheraven goto clean; 775227825Stheraven } 776227825Stheraven break; 777227825Stheraven 778227825Stheraven case TYPE_VAT: 779227825Stheraven if (!cpp_demangle_push_str(ddata, " volatile", 9)) 780227825Stheraven goto clean; 781227825Stheraven if (type_str != NULL) { 782227825Stheraven if (!vector_str_push(&subst_v, " volatile", 9)) 783227825Stheraven goto clean; 784227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 785227825Stheraven goto clean; 786227825Stheraven } 787227825Stheraven break; 788227825Stheraven 789227825Stheraven case TYPE_CST: 790227825Stheraven if (!cpp_demangle_push_str(ddata, " const", 6)) 791227825Stheraven goto clean; 792227825Stheraven if (type_str != NULL) { 793227825Stheraven if (!vector_str_push(&subst_v, " const", 6)) 794227825Stheraven goto clean; 795227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 796227825Stheraven goto clean; 797227825Stheraven } 798227825Stheraven break; 799227825Stheraven 800227825Stheraven }; 801227825Stheraven --idx; 802227825Stheraven } 803227825Stheraven 804227825Stheraven rtn = 1; 805227825Stheravenclean: 806227825Stheraven if (type_str != NULL) 807227825Stheraven vector_str_dest(&subst_v); 808227825Stheraven 809227825Stheraven return (rtn); 810227825Stheraven} 811227825Stheraven 812227825Stheravenstatic int 813227825Stheravencpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx) 814227825Stheraven{ 815227825Stheraven size_t len; 816227825Stheraven 817227825Stheraven if (ddata == NULL || ddata->subst.size <= idx) 818227825Stheraven return (0); 819227825Stheraven if ((len = strlen(ddata->subst.container[idx])) == 0) 820227825Stheraven return (0); 821227825Stheraven if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len)) 822227825Stheraven return (0); 823227825Stheraven 824227825Stheraven /* skip '_' */ 825227825Stheraven ++ddata->cur; 826227825Stheraven 827227825Stheraven return (1); 828227825Stheraven} 829227825Stheraven 830227825Stheravenstatic int 831227825Stheravencpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx) 832227825Stheraven{ 833227825Stheraven size_t len; 834227825Stheraven 835227825Stheraven if (ddata == NULL || ddata->tmpl.size <= idx) 836227825Stheraven return (0); 837227825Stheraven if ((len = strlen(ddata->tmpl.container[idx])) == 0) 838227825Stheraven return (0); 839227825Stheraven if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len)) 840227825Stheraven return (0); 841227825Stheraven 842227825Stheraven ++ddata->cur; 843227825Stheraven 844227825Stheraven return (1); 845227825Stheraven} 846227825Stheraven 847227825Stheravenstatic int 848227825Stheravencpp_demangle_read_array(struct cpp_demangle_data *ddata) 849227825Stheraven{ 850227825Stheraven size_t i, num_len, exp_len, p_idx, idx; 851227825Stheraven const char *num; 852227825Stheraven char *exp; 853227825Stheraven 854227825Stheraven if (ddata == NULL || *(++ddata->cur) == '\0') 855227825Stheraven return (0); 856227825Stheraven 857227825Stheraven if (*ddata->cur == '_') { 858227825Stheraven if (*(++ddata->cur) == '\0') 859227825Stheraven return (0); 860227825Stheraven 861227825Stheraven if (!cpp_demangle_read_type(ddata, 0)) 862227825Stheraven return (0); 863227825Stheraven 864227825Stheraven if (!cpp_demangle_push_str(ddata, "[]", 2)) 865227825Stheraven return (0); 866227825Stheraven } else { 867227825Stheraven if (ELFTC_ISDIGIT(*ddata->cur) != 0) { 868227825Stheraven num = ddata->cur; 869227825Stheraven while (ELFTC_ISDIGIT(*ddata->cur) != 0) 870227825Stheraven ++ddata->cur; 871227825Stheraven if (*ddata->cur != '_') 872227825Stheraven return (0); 873227825Stheraven num_len = ddata->cur - num; 874227825Stheraven assert(num_len > 0); 875227825Stheraven if (*(++ddata->cur) == '\0') 876227825Stheraven return (0); 877227825Stheraven if (!cpp_demangle_read_type(ddata, 0)) 878227825Stheraven return (0); 879227825Stheraven if (!cpp_demangle_push_str(ddata, "[", 1)) 880227825Stheraven return (0); 881227825Stheraven if (!cpp_demangle_push_str(ddata, num, num_len)) 882227825Stheraven return (0); 883227825Stheraven if (!cpp_demangle_push_str(ddata, "]", 1)) 884227825Stheraven return (0); 885227825Stheraven } else { 886227825Stheraven p_idx = ddata->output.size; 887227825Stheraven if (!cpp_demangle_read_expression(ddata)) 888227825Stheraven return (0); 889227825Stheraven if ((exp = vector_str_substr(&ddata->output, p_idx, 890227825Stheraven ddata->output.size - 1, &exp_len)) == NULL) 891227825Stheraven return (0); 892227825Stheraven idx = ddata->output.size; 893227825Stheraven for (i = p_idx; i < idx; ++i) 894227825Stheraven if (!vector_str_pop(&ddata->output)) { 895227825Stheraven free(exp); 896227825Stheraven return (0); 897227825Stheraven } 898227825Stheraven if (*ddata->cur != '_') { 899227825Stheraven free(exp); 900227825Stheraven return (0); 901227825Stheraven } 902227825Stheraven ++ddata->cur; 903227825Stheraven if (*ddata->cur == '\0') { 904227825Stheraven free(exp); 905227825Stheraven return (0); 906227825Stheraven } 907227825Stheraven if (!cpp_demangle_read_type(ddata, 0)) { 908227825Stheraven free(exp); 909227825Stheraven return (0); 910227825Stheraven } 911227825Stheraven if (!cpp_demangle_push_str(ddata, "[", 1)) { 912227825Stheraven free(exp); 913227825Stheraven return (0); 914227825Stheraven } 915227825Stheraven if (!cpp_demangle_push_str(ddata, exp, exp_len)) { 916227825Stheraven free(exp); 917227825Stheraven return (0); 918227825Stheraven } 919227825Stheraven if (!cpp_demangle_push_str(ddata, "]", 1)) { 920227825Stheraven free(exp); 921227825Stheraven return (0); 922227825Stheraven } 923227825Stheraven free(exp); 924227825Stheraven } 925227825Stheraven } 926227825Stheraven 927227825Stheraven return (1); 928227825Stheraven} 929227825Stheraven 930227825Stheravenstatic int 931227825Stheravencpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata) 932227825Stheraven{ 933227825Stheraven const char *num; 934227825Stheraven 935227825Stheraven if (ddata == NULL || *(++ddata->cur) == '\0') 936227825Stheraven return (0); 937227825Stheraven 938227825Stheraven if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') { 939227825Stheraven ddata->cur += 2; 940227825Stheraven if (*ddata->cur == '\0') 941227825Stheraven return (0); 942227825Stheraven if (!cpp_demangle_read_encoding(ddata)) 943227825Stheraven return (0); 944227825Stheraven ++ddata->cur; 945227825Stheraven return (1); 946227825Stheraven } 947227825Stheraven 948227825Stheraven switch (*ddata->cur) { 949227825Stheraven case 'b': 950227825Stheraven switch (*(++ddata->cur)) { 951227825Stheraven case '0': 952227825Stheraven return (cpp_demangle_push_str(ddata, "false", 5)); 953227825Stheraven case '1': 954227825Stheraven return (cpp_demangle_push_str(ddata, "true", 4)); 955227825Stheraven default: 956227825Stheraven return (0); 957227825Stheraven }; 958227825Stheraven 959227825Stheraven case 'd': 960227825Stheraven ++ddata->cur; 961227825Stheraven return (cpp_demangle_push_fp(ddata, decode_fp_to_double)); 962227825Stheraven 963227825Stheraven case 'e': 964227825Stheraven ++ddata->cur; 965227825Stheraven if (sizeof(long double) == 10) 966227825Stheraven return (cpp_demangle_push_fp(ddata, 967227825Stheraven decode_fp_to_double)); 968227825Stheraven return (cpp_demangle_push_fp(ddata, decode_fp_to_float80)); 969227825Stheraven 970227825Stheraven case 'f': 971227825Stheraven ++ddata->cur; 972227825Stheraven return (cpp_demangle_push_fp(ddata, decode_fp_to_float)); 973227825Stheraven 974227825Stheraven case 'g': 975227825Stheraven ++ddata->cur; 976227825Stheraven if (sizeof(long double) == 16) 977227825Stheraven return (cpp_demangle_push_fp(ddata, 978227825Stheraven decode_fp_to_double)); 979227825Stheraven return (cpp_demangle_push_fp(ddata, decode_fp_to_float128)); 980227825Stheraven 981227825Stheraven case 'i': 982227825Stheraven case 'j': 983227825Stheraven case 'l': 984227825Stheraven case 'm': 985227825Stheraven case 'n': 986227825Stheraven case 's': 987227825Stheraven case 't': 988227825Stheraven case 'x': 989227825Stheraven case 'y': 990227825Stheraven if (*(++ddata->cur) == 'n') { 991227825Stheraven if (!cpp_demangle_push_str(ddata, "-", 1)) 992227825Stheraven return (0); 993227825Stheraven ++ddata->cur; 994227825Stheraven } 995227825Stheraven num = ddata->cur; 996227825Stheraven while (*ddata->cur != 'E') { 997227825Stheraven if (!ELFTC_ISDIGIT(*ddata->cur)) 998227825Stheraven return (0); 999227825Stheraven ++ddata->cur; 1000227825Stheraven } 1001227825Stheraven ++ddata->cur; 1002227825Stheraven return (cpp_demangle_push_str(ddata, num, ddata->cur - num)); 1003227825Stheraven 1004227825Stheraven default: 1005227825Stheraven return (0); 1006227825Stheraven }; 1007227825Stheraven} 1008227825Stheraven 1009227825Stheravenstatic int 1010227825Stheravencpp_demangle_read_expression(struct cpp_demangle_data *ddata) 1011227825Stheraven{ 1012227825Stheraven 1013227825Stheraven if (ddata == NULL || *ddata->cur == '\0') 1014227825Stheraven return (0); 1015227825Stheraven 1016227825Stheraven switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 1017227825Stheraven case SIMPLE_HASH('s', 't'): 1018227825Stheraven ddata->cur += 2; 1019227825Stheraven return (cpp_demangle_read_type(ddata, 0)); 1020227825Stheraven 1021227825Stheraven case SIMPLE_HASH('s', 'r'): 1022227825Stheraven ddata->cur += 2; 1023227825Stheraven if (!cpp_demangle_read_type(ddata, 0)) 1024227825Stheraven return (0); 1025227825Stheraven if (!cpp_demangle_read_uqname(ddata)) 1026227825Stheraven return (0); 1027227825Stheraven if (*ddata->cur == 'I') 1028227825Stheraven return (cpp_demangle_read_tmpl_args(ddata)); 1029227825Stheraven return (1); 1030227825Stheraven 1031227825Stheraven case SIMPLE_HASH('a', 'a'): 1032227825Stheraven /* operator && */ 1033227825Stheraven ddata->cur += 2; 1034227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "&&", 2)); 1035227825Stheraven 1036227825Stheraven case SIMPLE_HASH('a', 'd'): 1037227825Stheraven /* operator & (unary) */ 1038227825Stheraven ddata->cur += 2; 1039227825Stheraven return (cpp_demangle_read_expression_unary(ddata, "&", 1)); 1040227825Stheraven 1041227825Stheraven case SIMPLE_HASH('a', 'n'): 1042227825Stheraven /* operator & */ 1043227825Stheraven ddata->cur += 2; 1044227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "&", 1)); 1045227825Stheraven 1046227825Stheraven case SIMPLE_HASH('a', 'N'): 1047227825Stheraven /* operator &= */ 1048227825Stheraven ddata->cur += 2; 1049227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "&=", 2)); 1050227825Stheraven 1051227825Stheraven case SIMPLE_HASH('a', 'S'): 1052227825Stheraven /* operator = */ 1053227825Stheraven ddata->cur += 2; 1054227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "=", 1)); 1055227825Stheraven 1056227825Stheraven case SIMPLE_HASH('c', 'l'): 1057227825Stheraven /* operator () */ 1058227825Stheraven ddata->cur += 2; 1059227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "()", 2)); 1060227825Stheraven 1061227825Stheraven case SIMPLE_HASH('c', 'm'): 1062227825Stheraven /* operator , */ 1063227825Stheraven ddata->cur += 2; 1064227825Stheraven return (cpp_demangle_read_expression_binary(ddata, ",", 1)); 1065227825Stheraven 1066227825Stheraven case SIMPLE_HASH('c', 'o'): 1067227825Stheraven /* operator ~ */ 1068227825Stheraven ddata->cur += 2; 1069227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "~", 1)); 1070227825Stheraven 1071227825Stheraven case SIMPLE_HASH('c', 'v'): 1072227825Stheraven /* operator (cast) */ 1073227825Stheraven ddata->cur += 2; 1074227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6)); 1075227825Stheraven 1076227825Stheraven case SIMPLE_HASH('d', 'a'): 1077227825Stheraven /* operator delete [] */ 1078227825Stheraven ddata->cur += 2; 1079227825Stheraven return (cpp_demangle_read_expression_unary(ddata, "delete []", 9)); 1080227825Stheraven 1081227825Stheraven case SIMPLE_HASH('d', 'e'): 1082227825Stheraven /* operator * (unary) */ 1083227825Stheraven ddata->cur += 2; 1084227825Stheraven return (cpp_demangle_read_expression_unary(ddata, "*", 1)); 1085227825Stheraven 1086227825Stheraven case SIMPLE_HASH('d', 'l'): 1087227825Stheraven /* operator delete */ 1088227825Stheraven ddata->cur += 2; 1089227825Stheraven return (cpp_demangle_read_expression_unary(ddata, "delete", 6)); 1090227825Stheraven 1091227825Stheraven case SIMPLE_HASH('d', 'v'): 1092227825Stheraven /* operator / */ 1093227825Stheraven ddata->cur += 2; 1094227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "/", 1)); 1095227825Stheraven 1096227825Stheraven case SIMPLE_HASH('d', 'V'): 1097227825Stheraven /* operator /= */ 1098227825Stheraven ddata->cur += 2; 1099227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "/=", 2)); 1100227825Stheraven 1101227825Stheraven case SIMPLE_HASH('e', 'o'): 1102227825Stheraven /* operator ^ */ 1103227825Stheraven ddata->cur += 2; 1104227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "^", 1)); 1105227825Stheraven 1106227825Stheraven case SIMPLE_HASH('e', 'O'): 1107227825Stheraven /* operator ^= */ 1108227825Stheraven ddata->cur += 2; 1109227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "^=", 2)); 1110227825Stheraven 1111227825Stheraven case SIMPLE_HASH('e', 'q'): 1112227825Stheraven /* operator == */ 1113227825Stheraven ddata->cur += 2; 1114227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "==", 2)); 1115227825Stheraven 1116227825Stheraven case SIMPLE_HASH('g', 'e'): 1117227825Stheraven /* operator >= */ 1118227825Stheraven ddata->cur += 2; 1119227825Stheraven return (cpp_demangle_read_expression_binary(ddata, ">=", 2)); 1120227825Stheraven 1121227825Stheraven case SIMPLE_HASH('g', 't'): 1122227825Stheraven /* operator > */ 1123227825Stheraven ddata->cur += 2; 1124227825Stheraven return (cpp_demangle_read_expression_binary(ddata, ">", 1)); 1125227825Stheraven 1126227825Stheraven case SIMPLE_HASH('i', 'x'): 1127227825Stheraven /* operator [] */ 1128227825Stheraven ddata->cur += 2; 1129227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "[]", 2)); 1130227825Stheraven 1131227825Stheraven case SIMPLE_HASH('l', 'e'): 1132227825Stheraven /* operator <= */ 1133227825Stheraven ddata->cur += 2; 1134227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "<=", 2)); 1135227825Stheraven 1136227825Stheraven case SIMPLE_HASH('l', 's'): 1137227825Stheraven /* operator << */ 1138227825Stheraven ddata->cur += 2; 1139227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "<<", 2)); 1140227825Stheraven 1141227825Stheraven case SIMPLE_HASH('l', 'S'): 1142227825Stheraven /* operator <<= */ 1143227825Stheraven ddata->cur += 2; 1144227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "<<=", 3)); 1145227825Stheraven 1146227825Stheraven case SIMPLE_HASH('l', 't'): 1147227825Stheraven /* operator < */ 1148227825Stheraven ddata->cur += 2; 1149227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "<", 1)); 1150227825Stheraven 1151227825Stheraven case SIMPLE_HASH('m', 'i'): 1152227825Stheraven /* operator - */ 1153227825Stheraven ddata->cur += 2; 1154227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "-", 1)); 1155227825Stheraven 1156227825Stheraven case SIMPLE_HASH('m', 'I'): 1157227825Stheraven /* operator -= */ 1158227825Stheraven ddata->cur += 2; 1159227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "-=", 2)); 1160227825Stheraven 1161227825Stheraven case SIMPLE_HASH('m', 'l'): 1162227825Stheraven /* operator * */ 1163227825Stheraven ddata->cur += 2; 1164227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "*", 1)); 1165227825Stheraven 1166227825Stheraven case SIMPLE_HASH('m', 'L'): 1167227825Stheraven /* operator *= */ 1168227825Stheraven ddata->cur += 2; 1169227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "*=", 2)); 1170227825Stheraven 1171227825Stheraven case SIMPLE_HASH('m', 'm'): 1172227825Stheraven /* operator -- */ 1173227825Stheraven ddata->cur += 2; 1174227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "--", 2)); 1175227825Stheraven 1176227825Stheraven case SIMPLE_HASH('n', 'a'): 1177227825Stheraven /* operator new[] */ 1178227825Stheraven ddata->cur += 2; 1179227825Stheraven return (cpp_demangle_read_expression_unary(ddata, "new []", 6)); 1180227825Stheraven 1181227825Stheraven case SIMPLE_HASH('n', 'e'): 1182227825Stheraven /* operator != */ 1183227825Stheraven ddata->cur += 2; 1184227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "!=", 2)); 1185227825Stheraven 1186227825Stheraven case SIMPLE_HASH('n', 'g'): 1187227825Stheraven /* operator - (unary) */ 1188227825Stheraven ddata->cur += 2; 1189227825Stheraven return (cpp_demangle_read_expression_unary(ddata, "-", 1)); 1190227825Stheraven 1191227825Stheraven case SIMPLE_HASH('n', 't'): 1192227825Stheraven /* operator ! */ 1193227825Stheraven ddata->cur += 2; 1194227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "!", 1)); 1195227825Stheraven 1196227825Stheraven case SIMPLE_HASH('n', 'w'): 1197227825Stheraven /* operator new */ 1198227825Stheraven ddata->cur += 2; 1199227825Stheraven return (cpp_demangle_read_expression_unary(ddata, "new", 3)); 1200227825Stheraven 1201227825Stheraven case SIMPLE_HASH('o', 'o'): 1202227825Stheraven /* operator || */ 1203227825Stheraven ddata->cur += 2; 1204227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "||", 2)); 1205227825Stheraven 1206227825Stheraven case SIMPLE_HASH('o', 'r'): 1207227825Stheraven /* operator | */ 1208227825Stheraven ddata->cur += 2; 1209227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "|", 1)); 1210227825Stheraven 1211227825Stheraven case SIMPLE_HASH('o', 'R'): 1212227825Stheraven /* operator |= */ 1213227825Stheraven ddata->cur += 2; 1214227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "|=", 2)); 1215227825Stheraven 1216227825Stheraven case SIMPLE_HASH('p', 'l'): 1217227825Stheraven /* operator + */ 1218227825Stheraven ddata->cur += 2; 1219227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "+", 1)); 1220227825Stheraven 1221227825Stheraven case SIMPLE_HASH('p', 'L'): 1222227825Stheraven /* operator += */ 1223227825Stheraven ddata->cur += 2; 1224227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "+=", 2)); 1225227825Stheraven 1226227825Stheraven case SIMPLE_HASH('p', 'm'): 1227227825Stheraven /* operator ->* */ 1228227825Stheraven ddata->cur += 2; 1229227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "->*", 3)); 1230227825Stheraven 1231227825Stheraven case SIMPLE_HASH('p', 'p'): 1232227825Stheraven /* operator ++ */ 1233227825Stheraven ddata->cur += 2; 1234227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "++", 2)); 1235227825Stheraven 1236227825Stheraven case SIMPLE_HASH('p', 's'): 1237227825Stheraven /* operator + (unary) */ 1238227825Stheraven ddata->cur += 2; 1239227825Stheraven return (cpp_demangle_read_expression_unary(ddata, "+", 1)); 1240227825Stheraven 1241227825Stheraven case SIMPLE_HASH('p', 't'): 1242227825Stheraven /* operator -> */ 1243227825Stheraven ddata->cur += 2; 1244227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "->", 2)); 1245227825Stheraven 1246227825Stheraven case SIMPLE_HASH('q', 'u'): 1247227825Stheraven /* operator ? */ 1248227825Stheraven ddata->cur += 2; 1249227825Stheraven return (cpp_demangle_read_expression_trinary(ddata, "?", 1, 1250227825Stheraven ":", 1)); 1251227825Stheraven 1252227825Stheraven case SIMPLE_HASH('r', 'm'): 1253227825Stheraven /* operator % */ 1254227825Stheraven ddata->cur += 2; 1255227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "%", 1)); 1256227825Stheraven 1257227825Stheraven case SIMPLE_HASH('r', 'M'): 1258227825Stheraven /* operator %= */ 1259227825Stheraven ddata->cur += 2; 1260227825Stheraven return (cpp_demangle_read_expression_binary(ddata, "%=", 2)); 1261227825Stheraven 1262227825Stheraven case SIMPLE_HASH('r', 's'): 1263227825Stheraven /* operator >> */ 1264227825Stheraven ddata->cur += 2; 1265227825Stheraven return (cpp_demangle_read_expression_binary(ddata, ">>", 2)); 1266227825Stheraven 1267227825Stheraven case SIMPLE_HASH('r', 'S'): 1268227825Stheraven /* operator >>= */ 1269227825Stheraven ddata->cur += 2; 1270227825Stheraven return (cpp_demangle_read_expression_binary(ddata, ">>=", 3)); 1271227825Stheraven 1272227825Stheraven case SIMPLE_HASH('r', 'z'): 1273227825Stheraven /* operator sizeof */ 1274227825Stheraven ddata->cur += 2; 1275227825Stheraven return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); 1276227825Stheraven 1277227825Stheraven case SIMPLE_HASH('s', 'v'): 1278227825Stheraven /* operator sizeof */ 1279227825Stheraven ddata->cur += 2; 1280227825Stheraven return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); 1281227825Stheraven }; 1282227825Stheraven 1283227825Stheraven switch (*ddata->cur) { 1284227825Stheraven case 'L': 1285227825Stheraven return (cpp_demangle_read_expr_primary(ddata)); 1286227825Stheraven case 'T': 1287227825Stheraven return (cpp_demangle_read_tmpl_param(ddata)); 1288227825Stheraven }; 1289227825Stheraven 1290227825Stheraven return (0); 1291227825Stheraven} 1292227825Stheraven 1293227825Stheravenstatic int 1294227825Stheravencpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata, 1295227825Stheraven const char *name, size_t len) 1296227825Stheraven{ 1297227825Stheraven 1298227825Stheraven if (ddata == NULL || name == NULL || len == 0) 1299227825Stheraven return (0); 1300227825Stheraven if (!cpp_demangle_read_expression(ddata)) 1301227825Stheraven return (0); 1302227825Stheraven if (!cpp_demangle_push_str(ddata, name, len)) 1303227825Stheraven return (0); 1304227825Stheraven 1305227825Stheraven return (cpp_demangle_read_expression(ddata)); 1306227825Stheraven} 1307227825Stheraven 1308227825Stheravenstatic int 1309227825Stheravencpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata, 1310227825Stheraven const char *name, size_t len) 1311227825Stheraven{ 1312227825Stheraven 1313227825Stheraven if (ddata == NULL || name == NULL || len == 0) 1314227825Stheraven return (0); 1315227825Stheraven if (!cpp_demangle_read_expression(ddata)) 1316227825Stheraven return (0); 1317227825Stheraven 1318227825Stheraven return (cpp_demangle_push_str(ddata, name, len)); 1319227825Stheraven} 1320227825Stheraven 1321227825Stheravenstatic int 1322227825Stheravencpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata, 1323227825Stheraven const char *name1, size_t len1, const char *name2, size_t len2) 1324227825Stheraven{ 1325227825Stheraven 1326227825Stheraven if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL || 1327227825Stheraven len2 == 0) 1328227825Stheraven return (0); 1329227825Stheraven 1330227825Stheraven if (!cpp_demangle_read_expression(ddata)) 1331227825Stheraven return (0); 1332227825Stheraven if (!cpp_demangle_push_str(ddata, name1, len1)) 1333227825Stheraven return (0); 1334227825Stheraven if (!cpp_demangle_read_expression(ddata)) 1335227825Stheraven return (0); 1336227825Stheraven if (!cpp_demangle_push_str(ddata, name2, len2)) 1337227825Stheraven return (0); 1338227825Stheraven 1339227825Stheraven return (cpp_demangle_read_expression(ddata)); 1340227825Stheraven} 1341227825Stheraven 1342227825Stheravenstatic int 1343227825Stheravencpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c, 1344227825Stheraven struct vector_type_qualifier *v) 1345227825Stheraven{ 1346227825Stheraven size_t class_type_size, class_type_len, limit; 1347227825Stheraven const char *class_type; 1348227825Stheraven 1349227825Stheraven if (ddata == NULL || *ddata->cur != 'F' || v == NULL) 1350227825Stheraven return (0); 1351227825Stheraven 1352227825Stheraven ++ddata->cur; 1353227825Stheraven if (*ddata->cur == 'Y') { 1354227825Stheraven if (ext_c != NULL) 1355227825Stheraven *ext_c = 1; 1356227825Stheraven ++ddata->cur; 1357227825Stheraven } 1358227825Stheraven if (!cpp_demangle_read_type(ddata, 0)) 1359227825Stheraven return (0); 1360227825Stheraven if (*ddata->cur != 'E') { 1361227825Stheraven if (!cpp_demangle_push_str(ddata, "(", 1)) 1362227825Stheraven return (0); 1363227825Stheraven if (vector_read_cmd_find(&ddata->cmd, READ_PTRMEM)) { 1364227825Stheraven if ((class_type_size = ddata->class_type.size) == 0) 1365227825Stheraven return (0); 1366227825Stheraven class_type = 1367227825Stheraven ddata->class_type.container[class_type_size - 1]; 1368227825Stheraven if (class_type == NULL) 1369227825Stheraven return (0); 1370227825Stheraven if ((class_type_len = strlen(class_type)) == 0) 1371227825Stheraven return (0); 1372227825Stheraven if (!cpp_demangle_push_str(ddata, class_type, 1373227825Stheraven class_type_len)) 1374227825Stheraven return (0); 1375227825Stheraven if (!cpp_demangle_push_str(ddata, "::*", 3)) 1376227825Stheraven return (0); 1377227825Stheraven ++ddata->func_type; 1378227825Stheraven } else { 1379227825Stheraven if (!cpp_demangle_push_type_qualifier(ddata, v, 1380227825Stheraven (const char *) NULL)) 1381227825Stheraven return (0); 1382227825Stheraven vector_type_qualifier_dest(v); 1383227825Stheraven if (!vector_type_qualifier_init(v)) 1384227825Stheraven return (0); 1385227825Stheraven } 1386227825Stheraven 1387227825Stheraven if (!cpp_demangle_push_str(ddata, ")(", 2)) 1388227825Stheraven return (0); 1389227825Stheraven 1390227825Stheraven limit = 0; 1391227825Stheraven for (;;) { 1392227825Stheraven if (!cpp_demangle_read_type(ddata, 0)) 1393227825Stheraven return (0); 1394227825Stheraven if (*ddata->cur == 'E') 1395227825Stheraven break; 1396227825Stheraven if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1397227825Stheraven return (0); 1398227825Stheraven } 1399227825Stheraven 1400227825Stheraven if (vector_read_cmd_find(&ddata->cmd, READ_PTRMEM) == 1) { 1401227825Stheraven if (!cpp_demangle_push_type_qualifier(ddata, v, 1402227825Stheraven (const char *) NULL)) 1403227825Stheraven return (0); 1404227825Stheraven vector_type_qualifier_dest(v); 1405227825Stheraven if (!vector_type_qualifier_init(v)) 1406227825Stheraven return (0); 1407227825Stheraven } 1408227825Stheraven 1409227825Stheraven if (!cpp_demangle_push_str(ddata, ")", 1)) 1410227825Stheraven return (0); 1411227825Stheraven } 1412227825Stheraven 1413227825Stheraven ++ddata->cur; 1414227825Stheraven 1415227825Stheraven return (1); 1416227825Stheraven} 1417227825Stheraven 1418227825Stheraven/* read encoding, encoding are function name, data name, special-name */ 1419227825Stheravenstatic int 1420227825Stheravencpp_demangle_read_encoding(struct cpp_demangle_data *ddata) 1421227825Stheraven{ 1422227825Stheraven 1423227825Stheraven if (ddata == NULL || *ddata->cur == '\0') 1424227825Stheraven return (0); 1425227825Stheraven 1426227825Stheraven /* special name */ 1427227825Stheraven switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 1428227825Stheraven case SIMPLE_HASH('G', 'V'): 1429227825Stheraven /* sentry object for 1 time init */ 1430227825Stheraven if (!cpp_demangle_push_str(ddata, "guard variable for ", 20)) 1431227825Stheraven return (0); 1432227825Stheraven ddata->cur += 2; 1433227825Stheraven break; 1434227825Stheraven 1435227825Stheraven case SIMPLE_HASH('T', 'c'): 1436227825Stheraven /* virtual function covariant override thunk */ 1437227825Stheraven if (!cpp_demangle_push_str(ddata, 1438227825Stheraven "virtual function covariant override ", 36)) 1439227825Stheraven return (0); 1440227825Stheraven ddata->cur += 2; 1441227825Stheraven if (*ddata->cur == '\0') 1442227825Stheraven return (0); 1443227825Stheraven if (!cpp_demangle_read_offset(ddata)) 1444227825Stheraven return (0); 1445227825Stheraven if (!cpp_demangle_read_offset(ddata)) 1446227825Stheraven return (0); 1447227825Stheraven return (cpp_demangle_read_encoding(ddata)); 1448227825Stheraven 1449227825Stheraven case SIMPLE_HASH('T', 'D'): 1450227825Stheraven /* typeinfo common proxy */ 1451227825Stheraven break; 1452227825Stheraven 1453227825Stheraven case SIMPLE_HASH('T', 'h'): 1454227825Stheraven /* virtual function non-virtual override thunk */ 1455227825Stheraven if (cpp_demangle_push_str(ddata, 1456227825Stheraven "virtual function non-virtual override ", 38) == 0) 1457227825Stheraven return (0); 1458227825Stheraven ddata->cur += 2; 1459227825Stheraven if (*ddata->cur == '\0') 1460227825Stheraven return (0); 1461227825Stheraven if (!cpp_demangle_read_nv_offset(ddata)) 1462227825Stheraven return (0); 1463227825Stheraven return (cpp_demangle_read_encoding(ddata)); 1464227825Stheraven 1465227825Stheraven case SIMPLE_HASH('T', 'I'): 1466227825Stheraven /* typeinfo structure */ 1467227825Stheraven /* FALLTHROUGH */ 1468227825Stheraven case SIMPLE_HASH('T', 'S'): 1469227825Stheraven /* RTTI name (NTBS) */ 1470227825Stheraven if (!cpp_demangle_push_str(ddata, "typeinfo for ", 14)) 1471227825Stheraven return (0); 1472227825Stheraven ddata->cur += 2; 1473227825Stheraven if (*ddata->cur == '\0') 1474227825Stheraven return (0); 1475227825Stheraven return (cpp_demangle_read_type(ddata, 1)); 1476227825Stheraven 1477227825Stheraven case SIMPLE_HASH('T', 'T'): 1478227825Stheraven /* VTT table */ 1479227825Stheraven if (!cpp_demangle_push_str(ddata, "VTT for ", 8)) 1480227825Stheraven return (0); 1481227825Stheraven ddata->cur += 2; 1482227825Stheraven return (cpp_demangle_read_type(ddata, 1)); 1483227825Stheraven 1484227825Stheraven case SIMPLE_HASH('T', 'v'): 1485227825Stheraven /* virtual function virtual override thunk */ 1486227825Stheraven if (!cpp_demangle_push_str(ddata, 1487227825Stheraven "virtual function virtual override ", 34)) 1488227825Stheraven return (0); 1489227825Stheraven ddata->cur += 2; 1490227825Stheraven if (*ddata->cur == '\0') 1491227825Stheraven return (0); 1492227825Stheraven if (!cpp_demangle_read_v_offset(ddata)) 1493227825Stheraven return (0); 1494227825Stheraven return (cpp_demangle_read_encoding(ddata)); 1495227825Stheraven 1496227825Stheraven case SIMPLE_HASH('T', 'V'): 1497227825Stheraven /* virtual table */ 1498227825Stheraven if (!cpp_demangle_push_str(ddata, "vtable for ", 12)) 1499227825Stheraven return (0); 1500227825Stheraven ddata->cur += 2; 1501227825Stheraven if (*ddata->cur == '\0') 1502227825Stheraven return (0); 1503227825Stheraven return (cpp_demangle_read_type(ddata, 1)); 1504227825Stheraven }; 1505227825Stheraven 1506227825Stheraven return (cpp_demangle_read_name(ddata)); 1507227825Stheraven} 1508227825Stheraven 1509227825Stheravenstatic int 1510227825Stheravencpp_demangle_read_local_name(struct cpp_demangle_data *ddata) 1511227825Stheraven{ 1512227825Stheraven size_t limit; 1513227825Stheraven 1514227825Stheraven if (ddata == NULL) 1515227825Stheraven return (0); 1516227825Stheraven if (*(++ddata->cur) == '\0') 1517227825Stheraven return (0); 1518227825Stheraven if (!cpp_demangle_read_encoding(ddata)) 1519227825Stheraven return (0); 1520227825Stheraven 1521227825Stheraven limit = 0; 1522227825Stheraven for (;;) { 1523227825Stheraven if (!cpp_demangle_read_type(ddata, 1)) 1524227825Stheraven return (0); 1525227825Stheraven if (*ddata->cur == 'E') 1526227825Stheraven break; 1527227825Stheraven if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1528227825Stheraven return (0); 1529227825Stheraven } 1530227825Stheraven if (*(++ddata->cur) == '\0') 1531227825Stheraven return (0); 1532227825Stheraven if (ddata->paren == true) { 1533227825Stheraven if (!cpp_demangle_push_str(ddata, ")", 1)) 1534227825Stheraven return (0); 1535227825Stheraven ddata->paren = false; 1536227825Stheraven } 1537227825Stheraven if (*ddata->cur == 's') 1538227825Stheraven ++ddata->cur; 1539227825Stheraven else { 1540227825Stheraven if (!cpp_demangle_push_str(ddata, "::", 2)) 1541227825Stheraven return (0); 1542227825Stheraven if (!cpp_demangle_read_name(ddata)) 1543227825Stheraven return (0); 1544227825Stheraven } 1545227825Stheraven if (*ddata->cur == '_') { 1546227825Stheraven ++ddata->cur; 1547227825Stheraven while (ELFTC_ISDIGIT(*ddata->cur) != 0) 1548227825Stheraven ++ddata->cur; 1549227825Stheraven } 1550227825Stheraven 1551227825Stheraven return (1); 1552227825Stheraven} 1553227825Stheraven 1554227825Stheravenstatic int 1555227825Stheravencpp_demangle_read_name(struct cpp_demangle_data *ddata) 1556227825Stheraven{ 1557227825Stheraven struct vector_str *output, v; 1558227825Stheraven size_t p_idx, subst_str_len; 1559227825Stheraven int rtn; 1560227825Stheraven char *subst_str; 1561227825Stheraven 1562227825Stheraven if (ddata == NULL || *ddata->cur == '\0') 1563227825Stheraven return (0); 1564227825Stheraven 1565227825Stheraven output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; 1566227825Stheraven 1567227825Stheraven subst_str = NULL; 1568227825Stheraven 1569227825Stheraven switch (*ddata->cur) { 1570227825Stheraven case 'S': 1571227825Stheraven return (cpp_demangle_read_subst(ddata)); 1572227825Stheraven case 'N': 1573227825Stheraven return (cpp_demangle_read_nested_name(ddata)); 1574227825Stheraven case 'Z': 1575227825Stheraven return (cpp_demangle_read_local_name(ddata)); 1576227825Stheraven }; 1577227825Stheraven 1578227825Stheraven if (!vector_str_init(&v)) 1579227825Stheraven return (0); 1580227825Stheraven 1581227825Stheraven p_idx = output->size; 1582227825Stheraven rtn = 0; 1583227825Stheraven if (!cpp_demangle_read_uqname(ddata)) 1584227825Stheraven goto clean; 1585227825Stheraven if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, 1586227825Stheraven &subst_str_len)) == NULL) 1587227825Stheraven goto clean; 1588227825Stheraven if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) { 1589227825Stheraven rtn = 1; 1590227825Stheraven goto clean; 1591227825Stheraven } 1592227825Stheraven if (!vector_str_push(&v, subst_str, subst_str_len)) 1593227825Stheraven goto clean; 1594227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &v)) 1595227825Stheraven goto clean; 1596227825Stheraven 1597227825Stheraven if (*ddata->cur == 'I') { 1598227825Stheraven p_idx = output->size; 1599227825Stheraven if (!cpp_demangle_read_tmpl_args(ddata)) 1600227825Stheraven goto clean; 1601227825Stheraven free(subst_str); 1602227825Stheraven if ((subst_str = vector_str_substr(output, p_idx, 1603227825Stheraven output->size - 1, &subst_str_len)) == NULL) 1604227825Stheraven goto clean; 1605227825Stheraven if (!vector_str_push(&v, subst_str, subst_str_len)) 1606227825Stheraven goto clean; 1607227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &v)) 1608227825Stheraven goto clean; 1609227825Stheraven } 1610227825Stheraven 1611227825Stheraven rtn = 1; 1612227825Stheraven 1613227825Stheravenclean: 1614227825Stheraven free(subst_str); 1615227825Stheraven vector_str_dest(&v); 1616227825Stheraven 1617227825Stheraven return (rtn); 1618227825Stheraven} 1619227825Stheraven 1620227825Stheravenstatic int 1621227825Stheravencpp_demangle_read_nested_name(struct cpp_demangle_data *ddata) 1622227825Stheraven{ 1623227825Stheraven struct vector_str *output, v; 1624227825Stheraven size_t limit, p_idx, subst_str_len; 1625227825Stheraven int rtn; 1626227825Stheraven char *subst_str; 1627227825Stheraven 1628227825Stheraven if (ddata == NULL || *ddata->cur != 'N') 1629227825Stheraven return (0); 1630227825Stheraven if (*(++ddata->cur) == '\0') 1631227825Stheraven return (0); 1632227825Stheraven 1633227825Stheraven while (*ddata->cur == 'r' || *ddata->cur == 'V' || 1634227825Stheraven *ddata->cur == 'K') { 1635227825Stheraven switch (*ddata->cur) { 1636227825Stheraven case 'r': 1637227825Stheraven ddata->mem_rst = true; 1638227825Stheraven break; 1639227825Stheraven case 'V': 1640227825Stheraven ddata->mem_vat = true; 1641227825Stheraven break; 1642227825Stheraven case 'K': 1643227825Stheraven ddata->mem_cst = true; 1644227825Stheraven break; 1645227825Stheraven }; 1646227825Stheraven ++ddata->cur; 1647227825Stheraven } 1648227825Stheraven 1649227825Stheraven output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; 1650227825Stheraven if (!vector_str_init(&v)) 1651227825Stheraven return (0); 1652227825Stheraven 1653227825Stheraven rtn = 0; 1654227825Stheraven limit = 0; 1655227825Stheraven for (;;) { 1656227825Stheraven p_idx = output->size; 1657227825Stheraven switch (*ddata->cur) { 1658227825Stheraven case 'I': 1659227825Stheraven if (!cpp_demangle_read_tmpl_args(ddata)) 1660227825Stheraven goto clean; 1661227825Stheraven break; 1662227825Stheraven case 'S': 1663227825Stheraven if (!cpp_demangle_read_subst(ddata)) 1664227825Stheraven goto clean; 1665227825Stheraven break; 1666227825Stheraven case 'T': 1667227825Stheraven if (!cpp_demangle_read_tmpl_param(ddata)) 1668227825Stheraven goto clean; 1669227825Stheraven break; 1670227825Stheraven default: 1671227825Stheraven if (!cpp_demangle_read_uqname(ddata)) 1672227825Stheraven goto clean; 1673227825Stheraven }; 1674227825Stheraven 1675227825Stheraven if ((subst_str = vector_str_substr(output, p_idx, 1676227825Stheraven output->size - 1, &subst_str_len)) == NULL) 1677227825Stheraven goto clean; 1678227825Stheraven if (!vector_str_push(&v, subst_str, subst_str_len)) { 1679227825Stheraven free(subst_str); 1680227825Stheraven goto clean; 1681227825Stheraven } 1682227825Stheraven free(subst_str); 1683227825Stheraven 1684227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &v)) 1685227825Stheraven goto clean; 1686227825Stheraven if (*ddata->cur == 'E') 1687227825Stheraven break; 1688227825Stheraven else if (*ddata->cur != 'I' && 1689227825Stheraven *ddata->cur != 'C' && *ddata->cur != 'D') { 1690227825Stheraven if (!cpp_demangle_push_str(ddata, "::", 2)) 1691227825Stheraven goto clean; 1692227825Stheraven if (!vector_str_push(&v, "::", 2)) 1693227825Stheraven goto clean; 1694227825Stheraven } 1695227825Stheraven if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1696227825Stheraven goto clean; 1697227825Stheraven } 1698227825Stheraven 1699227825Stheraven ++ddata->cur; 1700227825Stheraven rtn = 1; 1701227825Stheraven 1702227825Stheravenclean: 1703227825Stheraven vector_str_dest(&v); 1704227825Stheraven 1705227825Stheraven return (rtn); 1706227825Stheraven} 1707227825Stheraven 1708227825Stheraven/* 1709227825Stheraven * read number 1710227825Stheraven * number ::= [n] <decimal> 1711227825Stheraven */ 1712227825Stheravenstatic int 1713227825Stheravencpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn) 1714227825Stheraven{ 1715227825Stheraven long len, negative_factor; 1716227825Stheraven 1717227825Stheraven if (ddata == NULL || rtn == NULL) 1718227825Stheraven return (0); 1719227825Stheraven 1720227825Stheraven negative_factor = 1; 1721227825Stheraven if (*ddata->cur == 'n') { 1722227825Stheraven negative_factor = -1; 1723227825Stheraven 1724227825Stheraven ++ddata->cur; 1725227825Stheraven } 1726227825Stheraven if (ELFTC_ISDIGIT(*ddata->cur) == 0) 1727227825Stheraven return (0); 1728227825Stheraven 1729227825Stheraven errno = 0; 1730227825Stheraven if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 && 1731227825Stheraven errno != 0) 1732227825Stheraven return (0); 1733227825Stheraven 1734227825Stheraven while (ELFTC_ISDIGIT(*ddata->cur) != 0) 1735227825Stheraven ++ddata->cur; 1736227825Stheraven 1737227825Stheraven assert(len >= 0); 1738227825Stheraven assert(negative_factor == 1 || negative_factor == -1); 1739227825Stheraven 1740227825Stheraven *rtn = len * negative_factor; 1741227825Stheraven 1742227825Stheraven return (1); 1743227825Stheraven} 1744227825Stheraven 1745227825Stheravenstatic int 1746227825Stheravencpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata) 1747227825Stheraven{ 1748227825Stheraven 1749227825Stheraven if (ddata == NULL) 1750227825Stheraven return (0); 1751227825Stheraven 1752227825Stheraven if (!cpp_demangle_push_str(ddata, "offset : ", 9)) 1753227825Stheraven return (0); 1754227825Stheraven 1755227825Stheraven return (cpp_demangle_read_offset_number(ddata)); 1756227825Stheraven} 1757227825Stheraven 1758227825Stheraven/* read offset, offset are nv-offset, v-offset */ 1759227825Stheravenstatic int 1760227825Stheravencpp_demangle_read_offset(struct cpp_demangle_data *ddata) 1761227825Stheraven{ 1762227825Stheraven 1763227825Stheraven if (ddata == NULL) 1764227825Stheraven return (0); 1765227825Stheraven 1766227825Stheraven if (*ddata->cur == 'h') { 1767227825Stheraven ++ddata->cur; 1768227825Stheraven return (cpp_demangle_read_nv_offset(ddata)); 1769227825Stheraven } else if (*ddata->cur == 'v') { 1770227825Stheraven ++ddata->cur; 1771227825Stheraven return (cpp_demangle_read_v_offset(ddata)); 1772227825Stheraven } 1773227825Stheraven 1774227825Stheraven return (0); 1775227825Stheraven} 1776227825Stheraven 1777227825Stheravenstatic int 1778227825Stheravencpp_demangle_read_offset_number(struct cpp_demangle_data *ddata) 1779227825Stheraven{ 1780227825Stheraven bool negative; 1781227825Stheraven const char *start; 1782227825Stheraven 1783227825Stheraven if (ddata == NULL || *ddata->cur == '\0') 1784227825Stheraven return (0); 1785227825Stheraven 1786227825Stheraven /* offset could be negative */ 1787227825Stheraven if (*ddata->cur == 'n') { 1788227825Stheraven negative = true; 1789227825Stheraven start = ddata->cur + 1; 1790227825Stheraven } else { 1791227825Stheraven negative = false; 1792227825Stheraven start = ddata->cur; 1793227825Stheraven } 1794227825Stheraven 1795227825Stheraven while (*ddata->cur != '_') 1796227825Stheraven ++ddata->cur; 1797227825Stheraven 1798227825Stheraven if (negative && !cpp_demangle_push_str(ddata, "-", 1)) 1799227825Stheraven return (0); 1800227825Stheraven 1801227825Stheraven assert(start != NULL); 1802227825Stheraven 1803227825Stheraven if (!cpp_demangle_push_str(ddata, start, ddata->cur - start)) 1804227825Stheraven return (0); 1805227825Stheraven if (!cpp_demangle_push_str(ddata, " ", 1)) 1806227825Stheraven return (0); 1807227825Stheraven 1808227825Stheraven ++ddata->cur; 1809227825Stheraven 1810227825Stheraven return (1); 1811227825Stheraven} 1812227825Stheraven 1813227825Stheravenstatic int 1814227825Stheravencpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata) 1815227825Stheraven{ 1816227825Stheraven size_t class_type_len, i, idx, p_idx; 1817227825Stheraven int p_func_type, rtn; 1818227825Stheraven char *class_type; 1819227825Stheraven 1820227825Stheraven if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0') 1821227825Stheraven return (0); 1822227825Stheraven 1823227825Stheraven p_idx = ddata->output.size; 1824227825Stheraven if (!cpp_demangle_read_type(ddata, 0)) 1825227825Stheraven return (0); 1826227825Stheraven 1827227825Stheraven if ((class_type = vector_str_substr(&ddata->output, p_idx, 1828227825Stheraven ddata->output.size - 1, &class_type_len)) == NULL) 1829227825Stheraven return (0); 1830227825Stheraven 1831227825Stheraven rtn = 0; 1832227825Stheraven idx = ddata->output.size; 1833227825Stheraven for (i = p_idx; i < idx; ++i) 1834227825Stheraven if (!vector_str_pop(&ddata->output)) 1835227825Stheraven goto clean1; 1836227825Stheraven 1837227825Stheraven if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM)) 1838227825Stheraven goto clean1; 1839227825Stheraven 1840227825Stheraven if (!vector_str_push(&ddata->class_type, class_type, class_type_len)) 1841227825Stheraven goto clean2; 1842227825Stheraven 1843227825Stheraven p_func_type = ddata->func_type; 1844227825Stheraven if (!cpp_demangle_read_type(ddata, 0)) 1845227825Stheraven goto clean3; 1846227825Stheraven 1847227825Stheraven if (p_func_type == ddata->func_type) { 1848227825Stheraven if (!cpp_demangle_push_str(ddata, " ", 1)) 1849227825Stheraven goto clean3; 1850227825Stheraven if (!cpp_demangle_push_str(ddata, class_type, class_type_len)) 1851227825Stheraven goto clean3; 1852227825Stheraven if (!cpp_demangle_push_str(ddata, "::*", 3)) 1853227825Stheraven goto clean3; 1854227825Stheraven } 1855227825Stheraven 1856227825Stheraven rtn = 1; 1857227825Stheravenclean3: 1858227825Stheraven if (!vector_str_pop(&ddata->class_type)) 1859227825Stheraven rtn = 0; 1860227825Stheravenclean2: 1861227825Stheraven if (!vector_read_cmd_pop(&ddata->cmd)) 1862227825Stheraven rtn = 0; 1863227825Stheravenclean1: 1864227825Stheraven free(class_type); 1865227825Stheraven 1866227825Stheraven return (rtn); 1867227825Stheraven} 1868227825Stheraven 1869227825Stheraven/* read source-name, source-name is <len> <ID> */ 1870227825Stheravenstatic int 1871227825Stheravencpp_demangle_read_sname(struct cpp_demangle_data *ddata) 1872227825Stheraven{ 1873227825Stheraven long len; 1874255815Stheraven int err; 1875227825Stheraven 1876227825Stheraven if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 || 1877255815Stheraven len <= 0) 1878227825Stheraven return (0); 1879227825Stheraven 1880255815Stheraven if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0)) 1881255815Stheraven err = cpp_demangle_push_str(ddata, "(anonymous namespace)", 21); 1882255815Stheraven else 1883255815Stheraven err = cpp_demangle_push_str(ddata, ddata->cur, len); 1884255815Stheraven 1885255815Stheraven if (err == 0) 1886255815Stheraven return (0); 1887255815Stheraven 1888227825Stheraven assert(ddata->output.size > 0); 1889227825Stheraven if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == 0) 1890227825Stheraven ddata->last_sname = 1891227825Stheraven ddata->output.container[ddata->output.size - 1]; 1892227825Stheraven 1893227825Stheraven ddata->cur += len; 1894227825Stheraven 1895227825Stheraven return (1); 1896227825Stheraven} 1897227825Stheraven 1898227825Stheravenstatic int 1899227825Stheravencpp_demangle_read_subst(struct cpp_demangle_data *ddata) 1900227825Stheraven{ 1901227825Stheraven long nth; 1902227825Stheraven 1903227825Stheraven if (ddata == NULL || *ddata->cur == '\0') 1904227825Stheraven return (0); 1905227825Stheraven 1906227825Stheraven /* abbreviations of the form Sx */ 1907227825Stheraven switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 1908227825Stheraven case SIMPLE_HASH('S', 'a'): 1909227825Stheraven /* std::allocator */ 1910227825Stheraven if (cpp_demangle_push_str(ddata, "std::allocator", 14) == 0) 1911227825Stheraven return (0); 1912227825Stheraven ddata->cur += 2; 1913227825Stheraven if (*ddata->cur == 'I') 1914227825Stheraven return (cpp_demangle_read_subst_stdtmpl(ddata, 1915227825Stheraven "std::allocator", 14)); 1916227825Stheraven return (1); 1917227825Stheraven 1918227825Stheraven case SIMPLE_HASH('S', 'b'): 1919227825Stheraven /* std::basic_string */ 1920227825Stheraven if (!cpp_demangle_push_str(ddata, "std::basic_string", 17)) 1921227825Stheraven return (0); 1922227825Stheraven ddata->cur += 2; 1923227825Stheraven if (*ddata->cur == 'I') 1924227825Stheraven return (cpp_demangle_read_subst_stdtmpl(ddata, 1925227825Stheraven "std::basic_string", 17)); 1926227825Stheraven return (1); 1927227825Stheraven 1928227825Stheraven case SIMPLE_HASH('S', 'd'): 1929227825Stheraven /* std::basic_iostream<char, std::char_traits<char> > */ 1930227825Stheraven if (!cpp_demangle_push_str(ddata, "std::iostream", 19)) 1931227825Stheraven return (0); 1932227825Stheraven ddata->last_sname = "iostream"; 1933227825Stheraven ddata->cur += 2; 1934227825Stheraven if (*ddata->cur == 'I') 1935227825Stheraven return (cpp_demangle_read_subst_stdtmpl(ddata, 1936227825Stheraven "std::iostream", 19)); 1937227825Stheraven return (1); 1938227825Stheraven 1939227825Stheraven case SIMPLE_HASH('S', 'i'): 1940227825Stheraven /* std::basic_istream<char, std::char_traits<char> > */ 1941227825Stheraven if (!cpp_demangle_push_str(ddata, "std::istream", 18)) 1942227825Stheraven return (0); 1943227825Stheraven ddata->last_sname = "istream"; 1944227825Stheraven ddata->cur += 2; 1945227825Stheraven if (*ddata->cur == 'I') 1946227825Stheraven return (cpp_demangle_read_subst_stdtmpl(ddata, 1947227825Stheraven "std::istream", 18)); 1948227825Stheraven return (1); 1949227825Stheraven 1950227825Stheraven case SIMPLE_HASH('S', 'o'): 1951227825Stheraven /* std::basic_ostream<char, std::char_traits<char> > */ 1952227825Stheraven if (!cpp_demangle_push_str(ddata, "std::ostream", 18)) 1953227825Stheraven return (0); 1954227825Stheraven ddata->last_sname = "istream"; 1955227825Stheraven ddata->cur += 2; 1956227825Stheraven if (*ddata->cur == 'I') 1957227825Stheraven return (cpp_demangle_read_subst_stdtmpl(ddata, 1958227825Stheraven "std::ostream", 18)); 1959227825Stheraven return (1); 1960227825Stheraven 1961227825Stheraven case SIMPLE_HASH('S', 's'): 1962227825Stheraven /* 1963227825Stheraven * std::basic_string<char, std::char_traits<char>, 1964227825Stheraven * std::allocator<char> > 1965227825Stheraven * 1966227825Stheraven * a.k.a std::string 1967227825Stheraven */ 1968227825Stheraven if (!cpp_demangle_push_str(ddata, "std::string", 11)) 1969227825Stheraven return (0); 1970227825Stheraven ddata->last_sname = "string"; 1971227825Stheraven ddata->cur += 2; 1972227825Stheraven if (*ddata->cur == 'I') 1973227825Stheraven return (cpp_demangle_read_subst_stdtmpl(ddata, 1974227825Stheraven "std::string", 11)); 1975227825Stheraven return (1); 1976227825Stheraven 1977227825Stheraven case SIMPLE_HASH('S', 't'): 1978227825Stheraven /* std:: */ 1979227825Stheraven return (cpp_demangle_read_subst_std(ddata)); 1980227825Stheraven }; 1981227825Stheraven 1982227825Stheraven if (*(++ddata->cur) == '\0') 1983227825Stheraven return (0); 1984227825Stheraven 1985227825Stheraven /* substitution */ 1986227825Stheraven if (*ddata->cur == '_') 1987227825Stheraven return (cpp_demangle_get_subst(ddata, 0)); 1988227825Stheraven else { 1989227825Stheraven errno = 0; 1990227825Stheraven /* substitution number is base 36 */ 1991227825Stheraven if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && 1992227825Stheraven errno != 0) 1993227825Stheraven return (0); 1994227825Stheraven 1995227825Stheraven /* first was '_', so increase one */ 1996227825Stheraven ++nth; 1997227825Stheraven 1998227825Stheraven while (*ddata->cur != '_') 1999227825Stheraven ++ddata->cur; 2000227825Stheraven 2001227825Stheraven assert(nth > 0); 2002227825Stheraven 2003227825Stheraven return (cpp_demangle_get_subst(ddata, nth)); 2004227825Stheraven } 2005227825Stheraven 2006227825Stheraven /* NOTREACHED */ 2007227825Stheraven return (0); 2008227825Stheraven} 2009227825Stheraven 2010227825Stheravenstatic int 2011227825Stheravencpp_demangle_read_subst_std(struct cpp_demangle_data *ddata) 2012227825Stheraven{ 2013227825Stheraven struct vector_str *output, v; 2014227825Stheraven size_t p_idx, subst_str_len; 2015227825Stheraven int rtn; 2016227825Stheraven char *subst_str; 2017227825Stheraven 2018227825Stheraven if (ddata == NULL) 2019227825Stheraven return (0); 2020227825Stheraven 2021227825Stheraven if (!vector_str_init(&v)) 2022227825Stheraven return (0); 2023227825Stheraven 2024227825Stheraven subst_str = NULL; 2025227825Stheraven rtn = 0; 2026227825Stheraven if (!cpp_demangle_push_str(ddata, "std::", 5)) 2027227825Stheraven goto clean; 2028227825Stheraven 2029227825Stheraven if (!vector_str_push(&v, "std::", 5)) 2030227825Stheraven goto clean; 2031227825Stheraven 2032227825Stheraven ddata->cur += 2; 2033227825Stheraven 2034227825Stheraven output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; 2035227825Stheraven 2036227825Stheraven p_idx = output->size; 2037227825Stheraven if (!cpp_demangle_read_uqname(ddata)) 2038227825Stheraven goto clean; 2039227825Stheraven 2040227825Stheraven if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, 2041227825Stheraven &subst_str_len)) == NULL) 2042227825Stheraven goto clean; 2043227825Stheraven 2044227825Stheraven if (!vector_str_push(&v, subst_str, subst_str_len)) 2045227825Stheraven goto clean; 2046227825Stheraven 2047227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &v)) 2048227825Stheraven goto clean; 2049227825Stheraven 2050227825Stheraven if (*ddata->cur == 'I') { 2051227825Stheraven p_idx = output->size; 2052227825Stheraven if (!cpp_demangle_read_tmpl_args(ddata)) 2053227825Stheraven goto clean; 2054227825Stheraven free(subst_str); 2055227825Stheraven if ((subst_str = vector_str_substr(output, p_idx, 2056227825Stheraven output->size - 1, &subst_str_len)) == NULL) 2057227825Stheraven goto clean; 2058227825Stheraven if (!vector_str_push(&v, subst_str, subst_str_len)) 2059227825Stheraven goto clean; 2060227825Stheraven if (!cpp_demangle_push_subst_v(ddata, &v)) 2061227825Stheraven goto clean; 2062227825Stheraven } 2063227825Stheraven 2064227825Stheraven rtn = 1; 2065227825Stheravenclean: 2066227825Stheraven free(subst_str); 2067227825Stheraven vector_str_dest(&v); 2068227825Stheraven 2069255815Stheraven return (rtn); 2070227825Stheraven} 2071227825Stheraven 2072227825Stheravenstatic int 2073227825Stheravencpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata, 2074227825Stheraven const char *str, size_t len) 2075227825Stheraven{ 2076227825Stheraven struct vector_str *output; 2077227825Stheraven size_t p_idx, substr_len; 2078227825Stheraven int rtn; 2079227825Stheraven char *subst_str, *substr; 2080227825Stheraven 2081227825Stheraven if (ddata == NULL || str == NULL || len == 0) 2082227825Stheraven return (0); 2083227825Stheraven 2084227825Stheraven output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; 2085227825Stheraven 2086227825Stheraven p_idx = output->size; 2087227825Stheraven substr = NULL; 2088227825Stheraven subst_str = NULL; 2089227825Stheraven 2090227825Stheraven if (!cpp_demangle_read_tmpl_args(ddata)) 2091227825Stheraven return (0); 2092227825Stheraven if ((substr = vector_str_substr(output, p_idx, output->size - 1, 2093227825Stheraven &substr_len)) == NULL) 2094227825Stheraven return (0); 2095227825Stheraven 2096227825Stheraven rtn = 0; 2097227825Stheraven if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) == 2098227825Stheraven NULL) 2099227825Stheraven goto clean; 2100227825Stheraven 2101227825Stheraven memcpy(subst_str, str, len); 2102227825Stheraven memcpy(subst_str + len, substr, substr_len); 2103227825Stheraven subst_str[substr_len + len] = '\0'; 2104227825Stheraven 2105227825Stheraven if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len)) 2106227825Stheraven goto clean; 2107227825Stheraven 2108227825Stheraven rtn = 1; 2109227825Stheravenclean: 2110227825Stheraven free(subst_str); 2111227825Stheraven free(substr); 2112227825Stheraven 2113227825Stheraven return (rtn); 2114227825Stheraven} 2115227825Stheraven 2116227825Stheravenstatic int 2117227825Stheravencpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata) 2118227825Stheraven{ 2119227825Stheraven 2120227825Stheraven if (ddata == NULL || *ddata->cur == '\0') 2121227825Stheraven return (0); 2122227825Stheraven 2123227825Stheraven switch (*ddata->cur) { 2124227825Stheraven case 'L': 2125227825Stheraven return (cpp_demangle_read_expr_primary(ddata)); 2126227825Stheraven case 'X': 2127227825Stheraven return (cpp_demangle_read_expression(ddata)); 2128227825Stheraven }; 2129227825Stheraven 2130227825Stheraven return (cpp_demangle_read_type(ddata, 0)); 2131227825Stheraven} 2132227825Stheraven 2133227825Stheravenstatic int 2134227825Stheravencpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata) 2135227825Stheraven{ 2136227825Stheraven struct vector_str *v; 2137227825Stheraven size_t arg_len, idx, limit, size; 2138227825Stheraven char *arg; 2139227825Stheraven 2140227825Stheraven if (ddata == NULL || *ddata->cur == '\0') 2141227825Stheraven return (0); 2142227825Stheraven 2143227825Stheraven ++ddata->cur; 2144227825Stheraven 2145227825Stheraven if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL)) 2146227825Stheraven return (0); 2147227825Stheraven 2148227825Stheraven if (!cpp_demangle_push_str(ddata, "<", 1)) 2149227825Stheraven return (0); 2150227825Stheraven 2151227825Stheraven limit = 0; 2152227825Stheraven v = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; 2153227825Stheraven for (;;) { 2154227825Stheraven idx = v->size; 2155227825Stheraven if (!cpp_demangle_read_tmpl_arg(ddata)) 2156227825Stheraven return (0); 2157227825Stheraven if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) == 2158227825Stheraven NULL) 2159227825Stheraven return (0); 2160227825Stheraven if (!vector_str_find(&ddata->tmpl, arg, arg_len) && 2161227825Stheraven !vector_str_push(&ddata->tmpl, arg, arg_len)) { 2162227825Stheraven free(arg); 2163227825Stheraven return (0); 2164227825Stheraven } 2165227825Stheraven 2166227825Stheraven free(arg); 2167227825Stheraven 2168227825Stheraven if (*ddata->cur == 'E') { 2169227825Stheraven ++ddata->cur; 2170227825Stheraven size = v->size; 2171227825Stheraven assert(size > 0); 2172227825Stheraven if (!strncmp(v->container[size - 1], ">", 1)) { 2173227825Stheraven if (!cpp_demangle_push_str(ddata, " >", 2)) 2174227825Stheraven return (0); 2175227825Stheraven } else if (!cpp_demangle_push_str(ddata, ">", 1)) 2176227825Stheraven return (0); 2177227825Stheraven break; 2178227825Stheraven } else if (*ddata->cur != 'I' && 2179227825Stheraven !cpp_demangle_push_str(ddata, ", ", 2)) 2180227825Stheraven return (0); 2181227825Stheraven 2182227825Stheraven if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 2183227825Stheraven return (0); 2184227825Stheraven } 2185227825Stheraven 2186227825Stheraven return (vector_read_cmd_pop(&ddata->cmd)); 2187227825Stheraven} 2188227825Stheraven 2189227825Stheraven/* 2190227825Stheraven * Read template parameter that forms in 'T[number]_'. 2191227825Stheraven * This function much like to read_subst but only for types. 2192227825Stheraven */ 2193227825Stheravenstatic int 2194227825Stheravencpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata) 2195227825Stheraven{ 2196227825Stheraven long nth; 2197227825Stheraven 2198227825Stheraven if (ddata == NULL || *ddata->cur != 'T') 2199227825Stheraven return (0); 2200227825Stheraven 2201227825Stheraven ++ddata->cur; 2202227825Stheraven 2203227825Stheraven if (*ddata->cur == '_') 2204227825Stheraven return (cpp_demangle_get_tmpl_param(ddata, 0)); 2205227825Stheraven else { 2206227825Stheraven 2207227825Stheraven errno = 0; 2208227825Stheraven if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && 2209227825Stheraven errno != 0) 2210227825Stheraven return (0); 2211227825Stheraven 2212227825Stheraven /* T_ is first */ 2213227825Stheraven ++nth; 2214227825Stheraven 2215227825Stheraven while (*ddata->cur != '_') 2216227825Stheraven ++ddata->cur; 2217227825Stheraven 2218227825Stheraven assert(nth > 0); 2219227825Stheraven 2220227825Stheraven return (cpp_demangle_get_tmpl_param(ddata, nth)); 2221227825Stheraven } 2222227825Stheraven 2223227825Stheraven /* NOTREACHED */ 2224227825Stheraven return (0); 2225227825Stheraven} 2226227825Stheraven 2227227825Stheravenstatic int 2228227825Stheravencpp_demangle_read_type(struct cpp_demangle_data *ddata, int delimit) 2229227825Stheraven{ 2230227825Stheraven struct vector_type_qualifier v; 2231227825Stheraven struct vector_str *output; 2232227825Stheraven size_t p_idx, type_str_len; 2233227825Stheraven int extern_c, is_builtin; 2234227825Stheraven long len; 2235227825Stheraven char *type_str; 2236227825Stheraven 2237227825Stheraven if (ddata == NULL) 2238227825Stheraven return (0); 2239227825Stheraven 2240227825Stheraven output = &ddata->output; 2241227825Stheraven if (ddata->output.size > 0 && !strncmp(ddata->output.container[ddata->output.size - 1], ">", 1)) { 2242227825Stheraven ddata->push_head++; 2243227825Stheraven output = &ddata->output_tmp; 2244227825Stheraven } else if (delimit == 1) { 2245227825Stheraven if (ddata->paren == false) { 2246227825Stheraven if (!cpp_demangle_push_str(ddata, "(", 1)) 2247227825Stheraven return (0); 2248227825Stheraven if (ddata->output.size < 2) 2249227825Stheraven return (0); 2250227825Stheraven ddata->paren = true; 2251227825Stheraven ddata->pfirst = true; 2252227825Stheraven /* Need pop function name */ 2253227825Stheraven if (ddata->subst.size == 1 && 2254227825Stheraven !vector_str_pop(&ddata->subst)) 2255227825Stheraven return (0); 2256227825Stheraven } 2257227825Stheraven 2258227825Stheraven if (ddata->pfirst) 2259227825Stheraven ddata->pfirst = false; 2260227825Stheraven else if (*ddata->cur != 'I' && 2261227825Stheraven !cpp_demangle_push_str(ddata, ", ", 2)) 2262227825Stheraven return (0); 2263227825Stheraven } 2264227825Stheraven 2265227825Stheraven assert(output != NULL); 2266227825Stheraven /* 2267227825Stheraven * [r, V, K] [P, R, C, G, U] builtin, function, class-enum, array 2268227825Stheraven * pointer-to-member, template-param, template-template-param, subst 2269227825Stheraven */ 2270227825Stheraven 2271227825Stheraven if (!vector_type_qualifier_init(&v)) 2272227825Stheraven return (0); 2273227825Stheraven 2274227825Stheraven extern_c = 0; 2275227825Stheraven is_builtin = 1; 2276227825Stheraven p_idx = output->size; 2277227825Stheraven type_str = NULL; 2278227825Stheravenagain: 2279227825Stheraven /* builtin type */ 2280227825Stheraven switch (*ddata->cur) { 2281227825Stheraven case 'a': 2282227825Stheraven /* signed char */ 2283227825Stheraven if (!cpp_demangle_push_str(ddata, "signed char", 11)) 2284227825Stheraven goto clean; 2285227825Stheraven ++ddata->cur; 2286227825Stheraven goto rtn; 2287227825Stheraven 2288227825Stheraven case 'A': 2289227825Stheraven /* array type */ 2290227825Stheraven if (!cpp_demangle_read_array(ddata)) 2291227825Stheraven goto clean; 2292227825Stheraven is_builtin = 0; 2293227825Stheraven goto rtn; 2294227825Stheraven 2295227825Stheraven case 'b': 2296227825Stheraven /* bool */ 2297227825Stheraven if (!cpp_demangle_push_str(ddata, "bool", 4)) 2298227825Stheraven goto clean; 2299227825Stheraven ++ddata->cur; 2300227825Stheraven goto rtn; 2301227825Stheraven 2302227825Stheraven case 'C': 2303227825Stheraven /* complex pair */ 2304227825Stheraven if (!vector_type_qualifier_push(&v, TYPE_CMX)) 2305227825Stheraven goto clean; 2306227825Stheraven ++ddata->cur; 2307227825Stheraven goto again; 2308227825Stheraven 2309227825Stheraven case 'c': 2310227825Stheraven /* char */ 2311227825Stheraven if (!cpp_demangle_push_str(ddata, "char", 4)) 2312227825Stheraven goto clean; 2313227825Stheraven ++ddata->cur; 2314227825Stheraven goto rtn; 2315227825Stheraven 2316227825Stheraven case 'd': 2317227825Stheraven /* double */ 2318227825Stheraven if (!cpp_demangle_push_str(ddata, "double", 6)) 2319227825Stheraven goto clean; 2320227825Stheraven ++ddata->cur; 2321227825Stheraven goto rtn; 2322227825Stheraven 2323227825Stheraven case 'e': 2324227825Stheraven /* long double */ 2325227825Stheraven if (!cpp_demangle_push_str(ddata, "long double", 11)) 2326227825Stheraven goto clean; 2327227825Stheraven ++ddata->cur; 2328227825Stheraven goto rtn; 2329227825Stheraven 2330227825Stheraven case 'f': 2331227825Stheraven /* float */ 2332227825Stheraven if (!cpp_demangle_push_str(ddata, "float", 5)) 2333227825Stheraven goto clean; 2334227825Stheraven ++ddata->cur; 2335227825Stheraven goto rtn; 2336227825Stheraven 2337227825Stheraven case 'F': 2338227825Stheraven /* function */ 2339227825Stheraven if (!cpp_demangle_read_function(ddata, &extern_c, &v)) 2340227825Stheraven goto clean; 2341227825Stheraven is_builtin = 0; 2342227825Stheraven goto rtn; 2343227825Stheraven 2344227825Stheraven case 'g': 2345227825Stheraven /* __float128 */ 2346227825Stheraven if (!cpp_demangle_push_str(ddata, "__float128", 10)) 2347227825Stheraven goto clean; 2348227825Stheraven ++ddata->cur; 2349227825Stheraven goto rtn; 2350227825Stheraven 2351227825Stheraven case 'G': 2352227825Stheraven /* imaginary */ 2353227825Stheraven if (!vector_type_qualifier_push(&v, TYPE_IMG)) 2354227825Stheraven goto clean; 2355227825Stheraven ++ddata->cur; 2356227825Stheraven goto again; 2357227825Stheraven 2358227825Stheraven case 'h': 2359227825Stheraven /* unsigned char */ 2360227825Stheraven if (!cpp_demangle_push_str(ddata, "unsigned char", 13)) 2361227825Stheraven goto clean; 2362227825Stheraven ++ddata->cur; 2363227825Stheraven goto rtn; 2364227825Stheraven 2365227825Stheraven case 'i': 2366227825Stheraven /* int */ 2367227825Stheraven if (!cpp_demangle_push_str(ddata, "int", 3)) 2368227825Stheraven goto clean; 2369227825Stheraven ++ddata->cur; 2370227825Stheraven goto rtn; 2371227825Stheraven 2372227825Stheraven case 'j': 2373227825Stheraven /* unsigned int */ 2374227825Stheraven if (!cpp_demangle_push_str(ddata, "unsigned int", 12)) 2375227825Stheraven goto clean; 2376227825Stheraven ++ddata->cur; 2377227825Stheraven goto rtn; 2378227825Stheraven 2379227825Stheraven case 'K': 2380227825Stheraven /* const */ 2381227825Stheraven if (!vector_type_qualifier_push(&v, TYPE_CST)) 2382227825Stheraven goto clean; 2383227825Stheraven ++ddata->cur; 2384227825Stheraven goto again; 2385227825Stheraven 2386227825Stheraven case 'l': 2387227825Stheraven /* long */ 2388227825Stheraven if (!cpp_demangle_push_str(ddata, "long", 4)) 2389227825Stheraven goto clean; 2390227825Stheraven ++ddata->cur; 2391227825Stheraven goto rtn; 2392227825Stheraven 2393227825Stheraven case 'm': 2394227825Stheraven /* unsigned long */ 2395227825Stheraven if (!cpp_demangle_push_str(ddata, "unsigned long", 13)) 2396227825Stheraven goto clean; 2397227825Stheraven 2398227825Stheraven ++ddata->cur; 2399227825Stheraven 2400227825Stheraven goto rtn; 2401227825Stheraven case 'M': 2402227825Stheraven /* pointer to member */ 2403227825Stheraven if (!cpp_demangle_read_pointer_to_member(ddata)) 2404227825Stheraven goto clean; 2405227825Stheraven is_builtin = 0; 2406227825Stheraven goto rtn; 2407227825Stheraven 2408227825Stheraven case 'n': 2409227825Stheraven /* __int128 */ 2410227825Stheraven if (!cpp_demangle_push_str(ddata, "__int128", 8)) 2411227825Stheraven goto clean; 2412227825Stheraven ++ddata->cur; 2413227825Stheraven goto rtn; 2414227825Stheraven 2415227825Stheraven case 'o': 2416227825Stheraven /* unsigned __int128 */ 2417227825Stheraven if (!cpp_demangle_push_str(ddata, "unsigned _;int128", 17)) 2418227825Stheraven goto clean; 2419227825Stheraven ++ddata->cur; 2420227825Stheraven goto rtn; 2421227825Stheraven 2422227825Stheraven case 'P': 2423227825Stheraven /* pointer */ 2424227825Stheraven if (!vector_type_qualifier_push(&v, TYPE_PTR)) 2425227825Stheraven goto clean; 2426227825Stheraven ++ddata->cur; 2427227825Stheraven goto again; 2428227825Stheraven 2429227825Stheraven case 'r': 2430227825Stheraven /* restrict */ 2431227825Stheraven if (!vector_type_qualifier_push(&v, TYPE_RST)) 2432227825Stheraven goto clean; 2433227825Stheraven ++ddata->cur; 2434227825Stheraven goto again; 2435227825Stheraven 2436227825Stheraven case 'R': 2437227825Stheraven /* reference */ 2438227825Stheraven if (!vector_type_qualifier_push(&v, TYPE_REF)) 2439227825Stheraven goto clean; 2440227825Stheraven ++ddata->cur; 2441227825Stheraven goto again; 2442227825Stheraven 2443227825Stheraven case 's': 2444227825Stheraven /* short, local string */ 2445227825Stheraven if (!cpp_demangle_push_str(ddata, "short", 5)) 2446227825Stheraven goto clean; 2447227825Stheraven ++ddata->cur; 2448227825Stheraven goto rtn; 2449227825Stheraven 2450227825Stheraven case 'S': 2451227825Stheraven /* substitution */ 2452227825Stheraven if (!cpp_demangle_read_subst(ddata)) 2453227825Stheraven goto clean; 2454227825Stheraven is_builtin = 0; 2455227825Stheraven goto rtn; 2456227825Stheraven 2457227825Stheraven case 't': 2458227825Stheraven /* unsigned short */ 2459227825Stheraven if (!cpp_demangle_push_str(ddata, "unsigned short", 14)) 2460227825Stheraven goto clean; 2461227825Stheraven ++ddata->cur; 2462227825Stheraven goto rtn; 2463227825Stheraven 2464227825Stheraven case 'T': 2465227825Stheraven /* template parameter */ 2466227825Stheraven if (!cpp_demangle_read_tmpl_param(ddata)) 2467227825Stheraven goto clean; 2468227825Stheraven is_builtin = 0; 2469227825Stheraven goto rtn; 2470227825Stheraven 2471227825Stheraven case 'u': 2472227825Stheraven /* vendor extended builtin */ 2473227825Stheraven ++ddata->cur; 2474227825Stheraven if (!cpp_demangle_read_sname(ddata)) 2475227825Stheraven goto clean; 2476227825Stheraven is_builtin = 0; 2477227825Stheraven goto rtn; 2478227825Stheraven 2479227825Stheraven case 'U': 2480227825Stheraven /* vendor extended type qualifier */ 2481227825Stheraven if (!cpp_demangle_read_number(ddata, &len)) 2482227825Stheraven goto clean; 2483227825Stheraven if (len <= 0) 2484227825Stheraven goto clean; 2485227825Stheraven if (!vector_str_push(&v.ext_name, ddata->cur, len)) 2486227825Stheraven return (0); 2487227825Stheraven ddata->cur += len; 2488227825Stheraven goto again; 2489227825Stheraven 2490227825Stheraven case 'v': 2491227825Stheraven /* void */ 2492227825Stheraven if (!cpp_demangle_push_str(ddata, "void", 4)) 2493227825Stheraven goto clean; 2494227825Stheraven ++ddata->cur; 2495227825Stheraven goto rtn; 2496227825Stheraven 2497227825Stheraven case 'V': 2498227825Stheraven /* volatile */ 2499227825Stheraven if (!vector_type_qualifier_push(&v, TYPE_VAT)) 2500227825Stheraven goto clean; 2501227825Stheraven ++ddata->cur; 2502227825Stheraven goto again; 2503227825Stheraven 2504227825Stheraven case 'w': 2505227825Stheraven /* wchar_t */ 2506227825Stheraven if (!cpp_demangle_push_str(ddata, "wchar_t", 6)) 2507227825Stheraven goto clean; 2508227825Stheraven ++ddata->cur; 2509227825Stheraven goto rtn; 2510227825Stheraven 2511227825Stheraven case 'x': 2512227825Stheraven /* long long */ 2513227825Stheraven if (!cpp_demangle_push_str(ddata, "long long", 9)) 2514227825Stheraven goto clean; 2515227825Stheraven ++ddata->cur; 2516227825Stheraven goto rtn; 2517227825Stheraven 2518227825Stheraven case 'y': 2519227825Stheraven /* unsigned long long */ 2520227825Stheraven if (!cpp_demangle_push_str(ddata, "unsigned long long", 18)) 2521227825Stheraven goto clean; 2522227825Stheraven ++ddata->cur; 2523227825Stheraven goto rtn; 2524227825Stheraven 2525227825Stheraven case 'z': 2526227825Stheraven /* ellipsis */ 2527227825Stheraven if (!cpp_demangle_push_str(ddata, "ellipsis", 8)) 2528227825Stheraven goto clean; 2529227825Stheraven ++ddata->cur; 2530227825Stheraven goto rtn; 2531227825Stheraven }; 2532227825Stheraven 2533227825Stheraven if (!cpp_demangle_read_name(ddata)) 2534227825Stheraven goto clean; 2535227825Stheraven 2536227825Stheraven is_builtin = 0; 2537227825Stheravenrtn: 2538227825Stheraven if ((type_str = vector_str_substr(output, p_idx, output->size - 1, 2539227825Stheraven &type_str_len)) == NULL) 2540227825Stheraven goto clean; 2541227825Stheraven 2542227825Stheraven if (is_builtin == 0) { 2543227825Stheraven if (!vector_str_find(&ddata->subst, type_str, type_str_len) && 2544227825Stheraven !vector_str_push(&ddata->subst, type_str, type_str_len)) 2545227825Stheraven goto clean; 2546227825Stheraven } 2547227825Stheraven 2548227825Stheraven if (!cpp_demangle_push_type_qualifier(ddata, &v, type_str)) 2549227825Stheraven goto clean; 2550227825Stheraven 2551227825Stheraven free(type_str); 2552227825Stheraven vector_type_qualifier_dest(&v); 2553227825Stheraven 2554227825Stheraven if (ddata->push_head > 0) { 2555227825Stheraven if (*ddata->cur == 'I' && cpp_demangle_read_tmpl_args(ddata) 2556227825Stheraven == 0) 2557227825Stheraven return (0); 2558227825Stheraven 2559227825Stheraven if (--ddata->push_head > 0) 2560227825Stheraven return (1); 2561227825Stheraven 2562227825Stheraven if (!vector_str_push(&ddata->output_tmp, " ", 1)) 2563227825Stheraven return (0); 2564227825Stheraven 2565227825Stheraven if (!vector_str_push_vector_head(&ddata->output, 2566227825Stheraven &ddata->output_tmp)) 2567227825Stheraven return (0); 2568227825Stheraven 2569227825Stheraven vector_str_dest(&ddata->output_tmp); 2570227825Stheraven if (!vector_str_init(&ddata->output_tmp)) 2571227825Stheraven return (0); 2572227825Stheraven 2573227825Stheraven if (!cpp_demangle_push_str(ddata, "(", 1)) 2574227825Stheraven return (0); 2575227825Stheraven 2576227825Stheraven ddata->paren = true; 2577227825Stheraven ddata->pfirst = true; 2578227825Stheraven } 2579227825Stheraven 2580227825Stheraven return (1); 2581227825Stheravenclean: 2582227825Stheraven free(type_str); 2583227825Stheraven vector_type_qualifier_dest(&v); 2584227825Stheraven 2585227825Stheraven return (0); 2586227825Stheraven} 2587227825Stheraven 2588227825Stheraven/* 2589227825Stheraven * read unqualified-name, unqualified name are operator-name, ctor-dtor-name, 2590227825Stheraven * source-name 2591227825Stheraven */ 2592227825Stheravenstatic int 2593227825Stheravencpp_demangle_read_uqname(struct cpp_demangle_data *ddata) 2594227825Stheraven{ 2595227825Stheraven size_t len; 2596227825Stheraven 2597227825Stheraven if (ddata == NULL || *ddata->cur == '\0') 2598227825Stheraven return (0); 2599227825Stheraven 2600227825Stheraven /* operator name */ 2601227825Stheraven switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 2602227825Stheraven case SIMPLE_HASH('a', 'a'): 2603227825Stheraven /* operator && */ 2604227825Stheraven if (!cpp_demangle_push_str(ddata, "operator&&", 10)) 2605227825Stheraven return (0); 2606227825Stheraven ddata->cur += 2; 2607227825Stheraven return (1); 2608227825Stheraven 2609227825Stheraven case SIMPLE_HASH('a', 'd'): 2610227825Stheraven /* operator & (unary) */ 2611227825Stheraven if (!cpp_demangle_push_str(ddata, "operator&", 9)) 2612227825Stheraven return (0); 2613227825Stheraven ddata->cur += 2; 2614227825Stheraven return (1); 2615227825Stheraven 2616227825Stheraven case SIMPLE_HASH('a', 'n'): 2617227825Stheraven /* operator & */ 2618227825Stheraven if (!cpp_demangle_push_str(ddata, "operator&", 9)) 2619227825Stheraven return (0); 2620227825Stheraven ddata->cur += 2; 2621227825Stheraven return (1); 2622227825Stheraven 2623227825Stheraven case SIMPLE_HASH('a', 'N'): 2624227825Stheraven /* operator &= */ 2625227825Stheraven if (!cpp_demangle_push_str(ddata, "operator&=", 10)) 2626227825Stheraven return (0); 2627227825Stheraven ddata->cur += 2; 2628227825Stheraven return (1); 2629227825Stheraven 2630227825Stheraven case SIMPLE_HASH('a', 'S'): 2631227825Stheraven /* operator = */ 2632227825Stheraven if (!cpp_demangle_push_str(ddata, "operator=", 9)) 2633227825Stheraven return (0); 2634227825Stheraven ddata->cur += 2; 2635227825Stheraven return (1); 2636227825Stheraven 2637227825Stheraven case SIMPLE_HASH('c', 'l'): 2638227825Stheraven /* operator () */ 2639227825Stheraven if (!cpp_demangle_push_str(ddata, "operator()", 10)) 2640227825Stheraven return (0); 2641227825Stheraven ddata->cur += 2; 2642227825Stheraven return (1); 2643227825Stheraven 2644227825Stheraven case SIMPLE_HASH('c', 'm'): 2645227825Stheraven /* operator , */ 2646227825Stheraven if (!cpp_demangle_push_str(ddata, "operator,", 9)) 2647227825Stheraven return (0); 2648227825Stheraven ddata->cur += 2; 2649227825Stheraven return (1); 2650227825Stheraven 2651227825Stheraven case SIMPLE_HASH('c', 'o'): 2652227825Stheraven /* operator ~ */ 2653227825Stheraven if (!cpp_demangle_push_str(ddata, "operator~", 9)) 2654227825Stheraven return (0); 2655227825Stheraven ddata->cur += 2; 2656227825Stheraven return (1); 2657227825Stheraven 2658227825Stheraven case SIMPLE_HASH('c', 'v'): 2659227825Stheraven /* operator (cast) */ 2660227825Stheraven if (!cpp_demangle_push_str(ddata, "operator(cast)", 14)) 2661227825Stheraven return (0); 2662227825Stheraven ddata->cur += 2; 2663227825Stheraven return (cpp_demangle_read_type(ddata, 1)); 2664227825Stheraven 2665227825Stheraven case SIMPLE_HASH('d', 'a'): 2666227825Stheraven /* operator delete [] */ 2667227825Stheraven if (!cpp_demangle_push_str(ddata, "operator delete []", 18)) 2668227825Stheraven return (0); 2669227825Stheraven ddata->cur += 2; 2670227825Stheraven return (1); 2671227825Stheraven 2672227825Stheraven case SIMPLE_HASH('d', 'e'): 2673227825Stheraven /* operator * (unary) */ 2674227825Stheraven if (!cpp_demangle_push_str(ddata, "operator*", 9)) 2675227825Stheraven return (0); 2676227825Stheraven ddata->cur += 2; 2677227825Stheraven return (1); 2678227825Stheraven 2679227825Stheraven case SIMPLE_HASH('d', 'l'): 2680227825Stheraven /* operator delete */ 2681227825Stheraven if (!cpp_demangle_push_str(ddata, "operator delete", 15)) 2682227825Stheraven return (0); 2683227825Stheraven ddata->cur += 2; 2684227825Stheraven return (1); 2685227825Stheraven 2686227825Stheraven case SIMPLE_HASH('d', 'v'): 2687227825Stheraven /* operator / */ 2688227825Stheraven if (!cpp_demangle_push_str(ddata, "operator/", 9)) 2689227825Stheraven return (0); 2690227825Stheraven ddata->cur += 2; 2691227825Stheraven return (1); 2692227825Stheraven 2693227825Stheraven case SIMPLE_HASH('d', 'V'): 2694227825Stheraven /* operator /= */ 2695227825Stheraven if (!cpp_demangle_push_str(ddata, "operator/=", 10)) 2696227825Stheraven return (0); 2697227825Stheraven ddata->cur += 2; 2698227825Stheraven return (1); 2699227825Stheraven 2700227825Stheraven case SIMPLE_HASH('e', 'o'): 2701227825Stheraven /* operator ^ */ 2702227825Stheraven if (!cpp_demangle_push_str(ddata, "operator^", 9)) 2703227825Stheraven return (0); 2704227825Stheraven ddata->cur += 2; 2705227825Stheraven return (1); 2706227825Stheraven 2707227825Stheraven case SIMPLE_HASH('e', 'O'): 2708227825Stheraven /* operator ^= */ 2709227825Stheraven if (!cpp_demangle_push_str(ddata, "operator^=", 10)) 2710227825Stheraven return (0); 2711227825Stheraven ddata->cur += 2; 2712227825Stheraven return (1); 2713227825Stheraven 2714227825Stheraven case SIMPLE_HASH('e', 'q'): 2715227825Stheraven /* operator == */ 2716227825Stheraven if (!cpp_demangle_push_str(ddata, "operator==", 10)) 2717227825Stheraven return (0); 2718227825Stheraven ddata->cur += 2; 2719227825Stheraven return (1); 2720227825Stheraven 2721227825Stheraven case SIMPLE_HASH('g', 'e'): 2722227825Stheraven /* operator >= */ 2723227825Stheraven if (!cpp_demangle_push_str(ddata, "operator>=", 10)) 2724227825Stheraven return (0); 2725227825Stheraven ddata->cur += 2; 2726227825Stheraven return (1); 2727227825Stheraven 2728227825Stheraven case SIMPLE_HASH('g', 't'): 2729227825Stheraven /* operator > */ 2730227825Stheraven if (!cpp_demangle_push_str(ddata, "operator>", 9)) 2731227825Stheraven return (0); 2732227825Stheraven ddata->cur += 2; 2733227825Stheraven return (1); 2734227825Stheraven 2735227825Stheraven case SIMPLE_HASH('i', 'x'): 2736227825Stheraven /* operator [] */ 2737227825Stheraven if (!cpp_demangle_push_str(ddata, "operator[]", 10)) 2738227825Stheraven return (0); 2739227825Stheraven ddata->cur += 2; 2740227825Stheraven return (1); 2741227825Stheraven 2742227825Stheraven case SIMPLE_HASH('l', 'e'): 2743227825Stheraven /* operator <= */ 2744227825Stheraven if (!cpp_demangle_push_str(ddata, "operator<=", 10)) 2745227825Stheraven return (0); 2746227825Stheraven ddata->cur += 2; 2747227825Stheraven return (1); 2748227825Stheraven 2749227825Stheraven case SIMPLE_HASH('l', 's'): 2750227825Stheraven /* operator << */ 2751227825Stheraven if (!cpp_demangle_push_str(ddata, "operator<<", 10)) 2752227825Stheraven return (0); 2753227825Stheraven ddata->cur += 2; 2754227825Stheraven return (1); 2755227825Stheraven 2756227825Stheraven case SIMPLE_HASH('l', 'S'): 2757227825Stheraven /* operator <<= */ 2758227825Stheraven if (!cpp_demangle_push_str(ddata, "operator<<=", 11)) 2759227825Stheraven return (0); 2760227825Stheraven ddata->cur += 2; 2761227825Stheraven return (1); 2762227825Stheraven 2763227825Stheraven case SIMPLE_HASH('l', 't'): 2764227825Stheraven /* operator < */ 2765227825Stheraven if (!cpp_demangle_push_str(ddata, "operator<", 9)) 2766227825Stheraven return (0); 2767227825Stheraven ddata->cur += 2; 2768227825Stheraven return (1); 2769227825Stheraven 2770227825Stheraven case SIMPLE_HASH('m', 'i'): 2771227825Stheraven /* operator - */ 2772227825Stheraven if (!cpp_demangle_push_str(ddata, "operator-", 9)) 2773227825Stheraven return (0); 2774227825Stheraven ddata->cur += 2; 2775227825Stheraven return (1); 2776227825Stheraven 2777227825Stheraven case SIMPLE_HASH('m', 'I'): 2778227825Stheraven /* operator -= */ 2779227825Stheraven if (!cpp_demangle_push_str(ddata, "operator-=", 10)) 2780227825Stheraven return (0); 2781227825Stheraven ddata->cur += 2; 2782227825Stheraven return (1); 2783227825Stheraven 2784227825Stheraven case SIMPLE_HASH('m', 'l'): 2785227825Stheraven /* operator * */ 2786227825Stheraven if (!cpp_demangle_push_str(ddata, "operator*", 9)) 2787227825Stheraven return (0); 2788227825Stheraven ddata->cur += 2; 2789227825Stheraven return (1); 2790227825Stheraven 2791227825Stheraven case SIMPLE_HASH('m', 'L'): 2792227825Stheraven /* operator *= */ 2793227825Stheraven if (!cpp_demangle_push_str(ddata, "operator*=", 10)) 2794227825Stheraven return (0); 2795227825Stheraven ddata->cur += 2; 2796227825Stheraven return (1); 2797227825Stheraven 2798227825Stheraven case SIMPLE_HASH('m', 'm'): 2799227825Stheraven /* operator -- */ 2800227825Stheraven if (!cpp_demangle_push_str(ddata, "operator--", 10)) 2801227825Stheraven return (0); 2802227825Stheraven ddata->cur += 2; 2803227825Stheraven return (1); 2804227825Stheraven 2805227825Stheraven case SIMPLE_HASH('n', 'a'): 2806227825Stheraven /* operator new[] */ 2807227825Stheraven if (!cpp_demangle_push_str(ddata, "operator new []", 15)) 2808227825Stheraven return (0); 2809227825Stheraven ddata->cur += 2; 2810227825Stheraven return (1); 2811227825Stheraven 2812227825Stheraven case SIMPLE_HASH('n', 'e'): 2813227825Stheraven /* operator != */ 2814227825Stheraven if (!cpp_demangle_push_str(ddata, "operator!=", 10)) 2815227825Stheraven return (0); 2816227825Stheraven ddata->cur += 2; 2817227825Stheraven return (1); 2818227825Stheraven 2819227825Stheraven case SIMPLE_HASH('n', 'g'): 2820227825Stheraven /* operator - (unary) */ 2821227825Stheraven if (!cpp_demangle_push_str(ddata, "operator-", 9)) 2822227825Stheraven return (0); 2823227825Stheraven ddata->cur += 2; 2824227825Stheraven return (1); 2825227825Stheraven 2826227825Stheraven case SIMPLE_HASH('n', 't'): 2827227825Stheraven /* operator ! */ 2828227825Stheraven if (!cpp_demangle_push_str(ddata, "operator!", 9)) 2829227825Stheraven return (0); 2830227825Stheraven ddata->cur += 2; 2831227825Stheraven return (1); 2832227825Stheraven 2833227825Stheraven case SIMPLE_HASH('n', 'w'): 2834227825Stheraven /* operator new */ 2835227825Stheraven if (!cpp_demangle_push_str(ddata, "operator new", 12)) 2836227825Stheraven return (0); 2837227825Stheraven ddata->cur += 2; 2838227825Stheraven return (1); 2839227825Stheraven 2840227825Stheraven case SIMPLE_HASH('o', 'o'): 2841227825Stheraven /* operator || */ 2842227825Stheraven if (!cpp_demangle_push_str(ddata, "operator||", 10)) 2843227825Stheraven return (0); 2844227825Stheraven ddata->cur += 2; 2845227825Stheraven return (1); 2846227825Stheraven 2847227825Stheraven case SIMPLE_HASH('o', 'r'): 2848227825Stheraven /* operator | */ 2849227825Stheraven if (!cpp_demangle_push_str(ddata, "operator|", 9)) 2850227825Stheraven return (0); 2851227825Stheraven ddata->cur += 2; 2852227825Stheraven return (1); 2853227825Stheraven 2854227825Stheraven case SIMPLE_HASH('o', 'R'): 2855227825Stheraven /* operator |= */ 2856227825Stheraven if (!cpp_demangle_push_str(ddata, "operator|=", 10)) 2857227825Stheraven return (0); 2858227825Stheraven ddata->cur += 2; 2859227825Stheraven return (1); 2860227825Stheraven 2861227825Stheraven case SIMPLE_HASH('p', 'l'): 2862227825Stheraven /* operator + */ 2863227825Stheraven if (!cpp_demangle_push_str(ddata, "operator+", 9)) 2864227825Stheraven return (0); 2865227825Stheraven ddata->cur += 2; 2866227825Stheraven return (1); 2867227825Stheraven 2868227825Stheraven case SIMPLE_HASH('p', 'L'): 2869227825Stheraven /* operator += */ 2870227825Stheraven if (!cpp_demangle_push_str(ddata, "operator+=", 10)) 2871227825Stheraven return (0); 2872227825Stheraven ddata->cur += 2; 2873227825Stheraven return (1); 2874227825Stheraven 2875227825Stheraven case SIMPLE_HASH('p', 'm'): 2876227825Stheraven /* operator ->* */ 2877227825Stheraven if (!cpp_demangle_push_str(ddata, "operator->*", 11)) 2878227825Stheraven return (0); 2879227825Stheraven ddata->cur += 2; 2880227825Stheraven return (1); 2881227825Stheraven 2882227825Stheraven case SIMPLE_HASH('p', 'p'): 2883227825Stheraven /* operator ++ */ 2884227825Stheraven if (!cpp_demangle_push_str(ddata, "operator++", 10)) 2885227825Stheraven return (0); 2886227825Stheraven ddata->cur += 2; 2887227825Stheraven return (1); 2888227825Stheraven 2889227825Stheraven case SIMPLE_HASH('p', 's'): 2890227825Stheraven /* operator + (unary) */ 2891227825Stheraven if (!cpp_demangle_push_str(ddata, "operator+", 9)) 2892227825Stheraven return (0); 2893227825Stheraven ddata->cur += 2; 2894227825Stheraven return (1); 2895227825Stheraven 2896227825Stheraven case SIMPLE_HASH('p', 't'): 2897227825Stheraven /* operator -> */ 2898227825Stheraven if (!cpp_demangle_push_str(ddata, "operator->", 10)) 2899227825Stheraven return (0); 2900227825Stheraven ddata->cur += 2; 2901227825Stheraven return (1); 2902227825Stheraven 2903227825Stheraven case SIMPLE_HASH('q', 'u'): 2904227825Stheraven /* operator ? */ 2905227825Stheraven if (!cpp_demangle_push_str(ddata, "operator?", 9)) 2906227825Stheraven return (0); 2907227825Stheraven ddata->cur += 2; 2908227825Stheraven return (1); 2909227825Stheraven 2910227825Stheraven case SIMPLE_HASH('r', 'm'): 2911227825Stheraven /* operator % */ 2912227825Stheraven if (!cpp_demangle_push_str(ddata, "operator%", 9)) 2913227825Stheraven return (0); 2914227825Stheraven ddata->cur += 2; 2915227825Stheraven return (1); 2916227825Stheraven 2917227825Stheraven case SIMPLE_HASH('r', 'M'): 2918227825Stheraven /* operator %= */ 2919227825Stheraven if (!cpp_demangle_push_str(ddata, "operator%=", 10)) 2920227825Stheraven return (0); 2921227825Stheraven ddata->cur += 2; 2922227825Stheraven return (1); 2923227825Stheraven 2924227825Stheraven case SIMPLE_HASH('r', 's'): 2925227825Stheraven /* operator >> */ 2926227825Stheraven if (!cpp_demangle_push_str(ddata, "operator>>", 10)) 2927227825Stheraven return (0); 2928227825Stheraven ddata->cur += 2; 2929227825Stheraven return (1); 2930227825Stheraven 2931227825Stheraven case SIMPLE_HASH('r', 'S'): 2932227825Stheraven /* operator >>= */ 2933227825Stheraven if (!cpp_demangle_push_str(ddata, "operator>>=", 11)) 2934227825Stheraven return (0); 2935227825Stheraven ddata->cur += 2; 2936227825Stheraven return (1); 2937227825Stheraven 2938227825Stheraven case SIMPLE_HASH('r', 'z'): 2939227825Stheraven /* operator sizeof */ 2940227825Stheraven if (!cpp_demangle_push_str(ddata, "operator sizeof ", 16)) 2941227825Stheraven return (0); 2942227825Stheraven ddata->cur += 2; 2943227825Stheraven return (1); 2944227825Stheraven 2945227825Stheraven case SIMPLE_HASH('s', 'r'): 2946227825Stheraven /* scope resolution operator */ 2947227825Stheraven if (!cpp_demangle_push_str(ddata, "scope resolution operator ", 2948227825Stheraven 26)) 2949227825Stheraven return (0); 2950227825Stheraven ddata->cur += 2; 2951227825Stheraven return (1); 2952227825Stheraven 2953227825Stheraven case SIMPLE_HASH('s', 'v'): 2954227825Stheraven /* operator sizeof */ 2955227825Stheraven if (!cpp_demangle_push_str(ddata, "operator sizeof ", 16)) 2956227825Stheraven return (0); 2957227825Stheraven ddata->cur += 2; 2958227825Stheraven return (1); 2959227825Stheraven }; 2960227825Stheraven 2961227825Stheraven /* vendor extened operator */ 2962227825Stheraven if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) { 2963227825Stheraven if (!cpp_demangle_push_str(ddata, "vendor extened operator ", 2964227825Stheraven 24)) 2965227825Stheraven return (0); 2966227825Stheraven if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1)) 2967227825Stheraven return (0); 2968227825Stheraven ddata->cur += 2; 2969227825Stheraven return (cpp_demangle_read_sname(ddata)); 2970227825Stheraven } 2971227825Stheraven 2972227825Stheraven /* ctor-dtor-name */ 2973227825Stheraven switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 2974227825Stheraven case SIMPLE_HASH('C', '1'): 2975227825Stheraven /* FALLTHROUGH */ 2976227825Stheraven case SIMPLE_HASH('C', '2'): 2977227825Stheraven /* FALLTHROUGH */ 2978227825Stheraven case SIMPLE_HASH('C', '3'): 2979227825Stheraven if (ddata->last_sname == NULL) 2980227825Stheraven return (0); 2981227825Stheraven if ((len = strlen(ddata->last_sname)) == 0) 2982227825Stheraven return (0); 2983227825Stheraven if (!cpp_demangle_push_str(ddata, "::", 2)) 2984227825Stheraven return (0); 2985227825Stheraven if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) 2986227825Stheraven return (0); 2987227825Stheraven ddata->cur +=2; 2988227825Stheraven return (1); 2989227825Stheraven 2990227825Stheraven case SIMPLE_HASH('D', '0'): 2991227825Stheraven /* FALLTHROUGH */ 2992227825Stheraven case SIMPLE_HASH('D', '1'): 2993227825Stheraven /* FALLTHROUGH */ 2994227825Stheraven case SIMPLE_HASH('D', '2'): 2995227825Stheraven if (ddata->last_sname == NULL) 2996227825Stheraven return (0); 2997227825Stheraven if ((len = strlen(ddata->last_sname)) == 0) 2998227825Stheraven return (0); 2999227825Stheraven if (!cpp_demangle_push_str(ddata, "::~", 3)) 3000227825Stheraven return (0); 3001227825Stheraven if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) 3002227825Stheraven return (0); 3003227825Stheraven ddata->cur +=2; 3004227825Stheraven return (1); 3005227825Stheraven }; 3006227825Stheraven 3007227825Stheraven /* source name */ 3008227825Stheraven if (ELFTC_ISDIGIT(*ddata->cur) != 0) 3009227825Stheraven return (cpp_demangle_read_sname(ddata)); 3010227825Stheraven 3011255815Stheraven 3012255815Stheraven /* local source name */ 3013255815Stheraven if (*ddata->cur == 'L') 3014255815Stheraven return (cpp_demangle_local_source_name(ddata)); 3015255815Stheraven 3016255815Stheraven return (1); 3017255815Stheraven} 3018255815Stheraven 3019255815Stheraven/* 3020255815Stheraven * Read local source name. 3021255815Stheraven * 3022255815Stheraven * References: 3023255815Stheraven * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 3024255815Stheraven * http://gcc.gnu.org/viewcvs?view=rev&revision=124467 3025255815Stheraven */ 3026255815Stheravenstatic int 3027255815Stheravencpp_demangle_local_source_name(struct cpp_demangle_data *ddata) 3028255815Stheraven{ 3029255815Stheraven /* L */ 3030255815Stheraven if (ddata == NULL || *ddata->cur != 'L') 3031255815Stheraven return (0); 3032255815Stheraven ++ddata->cur; 3033255815Stheraven 3034255815Stheraven /* source name */ 3035255815Stheraven if (!cpp_demangle_read_sname(ddata)) 3036255815Stheraven return (0); 3037255815Stheraven 3038255815Stheraven /* discriminator */ 3039255815Stheraven if (*ddata->cur == '_') { 3040255815Stheraven ++ddata->cur; 3041255815Stheraven while (ELFTC_ISDIGIT(*ddata->cur) != 0) 3042255815Stheraven ++ddata->cur; 3043255815Stheraven } 3044255815Stheraven 3045227825Stheraven return (1); 3046227825Stheraven} 3047227825Stheraven 3048227825Stheravenstatic int 3049227825Stheravencpp_demangle_read_v_offset(struct cpp_demangle_data *ddata) 3050227825Stheraven{ 3051227825Stheraven 3052227825Stheraven if (ddata == NULL) 3053227825Stheraven return (0); 3054227825Stheraven 3055227825Stheraven if (!cpp_demangle_push_str(ddata, "offset : ", 9)) 3056227825Stheraven return (0); 3057227825Stheraven 3058227825Stheraven if (!cpp_demangle_read_offset_number(ddata)) 3059227825Stheraven return (0); 3060227825Stheraven 3061227825Stheraven if (!cpp_demangle_push_str(ddata, "virtual offset : ", 17)) 3062227825Stheraven return (0); 3063227825Stheraven 3064227825Stheraven return (!cpp_demangle_read_offset_number(ddata)); 3065227825Stheraven} 3066227825Stheraven 3067227825Stheraven/* 3068227825Stheraven * Decode floating point representation to string 3069227825Stheraven * Return new allocated string or NULL 3070227825Stheraven * 3071227825Stheraven * Todo 3072227825Stheraven * Replace these functions to macro. 3073227825Stheraven */ 3074227825Stheravenstatic char * 3075227825Stheravendecode_fp_to_double(const char *p, size_t len) 3076227825Stheraven{ 3077227825Stheraven double f; 3078227825Stheraven size_t rtn_len, limit, i; 3079227825Stheraven int byte; 3080227825Stheraven char *rtn; 3081227825Stheraven 3082227825Stheraven if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double)) 3083227825Stheraven return (NULL); 3084227825Stheraven 3085227825Stheraven memset(&f, 0, sizeof(double)); 3086227825Stheraven 3087227825Stheraven for (i = 0; i < len / 2; ++i) { 3088227825Stheraven byte = hex_to_dec(p[len - i * 2 - 1]) + 3089227825Stheraven hex_to_dec(p[len - i * 2 - 2]) * 16; 3090227825Stheraven 3091227825Stheraven if (byte < 0 || byte > 255) 3092227825Stheraven return (NULL); 3093227825Stheraven 3094227825Stheraven#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3095227825Stheraven ((unsigned char *)&f)[i] = (unsigned char)(byte); 3096227825Stheraven#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3097227825Stheraven ((unsigned char *)&f)[sizeof(double) - i - 1] = 3098227825Stheraven (unsigned char)(byte); 3099227825Stheraven#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3100227825Stheraven } 3101227825Stheraven 3102227825Stheraven rtn_len = 64; 3103227825Stheraven limit = 0; 3104227825Stheravenagain: 3105227825Stheraven if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3106227825Stheraven return (NULL); 3107227825Stheraven 3108227825Stheraven if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) { 3109227825Stheraven free(rtn); 3110227825Stheraven if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3111227825Stheraven return (NULL); 3112227825Stheraven rtn_len *= BUFFER_GROWFACTOR; 3113227825Stheraven goto again; 3114227825Stheraven } 3115227825Stheraven 3116227825Stheraven return rtn; 3117227825Stheraven} 3118227825Stheraven 3119227825Stheravenstatic char * 3120227825Stheravendecode_fp_to_float(const char *p, size_t len) 3121227825Stheraven{ 3122227825Stheraven size_t i, rtn_len, limit; 3123227825Stheraven float f; 3124227825Stheraven int byte; 3125227825Stheraven char *rtn; 3126227825Stheraven 3127227825Stheraven if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float)) 3128227825Stheraven return (NULL); 3129227825Stheraven 3130227825Stheraven memset(&f, 0, sizeof(float)); 3131227825Stheraven 3132227825Stheraven for (i = 0; i < len / 2; ++i) { 3133227825Stheraven byte = hex_to_dec(p[len - i * 2 - 1]) + 3134227825Stheraven hex_to_dec(p[len - i * 2 - 2]) * 16; 3135227825Stheraven if (byte < 0 || byte > 255) 3136227825Stheraven return (NULL); 3137227825Stheraven#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3138227825Stheraven ((unsigned char *)&f)[i] = (unsigned char)(byte); 3139227825Stheraven#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3140227825Stheraven ((unsigned char *)&f)[sizeof(float) - i - 1] = 3141227825Stheraven (unsigned char)(byte); 3142227825Stheraven#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3143227825Stheraven } 3144227825Stheraven 3145227825Stheraven rtn_len = 64; 3146227825Stheraven limit = 0; 3147227825Stheravenagain: 3148227825Stheraven if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3149227825Stheraven return (NULL); 3150227825Stheraven 3151227825Stheraven if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) { 3152227825Stheraven free(rtn); 3153227825Stheraven if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3154227825Stheraven return (NULL); 3155227825Stheraven rtn_len *= BUFFER_GROWFACTOR; 3156227825Stheraven goto again; 3157227825Stheraven } 3158227825Stheraven 3159227825Stheraven return rtn; 3160227825Stheraven} 3161227825Stheraven 3162227825Stheravenstatic char * 3163227825Stheravendecode_fp_to_float128(const char *p, size_t len) 3164227825Stheraven{ 3165227825Stheraven long double f; 3166227825Stheraven size_t rtn_len, limit, i; 3167227825Stheraven int byte; 3168227825Stheraven unsigned char buf[FLOAT_QUADRUPLE_BYTES]; 3169227825Stheraven char *rtn; 3170227825Stheraven 3171227825Stheraven switch(sizeof(long double)) { 3172227825Stheraven case FLOAT_QUADRUPLE_BYTES: 3173227825Stheraven return (decode_fp_to_long_double(p, len)); 3174227825Stheraven case FLOAT_EXTENED_BYTES: 3175227825Stheraven if (p == NULL || len == 0 || len % 2 != 0 || 3176227825Stheraven len / 2 > FLOAT_QUADRUPLE_BYTES) 3177227825Stheraven return (NULL); 3178227825Stheraven 3179227825Stheraven memset(buf, 0, FLOAT_QUADRUPLE_BYTES); 3180227825Stheraven 3181227825Stheraven for (i = 0; i < len / 2; ++i) { 3182227825Stheraven byte = hex_to_dec(p[len - i * 2 - 1]) + 3183227825Stheraven hex_to_dec(p[len - i * 2 - 2]) * 16; 3184227825Stheraven if (byte < 0 || byte > 255) 3185227825Stheraven return (NULL); 3186227825Stheraven#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3187227825Stheraven buf[i] = (unsigned char)(byte); 3188227825Stheraven#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3189227825Stheraven buf[FLOAT_QUADRUPLE_BYTES - i -1] = 3190227825Stheraven (unsigned char)(byte); 3191227825Stheraven#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3192227825Stheraven } 3193227825Stheraven memset(&f, 0, FLOAT_EXTENED_BYTES); 3194227825Stheraven 3195227825Stheraven#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3196227825Stheraven memcpy(&f, buf, FLOAT_EXTENED_BYTES); 3197227825Stheraven#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3198227825Stheraven memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES); 3199227825Stheraven#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3200227825Stheraven 3201227825Stheraven rtn_len = 256; 3202227825Stheraven limit = 0; 3203227825Stheravenagain: 3204227825Stheraven if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3205227825Stheraven return (NULL); 3206227825Stheraven 3207227825Stheraven if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 3208227825Stheraven free(rtn); 3209227825Stheraven if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3210227825Stheraven return (NULL); 3211227825Stheraven rtn_len *= BUFFER_GROWFACTOR; 3212227825Stheraven goto again; 3213227825Stheraven } 3214227825Stheraven 3215227825Stheraven return (rtn); 3216227825Stheraven default: 3217227825Stheraven return (NULL); 3218227825Stheraven } 3219227825Stheraven} 3220227825Stheraven 3221227825Stheravenstatic char * 3222227825Stheravendecode_fp_to_float80(const char *p, size_t len) 3223227825Stheraven{ 3224227825Stheraven long double f; 3225227825Stheraven size_t rtn_len, limit, i; 3226227825Stheraven int byte; 3227227825Stheraven unsigned char buf[FLOAT_EXTENED_BYTES]; 3228227825Stheraven char *rtn; 3229227825Stheraven 3230227825Stheraven switch(sizeof(long double)) { 3231227825Stheraven case FLOAT_QUADRUPLE_BYTES: 3232227825Stheraven if (p == NULL || len == 0 || len % 2 != 0 || 3233227825Stheraven len / 2 > FLOAT_EXTENED_BYTES) 3234227825Stheraven return (NULL); 3235227825Stheraven 3236227825Stheraven memset(buf, 0, FLOAT_EXTENED_BYTES); 3237227825Stheraven 3238227825Stheraven for (i = 0; i < len / 2; ++i) { 3239227825Stheraven byte = hex_to_dec(p[len - i * 2 - 1]) + 3240227825Stheraven hex_to_dec(p[len - i * 2 - 2]) * 16; 3241227825Stheraven 3242227825Stheraven if (byte < 0 || byte > 255) 3243227825Stheraven return (NULL); 3244227825Stheraven 3245227825Stheraven#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3246227825Stheraven buf[i] = (unsigned char)(byte); 3247227825Stheraven#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3248227825Stheraven buf[FLOAT_EXTENED_BYTES - i -1] = 3249227825Stheraven (unsigned char)(byte); 3250227825Stheraven#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3251227825Stheraven } 3252227825Stheraven 3253227825Stheraven memset(&f, 0, FLOAT_QUADRUPLE_BYTES); 3254227825Stheraven 3255227825Stheraven#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3256227825Stheraven memcpy(&f, buf, FLOAT_EXTENED_BYTES); 3257227825Stheraven#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3258227825Stheraven memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENED_BYTES); 3259227825Stheraven#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3260227825Stheraven 3261227825Stheraven rtn_len = 256; 3262227825Stheraven limit = 0; 3263227825Stheravenagain: 3264227825Stheraven if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3265227825Stheraven return (NULL); 3266227825Stheraven 3267227825Stheraven if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 3268227825Stheraven free(rtn); 3269227825Stheraven if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3270227825Stheraven return (NULL); 3271227825Stheraven rtn_len *= BUFFER_GROWFACTOR; 3272227825Stheraven goto again; 3273227825Stheraven } 3274227825Stheraven 3275227825Stheraven return (rtn); 3276227825Stheraven case FLOAT_EXTENED_BYTES: 3277227825Stheraven return (decode_fp_to_long_double(p, len)); 3278227825Stheraven default: 3279227825Stheraven return (NULL); 3280227825Stheraven } 3281227825Stheraven} 3282227825Stheraven 3283227825Stheravenstatic char * 3284227825Stheravendecode_fp_to_long_double(const char *p, size_t len) 3285227825Stheraven{ 3286227825Stheraven long double f; 3287227825Stheraven size_t rtn_len, limit, i; 3288227825Stheraven int byte; 3289227825Stheraven char *rtn; 3290227825Stheraven 3291227825Stheraven if (p == NULL || len == 0 || len % 2 != 0 || 3292227825Stheraven len / 2 > sizeof(long double)) 3293227825Stheraven return (NULL); 3294227825Stheraven 3295227825Stheraven memset(&f, 0, sizeof(long double)); 3296227825Stheraven 3297227825Stheraven for (i = 0; i < len / 2; ++i) { 3298227825Stheraven byte = hex_to_dec(p[len - i * 2 - 1]) + 3299227825Stheraven hex_to_dec(p[len - i * 2 - 2]) * 16; 3300227825Stheraven 3301227825Stheraven if (byte < 0 || byte > 255) 3302227825Stheraven return (NULL); 3303227825Stheraven 3304227825Stheraven#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3305227825Stheraven ((unsigned char *)&f)[i] = (unsigned char)(byte); 3306227825Stheraven#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3307227825Stheraven ((unsigned char *)&f)[sizeof(long double) - i - 1] = 3308227825Stheraven (unsigned char)(byte); 3309227825Stheraven#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3310227825Stheraven } 3311227825Stheraven 3312227825Stheraven rtn_len = 256; 3313227825Stheraven limit = 0; 3314227825Stheravenagain: 3315227825Stheraven if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3316227825Stheraven return (NULL); 3317227825Stheraven 3318227825Stheraven if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 3319227825Stheraven free(rtn); 3320227825Stheraven if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3321227825Stheraven return (NULL); 3322227825Stheraven rtn_len *= BUFFER_GROWFACTOR; 3323227825Stheraven goto again; 3324227825Stheraven } 3325227825Stheraven 3326227825Stheraven return (rtn); 3327227825Stheraven} 3328227825Stheraven 3329227825Stheraven/* Simple hex to integer function used by decode_to_* function. */ 3330227825Stheravenstatic int 3331227825Stheravenhex_to_dec(char c) 3332227825Stheraven{ 3333227825Stheraven 3334227825Stheraven switch (c) { 3335227825Stheraven case '0': 3336227825Stheraven return (0); 3337227825Stheraven case '1': 3338227825Stheraven return (1); 3339227825Stheraven case '2': 3340227825Stheraven return (2); 3341227825Stheraven case '3': 3342227825Stheraven return (3); 3343227825Stheraven case '4': 3344227825Stheraven return (4); 3345227825Stheraven case '5': 3346227825Stheraven return (5); 3347227825Stheraven case '6': 3348227825Stheraven return (6); 3349227825Stheraven case '7': 3350227825Stheraven return (7); 3351227825Stheraven case '8': 3352227825Stheraven return (8); 3353227825Stheraven case '9': 3354227825Stheraven return (9); 3355227825Stheraven case 'a': 3356227825Stheraven return (10); 3357227825Stheraven case 'b': 3358227825Stheraven return (11); 3359227825Stheraven case 'c': 3360227825Stheraven return (12); 3361227825Stheraven case 'd': 3362227825Stheraven return (13); 3363227825Stheraven case 'e': 3364227825Stheraven return (14); 3365227825Stheraven case 'f': 3366227825Stheraven return (15); 3367227825Stheraven default: 3368227825Stheraven return (-1); 3369227825Stheraven }; 3370227825Stheraven} 3371227825Stheraven 3372227825Stheravenstatic void 3373227825Stheravenvector_read_cmd_dest(struct vector_read_cmd *v) 3374227825Stheraven{ 3375227825Stheraven 3376227825Stheraven if (v == NULL) 3377227825Stheraven return; 3378227825Stheraven 3379227825Stheraven free(v->r_container); 3380227825Stheraven} 3381227825Stheraven 3382227825Stheraven/* return -1 at failed, 0 at not found, 1 at found. */ 3383227825Stheravenstatic int 3384227825Stheravenvector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst) 3385227825Stheraven{ 3386227825Stheraven size_t i; 3387227825Stheraven 3388227825Stheraven if (v == NULL || dst == READ_FAIL) 3389227825Stheraven return (-1); 3390227825Stheraven 3391227825Stheraven for (i = 0; i < v->size; ++i) 3392227825Stheraven if (v->r_container[i] == dst) 3393227825Stheraven return (1); 3394227825Stheraven 3395227825Stheraven return (0); 3396227825Stheraven} 3397227825Stheraven 3398227825Stheravenstatic int 3399227825Stheravenvector_read_cmd_init(struct vector_read_cmd *v) 3400227825Stheraven{ 3401227825Stheraven 3402227825Stheraven if (v == NULL) 3403227825Stheraven return (0); 3404227825Stheraven 3405227825Stheraven v->size = 0; 3406227825Stheraven v->capacity = VECTOR_DEF_CAPACITY; 3407227825Stheraven 3408227825Stheraven if ((v->r_container = malloc(sizeof(enum read_cmd) * v->capacity)) 3409227825Stheraven == NULL) 3410227825Stheraven return (0); 3411227825Stheraven 3412227825Stheraven return (1); 3413227825Stheraven} 3414227825Stheraven 3415227825Stheravenstatic int 3416227825Stheravenvector_read_cmd_pop(struct vector_read_cmd *v) 3417227825Stheraven{ 3418227825Stheraven 3419227825Stheraven if (v == NULL || v->size == 0) 3420227825Stheraven return (0); 3421227825Stheraven 3422227825Stheraven --v->size; 3423227825Stheraven v->r_container[v->size] = READ_FAIL; 3424227825Stheraven 3425227825Stheraven return (1); 3426227825Stheraven} 3427227825Stheraven 3428227825Stheravenstatic int 3429227825Stheravenvector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd) 3430227825Stheraven{ 3431227825Stheraven enum read_cmd *tmp_r_ctn; 3432227825Stheraven size_t tmp_cap; 3433227825Stheraven size_t i; 3434227825Stheraven 3435227825Stheraven if (v == NULL) 3436227825Stheraven return (0); 3437227825Stheraven 3438227825Stheraven if (v->size == v->capacity) { 3439227825Stheraven tmp_cap = v->capacity * BUFFER_GROWFACTOR; 3440227825Stheraven if ((tmp_r_ctn = malloc(sizeof(enum read_cmd) * tmp_cap)) 3441227825Stheraven == NULL) 3442227825Stheraven return (0); 3443227825Stheraven for (i = 0; i < v->size; ++i) 3444227825Stheraven tmp_r_ctn[i] = v->r_container[i]; 3445227825Stheraven free(v->r_container); 3446227825Stheraven v->r_container = tmp_r_ctn; 3447227825Stheraven v->capacity = tmp_cap; 3448227825Stheraven } 3449227825Stheraven 3450227825Stheraven v->r_container[v->size] = cmd; 3451227825Stheraven ++v->size; 3452227825Stheraven 3453227825Stheraven return (1); 3454227825Stheraven} 3455227825Stheraven 3456227825Stheravenstatic void 3457227825Stheravenvector_type_qualifier_dest(struct vector_type_qualifier *v) 3458227825Stheraven{ 3459227825Stheraven 3460227825Stheraven if (v == NULL) 3461227825Stheraven return; 3462227825Stheraven 3463227825Stheraven free(v->q_container); 3464227825Stheraven vector_str_dest(&v->ext_name); 3465227825Stheraven} 3466227825Stheraven 3467227825Stheraven/* size, capacity, ext_name */ 3468227825Stheravenstatic int 3469227825Stheravenvector_type_qualifier_init(struct vector_type_qualifier *v) 3470227825Stheraven{ 3471227825Stheraven 3472227825Stheraven if (v == NULL) 3473227825Stheraven return (0); 3474227825Stheraven 3475227825Stheraven v->size = 0; 3476227825Stheraven v->capacity = VECTOR_DEF_CAPACITY; 3477227825Stheraven 3478227825Stheraven if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity)) 3479227825Stheraven == NULL) 3480227825Stheraven return (0); 3481227825Stheraven 3482227825Stheraven assert(v->q_container != NULL); 3483227825Stheraven 3484227825Stheraven if (vector_str_init(&v->ext_name) == false) { 3485227825Stheraven free(v->q_container); 3486227825Stheraven return (0); 3487227825Stheraven } 3488227825Stheraven 3489227825Stheraven return (1); 3490227825Stheraven} 3491227825Stheraven 3492227825Stheravenstatic int 3493227825Stheravenvector_type_qualifier_push(struct vector_type_qualifier *v, 3494227825Stheraven enum type_qualifier t) 3495227825Stheraven{ 3496227825Stheraven enum type_qualifier *tmp_ctn; 3497227825Stheraven size_t tmp_cap; 3498227825Stheraven size_t i; 3499227825Stheraven 3500227825Stheraven if (v == NULL) 3501227825Stheraven return (0); 3502227825Stheraven 3503227825Stheraven if (v->size == v->capacity) { 3504227825Stheraven tmp_cap = v->capacity * BUFFER_GROWFACTOR; 3505227825Stheraven if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap)) 3506227825Stheraven == NULL) 3507227825Stheraven return (0); 3508227825Stheraven for (i = 0; i < v->size; ++i) 3509227825Stheraven tmp_ctn[i] = v->q_container[i]; 3510227825Stheraven free(v->q_container); 3511227825Stheraven v->q_container = tmp_ctn; 3512227825Stheraven v->capacity = tmp_cap; 3513227825Stheraven } 3514227825Stheraven 3515227825Stheraven v->q_container[v->size] = t; 3516227825Stheraven ++v->size; 3517227825Stheraven 3518227825Stheraven return (1); 3519227825Stheraven} 3520