libelftc_dem_gnu3.c revision 260684
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 39260684SkaiwELFTC_VCSID("$Id: libelftc_dem_gnu3.c 2179 2011-11-18 03:05:47Z jkoshy $"); 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, 53260684Skaiw TYPE_CST 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 */ 87260684Skaiw}; 88260684Skaiw 89260684Skaiw#define CPP_DEMANGLE_TRY_LIMIT 128 90260684Skaiw#define FLOAT_SPRINTF_TRY_LIMIT 5 91260684Skaiw#define FLOAT_QUADRUPLE_BYTES 16 92260684Skaiw#define FLOAT_EXTENED_BYTES 10 93260684Skaiw 94260684Skaiw#define SIMPLE_HASH(x,y) (64 * x + y) 95260684Skaiw 96260684Skaiwstatic void cpp_demangle_data_dest(struct cpp_demangle_data *); 97260684Skaiwstatic int cpp_demangle_data_init(struct cpp_demangle_data *, 98260684Skaiw const char *); 99260684Skaiwstatic int cpp_demangle_get_subst(struct cpp_demangle_data *, size_t); 100260684Skaiwstatic int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t); 101260684Skaiwstatic int cpp_demangle_push_fp(struct cpp_demangle_data *, 102260684Skaiw char *(*)(const char *, size_t)); 103260684Skaiwstatic int cpp_demangle_push_str(struct cpp_demangle_data *, const char *, 104260684Skaiw size_t); 105260684Skaiwstatic int cpp_demangle_push_subst(struct cpp_demangle_data *, 106260684Skaiw const char *, size_t); 107260684Skaiwstatic int cpp_demangle_push_subst_v(struct cpp_demangle_data *, 108260684Skaiw struct vector_str *); 109260684Skaiwstatic int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *, 110260684Skaiw struct vector_type_qualifier *, const char *); 111260684Skaiwstatic int cpp_demangle_read_array(struct cpp_demangle_data *); 112260684Skaiwstatic int cpp_demangle_read_encoding(struct cpp_demangle_data *); 113260684Skaiwstatic int cpp_demangle_read_expr_primary(struct cpp_demangle_data *); 114260684Skaiwstatic int cpp_demangle_read_expression(struct cpp_demangle_data *); 115260684Skaiwstatic int cpp_demangle_read_expression_binary(struct cpp_demangle_data *, 116260684Skaiw const char *, size_t); 117260684Skaiwstatic int cpp_demangle_read_expression_unary(struct cpp_demangle_data *, 118260684Skaiw const char *, size_t); 119260684Skaiwstatic int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *, 120260684Skaiw const char *, size_t, const char *, size_t); 121260684Skaiwstatic int cpp_demangle_read_function(struct cpp_demangle_data *, int *, 122260684Skaiw struct vector_type_qualifier *); 123260684Skaiwstatic int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata); 124260684Skaiwstatic int cpp_demangle_read_local_name(struct cpp_demangle_data *); 125260684Skaiwstatic int cpp_demangle_read_name(struct cpp_demangle_data *); 126260684Skaiwstatic int cpp_demangle_read_nested_name(struct cpp_demangle_data *); 127260684Skaiwstatic int cpp_demangle_read_number(struct cpp_demangle_data *, long *); 128260684Skaiwstatic int cpp_demangle_read_nv_offset(struct cpp_demangle_data *); 129260684Skaiwstatic int cpp_demangle_read_offset(struct cpp_demangle_data *); 130260684Skaiwstatic int cpp_demangle_read_offset_number(struct cpp_demangle_data *); 131260684Skaiwstatic int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *); 132260684Skaiwstatic int cpp_demangle_read_sname(struct cpp_demangle_data *); 133260684Skaiwstatic int cpp_demangle_read_subst(struct cpp_demangle_data *); 134260684Skaiwstatic int cpp_demangle_read_subst_std(struct cpp_demangle_data *); 135260684Skaiwstatic int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *, 136260684Skaiw const char *, size_t); 137260684Skaiwstatic int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *); 138260684Skaiwstatic int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *); 139260684Skaiwstatic int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *); 140260684Skaiwstatic int cpp_demangle_read_type(struct cpp_demangle_data *, int); 141260684Skaiwstatic int cpp_demangle_read_uqname(struct cpp_demangle_data *); 142260684Skaiwstatic int cpp_demangle_read_v_offset(struct cpp_demangle_data *); 143260684Skaiwstatic char *decode_fp_to_double(const char *, size_t); 144260684Skaiwstatic char *decode_fp_to_float(const char *, size_t); 145260684Skaiwstatic char *decode_fp_to_float128(const char *, size_t); 146260684Skaiwstatic char *decode_fp_to_float80(const char *, size_t); 147260684Skaiwstatic char *decode_fp_to_long_double(const char *, size_t); 148260684Skaiwstatic int hex_to_dec(char); 149260684Skaiwstatic void vector_read_cmd_dest(struct vector_read_cmd *); 150260684Skaiwstatic int vector_read_cmd_find(struct vector_read_cmd *, enum read_cmd); 151260684Skaiwstatic int vector_read_cmd_init(struct vector_read_cmd *); 152260684Skaiwstatic int vector_read_cmd_pop(struct vector_read_cmd *); 153260684Skaiwstatic int vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd); 154260684Skaiwstatic void vector_type_qualifier_dest(struct vector_type_qualifier *); 155260684Skaiwstatic int vector_type_qualifier_init(struct vector_type_qualifier *); 156260684Skaiwstatic int vector_type_qualifier_push(struct vector_type_qualifier *, 157260684Skaiw enum type_qualifier); 158260684Skaiw 159260684Skaiwint cpp_demangle_gnu3_push_head; 160260684Skaiw 161260684Skaiw/** 162260684Skaiw * @brief Decode the input string by IA-64 C++ ABI style. 163260684Skaiw * 164260684Skaiw * GNU GCC v3 use IA-64 standard ABI. 165260684Skaiw * @return New allocated demangled string or NULL if failed. 166260684Skaiw * @todo 1. Testing and more test case. 2. Code cleaning. 167260684Skaiw */ 168260684Skaiwchar * 169260684Skaiwcpp_demangle_gnu3(const char *org) 170260684Skaiw{ 171260684Skaiw struct cpp_demangle_data ddata; 172260684Skaiw ssize_t org_len; 173260684Skaiw unsigned int limit; 174260684Skaiw char *rtn; 175260684Skaiw 176260684Skaiw if (org == NULL || (org_len = strlen(org)) < 2) 177260684Skaiw return (NULL); 178260684Skaiw 179260684Skaiw if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) { 180260684Skaiw if ((rtn = malloc(org_len + 19)) == NULL) 181260684Skaiw return (NULL); 182260684Skaiw snprintf(rtn, org_len + 19, 183260684Skaiw "global constructors keyed to %s", org + 11); 184260684Skaiw return (rtn); 185260684Skaiw } 186260684Skaiw 187260684Skaiw if (org[0] != '_' || org[1] != 'Z') 188260684Skaiw return (NULL); 189260684Skaiw 190260684Skaiw if (!cpp_demangle_data_init(&ddata, org + 2)) 191260684Skaiw return (NULL); 192260684Skaiw 193260684Skaiw cpp_demangle_gnu3_push_head = 0; 194260684Skaiw rtn = NULL; 195260684Skaiw 196260684Skaiw if (!cpp_demangle_read_encoding(&ddata)) 197260684Skaiw goto clean; 198260684Skaiw 199260684Skaiw limit = 0; 200260684Skaiw while (*ddata.cur != '\0') { 201260684Skaiw /* 202260684Skaiw * Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4 203260684Skaiw */ 204260684Skaiw if (*ddata.cur == '@' && *(ddata.cur + 1) == '@') 205260684Skaiw break; 206260684Skaiw if (!cpp_demangle_read_type(&ddata, 1)) 207260684Skaiw goto clean; 208260684Skaiw if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 209260684Skaiw goto clean; 210260684Skaiw } 211260684Skaiw 212260684Skaiw if (ddata.output.size == 0) 213260684Skaiw goto clean; 214260684Skaiw if (ddata.paren && !vector_str_push(&ddata.output, ")", 1)) 215260684Skaiw goto clean; 216260684Skaiw if (ddata.mem_vat && !vector_str_push(&ddata.output, " volatile", 9)) 217260684Skaiw goto clean; 218260684Skaiw if (ddata.mem_cst && !vector_str_push(&ddata.output, " const", 6)) 219260684Skaiw goto clean; 220260684Skaiw if (ddata.mem_rst && !vector_str_push(&ddata.output, " restrict", 9)) 221260684Skaiw goto clean; 222260684Skaiw 223260684Skaiw rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL); 224260684Skaiw 225260684Skaiwclean: 226260684Skaiw cpp_demangle_data_dest(&ddata); 227260684Skaiw 228260684Skaiw return (rtn); 229260684Skaiw} 230260684Skaiw 231260684Skaiwstatic void 232260684Skaiwcpp_demangle_data_dest(struct cpp_demangle_data *d) 233260684Skaiw{ 234260684Skaiw 235260684Skaiw if (d == NULL) 236260684Skaiw return; 237260684Skaiw 238260684Skaiw vector_read_cmd_dest(&d->cmd); 239260684Skaiw vector_str_dest(&d->class_type); 240260684Skaiw vector_str_dest(&d->tmpl); 241260684Skaiw vector_str_dest(&d->subst); 242260684Skaiw vector_str_dest(&d->output_tmp); 243260684Skaiw vector_str_dest(&d->output); 244260684Skaiw} 245260684Skaiw 246260684Skaiwstatic int 247260684Skaiwcpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur) 248260684Skaiw{ 249260684Skaiw 250260684Skaiw if (d == NULL || cur == NULL) 251260684Skaiw return (0); 252260684Skaiw 253260684Skaiw if (!vector_str_init(&d->output)) 254260684Skaiw return (0); 255260684Skaiw if (!vector_str_init(&d->output_tmp)) 256260684Skaiw goto clean1; 257260684Skaiw if (!vector_str_init(&d->subst)) 258260684Skaiw goto clean2; 259260684Skaiw if (!vector_str_init(&d->tmpl)) 260260684Skaiw goto clean3; 261260684Skaiw if (!vector_str_init(&d->class_type)) 262260684Skaiw goto clean4; 263260684Skaiw if (!vector_read_cmd_init(&d->cmd)) 264260684Skaiw goto clean5; 265260684Skaiw 266260684Skaiw assert(d->output.container != NULL); 267260684Skaiw assert(d->output_tmp.container != NULL); 268260684Skaiw assert(d->subst.container != NULL); 269260684Skaiw assert(d->tmpl.container != NULL); 270260684Skaiw assert(d->class_type.container != NULL); 271260684Skaiw 272260684Skaiw d->paren = false; 273260684Skaiw d->pfirst = false; 274260684Skaiw d->mem_rst = false; 275260684Skaiw d->mem_vat = false; 276260684Skaiw d->mem_cst = false; 277260684Skaiw d->func_type = 0; 278260684Skaiw d->cur = cur; 279260684Skaiw d->last_sname = NULL; 280260684Skaiw 281260684Skaiw return (1); 282260684Skaiw 283260684Skaiwclean5: 284260684Skaiw vector_str_dest(&d->class_type); 285260684Skaiwclean4: 286260684Skaiw vector_str_dest(&d->tmpl); 287260684Skaiwclean3: 288260684Skaiw vector_str_dest(&d->subst); 289260684Skaiwclean2: 290260684Skaiw vector_str_dest(&d->output_tmp); 291260684Skaiwclean1: 292260684Skaiw vector_str_dest(&d->output); 293260684Skaiw 294260684Skaiw return (0); 295260684Skaiw} 296260684Skaiw 297260684Skaiwstatic int 298260684Skaiwcpp_demangle_push_fp(struct cpp_demangle_data *ddata, 299260684Skaiw char *(*decoder)(const char *, size_t)) 300260684Skaiw{ 301260684Skaiw size_t len; 302260684Skaiw int rtn; 303260684Skaiw const char *fp; 304260684Skaiw char *f; 305260684Skaiw 306260684Skaiw if (ddata == NULL || decoder == NULL) 307260684Skaiw return (0); 308260684Skaiw 309260684Skaiw fp = ddata->cur; 310260684Skaiw while (*ddata->cur != 'E') 311260684Skaiw ++ddata->cur; 312260684Skaiw ++ddata->cur; 313260684Skaiw 314260684Skaiw if ((f = decoder(fp, ddata->cur - fp)) == NULL) 315260684Skaiw return (0); 316260684Skaiw 317260684Skaiw rtn = 0; 318260684Skaiw if ((len = strlen(f)) > 0) 319260684Skaiw rtn = cpp_demangle_push_str(ddata, f, len); 320260684Skaiw 321260684Skaiw free(f); 322260684Skaiw 323260684Skaiw return (rtn); 324260684Skaiw} 325260684Skaiw 326260684Skaiwstatic int 327260684Skaiwcpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str, 328260684Skaiw size_t len) 329260684Skaiw{ 330260684Skaiw 331260684Skaiw if (ddata == NULL || str == NULL || len == 0) 332260684Skaiw return (0); 333260684Skaiw 334260684Skaiw if (cpp_demangle_gnu3_push_head > 0) 335260684Skaiw return (vector_str_push(&ddata->output_tmp, str, len)); 336260684Skaiw 337260684Skaiw return (vector_str_push(&ddata->output, str, len)); 338260684Skaiw} 339260684Skaiw 340260684Skaiwstatic int 341260684Skaiwcpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str, 342260684Skaiw size_t len) 343260684Skaiw{ 344260684Skaiw 345260684Skaiw if (ddata == NULL || str == NULL || len == 0) 346260684Skaiw return (0); 347260684Skaiw 348260684Skaiw if (!vector_str_find(&ddata->subst, str, len)) 349260684Skaiw return (vector_str_push(&ddata->subst, str, len)); 350260684Skaiw 351260684Skaiw return (1); 352260684Skaiw} 353260684Skaiw 354260684Skaiwstatic int 355260684Skaiwcpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v) 356260684Skaiw{ 357260684Skaiw size_t str_len; 358260684Skaiw int rtn; 359260684Skaiw char *str; 360260684Skaiw 361260684Skaiw if (ddata == NULL || v == NULL) 362260684Skaiw return (0); 363260684Skaiw 364260684Skaiw if ((str = vector_str_get_flat(v, &str_len)) == NULL) 365260684Skaiw return (0); 366260684Skaiw 367260684Skaiw rtn = cpp_demangle_push_subst(ddata, str, str_len); 368260684Skaiw 369260684Skaiw free(str); 370260684Skaiw 371260684Skaiw return (rtn); 372260684Skaiw} 373260684Skaiw 374260684Skaiwstatic int 375260684Skaiwcpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata, 376260684Skaiw struct vector_type_qualifier *v, const char *type_str) 377260684Skaiw{ 378260684Skaiw struct vector_str subst_v; 379260684Skaiw size_t idx, e_idx, e_len; 380260684Skaiw int rtn; 381260684Skaiw char *buf; 382260684Skaiw 383260684Skaiw if (ddata == NULL || v == NULL) 384260684Skaiw return (0); 385260684Skaiw 386260684Skaiw if ((idx = v->size) == 0) 387260684Skaiw return (1); 388260684Skaiw 389260684Skaiw rtn = 0; 390260684Skaiw if (type_str != NULL) { 391260684Skaiw if (!vector_str_init(&subst_v)) 392260684Skaiw return (0); 393260684Skaiw if (!vector_str_push(&subst_v, type_str, strlen(type_str))) 394260684Skaiw goto clean; 395260684Skaiw } 396260684Skaiw 397260684Skaiw e_idx = 0; 398260684Skaiw while (idx > 0) { 399260684Skaiw switch (v->q_container[idx - 1]) { 400260684Skaiw case TYPE_PTR: 401260684Skaiw if (!cpp_demangle_push_str(ddata, "*", 1)) 402260684Skaiw goto clean; 403260684Skaiw if (type_str != NULL) { 404260684Skaiw if (!vector_str_push(&subst_v, "*", 1)) 405260684Skaiw goto clean; 406260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 407260684Skaiw goto clean; 408260684Skaiw } 409260684Skaiw break; 410260684Skaiw 411260684Skaiw case TYPE_REF: 412260684Skaiw if (!cpp_demangle_push_str(ddata, "&", 1)) 413260684Skaiw goto clean; 414260684Skaiw if (type_str != NULL) { 415260684Skaiw if (!vector_str_push(&subst_v, "&", 1)) 416260684Skaiw goto clean; 417260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 418260684Skaiw goto clean; 419260684Skaiw } 420260684Skaiw break; 421260684Skaiw 422260684Skaiw case TYPE_CMX: 423260684Skaiw if (!cpp_demangle_push_str(ddata, " complex", 8)) 424260684Skaiw goto clean; 425260684Skaiw if (type_str != NULL) { 426260684Skaiw if (!vector_str_push(&subst_v, " complex", 8)) 427260684Skaiw goto clean; 428260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 429260684Skaiw goto clean; 430260684Skaiw } 431260684Skaiw break; 432260684Skaiw 433260684Skaiw case TYPE_IMG: 434260684Skaiw if (!cpp_demangle_push_str(ddata, " imaginary", 10)) 435260684Skaiw goto clean; 436260684Skaiw if (type_str != NULL) { 437260684Skaiw if (!vector_str_push(&subst_v, " imaginary", 10)) 438260684Skaiw goto clean; 439260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 440260684Skaiw goto clean; 441260684Skaiw } 442260684Skaiw break; 443260684Skaiw 444260684Skaiw case TYPE_EXT: 445260684Skaiw if (e_idx > v->ext_name.size - 1) 446260684Skaiw goto clean; 447260684Skaiw if ((e_len = strlen(v->ext_name.container[e_idx])) == 0) 448260684Skaiw goto clean; 449260684Skaiw if ((buf = malloc(sizeof(char) * (e_len + 1))) == NULL) 450260684Skaiw goto clean; 451260684Skaiw 452260684Skaiw memcpy(buf, " ", 1); 453260684Skaiw memcpy(buf + 1, v->ext_name.container[e_idx], e_len); 454260684Skaiw 455260684Skaiw if (!cpp_demangle_push_str(ddata, buf, e_len + 1)) { 456260684Skaiw free(buf); 457260684Skaiw goto clean; 458260684Skaiw } 459260684Skaiw 460260684Skaiw if (type_str != NULL) { 461260684Skaiw if (!vector_str_push(&subst_v, buf, 462260684Skaiw e_len + 1)) { 463260684Skaiw free(buf); 464260684Skaiw goto clean; 465260684Skaiw } 466260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &subst_v)) { 467260684Skaiw free(buf); 468260684Skaiw goto clean; 469260684Skaiw } 470260684Skaiw } 471260684Skaiw free(buf); 472260684Skaiw ++e_idx; 473260684Skaiw break; 474260684Skaiw 475260684Skaiw case TYPE_RST: 476260684Skaiw if (!cpp_demangle_push_str(ddata, " restrict", 9)) 477260684Skaiw goto clean; 478260684Skaiw if (type_str != NULL) { 479260684Skaiw if (!vector_str_push(&subst_v, " restrict", 9)) 480260684Skaiw goto clean; 481260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 482260684Skaiw goto clean; 483260684Skaiw } 484260684Skaiw break; 485260684Skaiw 486260684Skaiw case TYPE_VAT: 487260684Skaiw if (!cpp_demangle_push_str(ddata, " volatile", 9)) 488260684Skaiw goto clean; 489260684Skaiw if (type_str != NULL) { 490260684Skaiw if (!vector_str_push(&subst_v, " volatile", 9)) 491260684Skaiw goto clean; 492260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 493260684Skaiw goto clean; 494260684Skaiw } 495260684Skaiw break; 496260684Skaiw 497260684Skaiw case TYPE_CST: 498260684Skaiw if (!cpp_demangle_push_str(ddata, " const", 6)) 499260684Skaiw goto clean; 500260684Skaiw if (type_str != NULL) { 501260684Skaiw if (!vector_str_push(&subst_v, " const", 6)) 502260684Skaiw goto clean; 503260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &subst_v)) 504260684Skaiw goto clean; 505260684Skaiw } 506260684Skaiw break; 507260684Skaiw 508260684Skaiw }; 509260684Skaiw --idx; 510260684Skaiw } 511260684Skaiw 512260684Skaiw rtn = 1; 513260684Skaiwclean: 514260684Skaiw if (type_str != NULL) 515260684Skaiw vector_str_dest(&subst_v); 516260684Skaiw 517260684Skaiw return (rtn); 518260684Skaiw} 519260684Skaiw 520260684Skaiwstatic int 521260684Skaiwcpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx) 522260684Skaiw{ 523260684Skaiw size_t len; 524260684Skaiw 525260684Skaiw if (ddata == NULL || ddata->subst.size <= idx) 526260684Skaiw return (0); 527260684Skaiw if ((len = strlen(ddata->subst.container[idx])) == 0) 528260684Skaiw return (0); 529260684Skaiw if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len)) 530260684Skaiw return (0); 531260684Skaiw 532260684Skaiw /* skip '_' */ 533260684Skaiw ++ddata->cur; 534260684Skaiw 535260684Skaiw return (1); 536260684Skaiw} 537260684Skaiw 538260684Skaiwstatic int 539260684Skaiwcpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx) 540260684Skaiw{ 541260684Skaiw size_t len; 542260684Skaiw 543260684Skaiw if (ddata == NULL || ddata->tmpl.size <= idx) 544260684Skaiw return (0); 545260684Skaiw if ((len = strlen(ddata->tmpl.container[idx])) == 0) 546260684Skaiw return (0); 547260684Skaiw if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len)) 548260684Skaiw return (0); 549260684Skaiw 550260684Skaiw ++ddata->cur; 551260684Skaiw 552260684Skaiw return (1); 553260684Skaiw} 554260684Skaiw 555260684Skaiwstatic int 556260684Skaiwcpp_demangle_read_array(struct cpp_demangle_data *ddata) 557260684Skaiw{ 558260684Skaiw size_t i, num_len, exp_len, p_idx, idx; 559260684Skaiw const char *num; 560260684Skaiw char *exp; 561260684Skaiw 562260684Skaiw if (ddata == NULL || *(++ddata->cur) == '\0') 563260684Skaiw return (0); 564260684Skaiw 565260684Skaiw if (*ddata->cur == '_') { 566260684Skaiw if (*(++ddata->cur) == '\0') 567260684Skaiw return (0); 568260684Skaiw 569260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 570260684Skaiw return (0); 571260684Skaiw 572260684Skaiw if (!cpp_demangle_push_str(ddata, "[]", 2)) 573260684Skaiw return (0); 574260684Skaiw } else { 575260684Skaiw if (ELFTC_ISDIGIT(*ddata->cur) != 0) { 576260684Skaiw num = ddata->cur; 577260684Skaiw while (ELFTC_ISDIGIT(*ddata->cur) != 0) 578260684Skaiw ++ddata->cur; 579260684Skaiw if (*ddata->cur != '_') 580260684Skaiw return (0); 581260684Skaiw num_len = ddata->cur - num; 582260684Skaiw assert(num_len > 0); 583260684Skaiw if (*(++ddata->cur) == '\0') 584260684Skaiw return (0); 585260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 586260684Skaiw return (0); 587260684Skaiw if (!cpp_demangle_push_str(ddata, "[", 1)) 588260684Skaiw return (0); 589260684Skaiw if (!cpp_demangle_push_str(ddata, num, num_len)) 590260684Skaiw return (0); 591260684Skaiw if (!cpp_demangle_push_str(ddata, "]", 1)) 592260684Skaiw return (0); 593260684Skaiw } else { 594260684Skaiw p_idx = ddata->output.size; 595260684Skaiw if (!cpp_demangle_read_expression(ddata)) 596260684Skaiw return (0); 597260684Skaiw if ((exp = vector_str_substr(&ddata->output, p_idx, 598260684Skaiw ddata->output.size - 1, &exp_len)) == NULL) 599260684Skaiw return (0); 600260684Skaiw idx = ddata->output.size; 601260684Skaiw for (i = p_idx; i < idx; ++i) 602260684Skaiw if (!vector_str_pop(&ddata->output)) { 603260684Skaiw free(exp); 604260684Skaiw return (0); 605260684Skaiw } 606260684Skaiw if (*ddata->cur != '_') { 607260684Skaiw free(exp); 608260684Skaiw return (0); 609260684Skaiw } 610260684Skaiw ++ddata->cur; 611260684Skaiw if (*ddata->cur == '\0') { 612260684Skaiw free(exp); 613260684Skaiw return (0); 614260684Skaiw } 615260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) { 616260684Skaiw free(exp); 617260684Skaiw return (0); 618260684Skaiw } 619260684Skaiw if (!cpp_demangle_push_str(ddata, "[", 1)) { 620260684Skaiw free(exp); 621260684Skaiw return (0); 622260684Skaiw } 623260684Skaiw if (!cpp_demangle_push_str(ddata, exp, exp_len)) { 624260684Skaiw free(exp); 625260684Skaiw return (0); 626260684Skaiw } 627260684Skaiw if (!cpp_demangle_push_str(ddata, "]", 1)) { 628260684Skaiw free(exp); 629260684Skaiw return (0); 630260684Skaiw } 631260684Skaiw free(exp); 632260684Skaiw } 633260684Skaiw } 634260684Skaiw 635260684Skaiw return (1); 636260684Skaiw} 637260684Skaiw 638260684Skaiwstatic int 639260684Skaiwcpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata) 640260684Skaiw{ 641260684Skaiw const char *num; 642260684Skaiw 643260684Skaiw if (ddata == NULL || *(++ddata->cur) == '\0') 644260684Skaiw return (0); 645260684Skaiw 646260684Skaiw if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') { 647260684Skaiw ddata->cur += 2; 648260684Skaiw if (*ddata->cur == '\0') 649260684Skaiw return (0); 650260684Skaiw if (!cpp_demangle_read_encoding(ddata)) 651260684Skaiw return (0); 652260684Skaiw ++ddata->cur; 653260684Skaiw return (1); 654260684Skaiw } 655260684Skaiw 656260684Skaiw switch (*ddata->cur) { 657260684Skaiw case 'b': 658260684Skaiw switch (*(++ddata->cur)) { 659260684Skaiw case '0': 660260684Skaiw return (cpp_demangle_push_str(ddata, "false", 5)); 661260684Skaiw case '1': 662260684Skaiw return (cpp_demangle_push_str(ddata, "true", 4)); 663260684Skaiw default: 664260684Skaiw return (0); 665260684Skaiw }; 666260684Skaiw 667260684Skaiw case 'd': 668260684Skaiw ++ddata->cur; 669260684Skaiw return (cpp_demangle_push_fp(ddata, decode_fp_to_double)); 670260684Skaiw 671260684Skaiw case 'e': 672260684Skaiw ++ddata->cur; 673260684Skaiw if (sizeof(long double) == 10) 674260684Skaiw return (cpp_demangle_push_fp(ddata, 675260684Skaiw decode_fp_to_double)); 676260684Skaiw return (cpp_demangle_push_fp(ddata, decode_fp_to_float80)); 677260684Skaiw 678260684Skaiw case 'f': 679260684Skaiw ++ddata->cur; 680260684Skaiw return (cpp_demangle_push_fp(ddata, decode_fp_to_float)); 681260684Skaiw 682260684Skaiw case 'g': 683260684Skaiw ++ddata->cur; 684260684Skaiw if (sizeof(long double) == 16) 685260684Skaiw return (cpp_demangle_push_fp(ddata, 686260684Skaiw decode_fp_to_double)); 687260684Skaiw return (cpp_demangle_push_fp(ddata, decode_fp_to_float128)); 688260684Skaiw 689260684Skaiw case 'i': 690260684Skaiw case 'j': 691260684Skaiw case 'l': 692260684Skaiw case 'm': 693260684Skaiw case 'n': 694260684Skaiw case 's': 695260684Skaiw case 't': 696260684Skaiw case 'x': 697260684Skaiw case 'y': 698260684Skaiw if (*(++ddata->cur) == 'n') { 699260684Skaiw if (!cpp_demangle_push_str(ddata, "-", 1)) 700260684Skaiw return (0); 701260684Skaiw ++ddata->cur; 702260684Skaiw } 703260684Skaiw num = ddata->cur; 704260684Skaiw while (*ddata->cur != 'E') { 705260684Skaiw if (!ELFTC_ISDIGIT(*ddata->cur)) 706260684Skaiw return (0); 707260684Skaiw ++ddata->cur; 708260684Skaiw } 709260684Skaiw ++ddata->cur; 710260684Skaiw return (cpp_demangle_push_str(ddata, num, ddata->cur - num)); 711260684Skaiw 712260684Skaiw default: 713260684Skaiw return (0); 714260684Skaiw }; 715260684Skaiw} 716260684Skaiw 717260684Skaiwstatic int 718260684Skaiwcpp_demangle_read_expression(struct cpp_demangle_data *ddata) 719260684Skaiw{ 720260684Skaiw 721260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 722260684Skaiw return (0); 723260684Skaiw 724260684Skaiw switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 725260684Skaiw case SIMPLE_HASH('s', 't'): 726260684Skaiw ddata->cur += 2; 727260684Skaiw return (cpp_demangle_read_type(ddata, 0)); 728260684Skaiw 729260684Skaiw case SIMPLE_HASH('s', 'r'): 730260684Skaiw ddata->cur += 2; 731260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 732260684Skaiw return (0); 733260684Skaiw if (!cpp_demangle_read_uqname(ddata)) 734260684Skaiw return (0); 735260684Skaiw if (*ddata->cur == 'I') 736260684Skaiw return (cpp_demangle_read_tmpl_args(ddata)); 737260684Skaiw return (1); 738260684Skaiw 739260684Skaiw case SIMPLE_HASH('a', 'a'): 740260684Skaiw /* operator && */ 741260684Skaiw ddata->cur += 2; 742260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "&&", 2)); 743260684Skaiw 744260684Skaiw case SIMPLE_HASH('a', 'd'): 745260684Skaiw /* operator & (unary) */ 746260684Skaiw ddata->cur += 2; 747260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "&", 1)); 748260684Skaiw 749260684Skaiw case SIMPLE_HASH('a', 'n'): 750260684Skaiw /* operator & */ 751260684Skaiw ddata->cur += 2; 752260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "&", 1)); 753260684Skaiw 754260684Skaiw case SIMPLE_HASH('a', 'N'): 755260684Skaiw /* operator &= */ 756260684Skaiw ddata->cur += 2; 757260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "&=", 2)); 758260684Skaiw 759260684Skaiw case SIMPLE_HASH('a', 'S'): 760260684Skaiw /* operator = */ 761260684Skaiw ddata->cur += 2; 762260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "=", 1)); 763260684Skaiw 764260684Skaiw case SIMPLE_HASH('c', 'l'): 765260684Skaiw /* operator () */ 766260684Skaiw ddata->cur += 2; 767260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "()", 2)); 768260684Skaiw 769260684Skaiw case SIMPLE_HASH('c', 'm'): 770260684Skaiw /* operator , */ 771260684Skaiw ddata->cur += 2; 772260684Skaiw return (cpp_demangle_read_expression_binary(ddata, ",", 1)); 773260684Skaiw 774260684Skaiw case SIMPLE_HASH('c', 'o'): 775260684Skaiw /* operator ~ */ 776260684Skaiw ddata->cur += 2; 777260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "~", 1)); 778260684Skaiw 779260684Skaiw case SIMPLE_HASH('c', 'v'): 780260684Skaiw /* operator (cast) */ 781260684Skaiw ddata->cur += 2; 782260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6)); 783260684Skaiw 784260684Skaiw case SIMPLE_HASH('d', 'a'): 785260684Skaiw /* operator delete [] */ 786260684Skaiw ddata->cur += 2; 787260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "delete []", 9)); 788260684Skaiw 789260684Skaiw case SIMPLE_HASH('d', 'e'): 790260684Skaiw /* operator * (unary) */ 791260684Skaiw ddata->cur += 2; 792260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "*", 1)); 793260684Skaiw 794260684Skaiw case SIMPLE_HASH('d', 'l'): 795260684Skaiw /* operator delete */ 796260684Skaiw ddata->cur += 2; 797260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "delete", 6)); 798260684Skaiw 799260684Skaiw case SIMPLE_HASH('d', 'v'): 800260684Skaiw /* operator / */ 801260684Skaiw ddata->cur += 2; 802260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "/", 1)); 803260684Skaiw 804260684Skaiw case SIMPLE_HASH('d', 'V'): 805260684Skaiw /* operator /= */ 806260684Skaiw ddata->cur += 2; 807260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "/=", 2)); 808260684Skaiw 809260684Skaiw case SIMPLE_HASH('e', 'o'): 810260684Skaiw /* operator ^ */ 811260684Skaiw ddata->cur += 2; 812260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "^", 1)); 813260684Skaiw 814260684Skaiw case SIMPLE_HASH('e', 'O'): 815260684Skaiw /* operator ^= */ 816260684Skaiw ddata->cur += 2; 817260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "^=", 2)); 818260684Skaiw 819260684Skaiw case SIMPLE_HASH('e', 'q'): 820260684Skaiw /* operator == */ 821260684Skaiw ddata->cur += 2; 822260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "==", 2)); 823260684Skaiw 824260684Skaiw case SIMPLE_HASH('g', 'e'): 825260684Skaiw /* operator >= */ 826260684Skaiw ddata->cur += 2; 827260684Skaiw return (cpp_demangle_read_expression_binary(ddata, ">=", 2)); 828260684Skaiw 829260684Skaiw case SIMPLE_HASH('g', 't'): 830260684Skaiw /* operator > */ 831260684Skaiw ddata->cur += 2; 832260684Skaiw return (cpp_demangle_read_expression_binary(ddata, ">", 1)); 833260684Skaiw 834260684Skaiw case SIMPLE_HASH('i', 'x'): 835260684Skaiw /* operator [] */ 836260684Skaiw ddata->cur += 2; 837260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "[]", 2)); 838260684Skaiw 839260684Skaiw case SIMPLE_HASH('l', 'e'): 840260684Skaiw /* operator <= */ 841260684Skaiw ddata->cur += 2; 842260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "<=", 2)); 843260684Skaiw 844260684Skaiw case SIMPLE_HASH('l', 's'): 845260684Skaiw /* operator << */ 846260684Skaiw ddata->cur += 2; 847260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "<<", 2)); 848260684Skaiw 849260684Skaiw case SIMPLE_HASH('l', 'S'): 850260684Skaiw /* operator <<= */ 851260684Skaiw ddata->cur += 2; 852260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "<<=", 3)); 853260684Skaiw 854260684Skaiw case SIMPLE_HASH('l', 't'): 855260684Skaiw /* operator < */ 856260684Skaiw ddata->cur += 2; 857260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "<", 1)); 858260684Skaiw 859260684Skaiw case SIMPLE_HASH('m', 'i'): 860260684Skaiw /* operator - */ 861260684Skaiw ddata->cur += 2; 862260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "-", 1)); 863260684Skaiw 864260684Skaiw case SIMPLE_HASH('m', 'I'): 865260684Skaiw /* operator -= */ 866260684Skaiw ddata->cur += 2; 867260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "-=", 2)); 868260684Skaiw 869260684Skaiw case SIMPLE_HASH('m', 'l'): 870260684Skaiw /* operator * */ 871260684Skaiw ddata->cur += 2; 872260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "*", 1)); 873260684Skaiw 874260684Skaiw case SIMPLE_HASH('m', 'L'): 875260684Skaiw /* operator *= */ 876260684Skaiw ddata->cur += 2; 877260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "*=", 2)); 878260684Skaiw 879260684Skaiw case SIMPLE_HASH('m', 'm'): 880260684Skaiw /* operator -- */ 881260684Skaiw ddata->cur += 2; 882260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "--", 2)); 883260684Skaiw 884260684Skaiw case SIMPLE_HASH('n', 'a'): 885260684Skaiw /* operator new[] */ 886260684Skaiw ddata->cur += 2; 887260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "new []", 6)); 888260684Skaiw 889260684Skaiw case SIMPLE_HASH('n', 'e'): 890260684Skaiw /* operator != */ 891260684Skaiw ddata->cur += 2; 892260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "!=", 2)); 893260684Skaiw 894260684Skaiw case SIMPLE_HASH('n', 'g'): 895260684Skaiw /* operator - (unary) */ 896260684Skaiw ddata->cur += 2; 897260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "-", 1)); 898260684Skaiw 899260684Skaiw case SIMPLE_HASH('n', 't'): 900260684Skaiw /* operator ! */ 901260684Skaiw ddata->cur += 2; 902260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "!", 1)); 903260684Skaiw 904260684Skaiw case SIMPLE_HASH('n', 'w'): 905260684Skaiw /* operator new */ 906260684Skaiw ddata->cur += 2; 907260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "new", 3)); 908260684Skaiw 909260684Skaiw case SIMPLE_HASH('o', 'o'): 910260684Skaiw /* operator || */ 911260684Skaiw ddata->cur += 2; 912260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "||", 2)); 913260684Skaiw 914260684Skaiw case SIMPLE_HASH('o', 'r'): 915260684Skaiw /* operator | */ 916260684Skaiw ddata->cur += 2; 917260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "|", 1)); 918260684Skaiw 919260684Skaiw case SIMPLE_HASH('o', 'R'): 920260684Skaiw /* operator |= */ 921260684Skaiw ddata->cur += 2; 922260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "|=", 2)); 923260684Skaiw 924260684Skaiw case SIMPLE_HASH('p', 'l'): 925260684Skaiw /* operator + */ 926260684Skaiw ddata->cur += 2; 927260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "+", 1)); 928260684Skaiw 929260684Skaiw case SIMPLE_HASH('p', 'L'): 930260684Skaiw /* operator += */ 931260684Skaiw ddata->cur += 2; 932260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "+=", 2)); 933260684Skaiw 934260684Skaiw case SIMPLE_HASH('p', 'm'): 935260684Skaiw /* operator ->* */ 936260684Skaiw ddata->cur += 2; 937260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "->*", 3)); 938260684Skaiw 939260684Skaiw case SIMPLE_HASH('p', 'p'): 940260684Skaiw /* operator ++ */ 941260684Skaiw ddata->cur += 2; 942260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "++", 2)); 943260684Skaiw 944260684Skaiw case SIMPLE_HASH('p', 's'): 945260684Skaiw /* operator + (unary) */ 946260684Skaiw ddata->cur += 2; 947260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "+", 1)); 948260684Skaiw 949260684Skaiw case SIMPLE_HASH('p', 't'): 950260684Skaiw /* operator -> */ 951260684Skaiw ddata->cur += 2; 952260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "->", 2)); 953260684Skaiw 954260684Skaiw case SIMPLE_HASH('q', 'u'): 955260684Skaiw /* operator ? */ 956260684Skaiw ddata->cur += 2; 957260684Skaiw return (cpp_demangle_read_expression_trinary(ddata, "?", 1, 958260684Skaiw ":", 1)); 959260684Skaiw 960260684Skaiw case SIMPLE_HASH('r', 'm'): 961260684Skaiw /* operator % */ 962260684Skaiw ddata->cur += 2; 963260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "%", 1)); 964260684Skaiw 965260684Skaiw case SIMPLE_HASH('r', 'M'): 966260684Skaiw /* operator %= */ 967260684Skaiw ddata->cur += 2; 968260684Skaiw return (cpp_demangle_read_expression_binary(ddata, "%=", 2)); 969260684Skaiw 970260684Skaiw case SIMPLE_HASH('r', 's'): 971260684Skaiw /* operator >> */ 972260684Skaiw ddata->cur += 2; 973260684Skaiw return (cpp_demangle_read_expression_binary(ddata, ">>", 2)); 974260684Skaiw 975260684Skaiw case SIMPLE_HASH('r', 'S'): 976260684Skaiw /* operator >>= */ 977260684Skaiw ddata->cur += 2; 978260684Skaiw return (cpp_demangle_read_expression_binary(ddata, ">>=", 3)); 979260684Skaiw 980260684Skaiw case SIMPLE_HASH('r', 'z'): 981260684Skaiw /* operator sizeof */ 982260684Skaiw ddata->cur += 2; 983260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); 984260684Skaiw 985260684Skaiw case SIMPLE_HASH('s', 'v'): 986260684Skaiw /* operator sizeof */ 987260684Skaiw ddata->cur += 2; 988260684Skaiw return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6)); 989260684Skaiw }; 990260684Skaiw 991260684Skaiw switch (*ddata->cur) { 992260684Skaiw case 'L': 993260684Skaiw return (cpp_demangle_read_expr_primary(ddata)); 994260684Skaiw case 'T': 995260684Skaiw return (cpp_demangle_read_tmpl_param(ddata)); 996260684Skaiw }; 997260684Skaiw 998260684Skaiw return (0); 999260684Skaiw} 1000260684Skaiw 1001260684Skaiwstatic int 1002260684Skaiwcpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata, 1003260684Skaiw const char *name, size_t len) 1004260684Skaiw{ 1005260684Skaiw 1006260684Skaiw if (ddata == NULL || name == NULL || len == 0) 1007260684Skaiw return (0); 1008260684Skaiw if (!cpp_demangle_read_expression(ddata)) 1009260684Skaiw return (0); 1010260684Skaiw if (!cpp_demangle_push_str(ddata, name, len)) 1011260684Skaiw return (0); 1012260684Skaiw 1013260684Skaiw return (cpp_demangle_read_expression(ddata)); 1014260684Skaiw} 1015260684Skaiw 1016260684Skaiwstatic int 1017260684Skaiwcpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata, 1018260684Skaiw const char *name, size_t len) 1019260684Skaiw{ 1020260684Skaiw 1021260684Skaiw if (ddata == NULL || name == NULL || len == 0) 1022260684Skaiw return (0); 1023260684Skaiw if (!cpp_demangle_read_expression(ddata)) 1024260684Skaiw return (0); 1025260684Skaiw 1026260684Skaiw return (cpp_demangle_push_str(ddata, name, len)); 1027260684Skaiw} 1028260684Skaiw 1029260684Skaiwstatic int 1030260684Skaiwcpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata, 1031260684Skaiw const char *name1, size_t len1, const char *name2, size_t len2) 1032260684Skaiw{ 1033260684Skaiw 1034260684Skaiw if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL || 1035260684Skaiw len2 == 0) 1036260684Skaiw return (0); 1037260684Skaiw 1038260684Skaiw if (!cpp_demangle_read_expression(ddata)) 1039260684Skaiw return (0); 1040260684Skaiw if (!cpp_demangle_push_str(ddata, name1, len1)) 1041260684Skaiw return (0); 1042260684Skaiw if (!cpp_demangle_read_expression(ddata)) 1043260684Skaiw return (0); 1044260684Skaiw if (!cpp_demangle_push_str(ddata, name2, len2)) 1045260684Skaiw return (0); 1046260684Skaiw 1047260684Skaiw return (cpp_demangle_read_expression(ddata)); 1048260684Skaiw} 1049260684Skaiw 1050260684Skaiwstatic int 1051260684Skaiwcpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c, 1052260684Skaiw struct vector_type_qualifier *v) 1053260684Skaiw{ 1054260684Skaiw size_t class_type_size, class_type_len, limit; 1055260684Skaiw const char *class_type; 1056260684Skaiw 1057260684Skaiw if (ddata == NULL || *ddata->cur != 'F' || v == NULL) 1058260684Skaiw return (0); 1059260684Skaiw 1060260684Skaiw ++ddata->cur; 1061260684Skaiw if (*ddata->cur == 'Y') { 1062260684Skaiw if (ext_c != NULL) 1063260684Skaiw *ext_c = 1; 1064260684Skaiw ++ddata->cur; 1065260684Skaiw } 1066260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 1067260684Skaiw return (0); 1068260684Skaiw if (*ddata->cur != 'E') { 1069260684Skaiw if (!cpp_demangle_push_str(ddata, "(", 1)) 1070260684Skaiw return (0); 1071260684Skaiw if (vector_read_cmd_find(&ddata->cmd, READ_PTRMEM)) { 1072260684Skaiw if ((class_type_size = ddata->class_type.size) == 0) 1073260684Skaiw return (0); 1074260684Skaiw class_type = 1075260684Skaiw ddata->class_type.container[class_type_size - 1]; 1076260684Skaiw if (class_type == NULL) 1077260684Skaiw return (0); 1078260684Skaiw if ((class_type_len = strlen(class_type)) == 0) 1079260684Skaiw return (0); 1080260684Skaiw if (!cpp_demangle_push_str(ddata, class_type, 1081260684Skaiw class_type_len)) 1082260684Skaiw return (0); 1083260684Skaiw if (!cpp_demangle_push_str(ddata, "::*", 3)) 1084260684Skaiw return (0); 1085260684Skaiw ++ddata->func_type; 1086260684Skaiw } else { 1087260684Skaiw if (!cpp_demangle_push_type_qualifier(ddata, v, 1088260684Skaiw (const char *) NULL)) 1089260684Skaiw return (0); 1090260684Skaiw vector_type_qualifier_dest(v); 1091260684Skaiw if (!vector_type_qualifier_init(v)) 1092260684Skaiw return (0); 1093260684Skaiw } 1094260684Skaiw 1095260684Skaiw if (!cpp_demangle_push_str(ddata, ")(", 2)) 1096260684Skaiw return (0); 1097260684Skaiw 1098260684Skaiw limit = 0; 1099260684Skaiw for (;;) { 1100260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 1101260684Skaiw return (0); 1102260684Skaiw if (*ddata->cur == 'E') 1103260684Skaiw break; 1104260684Skaiw if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1105260684Skaiw return (0); 1106260684Skaiw } 1107260684Skaiw 1108260684Skaiw if (vector_read_cmd_find(&ddata->cmd, READ_PTRMEM) == 1) { 1109260684Skaiw if (!cpp_demangle_push_type_qualifier(ddata, v, 1110260684Skaiw (const char *) NULL)) 1111260684Skaiw return (0); 1112260684Skaiw vector_type_qualifier_dest(v); 1113260684Skaiw if (!vector_type_qualifier_init(v)) 1114260684Skaiw return (0); 1115260684Skaiw } 1116260684Skaiw 1117260684Skaiw if (!cpp_demangle_push_str(ddata, ")", 1)) 1118260684Skaiw return (0); 1119260684Skaiw } 1120260684Skaiw 1121260684Skaiw ++ddata->cur; 1122260684Skaiw 1123260684Skaiw return (1); 1124260684Skaiw} 1125260684Skaiw 1126260684Skaiw/* read encoding, encoding are function name, data name, special-name */ 1127260684Skaiwstatic int 1128260684Skaiwcpp_demangle_read_encoding(struct cpp_demangle_data *ddata) 1129260684Skaiw{ 1130260684Skaiw 1131260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 1132260684Skaiw return (0); 1133260684Skaiw 1134260684Skaiw /* special name */ 1135260684Skaiw switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 1136260684Skaiw case SIMPLE_HASH('G', 'V'): 1137260684Skaiw /* sentry object for 1 time init */ 1138260684Skaiw if (!cpp_demangle_push_str(ddata, "guard variable for ", 20)) 1139260684Skaiw return (0); 1140260684Skaiw ddata->cur += 2; 1141260684Skaiw break; 1142260684Skaiw 1143260684Skaiw case SIMPLE_HASH('T', 'c'): 1144260684Skaiw /* virtual function covariant override thunk */ 1145260684Skaiw if (!cpp_demangle_push_str(ddata, 1146260684Skaiw "virtual function covariant override ", 36)) 1147260684Skaiw return (0); 1148260684Skaiw ddata->cur += 2; 1149260684Skaiw if (*ddata->cur == '\0') 1150260684Skaiw return (0); 1151260684Skaiw if (!cpp_demangle_read_offset(ddata)) 1152260684Skaiw return (0); 1153260684Skaiw if (!cpp_demangle_read_offset(ddata)) 1154260684Skaiw return (0); 1155260684Skaiw return (cpp_demangle_read_encoding(ddata)); 1156260684Skaiw 1157260684Skaiw case SIMPLE_HASH('T', 'D'): 1158260684Skaiw /* typeinfo common proxy */ 1159260684Skaiw break; 1160260684Skaiw 1161260684Skaiw case SIMPLE_HASH('T', 'h'): 1162260684Skaiw /* virtual function non-virtual override thunk */ 1163260684Skaiw if (cpp_demangle_push_str(ddata, 1164260684Skaiw "virtual function non-virtual override ", 38) == 0) 1165260684Skaiw return (0); 1166260684Skaiw ddata->cur += 2; 1167260684Skaiw if (*ddata->cur == '\0') 1168260684Skaiw return (0); 1169260684Skaiw if (!cpp_demangle_read_nv_offset(ddata)) 1170260684Skaiw return (0); 1171260684Skaiw return (cpp_demangle_read_encoding(ddata)); 1172260684Skaiw 1173260684Skaiw case SIMPLE_HASH('T', 'I'): 1174260684Skaiw /* typeinfo structure */ 1175260684Skaiw /* FALLTHROUGH */ 1176260684Skaiw case SIMPLE_HASH('T', 'S'): 1177260684Skaiw /* RTTI name (NTBS) */ 1178260684Skaiw if (!cpp_demangle_push_str(ddata, "typeinfo for ", 14)) 1179260684Skaiw return (0); 1180260684Skaiw ddata->cur += 2; 1181260684Skaiw if (*ddata->cur == '\0') 1182260684Skaiw return (0); 1183260684Skaiw return (cpp_demangle_read_type(ddata, 1)); 1184260684Skaiw 1185260684Skaiw case SIMPLE_HASH('T', 'T'): 1186260684Skaiw /* VTT table */ 1187260684Skaiw if (!cpp_demangle_push_str(ddata, "VTT for ", 8)) 1188260684Skaiw return (0); 1189260684Skaiw ddata->cur += 2; 1190260684Skaiw return (cpp_demangle_read_type(ddata, 1)); 1191260684Skaiw 1192260684Skaiw case SIMPLE_HASH('T', 'v'): 1193260684Skaiw /* virtual function virtual override thunk */ 1194260684Skaiw if (!cpp_demangle_push_str(ddata, 1195260684Skaiw "virtual function virtual override ", 34)) 1196260684Skaiw return (0); 1197260684Skaiw ddata->cur += 2; 1198260684Skaiw if (*ddata->cur == '\0') 1199260684Skaiw return (0); 1200260684Skaiw if (!cpp_demangle_read_v_offset(ddata)) 1201260684Skaiw return (0); 1202260684Skaiw return (cpp_demangle_read_encoding(ddata)); 1203260684Skaiw 1204260684Skaiw case SIMPLE_HASH('T', 'V'): 1205260684Skaiw /* virtual table */ 1206260684Skaiw if (!cpp_demangle_push_str(ddata, "vtable for ", 12)) 1207260684Skaiw return (0); 1208260684Skaiw ddata->cur += 2; 1209260684Skaiw if (*ddata->cur == '\0') 1210260684Skaiw return (0); 1211260684Skaiw return (cpp_demangle_read_type(ddata, 1)); 1212260684Skaiw }; 1213260684Skaiw 1214260684Skaiw return (cpp_demangle_read_name(ddata)); 1215260684Skaiw} 1216260684Skaiw 1217260684Skaiwstatic int 1218260684Skaiwcpp_demangle_read_local_name(struct cpp_demangle_data *ddata) 1219260684Skaiw{ 1220260684Skaiw size_t limit; 1221260684Skaiw 1222260684Skaiw if (ddata == NULL) 1223260684Skaiw return (0); 1224260684Skaiw if (*(++ddata->cur) == '\0') 1225260684Skaiw return (0); 1226260684Skaiw if (!cpp_demangle_read_encoding(ddata)) 1227260684Skaiw return (0); 1228260684Skaiw 1229260684Skaiw limit = 0; 1230260684Skaiw for (;;) { 1231260684Skaiw if (!cpp_demangle_read_type(ddata, 1)) 1232260684Skaiw return (0); 1233260684Skaiw if (*ddata->cur == 'E') 1234260684Skaiw break; 1235260684Skaiw if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1236260684Skaiw return (0); 1237260684Skaiw } 1238260684Skaiw if (*(++ddata->cur) == '\0') 1239260684Skaiw return (0); 1240260684Skaiw if (ddata->paren == true) { 1241260684Skaiw if (!cpp_demangle_push_str(ddata, ")", 1)) 1242260684Skaiw return (0); 1243260684Skaiw ddata->paren = false; 1244260684Skaiw } 1245260684Skaiw if (*ddata->cur == 's') 1246260684Skaiw ++ddata->cur; 1247260684Skaiw else { 1248260684Skaiw if (!cpp_demangle_push_str(ddata, "::", 2)) 1249260684Skaiw return (0); 1250260684Skaiw if (!cpp_demangle_read_name(ddata)) 1251260684Skaiw return (0); 1252260684Skaiw } 1253260684Skaiw if (*ddata->cur == '_') { 1254260684Skaiw ++ddata->cur; 1255260684Skaiw while (ELFTC_ISDIGIT(*ddata->cur) != 0) 1256260684Skaiw ++ddata->cur; 1257260684Skaiw } 1258260684Skaiw 1259260684Skaiw return (1); 1260260684Skaiw} 1261260684Skaiw 1262260684Skaiwstatic int 1263260684Skaiwcpp_demangle_read_name(struct cpp_demangle_data *ddata) 1264260684Skaiw{ 1265260684Skaiw struct vector_str *output, v; 1266260684Skaiw size_t p_idx, subst_str_len; 1267260684Skaiw int rtn; 1268260684Skaiw char *subst_str; 1269260684Skaiw 1270260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 1271260684Skaiw return (0); 1272260684Skaiw 1273260684Skaiw output = cpp_demangle_gnu3_push_head > 0 ? 1274260684Skaiw &ddata->output_tmp : &ddata->output; 1275260684Skaiw 1276260684Skaiw subst_str = NULL; 1277260684Skaiw 1278260684Skaiw switch (*ddata->cur) { 1279260684Skaiw case 'S': 1280260684Skaiw return (cpp_demangle_read_subst(ddata)); 1281260684Skaiw case 'N': 1282260684Skaiw return (cpp_demangle_read_nested_name(ddata)); 1283260684Skaiw case 'Z': 1284260684Skaiw return (cpp_demangle_read_local_name(ddata)); 1285260684Skaiw }; 1286260684Skaiw 1287260684Skaiw if (!vector_str_init(&v)) 1288260684Skaiw return (0); 1289260684Skaiw 1290260684Skaiw p_idx = output->size; 1291260684Skaiw rtn = 0; 1292260684Skaiw if (!cpp_demangle_read_uqname(ddata)) 1293260684Skaiw goto clean; 1294260684Skaiw if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, 1295260684Skaiw &subst_str_len)) == NULL) 1296260684Skaiw goto clean; 1297260684Skaiw if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) { 1298260684Skaiw rtn = 1; 1299260684Skaiw goto clean; 1300260684Skaiw } 1301260684Skaiw if (!vector_str_push(&v, subst_str, subst_str_len)) 1302260684Skaiw goto clean; 1303260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &v)) 1304260684Skaiw goto clean; 1305260684Skaiw 1306260684Skaiw if (*ddata->cur == 'I') { 1307260684Skaiw p_idx = output->size; 1308260684Skaiw if (!cpp_demangle_read_tmpl_args(ddata)) 1309260684Skaiw goto clean; 1310260684Skaiw free(subst_str); 1311260684Skaiw if ((subst_str = vector_str_substr(output, p_idx, 1312260684Skaiw output->size - 1, &subst_str_len)) == NULL) 1313260684Skaiw goto clean; 1314260684Skaiw if (!vector_str_push(&v, subst_str, subst_str_len)) 1315260684Skaiw goto clean; 1316260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &v)) 1317260684Skaiw goto clean; 1318260684Skaiw } 1319260684Skaiw 1320260684Skaiw rtn = 1; 1321260684Skaiw 1322260684Skaiwclean: 1323260684Skaiw free(subst_str); 1324260684Skaiw vector_str_dest(&v); 1325260684Skaiw 1326260684Skaiw return (rtn); 1327260684Skaiw} 1328260684Skaiw 1329260684Skaiwstatic int 1330260684Skaiwcpp_demangle_read_nested_name(struct cpp_demangle_data *ddata) 1331260684Skaiw{ 1332260684Skaiw struct vector_str *output, v; 1333260684Skaiw size_t limit, p_idx, subst_str_len; 1334260684Skaiw int rtn; 1335260684Skaiw char *subst_str; 1336260684Skaiw 1337260684Skaiw if (ddata == NULL || *ddata->cur != 'N') 1338260684Skaiw return (0); 1339260684Skaiw if (*(++ddata->cur) == '\0') 1340260684Skaiw return (0); 1341260684Skaiw 1342260684Skaiw while (*ddata->cur == 'r' || *ddata->cur == 'V' || 1343260684Skaiw *ddata->cur == 'K') { 1344260684Skaiw switch (*ddata->cur) { 1345260684Skaiw case 'r': 1346260684Skaiw ddata->mem_rst = true; 1347260684Skaiw break; 1348260684Skaiw case 'V': 1349260684Skaiw ddata->mem_vat = true; 1350260684Skaiw break; 1351260684Skaiw case 'K': 1352260684Skaiw ddata->mem_cst = true; 1353260684Skaiw break; 1354260684Skaiw }; 1355260684Skaiw ++ddata->cur; 1356260684Skaiw } 1357260684Skaiw 1358260684Skaiw output = cpp_demangle_gnu3_push_head > 0 ? 1359260684Skaiw &ddata->output_tmp : &ddata->output; 1360260684Skaiw if (!vector_str_init(&v)) 1361260684Skaiw return (0); 1362260684Skaiw 1363260684Skaiw rtn = 0; 1364260684Skaiw limit = 0; 1365260684Skaiw for (;;) { 1366260684Skaiw p_idx = output->size; 1367260684Skaiw switch (*ddata->cur) { 1368260684Skaiw case 'I': 1369260684Skaiw if (!cpp_demangle_read_tmpl_args(ddata)) 1370260684Skaiw goto clean; 1371260684Skaiw break; 1372260684Skaiw case 'S': 1373260684Skaiw if (!cpp_demangle_read_subst(ddata)) 1374260684Skaiw goto clean; 1375260684Skaiw break; 1376260684Skaiw case 'T': 1377260684Skaiw if (!cpp_demangle_read_tmpl_param(ddata)) 1378260684Skaiw goto clean; 1379260684Skaiw break; 1380260684Skaiw default: 1381260684Skaiw if (!cpp_demangle_read_uqname(ddata)) 1382260684Skaiw goto clean; 1383260684Skaiw }; 1384260684Skaiw 1385260684Skaiw if ((subst_str = vector_str_substr(output, p_idx, 1386260684Skaiw output->size - 1, &subst_str_len)) == NULL) 1387260684Skaiw goto clean; 1388260684Skaiw if (!vector_str_push(&v, subst_str, subst_str_len)) { 1389260684Skaiw free(subst_str); 1390260684Skaiw goto clean; 1391260684Skaiw } 1392260684Skaiw free(subst_str); 1393260684Skaiw 1394260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &v)) 1395260684Skaiw goto clean; 1396260684Skaiw if (*ddata->cur == 'E') 1397260684Skaiw break; 1398260684Skaiw else if (*ddata->cur != 'I' && 1399260684Skaiw *ddata->cur != 'C' && *ddata->cur != 'D') { 1400260684Skaiw if (!cpp_demangle_push_str(ddata, "::", 2)) 1401260684Skaiw goto clean; 1402260684Skaiw if (!vector_str_push(&v, "::", 2)) 1403260684Skaiw goto clean; 1404260684Skaiw } 1405260684Skaiw if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1406260684Skaiw goto clean; 1407260684Skaiw } 1408260684Skaiw 1409260684Skaiw ++ddata->cur; 1410260684Skaiw rtn = 1; 1411260684Skaiw 1412260684Skaiwclean: 1413260684Skaiw vector_str_dest(&v); 1414260684Skaiw 1415260684Skaiw return (rtn); 1416260684Skaiw} 1417260684Skaiw 1418260684Skaiw/* 1419260684Skaiw * read number 1420260684Skaiw * number ::= [n] <decimal> 1421260684Skaiw */ 1422260684Skaiwstatic int 1423260684Skaiwcpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn) 1424260684Skaiw{ 1425260684Skaiw long len, negative_factor; 1426260684Skaiw 1427260684Skaiw if (ddata == NULL || rtn == NULL) 1428260684Skaiw return (0); 1429260684Skaiw 1430260684Skaiw negative_factor = 1; 1431260684Skaiw if (*ddata->cur == 'n') { 1432260684Skaiw negative_factor = -1; 1433260684Skaiw 1434260684Skaiw ++ddata->cur; 1435260684Skaiw } 1436260684Skaiw if (ELFTC_ISDIGIT(*ddata->cur) == 0) 1437260684Skaiw return (0); 1438260684Skaiw 1439260684Skaiw errno = 0; 1440260684Skaiw if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 && 1441260684Skaiw errno != 0) 1442260684Skaiw return (0); 1443260684Skaiw 1444260684Skaiw while (ELFTC_ISDIGIT(*ddata->cur) != 0) 1445260684Skaiw ++ddata->cur; 1446260684Skaiw 1447260684Skaiw assert(len >= 0); 1448260684Skaiw assert(negative_factor == 1 || negative_factor == -1); 1449260684Skaiw 1450260684Skaiw *rtn = len * negative_factor; 1451260684Skaiw 1452260684Skaiw return (1); 1453260684Skaiw} 1454260684Skaiw 1455260684Skaiwstatic int 1456260684Skaiwcpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata) 1457260684Skaiw{ 1458260684Skaiw 1459260684Skaiw if (ddata == NULL) 1460260684Skaiw return (0); 1461260684Skaiw 1462260684Skaiw if (!cpp_demangle_push_str(ddata, "offset : ", 9)) 1463260684Skaiw return (0); 1464260684Skaiw 1465260684Skaiw return (cpp_demangle_read_offset_number(ddata)); 1466260684Skaiw} 1467260684Skaiw 1468260684Skaiw/* read offset, offset are nv-offset, v-offset */ 1469260684Skaiwstatic int 1470260684Skaiwcpp_demangle_read_offset(struct cpp_demangle_data *ddata) 1471260684Skaiw{ 1472260684Skaiw 1473260684Skaiw if (ddata == NULL) 1474260684Skaiw return (0); 1475260684Skaiw 1476260684Skaiw if (*ddata->cur == 'h') { 1477260684Skaiw ++ddata->cur; 1478260684Skaiw return (cpp_demangle_read_nv_offset(ddata)); 1479260684Skaiw } else if (*ddata->cur == 'v') { 1480260684Skaiw ++ddata->cur; 1481260684Skaiw return (cpp_demangle_read_v_offset(ddata)); 1482260684Skaiw } 1483260684Skaiw 1484260684Skaiw return (0); 1485260684Skaiw} 1486260684Skaiw 1487260684Skaiwstatic int 1488260684Skaiwcpp_demangle_read_offset_number(struct cpp_demangle_data *ddata) 1489260684Skaiw{ 1490260684Skaiw bool negative; 1491260684Skaiw const char *start; 1492260684Skaiw 1493260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 1494260684Skaiw return (0); 1495260684Skaiw 1496260684Skaiw /* offset could be negative */ 1497260684Skaiw if (*ddata->cur == 'n') { 1498260684Skaiw negative = true; 1499260684Skaiw start = ddata->cur + 1; 1500260684Skaiw } else { 1501260684Skaiw negative = false; 1502260684Skaiw start = ddata->cur; 1503260684Skaiw } 1504260684Skaiw 1505260684Skaiw while (*ddata->cur != '_') 1506260684Skaiw ++ddata->cur; 1507260684Skaiw 1508260684Skaiw if (negative && !cpp_demangle_push_str(ddata, "-", 1)) 1509260684Skaiw return (0); 1510260684Skaiw 1511260684Skaiw assert(start != NULL); 1512260684Skaiw 1513260684Skaiw if (!cpp_demangle_push_str(ddata, start, ddata->cur - start)) 1514260684Skaiw return (0); 1515260684Skaiw if (!cpp_demangle_push_str(ddata, " ", 1)) 1516260684Skaiw return (0); 1517260684Skaiw 1518260684Skaiw ++ddata->cur; 1519260684Skaiw 1520260684Skaiw return (1); 1521260684Skaiw} 1522260684Skaiw 1523260684Skaiwstatic int 1524260684Skaiwcpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata) 1525260684Skaiw{ 1526260684Skaiw size_t class_type_len, i, idx, p_idx; 1527260684Skaiw int p_func_type, rtn; 1528260684Skaiw char *class_type; 1529260684Skaiw 1530260684Skaiw if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0') 1531260684Skaiw return (0); 1532260684Skaiw 1533260684Skaiw p_idx = ddata->output.size; 1534260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 1535260684Skaiw return (0); 1536260684Skaiw 1537260684Skaiw if ((class_type = vector_str_substr(&ddata->output, p_idx, 1538260684Skaiw ddata->output.size - 1, &class_type_len)) == NULL) 1539260684Skaiw return (0); 1540260684Skaiw 1541260684Skaiw rtn = 0; 1542260684Skaiw idx = ddata->output.size; 1543260684Skaiw for (i = p_idx; i < idx; ++i) 1544260684Skaiw if (!vector_str_pop(&ddata->output)) 1545260684Skaiw goto clean1; 1546260684Skaiw 1547260684Skaiw if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM)) 1548260684Skaiw goto clean1; 1549260684Skaiw 1550260684Skaiw if (!vector_str_push(&ddata->class_type, class_type, class_type_len)) 1551260684Skaiw goto clean2; 1552260684Skaiw 1553260684Skaiw p_func_type = ddata->func_type; 1554260684Skaiw if (!cpp_demangle_read_type(ddata, 0)) 1555260684Skaiw goto clean3; 1556260684Skaiw 1557260684Skaiw if (p_func_type == ddata->func_type) { 1558260684Skaiw if (!cpp_demangle_push_str(ddata, " ", 1)) 1559260684Skaiw goto clean3; 1560260684Skaiw if (!cpp_demangle_push_str(ddata, class_type, class_type_len)) 1561260684Skaiw goto clean3; 1562260684Skaiw if (!cpp_demangle_push_str(ddata, "::*", 3)) 1563260684Skaiw goto clean3; 1564260684Skaiw } 1565260684Skaiw 1566260684Skaiw rtn = 1; 1567260684Skaiwclean3: 1568260684Skaiw if (!vector_str_pop(&ddata->class_type)) 1569260684Skaiw rtn = 0; 1570260684Skaiwclean2: 1571260684Skaiw if (!vector_read_cmd_pop(&ddata->cmd)) 1572260684Skaiw rtn = 0; 1573260684Skaiwclean1: 1574260684Skaiw free(class_type); 1575260684Skaiw 1576260684Skaiw return (rtn); 1577260684Skaiw} 1578260684Skaiw 1579260684Skaiw/* read source-name, source-name is <len> <ID> */ 1580260684Skaiwstatic int 1581260684Skaiwcpp_demangle_read_sname(struct cpp_demangle_data *ddata) 1582260684Skaiw{ 1583260684Skaiw long len; 1584260684Skaiw 1585260684Skaiw if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 || 1586260684Skaiw len <= 0 || cpp_demangle_push_str(ddata, ddata->cur, len) == 0) 1587260684Skaiw return (0); 1588260684Skaiw 1589260684Skaiw assert(ddata->output.size > 0); 1590260684Skaiw if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == 0) 1591260684Skaiw ddata->last_sname = 1592260684Skaiw ddata->output.container[ddata->output.size - 1]; 1593260684Skaiw 1594260684Skaiw ddata->cur += len; 1595260684Skaiw 1596260684Skaiw return (1); 1597260684Skaiw} 1598260684Skaiw 1599260684Skaiwstatic int 1600260684Skaiwcpp_demangle_read_subst(struct cpp_demangle_data *ddata) 1601260684Skaiw{ 1602260684Skaiw long nth; 1603260684Skaiw 1604260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 1605260684Skaiw return (0); 1606260684Skaiw 1607260684Skaiw /* abbreviations of the form Sx */ 1608260684Skaiw switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 1609260684Skaiw case SIMPLE_HASH('S', 'a'): 1610260684Skaiw /* std::allocator */ 1611260684Skaiw if (cpp_demangle_push_str(ddata, "std::allocator", 14) == 0) 1612260684Skaiw return (0); 1613260684Skaiw ddata->cur += 2; 1614260684Skaiw if (*ddata->cur == 'I') 1615260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1616260684Skaiw "std::allocator", 14)); 1617260684Skaiw return (1); 1618260684Skaiw 1619260684Skaiw case SIMPLE_HASH('S', 'b'): 1620260684Skaiw /* std::basic_string */ 1621260684Skaiw if (!cpp_demangle_push_str(ddata, "std::basic_string", 17)) 1622260684Skaiw return (0); 1623260684Skaiw ddata->cur += 2; 1624260684Skaiw if (*ddata->cur == 'I') 1625260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1626260684Skaiw "std::basic_string", 17)); 1627260684Skaiw return (1); 1628260684Skaiw 1629260684Skaiw case SIMPLE_HASH('S', 'd'): 1630260684Skaiw /* std::basic_iostream<char, std::char_traits<char> > */ 1631260684Skaiw if (!cpp_demangle_push_str(ddata, "std::iostream", 19)) 1632260684Skaiw return (0); 1633260684Skaiw ddata->last_sname = "iostream"; 1634260684Skaiw ddata->cur += 2; 1635260684Skaiw if (*ddata->cur == 'I') 1636260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1637260684Skaiw "std::iostream", 19)); 1638260684Skaiw return (1); 1639260684Skaiw 1640260684Skaiw case SIMPLE_HASH('S', 'i'): 1641260684Skaiw /* std::basic_istream<char, std::char_traits<char> > */ 1642260684Skaiw if (!cpp_demangle_push_str(ddata, "std::istream", 18)) 1643260684Skaiw return (0); 1644260684Skaiw ddata->last_sname = "istream"; 1645260684Skaiw ddata->cur += 2; 1646260684Skaiw if (*ddata->cur == 'I') 1647260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1648260684Skaiw "std::istream", 18)); 1649260684Skaiw return (1); 1650260684Skaiw 1651260684Skaiw case SIMPLE_HASH('S', 'o'): 1652260684Skaiw /* std::basic_ostream<char, std::char_traits<char> > */ 1653260684Skaiw if (!cpp_demangle_push_str(ddata, "std::ostream", 18)) 1654260684Skaiw return (0); 1655260684Skaiw ddata->last_sname = "istream"; 1656260684Skaiw ddata->cur += 2; 1657260684Skaiw if (*ddata->cur == 'I') 1658260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1659260684Skaiw "std::ostream", 18)); 1660260684Skaiw return (1); 1661260684Skaiw 1662260684Skaiw case SIMPLE_HASH('S', 's'): 1663260684Skaiw /* 1664260684Skaiw * std::basic_string<char, std::char_traits<char>, 1665260684Skaiw * std::allocator<char> > 1666260684Skaiw * 1667260684Skaiw * a.k.a std::string 1668260684Skaiw */ 1669260684Skaiw if (!cpp_demangle_push_str(ddata, "std::string", 11)) 1670260684Skaiw return (0); 1671260684Skaiw ddata->last_sname = "string"; 1672260684Skaiw ddata->cur += 2; 1673260684Skaiw if (*ddata->cur == 'I') 1674260684Skaiw return (cpp_demangle_read_subst_stdtmpl(ddata, 1675260684Skaiw "std::string", 11)); 1676260684Skaiw return (1); 1677260684Skaiw 1678260684Skaiw case SIMPLE_HASH('S', 't'): 1679260684Skaiw /* std:: */ 1680260684Skaiw return (cpp_demangle_read_subst_std(ddata)); 1681260684Skaiw }; 1682260684Skaiw 1683260684Skaiw if (*(++ddata->cur) == '\0') 1684260684Skaiw return (0); 1685260684Skaiw 1686260684Skaiw /* substitution */ 1687260684Skaiw if (*ddata->cur == '_') 1688260684Skaiw return (cpp_demangle_get_subst(ddata, 0)); 1689260684Skaiw else { 1690260684Skaiw errno = 0; 1691260684Skaiw /* substitution number is base 36 */ 1692260684Skaiw if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && 1693260684Skaiw errno != 0) 1694260684Skaiw return (0); 1695260684Skaiw 1696260684Skaiw /* first was '_', so increase one */ 1697260684Skaiw ++nth; 1698260684Skaiw 1699260684Skaiw while (*ddata->cur != '_') 1700260684Skaiw ++ddata->cur; 1701260684Skaiw 1702260684Skaiw assert(nth > 0); 1703260684Skaiw 1704260684Skaiw return (cpp_demangle_get_subst(ddata, nth)); 1705260684Skaiw } 1706260684Skaiw 1707260684Skaiw /* NOTREACHED */ 1708260684Skaiw return (0); 1709260684Skaiw} 1710260684Skaiw 1711260684Skaiwstatic int 1712260684Skaiwcpp_demangle_read_subst_std(struct cpp_demangle_data *ddata) 1713260684Skaiw{ 1714260684Skaiw struct vector_str *output, v; 1715260684Skaiw size_t p_idx, subst_str_len; 1716260684Skaiw int rtn; 1717260684Skaiw char *subst_str; 1718260684Skaiw 1719260684Skaiw if (ddata == NULL) 1720260684Skaiw return (0); 1721260684Skaiw 1722260684Skaiw if (!vector_str_init(&v)) 1723260684Skaiw return (0); 1724260684Skaiw 1725260684Skaiw subst_str = NULL; 1726260684Skaiw rtn = 0; 1727260684Skaiw if (!cpp_demangle_push_str(ddata, "std::", 5)) 1728260684Skaiw goto clean; 1729260684Skaiw 1730260684Skaiw if (!vector_str_push(&v, "std::", 5)) 1731260684Skaiw goto clean; 1732260684Skaiw 1733260684Skaiw ddata->cur += 2; 1734260684Skaiw 1735260684Skaiw output = cpp_demangle_gnu3_push_head > 0 ? 1736260684Skaiw &ddata->output_tmp : &ddata->output; 1737260684Skaiw 1738260684Skaiw p_idx = output->size; 1739260684Skaiw if (!cpp_demangle_read_uqname(ddata)) 1740260684Skaiw goto clean; 1741260684Skaiw 1742260684Skaiw if ((subst_str = vector_str_substr(output, p_idx, output->size - 1, 1743260684Skaiw &subst_str_len)) == NULL) 1744260684Skaiw goto clean; 1745260684Skaiw 1746260684Skaiw if (!vector_str_push(&v, subst_str, subst_str_len)) 1747260684Skaiw goto clean; 1748260684Skaiw 1749260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &v)) 1750260684Skaiw goto clean; 1751260684Skaiw 1752260684Skaiw if (*ddata->cur == 'I') { 1753260684Skaiw p_idx = output->size; 1754260684Skaiw if (!cpp_demangle_read_tmpl_args(ddata)) 1755260684Skaiw goto clean; 1756260684Skaiw free(subst_str); 1757260684Skaiw if ((subst_str = vector_str_substr(output, p_idx, 1758260684Skaiw output->size - 1, &subst_str_len)) == NULL) 1759260684Skaiw goto clean; 1760260684Skaiw if (!vector_str_push(&v, subst_str, subst_str_len)) 1761260684Skaiw goto clean; 1762260684Skaiw if (!cpp_demangle_push_subst_v(ddata, &v)) 1763260684Skaiw goto clean; 1764260684Skaiw } 1765260684Skaiw 1766260684Skaiw rtn = 1; 1767260684Skaiwclean: 1768260684Skaiw free(subst_str); 1769260684Skaiw vector_str_dest(&v); 1770260684Skaiw 1771260684Skaiw return (rtn); 1772260684Skaiw} 1773260684Skaiw 1774260684Skaiwstatic int 1775260684Skaiwcpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata, 1776260684Skaiw const char *str, size_t len) 1777260684Skaiw{ 1778260684Skaiw struct vector_str *output; 1779260684Skaiw size_t p_idx, substr_len; 1780260684Skaiw int rtn; 1781260684Skaiw char *subst_str, *substr; 1782260684Skaiw 1783260684Skaiw if (ddata == NULL || str == NULL || len == 0) 1784260684Skaiw return (0); 1785260684Skaiw 1786260684Skaiw output = cpp_demangle_gnu3_push_head > 0 ? &ddata->output_tmp : 1787260684Skaiw &ddata->output; 1788260684Skaiw 1789260684Skaiw p_idx = output->size; 1790260684Skaiw substr = NULL; 1791260684Skaiw subst_str = NULL; 1792260684Skaiw 1793260684Skaiw if (!cpp_demangle_read_tmpl_args(ddata)) 1794260684Skaiw return (0); 1795260684Skaiw if ((substr = vector_str_substr(output, p_idx, output->size - 1, 1796260684Skaiw &substr_len)) == NULL) 1797260684Skaiw return (0); 1798260684Skaiw 1799260684Skaiw rtn = 0; 1800260684Skaiw if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) == 1801260684Skaiw NULL) 1802260684Skaiw goto clean; 1803260684Skaiw 1804260684Skaiw memcpy(subst_str, str, len); 1805260684Skaiw memcpy(subst_str + len, substr, substr_len); 1806260684Skaiw subst_str[substr_len + len] = '\0'; 1807260684Skaiw 1808260684Skaiw if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len)) 1809260684Skaiw goto clean; 1810260684Skaiw 1811260684Skaiw rtn = 1; 1812260684Skaiwclean: 1813260684Skaiw free(subst_str); 1814260684Skaiw free(substr); 1815260684Skaiw 1816260684Skaiw return (rtn); 1817260684Skaiw} 1818260684Skaiw 1819260684Skaiwstatic int 1820260684Skaiwcpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata) 1821260684Skaiw{ 1822260684Skaiw 1823260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 1824260684Skaiw return (0); 1825260684Skaiw 1826260684Skaiw switch (*ddata->cur) { 1827260684Skaiw case 'L': 1828260684Skaiw return (cpp_demangle_read_expr_primary(ddata)); 1829260684Skaiw case 'X': 1830260684Skaiw return (cpp_demangle_read_expression(ddata)); 1831260684Skaiw }; 1832260684Skaiw 1833260684Skaiw return (cpp_demangle_read_type(ddata, 0)); 1834260684Skaiw} 1835260684Skaiw 1836260684Skaiwstatic int 1837260684Skaiwcpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata) 1838260684Skaiw{ 1839260684Skaiw struct vector_str *v; 1840260684Skaiw size_t arg_len, idx, limit, size; 1841260684Skaiw char *arg; 1842260684Skaiw 1843260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 1844260684Skaiw return (0); 1845260684Skaiw 1846260684Skaiw ++ddata->cur; 1847260684Skaiw 1848260684Skaiw if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL)) 1849260684Skaiw return (0); 1850260684Skaiw 1851260684Skaiw if (!cpp_demangle_push_str(ddata, "<", 1)) 1852260684Skaiw return (0); 1853260684Skaiw 1854260684Skaiw limit = 0; 1855260684Skaiw v = cpp_demangle_gnu3_push_head > 0 ? 1856260684Skaiw &ddata->output_tmp : &ddata->output; 1857260684Skaiw for (;;) { 1858260684Skaiw idx = v->size; 1859260684Skaiw if (!cpp_demangle_read_tmpl_arg(ddata)) 1860260684Skaiw return (0); 1861260684Skaiw if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) == 1862260684Skaiw NULL) 1863260684Skaiw return (0); 1864260684Skaiw if (!vector_str_find(&ddata->tmpl, arg, arg_len) && 1865260684Skaiw !vector_str_push(&ddata->tmpl, arg, arg_len)) { 1866260684Skaiw free(arg); 1867260684Skaiw return (0); 1868260684Skaiw } 1869260684Skaiw 1870260684Skaiw free(arg); 1871260684Skaiw 1872260684Skaiw if (*ddata->cur == 'E') { 1873260684Skaiw ++ddata->cur; 1874260684Skaiw size = v->size; 1875260684Skaiw assert(size > 0); 1876260684Skaiw if (!strncmp(v->container[size - 1], ">", 1)) { 1877260684Skaiw if (!cpp_demangle_push_str(ddata, " >", 2)) 1878260684Skaiw return (0); 1879260684Skaiw } else if (!cpp_demangle_push_str(ddata, ">", 1)) 1880260684Skaiw return (0); 1881260684Skaiw break; 1882260684Skaiw } else if (*ddata->cur != 'I' && 1883260684Skaiw !cpp_demangle_push_str(ddata, ", ", 2)) 1884260684Skaiw return (0); 1885260684Skaiw 1886260684Skaiw if (limit++ > CPP_DEMANGLE_TRY_LIMIT) 1887260684Skaiw return (0); 1888260684Skaiw } 1889260684Skaiw 1890260684Skaiw return (vector_read_cmd_pop(&ddata->cmd)); 1891260684Skaiw} 1892260684Skaiw 1893260684Skaiw/* 1894260684Skaiw * Read template parameter that forms in 'T[number]_'. 1895260684Skaiw * This function much like to read_subst but only for types. 1896260684Skaiw */ 1897260684Skaiwstatic int 1898260684Skaiwcpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata) 1899260684Skaiw{ 1900260684Skaiw long nth; 1901260684Skaiw 1902260684Skaiw if (ddata == NULL || *ddata->cur != 'T') 1903260684Skaiw return (0); 1904260684Skaiw 1905260684Skaiw ++ddata->cur; 1906260684Skaiw 1907260684Skaiw if (*ddata->cur == '_') 1908260684Skaiw return (cpp_demangle_get_tmpl_param(ddata, 0)); 1909260684Skaiw else { 1910260684Skaiw 1911260684Skaiw errno = 0; 1912260684Skaiw if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 && 1913260684Skaiw errno != 0) 1914260684Skaiw return (0); 1915260684Skaiw 1916260684Skaiw /* T_ is first */ 1917260684Skaiw ++nth; 1918260684Skaiw 1919260684Skaiw while (*ddata->cur != '_') 1920260684Skaiw ++ddata->cur; 1921260684Skaiw 1922260684Skaiw assert(nth > 0); 1923260684Skaiw 1924260684Skaiw return (cpp_demangle_get_tmpl_param(ddata, nth)); 1925260684Skaiw } 1926260684Skaiw 1927260684Skaiw /* NOTREACHED */ 1928260684Skaiw return (0); 1929260684Skaiw} 1930260684Skaiw 1931260684Skaiwstatic int 1932260684Skaiwcpp_demangle_read_type(struct cpp_demangle_data *ddata, int delimit) 1933260684Skaiw{ 1934260684Skaiw struct vector_type_qualifier v; 1935260684Skaiw struct vector_str *output; 1936260684Skaiw size_t p_idx, type_str_len; 1937260684Skaiw int extern_c, is_builtin; 1938260684Skaiw long len; 1939260684Skaiw char *type_str; 1940260684Skaiw 1941260684Skaiw if (ddata == NULL) 1942260684Skaiw return (0); 1943260684Skaiw 1944260684Skaiw output = &ddata->output; 1945260684Skaiw if (!strncmp(ddata->output.container[ddata->output.size - 1], ">", 1)) { 1946260684Skaiw cpp_demangle_gnu3_push_head++; 1947260684Skaiw output = &ddata->output_tmp; 1948260684Skaiw } else if (delimit == 1) { 1949260684Skaiw if (ddata->paren == false) { 1950260684Skaiw if (!cpp_demangle_push_str(ddata, "(", 1)) 1951260684Skaiw return (0); 1952260684Skaiw if (ddata->output.size < 2) 1953260684Skaiw return (0); 1954260684Skaiw ddata->paren = true; 1955260684Skaiw ddata->pfirst = true; 1956260684Skaiw /* Need pop function name */ 1957260684Skaiw if (ddata->subst.size == 1 && 1958260684Skaiw !vector_str_pop(&ddata->subst)) 1959260684Skaiw return (0); 1960260684Skaiw } 1961260684Skaiw 1962260684Skaiw if (ddata->pfirst) 1963260684Skaiw ddata->pfirst = false; 1964260684Skaiw else if (*ddata->cur != 'I' && 1965260684Skaiw !cpp_demangle_push_str(ddata, ", ", 2)) 1966260684Skaiw return (0); 1967260684Skaiw } 1968260684Skaiw 1969260684Skaiw assert(output != NULL); 1970260684Skaiw /* 1971260684Skaiw * [r, V, K] [P, R, C, G, U] builtin, function, class-enum, array 1972260684Skaiw * pointer-to-member, template-param, template-template-param, subst 1973260684Skaiw */ 1974260684Skaiw 1975260684Skaiw if (!vector_type_qualifier_init(&v)) 1976260684Skaiw return (0); 1977260684Skaiw 1978260684Skaiw extern_c = 0; 1979260684Skaiw is_builtin = 1; 1980260684Skaiw p_idx = output->size; 1981260684Skaiw type_str = NULL; 1982260684Skaiwagain: 1983260684Skaiw /* builtin type */ 1984260684Skaiw switch (*ddata->cur) { 1985260684Skaiw case 'a': 1986260684Skaiw /* signed char */ 1987260684Skaiw if (!cpp_demangle_push_str(ddata, "signed char", 11)) 1988260684Skaiw goto clean; 1989260684Skaiw ++ddata->cur; 1990260684Skaiw goto rtn; 1991260684Skaiw 1992260684Skaiw case 'A': 1993260684Skaiw /* array type */ 1994260684Skaiw if (!cpp_demangle_read_array(ddata)) 1995260684Skaiw goto clean; 1996260684Skaiw is_builtin = 0; 1997260684Skaiw goto rtn; 1998260684Skaiw 1999260684Skaiw case 'b': 2000260684Skaiw /* bool */ 2001260684Skaiw if (!cpp_demangle_push_str(ddata, "bool", 4)) 2002260684Skaiw goto clean; 2003260684Skaiw ++ddata->cur; 2004260684Skaiw goto rtn; 2005260684Skaiw 2006260684Skaiw case 'C': 2007260684Skaiw /* complex pair */ 2008260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_CMX)) 2009260684Skaiw goto clean; 2010260684Skaiw ++ddata->cur; 2011260684Skaiw goto again; 2012260684Skaiw 2013260684Skaiw case 'c': 2014260684Skaiw /* char */ 2015260684Skaiw if (!cpp_demangle_push_str(ddata, "char", 4)) 2016260684Skaiw goto clean; 2017260684Skaiw ++ddata->cur; 2018260684Skaiw goto rtn; 2019260684Skaiw 2020260684Skaiw case 'd': 2021260684Skaiw /* double */ 2022260684Skaiw if (!cpp_demangle_push_str(ddata, "double", 6)) 2023260684Skaiw goto clean; 2024260684Skaiw ++ddata->cur; 2025260684Skaiw goto rtn; 2026260684Skaiw 2027260684Skaiw case 'e': 2028260684Skaiw /* long double */ 2029260684Skaiw if (!cpp_demangle_push_str(ddata, "long double", 11)) 2030260684Skaiw goto clean; 2031260684Skaiw ++ddata->cur; 2032260684Skaiw goto rtn; 2033260684Skaiw 2034260684Skaiw case 'f': 2035260684Skaiw /* float */ 2036260684Skaiw if (!cpp_demangle_push_str(ddata, "float", 5)) 2037260684Skaiw goto clean; 2038260684Skaiw ++ddata->cur; 2039260684Skaiw goto rtn; 2040260684Skaiw 2041260684Skaiw case 'F': 2042260684Skaiw /* function */ 2043260684Skaiw if (!cpp_demangle_read_function(ddata, &extern_c, &v)) 2044260684Skaiw goto clean; 2045260684Skaiw is_builtin = 0; 2046260684Skaiw goto rtn; 2047260684Skaiw 2048260684Skaiw case 'g': 2049260684Skaiw /* __float128 */ 2050260684Skaiw if (!cpp_demangle_push_str(ddata, "__float128", 10)) 2051260684Skaiw goto clean; 2052260684Skaiw ++ddata->cur; 2053260684Skaiw goto rtn; 2054260684Skaiw 2055260684Skaiw case 'G': 2056260684Skaiw /* imaginary */ 2057260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_IMG)) 2058260684Skaiw goto clean; 2059260684Skaiw ++ddata->cur; 2060260684Skaiw goto again; 2061260684Skaiw 2062260684Skaiw case 'h': 2063260684Skaiw /* unsigned char */ 2064260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned char", 13)) 2065260684Skaiw goto clean; 2066260684Skaiw ++ddata->cur; 2067260684Skaiw goto rtn; 2068260684Skaiw 2069260684Skaiw case 'i': 2070260684Skaiw /* int */ 2071260684Skaiw if (!cpp_demangle_push_str(ddata, "int", 3)) 2072260684Skaiw goto clean; 2073260684Skaiw ++ddata->cur; 2074260684Skaiw goto rtn; 2075260684Skaiw 2076260684Skaiw case 'j': 2077260684Skaiw /* unsigned int */ 2078260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned int", 12)) 2079260684Skaiw goto clean; 2080260684Skaiw ++ddata->cur; 2081260684Skaiw goto rtn; 2082260684Skaiw 2083260684Skaiw case 'K': 2084260684Skaiw /* const */ 2085260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_CST)) 2086260684Skaiw goto clean; 2087260684Skaiw ++ddata->cur; 2088260684Skaiw goto again; 2089260684Skaiw 2090260684Skaiw case 'l': 2091260684Skaiw /* long */ 2092260684Skaiw if (!cpp_demangle_push_str(ddata, "long", 4)) 2093260684Skaiw goto clean; 2094260684Skaiw ++ddata->cur; 2095260684Skaiw goto rtn; 2096260684Skaiw 2097260684Skaiw case 'm': 2098260684Skaiw /* unsigned long */ 2099260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned long", 13)) 2100260684Skaiw goto clean; 2101260684Skaiw 2102260684Skaiw ++ddata->cur; 2103260684Skaiw 2104260684Skaiw goto rtn; 2105260684Skaiw case 'M': 2106260684Skaiw /* pointer to member */ 2107260684Skaiw if (!cpp_demangle_read_pointer_to_member(ddata)) 2108260684Skaiw goto clean; 2109260684Skaiw is_builtin = 0; 2110260684Skaiw goto rtn; 2111260684Skaiw 2112260684Skaiw case 'n': 2113260684Skaiw /* __int128 */ 2114260684Skaiw if (!cpp_demangle_push_str(ddata, "__int128", 8)) 2115260684Skaiw goto clean; 2116260684Skaiw ++ddata->cur; 2117260684Skaiw goto rtn; 2118260684Skaiw 2119260684Skaiw case 'o': 2120260684Skaiw /* unsigned __int128 */ 2121260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned _;int128", 17)) 2122260684Skaiw goto clean; 2123260684Skaiw ++ddata->cur; 2124260684Skaiw goto rtn; 2125260684Skaiw 2126260684Skaiw case 'P': 2127260684Skaiw /* pointer */ 2128260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_PTR)) 2129260684Skaiw goto clean; 2130260684Skaiw ++ddata->cur; 2131260684Skaiw goto again; 2132260684Skaiw 2133260684Skaiw case 'r': 2134260684Skaiw /* restrict */ 2135260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_RST)) 2136260684Skaiw goto clean; 2137260684Skaiw ++ddata->cur; 2138260684Skaiw goto again; 2139260684Skaiw 2140260684Skaiw case 'R': 2141260684Skaiw /* reference */ 2142260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_REF)) 2143260684Skaiw goto clean; 2144260684Skaiw ++ddata->cur; 2145260684Skaiw goto again; 2146260684Skaiw 2147260684Skaiw case 's': 2148260684Skaiw /* short, local string */ 2149260684Skaiw if (!cpp_demangle_push_str(ddata, "short", 5)) 2150260684Skaiw goto clean; 2151260684Skaiw ++ddata->cur; 2152260684Skaiw goto rtn; 2153260684Skaiw 2154260684Skaiw case 'S': 2155260684Skaiw /* substitution */ 2156260684Skaiw if (!cpp_demangle_read_subst(ddata)) 2157260684Skaiw goto clean; 2158260684Skaiw is_builtin = 0; 2159260684Skaiw goto rtn; 2160260684Skaiw 2161260684Skaiw case 't': 2162260684Skaiw /* unsigned short */ 2163260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned short", 14)) 2164260684Skaiw goto clean; 2165260684Skaiw ++ddata->cur; 2166260684Skaiw goto rtn; 2167260684Skaiw 2168260684Skaiw case 'T': 2169260684Skaiw /* template parameter */ 2170260684Skaiw if (!cpp_demangle_read_tmpl_param(ddata)) 2171260684Skaiw goto clean; 2172260684Skaiw is_builtin = 0; 2173260684Skaiw goto rtn; 2174260684Skaiw 2175260684Skaiw case 'u': 2176260684Skaiw /* vendor extended builtin */ 2177260684Skaiw ++ddata->cur; 2178260684Skaiw if (!cpp_demangle_read_sname(ddata)) 2179260684Skaiw goto clean; 2180260684Skaiw is_builtin = 0; 2181260684Skaiw goto rtn; 2182260684Skaiw 2183260684Skaiw case 'U': 2184260684Skaiw /* vendor extended type qualifier */ 2185260684Skaiw if (!cpp_demangle_read_number(ddata, &len)) 2186260684Skaiw goto clean; 2187260684Skaiw if (len <= 0) 2188260684Skaiw goto clean; 2189260684Skaiw if (!vector_str_push(&v.ext_name, ddata->cur, len)) 2190260684Skaiw return (0); 2191260684Skaiw ddata->cur += len; 2192260684Skaiw goto again; 2193260684Skaiw 2194260684Skaiw case 'v': 2195260684Skaiw /* void */ 2196260684Skaiw if (!cpp_demangle_push_str(ddata, "void", 4)) 2197260684Skaiw goto clean; 2198260684Skaiw ++ddata->cur; 2199260684Skaiw goto rtn; 2200260684Skaiw 2201260684Skaiw case 'V': 2202260684Skaiw /* volatile */ 2203260684Skaiw if (!vector_type_qualifier_push(&v, TYPE_VAT)) 2204260684Skaiw goto clean; 2205260684Skaiw ++ddata->cur; 2206260684Skaiw goto again; 2207260684Skaiw 2208260684Skaiw case 'w': 2209260684Skaiw /* wchar_t */ 2210260684Skaiw if (!cpp_demangle_push_str(ddata, "wchar_t", 6)) 2211260684Skaiw goto clean; 2212260684Skaiw ++ddata->cur; 2213260684Skaiw goto rtn; 2214260684Skaiw 2215260684Skaiw case 'x': 2216260684Skaiw /* long long */ 2217260684Skaiw if (!cpp_demangle_push_str(ddata, "long long", 9)) 2218260684Skaiw goto clean; 2219260684Skaiw ++ddata->cur; 2220260684Skaiw goto rtn; 2221260684Skaiw 2222260684Skaiw case 'y': 2223260684Skaiw /* unsigned long long */ 2224260684Skaiw if (!cpp_demangle_push_str(ddata, "unsigned long long", 18)) 2225260684Skaiw goto clean; 2226260684Skaiw ++ddata->cur; 2227260684Skaiw goto rtn; 2228260684Skaiw 2229260684Skaiw case 'z': 2230260684Skaiw /* ellipsis */ 2231260684Skaiw if (!cpp_demangle_push_str(ddata, "ellipsis", 8)) 2232260684Skaiw goto clean; 2233260684Skaiw ++ddata->cur; 2234260684Skaiw goto rtn; 2235260684Skaiw }; 2236260684Skaiw 2237260684Skaiw if (!cpp_demangle_read_name(ddata)) 2238260684Skaiw goto clean; 2239260684Skaiw 2240260684Skaiw is_builtin = 0; 2241260684Skaiwrtn: 2242260684Skaiw if ((type_str = vector_str_substr(output, p_idx, output->size - 1, 2243260684Skaiw &type_str_len)) == NULL) 2244260684Skaiw goto clean; 2245260684Skaiw 2246260684Skaiw if (is_builtin == 0) { 2247260684Skaiw if (!vector_str_find(&ddata->subst, type_str, type_str_len) && 2248260684Skaiw !vector_str_push(&ddata->subst, type_str, type_str_len)) 2249260684Skaiw goto clean; 2250260684Skaiw } 2251260684Skaiw 2252260684Skaiw if (!cpp_demangle_push_type_qualifier(ddata, &v, type_str)) 2253260684Skaiw goto clean; 2254260684Skaiw 2255260684Skaiw free(type_str); 2256260684Skaiw vector_type_qualifier_dest(&v); 2257260684Skaiw 2258260684Skaiw if (cpp_demangle_gnu3_push_head > 0) { 2259260684Skaiw if (*ddata->cur == 'I' && cpp_demangle_read_tmpl_args(ddata) 2260260684Skaiw == 0) 2261260684Skaiw return (0); 2262260684Skaiw 2263260684Skaiw if (--cpp_demangle_gnu3_push_head > 0) 2264260684Skaiw return (1); 2265260684Skaiw 2266260684Skaiw if (!vector_str_push(&ddata->output_tmp, " ", 1)) 2267260684Skaiw return (0); 2268260684Skaiw 2269260684Skaiw if (!vector_str_push_vector_head(&ddata->output, 2270260684Skaiw &ddata->output_tmp)) 2271260684Skaiw return (0); 2272260684Skaiw 2273260684Skaiw vector_str_dest(&ddata->output_tmp); 2274260684Skaiw if (!vector_str_init(&ddata->output_tmp)) 2275260684Skaiw return (0); 2276260684Skaiw 2277260684Skaiw if (!cpp_demangle_push_str(ddata, "(", 1)) 2278260684Skaiw return (0); 2279260684Skaiw 2280260684Skaiw ddata->paren = true; 2281260684Skaiw ddata->pfirst = true; 2282260684Skaiw } 2283260684Skaiw 2284260684Skaiw return (1); 2285260684Skaiwclean: 2286260684Skaiw free(type_str); 2287260684Skaiw vector_type_qualifier_dest(&v); 2288260684Skaiw 2289260684Skaiw return (0); 2290260684Skaiw} 2291260684Skaiw 2292260684Skaiw/* 2293260684Skaiw * read unqualified-name, unqualified name are operator-name, ctor-dtor-name, 2294260684Skaiw * source-name 2295260684Skaiw */ 2296260684Skaiwstatic int 2297260684Skaiwcpp_demangle_read_uqname(struct cpp_demangle_data *ddata) 2298260684Skaiw{ 2299260684Skaiw size_t len; 2300260684Skaiw 2301260684Skaiw if (ddata == NULL || *ddata->cur == '\0') 2302260684Skaiw return (0); 2303260684Skaiw 2304260684Skaiw /* operator name */ 2305260684Skaiw switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 2306260684Skaiw case SIMPLE_HASH('a', 'a'): 2307260684Skaiw /* operator && */ 2308260684Skaiw if (!cpp_demangle_push_str(ddata, "operator&&", 10)) 2309260684Skaiw return (0); 2310260684Skaiw ddata->cur += 2; 2311260684Skaiw return (1); 2312260684Skaiw 2313260684Skaiw case SIMPLE_HASH('a', 'd'): 2314260684Skaiw /* operator & (unary) */ 2315260684Skaiw if (!cpp_demangle_push_str(ddata, "operator&", 9)) 2316260684Skaiw return (0); 2317260684Skaiw ddata->cur += 2; 2318260684Skaiw return (1); 2319260684Skaiw 2320260684Skaiw case SIMPLE_HASH('a', 'n'): 2321260684Skaiw /* operator & */ 2322260684Skaiw if (!cpp_demangle_push_str(ddata, "operator&", 9)) 2323260684Skaiw return (0); 2324260684Skaiw ddata->cur += 2; 2325260684Skaiw return (1); 2326260684Skaiw 2327260684Skaiw case SIMPLE_HASH('a', 'N'): 2328260684Skaiw /* operator &= */ 2329260684Skaiw if (!cpp_demangle_push_str(ddata, "operator&=", 10)) 2330260684Skaiw return (0); 2331260684Skaiw ddata->cur += 2; 2332260684Skaiw return (1); 2333260684Skaiw 2334260684Skaiw case SIMPLE_HASH('a', 'S'): 2335260684Skaiw /* operator = */ 2336260684Skaiw if (!cpp_demangle_push_str(ddata, "operator=", 9)) 2337260684Skaiw return (0); 2338260684Skaiw ddata->cur += 2; 2339260684Skaiw return (1); 2340260684Skaiw 2341260684Skaiw case SIMPLE_HASH('c', 'l'): 2342260684Skaiw /* operator () */ 2343260684Skaiw if (!cpp_demangle_push_str(ddata, "operator()", 10)) 2344260684Skaiw return (0); 2345260684Skaiw ddata->cur += 2; 2346260684Skaiw return (1); 2347260684Skaiw 2348260684Skaiw case SIMPLE_HASH('c', 'm'): 2349260684Skaiw /* operator , */ 2350260684Skaiw if (!cpp_demangle_push_str(ddata, "operator,", 9)) 2351260684Skaiw return (0); 2352260684Skaiw ddata->cur += 2; 2353260684Skaiw return (1); 2354260684Skaiw 2355260684Skaiw case SIMPLE_HASH('c', 'o'): 2356260684Skaiw /* operator ~ */ 2357260684Skaiw if (!cpp_demangle_push_str(ddata, "operator~", 9)) 2358260684Skaiw return (0); 2359260684Skaiw ddata->cur += 2; 2360260684Skaiw return (1); 2361260684Skaiw 2362260684Skaiw case SIMPLE_HASH('c', 'v'): 2363260684Skaiw /* operator (cast) */ 2364260684Skaiw if (!cpp_demangle_push_str(ddata, "operator(cast)", 14)) 2365260684Skaiw return (0); 2366260684Skaiw ddata->cur += 2; 2367260684Skaiw return (cpp_demangle_read_type(ddata, 1)); 2368260684Skaiw 2369260684Skaiw case SIMPLE_HASH('d', 'a'): 2370260684Skaiw /* operator delete [] */ 2371260684Skaiw if (!cpp_demangle_push_str(ddata, "operator delete []", 18)) 2372260684Skaiw return (0); 2373260684Skaiw ddata->cur += 2; 2374260684Skaiw return (1); 2375260684Skaiw 2376260684Skaiw case SIMPLE_HASH('d', 'e'): 2377260684Skaiw /* operator * (unary) */ 2378260684Skaiw if (!cpp_demangle_push_str(ddata, "operator*", 9)) 2379260684Skaiw return (0); 2380260684Skaiw ddata->cur += 2; 2381260684Skaiw return (1); 2382260684Skaiw 2383260684Skaiw case SIMPLE_HASH('d', 'l'): 2384260684Skaiw /* operator delete */ 2385260684Skaiw if (!cpp_demangle_push_str(ddata, "operator delete", 15)) 2386260684Skaiw return (0); 2387260684Skaiw ddata->cur += 2; 2388260684Skaiw return (1); 2389260684Skaiw 2390260684Skaiw case SIMPLE_HASH('d', 'v'): 2391260684Skaiw /* operator / */ 2392260684Skaiw if (!cpp_demangle_push_str(ddata, "operator/", 9)) 2393260684Skaiw return (0); 2394260684Skaiw ddata->cur += 2; 2395260684Skaiw return (1); 2396260684Skaiw 2397260684Skaiw case SIMPLE_HASH('d', 'V'): 2398260684Skaiw /* operator /= */ 2399260684Skaiw if (!cpp_demangle_push_str(ddata, "operator/=", 10)) 2400260684Skaiw return (0); 2401260684Skaiw ddata->cur += 2; 2402260684Skaiw return (1); 2403260684Skaiw 2404260684Skaiw case SIMPLE_HASH('e', 'o'): 2405260684Skaiw /* operator ^ */ 2406260684Skaiw if (!cpp_demangle_push_str(ddata, "operator^", 9)) 2407260684Skaiw return (0); 2408260684Skaiw ddata->cur += 2; 2409260684Skaiw return (1); 2410260684Skaiw 2411260684Skaiw case SIMPLE_HASH('e', 'O'): 2412260684Skaiw /* operator ^= */ 2413260684Skaiw if (!cpp_demangle_push_str(ddata, "operator^=", 10)) 2414260684Skaiw return (0); 2415260684Skaiw ddata->cur += 2; 2416260684Skaiw return (1); 2417260684Skaiw 2418260684Skaiw case SIMPLE_HASH('e', 'q'): 2419260684Skaiw /* operator == */ 2420260684Skaiw if (!cpp_demangle_push_str(ddata, "operator==", 10)) 2421260684Skaiw return (0); 2422260684Skaiw ddata->cur += 2; 2423260684Skaiw return (1); 2424260684Skaiw 2425260684Skaiw case SIMPLE_HASH('g', 'e'): 2426260684Skaiw /* operator >= */ 2427260684Skaiw if (!cpp_demangle_push_str(ddata, "operator>=", 10)) 2428260684Skaiw return (0); 2429260684Skaiw ddata->cur += 2; 2430260684Skaiw return (1); 2431260684Skaiw 2432260684Skaiw case SIMPLE_HASH('g', 't'): 2433260684Skaiw /* operator > */ 2434260684Skaiw if (!cpp_demangle_push_str(ddata, "operator>", 9)) 2435260684Skaiw return (0); 2436260684Skaiw ddata->cur += 2; 2437260684Skaiw return (1); 2438260684Skaiw 2439260684Skaiw case SIMPLE_HASH('i', 'x'): 2440260684Skaiw /* operator [] */ 2441260684Skaiw if (!cpp_demangle_push_str(ddata, "operator[]", 10)) 2442260684Skaiw return (0); 2443260684Skaiw ddata->cur += 2; 2444260684Skaiw return (1); 2445260684Skaiw 2446260684Skaiw case SIMPLE_HASH('l', 'e'): 2447260684Skaiw /* operator <= */ 2448260684Skaiw if (!cpp_demangle_push_str(ddata, "operator<=", 10)) 2449260684Skaiw return (0); 2450260684Skaiw ddata->cur += 2; 2451260684Skaiw return (1); 2452260684Skaiw 2453260684Skaiw case SIMPLE_HASH('l', 's'): 2454260684Skaiw /* operator << */ 2455260684Skaiw if (!cpp_demangle_push_str(ddata, "operator<<", 10)) 2456260684Skaiw return (0); 2457260684Skaiw ddata->cur += 2; 2458260684Skaiw return (1); 2459260684Skaiw 2460260684Skaiw case SIMPLE_HASH('l', 'S'): 2461260684Skaiw /* operator <<= */ 2462260684Skaiw if (!cpp_demangle_push_str(ddata, "operator<<=", 11)) 2463260684Skaiw return (0); 2464260684Skaiw ddata->cur += 2; 2465260684Skaiw return (1); 2466260684Skaiw 2467260684Skaiw case SIMPLE_HASH('l', 't'): 2468260684Skaiw /* operator < */ 2469260684Skaiw if (!cpp_demangle_push_str(ddata, "operator<", 9)) 2470260684Skaiw return (0); 2471260684Skaiw ddata->cur += 2; 2472260684Skaiw return (1); 2473260684Skaiw 2474260684Skaiw case SIMPLE_HASH('m', 'i'): 2475260684Skaiw /* operator - */ 2476260684Skaiw if (!cpp_demangle_push_str(ddata, "operator-", 9)) 2477260684Skaiw return (0); 2478260684Skaiw ddata->cur += 2; 2479260684Skaiw return (1); 2480260684Skaiw 2481260684Skaiw case SIMPLE_HASH('m', 'I'): 2482260684Skaiw /* operator -= */ 2483260684Skaiw if (!cpp_demangle_push_str(ddata, "operator-=", 10)) 2484260684Skaiw return (0); 2485260684Skaiw ddata->cur += 2; 2486260684Skaiw return (1); 2487260684Skaiw 2488260684Skaiw case SIMPLE_HASH('m', 'l'): 2489260684Skaiw /* operator * */ 2490260684Skaiw if (!cpp_demangle_push_str(ddata, "operator*", 9)) 2491260684Skaiw return (0); 2492260684Skaiw ddata->cur += 2; 2493260684Skaiw return (1); 2494260684Skaiw 2495260684Skaiw case SIMPLE_HASH('m', 'L'): 2496260684Skaiw /* operator *= */ 2497260684Skaiw if (!cpp_demangle_push_str(ddata, "operator*=", 10)) 2498260684Skaiw return (0); 2499260684Skaiw ddata->cur += 2; 2500260684Skaiw return (1); 2501260684Skaiw 2502260684Skaiw case SIMPLE_HASH('m', 'm'): 2503260684Skaiw /* operator -- */ 2504260684Skaiw if (!cpp_demangle_push_str(ddata, "operator--", 10)) 2505260684Skaiw return (0); 2506260684Skaiw ddata->cur += 2; 2507260684Skaiw return (1); 2508260684Skaiw 2509260684Skaiw case SIMPLE_HASH('n', 'a'): 2510260684Skaiw /* operator new[] */ 2511260684Skaiw if (!cpp_demangle_push_str(ddata, "operator new []", 15)) 2512260684Skaiw return (0); 2513260684Skaiw ddata->cur += 2; 2514260684Skaiw return (1); 2515260684Skaiw 2516260684Skaiw case SIMPLE_HASH('n', 'e'): 2517260684Skaiw /* operator != */ 2518260684Skaiw if (!cpp_demangle_push_str(ddata, "operator!=", 10)) 2519260684Skaiw return (0); 2520260684Skaiw ddata->cur += 2; 2521260684Skaiw return (1); 2522260684Skaiw 2523260684Skaiw case SIMPLE_HASH('n', 'g'): 2524260684Skaiw /* operator - (unary) */ 2525260684Skaiw if (!cpp_demangle_push_str(ddata, "operator-", 9)) 2526260684Skaiw return (0); 2527260684Skaiw ddata->cur += 2; 2528260684Skaiw return (1); 2529260684Skaiw 2530260684Skaiw case SIMPLE_HASH('n', 't'): 2531260684Skaiw /* operator ! */ 2532260684Skaiw if (!cpp_demangle_push_str(ddata, "operator!", 9)) 2533260684Skaiw return (0); 2534260684Skaiw ddata->cur += 2; 2535260684Skaiw return (1); 2536260684Skaiw 2537260684Skaiw case SIMPLE_HASH('n', 'w'): 2538260684Skaiw /* operator new */ 2539260684Skaiw if (!cpp_demangle_push_str(ddata, "operator new", 12)) 2540260684Skaiw return (0); 2541260684Skaiw ddata->cur += 2; 2542260684Skaiw return (1); 2543260684Skaiw 2544260684Skaiw case SIMPLE_HASH('o', 'o'): 2545260684Skaiw /* operator || */ 2546260684Skaiw if (!cpp_demangle_push_str(ddata, "operator||", 10)) 2547260684Skaiw return (0); 2548260684Skaiw ddata->cur += 2; 2549260684Skaiw return (1); 2550260684Skaiw 2551260684Skaiw case SIMPLE_HASH('o', 'r'): 2552260684Skaiw /* operator | */ 2553260684Skaiw if (!cpp_demangle_push_str(ddata, "operator|", 9)) 2554260684Skaiw return (0); 2555260684Skaiw ddata->cur += 2; 2556260684Skaiw return (1); 2557260684Skaiw 2558260684Skaiw case SIMPLE_HASH('o', 'R'): 2559260684Skaiw /* operator |= */ 2560260684Skaiw if (!cpp_demangle_push_str(ddata, "operator|=", 10)) 2561260684Skaiw return (0); 2562260684Skaiw ddata->cur += 2; 2563260684Skaiw return (1); 2564260684Skaiw 2565260684Skaiw case SIMPLE_HASH('p', 'l'): 2566260684Skaiw /* operator + */ 2567260684Skaiw if (!cpp_demangle_push_str(ddata, "operator+", 9)) 2568260684Skaiw return (0); 2569260684Skaiw ddata->cur += 2; 2570260684Skaiw return (1); 2571260684Skaiw 2572260684Skaiw case SIMPLE_HASH('p', 'L'): 2573260684Skaiw /* operator += */ 2574260684Skaiw if (!cpp_demangle_push_str(ddata, "operator+=", 10)) 2575260684Skaiw return (0); 2576260684Skaiw ddata->cur += 2; 2577260684Skaiw return (1); 2578260684Skaiw 2579260684Skaiw case SIMPLE_HASH('p', 'm'): 2580260684Skaiw /* operator ->* */ 2581260684Skaiw if (!cpp_demangle_push_str(ddata, "operator->*", 11)) 2582260684Skaiw return (0); 2583260684Skaiw ddata->cur += 2; 2584260684Skaiw return (1); 2585260684Skaiw 2586260684Skaiw case SIMPLE_HASH('p', 'p'): 2587260684Skaiw /* operator ++ */ 2588260684Skaiw if (!cpp_demangle_push_str(ddata, "operator++", 10)) 2589260684Skaiw return (0); 2590260684Skaiw ddata->cur += 2; 2591260684Skaiw return (1); 2592260684Skaiw 2593260684Skaiw case SIMPLE_HASH('p', 's'): 2594260684Skaiw /* operator + (unary) */ 2595260684Skaiw if (!cpp_demangle_push_str(ddata, "operator+", 9)) 2596260684Skaiw return (0); 2597260684Skaiw ddata->cur += 2; 2598260684Skaiw return (1); 2599260684Skaiw 2600260684Skaiw case SIMPLE_HASH('p', 't'): 2601260684Skaiw /* operator -> */ 2602260684Skaiw if (!cpp_demangle_push_str(ddata, "operator->", 10)) 2603260684Skaiw return (0); 2604260684Skaiw ddata->cur += 2; 2605260684Skaiw return (1); 2606260684Skaiw 2607260684Skaiw case SIMPLE_HASH('q', 'u'): 2608260684Skaiw /* operator ? */ 2609260684Skaiw if (!cpp_demangle_push_str(ddata, "operator?", 9)) 2610260684Skaiw return (0); 2611260684Skaiw ddata->cur += 2; 2612260684Skaiw return (1); 2613260684Skaiw 2614260684Skaiw case SIMPLE_HASH('r', 'm'): 2615260684Skaiw /* operator % */ 2616260684Skaiw if (!cpp_demangle_push_str(ddata, "operator%", 9)) 2617260684Skaiw return (0); 2618260684Skaiw ddata->cur += 2; 2619260684Skaiw return (1); 2620260684Skaiw 2621260684Skaiw case SIMPLE_HASH('r', 'M'): 2622260684Skaiw /* operator %= */ 2623260684Skaiw if (!cpp_demangle_push_str(ddata, "operator%=", 10)) 2624260684Skaiw return (0); 2625260684Skaiw ddata->cur += 2; 2626260684Skaiw return (1); 2627260684Skaiw 2628260684Skaiw case SIMPLE_HASH('r', 's'): 2629260684Skaiw /* operator >> */ 2630260684Skaiw if (!cpp_demangle_push_str(ddata, "operator>>", 10)) 2631260684Skaiw return (0); 2632260684Skaiw ddata->cur += 2; 2633260684Skaiw return (1); 2634260684Skaiw 2635260684Skaiw case SIMPLE_HASH('r', 'S'): 2636260684Skaiw /* operator >>= */ 2637260684Skaiw if (!cpp_demangle_push_str(ddata, "operator>>=", 11)) 2638260684Skaiw return (0); 2639260684Skaiw ddata->cur += 2; 2640260684Skaiw return (1); 2641260684Skaiw 2642260684Skaiw case SIMPLE_HASH('r', 'z'): 2643260684Skaiw /* operator sizeof */ 2644260684Skaiw if (!cpp_demangle_push_str(ddata, "operator sizeof ", 16)) 2645260684Skaiw return (0); 2646260684Skaiw ddata->cur += 2; 2647260684Skaiw return (1); 2648260684Skaiw 2649260684Skaiw case SIMPLE_HASH('s', 'r'): 2650260684Skaiw /* scope resolution operator */ 2651260684Skaiw if (!cpp_demangle_push_str(ddata, "scope resolution operator ", 2652260684Skaiw 26)) 2653260684Skaiw return (0); 2654260684Skaiw ddata->cur += 2; 2655260684Skaiw return (1); 2656260684Skaiw 2657260684Skaiw case SIMPLE_HASH('s', 'v'): 2658260684Skaiw /* operator sizeof */ 2659260684Skaiw if (!cpp_demangle_push_str(ddata, "operator sizeof ", 16)) 2660260684Skaiw return (0); 2661260684Skaiw ddata->cur += 2; 2662260684Skaiw return (1); 2663260684Skaiw }; 2664260684Skaiw 2665260684Skaiw /* vendor extened operator */ 2666260684Skaiw if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) { 2667260684Skaiw if (!cpp_demangle_push_str(ddata, "vendor extened operator ", 2668260684Skaiw 24)) 2669260684Skaiw return (0); 2670260684Skaiw if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1)) 2671260684Skaiw return (0); 2672260684Skaiw ddata->cur += 2; 2673260684Skaiw return (cpp_demangle_read_sname(ddata)); 2674260684Skaiw } 2675260684Skaiw 2676260684Skaiw /* ctor-dtor-name */ 2677260684Skaiw switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) { 2678260684Skaiw case SIMPLE_HASH('C', '1'): 2679260684Skaiw /* FALLTHROUGH */ 2680260684Skaiw case SIMPLE_HASH('C', '2'): 2681260684Skaiw /* FALLTHROUGH */ 2682260684Skaiw case SIMPLE_HASH('C', '3'): 2683260684Skaiw if (ddata->last_sname == NULL) 2684260684Skaiw return (0); 2685260684Skaiw if ((len = strlen(ddata->last_sname)) == 0) 2686260684Skaiw return (0); 2687260684Skaiw if (!cpp_demangle_push_str(ddata, "::", 2)) 2688260684Skaiw return (0); 2689260684Skaiw if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) 2690260684Skaiw return (0); 2691260684Skaiw ddata->cur +=2; 2692260684Skaiw return (1); 2693260684Skaiw 2694260684Skaiw case SIMPLE_HASH('D', '0'): 2695260684Skaiw /* FALLTHROUGH */ 2696260684Skaiw case SIMPLE_HASH('D', '1'): 2697260684Skaiw /* FALLTHROUGH */ 2698260684Skaiw case SIMPLE_HASH('D', '2'): 2699260684Skaiw if (ddata->last_sname == NULL) 2700260684Skaiw return (0); 2701260684Skaiw if ((len = strlen(ddata->last_sname)) == 0) 2702260684Skaiw return (0); 2703260684Skaiw if (!cpp_demangle_push_str(ddata, "::~", 3)) 2704260684Skaiw return (0); 2705260684Skaiw if (!cpp_demangle_push_str(ddata, ddata->last_sname, len)) 2706260684Skaiw return (0); 2707260684Skaiw ddata->cur +=2; 2708260684Skaiw return (1); 2709260684Skaiw }; 2710260684Skaiw 2711260684Skaiw /* source name */ 2712260684Skaiw if (ELFTC_ISDIGIT(*ddata->cur) != 0) 2713260684Skaiw return (cpp_demangle_read_sname(ddata)); 2714260684Skaiw 2715260684Skaiw /* local source name */ 2716260684Skaiw if (*ddata->cur == 'L') 2717260684Skaiw return (cpp_demangle_local_source_name(ddata)); 2718260684Skaiw 2719260684Skaiw return (1); 2720260684Skaiw} 2721260684Skaiw 2722260684Skaiw/* 2723260684Skaiw * Read local source name. 2724260684Skaiw * 2725260684Skaiw * References: 2726260684Skaiw * http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775 2727260684Skaiw * http://gcc.gnu.org/viewcvs?view=rev&revision=124467 2728260684Skaiw */ 2729260684Skaiwstatic int 2730260684Skaiwcpp_demangle_local_source_name(struct cpp_demangle_data *ddata) 2731260684Skaiw{ 2732260684Skaiw /* L */ 2733260684Skaiw if (ddata == NULL || *ddata->cur != 'L') 2734260684Skaiw return (0); 2735260684Skaiw ++ddata->cur; 2736260684Skaiw 2737260684Skaiw /* source name */ 2738260684Skaiw if (!cpp_demangle_read_sname(ddata)) 2739260684Skaiw return (0); 2740260684Skaiw 2741260684Skaiw /* discriminator */ 2742260684Skaiw if (*ddata->cur == '_') { 2743260684Skaiw ++ddata->cur; 2744260684Skaiw while (ELFTC_ISDIGIT(*ddata->cur) != 0) 2745260684Skaiw ++ddata->cur; 2746260684Skaiw } 2747260684Skaiw 2748260684Skaiw return (1); 2749260684Skaiw} 2750260684Skaiw 2751260684Skaiwstatic int 2752260684Skaiwcpp_demangle_read_v_offset(struct cpp_demangle_data *ddata) 2753260684Skaiw{ 2754260684Skaiw 2755260684Skaiw if (ddata == NULL) 2756260684Skaiw return (0); 2757260684Skaiw 2758260684Skaiw if (!cpp_demangle_push_str(ddata, "offset : ", 9)) 2759260684Skaiw return (0); 2760260684Skaiw 2761260684Skaiw if (!cpp_demangle_read_offset_number(ddata)) 2762260684Skaiw return (0); 2763260684Skaiw 2764260684Skaiw if (!cpp_demangle_push_str(ddata, "virtual offset : ", 17)) 2765260684Skaiw return (0); 2766260684Skaiw 2767260684Skaiw return (!cpp_demangle_read_offset_number(ddata)); 2768260684Skaiw} 2769260684Skaiw 2770260684Skaiw/* 2771260684Skaiw * Decode floating point representation to string 2772260684Skaiw * Return new allocated string or NULL 2773260684Skaiw * 2774260684Skaiw * Todo 2775260684Skaiw * Replace these functions to macro. 2776260684Skaiw */ 2777260684Skaiwstatic char * 2778260684Skaiwdecode_fp_to_double(const char *p, size_t len) 2779260684Skaiw{ 2780260684Skaiw double f; 2781260684Skaiw size_t rtn_len, limit, i; 2782260684Skaiw int byte; 2783260684Skaiw char *rtn; 2784260684Skaiw 2785260684Skaiw if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double)) 2786260684Skaiw return (NULL); 2787260684Skaiw 2788260684Skaiw memset(&f, 0, sizeof(double)); 2789260684Skaiw 2790260684Skaiw for (i = 0; i < len / 2; ++i) { 2791260684Skaiw byte = hex_to_dec(p[len - i * 2 - 1]) + 2792260684Skaiw hex_to_dec(p[len - i * 2 - 2]) * 16; 2793260684Skaiw 2794260684Skaiw if (byte < 0 || byte > 255) 2795260684Skaiw return (NULL); 2796260684Skaiw 2797260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 2798260684Skaiw ((unsigned char *)&f)[i] = (unsigned char)(byte); 2799260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2800260684Skaiw ((unsigned char *)&f)[sizeof(double) - i - 1] = 2801260684Skaiw (unsigned char)(byte); 2802260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2803260684Skaiw } 2804260684Skaiw 2805260684Skaiw rtn_len = 64; 2806260684Skaiw limit = 0; 2807260684Skaiwagain: 2808260684Skaiw if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 2809260684Skaiw return (NULL); 2810260684Skaiw 2811260684Skaiw if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) { 2812260684Skaiw free(rtn); 2813260684Skaiw if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 2814260684Skaiw return (NULL); 2815260684Skaiw rtn_len *= BUFFER_GROWFACTOR; 2816260684Skaiw goto again; 2817260684Skaiw } 2818260684Skaiw 2819260684Skaiw return rtn; 2820260684Skaiw} 2821260684Skaiw 2822260684Skaiwstatic char * 2823260684Skaiwdecode_fp_to_float(const char *p, size_t len) 2824260684Skaiw{ 2825260684Skaiw size_t i, rtn_len, limit; 2826260684Skaiw float f; 2827260684Skaiw int byte; 2828260684Skaiw char *rtn; 2829260684Skaiw 2830260684Skaiw if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float)) 2831260684Skaiw return (NULL); 2832260684Skaiw 2833260684Skaiw memset(&f, 0, sizeof(float)); 2834260684Skaiw 2835260684Skaiw for (i = 0; i < len / 2; ++i) { 2836260684Skaiw byte = hex_to_dec(p[len - i * 2 - 1]) + 2837260684Skaiw hex_to_dec(p[len - i * 2 - 2]) * 16; 2838260684Skaiw if (byte < 0 || byte > 255) 2839260684Skaiw return (NULL); 2840260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 2841260684Skaiw ((unsigned char *)&f)[i] = (unsigned char)(byte); 2842260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2843260684Skaiw ((unsigned char *)&f)[sizeof(float) - i - 1] = 2844260684Skaiw (unsigned char)(byte); 2845260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2846260684Skaiw } 2847260684Skaiw 2848260684Skaiw rtn_len = 64; 2849260684Skaiw limit = 0; 2850260684Skaiwagain: 2851260684Skaiw if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 2852260684Skaiw return (NULL); 2853260684Skaiw 2854260684Skaiw if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) { 2855260684Skaiw free(rtn); 2856260684Skaiw if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 2857260684Skaiw return (NULL); 2858260684Skaiw rtn_len *= BUFFER_GROWFACTOR; 2859260684Skaiw goto again; 2860260684Skaiw } 2861260684Skaiw 2862260684Skaiw return rtn; 2863260684Skaiw} 2864260684Skaiw 2865260684Skaiwstatic char * 2866260684Skaiwdecode_fp_to_float128(const char *p, size_t len) 2867260684Skaiw{ 2868260684Skaiw long double f; 2869260684Skaiw size_t rtn_len, limit, i; 2870260684Skaiw int byte; 2871260684Skaiw unsigned char buf[FLOAT_QUADRUPLE_BYTES]; 2872260684Skaiw char *rtn; 2873260684Skaiw 2874260684Skaiw switch(sizeof(long double)) { 2875260684Skaiw case FLOAT_QUADRUPLE_BYTES: 2876260684Skaiw return (decode_fp_to_long_double(p, len)); 2877260684Skaiw case FLOAT_EXTENED_BYTES: 2878260684Skaiw if (p == NULL || len == 0 || len % 2 != 0 || 2879260684Skaiw len / 2 > FLOAT_QUADRUPLE_BYTES) 2880260684Skaiw return (NULL); 2881260684Skaiw 2882260684Skaiw memset(buf, 0, FLOAT_QUADRUPLE_BYTES); 2883260684Skaiw 2884260684Skaiw for (i = 0; i < len / 2; ++i) { 2885260684Skaiw byte = hex_to_dec(p[len - i * 2 - 1]) + 2886260684Skaiw hex_to_dec(p[len - i * 2 - 2]) * 16; 2887260684Skaiw if (byte < 0 || byte > 255) 2888260684Skaiw return (NULL); 2889260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 2890260684Skaiw buf[i] = (unsigned char)(byte); 2891260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2892260684Skaiw buf[FLOAT_QUADRUPLE_BYTES - i -1] = 2893260684Skaiw (unsigned char)(byte); 2894260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2895260684Skaiw } 2896260684Skaiw memset(&f, 0, FLOAT_EXTENED_BYTES); 2897260684Skaiw 2898260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 2899260684Skaiw memcpy(&f, buf, FLOAT_EXTENED_BYTES); 2900260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2901260684Skaiw memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES); 2902260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2903260684Skaiw 2904260684Skaiw rtn_len = 256; 2905260684Skaiw limit = 0; 2906260684Skaiwagain: 2907260684Skaiw if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 2908260684Skaiw return (NULL); 2909260684Skaiw 2910260684Skaiw if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 2911260684Skaiw free(rtn); 2912260684Skaiw if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 2913260684Skaiw return (NULL); 2914260684Skaiw rtn_len *= BUFFER_GROWFACTOR; 2915260684Skaiw goto again; 2916260684Skaiw } 2917260684Skaiw 2918260684Skaiw return (rtn); 2919260684Skaiw default: 2920260684Skaiw return (NULL); 2921260684Skaiw } 2922260684Skaiw} 2923260684Skaiw 2924260684Skaiwstatic char * 2925260684Skaiwdecode_fp_to_float80(const char *p, size_t len) 2926260684Skaiw{ 2927260684Skaiw long double f; 2928260684Skaiw size_t rtn_len, limit, i; 2929260684Skaiw int byte; 2930260684Skaiw unsigned char buf[FLOAT_EXTENED_BYTES]; 2931260684Skaiw char *rtn; 2932260684Skaiw 2933260684Skaiw switch(sizeof(long double)) { 2934260684Skaiw case FLOAT_QUADRUPLE_BYTES: 2935260684Skaiw if (p == NULL || len == 0 || len % 2 != 0 || 2936260684Skaiw len / 2 > FLOAT_EXTENED_BYTES) 2937260684Skaiw return (NULL); 2938260684Skaiw 2939260684Skaiw memset(buf, 0, FLOAT_EXTENED_BYTES); 2940260684Skaiw 2941260684Skaiw for (i = 0; i < len / 2; ++i) { 2942260684Skaiw byte = hex_to_dec(p[len - i * 2 - 1]) + 2943260684Skaiw hex_to_dec(p[len - i * 2 - 2]) * 16; 2944260684Skaiw 2945260684Skaiw if (byte < 0 || byte > 255) 2946260684Skaiw return (NULL); 2947260684Skaiw 2948260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 2949260684Skaiw buf[i] = (unsigned char)(byte); 2950260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2951260684Skaiw buf[FLOAT_EXTENED_BYTES - i -1] = 2952260684Skaiw (unsigned char)(byte); 2953260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2954260684Skaiw } 2955260684Skaiw 2956260684Skaiw memset(&f, 0, FLOAT_QUADRUPLE_BYTES); 2957260684Skaiw 2958260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 2959260684Skaiw memcpy(&f, buf, FLOAT_EXTENED_BYTES); 2960260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2961260684Skaiw memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENED_BYTES); 2962260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 2963260684Skaiw 2964260684Skaiw rtn_len = 256; 2965260684Skaiw limit = 0; 2966260684Skaiwagain: 2967260684Skaiw if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 2968260684Skaiw return (NULL); 2969260684Skaiw 2970260684Skaiw if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 2971260684Skaiw free(rtn); 2972260684Skaiw if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 2973260684Skaiw return (NULL); 2974260684Skaiw rtn_len *= BUFFER_GROWFACTOR; 2975260684Skaiw goto again; 2976260684Skaiw } 2977260684Skaiw 2978260684Skaiw return (rtn); 2979260684Skaiw case FLOAT_EXTENED_BYTES: 2980260684Skaiw return (decode_fp_to_long_double(p, len)); 2981260684Skaiw default: 2982260684Skaiw return (NULL); 2983260684Skaiw } 2984260684Skaiw} 2985260684Skaiw 2986260684Skaiwstatic char * 2987260684Skaiwdecode_fp_to_long_double(const char *p, size_t len) 2988260684Skaiw{ 2989260684Skaiw long double f; 2990260684Skaiw size_t rtn_len, limit, i; 2991260684Skaiw int byte; 2992260684Skaiw char *rtn; 2993260684Skaiw 2994260684Skaiw if (p == NULL || len == 0 || len % 2 != 0 || 2995260684Skaiw len / 2 > sizeof(long double)) 2996260684Skaiw return (NULL); 2997260684Skaiw 2998260684Skaiw memset(&f, 0, sizeof(long double)); 2999260684Skaiw 3000260684Skaiw for (i = 0; i < len / 2; ++i) { 3001260684Skaiw byte = hex_to_dec(p[len - i * 2 - 1]) + 3002260684Skaiw hex_to_dec(p[len - i * 2 - 2]) * 16; 3003260684Skaiw 3004260684Skaiw if (byte < 0 || byte > 255) 3005260684Skaiw return (NULL); 3006260684Skaiw 3007260684Skaiw#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN 3008260684Skaiw ((unsigned char *)&f)[i] = (unsigned char)(byte); 3009260684Skaiw#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3010260684Skaiw ((unsigned char *)&f)[sizeof(long double) - i - 1] = 3011260684Skaiw (unsigned char)(byte); 3012260684Skaiw#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */ 3013260684Skaiw } 3014260684Skaiw 3015260684Skaiw rtn_len = 256; 3016260684Skaiw limit = 0; 3017260684Skaiwagain: 3018260684Skaiw if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL) 3019260684Skaiw return (NULL); 3020260684Skaiw 3021260684Skaiw if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) { 3022260684Skaiw free(rtn); 3023260684Skaiw if (limit++ > FLOAT_SPRINTF_TRY_LIMIT) 3024260684Skaiw return (NULL); 3025260684Skaiw rtn_len *= BUFFER_GROWFACTOR; 3026260684Skaiw goto again; 3027260684Skaiw } 3028260684Skaiw 3029260684Skaiw return (rtn); 3030260684Skaiw} 3031260684Skaiw 3032260684Skaiw/* Simple hex to integer function used by decode_to_* function. */ 3033260684Skaiwstatic int 3034260684Skaiwhex_to_dec(char c) 3035260684Skaiw{ 3036260684Skaiw 3037260684Skaiw switch (c) { 3038260684Skaiw case '0': 3039260684Skaiw return (0); 3040260684Skaiw case '1': 3041260684Skaiw return (1); 3042260684Skaiw case '2': 3043260684Skaiw return (2); 3044260684Skaiw case '3': 3045260684Skaiw return (3); 3046260684Skaiw case '4': 3047260684Skaiw return (4); 3048260684Skaiw case '5': 3049260684Skaiw return (5); 3050260684Skaiw case '6': 3051260684Skaiw return (6); 3052260684Skaiw case '7': 3053260684Skaiw return (7); 3054260684Skaiw case '8': 3055260684Skaiw return (8); 3056260684Skaiw case '9': 3057260684Skaiw return (9); 3058260684Skaiw case 'a': 3059260684Skaiw return (10); 3060260684Skaiw case 'b': 3061260684Skaiw return (11); 3062260684Skaiw case 'c': 3063260684Skaiw return (12); 3064260684Skaiw case 'd': 3065260684Skaiw return (13); 3066260684Skaiw case 'e': 3067260684Skaiw return (14); 3068260684Skaiw case 'f': 3069260684Skaiw return (15); 3070260684Skaiw default: 3071260684Skaiw return (-1); 3072260684Skaiw }; 3073260684Skaiw} 3074260684Skaiw 3075260684Skaiw/** 3076260684Skaiw * @brief Test input string is mangled by IA-64 C++ ABI style. 3077260684Skaiw * 3078260684Skaiw * Test string heads with "_Z" or "_GLOBAL__I_". 3079260684Skaiw * @return Return 0 at false. 3080260684Skaiw */ 3081260684Skaiwbool 3082260684Skaiwis_cpp_mangled_gnu3(const char *org) 3083260684Skaiw{ 3084260684Skaiw size_t len; 3085260684Skaiw 3086260684Skaiw len = strlen(org); 3087260684Skaiw return ((len > 2 && *org == '_' && *(org + 1) == 'Z') || 3088260684Skaiw (len > 11 && !strncmp(org, "_GLOBAL__I_", 11))); 3089260684Skaiw} 3090260684Skaiw 3091260684Skaiwstatic void 3092260684Skaiwvector_read_cmd_dest(struct vector_read_cmd *v) 3093260684Skaiw{ 3094260684Skaiw 3095260684Skaiw if (v == NULL) 3096260684Skaiw return; 3097260684Skaiw 3098260684Skaiw free(v->r_container); 3099260684Skaiw} 3100260684Skaiw 3101260684Skaiw/* return -1 at failed, 0 at not found, 1 at found. */ 3102260684Skaiwstatic int 3103260684Skaiwvector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst) 3104260684Skaiw{ 3105260684Skaiw size_t i; 3106260684Skaiw 3107260684Skaiw if (v == NULL || dst == READ_FAIL) 3108260684Skaiw return (-1); 3109260684Skaiw 3110260684Skaiw for (i = 0; i < v->size; ++i) 3111260684Skaiw if (v->r_container[i] == dst) 3112260684Skaiw return (1); 3113260684Skaiw 3114260684Skaiw return (0); 3115260684Skaiw} 3116260684Skaiw 3117260684Skaiwstatic int 3118260684Skaiwvector_read_cmd_init(struct vector_read_cmd *v) 3119260684Skaiw{ 3120260684Skaiw 3121260684Skaiw if (v == NULL) 3122260684Skaiw return (0); 3123260684Skaiw 3124260684Skaiw v->size = 0; 3125260684Skaiw v->capacity = VECTOR_DEF_CAPACITY; 3126260684Skaiw 3127260684Skaiw if ((v->r_container = malloc(sizeof(enum read_cmd) * v->capacity)) 3128260684Skaiw == NULL) 3129260684Skaiw return (0); 3130260684Skaiw 3131260684Skaiw return (1); 3132260684Skaiw} 3133260684Skaiw 3134260684Skaiwstatic int 3135260684Skaiwvector_read_cmd_pop(struct vector_read_cmd *v) 3136260684Skaiw{ 3137260684Skaiw 3138260684Skaiw if (v == NULL || v->size == 0) 3139260684Skaiw return (0); 3140260684Skaiw 3141260684Skaiw --v->size; 3142260684Skaiw v->r_container[v->size] = READ_FAIL; 3143260684Skaiw 3144260684Skaiw return (1); 3145260684Skaiw} 3146260684Skaiw 3147260684Skaiwstatic int 3148260684Skaiwvector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd) 3149260684Skaiw{ 3150260684Skaiw enum read_cmd *tmp_r_ctn; 3151260684Skaiw size_t tmp_cap; 3152260684Skaiw size_t i; 3153260684Skaiw 3154260684Skaiw if (v == NULL) 3155260684Skaiw return (0); 3156260684Skaiw 3157260684Skaiw if (v->size == v->capacity) { 3158260684Skaiw tmp_cap = v->capacity * BUFFER_GROWFACTOR; 3159260684Skaiw if ((tmp_r_ctn = malloc(sizeof(enum read_cmd) * tmp_cap)) 3160260684Skaiw == NULL) 3161260684Skaiw return (0); 3162260684Skaiw for (i = 0; i < v->size; ++i) 3163260684Skaiw tmp_r_ctn[i] = v->r_container[i]; 3164260684Skaiw free(v->r_container); 3165260684Skaiw v->r_container = tmp_r_ctn; 3166260684Skaiw v->capacity = tmp_cap; 3167260684Skaiw } 3168260684Skaiw 3169260684Skaiw v->r_container[v->size] = cmd; 3170260684Skaiw ++v->size; 3171260684Skaiw 3172260684Skaiw return (1); 3173260684Skaiw} 3174260684Skaiw 3175260684Skaiwstatic void 3176260684Skaiwvector_type_qualifier_dest(struct vector_type_qualifier *v) 3177260684Skaiw{ 3178260684Skaiw 3179260684Skaiw if (v == NULL) 3180260684Skaiw return; 3181260684Skaiw 3182260684Skaiw free(v->q_container); 3183260684Skaiw vector_str_dest(&v->ext_name); 3184260684Skaiw} 3185260684Skaiw 3186260684Skaiw/* size, capacity, ext_name */ 3187260684Skaiwstatic int 3188260684Skaiwvector_type_qualifier_init(struct vector_type_qualifier *v) 3189260684Skaiw{ 3190260684Skaiw 3191260684Skaiw if (v == NULL) 3192260684Skaiw return (0); 3193260684Skaiw 3194260684Skaiw v->size = 0; 3195260684Skaiw v->capacity = VECTOR_DEF_CAPACITY; 3196260684Skaiw 3197260684Skaiw if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity)) 3198260684Skaiw == NULL) 3199260684Skaiw return (0); 3200260684Skaiw 3201260684Skaiw assert(v->q_container != NULL); 3202260684Skaiw 3203260684Skaiw if (vector_str_init(&v->ext_name) == false) { 3204260684Skaiw free(v->q_container); 3205260684Skaiw return (0); 3206260684Skaiw } 3207260684Skaiw 3208260684Skaiw return (1); 3209260684Skaiw} 3210260684Skaiw 3211260684Skaiwstatic int 3212260684Skaiwvector_type_qualifier_push(struct vector_type_qualifier *v, 3213260684Skaiw enum type_qualifier t) 3214260684Skaiw{ 3215260684Skaiw enum type_qualifier *tmp_ctn; 3216260684Skaiw size_t tmp_cap; 3217260684Skaiw size_t i; 3218260684Skaiw 3219260684Skaiw if (v == NULL) 3220260684Skaiw return (0); 3221260684Skaiw 3222260684Skaiw if (v->size == v->capacity) { 3223260684Skaiw tmp_cap = v->capacity * BUFFER_GROWFACTOR; 3224260684Skaiw if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap)) 3225260684Skaiw == NULL) 3226260684Skaiw return (0); 3227260684Skaiw for (i = 0; i < v->size; ++i) 3228260684Skaiw tmp_ctn[i] = v->q_container[i]; 3229260684Skaiw free(v->q_container); 3230260684Skaiw v->q_container = tmp_ctn; 3231260684Skaiw v->capacity = tmp_cap; 3232260684Skaiw } 3233260684Skaiw 3234260684Skaiw v->q_container[v->size] = t; 3235260684Skaiw ++v->size; 3236260684Skaiw 3237260684Skaiw return (1); 3238260684Skaiw} 3239