Path: blob/main/contrib/elftoolchain/libelftc/libelftc_dem_gnu3.c
39478 views
/*-1* Copyright (c) 2007 Hyogeol Lee <[email protected]>2* Copyright (c) 2015-2017 Kai Wang <[email protected]>3* All rights reserved.4*5* Redistribution and use in source and binary forms, with or without6* modification, are permitted provided that the following conditions7* are met:8* 1. Redistributions of source code must retain the above copyright9* notice, this list of conditions and the following disclaimer10* in this position and unchanged.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14*15* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR16* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES17* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.18* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,19* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT20* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,21* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY22* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT23* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF24* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.25*/26#include <sys/types.h>27#include <assert.h>28#include <ctype.h>29#include <errno.h>30#include <libelftc.h>31#include <limits.h>32#include <stdbool.h>33#include <stdio.h>34#include <stdlib.h>35#include <string.h>3637#include "_libelftc.h"3839ELFTC_VCSID("$Id: libelftc_dem_gnu3.c 3583 2017-10-15 15:38:47Z emaste $");4041/**42* @file cpp_demangle.c43* @brief Decode IA-64 C++ ABI style implementation.44*45* IA-64 standard ABI(Itanium C++ ABI) references.46*47* http://www.codesourcery.com/cxx-abi/abi.html#mangling \n48* http://www.codesourcery.com/cxx-abi/abi-mangling.html49*/5051enum type_qualifier {52TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT,53TYPE_CST, TYPE_VEC, TYPE_RREF54};5556struct vector_type_qualifier {57size_t size, capacity;58enum type_qualifier *q_container;59struct vector_str ext_name;60};6162enum read_cmd {63READ_FAIL, READ_NEST, READ_TMPL, READ_EXPR, READ_EXPL, READ_LOCAL,64READ_TYPE, READ_FUNC, READ_PTRMEM65};6667struct read_cmd_item {68enum read_cmd cmd;69void *data;70};7172struct vector_read_cmd {73size_t size, capacity;74struct read_cmd_item *r_container;75};7677enum push_qualifier {78PUSH_ALL_QUALIFIER,79PUSH_CV_QUALIFIER,80PUSH_NON_CV_QUALIFIER,81};8283struct cpp_demangle_data {84struct vector_str output; /* output string vector */85struct vector_str subst; /* substitution string vector */86struct vector_str tmpl;87struct vector_str class_type;88struct vector_str *cur_output; /* ptr to current output vec */89struct vector_read_cmd cmd;90bool mem_rst; /* restrict member function */91bool mem_vat; /* volatile member function */92bool mem_cst; /* const member function */93bool mem_ref; /* lvalue-ref member func */94bool mem_rref; /* rvalue-ref member func */95bool is_tmpl; /* template args */96bool is_functype; /* function type */97bool ref_qualifier; /* ref qualifier */98enum type_qualifier ref_qualifier_type; /* ref qualifier type */99enum push_qualifier push_qualifier; /* which qualifiers to push */100int func_type;101const char *cur; /* current mangled name ptr */102const char *last_sname; /* last source name */103};104105struct type_delimit {106bool paren;107bool firstp;108};109110#define CPP_DEMANGLE_TRY_LIMIT 128111#define FLOAT_SPRINTF_TRY_LIMIT 5112#define FLOAT_QUADRUPLE_BYTES 16113#define FLOAT_EXTENED_BYTES 10114115#define SIMPLE_HASH(x,y) (64 * x + y)116#define DEM_PUSH_STR(d,s) cpp_demangle_push_str((d), (s), strlen((s)))117#define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s)))118119static void cpp_demangle_data_dest(struct cpp_demangle_data *);120static int cpp_demangle_data_init(struct cpp_demangle_data *,121const char *);122static int cpp_demangle_get_subst(struct cpp_demangle_data *, size_t);123static int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t);124static int cpp_demangle_push_fp(struct cpp_demangle_data *,125char *(*)(const char *, size_t));126static int cpp_demangle_push_str(struct cpp_demangle_data *, const char *,127size_t);128static int cpp_demangle_pop_str(struct cpp_demangle_data *);129static int cpp_demangle_push_subst(struct cpp_demangle_data *,130const char *, size_t);131static int cpp_demangle_push_subst_v(struct cpp_demangle_data *,132struct vector_str *);133static int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *,134struct vector_type_qualifier *, const char *);135static int cpp_demangle_read_array(struct cpp_demangle_data *);136static int cpp_demangle_read_encoding(struct cpp_demangle_data *);137static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *);138static int cpp_demangle_read_expression(struct cpp_demangle_data *);139static int cpp_demangle_read_expression_flat(struct cpp_demangle_data *,140char **);141static int cpp_demangle_read_expression_binary(struct cpp_demangle_data *,142const char *, size_t);143static int cpp_demangle_read_expression_unary(struct cpp_demangle_data *,144const char *, size_t);145static int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *,146const char *, size_t, const char *, size_t);147static int cpp_demangle_read_function(struct cpp_demangle_data *, int *,148struct vector_type_qualifier *);149static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata);150static int cpp_demangle_read_local_name(struct cpp_demangle_data *);151static int cpp_demangle_read_name(struct cpp_demangle_data *);152static int cpp_demangle_read_name_flat(struct cpp_demangle_data *,153char**);154static int cpp_demangle_read_nested_name(struct cpp_demangle_data *);155static int cpp_demangle_read_number(struct cpp_demangle_data *, long *);156static int cpp_demangle_read_number_as_string(struct cpp_demangle_data *,157char **);158static int cpp_demangle_read_nv_offset(struct cpp_demangle_data *);159static int cpp_demangle_read_offset(struct cpp_demangle_data *);160static int cpp_demangle_read_offset_number(struct cpp_demangle_data *);161static int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *,162struct vector_type_qualifier *);163static int cpp_demangle_read_sname(struct cpp_demangle_data *);164static int cpp_demangle_read_subst(struct cpp_demangle_data *);165static int cpp_demangle_read_subst_std(struct cpp_demangle_data *);166static int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *,167const char *);168static int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *);169static int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *);170static int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *);171static int cpp_demangle_read_type(struct cpp_demangle_data *,172struct type_delimit *);173static int cpp_demangle_read_type_flat(struct cpp_demangle_data *,174char **);175static int cpp_demangle_read_uqname(struct cpp_demangle_data *);176static int cpp_demangle_read_v_offset(struct cpp_demangle_data *);177static char *decode_fp_to_double(const char *, size_t);178static char *decode_fp_to_float(const char *, size_t);179static char *decode_fp_to_float128(const char *, size_t);180static char *decode_fp_to_float80(const char *, size_t);181static char *decode_fp_to_long_double(const char *, size_t);182static int hex_to_dec(char);183static void vector_read_cmd_dest(struct vector_read_cmd *);184static struct read_cmd_item *vector_read_cmd_find(struct vector_read_cmd *,185enum read_cmd);186static int vector_read_cmd_init(struct vector_read_cmd *);187static int vector_read_cmd_pop(struct vector_read_cmd *);188static int vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd,189void *);190static void vector_type_qualifier_dest(struct vector_type_qualifier *);191static int vector_type_qualifier_init(struct vector_type_qualifier *);192static int vector_type_qualifier_push(struct vector_type_qualifier *,193enum type_qualifier);194195/**196* @brief Decode the input string by IA-64 C++ ABI style.197*198* GNU GCC v3 use IA-64 standard ABI.199* @return New allocated demangled string or NULL if failed.200* @todo 1. Testing and more test case. 2. Code cleaning.201*/202char *203cpp_demangle_gnu3(const char *org)204{205struct cpp_demangle_data ddata;206struct vector_str ret_type;207struct type_delimit td;208ssize_t org_len;209unsigned int limit;210char *rtn;211bool has_ret, more_type;212213if (org == NULL || (org_len = strlen(org)) < 2)214return (NULL);215216if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {217if ((rtn = malloc(org_len + 19)) == NULL)218return (NULL);219snprintf(rtn, org_len + 19,220"global constructors keyed to %s", org + 11);221return (rtn);222}223224if (org[0] != '_' || org[1] != 'Z')225return (NULL);226227if (!cpp_demangle_data_init(&ddata, org + 2))228return (NULL);229230rtn = NULL;231has_ret = more_type = false;232233if (!cpp_demangle_read_encoding(&ddata))234goto clean;235236/*237* Pop function name from substitution candidate list.238*/239if (*ddata.cur != 0 && ddata.subst.size >= 1) {240if (!vector_str_pop(&ddata.subst))241goto clean;242}243244td.paren = false;245td.firstp = true;246limit = 0;247248/*249* The first type is a return type if we just demangled template250* args. (the template args is right next to the function name,251* which means it's a template function)252*/253if (ddata.is_tmpl) {254ddata.is_tmpl = false;255if (!vector_str_init(&ret_type))256goto clean;257ddata.cur_output = &ret_type;258has_ret = true;259}260261while (*ddata.cur != '\0') {262/*263* Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4264*/265if (*ddata.cur == '@' && *(ddata.cur + 1) == '@')266break;267268if (has_ret) {269/* Read return type */270if (!cpp_demangle_read_type(&ddata, NULL))271goto clean;272} else {273/* Read function arg type */274if (!cpp_demangle_read_type(&ddata, &td))275goto clean;276}277278if (has_ret) {279/* Push return type to the beginning */280if (!VEC_PUSH_STR(&ret_type, " "))281goto clean;282if (!vector_str_push_vector_head(&ddata.output,283&ret_type))284goto clean;285ddata.cur_output = &ddata.output;286vector_str_dest(&ret_type);287has_ret = false;288more_type = true;289} else if (more_type)290more_type = false;291if (limit++ > CPP_DEMANGLE_TRY_LIMIT)292goto clean;293}294if (more_type)295goto clean;296297if (ddata.output.size == 0)298goto clean;299if (td.paren && !VEC_PUSH_STR(&ddata.output, ")"))300goto clean;301if (ddata.mem_vat && !VEC_PUSH_STR(&ddata.output, " volatile"))302goto clean;303if (ddata.mem_cst && !VEC_PUSH_STR(&ddata.output, " const"))304goto clean;305if (ddata.mem_rst && !VEC_PUSH_STR(&ddata.output, " restrict"))306goto clean;307if (ddata.mem_ref && !VEC_PUSH_STR(&ddata.output, " &"))308goto clean;309if (ddata.mem_rref && !VEC_PUSH_STR(&ddata.output, " &&"))310goto clean;311312rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);313314clean:315if (has_ret)316vector_str_dest(&ret_type);317318cpp_demangle_data_dest(&ddata);319320return (rtn);321}322323static void324cpp_demangle_data_dest(struct cpp_demangle_data *d)325{326327if (d == NULL)328return;329330vector_read_cmd_dest(&d->cmd);331vector_str_dest(&d->class_type);332vector_str_dest(&d->tmpl);333vector_str_dest(&d->subst);334vector_str_dest(&d->output);335}336337static int338cpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur)339{340341if (d == NULL || cur == NULL)342return (0);343344if (!vector_str_init(&d->output))345return (0);346if (!vector_str_init(&d->subst))347goto clean1;348if (!vector_str_init(&d->tmpl))349goto clean2;350if (!vector_str_init(&d->class_type))351goto clean3;352if (!vector_read_cmd_init(&d->cmd))353goto clean4;354355assert(d->output.container != NULL);356assert(d->subst.container != NULL);357assert(d->tmpl.container != NULL);358assert(d->class_type.container != NULL);359360d->mem_rst = false;361d->mem_vat = false;362d->mem_cst = false;363d->mem_ref = false;364d->mem_rref = false;365d->is_tmpl = false;366d->is_functype = false;367d->ref_qualifier = false;368d->push_qualifier = PUSH_ALL_QUALIFIER;369d->func_type = 0;370d->cur = cur;371d->cur_output = &d->output;372d->last_sname = NULL;373374return (1);375376clean4:377vector_str_dest(&d->class_type);378clean3:379vector_str_dest(&d->tmpl);380clean2:381vector_str_dest(&d->subst);382clean1:383vector_str_dest(&d->output);384385return (0);386}387388static int389cpp_demangle_push_fp(struct cpp_demangle_data *ddata,390char *(*decoder)(const char *, size_t))391{392size_t len;393int rtn;394const char *fp;395char *f;396397if (ddata == NULL || decoder == NULL)398return (0);399400fp = ddata->cur;401while (*ddata->cur != 'E')402++ddata->cur;403404if ((f = decoder(fp, ddata->cur - fp)) == NULL)405return (0);406407rtn = 0;408if ((len = strlen(f)) > 0)409rtn = cpp_demangle_push_str(ddata, f, len);410411free(f);412413++ddata->cur;414415return (rtn);416}417418static int419cpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str,420size_t len)421{422423if (ddata == NULL || str == NULL || len == 0)424return (0);425426/*427* is_tmpl is used to check if the type (function arg) is right next428* to template args, and should always be cleared whenever new string429* pushed.430*/431ddata->is_tmpl = false;432433return (vector_str_push(ddata->cur_output, str, len));434}435436static int437cpp_demangle_pop_str(struct cpp_demangle_data *ddata)438{439440if (ddata == NULL)441return (0);442443return (vector_str_pop(ddata->cur_output));444}445446static int447cpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str,448size_t len)449{450451if (ddata == NULL || str == NULL || len == 0)452return (0);453454if (!vector_str_find(&ddata->subst, str, len))455return (vector_str_push(&ddata->subst, str, len));456457return (1);458}459460static int461cpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v)462{463size_t str_len;464int rtn;465char *str;466467if (ddata == NULL || v == NULL)468return (0);469470if ((str = vector_str_get_flat(v, &str_len)) == NULL)471return (0);472473rtn = cpp_demangle_push_subst(ddata, str, str_len);474475free(str);476477return (rtn);478}479480static int481cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata,482struct vector_type_qualifier *v, const char *type_str)483{484struct vector_str subst_v;485enum type_qualifier t;486size_t idx, e_idx, e_len;487char *buf;488int rtn;489bool cv;490491if (ddata == NULL || v == NULL)492return (0);493494if ((idx = v->size) == 0)495return (1);496497rtn = 0;498if (type_str != NULL) {499if (!vector_str_init(&subst_v))500return (0);501if (!VEC_PUSH_STR(&subst_v, type_str))502goto clean;503}504505cv = true;506e_idx = 0;507while (idx > 0) {508switch (v->q_container[idx - 1]) {509case TYPE_PTR:510cv = false;511if (ddata->push_qualifier == PUSH_CV_QUALIFIER)512break;513if (!DEM_PUSH_STR(ddata, "*"))514goto clean;515if (type_str != NULL) {516if (!VEC_PUSH_STR(&subst_v, "*"))517goto clean;518if (!cpp_demangle_push_subst_v(ddata,519&subst_v))520goto clean;521}522break;523524case TYPE_REF:525cv = false;526if (ddata->push_qualifier == PUSH_CV_QUALIFIER)527break;528if (!DEM_PUSH_STR(ddata, "&"))529goto clean;530if (type_str != NULL) {531if (!VEC_PUSH_STR(&subst_v, "&"))532goto clean;533if (!cpp_demangle_push_subst_v(ddata,534&subst_v))535goto clean;536}537break;538539case TYPE_RREF:540cv = false;541if (ddata->push_qualifier == PUSH_CV_QUALIFIER)542break;543if (!DEM_PUSH_STR(ddata, "&&"))544goto clean;545if (type_str != NULL) {546if (!VEC_PUSH_STR(&subst_v, "&&"))547goto clean;548if (!cpp_demangle_push_subst_v(ddata,549&subst_v))550goto clean;551}552break;553554case TYPE_CMX:555cv = false;556if (ddata->push_qualifier == PUSH_CV_QUALIFIER)557break;558if (!DEM_PUSH_STR(ddata, " complex"))559goto clean;560if (type_str != NULL) {561if (!VEC_PUSH_STR(&subst_v, " complex"))562goto clean;563if (!cpp_demangle_push_subst_v(ddata,564&subst_v))565goto clean;566}567break;568569case TYPE_IMG:570cv = false;571if (ddata->push_qualifier == PUSH_CV_QUALIFIER)572break;573if (!DEM_PUSH_STR(ddata, " imaginary"))574goto clean;575if (type_str != NULL) {576if (!VEC_PUSH_STR(&subst_v, " imaginary"))577goto clean;578if (!cpp_demangle_push_subst_v(ddata,579&subst_v))580goto clean;581}582break;583584case TYPE_EXT:585cv = false;586if (ddata->push_qualifier == PUSH_CV_QUALIFIER)587break;588if (v->ext_name.size == 0 ||589e_idx > v->ext_name.size - 1)590goto clean;591if ((e_len = strlen(v->ext_name.container[e_idx])) ==5920)593goto clean;594if ((buf = malloc(e_len + 2)) == NULL)595goto clean;596snprintf(buf, e_len + 2, " %s",597v->ext_name.container[e_idx]);598599if (!DEM_PUSH_STR(ddata, buf)) {600free(buf);601goto clean;602}603604if (type_str != NULL) {605if (!VEC_PUSH_STR(&subst_v, buf)) {606free(buf);607goto clean;608}609if (!cpp_demangle_push_subst_v(ddata,610&subst_v)) {611free(buf);612goto clean;613}614}615free(buf);616++e_idx;617break;618619case TYPE_RST:620if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&621cv)622break;623if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)624break;625if (!DEM_PUSH_STR(ddata, " restrict"))626goto clean;627if (type_str != NULL) {628if (!VEC_PUSH_STR(&subst_v, " restrict"))629goto clean;630if (idx - 1 > 0) {631t = v->q_container[idx - 2];632if (t == TYPE_RST || t == TYPE_VAT ||633t == TYPE_CST)634break;635}636if (!cpp_demangle_push_subst_v(ddata,637&subst_v))638goto clean;639}640break;641642case TYPE_VAT:643if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&644cv)645break;646if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)647break;648if (!DEM_PUSH_STR(ddata, " volatile"))649goto clean;650if (type_str != NULL) {651if (!VEC_PUSH_STR(&subst_v, " volatile"))652goto clean;653if (idx - 1 > 0) {654t = v->q_container[idx - 2];655if (t == TYPE_RST || t == TYPE_VAT ||656t == TYPE_CST)657break;658}659if (!cpp_demangle_push_subst_v(ddata,660&subst_v))661goto clean;662}663break;664665case TYPE_CST:666if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&667cv)668break;669if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)670break;671if (!DEM_PUSH_STR(ddata, " const"))672goto clean;673if (type_str != NULL) {674if (!VEC_PUSH_STR(&subst_v, " const"))675goto clean;676if (idx - 1 > 0) {677t = v->q_container[idx - 2];678if (t == TYPE_RST || t == TYPE_VAT ||679t == TYPE_CST)680break;681}682if (!cpp_demangle_push_subst_v(ddata,683&subst_v))684goto clean;685}686break;687688case TYPE_VEC:689cv = false;690if (ddata->push_qualifier == PUSH_CV_QUALIFIER)691break;692if (v->ext_name.size == 0 ||693e_idx > v->ext_name.size - 1)694goto clean;695if ((e_len = strlen(v->ext_name.container[e_idx])) ==6960)697goto clean;698if ((buf = malloc(e_len + 12)) == NULL)699goto clean;700snprintf(buf, e_len + 12, " __vector(%s)",701v->ext_name.container[e_idx]);702if (!DEM_PUSH_STR(ddata, buf)) {703free(buf);704goto clean;705}706if (type_str != NULL) {707if (!VEC_PUSH_STR(&subst_v, buf)) {708free(buf);709goto clean;710}711if (!cpp_demangle_push_subst_v(ddata,712&subst_v)) {713free(buf);714goto clean;715}716}717free(buf);718++e_idx;719break;720}721--idx;722}723724rtn = 1;725clean:726if (type_str != NULL)727vector_str_dest(&subst_v);728729return (rtn);730}731732static int733cpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx)734{735size_t len;736737if (ddata == NULL || ddata->subst.size <= idx)738return (0);739if ((len = strlen(ddata->subst.container[idx])) == 0)740return (0);741if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len))742return (0);743744/* skip '_' */745++ddata->cur;746747return (1);748}749750static int751cpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx)752{753size_t len;754755if (ddata == NULL || ddata->tmpl.size <= idx)756return (0);757if ((len = strlen(ddata->tmpl.container[idx])) == 0)758return (0);759if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len))760return (0);761762++ddata->cur;763764return (1);765}766767static int768cpp_demangle_read_array(struct cpp_demangle_data *ddata)769{770size_t i, num_len, exp_len, p_idx, idx;771const char *num;772char *exp;773774if (ddata == NULL || *(++ddata->cur) == '\0')775return (0);776777if (*ddata->cur == '_') {778if (*(++ddata->cur) == '\0')779return (0);780781if (!cpp_demangle_read_type(ddata, NULL))782return (0);783784if (!DEM_PUSH_STR(ddata, "[]"))785return (0);786} else {787if (ELFTC_ISDIGIT(*ddata->cur) != 0) {788num = ddata->cur;789while (ELFTC_ISDIGIT(*ddata->cur) != 0)790++ddata->cur;791if (*ddata->cur != '_')792return (0);793num_len = ddata->cur - num;794assert(num_len > 0);795if (*(++ddata->cur) == '\0')796return (0);797if (!cpp_demangle_read_type(ddata, NULL))798return (0);799if (!DEM_PUSH_STR(ddata, "["))800return (0);801if (!cpp_demangle_push_str(ddata, num, num_len))802return (0);803if (!DEM_PUSH_STR(ddata, "]"))804return (0);805} else {806p_idx = ddata->output.size;807if (!cpp_demangle_read_expression(ddata))808return (0);809if ((exp = vector_str_substr(&ddata->output, p_idx,810ddata->output.size - 1, &exp_len)) == NULL)811return (0);812idx = ddata->output.size;813for (i = p_idx; i < idx; ++i)814if (!vector_str_pop(&ddata->output)) {815free(exp);816return (0);817}818if (*ddata->cur != '_') {819free(exp);820return (0);821}822++ddata->cur;823if (*ddata->cur == '\0') {824free(exp);825return (0);826}827if (!cpp_demangle_read_type(ddata, NULL)) {828free(exp);829return (0);830}831if (!DEM_PUSH_STR(ddata, "[")) {832free(exp);833return (0);834}835if (!cpp_demangle_push_str(ddata, exp, exp_len)) {836free(exp);837return (0);838}839if (!DEM_PUSH_STR(ddata, "]")) {840free(exp);841return (0);842}843free(exp);844}845}846847return (1);848}849850static int851cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata)852{853const char *num;854855if (ddata == NULL || *(++ddata->cur) == '\0')856return (0);857858if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') {859ddata->cur += 2;860if (*ddata->cur == '\0')861return (0);862if (!cpp_demangle_read_encoding(ddata))863return (0);864++ddata->cur;865return (1);866}867868switch (*ddata->cur) {869case 'b':870if (*(ddata->cur + 2) != 'E')871return (0);872switch (*(++ddata->cur)) {873case '0':874ddata->cur += 2;875return (DEM_PUSH_STR(ddata, "false"));876case '1':877ddata->cur += 2;878return (DEM_PUSH_STR(ddata, "true"));879default:880return (0);881}882883case 'd':884++ddata->cur;885return (cpp_demangle_push_fp(ddata, decode_fp_to_double));886887case 'e':888++ddata->cur;889if (sizeof(long double) == 10)890return (cpp_demangle_push_fp(ddata,891decode_fp_to_double));892return (cpp_demangle_push_fp(ddata, decode_fp_to_float80));893894case 'f':895++ddata->cur;896return (cpp_demangle_push_fp(ddata, decode_fp_to_float));897898case 'g':899++ddata->cur;900if (sizeof(long double) == 16)901return (cpp_demangle_push_fp(ddata,902decode_fp_to_double));903return (cpp_demangle_push_fp(ddata, decode_fp_to_float128));904905case 'i':906case 'j':907case 'l':908case 'm':909case 'n':910case 's':911case 't':912case 'x':913case 'y':914if (*(++ddata->cur) == 'n') {915if (!DEM_PUSH_STR(ddata, "-"))916return (0);917++ddata->cur;918}919num = ddata->cur;920while (*ddata->cur != 'E') {921if (!ELFTC_ISDIGIT(*ddata->cur))922return (0);923++ddata->cur;924}925++ddata->cur;926return (cpp_demangle_push_str(ddata, num,927ddata->cur - num - 1));928929default:930return (0);931}932}933934static int935cpp_demangle_read_expression(struct cpp_demangle_data *ddata)936{937938if (ddata == NULL || *ddata->cur == '\0')939return (0);940941switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {942case SIMPLE_HASH('s', 't'):943ddata->cur += 2;944return (cpp_demangle_read_type(ddata, NULL));945946case SIMPLE_HASH('s', 'r'):947ddata->cur += 2;948if (!cpp_demangle_read_type(ddata, NULL))949return (0);950if (!cpp_demangle_read_uqname(ddata))951return (0);952if (*ddata->cur == 'I')953return (cpp_demangle_read_tmpl_args(ddata));954return (1);955956case SIMPLE_HASH('a', 'a'):957/* operator && */958ddata->cur += 2;959return (cpp_demangle_read_expression_binary(ddata, "&&", 2));960961case SIMPLE_HASH('a', 'd'):962/* operator & (unary) */963ddata->cur += 2;964return (cpp_demangle_read_expression_unary(ddata, "&", 1));965966case SIMPLE_HASH('a', 'n'):967/* operator & */968ddata->cur += 2;969return (cpp_demangle_read_expression_binary(ddata, "&", 1));970971case SIMPLE_HASH('a', 'N'):972/* operator &= */973ddata->cur += 2;974return (cpp_demangle_read_expression_binary(ddata, "&=", 2));975976case SIMPLE_HASH('a', 'S'):977/* operator = */978ddata->cur += 2;979return (cpp_demangle_read_expression_binary(ddata, "=", 1));980981case SIMPLE_HASH('c', 'l'):982/* operator () */983ddata->cur += 2;984return (cpp_demangle_read_expression_binary(ddata, "()", 2));985986case SIMPLE_HASH('c', 'm'):987/* operator , */988ddata->cur += 2;989return (cpp_demangle_read_expression_binary(ddata, ",", 1));990991case SIMPLE_HASH('c', 'o'):992/* operator ~ */993ddata->cur += 2;994return (cpp_demangle_read_expression_binary(ddata, "~", 1));995996case SIMPLE_HASH('c', 'v'):997/* operator (cast) */998ddata->cur += 2;999return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6));10001001case SIMPLE_HASH('d', 'a'):1002/* operator delete [] */1003ddata->cur += 2;1004return (cpp_demangle_read_expression_unary(ddata, "delete []", 9));10051006case SIMPLE_HASH('d', 'e'):1007/* operator * (unary) */1008ddata->cur += 2;1009return (cpp_demangle_read_expression_unary(ddata, "*", 1));10101011case SIMPLE_HASH('d', 'l'):1012/* operator delete */1013ddata->cur += 2;1014return (cpp_demangle_read_expression_unary(ddata, "delete", 6));10151016case SIMPLE_HASH('d', 'v'):1017/* operator / */1018ddata->cur += 2;1019return (cpp_demangle_read_expression_binary(ddata, "/", 1));10201021case SIMPLE_HASH('d', 'V'):1022/* operator /= */1023ddata->cur += 2;1024return (cpp_demangle_read_expression_binary(ddata, "/=", 2));10251026case SIMPLE_HASH('e', 'o'):1027/* operator ^ */1028ddata->cur += 2;1029return (cpp_demangle_read_expression_binary(ddata, "^", 1));10301031case SIMPLE_HASH('e', 'O'):1032/* operator ^= */1033ddata->cur += 2;1034return (cpp_demangle_read_expression_binary(ddata, "^=", 2));10351036case SIMPLE_HASH('e', 'q'):1037/* operator == */1038ddata->cur += 2;1039return (cpp_demangle_read_expression_binary(ddata, "==", 2));10401041case SIMPLE_HASH('g', 'e'):1042/* operator >= */1043ddata->cur += 2;1044return (cpp_demangle_read_expression_binary(ddata, ">=", 2));10451046case SIMPLE_HASH('g', 't'):1047/* operator > */1048ddata->cur += 2;1049return (cpp_demangle_read_expression_binary(ddata, ">", 1));10501051case SIMPLE_HASH('i', 'x'):1052/* operator [] */1053ddata->cur += 2;1054return (cpp_demangle_read_expression_binary(ddata, "[]", 2));10551056case SIMPLE_HASH('l', 'e'):1057/* operator <= */1058ddata->cur += 2;1059return (cpp_demangle_read_expression_binary(ddata, "<=", 2));10601061case SIMPLE_HASH('l', 's'):1062/* operator << */1063ddata->cur += 2;1064return (cpp_demangle_read_expression_binary(ddata, "<<", 2));10651066case SIMPLE_HASH('l', 'S'):1067/* operator <<= */1068ddata->cur += 2;1069return (cpp_demangle_read_expression_binary(ddata, "<<=", 3));10701071case SIMPLE_HASH('l', 't'):1072/* operator < */1073ddata->cur += 2;1074return (cpp_demangle_read_expression_binary(ddata, "<", 1));10751076case SIMPLE_HASH('m', 'i'):1077/* operator - */1078ddata->cur += 2;1079return (cpp_demangle_read_expression_binary(ddata, "-", 1));10801081case SIMPLE_HASH('m', 'I'):1082/* operator -= */1083ddata->cur += 2;1084return (cpp_demangle_read_expression_binary(ddata, "-=", 2));10851086case SIMPLE_HASH('m', 'l'):1087/* operator * */1088ddata->cur += 2;1089return (cpp_demangle_read_expression_binary(ddata, "*", 1));10901091case SIMPLE_HASH('m', 'L'):1092/* operator *= */1093ddata->cur += 2;1094return (cpp_demangle_read_expression_binary(ddata, "*=", 2));10951096case SIMPLE_HASH('m', 'm'):1097/* operator -- */1098ddata->cur += 2;1099return (cpp_demangle_read_expression_binary(ddata, "--", 2));11001101case SIMPLE_HASH('n', 'a'):1102/* operator new[] */1103ddata->cur += 2;1104return (cpp_demangle_read_expression_unary(ddata, "new []", 6));11051106case SIMPLE_HASH('n', 'e'):1107/* operator != */1108ddata->cur += 2;1109return (cpp_demangle_read_expression_binary(ddata, "!=", 2));11101111case SIMPLE_HASH('n', 'g'):1112/* operator - (unary) */1113ddata->cur += 2;1114return (cpp_demangle_read_expression_unary(ddata, "-", 1));11151116case SIMPLE_HASH('n', 't'):1117/* operator ! */1118ddata->cur += 2;1119return (cpp_demangle_read_expression_binary(ddata, "!", 1));11201121case SIMPLE_HASH('n', 'w'):1122/* operator new */1123ddata->cur += 2;1124return (cpp_demangle_read_expression_unary(ddata, "new", 3));11251126case SIMPLE_HASH('o', 'o'):1127/* operator || */1128ddata->cur += 2;1129return (cpp_demangle_read_expression_binary(ddata, "||", 2));11301131case SIMPLE_HASH('o', 'r'):1132/* operator | */1133ddata->cur += 2;1134return (cpp_demangle_read_expression_binary(ddata, "|", 1));11351136case SIMPLE_HASH('o', 'R'):1137/* operator |= */1138ddata->cur += 2;1139return (cpp_demangle_read_expression_binary(ddata, "|=", 2));11401141case SIMPLE_HASH('p', 'l'):1142/* operator + */1143ddata->cur += 2;1144return (cpp_demangle_read_expression_binary(ddata, "+", 1));11451146case SIMPLE_HASH('p', 'L'):1147/* operator += */1148ddata->cur += 2;1149return (cpp_demangle_read_expression_binary(ddata, "+=", 2));11501151case SIMPLE_HASH('p', 'm'):1152/* operator ->* */1153ddata->cur += 2;1154return (cpp_demangle_read_expression_binary(ddata, "->*", 3));11551156case SIMPLE_HASH('p', 'p'):1157/* operator ++ */1158ddata->cur += 2;1159return (cpp_demangle_read_expression_binary(ddata, "++", 2));11601161case SIMPLE_HASH('p', 's'):1162/* operator + (unary) */1163ddata->cur += 2;1164return (cpp_demangle_read_expression_unary(ddata, "+", 1));11651166case SIMPLE_HASH('p', 't'):1167/* operator -> */1168ddata->cur += 2;1169return (cpp_demangle_read_expression_binary(ddata, "->", 2));11701171case SIMPLE_HASH('q', 'u'):1172/* operator ? */1173ddata->cur += 2;1174return (cpp_demangle_read_expression_trinary(ddata, "?", 1,1175":", 1));11761177case SIMPLE_HASH('r', 'm'):1178/* operator % */1179ddata->cur += 2;1180return (cpp_demangle_read_expression_binary(ddata, "%", 1));11811182case SIMPLE_HASH('r', 'M'):1183/* operator %= */1184ddata->cur += 2;1185return (cpp_demangle_read_expression_binary(ddata, "%=", 2));11861187case SIMPLE_HASH('r', 's'):1188/* operator >> */1189ddata->cur += 2;1190return (cpp_demangle_read_expression_binary(ddata, ">>", 2));11911192case SIMPLE_HASH('r', 'S'):1193/* operator >>= */1194ddata->cur += 2;1195return (cpp_demangle_read_expression_binary(ddata, ">>=", 3));11961197case SIMPLE_HASH('r', 'z'):1198/* operator sizeof */1199ddata->cur += 2;1200return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6));12011202case SIMPLE_HASH('s', 'v'):1203/* operator sizeof */1204ddata->cur += 2;1205return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6));1206}12071208switch (*ddata->cur) {1209case 'L':1210return (cpp_demangle_read_expr_primary(ddata));1211case 'T':1212return (cpp_demangle_read_tmpl_param(ddata));1213}12141215return (0);1216}12171218static int1219cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str)1220{1221struct vector_str *output;1222size_t i, p_idx, idx, exp_len;1223char *exp;12241225output = &ddata->output;12261227p_idx = output->size;12281229if (!cpp_demangle_read_expression(ddata))1230return (0);12311232if ((exp = vector_str_substr(output, p_idx, output->size - 1,1233&exp_len)) == NULL)1234return (0);12351236idx = output->size;1237for (i = p_idx; i < idx; ++i) {1238if (!vector_str_pop(output)) {1239free(exp);1240return (0);1241}1242}12431244*str = exp;12451246return (1);1247}12481249static int1250cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata,1251const char *name, size_t len)1252{12531254if (ddata == NULL || name == NULL || len == 0)1255return (0);1256if (!cpp_demangle_read_expression(ddata))1257return (0);1258if (!cpp_demangle_push_str(ddata, name, len))1259return (0);12601261return (cpp_demangle_read_expression(ddata));1262}12631264static int1265cpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata,1266const char *name, size_t len)1267{12681269if (ddata == NULL || name == NULL || len == 0)1270return (0);1271if (!cpp_demangle_read_expression(ddata))1272return (0);12731274return (cpp_demangle_push_str(ddata, name, len));1275}12761277static int1278cpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata,1279const char *name1, size_t len1, const char *name2, size_t len2)1280{12811282if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL ||1283len2 == 0)1284return (0);12851286if (!cpp_demangle_read_expression(ddata))1287return (0);1288if (!cpp_demangle_push_str(ddata, name1, len1))1289return (0);1290if (!cpp_demangle_read_expression(ddata))1291return (0);1292if (!cpp_demangle_push_str(ddata, name2, len2))1293return (0);12941295return (cpp_demangle_read_expression(ddata));1296}12971298static int1299cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c,1300struct vector_type_qualifier *v)1301{1302struct type_delimit td;1303struct read_cmd_item *rc;1304size_t class_type_size, class_type_len, limit;1305const char *class_type;1306int i;1307bool paren, non_cv_qualifier;13081309if (ddata == NULL || *ddata->cur != 'F' || v == NULL)1310return (0);13111312++ddata->cur;1313if (*ddata->cur == 'Y') {1314if (ext_c != NULL)1315*ext_c = 1;1316++ddata->cur;1317}13181319/* Return type */1320if (!cpp_demangle_read_type(ddata, NULL))1321return (0);13221323if (*ddata->cur != 'E') {1324if (!DEM_PUSH_STR(ddata, " "))1325return (0);13261327non_cv_qualifier = false;1328if (v->size > 0) {1329for (i = 0; (size_t) i < v->size; i++) {1330if (v->q_container[i] != TYPE_RST &&1331v->q_container[i] != TYPE_VAT &&1332v->q_container[i] != TYPE_CST) {1333non_cv_qualifier = true;1334break;1335}1336}1337}13381339paren = false;1340rc = vector_read_cmd_find(&ddata->cmd, READ_PTRMEM);1341if (non_cv_qualifier || rc != NULL) {1342if (!DEM_PUSH_STR(ddata, "("))1343return (0);1344paren = true;1345}13461347/* Push non-cv qualifiers. */1348ddata->push_qualifier = PUSH_NON_CV_QUALIFIER;1349if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))1350return (0);13511352if (rc) {1353if (non_cv_qualifier && !DEM_PUSH_STR(ddata, " "))1354return (0);1355if ((class_type_size = ddata->class_type.size) == 0)1356return (0);1357class_type =1358ddata->class_type.container[class_type_size - 1];1359if (class_type == NULL)1360return (0);1361if ((class_type_len = strlen(class_type)) == 0)1362return (0);1363if (!cpp_demangle_push_str(ddata, class_type,1364class_type_len))1365return (0);1366if (!DEM_PUSH_STR(ddata, "::*"))1367return (0);1368/* Push pointer-to-member qualifiers. */1369ddata->push_qualifier = PUSH_ALL_QUALIFIER;1370if (!cpp_demangle_push_type_qualifier(ddata, rc->data,1371NULL))1372return (0);1373++ddata->func_type;1374}13751376if (paren) {1377if (!DEM_PUSH_STR(ddata, ")"))1378return (0);1379paren = false;1380}13811382td.paren = false;1383td.firstp = true;1384limit = 0;1385ddata->is_functype = true;1386for (;;) {1387if (!cpp_demangle_read_type(ddata, &td))1388return (0);1389if (*ddata->cur == 'E')1390break;1391if (limit++ > CPP_DEMANGLE_TRY_LIMIT)1392return (0);1393}1394ddata->is_functype = false;1395if (td.paren) {1396if (!DEM_PUSH_STR(ddata, ")"))1397return (0);1398td.paren = false;1399}14001401/* Push CV qualifiers. */1402ddata->push_qualifier = PUSH_CV_QUALIFIER;1403if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))1404return (0);14051406ddata->push_qualifier = PUSH_ALL_QUALIFIER;14071408/* Release type qualifier vector. */1409vector_type_qualifier_dest(v);1410if (!vector_type_qualifier_init(v))1411return (0);14121413/* Push ref-qualifiers. */1414if (ddata->ref_qualifier) {1415switch (ddata->ref_qualifier_type) {1416case TYPE_REF:1417if (!DEM_PUSH_STR(ddata, " &"))1418return (0);1419break;1420case TYPE_RREF:1421if (!DEM_PUSH_STR(ddata, " &&"))1422return (0);1423break;1424default:1425return (0);1426}1427ddata->ref_qualifier = false;1428}1429}14301431++ddata->cur;14321433return (1);1434}14351436/* read encoding, encoding are function name, data name, special-name */1437static int1438cpp_demangle_read_encoding(struct cpp_demangle_data *ddata)1439{1440char *name, *type, *num_str;1441long offset;1442int rtn;14431444if (ddata == NULL || *ddata->cur == '\0')1445return (0);14461447/* special name */1448switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {1449case SIMPLE_HASH('G', 'A'):1450if (!DEM_PUSH_STR(ddata, "hidden alias for "))1451return (0);1452ddata->cur += 2;1453if (*ddata->cur == '\0')1454return (0);1455return (cpp_demangle_read_encoding(ddata));14561457case SIMPLE_HASH('G', 'R'):1458if (!DEM_PUSH_STR(ddata, "reference temporary #"))1459return (0);1460ddata->cur += 2;1461if (*ddata->cur == '\0')1462return (0);1463if (!cpp_demangle_read_name_flat(ddata, &name))1464return (0);1465rtn = 0;1466if (!cpp_demangle_read_number_as_string(ddata, &num_str))1467goto clean1;1468if (!DEM_PUSH_STR(ddata, num_str))1469goto clean2;1470if (!DEM_PUSH_STR(ddata, " for "))1471goto clean2;1472if (!DEM_PUSH_STR(ddata, name))1473goto clean2;1474rtn = 1;1475clean2:1476free(num_str);1477clean1:1478free(name);1479return (rtn);14801481case SIMPLE_HASH('G', 'T'):1482ddata->cur += 2;1483if (*ddata->cur == '\0')1484return (0);1485switch (*ddata->cur) {1486case 'n':1487if (!DEM_PUSH_STR(ddata, "non-transaction clone for "))1488return (0);1489break;1490case 't':1491default:1492if (!DEM_PUSH_STR(ddata, "transaction clone for "))1493return (0);1494break;1495}1496++ddata->cur;1497return (cpp_demangle_read_encoding(ddata));14981499case SIMPLE_HASH('G', 'V'):1500/* sentry object for 1 time init */1501if (!DEM_PUSH_STR(ddata, "guard variable for "))1502return (0);1503ddata->cur += 2;1504break;15051506case SIMPLE_HASH('T', 'c'):1507/* virtual function covariant override thunk */1508if (!DEM_PUSH_STR(ddata,1509"virtual function covariant override "))1510return (0);1511ddata->cur += 2;1512if (*ddata->cur == '\0')1513return (0);1514if (!cpp_demangle_read_offset(ddata))1515return (0);1516if (!cpp_demangle_read_offset(ddata))1517return (0);1518return (cpp_demangle_read_encoding(ddata));15191520case SIMPLE_HASH('T', 'C'):1521/* construction vtable */1522if (!DEM_PUSH_STR(ddata, "construction vtable for "))1523return (0);1524ddata->cur += 2;1525if (*ddata->cur == '\0')1526return (0);1527if (!cpp_demangle_read_type_flat(ddata, &type))1528return (0);1529rtn = 0;1530if (!cpp_demangle_read_number(ddata, &offset))1531goto clean3;1532if (*ddata->cur++ != '_')1533goto clean3;1534if (!cpp_demangle_read_type(ddata, NULL))1535goto clean3;1536if (!DEM_PUSH_STR(ddata, "-in-"))1537goto clean3;1538if (!DEM_PUSH_STR(ddata, type))1539goto clean3;1540rtn = 1;1541clean3:1542free(type);1543return (rtn);15441545case SIMPLE_HASH('T', 'D'):1546/* typeinfo common proxy */1547break;15481549case SIMPLE_HASH('T', 'F'):1550/* typeinfo fn */1551if (!DEM_PUSH_STR(ddata, "typeinfo fn for "))1552return (0);1553ddata->cur += 2;1554if (*ddata->cur == '\0')1555return (0);1556return (cpp_demangle_read_type(ddata, NULL));15571558case SIMPLE_HASH('T', 'h'):1559/* virtual function non-virtual override thunk */1560if (!DEM_PUSH_STR(ddata,1561"virtual function non-virtual override "))1562return (0);1563ddata->cur += 2;1564if (*ddata->cur == '\0')1565return (0);1566if (!cpp_demangle_read_nv_offset(ddata))1567return (0);1568return (cpp_demangle_read_encoding(ddata));15691570case SIMPLE_HASH('T', 'H'):1571/* TLS init function */1572if (!DEM_PUSH_STR(ddata, "TLS init function for "))1573return (0);1574ddata->cur += 2;1575if (*ddata->cur == '\0')1576return (0);1577break;15781579case SIMPLE_HASH('T', 'I'):1580/* typeinfo structure */1581if (!DEM_PUSH_STR(ddata, "typeinfo for "))1582return (0);1583ddata->cur += 2;1584if (*ddata->cur == '\0')1585return (0);1586return (cpp_demangle_read_type(ddata, NULL));15871588case SIMPLE_HASH('T', 'J'):1589/* java class */1590if (!DEM_PUSH_STR(ddata, "java Class for "))1591return (0);1592ddata->cur += 2;1593if (*ddata->cur == '\0')1594return (0);1595return (cpp_demangle_read_type(ddata, NULL));15961597case SIMPLE_HASH('T', 'S'):1598/* RTTI name (NTBS) */1599if (!DEM_PUSH_STR(ddata, "typeinfo name for "))1600return (0);1601ddata->cur += 2;1602if (*ddata->cur == '\0')1603return (0);1604return (cpp_demangle_read_type(ddata, NULL));16051606case SIMPLE_HASH('T', 'T'):1607/* VTT table */1608if (!DEM_PUSH_STR(ddata, "VTT for "))1609return (0);1610ddata->cur += 2;1611if (*ddata->cur == '\0')1612return (0);1613return (cpp_demangle_read_type(ddata, NULL));16141615case SIMPLE_HASH('T', 'v'):1616/* virtual function virtual override thunk */1617if (!DEM_PUSH_STR(ddata, "virtual function virtual override "))1618return (0);1619ddata->cur += 2;1620if (*ddata->cur == '\0')1621return (0);1622if (!cpp_demangle_read_v_offset(ddata))1623return (0);1624return (cpp_demangle_read_encoding(ddata));16251626case SIMPLE_HASH('T', 'V'):1627/* virtual table */1628if (!DEM_PUSH_STR(ddata, "vtable for "))1629return (0);1630ddata->cur += 2;1631if (*ddata->cur == '\0')1632return (0);1633return (cpp_demangle_read_type(ddata, NULL));16341635case SIMPLE_HASH('T', 'W'):1636/* TLS wrapper function */1637if (!DEM_PUSH_STR(ddata, "TLS wrapper function for "))1638return (0);1639ddata->cur += 2;1640if (*ddata->cur == '\0')1641return (0);1642break;1643}16441645return (cpp_demangle_read_name(ddata));1646}16471648static int1649cpp_demangle_read_local_name(struct cpp_demangle_data *ddata)1650{1651struct vector_str local_name;1652struct type_delimit td;1653size_t limit;1654bool more_type;16551656if (ddata == NULL)1657return (0);1658if (*(++ddata->cur) == '\0')1659return (0);16601661if (!vector_str_init(&local_name))1662return (0);1663ddata->cur_output = &local_name;16641665if (!cpp_demangle_read_encoding(ddata)) {1666vector_str_dest(&local_name);1667return (0);1668}16691670ddata->cur_output = &ddata->output;16711672td.paren = false;1673td.firstp = true;1674more_type = false;1675limit = 0;16761677/*1678* The first type is a return type if we just demangled template1679* args. (the template args is right next to the function name,1680* which means it's a template function)1681*/1682if (ddata->is_tmpl) {1683ddata->is_tmpl = false;16841685/* Read return type */1686if (!cpp_demangle_read_type(ddata, NULL)) {1687vector_str_dest(&local_name);1688return (0);1689}16901691more_type = true;1692}16931694/* Now we can push the name after possible return type is handled. */1695if (!vector_str_push_vector(&ddata->output, &local_name)) {1696vector_str_dest(&local_name);1697return (0);1698}1699vector_str_dest(&local_name);17001701while (*ddata->cur != '\0') {1702if (!cpp_demangle_read_type(ddata, &td))1703return (0);1704if (more_type)1705more_type = false;1706if (*ddata->cur == 'E')1707break;1708if (limit++ > CPP_DEMANGLE_TRY_LIMIT)1709return (0);1710}1711if (more_type)1712return (0);17131714if (*(++ddata->cur) == '\0')1715return (0);1716if (td.paren == true) {1717if (!DEM_PUSH_STR(ddata, ")"))1718return (0);1719td.paren = false;1720}1721if (*ddata->cur == 's')1722++ddata->cur;1723else {1724if (!DEM_PUSH_STR(ddata, "::"))1725return (0);1726if (!cpp_demangle_read_name(ddata))1727return (0);1728}1729if (*ddata->cur == '_') {1730++ddata->cur;1731while (ELFTC_ISDIGIT(*ddata->cur) != 0)1732++ddata->cur;1733}17341735return (1);1736}17371738static int1739cpp_demangle_read_name(struct cpp_demangle_data *ddata)1740{1741struct vector_str *output, v;1742size_t p_idx, subst_str_len;1743int rtn;1744char *subst_str;17451746if (ddata == NULL || *ddata->cur == '\0')1747return (0);17481749output = ddata->cur_output;17501751subst_str = NULL;17521753switch (*ddata->cur) {1754case 'S':1755return (cpp_demangle_read_subst(ddata));1756case 'N':1757return (cpp_demangle_read_nested_name(ddata));1758case 'Z':1759return (cpp_demangle_read_local_name(ddata));1760}17611762if (!vector_str_init(&v))1763return (0);17641765p_idx = output->size;1766rtn = 0;1767if (!cpp_demangle_read_uqname(ddata))1768goto clean;1769if ((subst_str = vector_str_substr(output, p_idx, output->size - 1,1770&subst_str_len)) == NULL)1771goto clean;1772if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) {1773rtn = 1;1774goto clean;1775}1776if (!vector_str_push(&v, subst_str, subst_str_len))1777goto clean;1778if (!cpp_demangle_push_subst_v(ddata, &v))1779goto clean;17801781if (*ddata->cur == 'I') {1782p_idx = output->size;1783if (!cpp_demangle_read_tmpl_args(ddata))1784goto clean;1785free(subst_str);1786if ((subst_str = vector_str_substr(output, p_idx,1787output->size - 1, &subst_str_len)) == NULL)1788goto clean;1789if (!vector_str_push(&v, subst_str, subst_str_len))1790goto clean;1791if (!cpp_demangle_push_subst_v(ddata, &v))1792goto clean;1793}17941795rtn = 1;17961797clean:1798free(subst_str);1799vector_str_dest(&v);18001801return (rtn);1802}18031804static int1805cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str)1806{1807struct vector_str *output;1808size_t i, p_idx, idx, name_len;1809char *name;18101811output = ddata->cur_output;18121813p_idx = output->size;18141815if (!cpp_demangle_read_name(ddata))1816return (0);18171818if ((name = vector_str_substr(output, p_idx, output->size - 1,1819&name_len)) == NULL)1820return (0);18211822idx = output->size;1823for (i = p_idx; i < idx; ++i) {1824if (!vector_str_pop(output)) {1825free(name);1826return (0);1827}1828}18291830*str = name;18311832return (1);1833}18341835static int1836cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata)1837{1838struct vector_str *output, v;1839size_t limit, p_idx, subst_str_len;1840int rtn;1841char *subst_str;18421843if (ddata == NULL || *ddata->cur != 'N')1844return (0);1845if (*(++ddata->cur) == '\0')1846return (0);18471848do {1849switch (*ddata->cur) {1850case 'r':1851ddata->mem_rst = true;1852break;1853case 'V':1854ddata->mem_vat = true;1855break;1856case 'K':1857ddata->mem_cst = true;1858break;1859case 'R':1860ddata->mem_ref = true;1861break;1862case 'O':1863ddata->mem_rref = true;1864break;1865default:1866goto next;1867}1868} while (*(++ddata->cur));18691870next:1871output = ddata->cur_output;1872if (!vector_str_init(&v))1873return (0);18741875rtn = 0;1876limit = 0;1877for (;;) {1878p_idx = output->size;1879switch (*ddata->cur) {1880case 'I':1881if (!cpp_demangle_read_tmpl_args(ddata))1882goto clean;1883break;1884case 'S':1885if (!cpp_demangle_read_subst(ddata))1886goto clean;1887break;1888case 'T':1889if (!cpp_demangle_read_tmpl_param(ddata))1890goto clean;1891break;1892default:1893if (!cpp_demangle_read_uqname(ddata))1894goto clean;1895}18961897if (p_idx == output->size)1898goto next_comp;1899if ((subst_str = vector_str_substr(output, p_idx,1900output->size - 1, &subst_str_len)) == NULL)1901goto clean;1902if (!vector_str_push(&v, subst_str, subst_str_len)) {1903free(subst_str);1904goto clean;1905}1906free(subst_str);19071908if (!cpp_demangle_push_subst_v(ddata, &v))1909goto clean;19101911next_comp:1912if (*ddata->cur == 'E')1913break;1914else if (*ddata->cur != 'I' && *ddata->cur != 'C' &&1915*ddata->cur != 'D' && p_idx != output->size) {1916if (!DEM_PUSH_STR(ddata, "::"))1917goto clean;1918if (!VEC_PUSH_STR(&v, "::"))1919goto clean;1920}1921if (limit++ > CPP_DEMANGLE_TRY_LIMIT)1922goto clean;1923}19241925++ddata->cur;1926rtn = 1;19271928clean:1929vector_str_dest(&v);19301931return (rtn);1932}19331934/*1935* read number1936* number ::= [n] <decimal>1937*/1938static int1939cpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn)1940{1941long len, negative_factor;19421943if (ddata == NULL || rtn == NULL)1944return (0);19451946negative_factor = 1;1947if (*ddata->cur == 'n') {1948negative_factor = -1;19491950++ddata->cur;1951}1952if (ELFTC_ISDIGIT(*ddata->cur) == 0)1953return (0);19541955errno = 0;1956if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 &&1957errno != 0)1958return (0);19591960while (ELFTC_ISDIGIT(*ddata->cur) != 0)1961++ddata->cur;19621963assert(len >= 0);1964assert(negative_factor == 1 || negative_factor == -1);19651966*rtn = len * negative_factor;19671968return (1);1969}19701971static int1972cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str)1973{1974long n;19751976if (!cpp_demangle_read_number(ddata, &n)) {1977*str = NULL;1978return (0);1979}19801981if (asprintf(str, "%ld", n) < 0) {1982*str = NULL;1983return (0);1984}19851986return (1);1987}19881989static int1990cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata)1991{19921993if (ddata == NULL)1994return (0);19951996if (!DEM_PUSH_STR(ddata, "offset : "))1997return (0);19981999return (cpp_demangle_read_offset_number(ddata));2000}20012002/* read offset, offset are nv-offset, v-offset */2003static int2004cpp_demangle_read_offset(struct cpp_demangle_data *ddata)2005{20062007if (ddata == NULL)2008return (0);20092010if (*ddata->cur == 'h') {2011++ddata->cur;2012return (cpp_demangle_read_nv_offset(ddata));2013} else if (*ddata->cur == 'v') {2014++ddata->cur;2015return (cpp_demangle_read_v_offset(ddata));2016}20172018return (0);2019}20202021static int2022cpp_demangle_read_offset_number(struct cpp_demangle_data *ddata)2023{2024bool negative;2025const char *start;20262027if (ddata == NULL || *ddata->cur == '\0')2028return (0);20292030/* offset could be negative */2031if (*ddata->cur == 'n') {2032negative = true;2033start = ddata->cur + 1;2034} else {2035negative = false;2036start = ddata->cur;2037}20382039while (*ddata->cur != '_')2040++ddata->cur;20412042if (negative && !DEM_PUSH_STR(ddata, "-"))2043return (0);20442045assert(start != NULL);20462047if (!cpp_demangle_push_str(ddata, start, ddata->cur - start))2048return (0);2049if (!DEM_PUSH_STR(ddata, " "))2050return (0);20512052++ddata->cur;20532054return (1);2055}20562057static int2058cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata,2059struct vector_type_qualifier *v)2060{2061size_t class_type_len, i, idx, p_idx;2062int p_func_type, rtn;2063char *class_type;20642065if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0')2066return (0);20672068p_idx = ddata->output.size;2069if (!cpp_demangle_read_type(ddata, NULL))2070return (0);20712072if ((class_type = vector_str_substr(&ddata->output, p_idx,2073ddata->output.size - 1, &class_type_len)) == NULL)2074return (0);20752076rtn = 0;2077idx = ddata->output.size;2078for (i = p_idx; i < idx; ++i)2079if (!vector_str_pop(&ddata->output))2080goto clean1;20812082if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM, v))2083goto clean1;20842085if (!vector_str_push(&ddata->class_type, class_type, class_type_len))2086goto clean2;20872088p_func_type = ddata->func_type;2089if (!cpp_demangle_read_type(ddata, NULL))2090goto clean3;20912092if (p_func_type == ddata->func_type) {2093if (!DEM_PUSH_STR(ddata, " "))2094goto clean3;2095if (!cpp_demangle_push_str(ddata, class_type, class_type_len))2096goto clean3;2097if (!DEM_PUSH_STR(ddata, "::*"))2098goto clean3;2099}21002101rtn = 1;2102clean3:2103if (!vector_str_pop(&ddata->class_type))2104rtn = 0;2105clean2:2106if (!vector_read_cmd_pop(&ddata->cmd))2107rtn = 0;2108clean1:2109free(class_type);21102111vector_type_qualifier_dest(v);2112if (!vector_type_qualifier_init(v))2113return (0);21142115return (rtn);2116}21172118/* read source-name, source-name is <len> <ID> */2119static int2120cpp_demangle_read_sname(struct cpp_demangle_data *ddata)2121{2122long len;2123int err;21242125if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 ||2126len <= 0)2127return (0);21282129if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0))2130err = DEM_PUSH_STR(ddata, "(anonymous namespace)");2131else2132err = cpp_demangle_push_str(ddata, ddata->cur, len);21332134if (err == 0)2135return (0);21362137assert(ddata->cur_output->size > 0);2138if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == NULL)2139ddata->last_sname =2140ddata->cur_output->container[ddata->cur_output->size - 1];21412142ddata->cur += len;21432144return (1);2145}21462147static int2148cpp_demangle_read_subst(struct cpp_demangle_data *ddata)2149{2150long nth;21512152if (ddata == NULL || *ddata->cur == '\0')2153return (0);21542155/* abbreviations of the form Sx */2156switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {2157case SIMPLE_HASH('S', 'a'):2158/* std::allocator */2159if (!DEM_PUSH_STR(ddata, "std::allocator"))2160return (0);2161ddata->cur += 2;2162if (*ddata->cur == 'I')2163return (cpp_demangle_read_subst_stdtmpl(ddata,2164"std::allocator"));2165return (1);21662167case SIMPLE_HASH('S', 'b'):2168/* std::basic_string */2169if (!DEM_PUSH_STR(ddata, "std::basic_string"))2170return (0);2171ddata->cur += 2;2172if (*ddata->cur == 'I')2173return (cpp_demangle_read_subst_stdtmpl(ddata,2174"std::basic_string"));2175return (1);21762177case SIMPLE_HASH('S', 'd'):2178/* std::basic_iostream<char, std::char_traits<char> > */2179if (!DEM_PUSH_STR(ddata, "std::basic_iostream<char, "2180"std::char_traits<char> >"))2181return (0);2182ddata->last_sname = "basic_iostream";2183ddata->cur += 2;2184if (*ddata->cur == 'I')2185return (cpp_demangle_read_subst_stdtmpl(ddata,2186"std::basic_iostream<char, std::char_traits"2187"<char> >"));2188return (1);21892190case SIMPLE_HASH('S', 'i'):2191/* std::basic_istream<char, std::char_traits<char> > */2192if (!DEM_PUSH_STR(ddata, "std::basic_istream<char, "2193"std::char_traits<char> >"))2194return (0);2195ddata->last_sname = "basic_istream";2196ddata->cur += 2;2197if (*ddata->cur == 'I')2198return (cpp_demangle_read_subst_stdtmpl(ddata,2199"std::basic_istream<char, std::char_traits"2200"<char> >"));2201return (1);22022203case SIMPLE_HASH('S', 'o'):2204/* std::basic_ostream<char, std::char_traits<char> > */2205if (!DEM_PUSH_STR(ddata, "std::basic_ostream<char, "2206"std::char_traits<char> >"))2207return (0);2208ddata->last_sname = "basic_ostream";2209ddata->cur += 2;2210if (*ddata->cur == 'I')2211return (cpp_demangle_read_subst_stdtmpl(ddata,2212"std::basic_ostream<char, std::char_traits"2213"<char> >"));2214return (1);22152216case SIMPLE_HASH('S', 's'):2217/*2218* std::basic_string<char, std::char_traits<char>,2219* std::allocator<char> >2220*2221* a.k.a std::string2222*/2223if (!DEM_PUSH_STR(ddata, "std::basic_string<char, "2224"std::char_traits<char>, std::allocator<char> >"))2225return (0);2226ddata->last_sname = "string";2227ddata->cur += 2;2228if (*ddata->cur == 'I')2229return (cpp_demangle_read_subst_stdtmpl(ddata,2230"std::basic_string<char, std::char_traits<char>,"2231" std::allocator<char> >"));2232return (1);22332234case SIMPLE_HASH('S', 't'):2235/* std:: */2236return (cpp_demangle_read_subst_std(ddata));2237}22382239if (*(++ddata->cur) == '\0')2240return (0);22412242/* Skip unknown substitution abbreviations. */2243if (!(*ddata->cur >= '0' && *ddata->cur <= '9') &&2244!(*ddata->cur >= 'A' && *ddata->cur <= 'Z') &&2245*ddata->cur != '_') {2246++ddata->cur;2247return (1);2248}22492250/* substitution */2251if (*ddata->cur == '_')2252return (cpp_demangle_get_subst(ddata, 0));2253else {2254errno = 0;2255/* substitution number is base 36 */2256if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 &&2257errno != 0)2258return (0);22592260/* first was '_', so increase one */2261++nth;22622263while (*ddata->cur != '_')2264++ddata->cur;22652266assert(nth > 0);22672268return (cpp_demangle_get_subst(ddata, nth));2269}22702271/* NOTREACHED */2272return (0);2273}22742275static int2276cpp_demangle_read_subst_std(struct cpp_demangle_data *ddata)2277{2278struct vector_str *output, v;2279size_t p_idx, subst_str_len;2280int rtn;2281char *subst_str;22822283if (ddata == NULL)2284return (0);22852286if (!vector_str_init(&v))2287return (0);22882289subst_str = NULL;2290rtn = 0;2291if (!DEM_PUSH_STR(ddata, "std::"))2292goto clean;22932294if (!VEC_PUSH_STR(&v, "std::"))2295goto clean;22962297ddata->cur += 2;22982299output = ddata->cur_output;23002301p_idx = output->size;2302if (!cpp_demangle_read_uqname(ddata))2303goto clean;23042305if ((subst_str = vector_str_substr(output, p_idx, output->size - 1,2306&subst_str_len)) == NULL)2307goto clean;23082309if (!vector_str_push(&v, subst_str, subst_str_len))2310goto clean;23112312if (!cpp_demangle_push_subst_v(ddata, &v))2313goto clean;23142315if (*ddata->cur == 'I') {2316p_idx = output->size;2317if (!cpp_demangle_read_tmpl_args(ddata))2318goto clean;2319free(subst_str);2320if ((subst_str = vector_str_substr(output, p_idx,2321output->size - 1, &subst_str_len)) == NULL)2322goto clean;2323if (!vector_str_push(&v, subst_str, subst_str_len))2324goto clean;2325if (!cpp_demangle_push_subst_v(ddata, &v))2326goto clean;2327}23282329rtn = 1;2330clean:2331free(subst_str);2332vector_str_dest(&v);23332334return (rtn);2335}23362337static int2338cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata,2339const char *str)2340{2341struct vector_str *output;2342size_t p_idx, substr_len, len;2343int rtn;2344char *subst_str, *substr;23452346if (ddata == NULL || str == NULL)2347return (0);23482349if ((len = strlen(str)) == 0)2350return (0);23512352output = ddata->cur_output;23532354p_idx = output->size;2355substr = NULL;2356subst_str = NULL;23572358if (!cpp_demangle_read_tmpl_args(ddata))2359return (0);2360if ((substr = vector_str_substr(output, p_idx, output->size - 1,2361&substr_len)) == NULL)2362return (0);23632364rtn = 0;2365if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) ==2366NULL)2367goto clean;23682369memcpy(subst_str, str, len);2370memcpy(subst_str + len, substr, substr_len);2371subst_str[substr_len + len] = '\0';23722373if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len))2374goto clean;23752376rtn = 1;2377clean:2378free(subst_str);2379free(substr);23802381return (rtn);2382}23832384static int2385cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata)2386{23872388if (ddata == NULL || *ddata->cur == '\0')2389return (0);23902391switch (*ddata->cur) {2392case 'L':2393return (cpp_demangle_read_expr_primary(ddata));2394case 'X':2395++ddata->cur;2396if (!cpp_demangle_read_expression(ddata))2397return (0);2398return (*ddata->cur++ == 'E');2399}24002401return (cpp_demangle_read_type(ddata, NULL));2402}24032404static int2405cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata)2406{2407struct vector_str *v;2408size_t arg_len, idx, limit, size;2409char *arg;24102411if (ddata == NULL || *ddata->cur == '\0')2412return (0);24132414++ddata->cur;24152416if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL, NULL))2417return (0);24182419if (!DEM_PUSH_STR(ddata, "<"))2420return (0);24212422limit = 0;2423v = ddata->cur_output;2424for (;;) {2425idx = v->size;2426if (!cpp_demangle_read_tmpl_arg(ddata))2427return (0);2428if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) ==2429NULL)2430return (0);2431if (!vector_str_find(&ddata->tmpl, arg, arg_len) &&2432!vector_str_push(&ddata->tmpl, arg, arg_len)) {2433free(arg);2434return (0);2435}24362437free(arg);24382439if (*ddata->cur == 'E') {2440++ddata->cur;2441size = v->size;2442assert(size > 0);2443if (!strncmp(v->container[size - 1], ">", 1)) {2444if (!DEM_PUSH_STR(ddata, " >"))2445return (0);2446} else if (!DEM_PUSH_STR(ddata, ">"))2447return (0);2448ddata->is_tmpl = true;2449break;2450} else if (*ddata->cur != 'I' &&2451!DEM_PUSH_STR(ddata, ", "))2452return (0);24532454if (limit++ > CPP_DEMANGLE_TRY_LIMIT)2455return (0);2456}24572458return (vector_read_cmd_pop(&ddata->cmd));2459}24602461/*2462* Read template parameter that forms in 'T[number]_'.2463* This function much like to read_subst but only for types.2464*/2465static int2466cpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata)2467{2468long nth;24692470if (ddata == NULL || *ddata->cur != 'T')2471return (0);24722473++ddata->cur;24742475if (*ddata->cur == '_')2476return (cpp_demangle_get_tmpl_param(ddata, 0));2477else {24782479errno = 0;2480if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 &&2481errno != 0)2482return (0);24832484/* T_ is first */2485++nth;24862487while (*ddata->cur != '_')2488++ddata->cur;24892490assert(nth > 0);24912492return (cpp_demangle_get_tmpl_param(ddata, nth));2493}24942495/* NOTREACHED */2496return (0);2497}24982499static int2500cpp_demangle_read_type(struct cpp_demangle_data *ddata,2501struct type_delimit *td)2502{2503struct vector_type_qualifier v;2504struct vector_str *output, sv;2505size_t p_idx, type_str_len, subst_str_len;2506int extern_c, is_builtin;2507long len;2508const char *p;2509char *type_str, *exp_str, *num_str, *subst_str;2510bool skip_ref_qualifier, omit_void;25112512if (ddata == NULL)2513return (0);25142515output = ddata->cur_output;2516if (td) {2517if (td->paren == false) {2518if (!DEM_PUSH_STR(ddata, "("))2519return (0);2520if (ddata->output.size < 2)2521return (0);2522td->paren = true;2523}25242525if (!td->firstp) {2526if (*ddata->cur != 'I') {2527if (!DEM_PUSH_STR(ddata, ", "))2528return (0);2529}2530}2531}25322533assert(output != NULL);2534/*2535* [r, V, K] [P, R, O, C, G, U] builtin, function, class-enum, array2536* pointer-to-member, template-param, template-template-param, subst2537*/25382539if (!vector_type_qualifier_init(&v))2540return (0);25412542extern_c = 0;2543is_builtin = 1;2544p_idx = output->size;2545type_str = exp_str = num_str = NULL;2546skip_ref_qualifier = false;25472548again:25492550/* Clear ref-qualifier flag */2551if (*ddata->cur != 'R' && *ddata->cur != 'O' && *ddata->cur != 'E')2552ddata->ref_qualifier = false;25532554/* builtin type */2555switch (*ddata->cur) {2556case 'a':2557/* signed char */2558if (!DEM_PUSH_STR(ddata, "signed char"))2559goto clean;2560++ddata->cur;2561goto rtn;25622563case 'A':2564/* array type */2565if (!cpp_demangle_read_array(ddata))2566goto clean;2567is_builtin = 0;2568goto rtn;25692570case 'b':2571/* bool */2572if (!DEM_PUSH_STR(ddata, "bool"))2573goto clean;2574++ddata->cur;2575goto rtn;25762577case 'C':2578/* complex pair */2579if (!vector_type_qualifier_push(&v, TYPE_CMX))2580goto clean;2581++ddata->cur;2582if (td)2583td->firstp = false;2584goto again;25852586case 'c':2587/* char */2588if (!DEM_PUSH_STR(ddata, "char"))2589goto clean;2590++ddata->cur;2591goto rtn;25922593case 'd':2594/* double */2595if (!DEM_PUSH_STR(ddata, "double"))2596goto clean;2597++ddata->cur;2598goto rtn;25992600case 'D':2601++ddata->cur;2602switch (*ddata->cur) {2603case 'a':2604/* auto */2605if (!DEM_PUSH_STR(ddata, "auto"))2606goto clean;2607++ddata->cur;2608break;2609case 'c':2610/* decltype(auto) */2611if (!DEM_PUSH_STR(ddata, "decltype(auto)"))2612goto clean;2613++ddata->cur;2614break;2615case 'd':2616/* IEEE 754r decimal floating point (64 bits) */2617if (!DEM_PUSH_STR(ddata, "decimal64"))2618goto clean;2619++ddata->cur;2620break;2621case 'e':2622/* IEEE 754r decimal floating point (128 bits) */2623if (!DEM_PUSH_STR(ddata, "decimal128"))2624goto clean;2625++ddata->cur;2626break;2627case 'f':2628/* IEEE 754r decimal floating point (32 bits) */2629if (!DEM_PUSH_STR(ddata, "decimal32"))2630goto clean;2631++ddata->cur;2632break;2633case 'h':2634/* IEEE 754r half-precision floating point (16 bits) */2635if (!DEM_PUSH_STR(ddata, "half"))2636goto clean;2637++ddata->cur;2638break;2639case 'i':2640/* char32_t */2641if (!DEM_PUSH_STR(ddata, "char32_t"))2642goto clean;2643++ddata->cur;2644break;2645case 'n':2646/* std::nullptr_t (i.e., decltype(nullptr)) */2647if (!DEM_PUSH_STR(ddata, "decltype(nullptr)"))2648goto clean;2649++ddata->cur;2650break;2651case 's':2652/* char16_t */2653if (!DEM_PUSH_STR(ddata, "char16_t"))2654goto clean;2655++ddata->cur;2656break;2657case 'v':2658/* gcc vector_size extension. */2659++ddata->cur;2660if (*ddata->cur == '_') {2661++ddata->cur;2662if (!cpp_demangle_read_expression_flat(ddata,2663&exp_str))2664goto clean;2665if (!VEC_PUSH_STR(&v.ext_name, exp_str))2666goto clean;2667} else {2668if (!cpp_demangle_read_number_as_string(ddata,2669&num_str))2670goto clean;2671if (!VEC_PUSH_STR(&v.ext_name, num_str))2672goto clean;2673}2674if (*ddata->cur != '_')2675goto clean;2676++ddata->cur;2677if (!vector_type_qualifier_push(&v, TYPE_VEC))2678goto clean;2679if (td)2680td->firstp = false;2681goto again;2682default:2683goto clean;2684}2685goto rtn;26862687case 'e':2688/* long double */2689if (!DEM_PUSH_STR(ddata, "long double"))2690goto clean;2691++ddata->cur;2692goto rtn;26932694case 'E':2695/* unexpected end except ref-qualifiers */2696if (ddata->ref_qualifier && ddata->is_functype) {2697skip_ref_qualifier = true;2698/* Pop the delimiter. */2699cpp_demangle_pop_str(ddata);2700goto rtn;2701}2702goto clean;27032704case 'f':2705/* float */2706if (!DEM_PUSH_STR(ddata, "float"))2707goto clean;2708++ddata->cur;2709goto rtn;27102711case 'F':2712/* function */2713if (!cpp_demangle_read_function(ddata, &extern_c, &v))2714goto clean;2715is_builtin = 0;2716goto rtn;27172718case 'g':2719/* __float128 */2720if (!DEM_PUSH_STR(ddata, "__float128"))2721goto clean;2722++ddata->cur;2723goto rtn;27242725case 'G':2726/* imaginary */2727if (!vector_type_qualifier_push(&v, TYPE_IMG))2728goto clean;2729++ddata->cur;2730if (td)2731td->firstp = false;2732goto again;27332734case 'h':2735/* unsigned char */2736if (!DEM_PUSH_STR(ddata, "unsigned char"))2737goto clean;2738++ddata->cur;2739goto rtn;27402741case 'i':2742/* int */2743if (!DEM_PUSH_STR(ddata, "int"))2744goto clean;2745++ddata->cur;2746goto rtn;27472748case 'I':2749/* template args. */2750/* handles <substitute><template-args> */2751p_idx = output->size;2752if (!cpp_demangle_read_tmpl_args(ddata))2753goto clean;2754if ((subst_str = vector_str_substr(output, p_idx,2755output->size - 1, &subst_str_len)) == NULL)2756goto clean;2757if (!vector_str_init(&sv)) {2758free(subst_str);2759goto clean;2760}2761if (!vector_str_push(&sv, subst_str, subst_str_len)) {2762free(subst_str);2763vector_str_dest(&sv);2764goto clean;2765}2766free(subst_str);2767if (!cpp_demangle_push_subst_v(ddata, &sv)) {2768vector_str_dest(&sv);2769goto clean;2770}2771vector_str_dest(&sv);2772goto rtn;27732774case 'j':2775/* unsigned int */2776if (!DEM_PUSH_STR(ddata, "unsigned int"))2777goto clean;2778++ddata->cur;2779goto rtn;27802781case 'K':2782/* const */2783if (!vector_type_qualifier_push(&v, TYPE_CST))2784goto clean;2785++ddata->cur;2786if (td)2787td->firstp = false;2788goto again;27892790case 'l':2791/* long */2792if (!DEM_PUSH_STR(ddata, "long"))2793goto clean;2794++ddata->cur;2795goto rtn;27962797case 'm':2798/* unsigned long */2799if (!DEM_PUSH_STR(ddata, "unsigned long"))2800goto clean;28012802++ddata->cur;28032804goto rtn;2805case 'M':2806/* pointer to member */2807if (!cpp_demangle_read_pointer_to_member(ddata, &v))2808goto clean;2809is_builtin = 0;2810goto rtn;28112812case 'n':2813/* __int128 */2814if (!DEM_PUSH_STR(ddata, "__int128"))2815goto clean;2816++ddata->cur;2817goto rtn;28182819case 'o':2820/* unsigned __int128 */2821if (!DEM_PUSH_STR(ddata, "unsigned __int128"))2822goto clean;2823++ddata->cur;2824goto rtn;28252826case 'O':2827/* rvalue reference */2828if (ddata->ref_qualifier)2829goto clean;2830if (!vector_type_qualifier_push(&v, TYPE_RREF))2831goto clean;2832ddata->ref_qualifier = true;2833ddata->ref_qualifier_type = TYPE_RREF;2834++ddata->cur;2835if (td)2836td->firstp = false;2837goto again;28382839case 'P':2840/* pointer */2841if (!vector_type_qualifier_push(&v, TYPE_PTR))2842goto clean;2843++ddata->cur;2844if (td)2845td->firstp = false;2846goto again;28472848case 'r':2849/* restrict */2850if (!vector_type_qualifier_push(&v, TYPE_RST))2851goto clean;2852++ddata->cur;2853if (td)2854td->firstp = false;2855goto again;28562857case 'R':2858/* reference */2859if (ddata->ref_qualifier)2860goto clean;2861if (!vector_type_qualifier_push(&v, TYPE_REF))2862goto clean;2863ddata->ref_qualifier = true;2864ddata->ref_qualifier_type = TYPE_REF;2865++ddata->cur;2866if (td)2867td->firstp = false;2868goto again;28692870case 's':2871/* short, local string */2872if (!DEM_PUSH_STR(ddata, "short"))2873goto clean;2874++ddata->cur;2875goto rtn;28762877case 'S':2878/* substitution */2879if (!cpp_demangle_read_subst(ddata))2880goto clean;2881is_builtin = 0;2882goto rtn;28832884case 't':2885/* unsigned short */2886if (!DEM_PUSH_STR(ddata, "unsigned short"))2887goto clean;2888++ddata->cur;2889goto rtn;28902891case 'T':2892/* template parameter */2893if (!cpp_demangle_read_tmpl_param(ddata))2894goto clean;2895is_builtin = 0;2896goto rtn;28972898case 'u':2899/* vendor extended builtin */2900++ddata->cur;2901if (!cpp_demangle_read_sname(ddata))2902goto clean;2903is_builtin = 0;2904goto rtn;29052906case 'U':2907/* vendor extended type qualifier */2908++ddata->cur;2909if (!cpp_demangle_read_number(ddata, &len))2910goto clean;2911if (len <= 0)2912goto clean;2913if (!vector_str_push(&v.ext_name, ddata->cur, len))2914goto clean;2915ddata->cur += len;2916if (!vector_type_qualifier_push(&v, TYPE_EXT))2917goto clean;2918if (td)2919td->firstp = false;2920goto again;29212922case 'v':2923/* void */2924omit_void = false;2925if (td && td->firstp) {2926/*2927* peek into next bytes and see if we should omit2928* the "void".2929*/2930omit_void = true;2931for (p = ddata->cur + 1; *p != '\0'; p++) {2932if (*p == 'E')2933break;2934if (*p != 'R' && *p != 'O') {2935omit_void = false;2936break;2937}2938}2939}2940if (!omit_void && !DEM_PUSH_STR(ddata, "void"))2941goto clean;2942++ddata->cur;2943goto rtn;29442945case 'V':2946/* volatile */2947if (!vector_type_qualifier_push(&v, TYPE_VAT))2948goto clean;2949++ddata->cur;2950if (td)2951td->firstp = false;2952goto again;29532954case 'w':2955/* wchar_t */2956if (!DEM_PUSH_STR(ddata, "wchar_t"))2957goto clean;2958++ddata->cur;2959goto rtn;29602961case 'x':2962/* long long */2963if (!DEM_PUSH_STR(ddata, "long long"))2964goto clean;2965++ddata->cur;2966goto rtn;29672968case 'y':2969/* unsigned long long */2970if (!DEM_PUSH_STR(ddata, "unsigned long long"))2971goto clean;2972++ddata->cur;2973goto rtn;29742975case 'z':2976/* ellipsis */2977if (!DEM_PUSH_STR(ddata, "..."))2978goto clean;2979++ddata->cur;2980goto rtn;2981}29822983if (!cpp_demangle_read_name(ddata))2984goto clean;29852986is_builtin = 0;2987rtn:29882989type_str = vector_str_substr(output, p_idx, output->size - 1,2990&type_str_len);29912992if (is_builtin == 0) {2993if (!vector_str_find(&ddata->subst, type_str, type_str_len) &&2994!vector_str_push(&ddata->subst, type_str, type_str_len))2995goto clean;2996}29972998if (!skip_ref_qualifier &&2999!cpp_demangle_push_type_qualifier(ddata, &v, type_str))3000goto clean;30013002if (td)3003td->firstp = false;30043005free(type_str);3006free(exp_str);3007free(num_str);3008vector_type_qualifier_dest(&v);30093010return (1);3011clean:3012free(type_str);3013free(exp_str);3014free(num_str);3015vector_type_qualifier_dest(&v);30163017return (0);3018}30193020static int3021cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str)3022{3023struct vector_str *output;3024size_t i, p_idx, idx, type_len;3025char *type;30263027output = ddata->cur_output;30283029p_idx = output->size;30303031if (!cpp_demangle_read_type(ddata, NULL))3032return (0);30333034if ((type = vector_str_substr(output, p_idx, output->size - 1,3035&type_len)) == NULL)3036return (0);30373038idx = output->size;3039for (i = p_idx; i < idx; ++i) {3040if (!vector_str_pop(output)) {3041free(type);3042return (0);3043}3044}30453046*str = type;30473048return (1);3049}30503051/*3052* read unqualified-name, unqualified name are operator-name, ctor-dtor-name,3053* source-name3054*/3055static int3056cpp_demangle_read_uqname(struct cpp_demangle_data *ddata)3057{3058size_t len;30593060if (ddata == NULL || *ddata->cur == '\0')3061return (0);30623063/* operator name */3064switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {3065case SIMPLE_HASH('a', 'a'):3066/* operator && */3067if (!DEM_PUSH_STR(ddata, "operator&&"))3068return (0);3069ddata->cur += 2;3070return (1);30713072case SIMPLE_HASH('a', 'd'):3073/* operator & (unary) */3074if (!DEM_PUSH_STR(ddata, "operator&"))3075return (0);3076ddata->cur += 2;3077return (1);30783079case SIMPLE_HASH('a', 'n'):3080/* operator & */3081if (!DEM_PUSH_STR(ddata, "operator&"))3082return (0);3083ddata->cur += 2;3084return (1);30853086case SIMPLE_HASH('a', 'N'):3087/* operator &= */3088if (!DEM_PUSH_STR(ddata, "operator&="))3089return (0);3090ddata->cur += 2;3091return (1);30923093case SIMPLE_HASH('a', 'S'):3094/* operator = */3095if (!DEM_PUSH_STR(ddata, "operator="))3096return (0);3097ddata->cur += 2;3098return (1);30993100case SIMPLE_HASH('c', 'l'):3101/* operator () */3102if (!DEM_PUSH_STR(ddata, "operator()"))3103return (0);3104ddata->cur += 2;3105return (1);31063107case SIMPLE_HASH('c', 'm'):3108/* operator , */3109if (!DEM_PUSH_STR(ddata, "operator,"))3110return (0);3111ddata->cur += 2;3112return (1);31133114case SIMPLE_HASH('c', 'o'):3115/* operator ~ */3116if (!DEM_PUSH_STR(ddata, "operator~"))3117return (0);3118ddata->cur += 2;3119return (1);31203121case SIMPLE_HASH('c', 'v'):3122/* operator (cast) */3123if (!DEM_PUSH_STR(ddata, "operator(cast)"))3124return (0);3125ddata->cur += 2;3126return (cpp_demangle_read_type(ddata, NULL));31273128case SIMPLE_HASH('d', 'a'):3129/* operator delete [] */3130if (!DEM_PUSH_STR(ddata, "operator delete []"))3131return (0);3132ddata->cur += 2;3133return (1);31343135case SIMPLE_HASH('d', 'e'):3136/* operator * (unary) */3137if (!DEM_PUSH_STR(ddata, "operator*"))3138return (0);3139ddata->cur += 2;3140return (1);31413142case SIMPLE_HASH('d', 'l'):3143/* operator delete */3144if (!DEM_PUSH_STR(ddata, "operator delete"))3145return (0);3146ddata->cur += 2;3147return (1);31483149case SIMPLE_HASH('d', 'v'):3150/* operator / */3151if (!DEM_PUSH_STR(ddata, "operator/"))3152return (0);3153ddata->cur += 2;3154return (1);31553156case SIMPLE_HASH('d', 'V'):3157/* operator /= */3158if (!DEM_PUSH_STR(ddata, "operator/="))3159return (0);3160ddata->cur += 2;3161return (1);31623163case SIMPLE_HASH('e', 'o'):3164/* operator ^ */3165if (!DEM_PUSH_STR(ddata, "operator^"))3166return (0);3167ddata->cur += 2;3168return (1);31693170case SIMPLE_HASH('e', 'O'):3171/* operator ^= */3172if (!DEM_PUSH_STR(ddata, "operator^="))3173return (0);3174ddata->cur += 2;3175return (1);31763177case SIMPLE_HASH('e', 'q'):3178/* operator == */3179if (!DEM_PUSH_STR(ddata, "operator=="))3180return (0);3181ddata->cur += 2;3182return (1);31833184case SIMPLE_HASH('g', 'e'):3185/* operator >= */3186if (!DEM_PUSH_STR(ddata, "operator>="))3187return (0);3188ddata->cur += 2;3189return (1);31903191case SIMPLE_HASH('g', 't'):3192/* operator > */3193if (!DEM_PUSH_STR(ddata, "operator>"))3194return (0);3195ddata->cur += 2;3196return (1);31973198case SIMPLE_HASH('i', 'x'):3199/* operator [] */3200if (!DEM_PUSH_STR(ddata, "operator[]"))3201return (0);3202ddata->cur += 2;3203return (1);32043205case SIMPLE_HASH('l', 'e'):3206/* operator <= */3207if (!DEM_PUSH_STR(ddata, "operator<="))3208return (0);3209ddata->cur += 2;3210return (1);32113212case SIMPLE_HASH('l', 's'):3213/* operator << */3214if (!DEM_PUSH_STR(ddata, "operator<<"))3215return (0);3216ddata->cur += 2;3217return (1);32183219case SIMPLE_HASH('l', 'S'):3220/* operator <<= */3221if (!DEM_PUSH_STR(ddata, "operator<<="))3222return (0);3223ddata->cur += 2;3224return (1);32253226case SIMPLE_HASH('l', 't'):3227/* operator < */3228if (!DEM_PUSH_STR(ddata, "operator<"))3229return (0);3230ddata->cur += 2;3231return (1);32323233case SIMPLE_HASH('m', 'i'):3234/* operator - */3235if (!DEM_PUSH_STR(ddata, "operator-"))3236return (0);3237ddata->cur += 2;3238return (1);32393240case SIMPLE_HASH('m', 'I'):3241/* operator -= */3242if (!DEM_PUSH_STR(ddata, "operator-="))3243return (0);3244ddata->cur += 2;3245return (1);32463247case SIMPLE_HASH('m', 'l'):3248/* operator * */3249if (!DEM_PUSH_STR(ddata, "operator*"))3250return (0);3251ddata->cur += 2;3252return (1);32533254case SIMPLE_HASH('m', 'L'):3255/* operator *= */3256if (!DEM_PUSH_STR(ddata, "operator*="))3257return (0);3258ddata->cur += 2;3259return (1);32603261case SIMPLE_HASH('m', 'm'):3262/* operator -- */3263if (!DEM_PUSH_STR(ddata, "operator--"))3264return (0);3265ddata->cur += 2;3266return (1);32673268case SIMPLE_HASH('n', 'a'):3269/* operator new[] */3270if (!DEM_PUSH_STR(ddata, "operator new []"))3271return (0);3272ddata->cur += 2;3273return (1);32743275case SIMPLE_HASH('n', 'e'):3276/* operator != */3277if (!DEM_PUSH_STR(ddata, "operator!="))3278return (0);3279ddata->cur += 2;3280return (1);32813282case SIMPLE_HASH('n', 'g'):3283/* operator - (unary) */3284if (!DEM_PUSH_STR(ddata, "operator-"))3285return (0);3286ddata->cur += 2;3287return (1);32883289case SIMPLE_HASH('n', 't'):3290/* operator ! */3291if (!DEM_PUSH_STR(ddata, "operator!"))3292return (0);3293ddata->cur += 2;3294return (1);32953296case SIMPLE_HASH('n', 'w'):3297/* operator new */3298if (!DEM_PUSH_STR(ddata, "operator new"))3299return (0);3300ddata->cur += 2;3301return (1);33023303case SIMPLE_HASH('o', 'o'):3304/* operator || */3305if (!DEM_PUSH_STR(ddata, "operator||"))3306return (0);3307ddata->cur += 2;3308return (1);33093310case SIMPLE_HASH('o', 'r'):3311/* operator | */3312if (!DEM_PUSH_STR(ddata, "operator|"))3313return (0);3314ddata->cur += 2;3315return (1);33163317case SIMPLE_HASH('o', 'R'):3318/* operator |= */3319if (!DEM_PUSH_STR(ddata, "operator|="))3320return (0);3321ddata->cur += 2;3322return (1);33233324case SIMPLE_HASH('p', 'l'):3325/* operator + */3326if (!DEM_PUSH_STR(ddata, "operator+"))3327return (0);3328ddata->cur += 2;3329return (1);33303331case SIMPLE_HASH('p', 'L'):3332/* operator += */3333if (!DEM_PUSH_STR(ddata, "operator+="))3334return (0);3335ddata->cur += 2;3336return (1);33373338case SIMPLE_HASH('p', 'm'):3339/* operator ->* */3340if (!DEM_PUSH_STR(ddata, "operator->*"))3341return (0);3342ddata->cur += 2;3343return (1);33443345case SIMPLE_HASH('p', 'p'):3346/* operator ++ */3347if (!DEM_PUSH_STR(ddata, "operator++"))3348return (0);3349ddata->cur += 2;3350return (1);33513352case SIMPLE_HASH('p', 's'):3353/* operator + (unary) */3354if (!DEM_PUSH_STR(ddata, "operator+"))3355return (0);3356ddata->cur += 2;3357return (1);33583359case SIMPLE_HASH('p', 't'):3360/* operator -> */3361if (!DEM_PUSH_STR(ddata, "operator->"))3362return (0);3363ddata->cur += 2;3364return (1);33653366case SIMPLE_HASH('q', 'u'):3367/* operator ? */3368if (!DEM_PUSH_STR(ddata, "operator?"))3369return (0);3370ddata->cur += 2;3371return (1);33723373case SIMPLE_HASH('r', 'm'):3374/* operator % */3375if (!DEM_PUSH_STR(ddata, "operator%"))3376return (0);3377ddata->cur += 2;3378return (1);33793380case SIMPLE_HASH('r', 'M'):3381/* operator %= */3382if (!DEM_PUSH_STR(ddata, "operator%="))3383return (0);3384ddata->cur += 2;3385return (1);33863387case SIMPLE_HASH('r', 's'):3388/* operator >> */3389if (!DEM_PUSH_STR(ddata, "operator>>"))3390return (0);3391ddata->cur += 2;3392return (1);33933394case SIMPLE_HASH('r', 'S'):3395/* operator >>= */3396if (!DEM_PUSH_STR(ddata, "operator>>="))3397return (0);3398ddata->cur += 2;3399return (1);34003401case SIMPLE_HASH('r', 'z'):3402/* operator sizeof */3403if (!DEM_PUSH_STR(ddata, "operator sizeof "))3404return (0);3405ddata->cur += 2;3406return (1);34073408case SIMPLE_HASH('s', 'r'):3409/* scope resolution operator */3410if (!DEM_PUSH_STR(ddata, "scope resolution operator "))3411return (0);3412ddata->cur += 2;3413return (1);34143415case SIMPLE_HASH('s', 'v'):3416/* operator sizeof */3417if (!DEM_PUSH_STR(ddata, "operator sizeof "))3418return (0);3419ddata->cur += 2;3420return (1);3421}34223423/* vendor extened operator */3424if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) {3425if (!DEM_PUSH_STR(ddata, "vendor extened operator "))3426return (0);3427if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1))3428return (0);3429ddata->cur += 2;3430return (cpp_demangle_read_sname(ddata));3431}34323433/* ctor-dtor-name */3434switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {3435case SIMPLE_HASH('C', '1'):3436case SIMPLE_HASH('C', '2'):3437case SIMPLE_HASH('C', '3'):3438if (ddata->last_sname == NULL)3439return (0);3440if ((len = strlen(ddata->last_sname)) == 0)3441return (0);3442if (!DEM_PUSH_STR(ddata, "::"))3443return (0);3444if (!cpp_demangle_push_str(ddata, ddata->last_sname, len))3445return (0);3446ddata->cur +=2;3447return (1);34483449case SIMPLE_HASH('D', '0'):3450case SIMPLE_HASH('D', '1'):3451case SIMPLE_HASH('D', '2'):3452if (ddata->last_sname == NULL)3453return (0);3454if ((len = strlen(ddata->last_sname)) == 0)3455return (0);3456if (!DEM_PUSH_STR(ddata, "::~"))3457return (0);3458if (!cpp_demangle_push_str(ddata, ddata->last_sname, len))3459return (0);3460ddata->cur +=2;3461return (1);3462}34633464/* source name */3465if (ELFTC_ISDIGIT(*ddata->cur) != 0)3466return (cpp_demangle_read_sname(ddata));34673468/* local source name */3469if (*ddata->cur == 'L')3470return (cpp_demangle_local_source_name(ddata));34713472return (1);3473}34743475/*3476* Read local source name.3477*3478* References:3479* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=317753480* http://gcc.gnu.org/viewcvs?view=rev&revision=1244673481*/3482static int3483cpp_demangle_local_source_name(struct cpp_demangle_data *ddata)3484{3485/* L */3486if (ddata == NULL || *ddata->cur != 'L')3487return (0);3488++ddata->cur;34893490/* source name */3491if (!cpp_demangle_read_sname(ddata))3492return (0);34933494/* discriminator */3495if (*ddata->cur == '_') {3496++ddata->cur;3497while (ELFTC_ISDIGIT(*ddata->cur) != 0)3498++ddata->cur;3499}35003501return (1);3502}35033504static int3505cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata)3506{35073508if (ddata == NULL)3509return (0);35103511if (!DEM_PUSH_STR(ddata, "offset : "))3512return (0);35133514if (!cpp_demangle_read_offset_number(ddata))3515return (0);35163517if (!DEM_PUSH_STR(ddata, "virtual offset : "))3518return (0);35193520return (!cpp_demangle_read_offset_number(ddata));3521}35223523/*3524* Decode floating point representation to string3525* Return new allocated string or NULL3526*3527* Todo3528* Replace these functions to macro.3529*/3530static char *3531decode_fp_to_double(const char *p, size_t len)3532{3533double f;3534size_t rtn_len, limit, i;3535int byte;3536char *rtn;35373538if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double))3539return (NULL);35403541memset(&f, 0, sizeof(double));35423543for (i = 0; i < len / 2; ++i) {3544byte = hex_to_dec(p[len - i * 2 - 1]) +3545hex_to_dec(p[len - i * 2 - 2]) * 16;35463547if (byte < 0 || byte > 255)3548return (NULL);35493550#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3551((unsigned char *)&f)[i] = (unsigned char)(byte);3552#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3553((unsigned char *)&f)[sizeof(double) - i - 1] =3554(unsigned char)(byte);3555#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3556}35573558rtn_len = 64;3559limit = 0;3560again:3561if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)3562return (NULL);35633564if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) {3565free(rtn);3566if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)3567return (NULL);3568rtn_len *= BUFFER_GROWFACTOR;3569goto again;3570}35713572return rtn;3573}35743575static char *3576decode_fp_to_float(const char *p, size_t len)3577{3578size_t i, rtn_len, limit;3579float f;3580int byte;3581char *rtn;35823583if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float))3584return (NULL);35853586memset(&f, 0, sizeof(float));35873588for (i = 0; i < len / 2; ++i) {3589byte = hex_to_dec(p[len - i * 2 - 1]) +3590hex_to_dec(p[len - i * 2 - 2]) * 16;3591if (byte < 0 || byte > 255)3592return (NULL);3593#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3594((unsigned char *)&f)[i] = (unsigned char)(byte);3595#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3596((unsigned char *)&f)[sizeof(float) - i - 1] =3597(unsigned char)(byte);3598#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3599}36003601rtn_len = 64;3602limit = 0;3603again:3604if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)3605return (NULL);36063607if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) {3608free(rtn);3609if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)3610return (NULL);3611rtn_len *= BUFFER_GROWFACTOR;3612goto again;3613}36143615return rtn;3616}36173618static char *3619decode_fp_to_float128(const char *p, size_t len)3620{3621long double f;3622size_t rtn_len, limit, i;3623int byte;3624unsigned char buf[FLOAT_QUADRUPLE_BYTES];3625char *rtn;36263627switch(sizeof(long double)) {3628case FLOAT_QUADRUPLE_BYTES:3629return (decode_fp_to_long_double(p, len));3630case FLOAT_EXTENED_BYTES:3631if (p == NULL || len == 0 || len % 2 != 0 ||3632len / 2 > FLOAT_QUADRUPLE_BYTES)3633return (NULL);36343635memset(buf, 0, FLOAT_QUADRUPLE_BYTES);36363637for (i = 0; i < len / 2; ++i) {3638byte = hex_to_dec(p[len - i * 2 - 1]) +3639hex_to_dec(p[len - i * 2 - 2]) * 16;3640if (byte < 0 || byte > 255)3641return (NULL);3642#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3643buf[i] = (unsigned char)(byte);3644#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3645buf[FLOAT_QUADRUPLE_BYTES - i -1] =3646(unsigned char)(byte);3647#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3648}3649memset(&f, 0, FLOAT_EXTENED_BYTES);36503651#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3652memcpy(&f, buf, FLOAT_EXTENED_BYTES);3653#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3654memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES);3655#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */36563657rtn_len = 256;3658limit = 0;3659again:3660if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)3661return (NULL);36623663if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {3664free(rtn);3665if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)3666return (NULL);3667rtn_len *= BUFFER_GROWFACTOR;3668goto again;3669}36703671return (rtn);3672default:3673return (NULL);3674}3675}36763677static char *3678decode_fp_to_float80(const char *p, size_t len)3679{3680long double f;3681size_t rtn_len, limit, i;3682int byte;3683unsigned char buf[FLOAT_EXTENED_BYTES];3684char *rtn;36853686switch(sizeof(long double)) {3687case FLOAT_QUADRUPLE_BYTES:3688if (p == NULL || len == 0 || len % 2 != 0 ||3689len / 2 > FLOAT_EXTENED_BYTES)3690return (NULL);36913692memset(buf, 0, FLOAT_EXTENED_BYTES);36933694for (i = 0; i < len / 2; ++i) {3695byte = hex_to_dec(p[len - i * 2 - 1]) +3696hex_to_dec(p[len - i * 2 - 2]) * 16;36973698if (byte < 0 || byte > 255)3699return (NULL);37003701#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3702buf[i] = (unsigned char)(byte);3703#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3704buf[FLOAT_EXTENED_BYTES - i -1] =3705(unsigned char)(byte);3706#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3707}37083709memset(&f, 0, FLOAT_QUADRUPLE_BYTES);37103711#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3712memcpy(&f, buf, FLOAT_EXTENED_BYTES);3713#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3714memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENED_BYTES);3715#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */37163717rtn_len = 256;3718limit = 0;3719again:3720if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)3721return (NULL);37223723if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {3724free(rtn);3725if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)3726return (NULL);3727rtn_len *= BUFFER_GROWFACTOR;3728goto again;3729}37303731return (rtn);3732case FLOAT_EXTENED_BYTES:3733return (decode_fp_to_long_double(p, len));3734default:3735return (NULL);3736}3737}37383739static char *3740decode_fp_to_long_double(const char *p, size_t len)3741{3742long double f;3743size_t rtn_len, limit, i;3744int byte;3745char *rtn;37463747if (p == NULL || len == 0 || len % 2 != 0 ||3748len / 2 > sizeof(long double))3749return (NULL);37503751memset(&f, 0, sizeof(long double));37523753for (i = 0; i < len / 2; ++i) {3754byte = hex_to_dec(p[len - i * 2 - 1]) +3755hex_to_dec(p[len - i * 2 - 2]) * 16;37563757if (byte < 0 || byte > 255)3758return (NULL);37593760#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3761((unsigned char *)&f)[i] = (unsigned char)(byte);3762#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3763((unsigned char *)&f)[sizeof(long double) - i - 1] =3764(unsigned char)(byte);3765#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3766}37673768rtn_len = 256;3769limit = 0;3770again:3771if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)3772return (NULL);37733774if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {3775free(rtn);3776if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)3777return (NULL);3778rtn_len *= BUFFER_GROWFACTOR;3779goto again;3780}37813782return (rtn);3783}37843785/* Simple hex to integer function used by decode_to_* function. */3786static int3787hex_to_dec(char c)3788{37893790switch (c) {3791case '0':3792return (0);3793case '1':3794return (1);3795case '2':3796return (2);3797case '3':3798return (3);3799case '4':3800return (4);3801case '5':3802return (5);3803case '6':3804return (6);3805case '7':3806return (7);3807case '8':3808return (8);3809case '9':3810return (9);3811case 'a':3812return (10);3813case 'b':3814return (11);3815case 'c':3816return (12);3817case 'd':3818return (13);3819case 'e':3820return (14);3821case 'f':3822return (15);3823default:3824return (-1);3825}3826}38273828/**3829* @brief Test input string is mangled by IA-64 C++ ABI style.3830*3831* Test string heads with "_Z" or "_GLOBAL__I_".3832* @return Return 0 at false.3833*/3834bool3835is_cpp_mangled_gnu3(const char *org)3836{3837size_t len;38383839len = strlen(org);3840return ((len > 2 && *org == '_' && *(org + 1) == 'Z') ||3841(len > 11 && !strncmp(org, "_GLOBAL__I_", 11)));3842}38433844static void3845vector_read_cmd_dest(struct vector_read_cmd *v)3846{38473848if (v == NULL)3849return;38503851free(v->r_container);3852}38533854static struct read_cmd_item *3855vector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst)3856{3857int i;38583859if (v == NULL || dst == READ_FAIL)3860return (NULL);38613862for (i = (int) v->size - 1; i >= 0; i--)3863if (v->r_container[i].cmd == dst)3864return (&v->r_container[i]);38653866return (NULL);3867}38683869static int3870vector_read_cmd_init(struct vector_read_cmd *v)3871{38723873if (v == NULL)3874return (0);38753876v->size = 0;3877v->capacity = VECTOR_DEF_CAPACITY;38783879if ((v->r_container = malloc(sizeof(*v->r_container) * v->capacity))3880== NULL)3881return (0);38823883return (1);3884}38853886static int3887vector_read_cmd_pop(struct vector_read_cmd *v)3888{38893890if (v == NULL || v->size == 0)3891return (0);38923893--v->size;3894v->r_container[v->size].cmd = READ_FAIL;3895v->r_container[v->size].data = NULL;38963897return (1);3898}38993900static int3901vector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd, void *data)3902{3903struct read_cmd_item *tmp_r_ctn;3904size_t tmp_cap;3905size_t i;39063907if (v == NULL)3908return (0);39093910if (v->size == v->capacity) {3911tmp_cap = BUFFER_GROW(v->capacity);3912if ((tmp_r_ctn = malloc(sizeof(*tmp_r_ctn) * tmp_cap)) == NULL)3913return (0);3914for (i = 0; i < v->size; ++i)3915tmp_r_ctn[i] = v->r_container[i];3916free(v->r_container);3917v->r_container = tmp_r_ctn;3918v->capacity = tmp_cap;3919}39203921v->r_container[v->size].cmd = cmd;3922v->r_container[v->size].data = data;3923++v->size;39243925return (1);3926}39273928static void3929vector_type_qualifier_dest(struct vector_type_qualifier *v)3930{39313932if (v == NULL)3933return;39343935free(v->q_container);3936vector_str_dest(&v->ext_name);3937}39383939/* size, capacity, ext_name */3940static int3941vector_type_qualifier_init(struct vector_type_qualifier *v)3942{39433944if (v == NULL)3945return (0);39463947v->size = 0;3948v->capacity = VECTOR_DEF_CAPACITY;39493950if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity))3951== NULL)3952return (0);39533954assert(v->q_container != NULL);39553956if (!vector_str_init(&v->ext_name)) {3957free(v->q_container);3958return (0);3959}39603961return (1);3962}39633964static int3965vector_type_qualifier_push(struct vector_type_qualifier *v,3966enum type_qualifier t)3967{3968enum type_qualifier *tmp_ctn;3969size_t tmp_cap;3970size_t i;39713972if (v == NULL)3973return (0);39743975if (v->size == v->capacity) {3976tmp_cap = BUFFER_GROW(v->capacity);3977if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap))3978== NULL)3979return (0);3980for (i = 0; i < v->size; ++i)3981tmp_ctn[i] = v->q_container[i];3982free(v->q_container);3983v->q_container = tmp_ctn;3984v->capacity = tmp_cap;3985}39863987v->q_container[v->size] = t;3988++v->size;39893990return (1);3991}399239933994