1260684Skaiw/*- 2260684Skaiw * Copyright (c) 2007 Hyogeol Lee <hyogeollee@gmail.com> 3260684Skaiw * All rights reserved. 4260684Skaiw * 5260684Skaiw * Redistribution and use in source and binary forms, with or without 6260684Skaiw * modification, are permitted provided that the following conditions 7260684Skaiw * are met: 8260684Skaiw * 1. Redistributions of source code must retain the above copyright 9260684Skaiw * notice, this list of conditions and the following disclaimer 10260684Skaiw * in this position and unchanged. 11260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright 12260684Skaiw * notice, this list of conditions and the following disclaimer in the 13260684Skaiw * documentation and/or other materials provided with the distribution. 14260684Skaiw * 15260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 16260684Skaiw * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17260684Skaiw * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18260684Skaiw * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19260684Skaiw * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20260684Skaiw * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21260684Skaiw * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22260684Skaiw * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23260684Skaiw * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24260684Skaiw * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25260684Skaiw */ 26260684Skaiw#include <sys/types.h> 27260684Skaiw#include <assert.h> 28260684Skaiw#include <ctype.h> 29260684Skaiw#include <errno.h> 30260684Skaiw#include <libelftc.h> 31260684Skaiw#include <limits.h> 32260684Skaiw#include <stdbool.h> 33260684Skaiw#include <stdio.h> 34260684Skaiw#include <stdlib.h> 35260684Skaiw#include <string.h> 36260684Skaiw 37260684Skaiw#include "_libelftc.h" 38260684Skaiw 39300311SemasteELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3447 2016-05-03 13:32:23Z emaste $"); 40260684Skaiw 41260684Skaiw/** 42260684Skaiw * @file cpp_demangle.c 43260684Skaiw * @brief Decode IA-64 C++ ABI style implementation. 44260684Skaiw * 45260684Skaiw * IA-64 standard ABI(Itanium C++ ABI) references. 46260684Skaiw * 47260684Skaiw * http://www.codesourcery.com/cxx-abi/abi.html#mangling \n 48260684Skaiw * http://www.codesourcery.com/cxx-abi/abi-mangling.html 49260684Skaiw */ 50260684Skaiw 51260684Skaiwenum type_qualifier { 52260684Skaiw TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT, 53283616Semaste TYPE_CST, TYPE_VEC 54260684Skaiw}; 55260684Skaiw 56260684Skaiwstruct vector_type_qualifier { 57260684Skaiw size_t size, capacity; 58260684Skaiw enum type_qualifier *q_container; 59260684Skaiw struct vector_str ext_name; 60260684Skaiw}; 61260684Skaiw 62260684Skaiwenum read_cmd { 63260684Skaiw READ_FAIL, READ_NEST, READ_TMPL, READ_EXPR, READ_EXPL, READ_LOCAL, 64260684Skaiw READ_TYPE, READ_FUNC, READ_PTRMEM 65260684Skaiw}; 66260684Skaiw 67260684Skaiwstruct vector_read_cmd { 68260684Skaiw size_t size, capacity; 69260684Skaiw enum read_cmd *r_container; 70260684Skaiw}; 71260684Skaiw 72260684Skaiwstruct cpp_demangle_data { 73260684Skaiw struct vector_str output; /* output string vector */ 74260684Skaiw struct vector_str output_tmp; 75260684Skaiw struct vector_str subst; /* substitution string vector */ 76260684Skaiw struct vector_str tmpl; 77260684Skaiw struct vector_str class_type; 78260684Skaiw struct vector_read_cmd cmd; 79260684Skaiw bool paren; /* parenthesis opened */ 80260684Skaiw bool pfirst; /* first element of parameter */ 81260684Skaiw bool mem_rst; /* restrict member function */ 82260684Skaiw bool mem_vat; /* volatile member function */ 83260684Skaiw bool mem_cst; /* const member function */ 84260684Skaiw int func_type; 85260684Skaiw const char *cur; /* current mangled name ptr */ 86260684Skaiw const char *last_sname; /* last source name */ 87283616Semaste int push_head; 88260684Skaiw}; 89260684Skaiw 90260684Skaiw#define CPP_DEMANGLE_TRY_LIMIT 128 91260684Skaiw#define FLOAT_SPRINTF_TRY_LIMIT 5 92260684Skaiw#define FLOAT_QUADRUPLE_BYTES 16 93260684Skaiw#define FLOAT_EXTENED_BYTES 10 94260684Skaiw 95260684Skaiw#define SIMPLE_HASH(x,y) (64 * x + y) 96260684Skaiw 97260684Skaiwstatic void cpp_demangle_data_dest(struct cpp_demangle_data *); 98260684Skaiwstatic int cpp_demangle_data_init(struct cpp_demangle_data *, 99260684Skaiw const char *); 100260684Skaiwstatic int cpp_demangle_get_subst(struct cpp_demangle_data *, size_t); 101260684Skaiwstatic int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t); 102260684Skaiwstatic int cpp_demangle_push_fp(struct cpp_demangle_data *, 103260684Skaiw char *(*)(const char *, size_t)); 104260684Skaiwstatic int cpp_demangle_push_str(struct cpp_demangle_data *, const char *, 105260684Skaiw size_t); 106260684Skaiwstatic int cpp_demangle_push_subst(struct cpp_demangle_data *, 107260684Skaiw const char *, size_t); 108260684Skaiwstatic int cpp_demangle_push_subst_v(struct cpp_demangle_data *, 109260684Skaiw struct vector_str *); 110260684Skaiwstatic int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *, 111260684Skaiw struct vector_type_qualifier *, const char *); 112260684Skaiwstatic int cpp_demangle_read_array(struct cpp_demangle_data *); 113260684Skaiwstatic int cpp_demangle_read_encoding(struct cpp_demangle_data *); 114260684Skaiwstatic int cpp_demangle_read_expr_primary(struct cpp_demangle_data *); 115260684Skaiwstatic int cpp_demangle_read_expression(struct cpp_demangle_data *); 116283616Semastestatic int cpp_demangle_read_expression_flat(struct cpp_demangle_data *, 117283616Semaste char **); 118260684Skaiwstatic int cpp_demangle_read_expression_binary(struct cpp_demangle_data *, 119260684Skaiw const char *, size_t); 120260684Skaiwstatic int cpp_demangle_read_expression_unary(struct cpp_demangle_data *, 121260684Skaiw const char *, size_t); 122260684Skaiwstatic int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *, 123260684Skaiw const char *, size_t, const char *, size_t); 124260684Skaiwstatic int cpp_demangle_read_function(struct cpp_demangle_data *, int *, 125260684Skaiw struct vector_type_qualifier *); 126260684Skaiwstatic int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata); 127260684Skaiwstatic int cpp_demangle_read_local_name(struct cpp_demangle_data *); 128260684Skaiwstatic int cpp_demangle_read_name(struct cpp_demangle_data *); 129283616Semastestatic int cpp_demangle_read_name_flat(struct cpp_demangle_data *, 130283616Semaste char**); 131260684Skaiwstatic int cpp_demangle_read_nested_name(struct cpp_demangle_data *); 132260684Skaiwstatic int cpp_demangle_read_number(struct cpp_demangle_data *, long *); 133283616Semastestatic int cpp_demangle_read_number_as_string(struct cpp_demangle_data *, 134283616Semaste char **); 135260684Skaiwstatic int cpp_demangle_read_nv_offset(struct cpp_demangle_data *); 136260684Skaiwstatic int cpp_demangle_read_offset(struct cpp_demangle_data *); 137260684Skaiwstatic int cpp_demangle_read_offset_number(struct cpp_demangle_data *); 138260684Skaiwstatic int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *); 139260684Skaiwstatic int cpp_demangle_read_sname(struct cpp_demangle_data *); 140260684Skaiwstatic int cpp_demangle_read_subst(struct cpp_demangle_data *); 141260684Skaiwstatic int cpp_demangle_read_subst_std(struct cpp_demangle_data *); 142260684Skaiwstatic int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *, 143260684Skaiw const char *, size_t); 144260684Skaiwstatic int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *); 145260684Skaiwstatic int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *); 146260684Skaiwstatic int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *); 147260684Skaiwstatic int cpp_demangle_read_type(struct cpp_demangle_data *, int); 148283616Semastestatic int cpp_demangle_read_type_flat(struct cpp_demangle_data *, 149283616Semaste char **); 150260684Skaiwstatic int cpp_demangle_read_uqname(struct cpp_demangle_data *); 151260684Skaiwstatic int cpp_demangle_read_v_offset(struct cpp_demangle_data *); 152260684Skaiwstatic char *decode_fp_to_double(const char *, size_t); 153260684Skaiwstatic char *decode_fp_to_float(const char *, size_t); 154260684Skaiwstatic char *decode_fp_to_float128(const char *, size_t); 155260684Skaiwstatic char *decode_fp_to_float80(const char *, size_t); 156260684Skaiwstatic char *decode_fp_to_long_double(const char *, size_t); 157260684Skaiwstatic int hex_to_dec(char); 158260684Skaiwstatic void vector_read_cmd_dest(struct vector_read_cmd *); 159260684Skaiwstatic int vector_read_cmd_find(struct vector_read_cmd *, enum read_cmd); 160260684Skaiwstatic int vector_read_cmd_init(struct vector_read_cmd *); 161260684Skaiwstatic int vector_read_cmd_pop(struct vector_read_cmd *); 162260684Skaiwstatic int vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd); 163260684Skaiwstatic void vector_type_qualifier_dest(struct vector_type_qualifier *); 164260684Skaiwstatic int vector_type_qualifier_init(struct vector_type_qualifier *); 165260684Skaiwstatic int vector_type_qualifier_push(struct vector_type_qualifier *, 166260684Skaiw enum type_qualifier); 167260684Skaiw 168260684Skaiw/** 169260684Skaiw * @brief Decode the input string by IA-64 C++ ABI style. 170260684Skaiw * 171260684Skaiw * GNU GCC v3 use IA-64 standard ABI. 172260684Skaiw * @return New allocated demangled string or NULL if failed. 173260684Skaiw * @todo 1. Testing and more test case. 2. Code cleaning. 174260684Skaiw */ 175260684Skaiwchar * 176260684Skaiwcpp_demangle_gnu3(const char *org) 177260684Skaiw{ 178260684Skaiw struct cpp_demangle_data ddata; 179260684Skaiw ssize_t org_len; 180260684Skaiw unsigned int limit; 181260684Skaiw char *rtn; 182260684Skaiw 183260684Skaiw if (org == NULL || (org_len = strlen(org)) < 2) 184260684Skaiw return (NULL); 185260684Skaiw 186260684Skaiw if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) { 187260684Skaiw if ((rtn = malloc(org_len + 19)) == NULL) 188260684Skaiw return (NULL); 189260684Skaiw snprintf(rtn, org_len + 19, 190260684Skaiw "global constructors keyed to %s", org + 11); 191260684Skaiw return (rtn); 192260684Skaiw } 193260684Skaiw 194260684Skaiw if (org[0] != '_' || org[1] != 'Z') 195260684Skaiw return (NULL); 196260684Skaiw 197260684Skaiw if (!cpp_demangle_data_init(&ddata, org + 2)) 198260684Skaiw return (NULL); 199260684Skaiw 200260684Skaiw rtn = NULL; 201260684Skaiw 202260684Skaiw if (!cpp_demangle_read_encoding(&ddata)) 203260684Skaiw goto clean; 204260684Skaiw 205260684Skaiw limit = 0; 206260684Skaiw while (*ddata.cur != '\0') { 207260684Skaiw /* 208260684Skaiw * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4 209260684Skaiw */ 210260684Skaiw if (*ddata.cur == '@' && *(ddata.cur + 1) == '@') 211260684Skaiw break; 212260684Skaiw if (!cpp_demangle_read_type(&ddata, 1)) 213260684Skaiw goto clean; 214260684Skaiw if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 215260684Skaiw goto clean; 216260684Skaiw } 217260684Skaiw 218260684Skaiw if (ddata.output.size == 0) 219260684Skaiw goto clean; 220260684Skaiw if (ddata.paren && !vector_str_push(&ddata.output, ")", 1)) 221260684Skaiw goto clean; 222260684Skaiw if (ddata.mem_vat && !vector_str_push(&ddata.output, " volatile", 9)) 223260684Skaiw goto clean; 224260684Skaiw if (ddata.mem_cst && !vector_str_push(&ddata.output, " const", 6)) 225260684Skaiw goto clean; 226260684Skaiw if (ddata.mem_rst && !vector_str_push(&ddata.output, " restrict", 9)) 227260684Skaiw goto clean; 228260684Skaiw 229260684Skaiw rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); 230260684Skaiw 231260684Skaiwclean: 232260684Skaiw cpp_demangle_data_dest(&ddata); 233260684Skaiw 234260684Skaiw return (rtn); 235260684Skaiw} 236260684Skaiw 237260684Skaiwstatic void 238260684Skaiwcpp_demangle_data_dest(struct cpp_demangle_data *d) 239260684Skaiw{ 240260684Skaiw 241260684Skaiw if (d == NULL) 242260684Skaiw return; 243260684Skaiw 244260684Skaiw vector_read_cmd_dest(&d->cmd); 245260684Skaiw vector_str_dest(&d->class_type); 246260684Skaiw vector_str_dest(&d->tmpl); 247260684Skaiw vector_str_dest(&d->subst); 248260684Skaiw vector_str_dest(&d->output_tmp); 249260684Skaiw vector_str_dest(&d->output); 250260684Skaiw} 251260684Skaiw 252260684Skaiwstatic int 253260684Skaiwcpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur) 254260684Skaiw{ 255260684Skaiw 256260684Skaiw if (d == NULL || cur == NULL) 257260684Skaiw return (0); 258260684Skaiw 259260684Skaiw if (!vector_str_init(&d->output)) 260260684Skaiw return (0); 261260684Skaiw if (!vector_str_init(&d->output_tmp)) 262260684Skaiw goto clean1; 263260684Skaiw if (!vector_str_init(&d->subst)) 264260684Skaiw goto clean2; 265260684Skaiw if (!vector_str_init(&d->tmpl)) 266260684Skaiw goto clean3; 267260684Skaiw if (!vector_str_init(&d->class_type)) 268260684Skaiw goto clean4; 269260684Skaiw if (!vector_read_cmd_init(&d->cmd)) 270260684Skaiw goto clean5; 271260684Skaiw 272260684Skaiw assert(d->output.container != NULL); 273260684Skaiw assert(d->output_tmp.container != NULL); 274260684Skaiw assert(d->subst.container != NULL); 275260684Skaiw assert(d->tmpl.container != NULL); 276260684Skaiw assert(d->class_type.container != NULL); 277260684Skaiw 278260684Skaiw d->paren = false; 279260684Skaiw d->pfirst = false; 280260684Skaiw d->mem_rst = false; 281260684Skaiw d->mem_vat = false; 282260684Skaiw d->mem_cst = false; 283260684Skaiw d->func_type = 0; 284260684Skaiw d->cur = cur; 285260684Skaiw d->last_sname = NULL; 286283616Semaste d->push_head = 0; 287260684Skaiw 288260684Skaiw return (1); 289260684Skaiw 290260684Skaiwclean5: 291260684Skaiw vector_str_dest(&d->class_type); 292260684Skaiwclean4: 293260684Skaiw vector_str_dest(&d->tmpl); 294260684Skaiwclean3: 295260684Skaiw vector_str_dest(&d->subst); 296260684Skaiwclean2: 297260684Skaiw vector_str_dest(&d->output_tmp); 298260684Skaiwclean1: 299260684Skaiw vector_str_dest(&d->output); 300260684Skaiw 301260684Skaiw return (0); 302260684Skaiw} 303260684Skaiw 304260684Skaiwstatic int 305260684Skaiwcpp_demangle_push_fp(struct cpp_demangle_data *ddata, 306260684Skaiw char *(*decoder)(const char *, size_t)) 307260684Skaiw{ 308260684Skaiw size_t len; 309260684Skaiw int rtn; 310260684Skaiw const char *fp; 311260684Skaiw char *f; 312260684Skaiw 313260684Skaiw if (ddata == NULL || decoder == NULL) 314260684Skaiw return (0); 315260684Skaiw 316260684Skaiw fp = ddata->cur; 317260684Skaiw while (*ddata->cur != 'E') 318260684Skaiw ++ddata->cur; 319260684Skaiw 320260684Skaiw if ((f = decoder(fp, ddata->cur - fp)) == NULL) 321260684Skaiw return (0); 322260684Skaiw 323260684Skaiw rtn = 0; 324260684Skaiw if ((len = strlen(f)) > 0) 325282918Semaste rtn = cpp_demangle_push_str(ddata, f, len); 326260684Skaiw 327260684Skaiw free(f); 328260684Skaiw 329283616Semaste ++ddata->cur; 330283616Semaste 331260684Skaiw return (rtn); 332260684Skaiw} 333260684Skaiw 334260684Skaiwstatic int 335260684Skaiwcpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str, 336260684Skaiw size_t len) 337260684Skaiw{ 338260684Skaiw 339260684Skaiw if (ddata == NULL || str == NULL || len == 0) 340260684Skaiw return (0); 341260684Skaiw 342283616Semaste if (ddata->push_head > 0) 343260684Skaiw return (vector_str_push(&ddata->output_tmp, str, len)); 344260684Skaiw 345260684Skaiw return (vector_str_push(&ddata->output, str, len)); 346260684Skaiw} 347260684Skaiw 348260684Skaiwstatic int 349260684Skaiwcpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str, 350260684Skaiw size_t len) 351260684Skaiw{ 352260684Skaiw 353260684Skaiw if (ddata == NULL || str == NULL || len == 0) 354260684Skaiw return (0); 355260684Skaiw 356260684Skaiw if (!vector_str_find(&ddata->subst, str, len)) 357260684Skaiw return (vector_str_push(&ddata->subst, str, len)); 358260684Skaiw 359260684Skaiw return (1); 360260684Skaiw} 361260684Skaiw 362260684Skaiwstatic int 363260684Skaiwcpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v) 364260684Skaiw{ 365260684Skaiw size_t str_len; 366260684Skaiw int rtn; 367260684Skaiw char *str; 368260684Skaiw 369260684Skaiw if (ddata == NULL || v == NULL) 370260684Skaiw return (0); 371260684Skaiw 372260684Skaiw if ((str = vector_str_get_flat(v, &str_len)) == NULL) 373260684Skaiw return (0); 374260684Skaiw 375260684Skaiw rtn = cpp_demangle_push_subst(ddata, str, str_len); 376260684Skaiw 377260684Skaiw free(str); 378260684Skaiw 379260684Skaiw return (rtn); 380260684Skaiw} 381260684Skaiw 382260684Skaiwstatic int 383260684Skaiwcpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, 384260684Skaiw struct vector_type_qualifier *v, const char *type_str) 385260684Skaiw{ 386260684Skaiw struct vector_str subst_v; 387260684Skaiw size_t idx, e_idx, e_len; 388260684Skaiw int rtn; 389260684Skaiw char *buf; 390260684Skaiw 391260684Skaiw if (ddata == NULL || v == NULL) 392260684Skaiw return (0); 393260684Skaiw 394260684Skaiw if ((idx = v->size) == 0) 395260684Skaiw return (1); 396260684Skaiw 397260684Skaiw rtn = 0; 398260684Skaiw if (type_str != NULL) { 399260684Skaiw if (!vector_str_init(&subst_v)) 400260684Skaiw return (0); 401260684Skaiw if (!vector_str_push(&subst_v, type_str, strlen(type_str))) 402260684Skaiw goto clean; 403260684Skaiw } 404260684Skaiw 405260684Skaiw e_idx = 0; 406260684Skaiw while (idx > 0) { 407260684Skaiw switch (v->q_container[idx - 1]) { 408260684Skaiw case TYPE_PTR: 409260684Skaiw if (!cpp_demangle_push_str(ddata, "*", 1)) 410260684Skaiw goto clean; 411260684Skaiw if (type_str != NULL) { 412260684Skaiw if (!vector_str_push(&subst_v, "*", 1)) 413260684Skaiw goto clean; 414283616Semaste if (!cpp_demangle_push_subst_v(ddata, 415283616Semaste &subst_v)) 416260684Skaiw goto clean; 417260684Skaiw } 418260684Skaiw break; 419260684Skaiw 420260684Skaiw case TYPE_REF: 421260684Skaiw if (!cpp_demangle_push_str(ddata, "&", 1)) 422260684Skaiw goto clean; 423260684Skaiw if (type_str != NULL) { 424260684Skaiw if (!vector_str_push(&subst_v, "&", 1)) 425260684Skaiw goto clean; 426283616Semaste if (!cpp_demangle_push_subst_v(ddata, 427283616Semaste &subst_v)) 428260684Skaiw goto clean; 429260684Skaiw } 430260684Skaiw break; 431260684Skaiw 432260684Skaiw case TYPE_CMX: 433260684Skaiw if (!cpp_demangle_push_str(ddata, " complex", 8)) 434260684Skaiw goto clean; 435260684Skaiw if (type_str != NULL) { 436260684Skaiw if (!vector_str_push(&subst_v, " complex", 8)) 437260684Skaiw goto clean; 438283616Semaste if (!cpp_demangle_push_subst_v(ddata, 439283616Semaste &subst_v)) 440260684Skaiw goto clean; 441260684Skaiw } 442260684Skaiw break; 443260684Skaiw 444260684Skaiw case TYPE_IMG: 445260684Skaiw if (!cpp_demangle_push_str(ddata, " imaginary", 10)) 446260684Skaiw goto clean; 447260684Skaiw if (type_str != NULL) { 448283616Semaste if (!vector_str_push(&subst_v, " imaginary", 449283616Semaste 10)) 450260684Skaiw goto clean; 451283616Semaste if (!cpp_demangle_push_subst_v(ddata, 452283616Semaste &subst_v)) 453260684Skaiw goto clean; 454260684Skaiw } 455260684Skaiw break; 456260684Skaiw 457260684Skaiw case TYPE_EXT: 458283616Semaste if (v->ext_name.size == 0 || 459283616Semaste e_idx > v->ext_name.size - 1) 460260684Skaiw goto clean; 461283616Semaste if ((e_len = strlen(v->ext_name.container[e_idx])) == 462283616Semaste 0) 463260684Skaiw goto clean; 464283616Semaste if ((buf = malloc(e_len + 2)) == NULL) 465260684Skaiw goto clean; 466283616Semaste snprintf(buf, e_len + 2, " %s", 467283616Semaste v->ext_name.container[e_idx]); 468260684Skaiw 469260684Skaiw if (!cpp_demangle_push_str(ddata, buf, e_len + 1)) { 470260684Skaiw free(buf); 471260684Skaiw goto clean; 472260684Skaiw } 473260684Skaiw 474260684Skaiw if (type_str != NULL) { 475260684Skaiw if (!vector_str_push(&subst_v, buf, 476260684Skaiw e_len + 1)) { 477260684Skaiw free(buf); 478260684Skaiw goto clean; 479260684Skaiw } 480283616Semaste if (!cpp_demangle_push_subst_v(ddata, 481283616Semaste &subst_v)) { 482260684Skaiw free(buf); 483260684Skaiw goto clean; 484260684Skaiw } 485260684Skaiw } 486260684Skaiw free(buf); 487260684Skaiw ++e_idx; 488260684Skaiw break; 489260684Skaiw 490260684Skaiw case TYPE_RST: 491260684Skaiw if (!cpp_demangle_push_str(ddata, " restrict", 9)) 492260684Skaiw goto clean; 493260684Skaiw if (type_str != NULL) { 494260684Skaiw if (!vector_str_push(&subst_v, " restrict", 9)) 495260684Skaiw goto clean; 496283616Semaste if (!cpp_demangle_push_subst_v(ddata, 497283616Semaste &subst_v)) 498260684Skaiw goto clean; 499260684Skaiw } 500260684Skaiw break; 501260684Skaiw 502260684Skaiw case TYPE_VAT: 503260684Skaiw if (!cpp_demangle_push_str(ddata, " volatile", 9)) 504260684Skaiw goto clean; 505260684Skaiw if (type_str != NULL) { 506260684Skaiw if (!vector_str_push(&subst_v, " volatile", 9)) 507260684Skaiw goto clean; 508283616Semaste if (!cpp_demangle_push_subst_v(ddata, 509283616Semaste &subst_v)) 510260684Skaiw goto clean; 511260684Skaiw } 512260684Skaiw break; 513260684Skaiw 514260684Skaiw case TYPE_CST: 515260684Skaiw if (!cpp_demangle_push_str(ddata, " const", 6)) 516260684Skaiw goto clean; 517260684Skaiw if (type_str != NULL) { 518260684Skaiw if (!vector_str_push(&subst_v, " const", 6)) 519260684Skaiw goto clean; 520283616Semaste if (!cpp_demangle_push_subst_v(ddata, 521283616Semaste &subst_v)) 522260684Skaiw goto clean; 523260684Skaiw } 524260684Skaiw break; 525260684Skaiw 526283616Semaste case TYPE_VEC: 527283616Semaste if (v->ext_name.size == 0 || 528283616Semaste e_idx > v->ext_name.size - 1) 529283616Semaste goto clean; 530283616Semaste if ((e_len = strlen(v->ext_name.container[e_idx])) == 531283616Semaste 0) 532283616Semaste goto clean; 533283616Semaste if ((buf = malloc(e_len + 12)) == NULL) 534283616Semaste goto clean; 535283616Semaste snprintf(buf, e_len + 12, " __vector(%s)", 536283616Semaste v->ext_name.container[e_idx]); 537283616Semaste if (!cpp_demangle_push_str(ddata, buf, e_len + 11)) { 538283616Semaste free(buf); 539283616Semaste goto clean; 540283616Semaste } 541283616Semaste if (type_str != NULL) { 542283616Semaste if (!vector_str_push(&subst_v, buf, 543283616Semaste e_len + 11)) { 544283616Semaste free(buf); 545283616Semaste goto clean; 546283616Semaste } 547283616Semaste if (!cpp_demangle_push_subst_v(ddata, 548283616Semaste &subst_v)) { 549283616Semaste free(buf); 550283616Semaste goto clean; 551283616Semaste } 552283616Semaste } 553283616Semaste free(buf); 554283616Semaste ++e_idx; 555283616Semaste break; 556300311Semaste } 557260684Skaiw --idx; 558260684Skaiw } 559260684Skaiw 560260684Skaiw rtn = 1; 561260684Skaiwclean: 562260684Skaiw if (type_str != NULL) 563260684Skaiw vector_str_dest(&subst_v); 564260684Skaiw 565260684Skaiw return (rtn); 566260684Skaiw} 567260684Skaiw 568260684Skaiwstatic int 569260684Skaiwcpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx) 570260684Skaiw{ 571260684Skaiw size_t len; 572260684Skaiw 573260684Skaiw if (ddata == NULL || ddata->subst.size <= idx) 574260684Skaiw return (0); 575260684Skaiw if ((len = strlen(ddata->subst.container[idx])) == 0) 576260684Skaiw return (0); 577260684Skaiw if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len)) 578260684Skaiw return (0); 579260684Skaiw 580260684Skaiw /* skip '_' */ 581260684Skaiw ++ddata->cur; 582260684Skaiw 583260684Skaiw return (1); 584260684Skaiw} 585260684Skaiw 586260684Skaiwstatic int 587260684Skaiwcpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx) 588260684Skaiw{ 589260684Skaiw size_t len; 590260684Skaiw 591260684Skaiw if (ddata == NULL || ddata->tmpl.size <= idx) 592260684Skaiw return (0); 593260684Skaiw if ((len = strlen(ddata->tmpl.container[idx])) == 0) 594260684Skaiw return (0); 595260684Skaiw if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len)) 596260684Skaiw return (0); 597260684Skaiw 598260684Skaiw ++ddata->cur; 599260684Skaiw 600260684Skaiw return (1); 601260684Skaiw} 602260684Skaiw 603260684Skaiwstatic int 604260684Skaiwcpp_demangle_read_array(struct cpp_demangle_data *ddata) 605260684Skaiw{ 606260684Skaiw size_t i, num_len, exp_len, p_idx, idx; 607260684Skaiw const char *num; 608260684Skaiw char *exp; 609260684Skaiw 610260684Skaiw if (ddata == NULL || *(++ddata->cur) == '\0') 611260684Skaiw return (0); 612260684Skaiw 613260684Skaiw if (*ddata->cur == '_') { 614260684Skaiw if (*(++ddata->cur) == '\0') 615260684Skaiw return (0); 616260684Skaiw 617260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 618260684Skaiw return (0); 619260684Skaiw 620260684Skaiw if (!cpp_demangle_push_str(ddata, "[]", 2)) 621260684Skaiw return (0); 622260684Skaiw } else { 623260684Skaiw if (ELFTC_ISDIGIT(*ddata->cur) != 0) { 624260684Skaiw num = ddata->cur; 625260684Skaiw while (ELFTC_ISDIGIT(*ddata->cur) != 0) 626260684Skaiw ++ddata->cur; 627260684Skaiw if (*ddata->cur != '_') 628260684Skaiw return (0); 629260684Skaiw num_len = ddata->cur - num; 630260684Skaiw assert(num_len > 0); 631260684Skaiw if (*(++ddata->cur) == '\0') 632260684Skaiw return (0); 633260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 634260684Skaiw return (0); 635260684Skaiw if (!cpp_demangle_push_str(ddata, "[", 1)) 636260684Skaiw return (0); 637260684Skaiw if (!cpp_demangle_push_str(ddata, num, num_len)) 638260684Skaiw return (0); 639260684Skaiw if (!cpp_demangle_push_str(ddata, "]", 1)) 640260684Skaiw return (0); 641260684Skaiw } else { 642260684Skaiw p_idx = ddata->output.size; 643260684Skaiw if (!cpp_demangle_read_expression(ddata)) 644260684Skaiw return (0); 645260684Skaiw if ((exp = vector_str_substr(&ddata->output, p_idx, 646260684Skaiw ddata->output.size - 1, &exp_len)) == NULL) 647260684Skaiw return (0); 648260684Skaiw idx = ddata->output.size; 649260684Skaiw for (i = p_idx; i < idx; ++i) 650260684Skaiw if (!vector_str_pop(&ddata->output)) { 651260684Skaiw free(exp); 652260684Skaiw return (0); 653260684Skaiw } 654260684Skaiw if (*ddata->cur != '_') { 655260684Skaiw free(exp); 656260684Skaiw return (0); 657260684Skaiw } 658260684Skaiw ++ddata->cur; 659260684Skaiw if (*ddata->cur == '\0') { 660260684Skaiw free(exp); 661260684Skaiw return (0); 662260684Skaiw } 663260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) { 664260684Skaiw free(exp); 665260684Skaiw return (0); 666260684Skaiw } 667260684Skaiw if (!cpp_demangle_push_str(ddata, "[", 1)) { 668260684Skaiw free(exp); 669260684Skaiw return (0); 670260684Skaiw } 671260684Skaiw if (!cpp_demangle_push_str(ddata, exp, exp_len)) { 672260684Skaiw free(exp); 673260684Skaiw return (0); 674260684Skaiw } 675260684Skaiw if (!cpp_demangle_push_str(ddata, "]", 1)) { 676260684Skaiw free(exp); 677260684Skaiw return (0); 678260684Skaiw } 679260684Skaiw free(exp); 680260684Skaiw } 681260684Skaiw } 682260684Skaiw 683260684Skaiw return (1); 684260684Skaiw} 685260684Skaiw 686260684Skaiwstatic int 687260684Skaiwcpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata) 688260684Skaiw{ 689260684Skaiw const char *num; 690260684Skaiw 691260684Skaiw if (ddata == NULL || *(++ddata->cur) == '\0') 692260684Skaiw return (0); 693260684Skaiw 694260684Skaiw if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') { 695260684Skaiw ddata->cur += 2; 696260684Skaiw if (*ddata->cur == '\0') 697260684Skaiw return (0); 698260684Skaiw if (!cpp_demangle_read_encoding(ddata)) 699260684Skaiw return (0); 700260684Skaiw ++ddata->cur; 701260684Skaiw return (1); 702260684Skaiw } 703260684Skaiw 704260684Skaiw switch (*ddata->cur) { 705260684Skaiw case 'b': 706283616Semaste if (*(ddata->cur + 2) != 'E') 707283616Semaste return (0); 708260684Skaiw switch (*(++ddata->cur)) { 709260684Skaiw case '0': 710283616Semaste ddata->cur += 2; 711260684Skaiw return (cpp_demangle_push_str(ddata, "false", 5)); 712260684Skaiw case '1': 713283616Semaste ddata->cur += 2; 714260684Skaiw return (cpp_demangle_push_str(ddata, "true", 4)); 715260684Skaiw default: 716260684Skaiw return (0); 717300311Semaste } 718260684Skaiw 719260684Skaiw case 'd': 720260684Skaiw ++ddata->cur; 721260684Skaiw return (cpp_demangle_push_fp(ddata, decode_fp_to_double)); 722260684Skaiw 723260684Skaiw case 'e': 724260684Skaiw ++ddata->cur; 725260684Skaiw if (sizeof(long double) == 10) 726260684Skaiw return (cpp_demangle_push_fp(ddata, 727260684Skaiw decode_fp_to_double)); 728260684Skaiw return (cpp_demangle_push_fp(ddata, decode_fp_to_float80)); 729260684Skaiw 730260684Skaiw case 'f': 731260684Skaiw ++ddata->cur; 732260684Skaiw return (cpp_demangle_push_fp(ddata, decode_fp_to_float)); 733260684Skaiw 734260684Skaiw case 'g': 735260684Skaiw ++ddata->cur; 736260684Skaiw if (sizeof(long double) == 16) 737260684Skaiw return (cpp_demangle_push_fp(ddata, 738260684Skaiw decode_fp_to_double)); 739260684Skaiw return (cpp_demangle_push_fp(ddata, decode_fp_to_float128)); 740260684Skaiw 741260684Skaiw case 'i': 742260684Skaiw case 'j': 743260684Skaiw case 'l': 744260684Skaiw case 'm': 745260684Skaiw case 'n': 746260684Skaiw case 's': 747260684Skaiw case 't': 748260684Skaiw case 'x': 749260684Skaiw case 'y': 750260684Skaiw if (*(++ddata->cur) == 'n') { 751260684Skaiw if (!cpp_demangle_push_str(ddata, "-", 1)) 752260684Skaiw return (0); 753260684Skaiw ++ddata->cur; 754260684Skaiw } 755260684Skaiw num = ddata->cur; 756260684Skaiw while (*ddata->cur != 'E') { 757260684Skaiw if (!ELFTC_ISDIGIT(*ddata->cur)) 758260684Skaiw return (0); 759260684Skaiw ++ddata->cur; 760260684Skaiw } 761260684Skaiw ++ddata->cur; 762283616Semaste return (cpp_demangle_push_str(ddata, num, 763283616Semaste ddata->cur - num - 1)); 764260684Skaiw 765260684Skaiw default: 766260684Skaiw return (0); 767300311Semaste } 768260684Skaiw} 769260684Skaiw 770260684Skaiwstatic int 771260684Skaiwcpp_demangle_read_expression(struct cpp_demangle_data *ddata) 772260684Skaiw{ 773260684Skaiw 774260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 775260684Skaiw return (0); 776260684Skaiw 777260684Skaiw switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 778260684Skaiw case SIMPLE_HASH('s', 't'): 779260684Skaiw ddata->cur += 2; 780260684Skaiw return (cpp_demangle_read_type(ddata, 0)); 781260684Skaiw 782260684Skaiw case SIMPLE_HASH('s', 'r'): 783260684Skaiw ddata->cur += 2; 784260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 785260684Skaiw return (0); 786260684Skaiw if (!cpp_demangle_read_uqname(ddata)) 787260684Skaiw return (0); 788260684Skaiw if (*ddata->cur == 'I') 789260684Skaiw return (cpp_demangle_read_tmpl_args(ddata)); 790260684Skaiw return (1); 791260684Skaiw 792260684Skaiw case SIMPLE_HASH('a', 'a'): 793260684Skaiw /* operator && */ 794260684Skaiw ddata->cur += 2; 795260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "&&", 2)); 796260684Skaiw 797260684Skaiw case SIMPLE_HASH('a', 'd'): 798260684Skaiw /* operator & (unary) */ 799260684Skaiw ddata->cur += 2; 800260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "&", 1)); 801260684Skaiw 802260684Skaiw case SIMPLE_HASH('a', 'n'): 803260684Skaiw /* operator & */ 804260684Skaiw ddata->cur += 2; 805260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "&", 1)); 806260684Skaiw 807260684Skaiw case SIMPLE_HASH('a', 'N'): 808260684Skaiw /* operator &= */ 809260684Skaiw ddata->cur += 2; 810260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "&=", 2)); 811260684Skaiw 812260684Skaiw case SIMPLE_HASH('a', 'S'): 813260684Skaiw /* operator = */ 814260684Skaiw ddata->cur += 2; 815260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "=", 1)); 816260684Skaiw 817260684Skaiw case SIMPLE_HASH('c', 'l'): 818260684Skaiw /* operator () */ 819260684Skaiw ddata->cur += 2; 820260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "()", 2)); 821260684Skaiw 822260684Skaiw case SIMPLE_HASH('c', 'm'): 823260684Skaiw /* operator , */ 824260684Skaiw ddata->cur += 2; 825260684Skaiw return (cpp_demangle_read_expression_binary(ddata, ",", 1)); 826260684Skaiw 827260684Skaiw case SIMPLE_HASH('c', 'o'): 828260684Skaiw /* operator ~ */ 829260684Skaiw ddata->cur += 2; 830260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "~", 1)); 831260684Skaiw 832260684Skaiw case SIMPLE_HASH('c', 'v'): 833260684Skaiw /* operator (cast) */ 834260684Skaiw ddata->cur += 2; 835260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6)); 836260684Skaiw 837260684Skaiw case SIMPLE_HASH('d', 'a'): 838260684Skaiw /* operator delete [] */ 839260684Skaiw ddata->cur += 2; 840260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "delete []", 9)); 841260684Skaiw 842260684Skaiw case SIMPLE_HASH('d', 'e'): 843260684Skaiw /* operator * (unary) */ 844260684Skaiw ddata->cur += 2; 845260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "*", 1)); 846260684Skaiw 847260684Skaiw case SIMPLE_HASH('d', 'l'): 848260684Skaiw /* operator delete */ 849260684Skaiw ddata->cur += 2; 850260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "delete", 6)); 851260684Skaiw 852260684Skaiw case SIMPLE_HASH('d', 'v'): 853260684Skaiw /* operator / */ 854260684Skaiw ddata->cur += 2; 855260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "/", 1)); 856260684Skaiw 857260684Skaiw case SIMPLE_HASH('d', 'V'): 858260684Skaiw /* operator /= */ 859260684Skaiw ddata->cur += 2; 860260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "/=", 2)); 861260684Skaiw 862260684Skaiw case SIMPLE_HASH('e', 'o'): 863260684Skaiw /* operator ^ */ 864260684Skaiw ddata->cur += 2; 865260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "^", 1)); 866260684Skaiw 867260684Skaiw case SIMPLE_HASH('e', 'O'): 868260684Skaiw /* operator ^= */ 869260684Skaiw ddata->cur += 2; 870260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "^=", 2)); 871260684Skaiw 872260684Skaiw case SIMPLE_HASH('e', 'q'): 873260684Skaiw /* operator == */ 874260684Skaiw ddata->cur += 2; 875260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "==", 2)); 876260684Skaiw 877260684Skaiw case SIMPLE_HASH('g', 'e'): 878260684Skaiw /* operator >= */ 879260684Skaiw ddata->cur += 2; 880260684Skaiw return (cpp_demangle_read_expression_binary(ddata, ">=", 2)); 881260684Skaiw 882260684Skaiw case SIMPLE_HASH('g', 't'): 883260684Skaiw /* operator > */ 884260684Skaiw ddata->cur += 2; 885260684Skaiw return (cpp_demangle_read_expression_binary(ddata, ">", 1)); 886260684Skaiw 887260684Skaiw case SIMPLE_HASH('i', 'x'): 888260684Skaiw /* operator [] */ 889260684Skaiw ddata->cur += 2; 890260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "[]", 2)); 891260684Skaiw 892260684Skaiw case SIMPLE_HASH('l', 'e'): 893260684Skaiw /* operator <= */ 894260684Skaiw ddata->cur += 2; 895260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "<=", 2)); 896260684Skaiw 897260684Skaiw case SIMPLE_HASH('l', 's'): 898260684Skaiw /* operator << */ 899260684Skaiw ddata->cur += 2; 900260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "<<", 2)); 901260684Skaiw 902260684Skaiw case SIMPLE_HASH('l', 'S'): 903260684Skaiw /* operator <<= */ 904260684Skaiw ddata->cur += 2; 905260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "<<=", 3)); 906260684Skaiw 907260684Skaiw case SIMPLE_HASH('l', 't'): 908260684Skaiw /* operator < */ 909260684Skaiw ddata->cur += 2; 910260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "<", 1)); 911260684Skaiw 912260684Skaiw case SIMPLE_HASH('m', 'i'): 913260684Skaiw /* operator - */ 914260684Skaiw ddata->cur += 2; 915260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "-", 1)); 916260684Skaiw 917260684Skaiw case SIMPLE_HASH('m', 'I'): 918260684Skaiw /* operator -= */ 919260684Skaiw ddata->cur += 2; 920260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "-=", 2)); 921260684Skaiw 922260684Skaiw case SIMPLE_HASH('m', 'l'): 923260684Skaiw /* operator * */ 924260684Skaiw ddata->cur += 2; 925260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "*", 1)); 926260684Skaiw 927260684Skaiw case SIMPLE_HASH('m', 'L'): 928260684Skaiw /* operator *= */ 929260684Skaiw ddata->cur += 2; 930260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "*=", 2)); 931260684Skaiw 932260684Skaiw case SIMPLE_HASH('m', 'm'): 933260684Skaiw /* operator -- */ 934260684Skaiw ddata->cur += 2; 935260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "--", 2)); 936260684Skaiw 937260684Skaiw case SIMPLE_HASH('n', 'a'): 938260684Skaiw /* operator new[] */ 939260684Skaiw ddata->cur += 2; 940260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "new []", 6)); 941260684Skaiw 942260684Skaiw case SIMPLE_HASH('n', 'e'): 943260684Skaiw /* operator != */ 944260684Skaiw ddata->cur += 2; 945260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "!=", 2)); 946260684Skaiw 947260684Skaiw case SIMPLE_HASH('n', 'g'): 948260684Skaiw /* operator - (unary) */ 949260684Skaiw ddata->cur += 2; 950260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "-", 1)); 951260684Skaiw 952260684Skaiw case SIMPLE_HASH('n', 't'): 953260684Skaiw /* operator ! */ 954260684Skaiw ddata->cur += 2; 955260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "!", 1)); 956260684Skaiw 957260684Skaiw case SIMPLE_HASH('n', 'w'): 958260684Skaiw /* operator new */ 959260684Skaiw ddata->cur += 2; 960260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "new", 3)); 961260684Skaiw 962260684Skaiw case SIMPLE_HASH('o', 'o'): 963260684Skaiw /* operator || */ 964260684Skaiw ddata->cur += 2; 965260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "||", 2)); 966260684Skaiw 967260684Skaiw case SIMPLE_HASH('o', 'r'): 968260684Skaiw /* operator | */ 969260684Skaiw ddata->cur += 2; 970260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "|", 1)); 971260684Skaiw 972260684Skaiw case SIMPLE_HASH('o', 'R'): 973260684Skaiw /* operator |= */ 974260684Skaiw ddata->cur += 2; 975260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "|=", 2)); 976260684Skaiw 977260684Skaiw case SIMPLE_HASH('p', 'l'): 978260684Skaiw /* operator + */ 979260684Skaiw ddata->cur += 2; 980260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "+", 1)); 981260684Skaiw 982260684Skaiw case SIMPLE_HASH('p', 'L'): 983260684Skaiw /* operator += */ 984260684Skaiw ddata->cur += 2; 985260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "+=", 2)); 986260684Skaiw 987260684Skaiw case SIMPLE_HASH('p', 'm'): 988260684Skaiw /* operator ->* */ 989260684Skaiw ddata->cur += 2; 990260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "->*", 3)); 991260684Skaiw 992260684Skaiw case SIMPLE_HASH('p', 'p'): 993260684Skaiw /* operator ++ */ 994260684Skaiw ddata->cur += 2; 995260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "++", 2)); 996260684Skaiw 997260684Skaiw case SIMPLE_HASH('p', 's'): 998260684Skaiw /* operator + (unary) */ 999260684Skaiw ddata->cur += 2; 1000260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "+", 1)); 1001260684Skaiw 1002260684Skaiw case SIMPLE_HASH('p', 't'): 1003260684Skaiw /* operator -> */ 1004260684Skaiw ddata->cur += 2; 1005260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "->", 2)); 1006260684Skaiw 1007260684Skaiw case SIMPLE_HASH('q', 'u'): 1008260684Skaiw /* operator ? */ 1009260684Skaiw ddata->cur += 2; 1010260684Skaiw return (cpp_demangle_read_expression_trinary(ddata, "?", 1, 1011260684Skaiw ":", 1)); 1012260684Skaiw 1013260684Skaiw case SIMPLE_HASH('r', 'm'): 1014260684Skaiw /* operator % */ 1015260684Skaiw ddata->cur += 2; 1016260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "%", 1)); 1017260684Skaiw 1018260684Skaiw case SIMPLE_HASH('r', 'M'): 1019260684Skaiw /* operator %= */ 1020260684Skaiw ddata->cur += 2; 1021260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "%=", 2)); 1022260684Skaiw 1023260684Skaiw case SIMPLE_HASH('r', 's'): 1024260684Skaiw /* operator >> */ 1025260684Skaiw ddata->cur += 2; 1026260684Skaiw return (cpp_demangle_read_expression_binary(ddata, ">>", 2)); 1027260684Skaiw 1028260684Skaiw case SIMPLE_HASH('r', 'S'): 1029260684Skaiw /* operator >>= */ 1030260684Skaiw ddata->cur += 2; 1031260684Skaiw return (cpp_demangle_read_expression_binary(ddata, ">>=", 3)); 1032260684Skaiw 1033260684Skaiw case SIMPLE_HASH('r', 'z'): 1034260684Skaiw /* operator sizeof */ 1035260684Skaiw ddata->cur += 2; 1036260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); 1037260684Skaiw 1038260684Skaiw case SIMPLE_HASH('s', 'v'): 1039260684Skaiw /* operator sizeof */ 1040260684Skaiw ddata->cur += 2; 1041260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); 1042300311Semaste } 1043260684Skaiw 1044260684Skaiw switch (*ddata->cur) { 1045260684Skaiw case 'L': 1046260684Skaiw return (cpp_demangle_read_expr_primary(ddata)); 1047260684Skaiw case 'T': 1048260684Skaiw return (cpp_demangle_read_tmpl_param(ddata)); 1049300311Semaste } 1050260684Skaiw 1051260684Skaiw return (0); 1052260684Skaiw} 1053260684Skaiw 1054260684Skaiwstatic int 1055283616Semastecpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str) 1056283616Semaste{ 1057283616Semaste struct vector_str *output; 1058283616Semaste size_t i, p_idx, idx, exp_len; 1059283616Semaste char *exp; 1060283616Semaste 1061283616Semaste output = ddata->push_head > 0 ? &ddata->output_tmp : 1062283616Semaste &ddata->output; 1063283616Semaste 1064283616Semaste p_idx = output->size; 1065283616Semaste 1066283616Semaste if (!cpp_demangle_read_expression(ddata)) 1067283616Semaste return (0); 1068283616Semaste 1069283616Semaste if ((exp = vector_str_substr(output, p_idx, output->size - 1, 1070283616Semaste &exp_len)) == NULL) 1071283616Semaste return (0); 1072283616Semaste 1073283616Semaste idx = output->size; 1074283616Semaste for (i = p_idx; i < idx; ++i) { 1075283616Semaste if (!vector_str_pop(output)) { 1076283616Semaste free(exp); 1077283616Semaste return (0); 1078283616Semaste } 1079283616Semaste } 1080283616Semaste 1081283616Semaste *str = exp; 1082283616Semaste 1083283616Semaste return (1); 1084283616Semaste} 1085283616Semaste 1086283616Semastestatic int 1087260684Skaiwcpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata, 1088260684Skaiw const char *name, size_t len) 1089260684Skaiw{ 1090260684Skaiw 1091260684Skaiw if (ddata == NULL || name == NULL || len == 0) 1092260684Skaiw return (0); 1093260684Skaiw if (!cpp_demangle_read_expression(ddata)) 1094260684Skaiw return (0); 1095260684Skaiw if (!cpp_demangle_push_str(ddata, name, len)) 1096260684Skaiw return (0); 1097260684Skaiw 1098260684Skaiw return (cpp_demangle_read_expression(ddata)); 1099260684Skaiw} 1100260684Skaiw 1101260684Skaiwstatic int 1102260684Skaiwcpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata, 1103260684Skaiw const char *name, size_t len) 1104260684Skaiw{ 1105260684Skaiw 1106260684Skaiw if (ddata == NULL || name == NULL || len == 0) 1107260684Skaiw return (0); 1108260684Skaiw if (!cpp_demangle_read_expression(ddata)) 1109260684Skaiw return (0); 1110260684Skaiw 1111260684Skaiw return (cpp_demangle_push_str(ddata, name, len)); 1112260684Skaiw} 1113260684Skaiw 1114260684Skaiwstatic int 1115260684Skaiwcpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata, 1116260684Skaiw const char *name1, size_t len1, const char *name2, size_t len2) 1117260684Skaiw{ 1118260684Skaiw 1119260684Skaiw if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL || 1120260684Skaiw len2 == 0) 1121260684Skaiw return (0); 1122260684Skaiw 1123260684Skaiw if (!cpp_demangle_read_expression(ddata)) 1124260684Skaiw return (0); 1125260684Skaiw if (!cpp_demangle_push_str(ddata, name1, len1)) 1126260684Skaiw return (0); 1127260684Skaiw if (!cpp_demangle_read_expression(ddata)) 1128260684Skaiw return (0); 1129260684Skaiw if (!cpp_demangle_push_str(ddata, name2, len2)) 1130260684Skaiw return (0); 1131260684Skaiw 1132260684Skaiw return (cpp_demangle_read_expression(ddata)); 1133260684Skaiw} 1134260684Skaiw 1135260684Skaiwstatic int 1136260684Skaiwcpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c, 1137260684Skaiw struct vector_type_qualifier *v) 1138260684Skaiw{ 1139260684Skaiw size_t class_type_size, class_type_len, limit; 1140260684Skaiw const char *class_type; 1141260684Skaiw 1142260684Skaiw if (ddata == NULL || *ddata->cur != 'F' || v == NULL) 1143260684Skaiw return (0); 1144260684Skaiw 1145260684Skaiw ++ddata->cur; 1146260684Skaiw if (*ddata->cur == 'Y') { 1147260684Skaiw if (ext_c != NULL) 1148260684Skaiw *ext_c = 1; 1149260684Skaiw ++ddata->cur; 1150260684Skaiw } 1151260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 1152260684Skaiw return (0); 1153260684Skaiw if (*ddata->cur != 'E') { 1154260684Skaiw if (!cpp_demangle_push_str(ddata, "(", 1)) 1155260684Skaiw return (0); 1156260684Skaiw if (vector_read_cmd_find(&ddata->cmd, READ_PTRMEM)) { 1157260684Skaiw if ((class_type_size = ddata->class_type.size) == 0) 1158260684Skaiw return (0); 1159260684Skaiw class_type = 1160260684Skaiw ddata->class_type.container[class_type_size - 1]; 1161260684Skaiw if (class_type == NULL) 1162260684Skaiw return (0); 1163260684Skaiw if ((class_type_len = strlen(class_type)) == 0) 1164260684Skaiw return (0); 1165260684Skaiw if (!cpp_demangle_push_str(ddata, class_type, 1166260684Skaiw class_type_len)) 1167260684Skaiw return (0); 1168260684Skaiw if (!cpp_demangle_push_str(ddata, "::*", 3)) 1169260684Skaiw return (0); 1170260684Skaiw ++ddata->func_type; 1171260684Skaiw } else { 1172260684Skaiw if (!cpp_demangle_push_type_qualifier(ddata, v, 1173260684Skaiw (const char *) NULL)) 1174260684Skaiw return (0); 1175260684Skaiw vector_type_qualifier_dest(v); 1176260684Skaiw if (!vector_type_qualifier_init(v)) 1177260684Skaiw return (0); 1178260684Skaiw } 1179260684Skaiw 1180260684Skaiw if (!cpp_demangle_push_str(ddata, ")(", 2)) 1181260684Skaiw return (0); 1182260684Skaiw 1183260684Skaiw limit = 0; 1184260684Skaiw for (;;) { 1185260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 1186260684Skaiw return (0); 1187260684Skaiw if (*ddata->cur == 'E') 1188260684Skaiw break; 1189260684Skaiw if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1190260684Skaiw return (0); 1191260684Skaiw } 1192260684Skaiw 1193260684Skaiw if (vector_read_cmd_find(&ddata->cmd, READ_PTRMEM) == 1) { 1194260684Skaiw if (!cpp_demangle_push_type_qualifier(ddata, v, 1195260684Skaiw (const char *) NULL)) 1196260684Skaiw return (0); 1197260684Skaiw vector_type_qualifier_dest(v); 1198260684Skaiw if (!vector_type_qualifier_init(v)) 1199260684Skaiw return (0); 1200260684Skaiw } 1201260684Skaiw 1202260684Skaiw if (!cpp_demangle_push_str(ddata, ")", 1)) 1203260684Skaiw return (0); 1204260684Skaiw } 1205260684Skaiw 1206260684Skaiw ++ddata->cur; 1207260684Skaiw 1208260684Skaiw return (1); 1209260684Skaiw} 1210260684Skaiw 1211260684Skaiw/* read encoding, encoding are function name, data name, special-name */ 1212260684Skaiwstatic int 1213260684Skaiwcpp_demangle_read_encoding(struct cpp_demangle_data *ddata) 1214260684Skaiw{ 1215283616Semaste char *name, *type, *num_str; 1216283616Semaste long offset; 1217283616Semaste int rtn; 1218260684Skaiw 1219260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 1220260684Skaiw return (0); 1221260684Skaiw 1222260684Skaiw /* special name */ 1223260684Skaiw switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 1224283616Semaste case SIMPLE_HASH('G', 'A'): 1225283616Semaste if (!cpp_demangle_push_str(ddata, "hidden alias for ", 17)) 1226283616Semaste return (0); 1227283616Semaste ddata->cur += 2; 1228283616Semaste if (*ddata->cur == '\0') 1229283616Semaste return (0); 1230283616Semaste return (cpp_demangle_read_encoding(ddata)); 1231283616Semaste 1232283616Semaste case SIMPLE_HASH('G', 'R'): 1233283616Semaste if (!cpp_demangle_push_str(ddata, "reference temporary #", 21)) 1234283616Semaste return (0); 1235283616Semaste ddata->cur += 2; 1236283616Semaste if (*ddata->cur == '\0') 1237283616Semaste return (0); 1238283616Semaste if (!cpp_demangle_read_name_flat(ddata, &name)) 1239283616Semaste return (0); 1240283616Semaste rtn = 0; 1241283616Semaste if (!cpp_demangle_read_number_as_string(ddata, &num_str)) 1242283616Semaste goto clean1; 1243283616Semaste if (!cpp_demangle_push_str(ddata, num_str, strlen(num_str))) 1244283616Semaste goto clean2; 1245283616Semaste if (!cpp_demangle_push_str(ddata, " for ", 5)) 1246283616Semaste goto clean2; 1247283616Semaste if (!cpp_demangle_push_str(ddata, name, strlen(name))) 1248283616Semaste goto clean2; 1249283616Semaste rtn = 1; 1250283616Semaste clean2: 1251283616Semaste free(num_str); 1252283616Semaste clean1: 1253283616Semaste free(name); 1254283616Semaste return (rtn); 1255283616Semaste 1256283616Semaste case SIMPLE_HASH('G', 'T'): 1257283616Semaste ddata->cur += 2; 1258283616Semaste if (*ddata->cur == '\0') 1259283616Semaste return (0); 1260283616Semaste switch (*ddata->cur) { 1261283616Semaste case 'n': 1262283616Semaste if (!cpp_demangle_push_str(ddata, 1263283616Semaste "non-transaction clone for ", 26)) 1264283616Semaste return (0); 1265295577Semaste break; 1266283616Semaste case 't': 1267283616Semaste default: 1268283616Semaste if (!cpp_demangle_push_str(ddata, 1269283616Semaste "transaction clone for ", 22)) 1270283616Semaste return (0); 1271295577Semaste break; 1272283616Semaste } 1273283616Semaste ++ddata->cur; 1274283616Semaste return (cpp_demangle_read_encoding(ddata)); 1275283616Semaste 1276260684Skaiw case SIMPLE_HASH('G', 'V'): 1277260684Skaiw /* sentry object for 1 time init */ 1278260684Skaiw if (!cpp_demangle_push_str(ddata, "guard variable for ", 20)) 1279260684Skaiw return (0); 1280260684Skaiw ddata->cur += 2; 1281260684Skaiw break; 1282260684Skaiw 1283260684Skaiw case SIMPLE_HASH('T', 'c'): 1284260684Skaiw /* virtual function covariant override thunk */ 1285260684Skaiw if (!cpp_demangle_push_str(ddata, 1286260684Skaiw "virtual function covariant override ", 36)) 1287260684Skaiw return (0); 1288260684Skaiw ddata->cur += 2; 1289260684Skaiw if (*ddata->cur == '\0') 1290260684Skaiw return (0); 1291260684Skaiw if (!cpp_demangle_read_offset(ddata)) 1292260684Skaiw return (0); 1293260684Skaiw if (!cpp_demangle_read_offset(ddata)) 1294260684Skaiw return (0); 1295260684Skaiw return (cpp_demangle_read_encoding(ddata)); 1296260684Skaiw 1297283616Semaste case SIMPLE_HASH('T', 'C'): 1298283616Semaste /* construction vtable */ 1299283616Semaste if (!cpp_demangle_push_str(ddata, "construction vtable for ", 1300283616Semaste 24)) 1301283616Semaste return (0); 1302283616Semaste ddata->cur += 2; 1303283616Semaste if (*ddata->cur == '\0') 1304283616Semaste return (0); 1305283616Semaste if (!cpp_demangle_read_type_flat(ddata, &type)) 1306283616Semaste return (0); 1307283616Semaste rtn = 0; 1308283616Semaste if (!cpp_demangle_read_number(ddata, &offset)) 1309283616Semaste goto clean3; 1310283616Semaste if (*ddata->cur++ != '_') 1311283616Semaste goto clean3; 1312283616Semaste if (!cpp_demangle_read_type(ddata, 0)) 1313283616Semaste goto clean3; 1314283616Semaste if (!cpp_demangle_push_str(ddata, "-in-", 4)) 1315283616Semaste goto clean3; 1316283616Semaste if (!cpp_demangle_push_str(ddata, type, strlen(type))) 1317283616Semaste goto clean3; 1318283616Semaste rtn = 1; 1319283616Semaste clean3: 1320283616Semaste free(type); 1321283616Semaste return (rtn); 1322283616Semaste 1323260684Skaiw case SIMPLE_HASH('T', 'D'): 1324260684Skaiw /* typeinfo common proxy */ 1325260684Skaiw break; 1326260684Skaiw 1327283616Semaste case SIMPLE_HASH('T', 'F'): 1328283616Semaste /* typeinfo fn */ 1329283616Semaste if (!cpp_demangle_push_str(ddata, "typeinfo fn for ", 16)) 1330283616Semaste return (0); 1331283616Semaste ddata->cur += 2; 1332283616Semaste if (*ddata->cur == '\0') 1333283616Semaste return (0); 1334283616Semaste return (cpp_demangle_read_type(ddata, 0)); 1335283616Semaste 1336260684Skaiw case SIMPLE_HASH('T', 'h'): 1337260684Skaiw /* virtual function non-virtual override thunk */ 1338283616Semaste if (!cpp_demangle_push_str(ddata, 1339283616Semaste "virtual function non-virtual override ", 38)) 1340260684Skaiw return (0); 1341260684Skaiw ddata->cur += 2; 1342260684Skaiw if (*ddata->cur == '\0') 1343260684Skaiw return (0); 1344260684Skaiw if (!cpp_demangle_read_nv_offset(ddata)) 1345260684Skaiw return (0); 1346260684Skaiw return (cpp_demangle_read_encoding(ddata)); 1347260684Skaiw 1348283616Semaste case SIMPLE_HASH('T', 'H'): 1349283616Semaste /* TLS init function */ 1350283616Semaste if (!cpp_demangle_push_str(ddata, "TLS init function for ", 1351283616Semaste 22)) 1352283616Semaste return (0); 1353283616Semaste ddata->cur += 2; 1354283616Semaste if (*ddata->cur == '\0') 1355283616Semaste return (0); 1356283616Semaste break; 1357283616Semaste 1358260684Skaiw case SIMPLE_HASH('T', 'I'): 1359260684Skaiw /* typeinfo structure */ 1360283616Semaste if (!cpp_demangle_push_str(ddata, "typeinfo for ", 13)) 1361283616Semaste return (0); 1362283616Semaste ddata->cur += 2; 1363283616Semaste if (*ddata->cur == '\0') 1364283616Semaste return (0); 1365283616Semaste return (cpp_demangle_read_type(ddata, 0)); 1366283616Semaste 1367283616Semaste case SIMPLE_HASH('T', 'J'): 1368283616Semaste /* java class */ 1369283616Semaste if (!cpp_demangle_push_str(ddata, "java Class for ", 15)) 1370283616Semaste return (0); 1371283616Semaste ddata->cur += 2; 1372283616Semaste if (*ddata->cur == '\0') 1373283616Semaste return (0); 1374283616Semaste return (cpp_demangle_read_type(ddata, 0)); 1375283616Semaste 1376260684Skaiw case SIMPLE_HASH('T', 'S'): 1377260684Skaiw /* RTTI name (NTBS) */ 1378283616Semaste if (!cpp_demangle_push_str(ddata, "typeinfo name for ", 18)) 1379260684Skaiw return (0); 1380260684Skaiw ddata->cur += 2; 1381260684Skaiw if (*ddata->cur == '\0') 1382260684Skaiw return (0); 1383283616Semaste return (cpp_demangle_read_type(ddata, 0)); 1384260684Skaiw 1385260684Skaiw case SIMPLE_HASH('T', 'T'): 1386260684Skaiw /* VTT table */ 1387260684Skaiw if (!cpp_demangle_push_str(ddata, "VTT for ", 8)) 1388260684Skaiw return (0); 1389260684Skaiw ddata->cur += 2; 1390283616Semaste if (*ddata->cur == '\0') 1391283616Semaste return (0); 1392283616Semaste return (cpp_demangle_read_type(ddata, 0)); 1393260684Skaiw 1394260684Skaiw case SIMPLE_HASH('T', 'v'): 1395260684Skaiw /* virtual function virtual override thunk */ 1396260684Skaiw if (!cpp_demangle_push_str(ddata, 1397260684Skaiw "virtual function virtual override ", 34)) 1398260684Skaiw return (0); 1399260684Skaiw ddata->cur += 2; 1400260684Skaiw if (*ddata->cur == '\0') 1401260684Skaiw return (0); 1402260684Skaiw if (!cpp_demangle_read_v_offset(ddata)) 1403260684Skaiw return (0); 1404260684Skaiw return (cpp_demangle_read_encoding(ddata)); 1405260684Skaiw 1406260684Skaiw case SIMPLE_HASH('T', 'V'): 1407260684Skaiw /* virtual table */ 1408260684Skaiw if (!cpp_demangle_push_str(ddata, "vtable for ", 12)) 1409260684Skaiw return (0); 1410260684Skaiw ddata->cur += 2; 1411260684Skaiw if (*ddata->cur == '\0') 1412260684Skaiw return (0); 1413283616Semaste return (cpp_demangle_read_type(ddata, 0)); 1414283616Semaste 1415283616Semaste case SIMPLE_HASH('T', 'W'): 1416283616Semaste /* TLS wrapper function */ 1417283616Semaste if (!cpp_demangle_push_str(ddata, "TLS wrapper function for ", 1418283616Semaste 25)) 1419283616Semaste return (0); 1420283616Semaste ddata->cur += 2; 1421283616Semaste if (*ddata->cur == '\0') 1422283616Semaste return (0); 1423283616Semaste break; 1424300311Semaste } 1425260684Skaiw 1426260684Skaiw return (cpp_demangle_read_name(ddata)); 1427260684Skaiw} 1428260684Skaiw 1429260684Skaiwstatic int 1430260684Skaiwcpp_demangle_read_local_name(struct cpp_demangle_data *ddata) 1431260684Skaiw{ 1432260684Skaiw size_t limit; 1433260684Skaiw 1434260684Skaiw if (ddata == NULL) 1435260684Skaiw return (0); 1436260684Skaiw if (*(++ddata->cur) == '\0') 1437260684Skaiw return (0); 1438260684Skaiw if (!cpp_demangle_read_encoding(ddata)) 1439260684Skaiw return (0); 1440260684Skaiw 1441260684Skaiw limit = 0; 1442260684Skaiw for (;;) { 1443260684Skaiw if (!cpp_demangle_read_type(ddata, 1)) 1444260684Skaiw return (0); 1445260684Skaiw if (*ddata->cur == 'E') 1446260684Skaiw break; 1447260684Skaiw if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1448260684Skaiw return (0); 1449260684Skaiw } 1450260684Skaiw if (*(++ddata->cur) == '\0') 1451260684Skaiw return (0); 1452260684Skaiw if (ddata->paren == true) { 1453260684Skaiw if (!cpp_demangle_push_str(ddata, ")", 1)) 1454260684Skaiw return (0); 1455260684Skaiw ddata->paren = false; 1456260684Skaiw } 1457260684Skaiw if (*ddata->cur == 's') 1458260684Skaiw ++ddata->cur; 1459260684Skaiw else { 1460260684Skaiw if (!cpp_demangle_push_str(ddata, "::", 2)) 1461260684Skaiw return (0); 1462260684Skaiw if (!cpp_demangle_read_name(ddata)) 1463260684Skaiw return (0); 1464260684Skaiw } 1465260684Skaiw if (*ddata->cur == '_') { 1466260684Skaiw ++ddata->cur; 1467260684Skaiw while (ELFTC_ISDIGIT(*ddata->cur) != 0) 1468260684Skaiw ++ddata->cur; 1469260684Skaiw } 1470260684Skaiw 1471260684Skaiw return (1); 1472260684Skaiw} 1473260684Skaiw 1474260684Skaiwstatic int 1475260684Skaiwcpp_demangle_read_name(struct cpp_demangle_data *ddata) 1476260684Skaiw{ 1477260684Skaiw struct vector_str *output, v; 1478260684Skaiw size_t p_idx, subst_str_len; 1479260684Skaiw int rtn; 1480260684Skaiw char *subst_str; 1481260684Skaiw 1482260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 1483260684Skaiw return (0); 1484260684Skaiw 1485283616Semaste output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; 1486260684Skaiw 1487260684Skaiw subst_str = NULL; 1488260684Skaiw 1489260684Skaiw switch (*ddata->cur) { 1490260684Skaiw case 'S': 1491260684Skaiw return (cpp_demangle_read_subst(ddata)); 1492260684Skaiw case 'N': 1493260684Skaiw return (cpp_demangle_read_nested_name(ddata)); 1494260684Skaiw case 'Z': 1495260684Skaiw return (cpp_demangle_read_local_name(ddata)); 1496300311Semaste } 1497260684Skaiw 1498260684Skaiw if (!vector_str_init(&v)) 1499260684Skaiw return (0); 1500260684Skaiw 1501260684Skaiw p_idx = output->size; 1502260684Skaiw rtn = 0; 1503260684Skaiw if (!cpp_demangle_read_uqname(ddata)) 1504260684Skaiw goto clean; 1505260684Skaiw if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, 1506260684Skaiw &subst_str_len)) == NULL) 1507260684Skaiw goto clean; 1508260684Skaiw if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) { 1509260684Skaiw rtn = 1; 1510260684Skaiw goto clean; 1511260684Skaiw } 1512260684Skaiw if (!vector_str_push(&v, subst_str, subst_str_len)) 1513260684Skaiw goto clean; 1514260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &v)) 1515260684Skaiw goto clean; 1516260684Skaiw 1517260684Skaiw if (*ddata->cur == 'I') { 1518260684Skaiw p_idx = output->size; 1519260684Skaiw if (!cpp_demangle_read_tmpl_args(ddata)) 1520260684Skaiw goto clean; 1521260684Skaiw free(subst_str); 1522260684Skaiw if ((subst_str = vector_str_substr(output, p_idx, 1523260684Skaiw output->size - 1, &subst_str_len)) == NULL) 1524260684Skaiw goto clean; 1525260684Skaiw if (!vector_str_push(&v, subst_str, subst_str_len)) 1526260684Skaiw goto clean; 1527260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &v)) 1528260684Skaiw goto clean; 1529260684Skaiw } 1530260684Skaiw 1531260684Skaiw rtn = 1; 1532260684Skaiw 1533260684Skaiwclean: 1534260684Skaiw free(subst_str); 1535260684Skaiw vector_str_dest(&v); 1536260684Skaiw 1537260684Skaiw return (rtn); 1538260684Skaiw} 1539260684Skaiw 1540260684Skaiwstatic int 1541283616Semastecpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str) 1542283616Semaste{ 1543283616Semaste struct vector_str *output; 1544283616Semaste size_t i, p_idx, idx, name_len; 1545283616Semaste char *name; 1546283616Semaste 1547283616Semaste output = ddata->push_head > 0 ? &ddata->output_tmp : 1548283616Semaste &ddata->output; 1549283616Semaste 1550283616Semaste p_idx = output->size; 1551283616Semaste 1552283616Semaste if (!cpp_demangle_read_name(ddata)) 1553283616Semaste return (0); 1554283616Semaste 1555283616Semaste if ((name = vector_str_substr(output, p_idx, output->size - 1, 1556283616Semaste &name_len)) == NULL) 1557283616Semaste return (0); 1558283616Semaste 1559283616Semaste idx = output->size; 1560283616Semaste for (i = p_idx; i < idx; ++i) { 1561283616Semaste if (!vector_str_pop(output)) { 1562283616Semaste free(name); 1563283616Semaste return (0); 1564283616Semaste } 1565283616Semaste } 1566283616Semaste 1567283616Semaste *str = name; 1568283616Semaste 1569283616Semaste return (1); 1570283616Semaste} 1571283616Semaste 1572283616Semastestatic int 1573260684Skaiwcpp_demangle_read_nested_name(struct cpp_demangle_data *ddata) 1574260684Skaiw{ 1575260684Skaiw struct vector_str *output, v; 1576260684Skaiw size_t limit, p_idx, subst_str_len; 1577260684Skaiw int rtn; 1578260684Skaiw char *subst_str; 1579260684Skaiw 1580260684Skaiw if (ddata == NULL || *ddata->cur != 'N') 1581260684Skaiw return (0); 1582260684Skaiw if (*(++ddata->cur) == '\0') 1583260684Skaiw return (0); 1584260684Skaiw 1585260684Skaiw while (*ddata->cur == 'r' || *ddata->cur == 'V' || 1586260684Skaiw *ddata->cur == 'K') { 1587260684Skaiw switch (*ddata->cur) { 1588260684Skaiw case 'r': 1589260684Skaiw ddata->mem_rst = true; 1590260684Skaiw break; 1591260684Skaiw case 'V': 1592260684Skaiw ddata->mem_vat = true; 1593260684Skaiw break; 1594260684Skaiw case 'K': 1595260684Skaiw ddata->mem_cst = true; 1596260684Skaiw break; 1597300311Semaste } 1598260684Skaiw ++ddata->cur; 1599260684Skaiw } 1600260684Skaiw 1601283616Semaste output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; 1602260684Skaiw if (!vector_str_init(&v)) 1603260684Skaiw return (0); 1604260684Skaiw 1605260684Skaiw rtn = 0; 1606260684Skaiw limit = 0; 1607260684Skaiw for (;;) { 1608260684Skaiw p_idx = output->size; 1609260684Skaiw switch (*ddata->cur) { 1610260684Skaiw case 'I': 1611260684Skaiw if (!cpp_demangle_read_tmpl_args(ddata)) 1612260684Skaiw goto clean; 1613260684Skaiw break; 1614260684Skaiw case 'S': 1615260684Skaiw if (!cpp_demangle_read_subst(ddata)) 1616260684Skaiw goto clean; 1617260684Skaiw break; 1618260684Skaiw case 'T': 1619260684Skaiw if (!cpp_demangle_read_tmpl_param(ddata)) 1620260684Skaiw goto clean; 1621260684Skaiw break; 1622260684Skaiw default: 1623260684Skaiw if (!cpp_demangle_read_uqname(ddata)) 1624260684Skaiw goto clean; 1625300311Semaste } 1626260684Skaiw 1627260684Skaiw if ((subst_str = vector_str_substr(output, p_idx, 1628260684Skaiw output->size - 1, &subst_str_len)) == NULL) 1629260684Skaiw goto clean; 1630260684Skaiw if (!vector_str_push(&v, subst_str, subst_str_len)) { 1631260684Skaiw free(subst_str); 1632260684Skaiw goto clean; 1633260684Skaiw } 1634260684Skaiw free(subst_str); 1635260684Skaiw 1636260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &v)) 1637260684Skaiw goto clean; 1638260684Skaiw if (*ddata->cur == 'E') 1639260684Skaiw break; 1640260684Skaiw else if (*ddata->cur != 'I' && 1641260684Skaiw *ddata->cur != 'C' && *ddata->cur != 'D') { 1642260684Skaiw if (!cpp_demangle_push_str(ddata, "::", 2)) 1643260684Skaiw goto clean; 1644260684Skaiw if (!vector_str_push(&v, "::", 2)) 1645260684Skaiw goto clean; 1646260684Skaiw } 1647260684Skaiw if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1648260684Skaiw goto clean; 1649260684Skaiw } 1650260684Skaiw 1651260684Skaiw ++ddata->cur; 1652260684Skaiw rtn = 1; 1653260684Skaiw 1654260684Skaiwclean: 1655260684Skaiw vector_str_dest(&v); 1656260684Skaiw 1657260684Skaiw return (rtn); 1658260684Skaiw} 1659260684Skaiw 1660260684Skaiw/* 1661260684Skaiw * read number 1662260684Skaiw * number ::= [n] <decimal> 1663260684Skaiw */ 1664260684Skaiwstatic int 1665260684Skaiwcpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn) 1666260684Skaiw{ 1667260684Skaiw long len, negative_factor; 1668260684Skaiw 1669260684Skaiw if (ddata == NULL || rtn == NULL) 1670260684Skaiw return (0); 1671260684Skaiw 1672260684Skaiw negative_factor = 1; 1673260684Skaiw if (*ddata->cur == 'n') { 1674260684Skaiw negative_factor = -1; 1675260684Skaiw 1676260684Skaiw ++ddata->cur; 1677260684Skaiw } 1678260684Skaiw if (ELFTC_ISDIGIT(*ddata->cur) == 0) 1679260684Skaiw return (0); 1680260684Skaiw 1681260684Skaiw errno = 0; 1682260684Skaiw if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 && 1683260684Skaiw errno != 0) 1684260684Skaiw return (0); 1685260684Skaiw 1686260684Skaiw while (ELFTC_ISDIGIT(*ddata->cur) != 0) 1687260684Skaiw ++ddata->cur; 1688260684Skaiw 1689260684Skaiw assert(len >= 0); 1690260684Skaiw assert(negative_factor == 1 || negative_factor == -1); 1691260684Skaiw 1692260684Skaiw *rtn = len * negative_factor; 1693260684Skaiw 1694260684Skaiw return (1); 1695260684Skaiw} 1696260684Skaiw 1697260684Skaiwstatic int 1698283616Semastecpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str) 1699283616Semaste{ 1700283616Semaste long n; 1701283616Semaste 1702283616Semaste if (!cpp_demangle_read_number(ddata, &n)) { 1703283616Semaste *str = NULL; 1704283616Semaste return (0); 1705283616Semaste } 1706283616Semaste 1707283616Semaste if (asprintf(str, "%ld", n) < 0) { 1708283616Semaste *str = NULL; 1709283616Semaste return (0); 1710283616Semaste } 1711283616Semaste 1712283616Semaste return (1); 1713283616Semaste} 1714283616Semaste 1715283616Semastestatic int 1716260684Skaiwcpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata) 1717260684Skaiw{ 1718260684Skaiw 1719260684Skaiw if (ddata == NULL) 1720260684Skaiw return (0); 1721260684Skaiw 1722260684Skaiw if (!cpp_demangle_push_str(ddata, "offset : ", 9)) 1723260684Skaiw return (0); 1724260684Skaiw 1725260684Skaiw return (cpp_demangle_read_offset_number(ddata)); 1726260684Skaiw} 1727260684Skaiw 1728260684Skaiw/* read offset, offset are nv-offset, v-offset */ 1729260684Skaiwstatic int 1730260684Skaiwcpp_demangle_read_offset(struct cpp_demangle_data *ddata) 1731260684Skaiw{ 1732260684Skaiw 1733260684Skaiw if (ddata == NULL) 1734260684Skaiw return (0); 1735260684Skaiw 1736260684Skaiw if (*ddata->cur == 'h') { 1737260684Skaiw ++ddata->cur; 1738260684Skaiw return (cpp_demangle_read_nv_offset(ddata)); 1739260684Skaiw } else if (*ddata->cur == 'v') { 1740260684Skaiw ++ddata->cur; 1741260684Skaiw return (cpp_demangle_read_v_offset(ddata)); 1742260684Skaiw } 1743260684Skaiw 1744260684Skaiw return (0); 1745260684Skaiw} 1746260684Skaiw 1747260684Skaiwstatic int 1748260684Skaiwcpp_demangle_read_offset_number(struct cpp_demangle_data *ddata) 1749260684Skaiw{ 1750260684Skaiw bool negative; 1751260684Skaiw const char *start; 1752260684Skaiw 1753260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 1754260684Skaiw return (0); 1755260684Skaiw 1756260684Skaiw /* offset could be negative */ 1757260684Skaiw if (*ddata->cur == 'n') { 1758260684Skaiw negative = true; 1759260684Skaiw start = ddata->cur + 1; 1760260684Skaiw } else { 1761260684Skaiw negative = false; 1762260684Skaiw start = ddata->cur; 1763260684Skaiw } 1764260684Skaiw 1765260684Skaiw while (*ddata->cur != '_') 1766260684Skaiw ++ddata->cur; 1767260684Skaiw 1768260684Skaiw if (negative && !cpp_demangle_push_str(ddata, "-", 1)) 1769260684Skaiw return (0); 1770260684Skaiw 1771260684Skaiw assert(start != NULL); 1772260684Skaiw 1773260684Skaiw if (!cpp_demangle_push_str(ddata, start, ddata->cur - start)) 1774260684Skaiw return (0); 1775260684Skaiw if (!cpp_demangle_push_str(ddata, " ", 1)) 1776260684Skaiw return (0); 1777260684Skaiw 1778260684Skaiw ++ddata->cur; 1779260684Skaiw 1780260684Skaiw return (1); 1781260684Skaiw} 1782260684Skaiw 1783260684Skaiwstatic int 1784260684Skaiwcpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata) 1785260684Skaiw{ 1786260684Skaiw size_t class_type_len, i, idx, p_idx; 1787260684Skaiw int p_func_type, rtn; 1788260684Skaiw char *class_type; 1789260684Skaiw 1790260684Skaiw if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0') 1791260684Skaiw return (0); 1792260684Skaiw 1793260684Skaiw p_idx = ddata->output.size; 1794260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 1795260684Skaiw return (0); 1796260684Skaiw 1797260684Skaiw if ((class_type = vector_str_substr(&ddata->output, p_idx, 1798260684Skaiw ddata->output.size - 1, &class_type_len)) == NULL) 1799260684Skaiw return (0); 1800260684Skaiw 1801260684Skaiw rtn = 0; 1802260684Skaiw idx = ddata->output.size; 1803260684Skaiw for (i = p_idx; i < idx; ++i) 1804260684Skaiw if (!vector_str_pop(&ddata->output)) 1805260684Skaiw goto clean1; 1806260684Skaiw 1807260684Skaiw if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM)) 1808260684Skaiw goto clean1; 1809260684Skaiw 1810260684Skaiw if (!vector_str_push(&ddata->class_type, class_type, class_type_len)) 1811260684Skaiw goto clean2; 1812260684Skaiw 1813260684Skaiw p_func_type = ddata->func_type; 1814260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 1815260684Skaiw goto clean3; 1816260684Skaiw 1817260684Skaiw if (p_func_type == ddata->func_type) { 1818260684Skaiw if (!cpp_demangle_push_str(ddata, " ", 1)) 1819260684Skaiw goto clean3; 1820260684Skaiw if (!cpp_demangle_push_str(ddata, class_type, class_type_len)) 1821260684Skaiw goto clean3; 1822260684Skaiw if (!cpp_demangle_push_str(ddata, "::*", 3)) 1823260684Skaiw goto clean3; 1824260684Skaiw } 1825260684Skaiw 1826260684Skaiw rtn = 1; 1827260684Skaiwclean3: 1828260684Skaiw if (!vector_str_pop(&ddata->class_type)) 1829260684Skaiw rtn = 0; 1830260684Skaiwclean2: 1831260684Skaiw if (!vector_read_cmd_pop(&ddata->cmd)) 1832260684Skaiw rtn = 0; 1833260684Skaiwclean1: 1834260684Skaiw free(class_type); 1835260684Skaiw 1836260684Skaiw return (rtn); 1837260684Skaiw} 1838260684Skaiw 1839260684Skaiw/* read source-name, source-name is <len> <ID> */ 1840260684Skaiwstatic int 1841260684Skaiwcpp_demangle_read_sname(struct cpp_demangle_data *ddata) 1842260684Skaiw{ 1843260684Skaiw long len; 1844283616Semaste int err; 1845260684Skaiw 1846260684Skaiw if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 || 1847283616Semaste len <= 0) 1848260684Skaiw return (0); 1849260684Skaiw 1850283616Semaste if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0)) 1851283616Semaste err = cpp_demangle_push_str(ddata, "(anonymous namespace)", 21); 1852283616Semaste else 1853283616Semaste err = cpp_demangle_push_str(ddata, ddata->cur, len); 1854283616Semaste 1855283616Semaste if (err == 0) 1856283616Semaste return (0); 1857283616Semaste 1858260684Skaiw assert(ddata->output.size > 0); 1859260684Skaiw if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == 0) 1860260684Skaiw ddata->last_sname = 1861260684Skaiw ddata->output.container[ddata->output.size - 1]; 1862260684Skaiw 1863260684Skaiw ddata->cur += len; 1864260684Skaiw 1865260684Skaiw return (1); 1866260684Skaiw} 1867260684Skaiw 1868260684Skaiwstatic int 1869260684Skaiwcpp_demangle_read_subst(struct cpp_demangle_data *ddata) 1870260684Skaiw{ 1871260684Skaiw long nth; 1872260684Skaiw 1873260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 1874260684Skaiw return (0); 1875260684Skaiw 1876260684Skaiw /* abbreviations of the form Sx */ 1877260684Skaiw switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 1878260684Skaiw case SIMPLE_HASH('S', 'a'): 1879260684Skaiw /* std::allocator */ 1880260684Skaiw if (cpp_demangle_push_str(ddata, "std::allocator", 14) == 0) 1881260684Skaiw return (0); 1882260684Skaiw ddata->cur += 2; 1883260684Skaiw if (*ddata->cur == 'I') 1884260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1885260684Skaiw "std::allocator", 14)); 1886260684Skaiw return (1); 1887260684Skaiw 1888260684Skaiw case SIMPLE_HASH('S', 'b'): 1889260684Skaiw /* std::basic_string */ 1890260684Skaiw if (!cpp_demangle_push_str(ddata, "std::basic_string", 17)) 1891260684Skaiw return (0); 1892260684Skaiw ddata->cur += 2; 1893260684Skaiw if (*ddata->cur == 'I') 1894260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1895260684Skaiw "std::basic_string", 17)); 1896260684Skaiw return (1); 1897260684Skaiw 1898260684Skaiw case SIMPLE_HASH('S', 'd'): 1899260684Skaiw /* std::basic_iostream<char, std::char_traits<char> > */ 1900295577Semaste if (!cpp_demangle_push_str(ddata, "std::basic_iostream", 19)) 1901260684Skaiw return (0); 1902295577Semaste ddata->last_sname = "basic_iostream"; 1903260684Skaiw ddata->cur += 2; 1904260684Skaiw if (*ddata->cur == 'I') 1905260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1906295577Semaste "std::basic_iostream", 19)); 1907260684Skaiw return (1); 1908260684Skaiw 1909260684Skaiw case SIMPLE_HASH('S', 'i'): 1910260684Skaiw /* std::basic_istream<char, std::char_traits<char> > */ 1911295577Semaste if (!cpp_demangle_push_str(ddata, "std::basic_istream", 18)) 1912260684Skaiw return (0); 1913295577Semaste ddata->last_sname = "basic_istream"; 1914260684Skaiw ddata->cur += 2; 1915260684Skaiw if (*ddata->cur == 'I') 1916260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1917295577Semaste "std::basic_istream", 18)); 1918260684Skaiw return (1); 1919260684Skaiw 1920260684Skaiw case SIMPLE_HASH('S', 'o'): 1921260684Skaiw /* std::basic_ostream<char, std::char_traits<char> > */ 1922295577Semaste if (!cpp_demangle_push_str(ddata, "std::basic_ostream", 18)) 1923260684Skaiw return (0); 1924295577Semaste ddata->last_sname = "basic_ostream"; 1925260684Skaiw ddata->cur += 2; 1926260684Skaiw if (*ddata->cur == 'I') 1927260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1928295577Semaste "std::basic_ostream", 18)); 1929260684Skaiw return (1); 1930260684Skaiw 1931260684Skaiw case SIMPLE_HASH('S', 's'): 1932260684Skaiw /* 1933260684Skaiw * std::basic_string<char, std::char_traits<char>, 1934260684Skaiw * std::allocator<char> > 1935260684Skaiw * 1936260684Skaiw * a.k.a std::string 1937260684Skaiw */ 1938260684Skaiw if (!cpp_demangle_push_str(ddata, "std::string", 11)) 1939260684Skaiw return (0); 1940260684Skaiw ddata->last_sname = "string"; 1941260684Skaiw ddata->cur += 2; 1942260684Skaiw if (*ddata->cur == 'I') 1943260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1944260684Skaiw "std::string", 11)); 1945260684Skaiw return (1); 1946260684Skaiw 1947260684Skaiw case SIMPLE_HASH('S', 't'): 1948260684Skaiw /* std:: */ 1949260684Skaiw return (cpp_demangle_read_subst_std(ddata)); 1950300311Semaste } 1951260684Skaiw 1952260684Skaiw if (*(++ddata->cur) == '\0') 1953260684Skaiw return (0); 1954260684Skaiw 1955260684Skaiw /* substitution */ 1956260684Skaiw if (*ddata->cur == '_') 1957260684Skaiw return (cpp_demangle_get_subst(ddata, 0)); 1958260684Skaiw else { 1959260684Skaiw errno = 0; 1960260684Skaiw /* substitution number is base 36 */ 1961260684Skaiw if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && 1962260684Skaiw errno != 0) 1963260684Skaiw return (0); 1964260684Skaiw 1965260684Skaiw /* first was '_', so increase one */ 1966260684Skaiw ++nth; 1967260684Skaiw 1968260684Skaiw while (*ddata->cur != '_') 1969260684Skaiw ++ddata->cur; 1970260684Skaiw 1971260684Skaiw assert(nth > 0); 1972260684Skaiw 1973260684Skaiw return (cpp_demangle_get_subst(ddata, nth)); 1974260684Skaiw } 1975260684Skaiw 1976260684Skaiw /* NOTREACHED */ 1977260684Skaiw return (0); 1978260684Skaiw} 1979260684Skaiw 1980260684Skaiwstatic int 1981260684Skaiwcpp_demangle_read_subst_std(struct cpp_demangle_data *ddata) 1982260684Skaiw{ 1983260684Skaiw struct vector_str *output, v; 1984260684Skaiw size_t p_idx, subst_str_len; 1985260684Skaiw int rtn; 1986260684Skaiw char *subst_str; 1987260684Skaiw 1988260684Skaiw if (ddata == NULL) 1989260684Skaiw return (0); 1990260684Skaiw 1991260684Skaiw if (!vector_str_init(&v)) 1992260684Skaiw return (0); 1993260684Skaiw 1994260684Skaiw subst_str = NULL; 1995260684Skaiw rtn = 0; 1996260684Skaiw if (!cpp_demangle_push_str(ddata, "std::", 5)) 1997260684Skaiw goto clean; 1998260684Skaiw 1999260684Skaiw if (!vector_str_push(&v, "std::", 5)) 2000260684Skaiw goto clean; 2001260684Skaiw 2002260684Skaiw ddata->cur += 2; 2003260684Skaiw 2004283616Semaste output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; 2005260684Skaiw 2006260684Skaiw p_idx = output->size; 2007260684Skaiw if (!cpp_demangle_read_uqname(ddata)) 2008260684Skaiw goto clean; 2009260684Skaiw 2010260684Skaiw if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, 2011260684Skaiw &subst_str_len)) == NULL) 2012260684Skaiw goto clean; 2013260684Skaiw 2014260684Skaiw if (!vector_str_push(&v, subst_str, subst_str_len)) 2015260684Skaiw goto clean; 2016260684Skaiw 2017260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &v)) 2018260684Skaiw goto clean; 2019260684Skaiw 2020260684Skaiw if (*ddata->cur == 'I') { 2021260684Skaiw p_idx = output->size; 2022260684Skaiw if (!cpp_demangle_read_tmpl_args(ddata)) 2023260684Skaiw goto clean; 2024260684Skaiw free(subst_str); 2025260684Skaiw if ((subst_str = vector_str_substr(output, p_idx, 2026260684Skaiw output->size - 1, &subst_str_len)) == NULL) 2027260684Skaiw goto clean; 2028260684Skaiw if (!vector_str_push(&v, subst_str, subst_str_len)) 2029260684Skaiw goto clean; 2030260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &v)) 2031260684Skaiw goto clean; 2032260684Skaiw } 2033260684Skaiw 2034260684Skaiw rtn = 1; 2035260684Skaiwclean: 2036260684Skaiw free(subst_str); 2037260684Skaiw vector_str_dest(&v); 2038260684Skaiw 2039260684Skaiw return (rtn); 2040260684Skaiw} 2041260684Skaiw 2042260684Skaiwstatic int 2043260684Skaiwcpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata, 2044260684Skaiw const char *str, size_t len) 2045260684Skaiw{ 2046260684Skaiw struct vector_str *output; 2047260684Skaiw size_t p_idx, substr_len; 2048260684Skaiw int rtn; 2049260684Skaiw char *subst_str, *substr; 2050260684Skaiw 2051260684Skaiw if (ddata == NULL || str == NULL || len == 0) 2052260684Skaiw return (0); 2053260684Skaiw 2054283616Semaste output = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; 2055260684Skaiw 2056260684Skaiw p_idx = output->size; 2057260684Skaiw substr = NULL; 2058260684Skaiw subst_str = NULL; 2059260684Skaiw 2060260684Skaiw if (!cpp_demangle_read_tmpl_args(ddata)) 2061260684Skaiw return (0); 2062260684Skaiw if ((substr = vector_str_substr(output, p_idx, output->size - 1, 2063260684Skaiw &substr_len)) == NULL) 2064260684Skaiw return (0); 2065260684Skaiw 2066260684Skaiw rtn = 0; 2067260684Skaiw if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) == 2068260684Skaiw NULL) 2069260684Skaiw goto clean; 2070260684Skaiw 2071260684Skaiw memcpy(subst_str, str, len); 2072260684Skaiw memcpy(subst_str + len, substr, substr_len); 2073260684Skaiw subst_str[substr_len + len] = '\0'; 2074260684Skaiw 2075260684Skaiw if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len)) 2076260684Skaiw goto clean; 2077260684Skaiw 2078260684Skaiw rtn = 1; 2079260684Skaiwclean: 2080260684Skaiw free(subst_str); 2081260684Skaiw free(substr); 2082260684Skaiw 2083260684Skaiw return (rtn); 2084260684Skaiw} 2085260684Skaiw 2086260684Skaiwstatic int 2087260684Skaiwcpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata) 2088260684Skaiw{ 2089260684Skaiw 2090260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 2091260684Skaiw return (0); 2092260684Skaiw 2093260684Skaiw switch (*ddata->cur) { 2094260684Skaiw case 'L': 2095260684Skaiw return (cpp_demangle_read_expr_primary(ddata)); 2096260684Skaiw case 'X': 2097260684Skaiw return (cpp_demangle_read_expression(ddata)); 2098300311Semaste } 2099260684Skaiw 2100260684Skaiw return (cpp_demangle_read_type(ddata, 0)); 2101260684Skaiw} 2102260684Skaiw 2103260684Skaiwstatic int 2104260684Skaiwcpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata) 2105260684Skaiw{ 2106260684Skaiw struct vector_str *v; 2107260684Skaiw size_t arg_len, idx, limit, size; 2108260684Skaiw char *arg; 2109260684Skaiw 2110260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 2111260684Skaiw return (0); 2112260684Skaiw 2113260684Skaiw ++ddata->cur; 2114260684Skaiw 2115260684Skaiw if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL)) 2116260684Skaiw return (0); 2117260684Skaiw 2118260684Skaiw if (!cpp_demangle_push_str(ddata, "<", 1)) 2119260684Skaiw return (0); 2120260684Skaiw 2121260684Skaiw limit = 0; 2122283616Semaste v = ddata->push_head > 0 ? &ddata->output_tmp : &ddata->output; 2123260684Skaiw for (;;) { 2124260684Skaiw idx = v->size; 2125260684Skaiw if (!cpp_demangle_read_tmpl_arg(ddata)) 2126260684Skaiw return (0); 2127260684Skaiw if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) == 2128260684Skaiw NULL) 2129260684Skaiw return (0); 2130260684Skaiw if (!vector_str_find(&ddata->tmpl, arg, arg_len) && 2131260684Skaiw !vector_str_push(&ddata->tmpl, arg, arg_len)) { 2132260684Skaiw free(arg); 2133260684Skaiw return (0); 2134260684Skaiw } 2135260684Skaiw 2136260684Skaiw free(arg); 2137260684Skaiw 2138260684Skaiw if (*ddata->cur == 'E') { 2139260684Skaiw ++ddata->cur; 2140260684Skaiw size = v->size; 2141260684Skaiw assert(size > 0); 2142260684Skaiw if (!strncmp(v->container[size - 1], ">", 1)) { 2143260684Skaiw if (!cpp_demangle_push_str(ddata, " >", 2)) 2144260684Skaiw return (0); 2145260684Skaiw } else if (!cpp_demangle_push_str(ddata, ">", 1)) 2146260684Skaiw return (0); 2147260684Skaiw break; 2148260684Skaiw } else if (*ddata->cur != 'I' && 2149260684Skaiw !cpp_demangle_push_str(ddata, ", ", 2)) 2150260684Skaiw return (0); 2151260684Skaiw 2152260684Skaiw if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 2153260684Skaiw return (0); 2154260684Skaiw } 2155260684Skaiw 2156260684Skaiw return (vector_read_cmd_pop(&ddata->cmd)); 2157260684Skaiw} 2158260684Skaiw 2159260684Skaiw/* 2160260684Skaiw * Read template parameter that forms in 'T[number]_'. 2161260684Skaiw * This function much like to read_subst but only for types. 2162260684Skaiw */ 2163260684Skaiwstatic int 2164260684Skaiwcpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata) 2165260684Skaiw{ 2166260684Skaiw long nth; 2167260684Skaiw 2168260684Skaiw if (ddata == NULL || *ddata->cur != 'T') 2169260684Skaiw return (0); 2170260684Skaiw 2171260684Skaiw ++ddata->cur; 2172260684Skaiw 2173260684Skaiw if (*ddata->cur == '_') 2174260684Skaiw return (cpp_demangle_get_tmpl_param(ddata, 0)); 2175260684Skaiw else { 2176260684Skaiw 2177260684Skaiw errno = 0; 2178260684Skaiw if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && 2179260684Skaiw errno != 0) 2180260684Skaiw return (0); 2181260684Skaiw 2182260684Skaiw /* T_ is first */ 2183260684Skaiw ++nth; 2184260684Skaiw 2185260684Skaiw while (*ddata->cur != '_') 2186260684Skaiw ++ddata->cur; 2187260684Skaiw 2188260684Skaiw assert(nth > 0); 2189260684Skaiw 2190260684Skaiw return (cpp_demangle_get_tmpl_param(ddata, nth)); 2191260684Skaiw } 2192260684Skaiw 2193260684Skaiw /* NOTREACHED */ 2194260684Skaiw return (0); 2195260684Skaiw} 2196260684Skaiw 2197260684Skaiwstatic int 2198260684Skaiwcpp_demangle_read_type(struct cpp_demangle_data *ddata, int delimit) 2199260684Skaiw{ 2200260684Skaiw struct vector_type_qualifier v; 2201260684Skaiw struct vector_str *output; 2202260684Skaiw size_t p_idx, type_str_len; 2203260684Skaiw int extern_c, is_builtin; 2204260684Skaiw long len; 2205283616Semaste char *type_str, *exp_str, *num_str; 2206260684Skaiw 2207260684Skaiw if (ddata == NULL) 2208260684Skaiw return (0); 2209260684Skaiw 2210260684Skaiw output = &ddata->output; 2211260684Skaiw if (!strncmp(ddata->output.container[ddata->output.size - 1], ">", 1)) { 2212283616Semaste ddata->push_head++; 2213260684Skaiw output = &ddata->output_tmp; 2214260684Skaiw } else if (delimit == 1) { 2215260684Skaiw if (ddata->paren == false) { 2216260684Skaiw if (!cpp_demangle_push_str(ddata, "(", 1)) 2217260684Skaiw return (0); 2218260684Skaiw if (ddata->output.size < 2) 2219260684Skaiw return (0); 2220260684Skaiw ddata->paren = true; 2221260684Skaiw ddata->pfirst = true; 2222260684Skaiw /* Need pop function name */ 2223260684Skaiw if (ddata->subst.size == 1 && 2224260684Skaiw !vector_str_pop(&ddata->subst)) 2225260684Skaiw return (0); 2226260684Skaiw } 2227260684Skaiw 2228260684Skaiw if (ddata->pfirst) 2229260684Skaiw ddata->pfirst = false; 2230260684Skaiw else if (*ddata->cur != 'I' && 2231260684Skaiw !cpp_demangle_push_str(ddata, ", ", 2)) 2232260684Skaiw return (0); 2233260684Skaiw } 2234260684Skaiw 2235260684Skaiw assert(output != NULL); 2236260684Skaiw /* 2237260684Skaiw * [r, V, K] [P, R, C, G, U] builtin, function, class-enum, array 2238260684Skaiw * pointer-to-member, template-param, template-template-param, subst 2239260684Skaiw */ 2240260684Skaiw 2241260684Skaiw if (!vector_type_qualifier_init(&v)) 2242260684Skaiw return (0); 2243260684Skaiw 2244260684Skaiw extern_c = 0; 2245260684Skaiw is_builtin = 1; 2246260684Skaiw p_idx = output->size; 2247283616Semaste type_str = exp_str = num_str = NULL; 2248260684Skaiwagain: 2249260684Skaiw /* builtin type */ 2250260684Skaiw switch (*ddata->cur) { 2251260684Skaiw case 'a': 2252260684Skaiw /* signed char */ 2253260684Skaiw if (!cpp_demangle_push_str(ddata, "signed char", 11)) 2254260684Skaiw goto clean; 2255260684Skaiw ++ddata->cur; 2256260684Skaiw goto rtn; 2257260684Skaiw 2258260684Skaiw case 'A': 2259260684Skaiw /* array type */ 2260260684Skaiw if (!cpp_demangle_read_array(ddata)) 2261260684Skaiw goto clean; 2262260684Skaiw is_builtin = 0; 2263260684Skaiw goto rtn; 2264260684Skaiw 2265260684Skaiw case 'b': 2266260684Skaiw /* bool */ 2267260684Skaiw if (!cpp_demangle_push_str(ddata, "bool", 4)) 2268260684Skaiw goto clean; 2269260684Skaiw ++ddata->cur; 2270260684Skaiw goto rtn; 2271260684Skaiw 2272260684Skaiw case 'C': 2273260684Skaiw /* complex pair */ 2274260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_CMX)) 2275260684Skaiw goto clean; 2276260684Skaiw ++ddata->cur; 2277260684Skaiw goto again; 2278260684Skaiw 2279260684Skaiw case 'c': 2280260684Skaiw /* char */ 2281260684Skaiw if (!cpp_demangle_push_str(ddata, "char", 4)) 2282260684Skaiw goto clean; 2283260684Skaiw ++ddata->cur; 2284260684Skaiw goto rtn; 2285260684Skaiw 2286260684Skaiw case 'd': 2287260684Skaiw /* double */ 2288260684Skaiw if (!cpp_demangle_push_str(ddata, "double", 6)) 2289260684Skaiw goto clean; 2290260684Skaiw ++ddata->cur; 2291260684Skaiw goto rtn; 2292260684Skaiw 2293283616Semaste case 'D': 2294283616Semaste ++ddata->cur; 2295283616Semaste switch (*ddata->cur) { 2296283616Semaste case 'd': 2297283616Semaste /* IEEE 754r decimal floating point (64 bits) */ 2298283616Semaste if (!cpp_demangle_push_str(ddata, "decimal64", 9)) 2299283616Semaste goto clean; 2300283616Semaste ++ddata->cur; 2301283616Semaste break; 2302283616Semaste case 'e': 2303283616Semaste /* IEEE 754r decimal floating point (128 bits) */ 2304283616Semaste if (!cpp_demangle_push_str(ddata, "decimal128", 10)) 2305283616Semaste goto clean; 2306283616Semaste ++ddata->cur; 2307283616Semaste break; 2308283616Semaste case 'f': 2309283616Semaste /* IEEE 754r decimal floating point (32 bits) */ 2310283616Semaste if (!cpp_demangle_push_str(ddata, "decimal32", 9)) 2311283616Semaste goto clean; 2312283616Semaste ++ddata->cur; 2313283616Semaste break; 2314283616Semaste case 'h': 2315283616Semaste /* IEEE 754r half-precision floating point (16 bits) */ 2316283616Semaste if (!cpp_demangle_push_str(ddata, "half", 4)) 2317283616Semaste goto clean; 2318283616Semaste ++ddata->cur; 2319283616Semaste break; 2320283616Semaste case 'i': 2321283616Semaste /* char32_t */ 2322283616Semaste if (!cpp_demangle_push_str(ddata, "char32_t", 8)) 2323283616Semaste goto clean; 2324283616Semaste ++ddata->cur; 2325283616Semaste break; 2326283616Semaste case 'n': 2327283616Semaste /* std::nullptr_t (i.e., decltype(nullptr)) */ 2328283616Semaste if (!cpp_demangle_push_str(ddata, "decltype(nullptr)", 2329283616Semaste 17)) 2330283616Semaste goto clean; 2331283616Semaste ++ddata->cur; 2332283616Semaste break; 2333283616Semaste case 's': 2334283616Semaste /* char16_t */ 2335283616Semaste if (!cpp_demangle_push_str(ddata, "char16_t", 8)) 2336283616Semaste goto clean; 2337283616Semaste ++ddata->cur; 2338283616Semaste break; 2339283616Semaste case 'v': 2340283616Semaste /* gcc vector_size extension. */ 2341283616Semaste ++ddata->cur; 2342283616Semaste if (*ddata->cur == '_') { 2343283616Semaste ++ddata->cur; 2344283616Semaste if (!cpp_demangle_read_expression_flat(ddata, 2345283616Semaste &exp_str)) 2346283616Semaste goto clean; 2347283616Semaste if (!vector_str_push(&v.ext_name, exp_str, 2348283616Semaste strlen(exp_str))) 2349283616Semaste goto clean; 2350283616Semaste } else { 2351283616Semaste if (!cpp_demangle_read_number_as_string(ddata, 2352283616Semaste &num_str)) 2353283616Semaste goto clean; 2354283616Semaste if (!vector_str_push(&v.ext_name, num_str, 2355283616Semaste strlen(num_str))) 2356283616Semaste goto clean; 2357283616Semaste } 2358283616Semaste if (*ddata->cur != '_') 2359283616Semaste goto clean; 2360283616Semaste ++ddata->cur; 2361283616Semaste if (!vector_type_qualifier_push(&v, TYPE_VEC)) 2362283616Semaste goto clean; 2363283616Semaste goto again; 2364283616Semaste default: 2365283616Semaste goto clean; 2366283616Semaste } 2367283616Semaste goto rtn; 2368283616Semaste 2369260684Skaiw case 'e': 2370260684Skaiw /* long double */ 2371260684Skaiw if (!cpp_demangle_push_str(ddata, "long double", 11)) 2372260684Skaiw goto clean; 2373260684Skaiw ++ddata->cur; 2374260684Skaiw goto rtn; 2375260684Skaiw 2376260684Skaiw case 'f': 2377260684Skaiw /* float */ 2378260684Skaiw if (!cpp_demangle_push_str(ddata, "float", 5)) 2379260684Skaiw goto clean; 2380260684Skaiw ++ddata->cur; 2381260684Skaiw goto rtn; 2382260684Skaiw 2383260684Skaiw case 'F': 2384260684Skaiw /* function */ 2385260684Skaiw if (!cpp_demangle_read_function(ddata, &extern_c, &v)) 2386260684Skaiw goto clean; 2387260684Skaiw is_builtin = 0; 2388260684Skaiw goto rtn; 2389260684Skaiw 2390260684Skaiw case 'g': 2391260684Skaiw /* __float128 */ 2392260684Skaiw if (!cpp_demangle_push_str(ddata, "__float128", 10)) 2393260684Skaiw goto clean; 2394260684Skaiw ++ddata->cur; 2395260684Skaiw goto rtn; 2396260684Skaiw 2397260684Skaiw case 'G': 2398260684Skaiw /* imaginary */ 2399260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_IMG)) 2400260684Skaiw goto clean; 2401260684Skaiw ++ddata->cur; 2402260684Skaiw goto again; 2403260684Skaiw 2404260684Skaiw case 'h': 2405260684Skaiw /* unsigned char */ 2406260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned char", 13)) 2407260684Skaiw goto clean; 2408260684Skaiw ++ddata->cur; 2409260684Skaiw goto rtn; 2410260684Skaiw 2411260684Skaiw case 'i': 2412260684Skaiw /* int */ 2413260684Skaiw if (!cpp_demangle_push_str(ddata, "int", 3)) 2414260684Skaiw goto clean; 2415260684Skaiw ++ddata->cur; 2416260684Skaiw goto rtn; 2417260684Skaiw 2418260684Skaiw case 'j': 2419260684Skaiw /* unsigned int */ 2420260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned int", 12)) 2421260684Skaiw goto clean; 2422260684Skaiw ++ddata->cur; 2423260684Skaiw goto rtn; 2424260684Skaiw 2425260684Skaiw case 'K': 2426260684Skaiw /* const */ 2427260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_CST)) 2428260684Skaiw goto clean; 2429260684Skaiw ++ddata->cur; 2430260684Skaiw goto again; 2431260684Skaiw 2432260684Skaiw case 'l': 2433260684Skaiw /* long */ 2434260684Skaiw if (!cpp_demangle_push_str(ddata, "long", 4)) 2435260684Skaiw goto clean; 2436260684Skaiw ++ddata->cur; 2437260684Skaiw goto rtn; 2438260684Skaiw 2439260684Skaiw case 'm': 2440260684Skaiw /* unsigned long */ 2441260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned long", 13)) 2442260684Skaiw goto clean; 2443260684Skaiw 2444260684Skaiw ++ddata->cur; 2445260684Skaiw 2446260684Skaiw goto rtn; 2447260684Skaiw case 'M': 2448260684Skaiw /* pointer to member */ 2449260684Skaiw if (!cpp_demangle_read_pointer_to_member(ddata)) 2450260684Skaiw goto clean; 2451260684Skaiw is_builtin = 0; 2452260684Skaiw goto rtn; 2453260684Skaiw 2454260684Skaiw case 'n': 2455260684Skaiw /* __int128 */ 2456260684Skaiw if (!cpp_demangle_push_str(ddata, "__int128", 8)) 2457260684Skaiw goto clean; 2458260684Skaiw ++ddata->cur; 2459260684Skaiw goto rtn; 2460260684Skaiw 2461260684Skaiw case 'o': 2462260684Skaiw /* unsigned __int128 */ 2463283616Semaste if (!cpp_demangle_push_str(ddata, "unsigned __int128", 17)) 2464260684Skaiw goto clean; 2465260684Skaiw ++ddata->cur; 2466260684Skaiw goto rtn; 2467260684Skaiw 2468260684Skaiw case 'P': 2469260684Skaiw /* pointer */ 2470260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_PTR)) 2471260684Skaiw goto clean; 2472260684Skaiw ++ddata->cur; 2473260684Skaiw goto again; 2474260684Skaiw 2475260684Skaiw case 'r': 2476260684Skaiw /* restrict */ 2477260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_RST)) 2478260684Skaiw goto clean; 2479260684Skaiw ++ddata->cur; 2480260684Skaiw goto again; 2481260684Skaiw 2482260684Skaiw case 'R': 2483260684Skaiw /* reference */ 2484260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_REF)) 2485260684Skaiw goto clean; 2486260684Skaiw ++ddata->cur; 2487260684Skaiw goto again; 2488260684Skaiw 2489260684Skaiw case 's': 2490260684Skaiw /* short, local string */ 2491260684Skaiw if (!cpp_demangle_push_str(ddata, "short", 5)) 2492260684Skaiw goto clean; 2493260684Skaiw ++ddata->cur; 2494260684Skaiw goto rtn; 2495260684Skaiw 2496260684Skaiw case 'S': 2497260684Skaiw /* substitution */ 2498260684Skaiw if (!cpp_demangle_read_subst(ddata)) 2499260684Skaiw goto clean; 2500260684Skaiw is_builtin = 0; 2501260684Skaiw goto rtn; 2502260684Skaiw 2503260684Skaiw case 't': 2504260684Skaiw /* unsigned short */ 2505260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned short", 14)) 2506260684Skaiw goto clean; 2507260684Skaiw ++ddata->cur; 2508260684Skaiw goto rtn; 2509260684Skaiw 2510260684Skaiw case 'T': 2511260684Skaiw /* template parameter */ 2512260684Skaiw if (!cpp_demangle_read_tmpl_param(ddata)) 2513260684Skaiw goto clean; 2514260684Skaiw is_builtin = 0; 2515260684Skaiw goto rtn; 2516260684Skaiw 2517260684Skaiw case 'u': 2518260684Skaiw /* vendor extended builtin */ 2519260684Skaiw ++ddata->cur; 2520260684Skaiw if (!cpp_demangle_read_sname(ddata)) 2521260684Skaiw goto clean; 2522260684Skaiw is_builtin = 0; 2523260684Skaiw goto rtn; 2524260684Skaiw 2525260684Skaiw case 'U': 2526260684Skaiw /* vendor extended type qualifier */ 2527260684Skaiw if (!cpp_demangle_read_number(ddata, &len)) 2528260684Skaiw goto clean; 2529260684Skaiw if (len <= 0) 2530260684Skaiw goto clean; 2531260684Skaiw if (!vector_str_push(&v.ext_name, ddata->cur, len)) 2532260684Skaiw return (0); 2533260684Skaiw ddata->cur += len; 2534283616Semaste if (!vector_type_qualifier_push(&v, TYPE_EXT)) 2535283616Semaste goto clean; 2536260684Skaiw goto again; 2537260684Skaiw 2538260684Skaiw case 'v': 2539260684Skaiw /* void */ 2540260684Skaiw if (!cpp_demangle_push_str(ddata, "void", 4)) 2541260684Skaiw goto clean; 2542260684Skaiw ++ddata->cur; 2543260684Skaiw goto rtn; 2544260684Skaiw 2545260684Skaiw case 'V': 2546260684Skaiw /* volatile */ 2547260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_VAT)) 2548260684Skaiw goto clean; 2549260684Skaiw ++ddata->cur; 2550260684Skaiw goto again; 2551260684Skaiw 2552260684Skaiw case 'w': 2553260684Skaiw /* wchar_t */ 2554303398Semaste if (!cpp_demangle_push_str(ddata, "wchar_t", 7)) 2555260684Skaiw goto clean; 2556260684Skaiw ++ddata->cur; 2557260684Skaiw goto rtn; 2558260684Skaiw 2559260684Skaiw case 'x': 2560260684Skaiw /* long long */ 2561260684Skaiw if (!cpp_demangle_push_str(ddata, "long long", 9)) 2562260684Skaiw goto clean; 2563260684Skaiw ++ddata->cur; 2564260684Skaiw goto rtn; 2565260684Skaiw 2566260684Skaiw case 'y': 2567260684Skaiw /* unsigned long long */ 2568260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned long long", 18)) 2569260684Skaiw goto clean; 2570260684Skaiw ++ddata->cur; 2571260684Skaiw goto rtn; 2572260684Skaiw 2573260684Skaiw case 'z': 2574260684Skaiw /* ellipsis */ 2575260684Skaiw if (!cpp_demangle_push_str(ddata, "ellipsis", 8)) 2576260684Skaiw goto clean; 2577260684Skaiw ++ddata->cur; 2578260684Skaiw goto rtn; 2579300311Semaste } 2580260684Skaiw 2581260684Skaiw if (!cpp_demangle_read_name(ddata)) 2582260684Skaiw goto clean; 2583260684Skaiw 2584260684Skaiw is_builtin = 0; 2585260684Skaiwrtn: 2586260684Skaiw if ((type_str = vector_str_substr(output, p_idx, output->size - 1, 2587260684Skaiw &type_str_len)) == NULL) 2588260684Skaiw goto clean; 2589260684Skaiw 2590260684Skaiw if (is_builtin == 0) { 2591260684Skaiw if (!vector_str_find(&ddata->subst, type_str, type_str_len) && 2592260684Skaiw !vector_str_push(&ddata->subst, type_str, type_str_len)) 2593260684Skaiw goto clean; 2594260684Skaiw } 2595260684Skaiw 2596260684Skaiw if (!cpp_demangle_push_type_qualifier(ddata, &v, type_str)) 2597260684Skaiw goto clean; 2598260684Skaiw 2599260684Skaiw free(type_str); 2600283616Semaste free(exp_str); 2601283616Semaste free(num_str); 2602260684Skaiw vector_type_qualifier_dest(&v); 2603260684Skaiw 2604283616Semaste if (ddata->push_head > 0) { 2605260684Skaiw if (*ddata->cur == 'I' && cpp_demangle_read_tmpl_args(ddata) 2606260684Skaiw == 0) 2607260684Skaiw return (0); 2608260684Skaiw 2609283616Semaste if (--ddata->push_head > 0) 2610260684Skaiw return (1); 2611260684Skaiw 2612260684Skaiw if (!vector_str_push(&ddata->output_tmp, " ", 1)) 2613260684Skaiw return (0); 2614260684Skaiw 2615260684Skaiw if (!vector_str_push_vector_head(&ddata->output, 2616260684Skaiw &ddata->output_tmp)) 2617260684Skaiw return (0); 2618260684Skaiw 2619260684Skaiw vector_str_dest(&ddata->output_tmp); 2620260684Skaiw if (!vector_str_init(&ddata->output_tmp)) 2621260684Skaiw return (0); 2622260684Skaiw 2623260684Skaiw if (!cpp_demangle_push_str(ddata, "(", 1)) 2624260684Skaiw return (0); 2625260684Skaiw 2626260684Skaiw ddata->paren = true; 2627260684Skaiw ddata->pfirst = true; 2628260684Skaiw } 2629260684Skaiw 2630260684Skaiw return (1); 2631260684Skaiwclean: 2632260684Skaiw free(type_str); 2633283616Semaste free(exp_str); 2634283616Semaste free(num_str); 2635260684Skaiw vector_type_qualifier_dest(&v); 2636260684Skaiw 2637260684Skaiw return (0); 2638260684Skaiw} 2639260684Skaiw 2640283616Semastestatic int 2641283616Semastecpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str) 2642283616Semaste{ 2643283616Semaste struct vector_str *output; 2644283616Semaste size_t i, p_idx, idx, type_len; 2645283616Semaste char *type; 2646283616Semaste 2647283616Semaste output = ddata->push_head > 0 ? &ddata->output_tmp : 2648283616Semaste &ddata->output; 2649283616Semaste 2650283616Semaste p_idx = output->size; 2651283616Semaste 2652283616Semaste if (!cpp_demangle_read_type(ddata, 0)) 2653283616Semaste return (0); 2654283616Semaste 2655283616Semaste if ((type = vector_str_substr(output, p_idx, output->size - 1, 2656283616Semaste &type_len)) == NULL) 2657283616Semaste return (0); 2658283616Semaste 2659283616Semaste idx = output->size; 2660283616Semaste for (i = p_idx; i < idx; ++i) { 2661283616Semaste if (!vector_str_pop(output)) { 2662283616Semaste free(type); 2663283616Semaste return (0); 2664283616Semaste } 2665283616Semaste } 2666283616Semaste 2667283616Semaste *str = type; 2668283616Semaste 2669283616Semaste return (1); 2670283616Semaste} 2671283616Semaste 2672260684Skaiw/* 2673260684Skaiw * read unqualified-name, unqualified name are operator-name, ctor-dtor-name, 2674260684Skaiw * source-name 2675260684Skaiw */ 2676260684Skaiwstatic int 2677260684Skaiwcpp_demangle_read_uqname(struct cpp_demangle_data *ddata) 2678260684Skaiw{ 2679260684Skaiw size_t len; 2680260684Skaiw 2681260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 2682260684Skaiw return (0); 2683260684Skaiw 2684260684Skaiw /* operator name */ 2685260684Skaiw switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 2686260684Skaiw case SIMPLE_HASH('a', 'a'): 2687260684Skaiw /* operator && */ 2688260684Skaiw if (!cpp_demangle_push_str(ddata, "operator&&", 10)) 2689260684Skaiw return (0); 2690260684Skaiw ddata->cur += 2; 2691260684Skaiw return (1); 2692260684Skaiw 2693260684Skaiw case SIMPLE_HASH('a', 'd'): 2694260684Skaiw /* operator & (unary) */ 2695260684Skaiw if (!cpp_demangle_push_str(ddata, "operator&", 9)) 2696260684Skaiw return (0); 2697260684Skaiw ddata->cur += 2; 2698260684Skaiw return (1); 2699260684Skaiw 2700260684Skaiw case SIMPLE_HASH('a', 'n'): 2701260684Skaiw /* operator & */ 2702260684Skaiw if (!cpp_demangle_push_str(ddata, "operator&", 9)) 2703260684Skaiw return (0); 2704260684Skaiw ddata->cur += 2; 2705260684Skaiw return (1); 2706260684Skaiw 2707260684Skaiw case SIMPLE_HASH('a', 'N'): 2708260684Skaiw /* operator &= */ 2709260684Skaiw if (!cpp_demangle_push_str(ddata, "operator&=", 10)) 2710260684Skaiw return (0); 2711260684Skaiw ddata->cur += 2; 2712260684Skaiw return (1); 2713260684Skaiw 2714260684Skaiw case SIMPLE_HASH('a', 'S'): 2715260684Skaiw /* operator = */ 2716260684Skaiw if (!cpp_demangle_push_str(ddata, "operator=", 9)) 2717260684Skaiw return (0); 2718260684Skaiw ddata->cur += 2; 2719260684Skaiw return (1); 2720260684Skaiw 2721260684Skaiw case SIMPLE_HASH('c', 'l'): 2722260684Skaiw /* operator () */ 2723260684Skaiw if (!cpp_demangle_push_str(ddata, "operator()", 10)) 2724260684Skaiw return (0); 2725260684Skaiw ddata->cur += 2; 2726260684Skaiw return (1); 2727260684Skaiw 2728260684Skaiw case SIMPLE_HASH('c', 'm'): 2729260684Skaiw /* operator , */ 2730260684Skaiw if (!cpp_demangle_push_str(ddata, "operator,", 9)) 2731260684Skaiw return (0); 2732260684Skaiw ddata->cur += 2; 2733260684Skaiw return (1); 2734260684Skaiw 2735260684Skaiw case SIMPLE_HASH('c', 'o'): 2736260684Skaiw /* operator ~ */ 2737260684Skaiw if (!cpp_demangle_push_str(ddata, "operator~", 9)) 2738260684Skaiw return (0); 2739260684Skaiw ddata->cur += 2; 2740260684Skaiw return (1); 2741260684Skaiw 2742260684Skaiw case SIMPLE_HASH('c', 'v'): 2743260684Skaiw /* operator (cast) */ 2744260684Skaiw if (!cpp_demangle_push_str(ddata, "operator(cast)", 14)) 2745260684Skaiw return (0); 2746260684Skaiw ddata->cur += 2; 2747260684Skaiw return (cpp_demangle_read_type(ddata, 1)); 2748260684Skaiw 2749260684Skaiw case SIMPLE_HASH('d', 'a'): 2750260684Skaiw /* operator delete [] */ 2751260684Skaiw if (!cpp_demangle_push_str(ddata, "operator delete []", 18)) 2752260684Skaiw return (0); 2753260684Skaiw ddata->cur += 2; 2754260684Skaiw return (1); 2755260684Skaiw 2756260684Skaiw case SIMPLE_HASH('d', 'e'): 2757260684Skaiw /* operator * (unary) */ 2758260684Skaiw if (!cpp_demangle_push_str(ddata, "operator*", 9)) 2759260684Skaiw return (0); 2760260684Skaiw ddata->cur += 2; 2761260684Skaiw return (1); 2762260684Skaiw 2763260684Skaiw case SIMPLE_HASH('d', 'l'): 2764260684Skaiw /* operator delete */ 2765260684Skaiw if (!cpp_demangle_push_str(ddata, "operator delete", 15)) 2766260684Skaiw return (0); 2767260684Skaiw ddata->cur += 2; 2768260684Skaiw return (1); 2769260684Skaiw 2770260684Skaiw case SIMPLE_HASH('d', 'v'): 2771260684Skaiw /* operator / */ 2772260684Skaiw if (!cpp_demangle_push_str(ddata, "operator/", 9)) 2773260684Skaiw return (0); 2774260684Skaiw ddata->cur += 2; 2775260684Skaiw return (1); 2776260684Skaiw 2777260684Skaiw case SIMPLE_HASH('d', 'V'): 2778260684Skaiw /* operator /= */ 2779260684Skaiw if (!cpp_demangle_push_str(ddata, "operator/=", 10)) 2780260684Skaiw return (0); 2781260684Skaiw ddata->cur += 2; 2782260684Skaiw return (1); 2783260684Skaiw 2784260684Skaiw case SIMPLE_HASH('e', 'o'): 2785260684Skaiw /* operator ^ */ 2786260684Skaiw if (!cpp_demangle_push_str(ddata, "operator^", 9)) 2787260684Skaiw return (0); 2788260684Skaiw ddata->cur += 2; 2789260684Skaiw return (1); 2790260684Skaiw 2791260684Skaiw case SIMPLE_HASH('e', 'O'): 2792260684Skaiw /* operator ^= */ 2793260684Skaiw if (!cpp_demangle_push_str(ddata, "operator^=", 10)) 2794260684Skaiw return (0); 2795260684Skaiw ddata->cur += 2; 2796260684Skaiw return (1); 2797260684Skaiw 2798260684Skaiw case SIMPLE_HASH('e', 'q'): 2799260684Skaiw /* operator == */ 2800260684Skaiw if (!cpp_demangle_push_str(ddata, "operator==", 10)) 2801260684Skaiw return (0); 2802260684Skaiw ddata->cur += 2; 2803260684Skaiw return (1); 2804260684Skaiw 2805260684Skaiw case SIMPLE_HASH('g', 'e'): 2806260684Skaiw /* operator >= */ 2807260684Skaiw if (!cpp_demangle_push_str(ddata, "operator>=", 10)) 2808260684Skaiw return (0); 2809260684Skaiw ddata->cur += 2; 2810260684Skaiw return (1); 2811260684Skaiw 2812260684Skaiw case SIMPLE_HASH('g', 't'): 2813260684Skaiw /* operator > */ 2814260684Skaiw if (!cpp_demangle_push_str(ddata, "operator>", 9)) 2815260684Skaiw return (0); 2816260684Skaiw ddata->cur += 2; 2817260684Skaiw return (1); 2818260684Skaiw 2819260684Skaiw case SIMPLE_HASH('i', 'x'): 2820260684Skaiw /* operator [] */ 2821260684Skaiw if (!cpp_demangle_push_str(ddata, "operator[]", 10)) 2822260684Skaiw return (0); 2823260684Skaiw ddata->cur += 2; 2824260684Skaiw return (1); 2825260684Skaiw 2826260684Skaiw case SIMPLE_HASH('l', 'e'): 2827260684Skaiw /* operator <= */ 2828260684Skaiw if (!cpp_demangle_push_str(ddata, "operator<=", 10)) 2829260684Skaiw return (0); 2830260684Skaiw ddata->cur += 2; 2831260684Skaiw return (1); 2832260684Skaiw 2833260684Skaiw case SIMPLE_HASH('l', 's'): 2834260684Skaiw /* operator << */ 2835260684Skaiw if (!cpp_demangle_push_str(ddata, "operator<<", 10)) 2836260684Skaiw return (0); 2837260684Skaiw ddata->cur += 2; 2838260684Skaiw return (1); 2839260684Skaiw 2840260684Skaiw case SIMPLE_HASH('l', 'S'): 2841260684Skaiw /* operator <<= */ 2842260684Skaiw if (!cpp_demangle_push_str(ddata, "operator<<=", 11)) 2843260684Skaiw return (0); 2844260684Skaiw ddata->cur += 2; 2845260684Skaiw return (1); 2846260684Skaiw 2847260684Skaiw case SIMPLE_HASH('l', 't'): 2848260684Skaiw /* operator < */ 2849260684Skaiw if (!cpp_demangle_push_str(ddata, "operator<", 9)) 2850260684Skaiw return (0); 2851260684Skaiw ddata->cur += 2; 2852260684Skaiw return (1); 2853260684Skaiw 2854260684Skaiw case SIMPLE_HASH('m', 'i'): 2855260684Skaiw /* operator - */ 2856260684Skaiw if (!cpp_demangle_push_str(ddata, "operator-", 9)) 2857260684Skaiw return (0); 2858260684Skaiw ddata->cur += 2; 2859260684Skaiw return (1); 2860260684Skaiw 2861260684Skaiw case SIMPLE_HASH('m', 'I'): 2862260684Skaiw /* operator -= */ 2863260684Skaiw if (!cpp_demangle_push_str(ddata, "operator-=", 10)) 2864260684Skaiw return (0); 2865260684Skaiw ddata->cur += 2; 2866260684Skaiw return (1); 2867260684Skaiw 2868260684Skaiw case SIMPLE_HASH('m', 'l'): 2869260684Skaiw /* operator * */ 2870260684Skaiw if (!cpp_demangle_push_str(ddata, "operator*", 9)) 2871260684Skaiw return (0); 2872260684Skaiw ddata->cur += 2; 2873260684Skaiw return (1); 2874260684Skaiw 2875260684Skaiw case SIMPLE_HASH('m', 'L'): 2876260684Skaiw /* operator *= */ 2877260684Skaiw if (!cpp_demangle_push_str(ddata, "operator*=", 10)) 2878260684Skaiw return (0); 2879260684Skaiw ddata->cur += 2; 2880260684Skaiw return (1); 2881260684Skaiw 2882260684Skaiw case SIMPLE_HASH('m', 'm'): 2883260684Skaiw /* operator -- */ 2884260684Skaiw if (!cpp_demangle_push_str(ddata, "operator--", 10)) 2885260684Skaiw return (0); 2886260684Skaiw ddata->cur += 2; 2887260684Skaiw return (1); 2888260684Skaiw 2889260684Skaiw case SIMPLE_HASH('n', 'a'): 2890260684Skaiw /* operator new[] */ 2891260684Skaiw if (!cpp_demangle_push_str(ddata, "operator new []", 15)) 2892260684Skaiw return (0); 2893260684Skaiw ddata->cur += 2; 2894260684Skaiw return (1); 2895260684Skaiw 2896260684Skaiw case SIMPLE_HASH('n', 'e'): 2897260684Skaiw /* operator != */ 2898260684Skaiw if (!cpp_demangle_push_str(ddata, "operator!=", 10)) 2899260684Skaiw return (0); 2900260684Skaiw ddata->cur += 2; 2901260684Skaiw return (1); 2902260684Skaiw 2903260684Skaiw case SIMPLE_HASH('n', 'g'): 2904260684Skaiw /* operator - (unary) */ 2905260684Skaiw if (!cpp_demangle_push_str(ddata, "operator-", 9)) 2906260684Skaiw return (0); 2907260684Skaiw ddata->cur += 2; 2908260684Skaiw return (1); 2909260684Skaiw 2910260684Skaiw case SIMPLE_HASH('n', 't'): 2911260684Skaiw /* operator ! */ 2912260684Skaiw if (!cpp_demangle_push_str(ddata, "operator!", 9)) 2913260684Skaiw return (0); 2914260684Skaiw ddata->cur += 2; 2915260684Skaiw return (1); 2916260684Skaiw 2917260684Skaiw case SIMPLE_HASH('n', 'w'): 2918260684Skaiw /* operator new */ 2919260684Skaiw if (!cpp_demangle_push_str(ddata, "operator new", 12)) 2920260684Skaiw return (0); 2921260684Skaiw ddata->cur += 2; 2922260684Skaiw return (1); 2923260684Skaiw 2924260684Skaiw case SIMPLE_HASH('o', 'o'): 2925260684Skaiw /* operator || */ 2926260684Skaiw if (!cpp_demangle_push_str(ddata, "operator||", 10)) 2927260684Skaiw return (0); 2928260684Skaiw ddata->cur += 2; 2929260684Skaiw return (1); 2930260684Skaiw 2931260684Skaiw case SIMPLE_HASH('o', 'r'): 2932260684Skaiw /* operator | */ 2933260684Skaiw if (!cpp_demangle_push_str(ddata, "operator|", 9)) 2934260684Skaiw return (0); 2935260684Skaiw ddata->cur += 2; 2936260684Skaiw return (1); 2937260684Skaiw 2938260684Skaiw case SIMPLE_HASH('o', 'R'): 2939260684Skaiw /* operator |= */ 2940260684Skaiw if (!cpp_demangle_push_str(ddata, "operator|=", 10)) 2941260684Skaiw return (0); 2942260684Skaiw ddata->cur += 2; 2943260684Skaiw return (1); 2944260684Skaiw 2945260684Skaiw case SIMPLE_HASH('p', 'l'): 2946260684Skaiw /* operator + */ 2947260684Skaiw if (!cpp_demangle_push_str(ddata, "operator+", 9)) 2948260684Skaiw return (0); 2949260684Skaiw ddata->cur += 2; 2950260684Skaiw return (1); 2951260684Skaiw 2952260684Skaiw case SIMPLE_HASH('p', 'L'): 2953260684Skaiw /* operator += */ 2954260684Skaiw if (!cpp_demangle_push_str(ddata, "operator+=", 10)) 2955260684Skaiw return (0); 2956260684Skaiw ddata->cur += 2; 2957260684Skaiw return (1); 2958260684Skaiw 2959260684Skaiw case SIMPLE_HASH('p', 'm'): 2960260684Skaiw /* operator ->* */ 2961260684Skaiw if (!cpp_demangle_push_str(ddata, "operator->*", 11)) 2962260684Skaiw return (0); 2963260684Skaiw ddata->cur += 2; 2964260684Skaiw return (1); 2965260684Skaiw 2966260684Skaiw case SIMPLE_HASH('p', 'p'): 2967260684Skaiw /* operator ++ */ 2968260684Skaiw if (!cpp_demangle_push_str(ddata, "operator++", 10)) 2969260684Skaiw return (0); 2970260684Skaiw ddata->cur += 2; 2971260684Skaiw return (1); 2972260684Skaiw 2973260684Skaiw case SIMPLE_HASH('p', 's'): 2974260684Skaiw /* operator + (unary) */ 2975260684Skaiw if (!cpp_demangle_push_str(ddata, "operator+", 9)) 2976260684Skaiw return (0); 2977260684Skaiw ddata->cur += 2; 2978260684Skaiw return (1); 2979260684Skaiw 2980260684Skaiw case SIMPLE_HASH('p', 't'): 2981260684Skaiw /* operator -> */ 2982260684Skaiw if (!cpp_demangle_push_str(ddata, "operator->", 10)) 2983260684Skaiw return (0); 2984260684Skaiw ddata->cur += 2; 2985260684Skaiw return (1); 2986260684Skaiw 2987260684Skaiw case SIMPLE_HASH('q', 'u'): 2988260684Skaiw /* operator ? */ 2989260684Skaiw if (!cpp_demangle_push_str(ddata, "operator?", 9)) 2990260684Skaiw return (0); 2991260684Skaiw ddata->cur += 2; 2992260684Skaiw return (1); 2993260684Skaiw 2994260684Skaiw case SIMPLE_HASH('r', 'm'): 2995260684Skaiw /* operator % */ 2996260684Skaiw if (!cpp_demangle_push_str(ddata, "operator%", 9)) 2997260684Skaiw return (0); 2998260684Skaiw ddata->cur += 2; 2999260684Skaiw return (1); 3000260684Skaiw 3001260684Skaiw case SIMPLE_HASH('r', 'M'): 3002260684Skaiw /* operator %= */ 3003260684Skaiw if (!cpp_demangle_push_str(ddata, "operator%=", 10)) 3004260684Skaiw return (0); 3005260684Skaiw ddata->cur += 2; 3006260684Skaiw return (1); 3007260684Skaiw 3008260684Skaiw case SIMPLE_HASH('r', 's'): 3009260684Skaiw /* operator >> */ 3010260684Skaiw if (!cpp_demangle_push_str(ddata, "operator>>", 10)) 3011260684Skaiw return (0); 3012260684Skaiw ddata->cur += 2; 3013260684Skaiw return (1); 3014260684Skaiw 3015260684Skaiw case SIMPLE_HASH('r', 'S'): 3016260684Skaiw /* operator >>= */ 3017260684Skaiw if (!cpp_demangle_push_str(ddata, "operator>>=", 11)) 3018260684Skaiw return (0); 3019260684Skaiw ddata->cur += 2; 3020260684Skaiw return (1); 3021260684Skaiw 3022260684Skaiw case SIMPLE_HASH('r', 'z'): 3023260684Skaiw /* operator sizeof */ 3024260684Skaiw if (!cpp_demangle_push_str(ddata, "operator sizeof ", 16)) 3025260684Skaiw return (0); 3026260684Skaiw ddata->cur += 2; 3027260684Skaiw return (1); 3028260684Skaiw 3029260684Skaiw case SIMPLE_HASH('s', 'r'): 3030260684Skaiw /* scope resolution operator */ 3031260684Skaiw if (!cpp_demangle_push_str(ddata, "scope resolution operator ", 3032260684Skaiw 26)) 3033260684Skaiw return (0); 3034260684Skaiw ddata->cur += 2; 3035260684Skaiw return (1); 3036260684Skaiw 3037260684Skaiw case SIMPLE_HASH('s', 'v'): 3038260684Skaiw /* operator sizeof */ 3039260684Skaiw if (!cpp_demangle_push_str(ddata, "operator sizeof ", 16)) 3040260684Skaiw return (0); 3041260684Skaiw ddata->cur += 2; 3042260684Skaiw return (1); 3043300311Semaste } 3044260684Skaiw 3045260684Skaiw /* vendor extened operator */ 3046260684Skaiw if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) { 3047260684Skaiw if (!cpp_demangle_push_str(ddata, "vendor extened operator ", 3048260684Skaiw 24)) 3049260684Skaiw return (0); 3050260684Skaiw if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1)) 3051260684Skaiw return (0); 3052260684Skaiw ddata->cur += 2; 3053260684Skaiw return (cpp_demangle_read_sname(ddata)); 3054260684Skaiw } 3055260684Skaiw 3056260684Skaiw /* ctor-dtor-name */ 3057260684Skaiw switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 3058260684Skaiw case SIMPLE_HASH('C', '1'): 3059260684Skaiw /* FALLTHROUGH */ 3060260684Skaiw case SIMPLE_HASH('C', '2'): 3061260684Skaiw /* FALLTHROUGH */ 3062260684Skaiw case SIMPLE_HASH('C', '3'): 3063260684Skaiw if (ddata->last_sname == NULL) 3064260684Skaiw return (0); 3065260684Skaiw if ((len = strlen(ddata->last_sname)) == 0) 3066260684Skaiw return (0); 3067260684Skaiw if (!cpp_demangle_push_str(ddata, "::", 2)) 3068260684Skaiw return (0); 3069260684Skaiw if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) 3070260684Skaiw return (0); 3071260684Skaiw ddata->cur +=2; 3072260684Skaiw return (1); 3073260684Skaiw 3074260684Skaiw case SIMPLE_HASH('D', '0'): 3075260684Skaiw /* FALLTHROUGH */ 3076260684Skaiw case SIMPLE_HASH('D', '1'): 3077260684Skaiw /* FALLTHROUGH */ 3078260684Skaiw case SIMPLE_HASH('D', '2'): 3079260684Skaiw if (ddata->last_sname == NULL) 3080260684Skaiw return (0); 3081260684Skaiw if ((len = strlen(ddata->last_sname)) == 0) 3082260684Skaiw return (0); 3083260684Skaiw if (!cpp_demangle_push_str(ddata, "::~", 3)) 3084260684Skaiw return (0); 3085260684Skaiw if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) 3086260684Skaiw return (0); 3087260684Skaiw ddata->cur +=2; 3088260684Skaiw return (1); 3089300311Semaste } 3090260684Skaiw 3091260684Skaiw /* source name */ 3092260684Skaiw if (ELFTC_ISDIGIT(*ddata->cur) != 0) 3093260684Skaiw return (cpp_demangle_read_sname(ddata)); 3094260684Skaiw 3095260684Skaiw /* local source name */ 3096260684Skaiw if (*ddata->cur == 'L') 3097260684Skaiw return (cpp_demangle_local_source_name(ddata)); 3098260684Skaiw 3099260684Skaiw return (1); 3100260684Skaiw} 3101260684Skaiw 3102260684Skaiw/* 3103260684Skaiw * Read local source name. 3104260684Skaiw * 3105260684Skaiw * References: 3106260684Skaiw * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 3107260684Skaiw * http://gcc.gnu.org/viewcvs?view=rev&revision=124467 3108260684Skaiw */ 3109260684Skaiwstatic int 3110260684Skaiwcpp_demangle_local_source_name(struct cpp_demangle_data *ddata) 3111260684Skaiw{ 3112260684Skaiw /* L */ 3113260684Skaiw if (ddata == NULL || *ddata->cur != 'L') 3114260684Skaiw return (0); 3115260684Skaiw ++ddata->cur; 3116260684Skaiw 3117260684Skaiw /* source name */ 3118260684Skaiw if (!cpp_demangle_read_sname(ddata)) 3119260684Skaiw return (0); 3120260684Skaiw 3121260684Skaiw /* discriminator */ 3122260684Skaiw if (*ddata->cur == '_') { 3123260684Skaiw ++ddata->cur; 3124260684Skaiw while (ELFTC_ISDIGIT(*ddata->cur) != 0) 3125260684Skaiw ++ddata->cur; 3126260684Skaiw } 3127260684Skaiw 3128260684Skaiw return (1); 3129260684Skaiw} 3130260684Skaiw 3131260684Skaiwstatic int 3132260684Skaiwcpp_demangle_read_v_offset(struct cpp_demangle_data *ddata) 3133260684Skaiw{ 3134260684Skaiw 3135260684Skaiw if (ddata == NULL) 3136260684Skaiw return (0); 3137260684Skaiw 3138260684Skaiw if (!cpp_demangle_push_str(ddata, "offset : ", 9)) 3139260684Skaiw return (0); 3140260684Skaiw 3141260684Skaiw if (!cpp_demangle_read_offset_number(ddata)) 3142260684Skaiw return (0); 3143260684Skaiw 3144260684Skaiw if (!cpp_demangle_push_str(ddata, "virtual offset : ", 17)) 3145260684Skaiw return (0); 3146260684Skaiw 3147260684Skaiw return (!cpp_demangle_read_offset_number(ddata)); 3148260684Skaiw} 3149260684Skaiw 3150260684Skaiw/* 3151260684Skaiw * Decode floating point representation to string 3152260684Skaiw * Return new allocated string or NULL 3153260684Skaiw * 3154260684Skaiw * Todo 3155260684Skaiw * Replace these functions to macro. 3156260684Skaiw */ 3157260684Skaiwstatic char * 3158260684Skaiwdecode_fp_to_double(const char *p, size_t len) 3159260684Skaiw{ 3160260684Skaiw double f; 3161260684Skaiw size_t rtn_len, limit, i; 3162260684Skaiw int byte; 3163260684Skaiw char *rtn; 3164260684Skaiw 3165260684Skaiw if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double)) 3166260684Skaiw return (NULL); 3167260684Skaiw 3168260684Skaiw memset(&f, 0, sizeof(double)); 3169260684Skaiw 3170260684Skaiw for (i = 0; i < len / 2; ++i) { 3171260684Skaiw byte = hex_to_dec(p[len - i * 2 - 1]) + 3172260684Skaiw hex_to_dec(p[len - i * 2 - 2]) * 16; 3173260684Skaiw 3174260684Skaiw if (byte < 0 || byte > 255) 3175260684Skaiw return (NULL); 3176260684Skaiw 3177260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3178260684Skaiw ((unsigned char *)&f)[i] = (unsigned char)(byte); 3179260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3180260684Skaiw ((unsigned char *)&f)[sizeof(double) - i - 1] = 3181260684Skaiw (unsigned char)(byte); 3182260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3183260684Skaiw } 3184260684Skaiw 3185260684Skaiw rtn_len = 64; 3186260684Skaiw limit = 0; 3187260684Skaiwagain: 3188260684Skaiw if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3189260684Skaiw return (NULL); 3190260684Skaiw 3191260684Skaiw if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) { 3192260684Skaiw free(rtn); 3193260684Skaiw if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3194260684Skaiw return (NULL); 3195260684Skaiw rtn_len *= BUFFER_GROWFACTOR; 3196260684Skaiw goto again; 3197260684Skaiw } 3198260684Skaiw 3199260684Skaiw return rtn; 3200260684Skaiw} 3201260684Skaiw 3202260684Skaiwstatic char * 3203260684Skaiwdecode_fp_to_float(const char *p, size_t len) 3204260684Skaiw{ 3205260684Skaiw size_t i, rtn_len, limit; 3206260684Skaiw float f; 3207260684Skaiw int byte; 3208260684Skaiw char *rtn; 3209260684Skaiw 3210260684Skaiw if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float)) 3211260684Skaiw return (NULL); 3212260684Skaiw 3213260684Skaiw memset(&f, 0, sizeof(float)); 3214260684Skaiw 3215260684Skaiw for (i = 0; i < len / 2; ++i) { 3216260684Skaiw byte = hex_to_dec(p[len - i * 2 - 1]) + 3217260684Skaiw hex_to_dec(p[len - i * 2 - 2]) * 16; 3218260684Skaiw if (byte < 0 || byte > 255) 3219260684Skaiw return (NULL); 3220260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3221260684Skaiw ((unsigned char *)&f)[i] = (unsigned char)(byte); 3222260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3223260684Skaiw ((unsigned char *)&f)[sizeof(float) - i - 1] = 3224260684Skaiw (unsigned char)(byte); 3225260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3226260684Skaiw } 3227260684Skaiw 3228260684Skaiw rtn_len = 64; 3229260684Skaiw limit = 0; 3230260684Skaiwagain: 3231260684Skaiw if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3232260684Skaiw return (NULL); 3233260684Skaiw 3234260684Skaiw if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) { 3235260684Skaiw free(rtn); 3236260684Skaiw if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3237260684Skaiw return (NULL); 3238260684Skaiw rtn_len *= BUFFER_GROWFACTOR; 3239260684Skaiw goto again; 3240260684Skaiw } 3241260684Skaiw 3242260684Skaiw return rtn; 3243260684Skaiw} 3244260684Skaiw 3245260684Skaiwstatic char * 3246260684Skaiwdecode_fp_to_float128(const char *p, size_t len) 3247260684Skaiw{ 3248260684Skaiw long double f; 3249260684Skaiw size_t rtn_len, limit, i; 3250260684Skaiw int byte; 3251260684Skaiw unsigned char buf[FLOAT_QUADRUPLE_BYTES]; 3252260684Skaiw char *rtn; 3253260684Skaiw 3254260684Skaiw switch(sizeof(long double)) { 3255260684Skaiw case FLOAT_QUADRUPLE_BYTES: 3256260684Skaiw return (decode_fp_to_long_double(p, len)); 3257260684Skaiw case FLOAT_EXTENED_BYTES: 3258260684Skaiw if (p == NULL || len == 0 || len % 2 != 0 || 3259260684Skaiw len / 2 > FLOAT_QUADRUPLE_BYTES) 3260260684Skaiw return (NULL); 3261260684Skaiw 3262260684Skaiw memset(buf, 0, FLOAT_QUADRUPLE_BYTES); 3263260684Skaiw 3264260684Skaiw for (i = 0; i < len / 2; ++i) { 3265260684Skaiw byte = hex_to_dec(p[len - i * 2 - 1]) + 3266260684Skaiw hex_to_dec(p[len - i * 2 - 2]) * 16; 3267260684Skaiw if (byte < 0 || byte > 255) 3268260684Skaiw return (NULL); 3269260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3270260684Skaiw buf[i] = (unsigned char)(byte); 3271260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3272260684Skaiw buf[FLOAT_QUADRUPLE_BYTES - i -1] = 3273260684Skaiw (unsigned char)(byte); 3274260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3275260684Skaiw } 3276260684Skaiw memset(&f, 0, FLOAT_EXTENED_BYTES); 3277260684Skaiw 3278260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3279260684Skaiw memcpy(&f, buf, FLOAT_EXTENED_BYTES); 3280260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3281260684Skaiw memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES); 3282260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3283260684Skaiw 3284260684Skaiw rtn_len = 256; 3285260684Skaiw limit = 0; 3286260684Skaiwagain: 3287260684Skaiw if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3288260684Skaiw return (NULL); 3289260684Skaiw 3290260684Skaiw if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 3291260684Skaiw free(rtn); 3292260684Skaiw if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3293260684Skaiw return (NULL); 3294260684Skaiw rtn_len *= BUFFER_GROWFACTOR; 3295260684Skaiw goto again; 3296260684Skaiw } 3297260684Skaiw 3298260684Skaiw return (rtn); 3299260684Skaiw default: 3300260684Skaiw return (NULL); 3301260684Skaiw } 3302260684Skaiw} 3303260684Skaiw 3304260684Skaiwstatic char * 3305260684Skaiwdecode_fp_to_float80(const char *p, size_t len) 3306260684Skaiw{ 3307260684Skaiw long double f; 3308260684Skaiw size_t rtn_len, limit, i; 3309260684Skaiw int byte; 3310260684Skaiw unsigned char buf[FLOAT_EXTENED_BYTES]; 3311260684Skaiw char *rtn; 3312260684Skaiw 3313260684Skaiw switch(sizeof(long double)) { 3314260684Skaiw case FLOAT_QUADRUPLE_BYTES: 3315260684Skaiw if (p == NULL || len == 0 || len % 2 != 0 || 3316260684Skaiw len / 2 > FLOAT_EXTENED_BYTES) 3317260684Skaiw return (NULL); 3318260684Skaiw 3319260684Skaiw memset(buf, 0, FLOAT_EXTENED_BYTES); 3320260684Skaiw 3321260684Skaiw for (i = 0; i < len / 2; ++i) { 3322260684Skaiw byte = hex_to_dec(p[len - i * 2 - 1]) + 3323260684Skaiw hex_to_dec(p[len - i * 2 - 2]) * 16; 3324260684Skaiw 3325260684Skaiw if (byte < 0 || byte > 255) 3326260684Skaiw return (NULL); 3327260684Skaiw 3328260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3329260684Skaiw buf[i] = (unsigned char)(byte); 3330260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3331260684Skaiw buf[FLOAT_EXTENED_BYTES - i -1] = 3332260684Skaiw (unsigned char)(byte); 3333260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3334260684Skaiw } 3335260684Skaiw 3336260684Skaiw memset(&f, 0, FLOAT_QUADRUPLE_BYTES); 3337260684Skaiw 3338260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3339260684Skaiw memcpy(&f, buf, FLOAT_EXTENED_BYTES); 3340260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3341260684Skaiw memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENED_BYTES); 3342260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3343260684Skaiw 3344260684Skaiw rtn_len = 256; 3345260684Skaiw limit = 0; 3346260684Skaiwagain: 3347260684Skaiw if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3348260684Skaiw return (NULL); 3349260684Skaiw 3350260684Skaiw if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 3351260684Skaiw free(rtn); 3352260684Skaiw if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3353260684Skaiw return (NULL); 3354260684Skaiw rtn_len *= BUFFER_GROWFACTOR; 3355260684Skaiw goto again; 3356260684Skaiw } 3357260684Skaiw 3358260684Skaiw return (rtn); 3359260684Skaiw case FLOAT_EXTENED_BYTES: 3360260684Skaiw return (decode_fp_to_long_double(p, len)); 3361260684Skaiw default: 3362260684Skaiw return (NULL); 3363260684Skaiw } 3364260684Skaiw} 3365260684Skaiw 3366260684Skaiwstatic char * 3367260684Skaiwdecode_fp_to_long_double(const char *p, size_t len) 3368260684Skaiw{ 3369260684Skaiw long double f; 3370260684Skaiw size_t rtn_len, limit, i; 3371260684Skaiw int byte; 3372260684Skaiw char *rtn; 3373260684Skaiw 3374260684Skaiw if (p == NULL || len == 0 || len % 2 != 0 || 3375260684Skaiw len / 2 > sizeof(long double)) 3376260684Skaiw return (NULL); 3377260684Skaiw 3378260684Skaiw memset(&f, 0, sizeof(long double)); 3379260684Skaiw 3380260684Skaiw for (i = 0; i < len / 2; ++i) { 3381260684Skaiw byte = hex_to_dec(p[len - i * 2 - 1]) + 3382260684Skaiw hex_to_dec(p[len - i * 2 - 2]) * 16; 3383260684Skaiw 3384260684Skaiw if (byte < 0 || byte > 255) 3385260684Skaiw return (NULL); 3386260684Skaiw 3387260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3388260684Skaiw ((unsigned char *)&f)[i] = (unsigned char)(byte); 3389260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3390260684Skaiw ((unsigned char *)&f)[sizeof(long double) - i - 1] = 3391260684Skaiw (unsigned char)(byte); 3392260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3393260684Skaiw } 3394260684Skaiw 3395260684Skaiw rtn_len = 256; 3396260684Skaiw limit = 0; 3397260684Skaiwagain: 3398260684Skaiw if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3399260684Skaiw return (NULL); 3400260684Skaiw 3401260684Skaiw if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 3402260684Skaiw free(rtn); 3403260684Skaiw if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3404260684Skaiw return (NULL); 3405260684Skaiw rtn_len *= BUFFER_GROWFACTOR; 3406260684Skaiw goto again; 3407260684Skaiw } 3408260684Skaiw 3409260684Skaiw return (rtn); 3410260684Skaiw} 3411260684Skaiw 3412260684Skaiw/* Simple hex to integer function used by decode_to_* function. */ 3413260684Skaiwstatic int 3414260684Skaiwhex_to_dec(char c) 3415260684Skaiw{ 3416260684Skaiw 3417260684Skaiw switch (c) { 3418260684Skaiw case '0': 3419260684Skaiw return (0); 3420260684Skaiw case '1': 3421260684Skaiw return (1); 3422260684Skaiw case '2': 3423260684Skaiw return (2); 3424260684Skaiw case '3': 3425260684Skaiw return (3); 3426260684Skaiw case '4': 3427260684Skaiw return (4); 3428260684Skaiw case '5': 3429260684Skaiw return (5); 3430260684Skaiw case '6': 3431260684Skaiw return (6); 3432260684Skaiw case '7': 3433260684Skaiw return (7); 3434260684Skaiw case '8': 3435260684Skaiw return (8); 3436260684Skaiw case '9': 3437260684Skaiw return (9); 3438260684Skaiw case 'a': 3439260684Skaiw return (10); 3440260684Skaiw case 'b': 3441260684Skaiw return (11); 3442260684Skaiw case 'c': 3443260684Skaiw return (12); 3444260684Skaiw case 'd': 3445260684Skaiw return (13); 3446260684Skaiw case 'e': 3447260684Skaiw return (14); 3448260684Skaiw case 'f': 3449260684Skaiw return (15); 3450260684Skaiw default: 3451260684Skaiw return (-1); 3452300311Semaste } 3453260684Skaiw} 3454260684Skaiw 3455260684Skaiw/** 3456260684Skaiw * @brief Test input string is mangled by IA-64 C++ ABI style. 3457260684Skaiw * 3458260684Skaiw * Test string heads with "_Z" or "_GLOBAL__I_". 3459260684Skaiw * @return Return 0 at false. 3460260684Skaiw */ 3461260684Skaiwbool 3462260684Skaiwis_cpp_mangled_gnu3(const char *org) 3463260684Skaiw{ 3464260684Skaiw size_t len; 3465260684Skaiw 3466260684Skaiw len = strlen(org); 3467260684Skaiw return ((len > 2 && *org == '_' && *(org + 1) == 'Z') || 3468260684Skaiw (len > 11 && !strncmp(org, "_GLOBAL__I_", 11))); 3469260684Skaiw} 3470260684Skaiw 3471260684Skaiwstatic void 3472260684Skaiwvector_read_cmd_dest(struct vector_read_cmd *v) 3473260684Skaiw{ 3474260684Skaiw 3475260684Skaiw if (v == NULL) 3476260684Skaiw return; 3477260684Skaiw 3478260684Skaiw free(v->r_container); 3479260684Skaiw} 3480260684Skaiw 3481260684Skaiw/* return -1 at failed, 0 at not found, 1 at found. */ 3482260684Skaiwstatic int 3483260684Skaiwvector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst) 3484260684Skaiw{ 3485260684Skaiw size_t i; 3486260684Skaiw 3487260684Skaiw if (v == NULL || dst == READ_FAIL) 3488260684Skaiw return (-1); 3489260684Skaiw 3490260684Skaiw for (i = 0; i < v->size; ++i) 3491260684Skaiw if (v->r_container[i] == dst) 3492260684Skaiw return (1); 3493260684Skaiw 3494260684Skaiw return (0); 3495260684Skaiw} 3496260684Skaiw 3497260684Skaiwstatic int 3498260684Skaiwvector_read_cmd_init(struct vector_read_cmd *v) 3499260684Skaiw{ 3500260684Skaiw 3501260684Skaiw if (v == NULL) 3502260684Skaiw return (0); 3503260684Skaiw 3504260684Skaiw v->size = 0; 3505260684Skaiw v->capacity = VECTOR_DEF_CAPACITY; 3506260684Skaiw 3507260684Skaiw if ((v->r_container = malloc(sizeof(enum read_cmd) * v->capacity)) 3508260684Skaiw == NULL) 3509260684Skaiw return (0); 3510260684Skaiw 3511260684Skaiw return (1); 3512260684Skaiw} 3513260684Skaiw 3514260684Skaiwstatic int 3515260684Skaiwvector_read_cmd_pop(struct vector_read_cmd *v) 3516260684Skaiw{ 3517260684Skaiw 3518260684Skaiw if (v == NULL || v->size == 0) 3519260684Skaiw return (0); 3520260684Skaiw 3521260684Skaiw --v->size; 3522260684Skaiw v->r_container[v->size] = READ_FAIL; 3523260684Skaiw 3524260684Skaiw return (1); 3525260684Skaiw} 3526260684Skaiw 3527260684Skaiwstatic int 3528260684Skaiwvector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd) 3529260684Skaiw{ 3530260684Skaiw enum read_cmd *tmp_r_ctn; 3531260684Skaiw size_t tmp_cap; 3532260684Skaiw size_t i; 3533260684Skaiw 3534260684Skaiw if (v == NULL) 3535260684Skaiw return (0); 3536260684Skaiw 3537260684Skaiw if (v->size == v->capacity) { 3538260684Skaiw tmp_cap = v->capacity * BUFFER_GROWFACTOR; 3539260684Skaiw if ((tmp_r_ctn = malloc(sizeof(enum read_cmd) * tmp_cap)) 3540260684Skaiw == NULL) 3541260684Skaiw return (0); 3542260684Skaiw for (i = 0; i < v->size; ++i) 3543260684Skaiw tmp_r_ctn[i] = v->r_container[i]; 3544260684Skaiw free(v->r_container); 3545260684Skaiw v->r_container = tmp_r_ctn; 3546260684Skaiw v->capacity = tmp_cap; 3547260684Skaiw } 3548260684Skaiw 3549260684Skaiw v->r_container[v->size] = cmd; 3550260684Skaiw ++v->size; 3551260684Skaiw 3552260684Skaiw return (1); 3553260684Skaiw} 3554260684Skaiw 3555260684Skaiwstatic void 3556260684Skaiwvector_type_qualifier_dest(struct vector_type_qualifier *v) 3557260684Skaiw{ 3558260684Skaiw 3559260684Skaiw if (v == NULL) 3560260684Skaiw return; 3561260684Skaiw 3562260684Skaiw free(v->q_container); 3563260684Skaiw vector_str_dest(&v->ext_name); 3564260684Skaiw} 3565260684Skaiw 3566260684Skaiw/* size, capacity, ext_name */ 3567260684Skaiwstatic int 3568260684Skaiwvector_type_qualifier_init(struct vector_type_qualifier *v) 3569260684Skaiw{ 3570260684Skaiw 3571260684Skaiw if (v == NULL) 3572260684Skaiw return (0); 3573260684Skaiw 3574260684Skaiw v->size = 0; 3575260684Skaiw v->capacity = VECTOR_DEF_CAPACITY; 3576260684Skaiw 3577260684Skaiw if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity)) 3578260684Skaiw == NULL) 3579260684Skaiw return (0); 3580260684Skaiw 3581260684Skaiw assert(v->q_container != NULL); 3582260684Skaiw 3583260684Skaiw if (vector_str_init(&v->ext_name) == false) { 3584260684Skaiw free(v->q_container); 3585260684Skaiw return (0); 3586260684Skaiw } 3587260684Skaiw 3588260684Skaiw return (1); 3589260684Skaiw} 3590260684Skaiw 3591260684Skaiwstatic int 3592260684Skaiwvector_type_qualifier_push(struct vector_type_qualifier *v, 3593260684Skaiw enum type_qualifier t) 3594260684Skaiw{ 3595260684Skaiw enum type_qualifier *tmp_ctn; 3596260684Skaiw size_t tmp_cap; 3597260684Skaiw size_t i; 3598260684Skaiw 3599260684Skaiw if (v == NULL) 3600260684Skaiw return (0); 3601260684Skaiw 3602260684Skaiw if (v->size == v->capacity) { 3603260684Skaiw tmp_cap = v->capacity * BUFFER_GROWFACTOR; 3604260684Skaiw if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap)) 3605260684Skaiw == NULL) 3606260684Skaiw return (0); 3607260684Skaiw for (i = 0; i < v->size; ++i) 3608260684Skaiw tmp_ctn[i] = v->q_container[i]; 3609260684Skaiw free(v->q_container); 3610260684Skaiw v->q_container = tmp_ctn; 3611260684Skaiw v->capacity = tmp_cap; 3612260684Skaiw } 3613260684Skaiw 3614260684Skaiw v->q_container[v->size] = t; 3615260684Skaiw ++v->size; 3616260684Skaiw 3617260684Skaiw return (1); 3618260684Skaiw} 3619