Path: blob/main/contrib/libcxxrt/libelftc_dem_gnu3.c
39476 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 <limits.h>31#include <stdbool.h>32#include <stdio.h>33#include <stdlib.h>34#include <string.h>3536/**37* @file cpp_demangle.c38* @brief Decode IA-64 C++ ABI style implementation.39*40* IA-64 standard ABI(Itanium C++ ABI) references.41*42* http://www.codesourcery.com/cxx-abi/abi.html#mangling \n43* http://www.codesourcery.com/cxx-abi/abi-mangling.html44*/4546/** @brief Dynamic vector data for string. */47struct vector_str {48/** Current size */49size_t size;50/** Total capacity */51size_t capacity;52/** String array */53char **container;54};5556#define BUFFER_GROWFACTOR 1.61857#define BUFFER_GROW(x) (((x)+0.5)*BUFFER_GROWFACTOR)5859#define ELFTC_FAILURE 060#define ELFTC_ISDIGIT(C) (isdigit((C) & 0xFF))61#define ELFTC_SUCCESS 16263#define VECTOR_DEF_CAPACITY 86465enum type_qualifier {66TYPE_PTR, TYPE_REF, TYPE_CMX, TYPE_IMG, TYPE_EXT, TYPE_RST, TYPE_VAT,67TYPE_CST, TYPE_VEC, TYPE_RREF68};6970struct vector_type_qualifier {71size_t size, capacity;72enum type_qualifier *q_container;73struct vector_str ext_name;74};7576enum read_cmd {77READ_FAIL, READ_NEST, READ_TMPL, READ_EXPR, READ_EXPL, READ_LOCAL,78READ_TYPE, READ_FUNC, READ_PTRMEM79};8081struct read_cmd_item {82enum read_cmd cmd;83void *data;84};8586struct vector_read_cmd {87size_t size, capacity;88struct read_cmd_item *r_container;89};9091enum push_qualifier {92PUSH_ALL_QUALIFIER,93PUSH_CV_QUALIFIER,94PUSH_NON_CV_QUALIFIER,95};9697struct cpp_demangle_data {98struct vector_str output; /* output string vector */99struct vector_str subst; /* substitution string vector */100struct vector_str tmpl;101struct vector_str class_type;102struct vector_str *cur_output; /* ptr to current output vec */103struct vector_read_cmd cmd;104bool mem_rst; /* restrict member function */105bool mem_vat; /* volatile member function */106bool mem_cst; /* const member function */107bool mem_ref; /* lvalue-ref member func */108bool mem_rref; /* rvalue-ref member func */109bool is_tmpl; /* template args */110bool is_functype; /* function type */111bool ref_qualifier; /* ref qualifier */112enum type_qualifier ref_qualifier_type; /* ref qualifier type */113enum push_qualifier push_qualifier; /* which qualifiers to push */114int func_type;115const char *cur; /* current mangled name ptr */116const char *last_sname; /* last source name */117};118119struct type_delimit {120bool paren;121bool firstp;122};123124#define CPP_DEMANGLE_TRY_LIMIT 128125#define FLOAT_SPRINTF_TRY_LIMIT 5126#define FLOAT_QUADRUPLE_BYTES 16127#define FLOAT_EXTENED_BYTES 10128129#define SIMPLE_HASH(x,y) (64 * x + y)130#define DEM_PUSH_STR(d,s) cpp_demangle_push_str((d), (s), strlen((s)))131#define VEC_PUSH_STR(d,s) vector_str_push((d), (s), strlen((s)))132133static size_t get_strlen_sum(const struct vector_str *v);134static bool vector_str_grow(struct vector_str *v);135136static size_t137get_strlen_sum(const struct vector_str *v)138{139size_t i, len = 0;140141if (v == NULL)142return (0);143144assert(v->size > 0);145146for (i = 0; i < v->size; ++i)147len += strlen(v->container[i]);148149return (len);150}151152/**153* @brief Deallocate resource in vector_str.154*/155static void156vector_str_dest(struct vector_str *v)157{158size_t i;159160if (v == NULL)161return;162163for (i = 0; i < v->size; ++i)164free(v->container[i]);165166free(v->container);167}168169/**170* @brief Find string in vector_str.171* @param v Destination vector.172* @param o String to find.173* @param l Length of the string.174* @return -1 at failed, 0 at not found, 1 at found.175*/176static int177vector_str_find(const struct vector_str *v, const char *o, size_t l)178{179size_t i;180181if (v == NULL || o == NULL)182return (-1);183184for (i = 0; i < v->size; ++i)185if (strncmp(v->container[i], o, l) == 0)186return (1);187188return (0);189}190191/**192* @brief Get new allocated flat string from vector.193*194* If l is not NULL, return length of the string.195* @param v Destination vector.196* @param l Length of the string.197* @return NULL at failed or NUL terminated new allocated string.198*/199static char *200vector_str_get_flat(const struct vector_str *v, size_t *l)201{202size_t i;203char *rtn, *p;204ssize_t rtn_size;205206if (v == NULL || v->size == 0)207return (NULL);208209if ((rtn_size = get_strlen_sum(v)) == 0)210return (NULL);211212if ((rtn = malloc(sizeof(char) * (rtn_size + 1))) == NULL)213return (NULL);214215p = rtn;216for (i = 0; i < v->size; ++i)217p = stpcpy(p, v->container[i]);218219if (l != NULL)220*l = rtn_size;221222return (rtn);223}224225static bool226vector_str_grow(struct vector_str *v)227{228size_t i, tmp_cap;229char **tmp_ctn;230231if (v == NULL)232return (false);233234assert(v->capacity > 0);235236tmp_cap = BUFFER_GROW(v->capacity);237238assert(tmp_cap > v->capacity);239240if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)241return (false);242243for (i = 0; i < v->size; ++i)244tmp_ctn[i] = v->container[i];245246free(v->container);247248v->container = tmp_ctn;249v->capacity = tmp_cap;250251return (true);252}253254/**255* @brief Initialize vector_str.256* @return false at failed, true at success.257*/258static bool259vector_str_init(struct vector_str *v)260{261262if (v == NULL)263return (false);264265v->size = 0;266v->capacity = VECTOR_DEF_CAPACITY;267268assert(v->capacity > 0);269270if ((v->container = malloc(sizeof(char *) * v->capacity)) == NULL)271return (false);272273assert(v->container != NULL);274275return (true);276}277278/**279* @brief Remove last element in vector_str.280* @return false at failed, true at success.281*/282static bool283vector_str_pop(struct vector_str *v)284{285286if (v == NULL)287return (false);288289if (v->size == 0)290return (true);291292--v->size;293294free(v->container[v->size]);295v->container[v->size] = NULL;296297return (true);298}299300/**301* @brief Implements strlcpy() without result.302*/303static void304copy_string(char *dst, const char *src, size_t dsize)305{306size_t remain;307if ((remain = dsize))308while (--remain)309if (!(*dst++ = *src++))310break;311if (!remain && dsize)312*dst = 0;313}314315/**316* @brief Push back string to vector.317* @return false at failed, true at success.318*/319static bool320vector_str_push(struct vector_str *v, const char *str, size_t len)321{322323if (v == NULL || str == NULL)324return (false);325326if (v->size == v->capacity && vector_str_grow(v) == false)327return (false);328329if ((v->container[v->size] = malloc(sizeof(char) * (len + 1))) == NULL)330return (false);331332copy_string(v->container[v->size], str, len + 1);333334++v->size;335336return (true);337}338339/**340* @brief Push front org vector to det vector.341* @return false at failed, true at success.342*/343static bool344vector_str_push_vector_head(struct vector_str *dst, struct vector_str *org)345{346size_t i, j, tmp_cap;347char **tmp_ctn;348349if (dst == NULL || org == NULL)350return (false);351352tmp_cap = BUFFER_GROW(dst->size + org->size);353354if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)355return (false);356357for (i = 0; i < org->size; ++i)358if ((tmp_ctn[i] = strdup(org->container[i])) == NULL) {359for (j = 0; j < i; ++j)360free(tmp_ctn[j]);361362free(tmp_ctn);363364return (false);365}366367for (i = 0; i < dst->size; ++i)368tmp_ctn[i + org->size] = dst->container[i];369370free(dst->container);371372dst->container = tmp_ctn;373dst->capacity = tmp_cap;374dst->size += org->size;375376return (true);377}378379/**380* @brief Push org vector to the tail of det vector.381* @return false at failed, true at success.382*/383static bool384vector_str_push_vector(struct vector_str *dst, struct vector_str *org)385{386size_t i, j, tmp_cap;387char **tmp_ctn;388389if (dst == NULL || org == NULL)390return (false);391392tmp_cap = BUFFER_GROW(dst->size + org->size);393394if ((tmp_ctn = malloc(sizeof(char *) * tmp_cap)) == NULL)395return (false);396397for (i = 0; i < dst->size; ++i)398tmp_ctn[i] = dst->container[i];399400for (i = 0; i < org->size; ++i)401if ((tmp_ctn[i + dst->size] = strdup(org->container[i])) ==402NULL) {403for (j = 0; j < i + dst->size; ++j)404free(tmp_ctn[j]);405406free(tmp_ctn);407408return (false);409}410411free(dst->container);412413dst->container = tmp_ctn;414dst->capacity = tmp_cap;415dst->size += org->size;416417return (true);418}419420/**421* @brief Get new allocated flat string from vector between begin and end.422*423* If r_len is not NULL, string length will be returned.424* @return NULL at failed or NUL terminated new allocated string.425*/426static char *427vector_str_substr(const struct vector_str *v, size_t begin, size_t end,428size_t *r_len)429{430char *rtn, *p;431size_t i, len;432433if (v == NULL || begin > end)434return (NULL);435436len = 0;437for (i = begin; i < end + 1; ++i)438len += strlen(v->container[i]);439440if ((rtn = malloc(sizeof(char) * (len + 1))) == NULL)441return (NULL);442443if (r_len != NULL)444*r_len = len;445446p = rtn;447for (i = begin; i < end + 1; ++i)448p = stpcpy(p, v->container[i]);449450return (rtn);451}452453static void cpp_demangle_data_dest(struct cpp_demangle_data *);454static int cpp_demangle_data_init(struct cpp_demangle_data *,455const char *);456static int cpp_demangle_get_subst(struct cpp_demangle_data *, size_t);457static int cpp_demangle_get_tmpl_param(struct cpp_demangle_data *, size_t);458static int cpp_demangle_push_fp(struct cpp_demangle_data *,459char *(*)(const char *, size_t));460static int cpp_demangle_push_str(struct cpp_demangle_data *, const char *,461size_t);462static int cpp_demangle_pop_str(struct cpp_demangle_data *);463static int cpp_demangle_push_subst(struct cpp_demangle_data *,464const char *, size_t);465static int cpp_demangle_push_subst_v(struct cpp_demangle_data *,466struct vector_str *);467static int cpp_demangle_push_type_qualifier(struct cpp_demangle_data *,468struct vector_type_qualifier *, const char *);469static int cpp_demangle_read_array(struct cpp_demangle_data *);470static int cpp_demangle_read_encoding(struct cpp_demangle_data *);471static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *);472static int cpp_demangle_read_expression(struct cpp_demangle_data *);473static int cpp_demangle_read_expression_flat(struct cpp_demangle_data *,474char **);475static int cpp_demangle_read_expression_binary(struct cpp_demangle_data *,476const char *, size_t);477static int cpp_demangle_read_expression_unary(struct cpp_demangle_data *,478const char *, size_t);479static int cpp_demangle_read_expression_trinary(struct cpp_demangle_data *,480const char *, size_t, const char *, size_t);481static int cpp_demangle_read_function(struct cpp_demangle_data *, int *,482struct vector_type_qualifier *);483static int cpp_demangle_local_source_name(struct cpp_demangle_data *ddata);484static int cpp_demangle_read_local_name(struct cpp_demangle_data *);485static int cpp_demangle_read_name(struct cpp_demangle_data *);486static int cpp_demangle_read_name_flat(struct cpp_demangle_data *,487char**);488static int cpp_demangle_read_nested_name(struct cpp_demangle_data *);489static int cpp_demangle_read_number(struct cpp_demangle_data *, long *);490static int cpp_demangle_read_number_as_string(struct cpp_demangle_data *,491char **);492static int cpp_demangle_read_nv_offset(struct cpp_demangle_data *);493static int cpp_demangle_read_offset(struct cpp_demangle_data *);494static int cpp_demangle_read_offset_number(struct cpp_demangle_data *);495static int cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *,496struct vector_type_qualifier *);497static int cpp_demangle_read_sname(struct cpp_demangle_data *);498static int cpp_demangle_read_subst(struct cpp_demangle_data *);499static int cpp_demangle_read_subst_std(struct cpp_demangle_data *);500static int cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *,501const char *);502static int cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *);503static int cpp_demangle_read_tmpl_args(struct cpp_demangle_data *);504static int cpp_demangle_read_tmpl_param(struct cpp_demangle_data *);505static int cpp_demangle_read_type(struct cpp_demangle_data *,506struct type_delimit *);507static int cpp_demangle_read_type_flat(struct cpp_demangle_data *,508char **);509static int cpp_demangle_read_uqname(struct cpp_demangle_data *);510static int cpp_demangle_read_v_offset(struct cpp_demangle_data *);511static char *decode_fp_to_double(const char *, size_t);512static char *decode_fp_to_float(const char *, size_t);513static char *decode_fp_to_float128(const char *, size_t);514static char *decode_fp_to_float80(const char *, size_t);515static char *decode_fp_to_long_double(const char *, size_t);516static int hex_to_dec(char);517static void vector_read_cmd_dest(struct vector_read_cmd *);518static struct read_cmd_item *vector_read_cmd_find(struct vector_read_cmd *,519enum read_cmd);520static int vector_read_cmd_init(struct vector_read_cmd *);521static int vector_read_cmd_pop(struct vector_read_cmd *);522static int vector_read_cmd_push(struct vector_read_cmd *, enum read_cmd,523void *);524static void vector_type_qualifier_dest(struct vector_type_qualifier *);525static int vector_type_qualifier_init(struct vector_type_qualifier *);526static int vector_type_qualifier_push(struct vector_type_qualifier *,527enum type_qualifier);528529/**530* @brief Decode the input string by IA-64 C++ ABI style.531*532* GNU GCC v3 use IA-64 standard ABI.533* @return New allocated demangled string or NULL if failed.534* @todo 1. Testing and more test case. 2. Code cleaning.535*/536char *537__cxa_demangle_gnu3(const char *org)538{539struct cpp_demangle_data ddata;540struct vector_str ret_type;541struct type_delimit td;542ssize_t org_len;543unsigned int limit;544char *rtn = NULL;545bool has_ret = false, more_type = false;546547if (org == NULL)548return (NULL);549550org_len = strlen(org);551// Try demangling as a type for short encodings552if ((org_len < 2) || (org[0] != '_' || org[1] != 'Z' )) {553if (!cpp_demangle_data_init(&ddata, org))554return (NULL);555if (!cpp_demangle_read_type(&ddata, 0))556goto clean;557rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);558goto clean;559}560if (org_len > 11 && !strncmp(org, "_GLOBAL__I_", 11)) {561if ((rtn = malloc(org_len + 19)) == NULL)562return (NULL);563snprintf(rtn, org_len + 19,564"global constructors keyed to %s", org + 11);565return (rtn);566}567568if (!cpp_demangle_data_init(&ddata, org + 2))569return (NULL);570571if (!cpp_demangle_read_encoding(&ddata))572goto clean;573574/*575* Pop function name from substitution candidate list.576*/577if (*ddata.cur != 0 && ddata.subst.size >= 1) {578if (!vector_str_pop(&ddata.subst))579goto clean;580}581582td.paren = false;583td.firstp = true;584limit = 0;585586/*587* The first type is a return type if we just demangled template588* args. (the template args is right next to the function name,589* which means it's a template function)590*/591if (ddata.is_tmpl) {592ddata.is_tmpl = false;593if (!vector_str_init(&ret_type))594goto clean;595ddata.cur_output = &ret_type;596has_ret = true;597}598599while (*ddata.cur != '\0') {600/*601* Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4602*/603if (*ddata.cur == '@' && *(ddata.cur + 1) == '@')604break;605606if (has_ret) {607/* Read return type */608if (!cpp_demangle_read_type(&ddata, NULL))609goto clean;610} else {611/* Read function arg type */612if (!cpp_demangle_read_type(&ddata, &td))613goto clean;614}615616if (has_ret) {617/* Push return type to the beginning */618if (!VEC_PUSH_STR(&ret_type, " "))619goto clean;620if (!vector_str_push_vector_head(&ddata.output,621&ret_type))622goto clean;623ddata.cur_output = &ddata.output;624vector_str_dest(&ret_type);625has_ret = false;626more_type = true;627} else if (more_type)628more_type = false;629if (limit++ > CPP_DEMANGLE_TRY_LIMIT)630goto clean;631}632if (more_type)633goto clean;634635if (ddata.output.size == 0)636goto clean;637if (td.paren && !VEC_PUSH_STR(&ddata.output, ")"))638goto clean;639if (ddata.mem_vat && !VEC_PUSH_STR(&ddata.output, " volatile"))640goto clean;641if (ddata.mem_cst && !VEC_PUSH_STR(&ddata.output, " const"))642goto clean;643if (ddata.mem_rst && !VEC_PUSH_STR(&ddata.output, " restrict"))644goto clean;645if (ddata.mem_ref && !VEC_PUSH_STR(&ddata.output, " &"))646goto clean;647if (ddata.mem_rref && !VEC_PUSH_STR(&ddata.output, " &&"))648goto clean;649650rtn = vector_str_get_flat(&ddata.output, (size_t *) NULL);651652clean:653if (has_ret)654vector_str_dest(&ret_type);655656cpp_demangle_data_dest(&ddata);657658return (rtn);659}660661static void662cpp_demangle_data_dest(struct cpp_demangle_data *d)663{664665if (d == NULL)666return;667668vector_read_cmd_dest(&d->cmd);669vector_str_dest(&d->class_type);670vector_str_dest(&d->tmpl);671vector_str_dest(&d->subst);672vector_str_dest(&d->output);673}674675static int676cpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur)677{678679if (d == NULL || cur == NULL)680return (0);681682if (!vector_str_init(&d->output))683return (0);684if (!vector_str_init(&d->subst))685goto clean1;686if (!vector_str_init(&d->tmpl))687goto clean2;688if (!vector_str_init(&d->class_type))689goto clean3;690if (!vector_read_cmd_init(&d->cmd))691goto clean4;692693assert(d->output.container != NULL);694assert(d->subst.container != NULL);695assert(d->tmpl.container != NULL);696assert(d->class_type.container != NULL);697698d->mem_rst = false;699d->mem_vat = false;700d->mem_cst = false;701d->mem_ref = false;702d->mem_rref = false;703d->is_tmpl = false;704d->is_functype = false;705d->ref_qualifier = false;706d->push_qualifier = PUSH_ALL_QUALIFIER;707d->func_type = 0;708d->cur = cur;709d->cur_output = &d->output;710d->last_sname = NULL;711712return (1);713714clean4:715vector_str_dest(&d->class_type);716clean3:717vector_str_dest(&d->tmpl);718clean2:719vector_str_dest(&d->subst);720clean1:721vector_str_dest(&d->output);722723return (0);724}725726static int727cpp_demangle_push_fp(struct cpp_demangle_data *ddata,728char *(*decoder)(const char *, size_t))729{730size_t len;731int rtn;732const char *fp;733char *f;734735if (ddata == NULL || decoder == NULL)736return (0);737738fp = ddata->cur;739while (*ddata->cur != 'E')740++ddata->cur;741742if ((f = decoder(fp, ddata->cur - fp)) == NULL)743return (0);744745rtn = 0;746if ((len = strlen(f)) > 0)747rtn = cpp_demangle_push_str(ddata, f, len);748749free(f);750751++ddata->cur;752753return (rtn);754}755756static int757cpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str,758size_t len)759{760761if (ddata == NULL || str == NULL || len == 0)762return (0);763764/*765* is_tmpl is used to check if the type (function arg) is right next766* to template args, and should always be cleared whenever new string767* pushed.768*/769ddata->is_tmpl = false;770771return (vector_str_push(ddata->cur_output, str, len));772}773774static int775cpp_demangle_pop_str(struct cpp_demangle_data *ddata)776{777778if (ddata == NULL)779return (0);780781return (vector_str_pop(ddata->cur_output));782}783784static int785cpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str,786size_t len)787{788789if (ddata == NULL || str == NULL || len == 0)790return (0);791792if (!vector_str_find(&ddata->subst, str, len))793return (vector_str_push(&ddata->subst, str, len));794795return (1);796}797798static int799cpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v)800{801size_t str_len;802int rtn;803char *str;804805if (ddata == NULL || v == NULL)806return (0);807808if ((str = vector_str_get_flat(v, &str_len)) == NULL)809return (0);810811rtn = cpp_demangle_push_subst(ddata, str, str_len);812813free(str);814815return (rtn);816}817818static int819cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata,820struct vector_type_qualifier *v, const char *type_str)821{822struct vector_str subst_v;823enum type_qualifier t;824size_t idx, e_idx, e_len;825char *buf;826int rtn;827bool cv;828829if (ddata == NULL || v == NULL)830return (0);831832if ((idx = v->size) == 0)833return (1);834835rtn = 0;836if (type_str != NULL) {837if (!vector_str_init(&subst_v))838return (0);839if (!VEC_PUSH_STR(&subst_v, type_str))840goto clean;841}842843cv = true;844e_idx = 0;845while (idx > 0) {846switch (v->q_container[idx - 1]) {847case TYPE_PTR:848cv = false;849if (ddata->push_qualifier == PUSH_CV_QUALIFIER)850break;851if (!DEM_PUSH_STR(ddata, "*"))852goto clean;853if (type_str != NULL) {854if (!VEC_PUSH_STR(&subst_v, "*"))855goto clean;856if (!cpp_demangle_push_subst_v(ddata,857&subst_v))858goto clean;859}860break;861862case TYPE_REF:863cv = false;864if (ddata->push_qualifier == PUSH_CV_QUALIFIER)865break;866if (!DEM_PUSH_STR(ddata, "&"))867goto clean;868if (type_str != NULL) {869if (!VEC_PUSH_STR(&subst_v, "&"))870goto clean;871if (!cpp_demangle_push_subst_v(ddata,872&subst_v))873goto clean;874}875break;876877case TYPE_RREF:878cv = false;879if (ddata->push_qualifier == PUSH_CV_QUALIFIER)880break;881if (!DEM_PUSH_STR(ddata, "&&"))882goto clean;883if (type_str != NULL) {884if (!VEC_PUSH_STR(&subst_v, "&&"))885goto clean;886if (!cpp_demangle_push_subst_v(ddata,887&subst_v))888goto clean;889}890break;891892case TYPE_CMX:893cv = false;894if (ddata->push_qualifier == PUSH_CV_QUALIFIER)895break;896if (!DEM_PUSH_STR(ddata, " complex"))897goto clean;898if (type_str != NULL) {899if (!VEC_PUSH_STR(&subst_v, " complex"))900goto clean;901if (!cpp_demangle_push_subst_v(ddata,902&subst_v))903goto clean;904}905break;906907case TYPE_IMG:908cv = false;909if (ddata->push_qualifier == PUSH_CV_QUALIFIER)910break;911if (!DEM_PUSH_STR(ddata, " imaginary"))912goto clean;913if (type_str != NULL) {914if (!VEC_PUSH_STR(&subst_v, " imaginary"))915goto clean;916if (!cpp_demangle_push_subst_v(ddata,917&subst_v))918goto clean;919}920break;921922case TYPE_EXT:923cv = false;924if (ddata->push_qualifier == PUSH_CV_QUALIFIER)925break;926if (v->ext_name.size == 0 ||927e_idx > v->ext_name.size - 1)928goto clean;929if ((e_len = strlen(v->ext_name.container[e_idx])) ==9300)931goto clean;932if ((buf = malloc(e_len + 2)) == NULL)933goto clean;934snprintf(buf, e_len + 2, " %s",935v->ext_name.container[e_idx]);936937if (!DEM_PUSH_STR(ddata, buf)) {938free(buf);939goto clean;940}941942if (type_str != NULL) {943if (!VEC_PUSH_STR(&subst_v, buf)) {944free(buf);945goto clean;946}947if (!cpp_demangle_push_subst_v(ddata,948&subst_v)) {949free(buf);950goto clean;951}952}953free(buf);954++e_idx;955break;956957case TYPE_RST:958if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&959cv)960break;961if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)962break;963if (!DEM_PUSH_STR(ddata, " restrict"))964goto clean;965if (type_str != NULL) {966if (!VEC_PUSH_STR(&subst_v, " restrict"))967goto clean;968if (idx - 1 > 0) {969t = v->q_container[idx - 2];970if (t == TYPE_RST || t == TYPE_VAT ||971t == TYPE_CST)972break;973}974if (!cpp_demangle_push_subst_v(ddata,975&subst_v))976goto clean;977}978break;979980case TYPE_VAT:981if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&982cv)983break;984if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)985break;986if (!DEM_PUSH_STR(ddata, " volatile"))987goto clean;988if (type_str != NULL) {989if (!VEC_PUSH_STR(&subst_v, " volatile"))990goto clean;991if (idx - 1 > 0) {992t = v->q_container[idx - 2];993if (t == TYPE_RST || t == TYPE_VAT ||994t == TYPE_CST)995break;996}997if (!cpp_demangle_push_subst_v(ddata,998&subst_v))999goto clean;1000}1001break;10021003case TYPE_CST:1004if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&1005cv)1006break;1007if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)1008break;1009if (!DEM_PUSH_STR(ddata, " const"))1010goto clean;1011if (type_str != NULL) {1012if (!VEC_PUSH_STR(&subst_v, " const"))1013goto clean;1014if (idx - 1 > 0) {1015t = v->q_container[idx - 2];1016if (t == TYPE_RST || t == TYPE_VAT ||1017t == TYPE_CST)1018break;1019}1020if (!cpp_demangle_push_subst_v(ddata,1021&subst_v))1022goto clean;1023}1024break;10251026case TYPE_VEC:1027cv = false;1028if (ddata->push_qualifier == PUSH_CV_QUALIFIER)1029break;1030if (v->ext_name.size == 0 ||1031e_idx > v->ext_name.size - 1)1032goto clean;1033if ((e_len = strlen(v->ext_name.container[e_idx])) ==10340)1035goto clean;1036if ((buf = malloc(e_len + 12)) == NULL)1037goto clean;1038snprintf(buf, e_len + 12, " __vector(%s)",1039v->ext_name.container[e_idx]);1040if (!DEM_PUSH_STR(ddata, buf)) {1041free(buf);1042goto clean;1043}1044if (type_str != NULL) {1045if (!VEC_PUSH_STR(&subst_v, buf)) {1046free(buf);1047goto clean;1048}1049if (!cpp_demangle_push_subst_v(ddata,1050&subst_v)) {1051free(buf);1052goto clean;1053}1054}1055free(buf);1056++e_idx;1057break;1058}1059--idx;1060}10611062rtn = 1;1063clean:1064if (type_str != NULL)1065vector_str_dest(&subst_v);10661067return (rtn);1068}10691070static int1071cpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx)1072{1073size_t len;10741075if (ddata == NULL || ddata->subst.size <= idx)1076return (0);1077if ((len = strlen(ddata->subst.container[idx])) == 0)1078return (0);1079if (!cpp_demangle_push_str(ddata, ddata->subst.container[idx], len))1080return (0);10811082/* skip '_' */1083++ddata->cur;10841085return (1);1086}10871088static int1089cpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx)1090{1091size_t len;10921093if (ddata == NULL || ddata->tmpl.size <= idx)1094return (0);1095if ((len = strlen(ddata->tmpl.container[idx])) == 0)1096return (0);1097if (!cpp_demangle_push_str(ddata, ddata->tmpl.container[idx], len))1098return (0);10991100++ddata->cur;11011102return (1);1103}11041105static int1106cpp_demangle_read_array(struct cpp_demangle_data *ddata)1107{1108size_t i, num_len, exp_len, p_idx, idx;1109const char *num;1110char *exp;11111112if (ddata == NULL || *(++ddata->cur) == '\0')1113return (0);11141115if (*ddata->cur == '_') {1116if (*(++ddata->cur) == '\0')1117return (0);11181119if (!cpp_demangle_read_type(ddata, NULL))1120return (0);11211122if (!DEM_PUSH_STR(ddata, " []"))1123return (0);1124} else {1125if (ELFTC_ISDIGIT(*ddata->cur) != 0) {1126num = ddata->cur;1127while (ELFTC_ISDIGIT(*ddata->cur) != 0)1128++ddata->cur;1129if (*ddata->cur != '_')1130return (0);1131num_len = ddata->cur - num;1132assert(num_len > 0);1133if (*(++ddata->cur) == '\0')1134return (0);1135if (!cpp_demangle_read_type(ddata, NULL))1136return (0);1137if (!DEM_PUSH_STR(ddata, " ["))1138return (0);1139if (!cpp_demangle_push_str(ddata, num, num_len))1140return (0);1141if (!DEM_PUSH_STR(ddata, "]"))1142return (0);1143} else {1144p_idx = ddata->output.size;1145if (!cpp_demangle_read_expression(ddata))1146return (0);1147if ((exp = vector_str_substr(&ddata->output, p_idx,1148ddata->output.size - 1, &exp_len)) == NULL)1149return (0);1150idx = ddata->output.size;1151for (i = p_idx; i < idx; ++i)1152if (!vector_str_pop(&ddata->output)) {1153free(exp);1154return (0);1155}1156if (*ddata->cur != '_') {1157free(exp);1158return (0);1159}1160++ddata->cur;1161if (*ddata->cur == '\0') {1162free(exp);1163return (0);1164}1165if (!cpp_demangle_read_type(ddata, NULL)) {1166free(exp);1167return (0);1168}1169if (!DEM_PUSH_STR(ddata, " [")) {1170free(exp);1171return (0);1172}1173if (!cpp_demangle_push_str(ddata, exp, exp_len)) {1174free(exp);1175return (0);1176}1177if (!DEM_PUSH_STR(ddata, "]")) {1178free(exp);1179return (0);1180}1181free(exp);1182}1183}11841185return (1);1186}11871188static int1189cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata)1190{1191const char *num;11921193if (ddata == NULL || *(++ddata->cur) == '\0')1194return (0);11951196if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') {1197ddata->cur += 2;1198if (*ddata->cur == '\0')1199return (0);1200if (!cpp_demangle_read_encoding(ddata))1201return (0);1202++ddata->cur;1203return (1);1204}12051206switch (*ddata->cur) {1207case 'b':1208if (*(ddata->cur + 2) != 'E')1209return (0);1210switch (*(++ddata->cur)) {1211case '0':1212ddata->cur += 2;1213return (DEM_PUSH_STR(ddata, "false"));1214case '1':1215ddata->cur += 2;1216return (DEM_PUSH_STR(ddata, "true"));1217default:1218return (0);1219}12201221case 'd':1222++ddata->cur;1223return (cpp_demangle_push_fp(ddata, decode_fp_to_double));12241225case 'e':1226++ddata->cur;1227if (sizeof(long double) == 10)1228return (cpp_demangle_push_fp(ddata,1229decode_fp_to_double));1230return (cpp_demangle_push_fp(ddata, decode_fp_to_float80));12311232case 'f':1233++ddata->cur;1234return (cpp_demangle_push_fp(ddata, decode_fp_to_float));12351236case 'g':1237++ddata->cur;1238if (sizeof(long double) == 16)1239return (cpp_demangle_push_fp(ddata,1240decode_fp_to_double));1241return (cpp_demangle_push_fp(ddata, decode_fp_to_float128));12421243case 'i':1244case 'j':1245case 'l':1246case 'm':1247case 'n':1248case 's':1249case 't':1250case 'x':1251case 'y':1252if (*(++ddata->cur) == 'n') {1253if (!DEM_PUSH_STR(ddata, "-"))1254return (0);1255++ddata->cur;1256}1257num = ddata->cur;1258while (*ddata->cur != 'E') {1259if (!ELFTC_ISDIGIT(*ddata->cur))1260return (0);1261++ddata->cur;1262}1263++ddata->cur;1264return (cpp_demangle_push_str(ddata, num,1265ddata->cur - num - 1));12661267default:1268return (0);1269}1270}12711272static int1273cpp_demangle_read_expression(struct cpp_demangle_data *ddata)1274{12751276if (ddata == NULL || *ddata->cur == '\0')1277return (0);12781279switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {1280case SIMPLE_HASH('s', 't'):1281ddata->cur += 2;1282return (cpp_demangle_read_type(ddata, NULL));12831284case SIMPLE_HASH('s', 'r'):1285ddata->cur += 2;1286if (!cpp_demangle_read_type(ddata, NULL))1287return (0);1288if (!cpp_demangle_read_uqname(ddata))1289return (0);1290if (*ddata->cur == 'I')1291return (cpp_demangle_read_tmpl_args(ddata));1292return (1);12931294case SIMPLE_HASH('a', 'a'):1295/* operator && */1296ddata->cur += 2;1297return (cpp_demangle_read_expression_binary(ddata, "&&", 2));12981299case SIMPLE_HASH('a', 'd'):1300/* operator & (unary) */1301ddata->cur += 2;1302return (cpp_demangle_read_expression_unary(ddata, "&", 1));13031304case SIMPLE_HASH('a', 'n'):1305/* operator & */1306ddata->cur += 2;1307return (cpp_demangle_read_expression_binary(ddata, "&", 1));13081309case SIMPLE_HASH('a', 'N'):1310/* operator &= */1311ddata->cur += 2;1312return (cpp_demangle_read_expression_binary(ddata, "&=", 2));13131314case SIMPLE_HASH('a', 'S'):1315/* operator = */1316ddata->cur += 2;1317return (cpp_demangle_read_expression_binary(ddata, "=", 1));13181319case SIMPLE_HASH('c', 'l'):1320/* operator () */1321ddata->cur += 2;1322return (cpp_demangle_read_expression_binary(ddata, "()", 2));13231324case SIMPLE_HASH('c', 'm'):1325/* operator , */1326ddata->cur += 2;1327return (cpp_demangle_read_expression_binary(ddata, ",", 1));13281329case SIMPLE_HASH('c', 'o'):1330/* operator ~ */1331ddata->cur += 2;1332return (cpp_demangle_read_expression_binary(ddata, "~", 1));13331334case SIMPLE_HASH('c', 'v'):1335/* operator (cast) */1336ddata->cur += 2;1337return (cpp_demangle_read_expression_binary(ddata, "(cast)", 6));13381339case SIMPLE_HASH('d', 'a'):1340/* operator delete [] */1341ddata->cur += 2;1342return (cpp_demangle_read_expression_unary(ddata, "delete []", 9));13431344case SIMPLE_HASH('d', 'e'):1345/* operator * (unary) */1346ddata->cur += 2;1347return (cpp_demangle_read_expression_unary(ddata, "*", 1));13481349case SIMPLE_HASH('d', 'l'):1350/* operator delete */1351ddata->cur += 2;1352return (cpp_demangle_read_expression_unary(ddata, "delete", 6));13531354case SIMPLE_HASH('d', 'v'):1355/* operator / */1356ddata->cur += 2;1357return (cpp_demangle_read_expression_binary(ddata, "/", 1));13581359case SIMPLE_HASH('d', 'V'):1360/* operator /= */1361ddata->cur += 2;1362return (cpp_demangle_read_expression_binary(ddata, "/=", 2));13631364case SIMPLE_HASH('e', 'o'):1365/* operator ^ */1366ddata->cur += 2;1367return (cpp_demangle_read_expression_binary(ddata, "^", 1));13681369case SIMPLE_HASH('e', 'O'):1370/* operator ^= */1371ddata->cur += 2;1372return (cpp_demangle_read_expression_binary(ddata, "^=", 2));13731374case SIMPLE_HASH('e', 'q'):1375/* operator == */1376ddata->cur += 2;1377return (cpp_demangle_read_expression_binary(ddata, "==", 2));13781379case SIMPLE_HASH('g', 'e'):1380/* operator >= */1381ddata->cur += 2;1382return (cpp_demangle_read_expression_binary(ddata, ">=", 2));13831384case SIMPLE_HASH('g', 't'):1385/* operator > */1386ddata->cur += 2;1387return (cpp_demangle_read_expression_binary(ddata, ">", 1));13881389case SIMPLE_HASH('i', 'x'):1390/* operator [] */1391ddata->cur += 2;1392return (cpp_demangle_read_expression_binary(ddata, "[]", 2));13931394case SIMPLE_HASH('l', 'e'):1395/* operator <= */1396ddata->cur += 2;1397return (cpp_demangle_read_expression_binary(ddata, "<=", 2));13981399case SIMPLE_HASH('l', 's'):1400/* operator << */1401ddata->cur += 2;1402return (cpp_demangle_read_expression_binary(ddata, "<<", 2));14031404case SIMPLE_HASH('l', 'S'):1405/* operator <<= */1406ddata->cur += 2;1407return (cpp_demangle_read_expression_binary(ddata, "<<=", 3));14081409case SIMPLE_HASH('l', 't'):1410/* operator < */1411ddata->cur += 2;1412return (cpp_demangle_read_expression_binary(ddata, "<", 1));14131414case SIMPLE_HASH('m', 'i'):1415/* operator - */1416ddata->cur += 2;1417return (cpp_demangle_read_expression_binary(ddata, "-", 1));14181419case SIMPLE_HASH('m', 'I'):1420/* operator -= */1421ddata->cur += 2;1422return (cpp_demangle_read_expression_binary(ddata, "-=", 2));14231424case SIMPLE_HASH('m', 'l'):1425/* operator * */1426ddata->cur += 2;1427return (cpp_demangle_read_expression_binary(ddata, "*", 1));14281429case SIMPLE_HASH('m', 'L'):1430/* operator *= */1431ddata->cur += 2;1432return (cpp_demangle_read_expression_binary(ddata, "*=", 2));14331434case SIMPLE_HASH('m', 'm'):1435/* operator -- */1436ddata->cur += 2;1437return (cpp_demangle_read_expression_binary(ddata, "--", 2));14381439case SIMPLE_HASH('n', 'a'):1440/* operator new[] */1441ddata->cur += 2;1442return (cpp_demangle_read_expression_unary(ddata, "new []", 6));14431444case SIMPLE_HASH('n', 'e'):1445/* operator != */1446ddata->cur += 2;1447return (cpp_demangle_read_expression_binary(ddata, "!=", 2));14481449case SIMPLE_HASH('n', 'g'):1450/* operator - (unary) */1451ddata->cur += 2;1452return (cpp_demangle_read_expression_unary(ddata, "-", 1));14531454case SIMPLE_HASH('n', 't'):1455/* operator ! */1456ddata->cur += 2;1457return (cpp_demangle_read_expression_binary(ddata, "!", 1));14581459case SIMPLE_HASH('n', 'w'):1460/* operator new */1461ddata->cur += 2;1462return (cpp_demangle_read_expression_unary(ddata, "new", 3));14631464case SIMPLE_HASH('o', 'o'):1465/* operator || */1466ddata->cur += 2;1467return (cpp_demangle_read_expression_binary(ddata, "||", 2));14681469case SIMPLE_HASH('o', 'r'):1470/* operator | */1471ddata->cur += 2;1472return (cpp_demangle_read_expression_binary(ddata, "|", 1));14731474case SIMPLE_HASH('o', 'R'):1475/* operator |= */1476ddata->cur += 2;1477return (cpp_demangle_read_expression_binary(ddata, "|=", 2));14781479case SIMPLE_HASH('p', 'l'):1480/* operator + */1481ddata->cur += 2;1482return (cpp_demangle_read_expression_binary(ddata, "+", 1));14831484case SIMPLE_HASH('p', 'L'):1485/* operator += */1486ddata->cur += 2;1487return (cpp_demangle_read_expression_binary(ddata, "+=", 2));14881489case SIMPLE_HASH('p', 'm'):1490/* operator ->* */1491ddata->cur += 2;1492return (cpp_demangle_read_expression_binary(ddata, "->*", 3));14931494case SIMPLE_HASH('p', 'p'):1495/* operator ++ */1496ddata->cur += 2;1497return (cpp_demangle_read_expression_binary(ddata, "++", 2));14981499case SIMPLE_HASH('p', 's'):1500/* operator + (unary) */1501ddata->cur += 2;1502return (cpp_demangle_read_expression_unary(ddata, "+", 1));15031504case SIMPLE_HASH('p', 't'):1505/* operator -> */1506ddata->cur += 2;1507return (cpp_demangle_read_expression_binary(ddata, "->", 2));15081509case SIMPLE_HASH('q', 'u'):1510/* operator ? */1511ddata->cur += 2;1512return (cpp_demangle_read_expression_trinary(ddata, "?", 1,1513":", 1));15141515case SIMPLE_HASH('r', 'm'):1516/* operator % */1517ddata->cur += 2;1518return (cpp_demangle_read_expression_binary(ddata, "%", 1));15191520case SIMPLE_HASH('r', 'M'):1521/* operator %= */1522ddata->cur += 2;1523return (cpp_demangle_read_expression_binary(ddata, "%=", 2));15241525case SIMPLE_HASH('r', 's'):1526/* operator >> */1527ddata->cur += 2;1528return (cpp_demangle_read_expression_binary(ddata, ">>", 2));15291530case SIMPLE_HASH('r', 'S'):1531/* operator >>= */1532ddata->cur += 2;1533return (cpp_demangle_read_expression_binary(ddata, ">>=", 3));15341535case SIMPLE_HASH('r', 'z'):1536/* operator sizeof */1537ddata->cur += 2;1538return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6));15391540case SIMPLE_HASH('s', 'v'):1541/* operator sizeof */1542ddata->cur += 2;1543return (cpp_demangle_read_expression_unary(ddata, "sizeof", 6));1544}15451546switch (*ddata->cur) {1547case 'L':1548return (cpp_demangle_read_expr_primary(ddata));1549case 'T':1550return (cpp_demangle_read_tmpl_param(ddata));1551}15521553return (0);1554}15551556static int1557cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str)1558{1559struct vector_str *output;1560size_t i, p_idx, idx, exp_len;1561char *exp;15621563output = &ddata->output;15641565p_idx = output->size;15661567if (!cpp_demangle_read_expression(ddata))1568return (0);15691570if ((exp = vector_str_substr(output, p_idx, output->size - 1,1571&exp_len)) == NULL)1572return (0);15731574idx = output->size;1575for (i = p_idx; i < idx; ++i) {1576if (!vector_str_pop(output)) {1577free(exp);1578return (0);1579}1580}15811582*str = exp;15831584return (1);1585}15861587static int1588cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata,1589const char *name, size_t len)1590{15911592if (ddata == NULL || name == NULL || len == 0)1593return (0);1594if (!cpp_demangle_read_expression(ddata))1595return (0);1596if (!cpp_demangle_push_str(ddata, name, len))1597return (0);15981599return (cpp_demangle_read_expression(ddata));1600}16011602static int1603cpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata,1604const char *name, size_t len)1605{16061607if (ddata == NULL || name == NULL || len == 0)1608return (0);1609if (!cpp_demangle_read_expression(ddata))1610return (0);16111612return (cpp_demangle_push_str(ddata, name, len));1613}16141615static int1616cpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata,1617const char *name1, size_t len1, const char *name2, size_t len2)1618{16191620if (ddata == NULL || name1 == NULL || len1 == 0 || name2 == NULL ||1621len2 == 0)1622return (0);16231624if (!cpp_demangle_read_expression(ddata))1625return (0);1626if (!cpp_demangle_push_str(ddata, name1, len1))1627return (0);1628if (!cpp_demangle_read_expression(ddata))1629return (0);1630if (!cpp_demangle_push_str(ddata, name2, len2))1631return (0);16321633return (cpp_demangle_read_expression(ddata));1634}16351636static int1637cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c,1638struct vector_type_qualifier *v)1639{1640struct type_delimit td;1641struct read_cmd_item *rc;1642size_t class_type_size, class_type_len, limit;1643const char *class_type;1644int i;1645bool paren, non_cv_qualifier;16461647if (ddata == NULL || *ddata->cur != 'F' || v == NULL)1648return (0);16491650++ddata->cur;1651if (*ddata->cur == 'Y') {1652if (ext_c != NULL)1653*ext_c = 1;1654++ddata->cur;1655}16561657/* Return type */1658if (!cpp_demangle_read_type(ddata, NULL))1659return (0);16601661if (*ddata->cur != 'E') {1662if (!DEM_PUSH_STR(ddata, " "))1663return (0);16641665non_cv_qualifier = false;1666if (v->size > 0) {1667for (i = 0; (size_t) i < v->size; i++) {1668if (v->q_container[i] != TYPE_RST &&1669v->q_container[i] != TYPE_VAT &&1670v->q_container[i] != TYPE_CST) {1671non_cv_qualifier = true;1672break;1673}1674}1675}16761677paren = false;1678rc = vector_read_cmd_find(&ddata->cmd, READ_PTRMEM);1679if (non_cv_qualifier || rc != NULL) {1680if (!DEM_PUSH_STR(ddata, "("))1681return (0);1682paren = true;1683}16841685/* Push non-cv qualifiers. */1686ddata->push_qualifier = PUSH_NON_CV_QUALIFIER;1687if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))1688return (0);16891690if (rc) {1691if (non_cv_qualifier && !DEM_PUSH_STR(ddata, " "))1692return (0);1693if ((class_type_size = ddata->class_type.size) == 0)1694return (0);1695class_type =1696ddata->class_type.container[class_type_size - 1];1697if (class_type == NULL)1698return (0);1699if ((class_type_len = strlen(class_type)) == 0)1700return (0);1701if (!cpp_demangle_push_str(ddata, class_type,1702class_type_len))1703return (0);1704if (!DEM_PUSH_STR(ddata, "::*"))1705return (0);1706/* Push pointer-to-member qualifiers. */1707ddata->push_qualifier = PUSH_ALL_QUALIFIER;1708if (!cpp_demangle_push_type_qualifier(ddata, rc->data,1709NULL))1710return (0);1711++ddata->func_type;1712}17131714if (paren) {1715if (!DEM_PUSH_STR(ddata, ")"))1716return (0);1717paren = false;1718}17191720td.paren = false;1721td.firstp = true;1722limit = 0;1723ddata->is_functype = true;1724for (;;) {1725if (!cpp_demangle_read_type(ddata, &td))1726return (0);1727if (*ddata->cur == 'E')1728break;1729if (limit++ > CPP_DEMANGLE_TRY_LIMIT)1730return (0);1731}1732ddata->is_functype = false;1733if (td.paren) {1734if (!DEM_PUSH_STR(ddata, ")"))1735return (0);1736td.paren = false;1737}17381739/* Push CV qualifiers. */1740ddata->push_qualifier = PUSH_CV_QUALIFIER;1741if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))1742return (0);17431744ddata->push_qualifier = PUSH_ALL_QUALIFIER;17451746/* Release type qualifier vector. */1747vector_type_qualifier_dest(v);1748if (!vector_type_qualifier_init(v))1749return (0);17501751/* Push ref-qualifiers. */1752if (ddata->ref_qualifier) {1753switch (ddata->ref_qualifier_type) {1754case TYPE_REF:1755if (!DEM_PUSH_STR(ddata, " &"))1756return (0);1757break;1758case TYPE_RREF:1759if (!DEM_PUSH_STR(ddata, " &&"))1760return (0);1761break;1762default:1763return (0);1764}1765ddata->ref_qualifier = false;1766}1767}17681769++ddata->cur;17701771return (1);1772}17731774/* read encoding, encoding are function name, data name, special-name */1775static int1776cpp_demangle_read_encoding(struct cpp_demangle_data *ddata)1777{1778char *name, *type, *num_str;1779long offset;1780int rtn;17811782if (ddata == NULL || *ddata->cur == '\0')1783return (0);17841785/* special name */1786switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {1787case SIMPLE_HASH('G', 'A'):1788if (!DEM_PUSH_STR(ddata, "hidden alias for "))1789return (0);1790ddata->cur += 2;1791if (*ddata->cur == '\0')1792return (0);1793return (cpp_demangle_read_encoding(ddata));17941795case SIMPLE_HASH('G', 'R'):1796if (!DEM_PUSH_STR(ddata, "reference temporary #"))1797return (0);1798ddata->cur += 2;1799if (*ddata->cur == '\0')1800return (0);1801if (!cpp_demangle_read_name_flat(ddata, &name))1802return (0);1803rtn = 0;1804if (!cpp_demangle_read_number_as_string(ddata, &num_str))1805goto clean1;1806if (!DEM_PUSH_STR(ddata, num_str))1807goto clean2;1808if (!DEM_PUSH_STR(ddata, " for "))1809goto clean2;1810if (!DEM_PUSH_STR(ddata, name))1811goto clean2;1812rtn = 1;1813clean2:1814free(num_str);1815clean1:1816free(name);1817return (rtn);18181819case SIMPLE_HASH('G', 'T'):1820ddata->cur += 2;1821if (*ddata->cur == '\0')1822return (0);1823switch (*ddata->cur) {1824case 'n':1825if (!DEM_PUSH_STR(ddata, "non-transaction clone for "))1826return (0);1827break;1828case 't':1829default:1830if (!DEM_PUSH_STR(ddata, "transaction clone for "))1831return (0);1832break;1833}1834++ddata->cur;1835return (cpp_demangle_read_encoding(ddata));18361837case SIMPLE_HASH('G', 'V'):1838/* sentry object for 1 time init */1839if (!DEM_PUSH_STR(ddata, "guard variable for "))1840return (0);1841ddata->cur += 2;1842break;18431844case SIMPLE_HASH('T', 'c'):1845/* virtual function covariant override thunk */1846if (!DEM_PUSH_STR(ddata,1847"virtual function covariant override "))1848return (0);1849ddata->cur += 2;1850if (*ddata->cur == '\0')1851return (0);1852if (!cpp_demangle_read_offset(ddata))1853return (0);1854if (!cpp_demangle_read_offset(ddata))1855return (0);1856return (cpp_demangle_read_encoding(ddata));18571858case SIMPLE_HASH('T', 'C'):1859/* construction vtable */1860if (!DEM_PUSH_STR(ddata, "construction vtable for "))1861return (0);1862ddata->cur += 2;1863if (*ddata->cur == '\0')1864return (0);1865if (!cpp_demangle_read_type_flat(ddata, &type))1866return (0);1867rtn = 0;1868if (!cpp_demangle_read_number(ddata, &offset))1869goto clean3;1870if (*ddata->cur++ != '_')1871goto clean3;1872if (!cpp_demangle_read_type(ddata, NULL))1873goto clean3;1874if (!DEM_PUSH_STR(ddata, "-in-"))1875goto clean3;1876if (!DEM_PUSH_STR(ddata, type))1877goto clean3;1878rtn = 1;1879clean3:1880free(type);1881return (rtn);18821883case SIMPLE_HASH('T', 'D'):1884/* typeinfo common proxy */1885break;18861887case SIMPLE_HASH('T', 'F'):1888/* typeinfo fn */1889if (!DEM_PUSH_STR(ddata, "typeinfo fn for "))1890return (0);1891ddata->cur += 2;1892if (*ddata->cur == '\0')1893return (0);1894return (cpp_demangle_read_type(ddata, NULL));18951896case SIMPLE_HASH('T', 'h'):1897/* virtual function non-virtual override thunk */1898if (!DEM_PUSH_STR(ddata,1899"virtual function non-virtual override "))1900return (0);1901ddata->cur += 2;1902if (*ddata->cur == '\0')1903return (0);1904if (!cpp_demangle_read_nv_offset(ddata))1905return (0);1906return (cpp_demangle_read_encoding(ddata));19071908case SIMPLE_HASH('T', 'H'):1909/* TLS init function */1910if (!DEM_PUSH_STR(ddata, "TLS init function for "))1911return (0);1912ddata->cur += 2;1913if (*ddata->cur == '\0')1914return (0);1915break;19161917case SIMPLE_HASH('T', 'I'):1918/* typeinfo structure */1919if (!DEM_PUSH_STR(ddata, "typeinfo for "))1920return (0);1921ddata->cur += 2;1922if (*ddata->cur == '\0')1923return (0);1924return (cpp_demangle_read_type(ddata, NULL));19251926case SIMPLE_HASH('T', 'J'):1927/* java class */1928if (!DEM_PUSH_STR(ddata, "java Class for "))1929return (0);1930ddata->cur += 2;1931if (*ddata->cur == '\0')1932return (0);1933return (cpp_demangle_read_type(ddata, NULL));19341935case SIMPLE_HASH('T', 'S'):1936/* RTTI name (NTBS) */1937if (!DEM_PUSH_STR(ddata, "typeinfo name for "))1938return (0);1939ddata->cur += 2;1940if (*ddata->cur == '\0')1941return (0);1942return (cpp_demangle_read_type(ddata, NULL));19431944case SIMPLE_HASH('T', 'T'):1945/* VTT table */1946if (!DEM_PUSH_STR(ddata, "VTT for "))1947return (0);1948ddata->cur += 2;1949if (*ddata->cur == '\0')1950return (0);1951return (cpp_demangle_read_type(ddata, NULL));19521953case SIMPLE_HASH('T', 'v'):1954/* virtual function virtual override thunk */1955if (!DEM_PUSH_STR(ddata, "virtual function virtual override "))1956return (0);1957ddata->cur += 2;1958if (*ddata->cur == '\0')1959return (0);1960if (!cpp_demangle_read_v_offset(ddata))1961return (0);1962return (cpp_demangle_read_encoding(ddata));19631964case SIMPLE_HASH('T', 'V'):1965/* virtual table */1966if (!DEM_PUSH_STR(ddata, "vtable for "))1967return (0);1968ddata->cur += 2;1969if (*ddata->cur == '\0')1970return (0);1971return (cpp_demangle_read_type(ddata, NULL));19721973case SIMPLE_HASH('T', 'W'):1974/* TLS wrapper function */1975if (!DEM_PUSH_STR(ddata, "TLS wrapper function for "))1976return (0);1977ddata->cur += 2;1978if (*ddata->cur == '\0')1979return (0);1980break;1981}19821983return (cpp_demangle_read_name(ddata));1984}19851986static int1987cpp_demangle_read_local_name(struct cpp_demangle_data *ddata)1988{1989struct vector_str local_name;1990struct type_delimit td;1991size_t limit;1992bool more_type;19931994if (ddata == NULL)1995return (0);1996if (*(++ddata->cur) == '\0')1997return (0);19981999if (!vector_str_init(&local_name))2000return (0);2001ddata->cur_output = &local_name;20022003if (!cpp_demangle_read_encoding(ddata)) {2004vector_str_dest(&local_name);2005return (0);2006}20072008ddata->cur_output = &ddata->output;20092010td.paren = false;2011td.firstp = true;2012more_type = false;2013limit = 0;20142015/*2016* The first type is a return type if we just demangled template2017* args. (the template args is right next to the function name,2018* which means it's a template function)2019*/2020if (ddata->is_tmpl) {2021ddata->is_tmpl = false;20222023/* Read return type */2024if (!cpp_demangle_read_type(ddata, NULL)) {2025vector_str_dest(&local_name);2026return (0);2027}20282029more_type = true;2030}20312032/* Now we can push the name after possible return type is handled. */2033if (!vector_str_push_vector(&ddata->output, &local_name)) {2034vector_str_dest(&local_name);2035return (0);2036}2037vector_str_dest(&local_name);20382039while (*ddata->cur != '\0') {2040if (!cpp_demangle_read_type(ddata, &td))2041return (0);2042if (more_type)2043more_type = false;2044if (*ddata->cur == 'E')2045break;2046if (limit++ > CPP_DEMANGLE_TRY_LIMIT)2047return (0);2048}2049if (more_type)2050return (0);20512052if (*(++ddata->cur) == '\0')2053return (0);2054if (td.paren == true) {2055if (!DEM_PUSH_STR(ddata, ")"))2056return (0);2057td.paren = false;2058}2059if (*ddata->cur == 's')2060++ddata->cur;2061else {2062if (!DEM_PUSH_STR(ddata, "::"))2063return (0);2064if (!cpp_demangle_read_name(ddata))2065return (0);2066}2067if (*ddata->cur == '_') {2068++ddata->cur;2069while (ELFTC_ISDIGIT(*ddata->cur) != 0)2070++ddata->cur;2071}20722073return (1);2074}20752076static int2077cpp_demangle_read_name(struct cpp_demangle_data *ddata)2078{2079struct vector_str *output, v;2080size_t p_idx, subst_str_len;2081int rtn;2082char *subst_str;20832084if (ddata == NULL || *ddata->cur == '\0')2085return (0);20862087output = ddata->cur_output;20882089subst_str = NULL;20902091switch (*ddata->cur) {2092case 'S':2093return (cpp_demangle_read_subst(ddata));2094case 'N':2095return (cpp_demangle_read_nested_name(ddata));2096case 'Z':2097return (cpp_demangle_read_local_name(ddata));2098}20992100if (!vector_str_init(&v))2101return (0);21022103p_idx = output->size;2104rtn = 0;2105if (!cpp_demangle_read_uqname(ddata))2106goto clean;2107if ((subst_str = vector_str_substr(output, p_idx, output->size - 1,2108&subst_str_len)) == NULL)2109goto clean;2110if (subst_str_len > 8 && strstr(subst_str, "operator") != NULL) {2111rtn = 1;2112goto clean;2113}2114if (!vector_str_push(&v, subst_str, subst_str_len))2115goto clean;2116if (!cpp_demangle_push_subst_v(ddata, &v))2117goto clean;21182119if (*ddata->cur == 'I') {2120p_idx = output->size;2121if (!cpp_demangle_read_tmpl_args(ddata))2122goto clean;2123free(subst_str);2124if ((subst_str = vector_str_substr(output, p_idx,2125output->size - 1, &subst_str_len)) == NULL)2126goto clean;2127if (!vector_str_push(&v, subst_str, subst_str_len))2128goto clean;2129if (!cpp_demangle_push_subst_v(ddata, &v))2130goto clean;2131}21322133rtn = 1;21342135clean:2136free(subst_str);2137vector_str_dest(&v);21382139return (rtn);2140}21412142static int2143cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str)2144{2145struct vector_str *output;2146size_t i, p_idx, idx, name_len;2147char *name;21482149output = ddata->cur_output;21502151p_idx = output->size;21522153if (!cpp_demangle_read_name(ddata))2154return (0);21552156if ((name = vector_str_substr(output, p_idx, output->size - 1,2157&name_len)) == NULL)2158return (0);21592160idx = output->size;2161for (i = p_idx; i < idx; ++i) {2162if (!vector_str_pop(output)) {2163free(name);2164return (0);2165}2166}21672168*str = name;21692170return (1);2171}21722173static int2174cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata)2175{2176struct vector_str *output, v;2177size_t limit, p_idx, subst_str_len;2178int rtn;2179char *subst_str;21802181if (ddata == NULL || *ddata->cur != 'N')2182return (0);2183if (*(++ddata->cur) == '\0')2184return (0);21852186do {2187switch (*ddata->cur) {2188case 'r':2189ddata->mem_rst = true;2190break;2191case 'V':2192ddata->mem_vat = true;2193break;2194case 'K':2195ddata->mem_cst = true;2196break;2197case 'R':2198ddata->mem_ref = true;2199break;2200case 'O':2201ddata->mem_rref = true;2202break;2203default:2204goto next;2205}2206} while (*(++ddata->cur));22072208next:2209output = ddata->cur_output;2210if (!vector_str_init(&v))2211return (0);22122213rtn = 0;2214limit = 0;2215for (;;) {2216p_idx = output->size;2217switch (*ddata->cur) {2218case 'I':2219if (!cpp_demangle_read_tmpl_args(ddata))2220goto clean;2221break;2222case 'S':2223if (!cpp_demangle_read_subst(ddata))2224goto clean;2225break;2226case 'T':2227if (!cpp_demangle_read_tmpl_param(ddata))2228goto clean;2229break;2230default:2231if (!cpp_demangle_read_uqname(ddata))2232goto clean;2233}22342235if (p_idx == output->size)2236goto next_comp;2237if ((subst_str = vector_str_substr(output, p_idx,2238output->size - 1, &subst_str_len)) == NULL)2239goto clean;2240if (!vector_str_push(&v, subst_str, subst_str_len)) {2241free(subst_str);2242goto clean;2243}2244free(subst_str);22452246if (!cpp_demangle_push_subst_v(ddata, &v))2247goto clean;22482249next_comp:2250if (*ddata->cur == 'E')2251break;2252else if (*ddata->cur != 'I' && *ddata->cur != 'C' &&2253*ddata->cur != 'D' && p_idx != output->size) {2254if (!DEM_PUSH_STR(ddata, "::"))2255goto clean;2256if (!VEC_PUSH_STR(&v, "::"))2257goto clean;2258}2259if (limit++ > CPP_DEMANGLE_TRY_LIMIT)2260goto clean;2261}22622263++ddata->cur;2264rtn = 1;22652266clean:2267vector_str_dest(&v);22682269return (rtn);2270}22712272/*2273* read number2274* number ::= [n] <decimal>2275*/2276static int2277cpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn)2278{2279long len, negative_factor;22802281if (ddata == NULL || rtn == NULL)2282return (0);22832284negative_factor = 1;2285if (*ddata->cur == 'n') {2286negative_factor = -1;22872288++ddata->cur;2289}2290if (ELFTC_ISDIGIT(*ddata->cur) == 0)2291return (0);22922293errno = 0;2294if ((len = strtol(ddata->cur, (char **) NULL, 10)) == 0 &&2295errno != 0)2296return (0);22972298while (ELFTC_ISDIGIT(*ddata->cur) != 0)2299++ddata->cur;23002301assert(len >= 0);2302assert(negative_factor == 1 || negative_factor == -1);23032304*rtn = len * negative_factor;23052306return (1);2307}23082309static int2310cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str)2311{2312long n;23132314if (!cpp_demangle_read_number(ddata, &n)) {2315*str = NULL;2316return (0);2317}23182319if (asprintf(str, "%ld", n) < 0) {2320*str = NULL;2321return (0);2322}23232324return (1);2325}23262327static int2328cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata)2329{23302331if (ddata == NULL)2332return (0);23332334if (!DEM_PUSH_STR(ddata, "offset : "))2335return (0);23362337return (cpp_demangle_read_offset_number(ddata));2338}23392340/* read offset, offset are nv-offset, v-offset */2341static int2342cpp_demangle_read_offset(struct cpp_demangle_data *ddata)2343{23442345if (ddata == NULL)2346return (0);23472348if (*ddata->cur == 'h') {2349++ddata->cur;2350return (cpp_demangle_read_nv_offset(ddata));2351} else if (*ddata->cur == 'v') {2352++ddata->cur;2353return (cpp_demangle_read_v_offset(ddata));2354}23552356return (0);2357}23582359static int2360cpp_demangle_read_offset_number(struct cpp_demangle_data *ddata)2361{2362bool negative;2363const char *start;23642365if (ddata == NULL || *ddata->cur == '\0')2366return (0);23672368/* offset could be negative */2369if (*ddata->cur == 'n') {2370negative = true;2371start = ddata->cur + 1;2372} else {2373negative = false;2374start = ddata->cur;2375}23762377while (*ddata->cur != '_')2378++ddata->cur;23792380if (negative && !DEM_PUSH_STR(ddata, "-"))2381return (0);23822383assert(start != NULL);23842385if (!cpp_demangle_push_str(ddata, start, ddata->cur - start))2386return (0);2387if (!DEM_PUSH_STR(ddata, " "))2388return (0);23892390++ddata->cur;23912392return (1);2393}23942395static int2396cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata,2397struct vector_type_qualifier *v)2398{2399size_t class_type_len, i, idx, p_idx;2400int p_func_type, rtn;2401char *class_type;24022403if (ddata == NULL || *ddata->cur != 'M' || *(++ddata->cur) == '\0')2404return (0);24052406p_idx = ddata->output.size;2407if (!cpp_demangle_read_type(ddata, NULL))2408return (0);24092410if ((class_type = vector_str_substr(&ddata->output, p_idx,2411ddata->output.size - 1, &class_type_len)) == NULL)2412return (0);24132414rtn = 0;2415idx = ddata->output.size;2416for (i = p_idx; i < idx; ++i)2417if (!vector_str_pop(&ddata->output))2418goto clean1;24192420if (!vector_read_cmd_push(&ddata->cmd, READ_PTRMEM, v))2421goto clean1;24222423if (!vector_str_push(&ddata->class_type, class_type, class_type_len))2424goto clean2;24252426p_func_type = ddata->func_type;2427if (!cpp_demangle_read_type(ddata, NULL))2428goto clean3;24292430if (p_func_type == ddata->func_type) {2431if (!DEM_PUSH_STR(ddata, " "))2432goto clean3;2433if (!cpp_demangle_push_str(ddata, class_type, class_type_len))2434goto clean3;2435if (!DEM_PUSH_STR(ddata, "::*"))2436goto clean3;2437}24382439rtn = 1;2440clean3:2441if (!vector_str_pop(&ddata->class_type))2442rtn = 0;2443clean2:2444if (!vector_read_cmd_pop(&ddata->cmd))2445rtn = 0;2446clean1:2447free(class_type);24482449vector_type_qualifier_dest(v);2450if (!vector_type_qualifier_init(v))2451return (0);24522453return (rtn);2454}24552456/* read source-name, source-name is <len> <ID> */2457static int2458cpp_demangle_read_sname(struct cpp_demangle_data *ddata)2459{2460long len;2461int err;24622463if (ddata == NULL || cpp_demangle_read_number(ddata, &len) == 0 ||2464len <= 0)2465return (0);24662467if (len == 12 && (memcmp("_GLOBAL__N_1", ddata->cur, 12) == 0))2468err = DEM_PUSH_STR(ddata, "(anonymous namespace)");2469else2470err = cpp_demangle_push_str(ddata, ddata->cur, len);24712472if (err == 0)2473return (0);24742475assert(ddata->cur_output->size > 0);2476if (vector_read_cmd_find(&ddata->cmd, READ_TMPL) == NULL)2477ddata->last_sname =2478ddata->cur_output->container[ddata->cur_output->size - 1];24792480ddata->cur += len;24812482return (1);2483}24842485static int2486cpp_demangle_read_subst(struct cpp_demangle_data *ddata)2487{2488long nth;24892490if (ddata == NULL || *ddata->cur == '\0')2491return (0);24922493/* abbreviations of the form Sx */2494switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {2495case SIMPLE_HASH('S', 'a'):2496/* std::allocator */2497if (!DEM_PUSH_STR(ddata, "std::allocator"))2498return (0);2499ddata->cur += 2;2500if (*ddata->cur == 'I')2501return (cpp_demangle_read_subst_stdtmpl(ddata,2502"std::allocator"));2503return (1);25042505case SIMPLE_HASH('S', 'b'):2506/* std::basic_string */2507if (!DEM_PUSH_STR(ddata, "std::basic_string"))2508return (0);2509ddata->cur += 2;2510if (*ddata->cur == 'I')2511return (cpp_demangle_read_subst_stdtmpl(ddata,2512"std::basic_string"));2513return (1);25142515case SIMPLE_HASH('S', 'd'):2516/* std::basic_iostream<char, std::char_traits<char>> */2517if (!DEM_PUSH_STR(ddata, "std::basic_iostream<char, "2518"std::char_traits<char>>"))2519return (0);2520ddata->last_sname = "basic_iostream";2521ddata->cur += 2;2522if (*ddata->cur == 'I')2523return (cpp_demangle_read_subst_stdtmpl(ddata,2524"std::basic_iostream<char, std::char_traits"2525"<char>>"));2526return (1);25272528case SIMPLE_HASH('S', 'i'):2529/* std::basic_istream<char, std::char_traits<char>> */2530if (!DEM_PUSH_STR(ddata, "std::basic_istream<char, "2531"std::char_traits<char>>"))2532return (0);2533ddata->last_sname = "basic_istream";2534ddata->cur += 2;2535if (*ddata->cur == 'I')2536return (cpp_demangle_read_subst_stdtmpl(ddata,2537"std::basic_istream<char, std::char_traits"2538"<char>>"));2539return (1);25402541case SIMPLE_HASH('S', 'o'):2542/* std::basic_ostream<char, std::char_traits<char>> */2543if (!DEM_PUSH_STR(ddata, "std::basic_ostream<char, "2544"std::char_traits<char>>"))2545return (0);2546ddata->last_sname = "basic_ostream";2547ddata->cur += 2;2548if (*ddata->cur == 'I')2549return (cpp_demangle_read_subst_stdtmpl(ddata,2550"std::basic_ostream<char, std::char_traits"2551"<char>>"));2552return (1);25532554case SIMPLE_HASH('S', 's'):2555/*2556* std::string for consistency with libcxxabi2557*/2558if (!DEM_PUSH_STR(ddata, "std::string"))2559return 0;2560ddata->last_sname = "string";2561ddata->cur += 2;2562if (*ddata->cur == 'I')2563return cpp_demangle_read_subst_stdtmpl(ddata,2564"std::string");2565return 1;25662567case SIMPLE_HASH('S', 't'):2568/* std:: */2569return (cpp_demangle_read_subst_std(ddata));2570}25712572if (*(++ddata->cur) == '\0')2573return (0);25742575/* Skip unknown substitution abbreviations. */2576if (!(*ddata->cur >= '0' && *ddata->cur <= '9') &&2577!(*ddata->cur >= 'A' && *ddata->cur <= 'Z') &&2578*ddata->cur != '_') {2579++ddata->cur;2580return (1);2581}25822583/* substitution */2584if (*ddata->cur == '_')2585return (cpp_demangle_get_subst(ddata, 0));2586else {2587errno = 0;2588/* substitution number is base 36 */2589if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 &&2590errno != 0)2591return (0);25922593/* first was '_', so increase one */2594++nth;25952596while (*ddata->cur != '_')2597++ddata->cur;25982599assert(nth > 0);26002601return (cpp_demangle_get_subst(ddata, nth));2602}26032604/* NOTREACHED */2605return (0);2606}26072608static int2609cpp_demangle_read_subst_std(struct cpp_demangle_data *ddata)2610{2611struct vector_str *output, v;2612size_t p_idx, subst_str_len;2613int rtn;2614char *subst_str;26152616if (ddata == NULL)2617return (0);26182619if (!vector_str_init(&v))2620return (0);26212622subst_str = NULL;2623rtn = 0;2624if (!DEM_PUSH_STR(ddata, "std::"))2625goto clean;26262627if (!VEC_PUSH_STR(&v, "std::"))2628goto clean;26292630ddata->cur += 2;26312632output = ddata->cur_output;26332634p_idx = output->size;2635if (!cpp_demangle_read_uqname(ddata))2636goto clean;26372638if ((subst_str = vector_str_substr(output, p_idx, output->size - 1,2639&subst_str_len)) == NULL)2640goto clean;26412642if (!vector_str_push(&v, subst_str, subst_str_len))2643goto clean;26442645if (!cpp_demangle_push_subst_v(ddata, &v))2646goto clean;26472648if (*ddata->cur == 'I') {2649p_idx = output->size;2650if (!cpp_demangle_read_tmpl_args(ddata))2651goto clean;2652free(subst_str);2653if ((subst_str = vector_str_substr(output, p_idx,2654output->size - 1, &subst_str_len)) == NULL)2655goto clean;2656if (!vector_str_push(&v, subst_str, subst_str_len))2657goto clean;2658if (!cpp_demangle_push_subst_v(ddata, &v))2659goto clean;2660}26612662rtn = 1;2663clean:2664free(subst_str);2665vector_str_dest(&v);26662667return (rtn);2668}26692670static int2671cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata,2672const char *str)2673{2674struct vector_str *output;2675size_t p_idx, substr_len, len;2676int rtn;2677char *subst_str, *substr;26782679if (ddata == NULL || str == NULL)2680return (0);26812682if ((len = strlen(str)) == 0)2683return (0);26842685output = ddata->cur_output;26862687p_idx = output->size;2688substr = NULL;2689subst_str = NULL;26902691if (!cpp_demangle_read_tmpl_args(ddata))2692return (0);2693if ((substr = vector_str_substr(output, p_idx, output->size - 1,2694&substr_len)) == NULL)2695return (0);26962697rtn = 0;2698if ((subst_str = malloc(sizeof(char) * (substr_len + len + 1))) ==2699NULL)2700goto clean;27012702memcpy(subst_str, str, len);2703memcpy(subst_str + len, substr, substr_len);2704subst_str[substr_len + len] = '\0';27052706if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len))2707goto clean;27082709rtn = 1;2710clean:2711free(subst_str);2712free(substr);27132714return (rtn);2715}27162717static int2718cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata)2719{27202721if (ddata == NULL || *ddata->cur == '\0')2722return (0);27232724switch (*ddata->cur) {2725case 'L':2726return (cpp_demangle_read_expr_primary(ddata));2727case 'X':2728++ddata->cur;2729if (!cpp_demangle_read_expression(ddata))2730return (0);2731return (*ddata->cur++ == 'E');2732}27332734return (cpp_demangle_read_type(ddata, NULL));2735}27362737static int2738cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata)2739{2740struct vector_str *v;2741size_t arg_len, idx, limit;2742char *arg;27432744if (ddata == NULL || *ddata->cur == '\0')2745return (0);27462747++ddata->cur;27482749if (!vector_read_cmd_push(&ddata->cmd, READ_TMPL, NULL))2750return (0);27512752if (!DEM_PUSH_STR(ddata, "<"))2753return (0);27542755limit = 0;2756v = ddata->cur_output;2757for (;;) {2758idx = v->size;2759if (!cpp_demangle_read_tmpl_arg(ddata))2760return (0);2761if ((arg = vector_str_substr(v, idx, v->size - 1, &arg_len)) ==2762NULL)2763return (0);2764if (!vector_str_find(&ddata->tmpl, arg, arg_len) &&2765!vector_str_push(&ddata->tmpl, arg, arg_len)) {2766free(arg);2767return (0);2768}27692770free(arg);27712772if (*ddata->cur == 'E') {2773++ddata->cur;2774if (!DEM_PUSH_STR(ddata, ">"))2775return (0);2776ddata->is_tmpl = true;2777break;2778} else if (*ddata->cur != 'I' &&2779!DEM_PUSH_STR(ddata, ", "))2780return (0);27812782if (limit++ > CPP_DEMANGLE_TRY_LIMIT)2783return (0);2784}27852786return (vector_read_cmd_pop(&ddata->cmd));2787}27882789/*2790* Read template parameter that forms in 'T[number]_'.2791* This function much like to read_subst but only for types.2792*/2793static int2794cpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata)2795{2796long nth;27972798if (ddata == NULL || *ddata->cur != 'T')2799return (0);28002801++ddata->cur;28022803if (*ddata->cur == '_')2804return (cpp_demangle_get_tmpl_param(ddata, 0));2805else {28062807errno = 0;2808if ((nth = strtol(ddata->cur, (char **) NULL, 36)) == 0 &&2809errno != 0)2810return (0);28112812/* T_ is first */2813++nth;28142815while (*ddata->cur != '_')2816++ddata->cur;28172818assert(nth > 0);28192820return (cpp_demangle_get_tmpl_param(ddata, nth));2821}28222823/* NOTREACHED */2824return (0);2825}28262827static int2828cpp_demangle_read_type(struct cpp_demangle_data *ddata,2829struct type_delimit *td)2830{2831struct vector_type_qualifier v;2832struct vector_str *output, sv;2833size_t p_idx, type_str_len, subst_str_len;2834int extern_c, is_builtin;2835long len;2836const char *p;2837char *type_str, *exp_str, *num_str, *subst_str;2838bool skip_ref_qualifier, omit_void;28392840if (ddata == NULL)2841return (0);28422843output = ddata->cur_output;2844if (td) {2845if (td->paren == false) {2846if (!DEM_PUSH_STR(ddata, "("))2847return (0);2848if (ddata->output.size < 2)2849return (0);2850td->paren = true;2851}28522853if (!td->firstp) {2854if (*ddata->cur != 'I') {2855if (!DEM_PUSH_STR(ddata, ", "))2856return (0);2857}2858}2859}28602861assert(output != NULL);2862/*2863* [r, V, K] [P, R, O, C, G, U] builtin, function, class-enum, array2864* pointer-to-member, template-param, template-template-param, subst2865*/28662867if (!vector_type_qualifier_init(&v))2868return (0);28692870extern_c = 0;2871is_builtin = 1;2872p_idx = output->size;2873type_str = exp_str = num_str = NULL;2874skip_ref_qualifier = false;28752876again:28772878/* Clear ref-qualifier flag */2879if (*ddata->cur != 'R' && *ddata->cur != 'O' && *ddata->cur != 'E')2880ddata->ref_qualifier = false;28812882/* builtin type */2883switch (*ddata->cur) {2884case 'a':2885/* signed char */2886if (!DEM_PUSH_STR(ddata, "signed char"))2887goto clean;2888++ddata->cur;2889goto rtn;28902891case 'A':2892/* array type */2893if (!cpp_demangle_read_array(ddata))2894goto clean;2895is_builtin = 0;2896goto rtn;28972898case 'b':2899/* bool */2900if (!DEM_PUSH_STR(ddata, "bool"))2901goto clean;2902++ddata->cur;2903goto rtn;29042905case 'C':2906/* complex pair */2907if (!vector_type_qualifier_push(&v, TYPE_CMX))2908goto clean;2909++ddata->cur;2910if (td)2911td->firstp = false;2912goto again;29132914case 'c':2915/* char */2916if (!DEM_PUSH_STR(ddata, "char"))2917goto clean;2918++ddata->cur;2919goto rtn;29202921case 'd':2922/* double */2923if (!DEM_PUSH_STR(ddata, "double"))2924goto clean;2925++ddata->cur;2926goto rtn;29272928case 'D':2929++ddata->cur;2930switch (*ddata->cur) {2931case 'a':2932/* auto */2933if (!DEM_PUSH_STR(ddata, "auto"))2934goto clean;2935++ddata->cur;2936break;2937case 'c':2938/* decltype(auto) */2939if (!DEM_PUSH_STR(ddata, "decltype(auto)"))2940goto clean;2941++ddata->cur;2942break;2943case 'd':2944/* IEEE 754r decimal floating point (64 bits) */2945if (!DEM_PUSH_STR(ddata, "decimal64"))2946goto clean;2947++ddata->cur;2948break;2949case 'e':2950/* IEEE 754r decimal floating point (128 bits) */2951if (!DEM_PUSH_STR(ddata, "decimal128"))2952goto clean;2953++ddata->cur;2954break;2955case 'f':2956/* IEEE 754r decimal floating point (32 bits) */2957if (!DEM_PUSH_STR(ddata, "decimal32"))2958goto clean;2959++ddata->cur;2960break;2961case 'h':2962/* IEEE 754r half-precision floating point (16 bits) */2963if (!DEM_PUSH_STR(ddata, "half"))2964goto clean;2965++ddata->cur;2966break;2967case 'i':2968/* char32_t */2969if (!DEM_PUSH_STR(ddata, "char32_t"))2970goto clean;2971++ddata->cur;2972break;2973case 'n':2974/* std::nullptr_t (i.e., decltype(nullptr)) */2975if (!DEM_PUSH_STR(ddata, "decltype(nullptr)"))2976goto clean;2977++ddata->cur;2978break;2979case 's':2980/* char16_t */2981if (!DEM_PUSH_STR(ddata, "char16_t"))2982goto clean;2983++ddata->cur;2984break;2985case 'v':2986/* gcc vector_size extension. */2987++ddata->cur;2988if (*ddata->cur == '_') {2989++ddata->cur;2990if (!cpp_demangle_read_expression_flat(ddata,2991&exp_str))2992goto clean;2993if (!VEC_PUSH_STR(&v.ext_name, exp_str))2994goto clean;2995} else {2996if (!cpp_demangle_read_number_as_string(ddata,2997&num_str))2998goto clean;2999if (!VEC_PUSH_STR(&v.ext_name, num_str))3000goto clean;3001}3002if (*ddata->cur != '_')3003goto clean;3004++ddata->cur;3005if (!vector_type_qualifier_push(&v, TYPE_VEC))3006goto clean;3007if (td)3008td->firstp = false;3009goto again;3010default:3011goto clean;3012}3013goto rtn;30143015case 'e':3016/* long double */3017if (!DEM_PUSH_STR(ddata, "long double"))3018goto clean;3019++ddata->cur;3020goto rtn;30213022case 'E':3023/* unexpected end except ref-qualifiers */3024if (ddata->ref_qualifier && ddata->is_functype) {3025skip_ref_qualifier = true;3026/* Pop the delimiter. */3027cpp_demangle_pop_str(ddata);3028goto rtn;3029}3030goto clean;30313032case 'f':3033/* float */3034if (!DEM_PUSH_STR(ddata, "float"))3035goto clean;3036++ddata->cur;3037goto rtn;30383039case 'F':3040/* function */3041if (!cpp_demangle_read_function(ddata, &extern_c, &v))3042goto clean;3043is_builtin = 0;3044goto rtn;30453046case 'g':3047/* __float128 */3048if (!DEM_PUSH_STR(ddata, "__float128"))3049goto clean;3050++ddata->cur;3051goto rtn;30523053case 'G':3054/* imaginary */3055if (!vector_type_qualifier_push(&v, TYPE_IMG))3056goto clean;3057++ddata->cur;3058if (td)3059td->firstp = false;3060goto again;30613062case 'h':3063/* unsigned char */3064if (!DEM_PUSH_STR(ddata, "unsigned char"))3065goto clean;3066++ddata->cur;3067goto rtn;30683069case 'i':3070/* int */3071if (!DEM_PUSH_STR(ddata, "int"))3072goto clean;3073++ddata->cur;3074goto rtn;30753076case 'I':3077/* template args. */3078/* handles <substitute><template-args> */3079p_idx = output->size;3080if (!cpp_demangle_read_tmpl_args(ddata))3081goto clean;3082if ((subst_str = vector_str_substr(output, p_idx,3083output->size - 1, &subst_str_len)) == NULL)3084goto clean;3085if (!vector_str_init(&sv)) {3086free(subst_str);3087goto clean;3088}3089if (!vector_str_push(&sv, subst_str, subst_str_len)) {3090free(subst_str);3091vector_str_dest(&sv);3092goto clean;3093}3094free(subst_str);3095if (!cpp_demangle_push_subst_v(ddata, &sv)) {3096vector_str_dest(&sv);3097goto clean;3098}3099vector_str_dest(&sv);3100goto rtn;31013102case 'j':3103/* unsigned int */3104if (!DEM_PUSH_STR(ddata, "unsigned int"))3105goto clean;3106++ddata->cur;3107goto rtn;31083109case 'K':3110/* const */3111if (!vector_type_qualifier_push(&v, TYPE_CST))3112goto clean;3113++ddata->cur;3114if (td)3115td->firstp = false;3116goto again;31173118case 'l':3119/* long */3120if (!DEM_PUSH_STR(ddata, "long"))3121goto clean;3122++ddata->cur;3123goto rtn;31243125case 'm':3126/* unsigned long */3127if (!DEM_PUSH_STR(ddata, "unsigned long"))3128goto clean;31293130++ddata->cur;31313132goto rtn;3133case 'M':3134/* pointer to member */3135if (!cpp_demangle_read_pointer_to_member(ddata, &v))3136goto clean;3137is_builtin = 0;3138goto rtn;31393140case 'n':3141/* __int128 */3142if (!DEM_PUSH_STR(ddata, "__int128"))3143goto clean;3144++ddata->cur;3145goto rtn;31463147case 'o':3148/* unsigned __int128 */3149if (!DEM_PUSH_STR(ddata, "unsigned __int128"))3150goto clean;3151++ddata->cur;3152goto rtn;31533154case 'O':3155/* rvalue reference */3156if (ddata->ref_qualifier)3157goto clean;3158if (!vector_type_qualifier_push(&v, TYPE_RREF))3159goto clean;3160ddata->ref_qualifier = true;3161ddata->ref_qualifier_type = TYPE_RREF;3162++ddata->cur;3163if (td)3164td->firstp = false;3165goto again;31663167case 'P':3168/* pointer */3169if (!vector_type_qualifier_push(&v, TYPE_PTR))3170goto clean;3171++ddata->cur;3172if (td)3173td->firstp = false;3174goto again;31753176case 'r':3177/* restrict */3178if (!vector_type_qualifier_push(&v, TYPE_RST))3179goto clean;3180++ddata->cur;3181if (td)3182td->firstp = false;3183goto again;31843185case 'R':3186/* reference */3187if (ddata->ref_qualifier)3188goto clean;3189if (!vector_type_qualifier_push(&v, TYPE_REF))3190goto clean;3191ddata->ref_qualifier = true;3192ddata->ref_qualifier_type = TYPE_REF;3193++ddata->cur;3194if (td)3195td->firstp = false;3196goto again;31973198case 's':3199/* short, local string */3200if (!DEM_PUSH_STR(ddata, "short"))3201goto clean;3202++ddata->cur;3203goto rtn;32043205case 'S':3206/* substitution */3207if (!cpp_demangle_read_subst(ddata))3208goto clean;3209is_builtin = 0;3210goto rtn;32113212case 't':3213/* unsigned short */3214if (!DEM_PUSH_STR(ddata, "unsigned short"))3215goto clean;3216++ddata->cur;3217goto rtn;32183219case 'T':3220/* template parameter */3221if (!cpp_demangle_read_tmpl_param(ddata))3222goto clean;3223is_builtin = 0;3224goto rtn;32253226case 'u':3227/* vendor extended builtin */3228++ddata->cur;3229if (!cpp_demangle_read_sname(ddata))3230goto clean;3231is_builtin = 0;3232goto rtn;32333234case 'U':3235/* vendor extended type qualifier */3236++ddata->cur;3237if (!cpp_demangle_read_number(ddata, &len))3238goto clean;3239if (len <= 0)3240goto clean;3241if (!vector_str_push(&v.ext_name, ddata->cur, len))3242goto clean;3243ddata->cur += len;3244if (!vector_type_qualifier_push(&v, TYPE_EXT))3245goto clean;3246if (td)3247td->firstp = false;3248goto again;32493250case 'v':3251/* void */3252omit_void = false;3253if (td && td->firstp) {3254/*3255* peek into next bytes and see if we should omit3256* the "void".3257*/3258omit_void = true;3259for (p = ddata->cur + 1; *p != '\0'; p++) {3260if (*p == 'E')3261break;3262if (*p != 'R' && *p != 'O') {3263omit_void = false;3264break;3265}3266}3267}3268if (!omit_void && !DEM_PUSH_STR(ddata, "void"))3269goto clean;3270++ddata->cur;3271goto rtn;32723273case 'V':3274/* volatile */3275if (!vector_type_qualifier_push(&v, TYPE_VAT))3276goto clean;3277++ddata->cur;3278if (td)3279td->firstp = false;3280goto again;32813282case 'w':3283/* wchar_t */3284if (!DEM_PUSH_STR(ddata, "wchar_t"))3285goto clean;3286++ddata->cur;3287goto rtn;32883289case 'x':3290/* long long */3291if (!DEM_PUSH_STR(ddata, "long long"))3292goto clean;3293++ddata->cur;3294goto rtn;32953296case 'y':3297/* unsigned long long */3298if (!DEM_PUSH_STR(ddata, "unsigned long long"))3299goto clean;3300++ddata->cur;3301goto rtn;33023303case 'z':3304/* ellipsis */3305if (!DEM_PUSH_STR(ddata, "..."))3306goto clean;3307++ddata->cur;3308goto rtn;3309}33103311if (!cpp_demangle_read_name(ddata))3312goto clean;33133314is_builtin = 0;3315rtn:33163317type_str = vector_str_substr(output, p_idx, output->size - 1,3318&type_str_len);33193320if (is_builtin == 0) {3321if (!vector_str_find(&ddata->subst, type_str, type_str_len) &&3322!vector_str_push(&ddata->subst, type_str, type_str_len))3323goto clean;3324}33253326if (!skip_ref_qualifier &&3327!cpp_demangle_push_type_qualifier(ddata, &v, type_str))3328goto clean;33293330if (td)3331td->firstp = false;33323333free(type_str);3334free(exp_str);3335free(num_str);3336vector_type_qualifier_dest(&v);33373338return (1);3339clean:3340free(type_str);3341free(exp_str);3342free(num_str);3343vector_type_qualifier_dest(&v);33443345return (0);3346}33473348static int3349cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str)3350{3351struct vector_str *output;3352size_t i, p_idx, idx, type_len;3353char *type;33543355output = ddata->cur_output;33563357p_idx = output->size;33583359if (!cpp_demangle_read_type(ddata, NULL))3360return (0);33613362if ((type = vector_str_substr(output, p_idx, output->size - 1,3363&type_len)) == NULL)3364return (0);33653366idx = output->size;3367for (i = p_idx; i < idx; ++i) {3368if (!vector_str_pop(output)) {3369free(type);3370return (0);3371}3372}33733374*str = type;33753376return (1);3377}33783379/*3380* read unqualified-name, unqualified name are operator-name, ctor-dtor-name,3381* source-name3382*/3383static int3384cpp_demangle_read_uqname(struct cpp_demangle_data *ddata)3385{3386size_t len;33873388if (ddata == NULL || *ddata->cur == '\0')3389return (0);33903391/* operator name */3392switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {3393case SIMPLE_HASH('a', 'a'):3394/* operator && */3395if (!DEM_PUSH_STR(ddata, "operator&&"))3396return (0);3397ddata->cur += 2;3398return (1);33993400case SIMPLE_HASH('a', 'd'):3401/* operator & (unary) */3402if (!DEM_PUSH_STR(ddata, "operator&"))3403return (0);3404ddata->cur += 2;3405return (1);34063407case SIMPLE_HASH('a', 'n'):3408/* operator & */3409if (!DEM_PUSH_STR(ddata, "operator&"))3410return (0);3411ddata->cur += 2;3412return (1);34133414case SIMPLE_HASH('a', 'N'):3415/* operator &= */3416if (!DEM_PUSH_STR(ddata, "operator&="))3417return (0);3418ddata->cur += 2;3419return (1);34203421case SIMPLE_HASH('a', 'S'):3422/* operator = */3423if (!DEM_PUSH_STR(ddata, "operator="))3424return (0);3425ddata->cur += 2;3426return (1);34273428case SIMPLE_HASH('c', 'l'):3429/* operator () */3430if (!DEM_PUSH_STR(ddata, "operator()"))3431return (0);3432ddata->cur += 2;3433return (1);34343435case SIMPLE_HASH('c', 'm'):3436/* operator , */3437if (!DEM_PUSH_STR(ddata, "operator,"))3438return (0);3439ddata->cur += 2;3440return (1);34413442case SIMPLE_HASH('c', 'o'):3443/* operator ~ */3444if (!DEM_PUSH_STR(ddata, "operator~"))3445return (0);3446ddata->cur += 2;3447return (1);34483449case SIMPLE_HASH('c', 'v'):3450/* operator (cast) */3451if (!DEM_PUSH_STR(ddata, "operator(cast)"))3452return (0);3453ddata->cur += 2;3454return (cpp_demangle_read_type(ddata, NULL));34553456case SIMPLE_HASH('d', 'a'):3457/* operator delete [] */3458if (!DEM_PUSH_STR(ddata, "operator delete []"))3459return (0);3460ddata->cur += 2;3461return (1);34623463case SIMPLE_HASH('d', 'e'):3464/* operator * (unary) */3465if (!DEM_PUSH_STR(ddata, "operator*"))3466return (0);3467ddata->cur += 2;3468return (1);34693470case SIMPLE_HASH('d', 'l'):3471/* operator delete */3472if (!DEM_PUSH_STR(ddata, "operator delete"))3473return (0);3474ddata->cur += 2;3475return (1);34763477case SIMPLE_HASH('d', 'v'):3478/* operator / */3479if (!DEM_PUSH_STR(ddata, "operator/"))3480return (0);3481ddata->cur += 2;3482return (1);34833484case SIMPLE_HASH('d', 'V'):3485/* operator /= */3486if (!DEM_PUSH_STR(ddata, "operator/="))3487return (0);3488ddata->cur += 2;3489return (1);34903491case SIMPLE_HASH('e', 'o'):3492/* operator ^ */3493if (!DEM_PUSH_STR(ddata, "operator^"))3494return (0);3495ddata->cur += 2;3496return (1);34973498case SIMPLE_HASH('e', 'O'):3499/* operator ^= */3500if (!DEM_PUSH_STR(ddata, "operator^="))3501return (0);3502ddata->cur += 2;3503return (1);35043505case SIMPLE_HASH('e', 'q'):3506/* operator == */3507if (!DEM_PUSH_STR(ddata, "operator=="))3508return (0);3509ddata->cur += 2;3510return (1);35113512case SIMPLE_HASH('g', 'e'):3513/* operator >= */3514if (!DEM_PUSH_STR(ddata, "operator>="))3515return (0);3516ddata->cur += 2;3517return (1);35183519case SIMPLE_HASH('g', 't'):3520/* operator > */3521if (!DEM_PUSH_STR(ddata, "operator>"))3522return (0);3523ddata->cur += 2;3524return (1);35253526case SIMPLE_HASH('i', 'x'):3527/* operator [] */3528if (!DEM_PUSH_STR(ddata, "operator[]"))3529return (0);3530ddata->cur += 2;3531return (1);35323533case SIMPLE_HASH('l', 'e'):3534/* operator <= */3535if (!DEM_PUSH_STR(ddata, "operator<="))3536return (0);3537ddata->cur += 2;3538return (1);35393540case SIMPLE_HASH('l', 's'):3541/* operator << */3542if (!DEM_PUSH_STR(ddata, "operator<<"))3543return (0);3544ddata->cur += 2;3545return (1);35463547case SIMPLE_HASH('l', 'S'):3548/* operator <<= */3549if (!DEM_PUSH_STR(ddata, "operator<<="))3550return (0);3551ddata->cur += 2;3552return (1);35533554case SIMPLE_HASH('l', 't'):3555/* operator < */3556if (!DEM_PUSH_STR(ddata, "operator<"))3557return (0);3558ddata->cur += 2;3559return (1);35603561case SIMPLE_HASH('m', 'i'):3562/* operator - */3563if (!DEM_PUSH_STR(ddata, "operator-"))3564return (0);3565ddata->cur += 2;3566return (1);35673568case SIMPLE_HASH('m', 'I'):3569/* operator -= */3570if (!DEM_PUSH_STR(ddata, "operator-="))3571return (0);3572ddata->cur += 2;3573return (1);35743575case SIMPLE_HASH('m', 'l'):3576/* operator * */3577if (!DEM_PUSH_STR(ddata, "operator*"))3578return (0);3579ddata->cur += 2;3580return (1);35813582case SIMPLE_HASH('m', 'L'):3583/* operator *= */3584if (!DEM_PUSH_STR(ddata, "operator*="))3585return (0);3586ddata->cur += 2;3587return (1);35883589case SIMPLE_HASH('m', 'm'):3590/* operator -- */3591if (!DEM_PUSH_STR(ddata, "operator--"))3592return (0);3593ddata->cur += 2;3594return (1);35953596case SIMPLE_HASH('n', 'a'):3597/* operator new[] */3598if (!DEM_PUSH_STR(ddata, "operator new []"))3599return (0);3600ddata->cur += 2;3601return (1);36023603case SIMPLE_HASH('n', 'e'):3604/* operator != */3605if (!DEM_PUSH_STR(ddata, "operator!="))3606return (0);3607ddata->cur += 2;3608return (1);36093610case SIMPLE_HASH('n', 'g'):3611/* operator - (unary) */3612if (!DEM_PUSH_STR(ddata, "operator-"))3613return (0);3614ddata->cur += 2;3615return (1);36163617case SIMPLE_HASH('n', 't'):3618/* operator ! */3619if (!DEM_PUSH_STR(ddata, "operator!"))3620return (0);3621ddata->cur += 2;3622return (1);36233624case SIMPLE_HASH('n', 'w'):3625/* operator new */3626if (!DEM_PUSH_STR(ddata, "operator new"))3627return (0);3628ddata->cur += 2;3629return (1);36303631case SIMPLE_HASH('o', 'o'):3632/* operator || */3633if (!DEM_PUSH_STR(ddata, "operator||"))3634return (0);3635ddata->cur += 2;3636return (1);36373638case SIMPLE_HASH('o', 'r'):3639/* operator | */3640if (!DEM_PUSH_STR(ddata, "operator|"))3641return (0);3642ddata->cur += 2;3643return (1);36443645case SIMPLE_HASH('o', 'R'):3646/* operator |= */3647if (!DEM_PUSH_STR(ddata, "operator|="))3648return (0);3649ddata->cur += 2;3650return (1);36513652case SIMPLE_HASH('p', 'l'):3653/* operator + */3654if (!DEM_PUSH_STR(ddata, "operator+"))3655return (0);3656ddata->cur += 2;3657return (1);36583659case SIMPLE_HASH('p', 'L'):3660/* operator += */3661if (!DEM_PUSH_STR(ddata, "operator+="))3662return (0);3663ddata->cur += 2;3664return (1);36653666case SIMPLE_HASH('p', 'm'):3667/* operator ->* */3668if (!DEM_PUSH_STR(ddata, "operator->*"))3669return (0);3670ddata->cur += 2;3671return (1);36723673case SIMPLE_HASH('p', 'p'):3674/* operator ++ */3675if (!DEM_PUSH_STR(ddata, "operator++"))3676return (0);3677ddata->cur += 2;3678return (1);36793680case SIMPLE_HASH('p', 's'):3681/* operator + (unary) */3682if (!DEM_PUSH_STR(ddata, "operator+"))3683return (0);3684ddata->cur += 2;3685return (1);36863687case SIMPLE_HASH('p', 't'):3688/* operator -> */3689if (!DEM_PUSH_STR(ddata, "operator->"))3690return (0);3691ddata->cur += 2;3692return (1);36933694case SIMPLE_HASH('q', 'u'):3695/* operator ? */3696if (!DEM_PUSH_STR(ddata, "operator?"))3697return (0);3698ddata->cur += 2;3699return (1);37003701case SIMPLE_HASH('r', 'm'):3702/* operator % */3703if (!DEM_PUSH_STR(ddata, "operator%"))3704return (0);3705ddata->cur += 2;3706return (1);37073708case SIMPLE_HASH('r', 'M'):3709/* operator %= */3710if (!DEM_PUSH_STR(ddata, "operator%="))3711return (0);3712ddata->cur += 2;3713return (1);37143715case SIMPLE_HASH('r', 's'):3716/* operator >> */3717if (!DEM_PUSH_STR(ddata, "operator>>"))3718return (0);3719ddata->cur += 2;3720return (1);37213722case SIMPLE_HASH('r', 'S'):3723/* operator >>= */3724if (!DEM_PUSH_STR(ddata, "operator>>="))3725return (0);3726ddata->cur += 2;3727return (1);37283729case SIMPLE_HASH('r', 'z'):3730/* operator sizeof */3731if (!DEM_PUSH_STR(ddata, "operator sizeof "))3732return (0);3733ddata->cur += 2;3734return (1);37353736case SIMPLE_HASH('s', 'r'):3737/* scope resolution operator */3738if (!DEM_PUSH_STR(ddata, "scope resolution operator "))3739return (0);3740ddata->cur += 2;3741return (1);37423743case SIMPLE_HASH('s', 'v'):3744/* operator sizeof */3745if (!DEM_PUSH_STR(ddata, "operator sizeof "))3746return (0);3747ddata->cur += 2;3748return (1);3749}37503751/* vendor extened operator */3752if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) {3753if (!DEM_PUSH_STR(ddata, "vendor extened operator "))3754return (0);3755if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1))3756return (0);3757ddata->cur += 2;3758return (cpp_demangle_read_sname(ddata));3759}37603761/* ctor-dtor-name */3762switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {3763case SIMPLE_HASH('C', '1'):3764case SIMPLE_HASH('C', '2'):3765case SIMPLE_HASH('C', '3'):3766if (ddata->last_sname == NULL)3767return (0);3768if ((len = strlen(ddata->last_sname)) == 0)3769return (0);3770if (!DEM_PUSH_STR(ddata, "::"))3771return (0);3772if (!cpp_demangle_push_str(ddata, ddata->last_sname, len))3773return (0);3774ddata->cur +=2;3775return (1);37763777case SIMPLE_HASH('D', '0'):3778case SIMPLE_HASH('D', '1'):3779case SIMPLE_HASH('D', '2'):3780if (ddata->last_sname == NULL)3781return (0);3782if ((len = strlen(ddata->last_sname)) == 0)3783return (0);3784if (!DEM_PUSH_STR(ddata, "::~"))3785return (0);3786if (!cpp_demangle_push_str(ddata, ddata->last_sname, len))3787return (0);3788ddata->cur +=2;3789return (1);3790}37913792/* source name */3793if (ELFTC_ISDIGIT(*ddata->cur) != 0)3794return (cpp_demangle_read_sname(ddata));37953796/* local source name */3797if (*ddata->cur == 'L')3798return (cpp_demangle_local_source_name(ddata));37993800return (1);3801}38023803/*3804* Read local source name.3805*3806* References:3807* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=317753808* http://gcc.gnu.org/viewcvs?view=rev&revision=1244673809*/3810static int3811cpp_demangle_local_source_name(struct cpp_demangle_data *ddata)3812{3813/* L */3814if (ddata == NULL || *ddata->cur != 'L')3815return (0);3816++ddata->cur;38173818/* source name */3819if (!cpp_demangle_read_sname(ddata))3820return (0);38213822/* discriminator */3823if (*ddata->cur == '_') {3824++ddata->cur;3825while (ELFTC_ISDIGIT(*ddata->cur) != 0)3826++ddata->cur;3827}38283829return (1);3830}38313832static int3833cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata)3834{38353836if (ddata == NULL)3837return (0);38383839if (!DEM_PUSH_STR(ddata, "offset : "))3840return (0);38413842if (!cpp_demangle_read_offset_number(ddata))3843return (0);38443845if (!DEM_PUSH_STR(ddata, "virtual offset : "))3846return (0);38473848return (!cpp_demangle_read_offset_number(ddata));3849}38503851/*3852* Decode floating point representation to string3853* Return new allocated string or NULL3854*3855* Todo3856* Replace these functions to macro.3857*/3858static char *3859decode_fp_to_double(const char *p, size_t len)3860{3861double f;3862size_t rtn_len, limit, i;3863int byte;3864char *rtn;38653866if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(double))3867return (NULL);38683869memset(&f, 0, sizeof(double));38703871for (i = 0; i < len / 2; ++i) {3872byte = hex_to_dec(p[len - i * 2 - 1]) +3873hex_to_dec(p[len - i * 2 - 2]) * 16;38743875if (byte < 0 || byte > 255)3876return (NULL);38773878#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3879((unsigned char *)&f)[i] = (unsigned char)(byte);3880#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3881((unsigned char *)&f)[sizeof(double) - i - 1] =3882(unsigned char)(byte);3883#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3884}38853886rtn_len = 64;3887limit = 0;3888again:3889if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)3890return (NULL);38913892if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) {3893free(rtn);3894if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)3895return (NULL);3896rtn_len *= BUFFER_GROWFACTOR;3897goto again;3898}38993900return rtn;3901}39023903static char *3904decode_fp_to_float(const char *p, size_t len)3905{3906size_t i, rtn_len, limit;3907float f;3908int byte;3909char *rtn;39103911if (p == NULL || len == 0 || len % 2 != 0 || len / 2 > sizeof(float))3912return (NULL);39133914memset(&f, 0, sizeof(float));39153916for (i = 0; i < len / 2; ++i) {3917byte = hex_to_dec(p[len - i * 2 - 1]) +3918hex_to_dec(p[len - i * 2 - 2]) * 16;3919if (byte < 0 || byte > 255)3920return (NULL);3921#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3922((unsigned char *)&f)[i] = (unsigned char)(byte);3923#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3924((unsigned char *)&f)[sizeof(float) - i - 1] =3925(unsigned char)(byte);3926#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3927}39283929rtn_len = 64;3930limit = 0;3931again:3932if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)3933return (NULL);39343935if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) {3936free(rtn);3937if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)3938return (NULL);3939rtn_len *= BUFFER_GROWFACTOR;3940goto again;3941}39423943return rtn;3944}39453946static char *3947decode_fp_to_float128(const char *p, size_t len)3948{3949long double f;3950size_t rtn_len, limit, i;3951int byte;3952unsigned char buf[FLOAT_QUADRUPLE_BYTES];3953char *rtn;39543955switch(sizeof(long double)) {3956case FLOAT_QUADRUPLE_BYTES:3957return (decode_fp_to_long_double(p, len));3958case FLOAT_EXTENED_BYTES:3959if (p == NULL || len == 0 || len % 2 != 0 ||3960len / 2 > FLOAT_QUADRUPLE_BYTES)3961return (NULL);39623963memset(buf, 0, FLOAT_QUADRUPLE_BYTES);39643965for (i = 0; i < len / 2; ++i) {3966byte = hex_to_dec(p[len - i * 2 - 1]) +3967hex_to_dec(p[len - i * 2 - 2]) * 16;3968if (byte < 0 || byte > 255)3969return (NULL);3970#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3971buf[i] = (unsigned char)(byte);3972#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3973buf[FLOAT_QUADRUPLE_BYTES - i -1] =3974(unsigned char)(byte);3975#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3976}3977memset(&f, 0, FLOAT_EXTENED_BYTES);39783979#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN3980memcpy(&f, buf, FLOAT_EXTENED_BYTES);3981#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */3982memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES);3983#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */39843985rtn_len = 256;3986limit = 0;3987again:3988if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)3989return (NULL);39903991if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {3992free(rtn);3993if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)3994return (NULL);3995rtn_len *= BUFFER_GROWFACTOR;3996goto again;3997}39983999return (rtn);4000default:4001return (NULL);4002}4003}40044005static char *4006decode_fp_to_float80(const char *p, size_t len)4007{4008long double f;4009size_t rtn_len, limit, i;4010int byte;4011unsigned char buf[FLOAT_EXTENED_BYTES];4012char *rtn;40134014switch(sizeof(long double)) {4015case FLOAT_QUADRUPLE_BYTES:4016if (p == NULL || len == 0 || len % 2 != 0 ||4017len / 2 > FLOAT_EXTENED_BYTES)4018return (NULL);40194020memset(buf, 0, FLOAT_EXTENED_BYTES);40214022for (i = 0; i < len / 2; ++i) {4023byte = hex_to_dec(p[len - i * 2 - 1]) +4024hex_to_dec(p[len - i * 2 - 2]) * 16;40254026if (byte < 0 || byte > 255)4027return (NULL);40284029#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN4030buf[i] = (unsigned char)(byte);4031#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */4032buf[FLOAT_EXTENED_BYTES - i -1] =4033(unsigned char)(byte);4034#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */4035}40364037memset(&f, 0, FLOAT_QUADRUPLE_BYTES);40384039#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN4040memcpy(&f, buf, FLOAT_EXTENED_BYTES);4041#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */4042memcpy((unsigned char *)(&f) + 6, buf, FLOAT_EXTENED_BYTES);4043#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */40444045rtn_len = 256;4046limit = 0;4047again:4048if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)4049return (NULL);40504051if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {4052free(rtn);4053if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)4054return (NULL);4055rtn_len *= BUFFER_GROWFACTOR;4056goto again;4057}40584059return (rtn);4060case FLOAT_EXTENED_BYTES:4061return (decode_fp_to_long_double(p, len));4062default:4063return (NULL);4064}4065}40664067static char *4068decode_fp_to_long_double(const char *p, size_t len)4069{4070long double f;4071size_t rtn_len, limit, i;4072int byte;4073char *rtn;40744075if (p == NULL || len == 0 || len % 2 != 0 ||4076len / 2 > sizeof(long double))4077return (NULL);40784079memset(&f, 0, sizeof(long double));40804081for (i = 0; i < len / 2; ++i) {4082byte = hex_to_dec(p[len - i * 2 - 1]) +4083hex_to_dec(p[len - i * 2 - 2]) * 16;40844085if (byte < 0 || byte > 255)4086return (NULL);40874088#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN4089((unsigned char *)&f)[i] = (unsigned char)(byte);4090#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */4091((unsigned char *)&f)[sizeof(long double) - i - 1] =4092(unsigned char)(byte);4093#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */4094}40954096rtn_len = 256;4097limit = 0;4098again:4099if ((rtn = malloc(sizeof(char) * rtn_len)) == NULL)4100return (NULL);41014102if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {4103free(rtn);4104if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)4105return (NULL);4106rtn_len *= BUFFER_GROWFACTOR;4107goto again;4108}41094110return (rtn);4111}41124113/* Simple hex to integer function used by decode_to_* function. */4114static int4115hex_to_dec(char c)4116{41174118switch (c) {4119case '0':4120return (0);4121case '1':4122return (1);4123case '2':4124return (2);4125case '3':4126return (3);4127case '4':4128return (4);4129case '5':4130return (5);4131case '6':4132return (6);4133case '7':4134return (7);4135case '8':4136return (8);4137case '9':4138return (9);4139case 'a':4140return (10);4141case 'b':4142return (11);4143case 'c':4144return (12);4145case 'd':4146return (13);4147case 'e':4148return (14);4149case 'f':4150return (15);4151default:4152return (-1);4153}4154}41554156/**4157* @brief Test input string is mangled by IA-64 C++ ABI style.4158*4159* Test string heads with "_Z" or "_GLOBAL__I_".4160* @return Return 0 at false.4161*/4162bool4163is_cpp_mangled_gnu3(const char *org)4164{4165size_t len;41664167len = strlen(org);4168return ((len > 2 && *org == '_' && *(org + 1) == 'Z') ||4169(len > 11 && !strncmp(org, "_GLOBAL__I_", 11)));4170}41714172static void4173vector_read_cmd_dest(struct vector_read_cmd *v)4174{41754176if (v == NULL)4177return;41784179free(v->r_container);4180}41814182static struct read_cmd_item *4183vector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst)4184{4185int i;41864187if (v == NULL || dst == READ_FAIL)4188return (NULL);41894190for (i = (int) v->size - 1; i >= 0; i--)4191if (v->r_container[i].cmd == dst)4192return (&v->r_container[i]);41934194return (NULL);4195}41964197static int4198vector_read_cmd_init(struct vector_read_cmd *v)4199{42004201if (v == NULL)4202return (0);42034204v->size = 0;4205v->capacity = VECTOR_DEF_CAPACITY;42064207if ((v->r_container = malloc(sizeof(*v->r_container) * v->capacity))4208== NULL)4209return (0);42104211return (1);4212}42134214static int4215vector_read_cmd_pop(struct vector_read_cmd *v)4216{42174218if (v == NULL || v->size == 0)4219return (0);42204221--v->size;4222v->r_container[v->size].cmd = READ_FAIL;4223v->r_container[v->size].data = NULL;42244225return (1);4226}42274228static int4229vector_read_cmd_push(struct vector_read_cmd *v, enum read_cmd cmd, void *data)4230{4231struct read_cmd_item *tmp_r_ctn;4232size_t tmp_cap;4233size_t i;42344235if (v == NULL)4236return (0);42374238if (v->size == v->capacity) {4239tmp_cap = BUFFER_GROW(v->capacity);4240if ((tmp_r_ctn = malloc(sizeof(*tmp_r_ctn) * tmp_cap)) == NULL)4241return (0);4242for (i = 0; i < v->size; ++i)4243tmp_r_ctn[i] = v->r_container[i];4244free(v->r_container);4245v->r_container = tmp_r_ctn;4246v->capacity = tmp_cap;4247}42484249v->r_container[v->size].cmd = cmd;4250v->r_container[v->size].data = data;4251++v->size;42524253return (1);4254}42554256static void4257vector_type_qualifier_dest(struct vector_type_qualifier *v)4258{42594260if (v == NULL)4261return;42624263free(v->q_container);4264vector_str_dest(&v->ext_name);4265}42664267/* size, capacity, ext_name */4268static int4269vector_type_qualifier_init(struct vector_type_qualifier *v)4270{42714272if (v == NULL)4273return (0);42744275v->size = 0;4276v->capacity = VECTOR_DEF_CAPACITY;42774278if ((v->q_container = malloc(sizeof(enum type_qualifier) * v->capacity))4279== NULL)4280return (0);42814282assert(v->q_container != NULL);42834284if (!vector_str_init(&v->ext_name)) {4285free(v->q_container);4286return (0);4287}42884289return (1);4290}42914292static int4293vector_type_qualifier_push(struct vector_type_qualifier *v,4294enum type_qualifier t)4295{4296enum type_qualifier *tmp_ctn;4297size_t tmp_cap;4298size_t i;42994300if (v == NULL)4301return (0);43024303if (v->size == v->capacity) {4304tmp_cap = BUFFER_GROW(v->capacity);4305if ((tmp_ctn = malloc(sizeof(enum type_qualifier) * tmp_cap))4306== NULL)4307return (0);4308for (i = 0; i < v->size; ++i)4309tmp_ctn[i] = v->q_container[i];4310free(v->q_container);4311v->q_container = tmp_ctn;4312v->capacity = tmp_cap;4313}43144315v->q_container[v->size] = t;4316++v->size;43174318return (1);4319}432043214322