2023-07-07 17:26:07 +00:00
|
|
|
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
|
|
|
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
|
|
|
╞══════════════════════════════════════════════════════════════════════════════╡
|
|
|
|
│ Copyright (c) 2007 Hyogeol Lee <hyogeollee@gmail.com> │
|
|
|
|
│ Copyright (c) 2015-2017 Kai Wang <kaiwang27@gmail.com> │
|
2024-05-07 10:06:12 +00:00
|
|
|
│ Copyright (c) 2024 Justine Tunney <jtunney@gmail.com> │
|
2023-07-07 17:26:07 +00:00
|
|
|
│ All rights reserved. │
|
|
|
|
│ │
|
|
|
|
│ Redistribution and use in source and binary forms, with or without │
|
|
|
|
│ modification, are permitted provided that the following conditions │
|
|
|
|
│ are met: │
|
|
|
|
│ 1. Redistributions of source code must retain the above copyright │
|
|
|
|
│ notice, this list of conditions and the following disclaimer │
|
|
|
|
│ in this position and unchanged. │
|
|
|
|
│ 2. Redistributions in binary form must reproduce the above copyright │
|
|
|
|
│ notice, this list of conditions and the following disclaimer in the │
|
|
|
|
│ documentation and/or other materials provided with the distribution. │
|
|
|
|
│ │
|
|
|
|
│ THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR │
|
|
|
|
│ IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES │
|
|
|
|
│ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. │
|
|
|
|
│ IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, │
|
|
|
|
│ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT │
|
|
|
|
│ NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, │
|
|
|
|
│ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY │
|
|
|
|
│ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT │
|
|
|
|
│ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF │
|
|
|
|
│ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. │
|
|
|
|
╚─────────────────────────────────────────────────────────────────────────────*/
|
2024-06-02 02:57:32 +00:00
|
|
|
#include <stdalign.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <stddef.h>
|
|
|
|
#include <stdint.h>
|
2023-07-07 17:26:07 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
__notice(cpp_demangle_notice, "\
|
|
|
|
Cosmopolitan FreeBSD libcxxrt C++ Demangle (BSD-2)\n\
|
Release Cosmopolitan v3.3
This change upgrades to GCC 12.3 and GNU binutils 2.42. The GNU linker
appears to have changed things so that only a single de-duplicated str
table is present in the binary, and it gets placed wherever the linker
wants, regardless of what the linker script says. To cope with that we
need to stop using .ident to embed licenses. As such, this change does
significant work to revamp how third party licenses are defined in the
codebase, using `.section .notice,"aR",@progbits`.
This new GCC 12.3 toolchain has support for GNU indirect functions. It
lets us support __target_clones__ for the first time. This is used for
optimizing the performance of libc string functions such as strlen and
friends so far on x86, by ensuring AVX systems favor a second codepath
that uses VEX encoding. It shaves some latency off certain operations.
It's a useful feature to have for scientific computing for the reasons
explained by the test/libcxx/openmp_test.cc example which compiles for
fifteen different microarchitectures. Thanks to the upgrades, it's now
also possible to use newer instruction sets, such as AVX512FP16, VNNI.
Cosmo now uses the %gs register on x86 by default for TLS. Doing it is
helpful for any program that links `cosmo_dlopen()`. Such programs had
to recompile their binaries at startup to change the TLS instructions.
That's not great, since it means every page in the executable needs to
be faulted. The work of rewriting TLS-related x86 opcodes, is moved to
fixupobj.com instead. This is great news for MacOS x86 users, since we
previously needed to morph the binary every time for that platform but
now that's no longer necessary. The only platforms where we need fixup
of TLS x86 opcodes at runtime are now Windows, OpenBSD, and NetBSD. On
Windows we morph TLS to point deeper into the TIB, based on a TlsAlloc
assignment, and on OpenBSD/NetBSD we morph %gs back into %fs since the
kernels do not allow us to specify a value for the %gs register.
OpenBSD users are now required to use APE Loader to run Cosmo binaries
and assimilation is no longer possible. OpenBSD kernel needs to change
to allow programs to specify a value for the %gs register, or it needs
to stop marking executable pages loaded by the kernel as mimmutable().
This release fixes __constructor__, .ctor, .init_array, and lastly the
.preinit_array so they behave the exact same way as glibc.
We no longer use hex constants to define math.h symbols like M_PI.
2024-02-20 19:12:09 +00:00
|
|
|
Copyright (c) 2007 Hyogeol Lee <hyogeollee@gmail.com>\n\
|
2024-05-07 10:06:12 +00:00
|
|
|
Copyright (c) 2015-2017 Kai Wang <kaiwang27@gmail.com>\n\
|
|
|
|
Copyright (c) 2024 Justine Tunney <jtunney@gmail.com>");
|
2024-05-26 13:03:50 +00:00
|
|
|
// https://sourceforge.net/p/elftoolchain/code/HEAD/tree/trunk/libelftc/libelftc_dem_gnu3.c
|
2023-07-07 17:26:07 +00:00
|
|
|
// https://github.com/freebsd/freebsd-src/blob/2176c9ab71c85efd90a6c7af4a9e04fe8e3d49ca/contrib/libcxxrt/libelftc_dem_gnu3.c
|
2024-05-08 00:36:17 +00:00
|
|
|
// clang-format off
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
/**
|
2023-07-07 17:26:07 +00:00
|
|
|
* @file demangle.c
|
2023-07-03 04:08:52 +00:00
|
|
|
* @brief Decode IA-64 C++ ABI style implementation.
|
|
|
|
*
|
|
|
|
* IA-64 standard ABI(Itanium C++ ABI) references.
|
|
|
|
*
|
2024-06-02 02:57:32 +00:00
|
|
|
* http://www.codesourcery.com/cxx-abi/abi.html#mangling
|
2023-07-03 04:08:52 +00:00
|
|
|
* http://www.codesourcery.com/cxx-abi/abi-mangling.html
|
|
|
|
*/
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
#define DEMANGLE_NO_FLOATING_POINT
|
|
|
|
|
|
|
|
#define ASSERT(x) (void)0
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
#define BUFFER_GROWFACTOR 2
|
|
|
|
#define BUFFER_GROW(x) (((x) + 1) * BUFFER_GROWFACTOR)
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
#define ELFTC_FAILURE 0
|
|
|
|
#define ELFTC_ISDIGIT(C) ('0' <= (C) && (C) <= '9')
|
|
|
|
#define ELFTC_SUCCESS 1
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
#define VECTOR_DEF_CAPACITY 1
|
|
|
|
|
|
|
|
typedef unsigned short index_t;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
struct stack_str {
|
|
|
|
char *str;
|
|
|
|
int len;
|
|
|
|
int cap;
|
|
|
|
char buf[128];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct vector_str {
|
2024-06-02 02:57:32 +00:00
|
|
|
int size;
|
|
|
|
int capacity;
|
|
|
|
index_t *container;
|
2024-05-07 10:06:12 +00:00
|
|
|
};
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
enum type_qualifier {
|
2024-05-07 10:06:12 +00:00
|
|
|
TYPE_PTR,
|
|
|
|
TYPE_REF,
|
|
|
|
TYPE_CMX,
|
|
|
|
TYPE_IMG,
|
|
|
|
TYPE_EXT,
|
|
|
|
TYPE_RST,
|
|
|
|
TYPE_VAT,
|
|
|
|
TYPE_CST,
|
|
|
|
TYPE_VEC,
|
|
|
|
TYPE_RREF
|
2023-07-03 04:08:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct vector_type_qualifier {
|
2024-06-02 02:57:32 +00:00
|
|
|
int size, capacity;
|
2023-07-03 04:08:52 +00:00
|
|
|
enum type_qualifier *q_container;
|
|
|
|
struct vector_str ext_name;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum read_cmd {
|
2024-05-07 10:06:12 +00:00
|
|
|
READ_FAIL,
|
|
|
|
READ_NEST,
|
|
|
|
READ_TMPL,
|
|
|
|
READ_EXPR,
|
|
|
|
READ_EXPL,
|
|
|
|
READ_LOCAL,
|
|
|
|
READ_TYPE,
|
|
|
|
READ_FUNC,
|
|
|
|
READ_PTRMEM
|
2023-07-03 04:08:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct read_cmd_item {
|
|
|
|
enum read_cmd cmd;
|
|
|
|
void *data;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct vector_read_cmd {
|
2024-06-02 02:57:32 +00:00
|
|
|
int size, capacity;
|
2023-07-03 04:08:52 +00:00
|
|
|
struct read_cmd_item *r_container;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum push_qualifier {
|
|
|
|
PUSH_ALL_QUALIFIER,
|
|
|
|
PUSH_CV_QUALIFIER,
|
|
|
|
PUSH_NON_CV_QUALIFIER,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct cpp_demangle_data {
|
2024-06-02 02:57:32 +00:00
|
|
|
int hoff;
|
|
|
|
index_t free;
|
2024-05-07 10:06:12 +00:00
|
|
|
uintptr_t heap;
|
|
|
|
struct vector_str output; /* output string vector */
|
|
|
|
struct vector_str subst; /* substitution string vector */
|
|
|
|
struct vector_str tmpl;
|
|
|
|
struct vector_str class_type;
|
|
|
|
struct vector_str *cur_output; /* ptr to current output vec */
|
|
|
|
struct vector_read_cmd cmd;
|
|
|
|
bool mem_rst; /* restrict member function */
|
|
|
|
bool mem_vat; /* volatile member function */
|
|
|
|
bool mem_cst; /* const member function */
|
|
|
|
bool mem_ref; /* lvalue-ref member func */
|
|
|
|
bool mem_rref; /* rvalue-ref member func */
|
|
|
|
bool is_tmpl; /* template args */
|
|
|
|
bool is_functype; /* function type */
|
|
|
|
bool ref_qualifier; /* ref qualifier */
|
|
|
|
enum type_qualifier ref_qualifier_type; /* ref qualifier type */
|
|
|
|
enum push_qualifier push_qualifier; /* which qualifiers to push */
|
|
|
|
int func_type;
|
|
|
|
const char *cur; /* current mangled name ptr */
|
|
|
|
const char *last_sname; /* last source name */
|
2023-07-03 04:08:52 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
struct type_delimit {
|
|
|
|
bool paren;
|
|
|
|
bool firstp;
|
|
|
|
};
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
#define CPP_DEMANGLE_TRY_LIMIT 128
|
|
|
|
#define FLOAT_SPRINTF_TRY_LIMIT 5
|
|
|
|
#define FLOAT_QUADRUPLE_BYTES 16
|
|
|
|
#define FLOAT_EXTENED_BYTES 10
|
|
|
|
|
|
|
|
#define SIMPLE_HASH(x, y) (64 * x + y)
|
2024-06-02 02:57:32 +00:00
|
|
|
#define DEM_PUSH_STR(d, s) cpp_demangle_push_str((d), (s), demangle_strlen(s))
|
|
|
|
#define VEC_PUSH_STR(d, s) vector_str_push(ddata, (d), (s), demangle_strlen(s))
|
|
|
|
#define VEC_STR(d, v, i) ((char *)((d)->heap + (v)->container[i]))
|
2024-05-26 13:03:50 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
static int cpp_demangle_read_encoding(struct cpp_demangle_data *);
|
|
|
|
static int cpp_demangle_read_expr_primary(struct cpp_demangle_data *);
|
|
|
|
static int cpp_demangle_read_expression(struct cpp_demangle_data *);
|
|
|
|
static int cpp_demangle_read_function(struct cpp_demangle_data *, int *,
|
|
|
|
struct vector_type_qualifier *);
|
|
|
|
static int cpp_demangle_read_name(struct cpp_demangle_data *);
|
|
|
|
static int cpp_demangle_read_name_flat(struct cpp_demangle_data *, char **);
|
|
|
|
static int cpp_demangle_read_sname(struct cpp_demangle_data *);
|
|
|
|
static int cpp_demangle_read_subst(struct cpp_demangle_data *);
|
|
|
|
static int cpp_demangle_read_type(struct cpp_demangle_data *,
|
|
|
|
struct type_delimit *);
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged size_t
|
|
|
|
demangle_strlen(const char *s)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-06-02 02:57:32 +00:00
|
|
|
size_t n = 0;
|
|
|
|
while (*s++)
|
|
|
|
++n;
|
|
|
|
return n;
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged char *
|
|
|
|
demangle_stpcpy(char *d, const char *s)
|
|
|
|
{
|
|
|
|
size_t i = 0;
|
|
|
|
for (;;) {
|
|
|
|
if (!(d[i] = s[i]))
|
|
|
|
return d + i;
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged void *
|
|
|
|
demangle_mempcpy(void *a, const void *b, size_t n)
|
|
|
|
{
|
|
|
|
char *d = a;
|
|
|
|
const char *s = b;
|
|
|
|
while (n--)
|
|
|
|
*d++ = *s++;
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged void *
|
|
|
|
demangle_memcpy(void *a, const void *b, size_t n)
|
|
|
|
{
|
|
|
|
demangle_mempcpy(a, b, n);
|
|
|
|
return a;
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged int
|
|
|
|
demangle_strncmp(const char *a, const char *b, size_t n)
|
|
|
|
{
|
|
|
|
size_t i = 0;
|
|
|
|
if (!n-- || a == b)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
while (i < n && a[i] == b[i] && b[i])
|
|
|
|
++i;
|
|
|
|
return (a[i] & 0xff) - (b[i] & 0xff);
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged int
|
|
|
|
demangle_memcmp(const void *a, const void *b, size_t n)
|
|
|
|
{
|
|
|
|
int c;
|
|
|
|
const unsigned char *p, *q;
|
|
|
|
if ((p = a) == (q = b) || !n)
|
|
|
|
return 0;
|
|
|
|
if ((c = *p - *q))
|
|
|
|
return c;
|
|
|
|
for (; n; ++p, ++q, --n)
|
|
|
|
if ((c = *p - *q))
|
|
|
|
return c;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged void
|
|
|
|
demangle_strlcpy(char *dst, const char *src, size_t dsize)
|
|
|
|
{
|
|
|
|
size_t remain;
|
|
|
|
if ((remain = dsize))
|
|
|
|
while (--remain)
|
|
|
|
if (!(*dst++ = *src++))
|
|
|
|
break;
|
|
|
|
if (!remain && dsize)
|
|
|
|
*dst = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged long
|
|
|
|
demangle_strtol(const char *s, int base)
|
|
|
|
{
|
|
|
|
static const uint8_t base36[80] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 0, 0,
|
|
|
|
0, 0, 0, 0, 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
|
|
|
|
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 0, 0, 0,
|
|
|
|
0, 0, 0, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
|
|
|
|
25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 0, 0, 0, 0, 0 };
|
|
|
|
int c;
|
|
|
|
long x = 0;
|
|
|
|
while ((c = *s++ & 255) < 128 && c - '0' >= 0 &&
|
|
|
|
(c = base36[c - '0']) && --c < base)
|
|
|
|
x = x * base + c;
|
|
|
|
return x;
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged char *
|
|
|
|
demangle_strstr(const char *haystack, const char *needle)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
if (haystack == needle || !*needle)
|
|
|
|
return (void *)haystack;
|
|
|
|
for (;;) {
|
|
|
|
for (i = 0;; ++i) {
|
|
|
|
if (!needle[i])
|
|
|
|
return (/*unconst*/ char *)haystack;
|
|
|
|
if (!haystack[i])
|
|
|
|
break;
|
|
|
|
if (needle[i] != haystack[i])
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!*haystack++)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged bool
|
|
|
|
demangle_startswith(const char *s, const char *prefix)
|
|
|
|
{
|
|
|
|
for (;;) {
|
|
|
|
if (!*prefix)
|
|
|
|
return true;
|
|
|
|
if (!*s)
|
|
|
|
return false;
|
|
|
|
if (*s++ != *prefix++)
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged char *
|
|
|
|
demangle_utoa(char *p, unsigned long long x)
|
|
|
|
{
|
|
|
|
char t;
|
|
|
|
size_t i, a, b;
|
|
|
|
i = 0;
|
|
|
|
do {
|
|
|
|
p[i++] = x % 10 + '0';
|
|
|
|
x = x / 10;
|
|
|
|
} while (x > 0);
|
|
|
|
p[i] = '\0';
|
|
|
|
if (i) {
|
|
|
|
for (a = 0, b = i - 1; a < b; ++a, --b) {
|
|
|
|
t = p[a];
|
|
|
|
p[a] = p[b];
|
|
|
|
p[b] = t;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return p + i;
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged char *
|
|
|
|
demangle_itoa(char *p, long long x)
|
|
|
|
{
|
|
|
|
if (x < 0)
|
|
|
|
*p++ = '-', x = -(unsigned long long)x;
|
|
|
|
return demangle_utoa(p, x);
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged void
|
|
|
|
demangle_free(struct cpp_demangle_data *h, void *ptr)
|
|
|
|
{
|
|
|
|
index_t base;
|
|
|
|
uintptr_t mem;
|
|
|
|
if (ptr) {
|
|
|
|
mem = (uintptr_t)ptr;
|
|
|
|
base = mem - h->heap;
|
|
|
|
if (base - sizeof(index_t) == h->hoff) {
|
|
|
|
h->hoff += ((index_t *)mem)[-1];
|
|
|
|
} else {
|
|
|
|
*(index_t *)mem = h->free;
|
|
|
|
h->free = base;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged void *
|
|
|
|
demangle_malloc(struct cpp_demangle_data *h, int a, int n)
|
|
|
|
{
|
|
|
|
uintptr_t ptr;
|
|
|
|
int next, next2;
|
|
|
|
index_t *link, *link2;
|
|
|
|
|
|
|
|
/* Roundup size. */
|
|
|
|
n += sizeof(index_t) - 1;
|
|
|
|
n &= -sizeof(index_t);
|
|
|
|
n += a - 1;
|
|
|
|
n &= -a;
|
|
|
|
|
|
|
|
/* Try free list. */
|
|
|
|
next = h->free;
|
|
|
|
link = &h->free;
|
|
|
|
while (next) {
|
|
|
|
next2 = *(index_t *)(h->heap + next);
|
|
|
|
link2 = (index_t *)(h->heap + next);
|
|
|
|
if (!(next & (a - 1)) &&
|
|
|
|
n <= ((index_t *)(h->heap + next))[-1]) {
|
|
|
|
*link = next2;
|
|
|
|
return (void *)(h->heap + next);
|
|
|
|
}
|
|
|
|
next = next2;
|
|
|
|
link = link2;
|
2024-05-07 10:06:12 +00:00
|
|
|
}
|
2024-06-02 02:57:32 +00:00
|
|
|
|
|
|
|
/* Allocate new memory. */
|
|
|
|
h->hoff -= n;
|
|
|
|
h->hoff &= -a;
|
|
|
|
h->hoff &= -sizeof(index_t);
|
|
|
|
if (h->hoff < sizeof(index_t))
|
|
|
|
return 0;
|
|
|
|
ptr = h->heap + h->hoff;
|
|
|
|
h->hoff -= sizeof(index_t);
|
|
|
|
((index_t *)ptr)[-1] = n;
|
2024-05-07 10:06:12 +00:00
|
|
|
return (void *)ptr;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged char *
|
|
|
|
demangle_strdup(struct cpp_demangle_data *h, const char *s)
|
2024-05-07 10:06:12 +00:00
|
|
|
{
|
|
|
|
char *d = 0;
|
|
|
|
if (s) {
|
2024-06-02 02:57:32 +00:00
|
|
|
size_t n = demangle_strlen(s) + 1;
|
|
|
|
if ((d = (char *)demangle_malloc(h, 1, n)))
|
|
|
|
demangle_memcpy(d, s, n);
|
2024-05-07 10:06:12 +00:00
|
|
|
}
|
|
|
|
return d;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged void
|
|
|
|
vector_str_dest(struct cpp_demangle_data *h, struct vector_str *v)
|
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
if (!v)
|
|
|
|
return;
|
|
|
|
for (i = 0; i < v->size; ++i)
|
|
|
|
demangle_free(h, VEC_STR(h, v, i));
|
|
|
|
demangle_free(h, v->container);
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged void
|
|
|
|
vector_read_cmd_dest(struct cpp_demangle_data *h, struct vector_read_cmd *v)
|
|
|
|
{
|
|
|
|
if (!v)
|
|
|
|
return;
|
|
|
|
demangle_free(h, v->r_container);
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged void
|
|
|
|
cpp_demangle_data_dest(struct cpp_demangle_data *d)
|
|
|
|
{
|
|
|
|
if (!d)
|
|
|
|
return;
|
|
|
|
vector_read_cmd_dest(d, &d->cmd);
|
|
|
|
vector_str_dest(d, &d->class_type);
|
|
|
|
vector_str_dest(d, &d->tmpl);
|
|
|
|
vector_str_dest(d, &d->subst);
|
|
|
|
vector_str_dest(d, &d->output);
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged void
|
|
|
|
vector_type_qualifier_dest(struct cpp_demangle_data *d,
|
|
|
|
struct vector_type_qualifier *v)
|
|
|
|
{
|
|
|
|
if (!v)
|
|
|
|
return;
|
|
|
|
demangle_free(d, v->q_container);
|
|
|
|
vector_str_dest(d, &v->ext_name);
|
|
|
|
}
|
|
|
|
|
|
|
|
static privileged void
|
2024-05-07 10:06:12 +00:00
|
|
|
stack_str_init(struct stack_str *ss)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
ss->str = ss->buf;
|
|
|
|
ss->buf[0] = 0;
|
|
|
|
ss->len = 0;
|
|
|
|
ss->cap = sizeof(ss->buf);
|
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged bool
|
2024-05-07 10:06:12 +00:00
|
|
|
stack_str_append(struct cpp_demangle_data *h, struct stack_str *ss,
|
|
|
|
const char *str, size_t len)
|
|
|
|
{
|
|
|
|
int len2 = ss->len + len;
|
|
|
|
int need = len2 + 1;
|
|
|
|
if (need > ss->cap) {
|
|
|
|
int cap2;
|
|
|
|
char *str2;
|
|
|
|
cap2 = need + (ss->cap >> 1);
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(str2 = (char *)demangle_malloc(h, 1, cap2)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return false;
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_memcpy(str2, ss->str, ss->len);
|
2024-05-07 10:06:12 +00:00
|
|
|
ss->str = str2;
|
|
|
|
ss->cap = cap2;
|
|
|
|
}
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_memcpy(ss->str + ss->len, str, len);
|
2024-05-07 10:06:12 +00:00
|
|
|
ss->str[len2] = 0;
|
|
|
|
ss->len = len2;
|
|
|
|
return true;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
#define stack_str_append_str(h, ss, s) \
|
|
|
|
stack_str_append(h, ss, s, demangle_strlen(s))
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged size_t
|
|
|
|
get_demangle_strlen_sum(struct cpp_demangle_data *h, const struct vector_str *v)
|
2024-05-07 10:06:12 +00:00
|
|
|
{
|
|
|
|
size_t i, len = 0;
|
|
|
|
if (!v)
|
|
|
|
return 0;
|
|
|
|
ASSERT(v->size > 0);
|
2023-07-03 04:08:52 +00:00
|
|
|
for (i = 0; i < v->size; ++i)
|
2024-06-02 02:57:32 +00:00
|
|
|
len += demangle_strlen(VEC_STR(h, v, i));
|
2024-05-07 10:06:12 +00:00
|
|
|
return len;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
|
|
|
demangle_demangle_strncmp(const char *a, const char *b, size_t n)
|
|
|
|
{
|
|
|
|
size_t i = 0;
|
|
|
|
if (!n-- || a == b)
|
|
|
|
return 0;
|
|
|
|
while (i < n && a[i] == b[i] && b[i])
|
|
|
|
++i;
|
|
|
|
return (a[i] & 0xff) - (b[i] & 0xff);
|
|
|
|
}
|
|
|
|
|
2023-07-03 04:08:52 +00:00
|
|
|
/**
|
|
|
|
* @brief Find string in vector_str.
|
|
|
|
* @param v Destination vector.
|
|
|
|
* @param o String to find.
|
|
|
|
* @param l Length of the string.
|
|
|
|
* @return -1 at failed, 0 at not found, 1 at found.
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
|
|
|
vector_str_find(struct cpp_demangle_data *h, const struct vector_str *v,
|
|
|
|
const char *o, size_t l)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v || !o)
|
|
|
|
return -1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
for (i = 0; i < v->size; ++i)
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!demangle_demangle_strncmp(VEC_STR(h, v, i), o, l))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get new allocated flat string from vector.
|
|
|
|
*
|
|
|
|
* If l is not NULL, return length of the string.
|
|
|
|
* @param v Destination vector.
|
|
|
|
* @param l Length of the string.
|
|
|
|
* @return NULL at failed or NUL terminated new allocated string.
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged char *
|
2024-05-07 10:06:12 +00:00
|
|
|
vector_str_get_flat(struct cpp_demangle_data *ddata, const struct vector_str *v,
|
|
|
|
size_t *l)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
2024-05-08 00:36:17 +00:00
|
|
|
char *rtn, *p;
|
|
|
|
ssize_t rtn_size;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v || !v->size)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(rtn_size = get_demangle_strlen_sum(ddata, v)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(rtn = (char *)demangle_malloc(ddata, 1, rtn_size + 1)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-08 00:36:17 +00:00
|
|
|
p = rtn;
|
|
|
|
for (i = 0; i < v->size; ++i)
|
2024-06-02 02:57:32 +00:00
|
|
|
p = demangle_stpcpy(p, VEC_STR(ddata, v, i));
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (l)
|
2023-07-03 04:08:52 +00:00
|
|
|
*l = rtn_size;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged bool
|
2024-05-07 10:06:12 +00:00
|
|
|
vector_str_grow(struct cpp_demangle_data *ddata, struct vector_str *v)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
|
|
|
size_t i, tmp_cap;
|
2024-06-02 02:57:32 +00:00
|
|
|
index_t *tmp_ctn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v)
|
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
ASSERT(v->capacity > 0);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
tmp_cap = BUFFER_GROW(v->capacity);
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
ASSERT(tmp_cap > v->capacity);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(tmp_ctn = (index_t *)demangle_malloc(ddata, alignof(index_t),
|
|
|
|
sizeof(index_t) * tmp_cap)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
for (i = 0; i < v->size; ++i)
|
|
|
|
tmp_ctn[i] = v->container[i];
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_free(ddata, v->container);
|
|
|
|
|
2023-07-03 04:08:52 +00:00
|
|
|
v->container = tmp_ctn;
|
|
|
|
v->capacity = tmp_cap;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return true;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Initialize vector_str.
|
|
|
|
* @return false at failed, true at success.
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged bool
|
2024-05-07 10:06:12 +00:00
|
|
|
vector_str_init(struct cpp_demangle_data *ddata, struct vector_str *v)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v)
|
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
v->size = 0;
|
|
|
|
v->capacity = VECTOR_DEF_CAPACITY;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
ASSERT(v->capacity > 0);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(v->container = (index_t *)demangle_malloc(ddata, alignof(index_t),
|
|
|
|
sizeof(index_t) * v->capacity)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
ASSERT(v->container);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return true;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Remove last element in vector_str.
|
|
|
|
* @return false at failed, true at success.
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged bool
|
2023-07-03 04:08:52 +00:00
|
|
|
vector_str_pop(struct vector_str *v)
|
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v)
|
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v->size)
|
|
|
|
return true;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
--v->size;
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
v->container[v->size] = 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return true;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Push back string to vector.
|
|
|
|
* @return false at failed, true at success.
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged bool
|
2024-05-07 10:06:12 +00:00
|
|
|
vector_str_push(struct cpp_demangle_data *ddata, struct vector_str *v,
|
|
|
|
const char *str, size_t len)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v || !str)
|
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (v->size == v->capacity && !vector_str_grow(ddata, v))
|
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(v->container[v->size] = (uintptr_t)demangle_malloc(ddata, 1,
|
|
|
|
len + 1) -
|
|
|
|
ddata->heap))
|
2024-05-07 10:06:12 +00:00
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_strlcpy(VEC_STR(ddata, v, v->size), str, len + 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
++v->size;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return true;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Push front org vector to det vector.
|
|
|
|
* @return false at failed, true at success.
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged bool
|
2024-05-07 10:06:12 +00:00
|
|
|
vector_str_push_vector_head(struct cpp_demangle_data *ddata,
|
|
|
|
struct vector_str *dst, struct vector_str *org)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-06-02 02:57:32 +00:00
|
|
|
size_t i, j, tmp_cap;
|
|
|
|
index_t *tmp_ctn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!dst || !org)
|
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
tmp_cap = BUFFER_GROW(dst->size + org->size);
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(tmp_ctn = (index_t *)demangle_malloc(ddata, alignof(index_t),
|
|
|
|
sizeof(index_t) * tmp_cap)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
for (i = 0; i < org->size; ++i)
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(tmp_ctn[i] = (uintptr_t)demangle_strdup(ddata,
|
|
|
|
VEC_STR(ddata, org, i)) -
|
|
|
|
ddata->heap)) {
|
|
|
|
for (j = 0; j < i; ++j)
|
|
|
|
demangle_free(ddata,
|
|
|
|
(void *)(ddata->heap + tmp_ctn[j]));
|
|
|
|
|
|
|
|
demangle_free(ddata, tmp_ctn);
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return false;
|
2024-06-02 02:57:32 +00:00
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
for (i = 0; i < dst->size; ++i)
|
|
|
|
tmp_ctn[i + org->size] = dst->container[i];
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_free(ddata, dst->container);
|
|
|
|
|
2023-07-03 04:08:52 +00:00
|
|
|
dst->container = tmp_ctn;
|
|
|
|
dst->capacity = tmp_cap;
|
|
|
|
dst->size += org->size;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return true;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Push org vector to the tail of det vector.
|
|
|
|
* @return false at failed, true at success.
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged bool
|
2024-05-07 10:06:12 +00:00
|
|
|
vector_str_push_vector(struct cpp_demangle_data *ddata, struct vector_str *dst,
|
|
|
|
struct vector_str *org)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-06-02 02:57:32 +00:00
|
|
|
size_t i, j, tmp_cap;
|
|
|
|
index_t *tmp_ctn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!dst || !org)
|
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
tmp_cap = BUFFER_GROW(dst->size + org->size);
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(tmp_ctn = (index_t *)demangle_malloc(ddata, alignof(index_t),
|
|
|
|
sizeof(index_t) * tmp_cap)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
for (i = 0; i < dst->size; ++i)
|
|
|
|
tmp_ctn[i] = dst->container[i];
|
|
|
|
|
|
|
|
for (i = 0; i < org->size; ++i)
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(tmp_ctn[i + dst->size] = (uintptr_t)demangle_strdup(ddata,
|
|
|
|
VEC_STR(ddata, org, i)) -
|
|
|
|
ddata->heap)) {
|
|
|
|
for (j = 0; j < i + dst->size; ++j)
|
|
|
|
demangle_free(ddata,
|
|
|
|
(char *)(ddata->heap + tmp_ctn[j]));
|
|
|
|
|
|
|
|
demangle_free(ddata, tmp_ctn);
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return false;
|
2024-06-02 02:57:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
demangle_free(ddata, dst->container);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
dst->container = tmp_ctn;
|
|
|
|
dst->capacity = tmp_cap;
|
|
|
|
dst->size += org->size;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return true;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Get new allocated flat string from vector between begin and end.
|
|
|
|
*
|
|
|
|
* If r_len is not NULL, string length will be returned.
|
|
|
|
* @return NULL at failed or NUL terminated new allocated string.
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged char *
|
2024-05-07 10:06:12 +00:00
|
|
|
vector_str_substr(struct cpp_demangle_data *ddata, const struct vector_str *v,
|
|
|
|
size_t begin, size_t end, size_t *r_len)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
char *rtn, *p;
|
|
|
|
size_t i, len;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v || begin > end)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
len = 0;
|
|
|
|
for (i = begin; i < end + 1; ++i)
|
2024-06-02 02:57:32 +00:00
|
|
|
len += demangle_strlen(VEC_STR(ddata, v, i));
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(rtn = (char *)demangle_malloc(ddata, 1, len + 1)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (r_len)
|
2023-07-03 04:08:52 +00:00
|
|
|
*r_len = len;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
p = rtn;
|
|
|
|
for (i = begin; i < end + 1; ++i)
|
2024-06-02 02:57:32 +00:00
|
|
|
p = demangle_stpcpy(p, VEC_STR(ddata, v, i));
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-07 10:06:12 +00:00
|
|
|
vector_read_cmd_pop(struct vector_read_cmd *v)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v || !v->size)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
--v->size;
|
|
|
|
v->r_container[v->size].cmd = READ_FAIL;
|
|
|
|
v->r_container[v->size].data = NULL;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-07 10:06:12 +00:00
|
|
|
vector_read_cmd_init(struct cpp_demangle_data *ddata, struct vector_read_cmd *v)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
v->size = 0;
|
|
|
|
v->capacity = VECTOR_DEF_CAPACITY;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(v->r_container = (struct read_cmd_item *)demangle_malloc(ddata,
|
2024-05-07 10:06:12 +00:00
|
|
|
alignof(*v->r_container),
|
|
|
|
sizeof(*v->r_container) * v->capacity)))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_data_init(struct cpp_demangle_data *d, const char *cur)
|
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!d || !cur)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!vector_str_init(d, &d->output))
|
|
|
|
return 0;
|
|
|
|
if (!vector_str_init(d, &d->subst))
|
|
|
|
return 0;
|
|
|
|
if (!vector_str_init(d, &d->tmpl))
|
|
|
|
return 0;
|
|
|
|
if (!vector_str_init(d, &d->class_type))
|
|
|
|
return 0;
|
|
|
|
if (!vector_read_cmd_init(d, &d->cmd))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ASSERT(d->output.container);
|
|
|
|
ASSERT(d->subst.container);
|
|
|
|
ASSERT(d->tmpl.container);
|
|
|
|
ASSERT(d->class_type.container);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
d->mem_rst = false;
|
|
|
|
d->mem_vat = false;
|
|
|
|
d->mem_cst = false;
|
|
|
|
d->mem_ref = false;
|
|
|
|
d->mem_rref = false;
|
|
|
|
d->is_tmpl = false;
|
|
|
|
d->is_functype = false;
|
|
|
|
d->ref_qualifier = false;
|
|
|
|
d->push_qualifier = PUSH_ALL_QUALIFIER;
|
|
|
|
d->func_type = 0;
|
|
|
|
d->cur = cur;
|
|
|
|
d->cur_output = &d->output;
|
|
|
|
d->last_sname = NULL;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-07 10:06:12 +00:00
|
|
|
cpp_demangle_push_str(struct cpp_demangle_data *ddata, const char *str,
|
|
|
|
size_t len)
|
|
|
|
{
|
|
|
|
if (!ddata || !str || !len)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* is_tmpl is used to check if the type (function arg) is right next
|
|
|
|
* to template args, and should always be cleared whenever new string
|
|
|
|
* pushed.
|
|
|
|
*/
|
|
|
|
ddata->is_tmpl = false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return vector_str_push(ddata, ddata->cur_output, str, len);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
#ifndef DEMANGLE_NO_FLOATING_POINT
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_push_fp(struct cpp_demangle_data *ddata,
|
2024-05-07 10:06:12 +00:00
|
|
|
char *decoder(struct cpp_demangle_data *, const char *, size_t))
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
int rtn;
|
|
|
|
const char *fp;
|
|
|
|
char *f;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata || !decoder)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
fp = ddata->cur;
|
|
|
|
while (*ddata->cur != 'E')
|
|
|
|
++ddata->cur;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!(f = decoder(ddata, fp, ddata->cur - fp)))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
rtn = 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if ((len = demangle_strlen(f)) > 0)
|
2023-07-03 04:08:52 +00:00
|
|
|
rtn = cpp_demangle_push_str(ddata, f, len);
|
|
|
|
|
|
|
|
++ddata->cur;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
2024-05-07 10:06:12 +00:00
|
|
|
#endif // DEMANGLE_NO_FLOATING_POINT
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_pop_str(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return vector_str_pop(ddata->cur_output);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_push_subst(struct cpp_demangle_data *ddata, const char *str,
|
|
|
|
size_t len)
|
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata || !str || !len)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!vector_str_find(ddata, &ddata->subst, str, len))
|
2024-05-07 10:06:12 +00:00
|
|
|
return vector_str_push(ddata, &ddata->subst, str, len);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_push_subst_v(struct cpp_demangle_data *ddata, struct vector_str *v)
|
|
|
|
{
|
|
|
|
int rtn;
|
|
|
|
char *str;
|
2024-05-07 10:06:12 +00:00
|
|
|
size_t str_len;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata || !v)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!(str = vector_str_get_flat(ddata, v, &str_len)))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
rtn = cpp_demangle_push_subst(ddata, str, str_len);
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_free(ddata, str);
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_push_type_qualifier(struct cpp_demangle_data *ddata,
|
|
|
|
struct vector_type_qualifier *v, const char *type_str)
|
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
struct stack_str subst_v;
|
2023-07-03 04:08:52 +00:00
|
|
|
enum type_qualifier t;
|
|
|
|
size_t idx, e_idx, e_len;
|
|
|
|
char *buf;
|
|
|
|
bool cv;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata || !v)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!(idx = v->size))
|
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (type_str) {
|
|
|
|
stack_str_init(&subst_v);
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v, type_str))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cv = true;
|
|
|
|
e_idx = 0;
|
|
|
|
while (idx > 0) {
|
|
|
|
switch (v->q_container[idx - 1]) {
|
|
|
|
case TYPE_PTR:
|
|
|
|
cv = false;
|
|
|
|
if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
|
|
|
|
break;
|
|
|
|
if (!DEM_PUSH_STR(ddata, "*"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
if (type_str) {
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v, "*"))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_v.str,
|
|
|
|
subst_v.len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_REF:
|
|
|
|
cv = false;
|
|
|
|
if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
|
|
|
|
break;
|
|
|
|
if (!DEM_PUSH_STR(ddata, "&"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
if (type_str) {
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v, "&"))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_v.str,
|
|
|
|
subst_v.len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_RREF:
|
|
|
|
cv = false;
|
|
|
|
if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
|
|
|
|
break;
|
|
|
|
if (!DEM_PUSH_STR(ddata, "&&"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
if (type_str) {
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v,
|
|
|
|
"&&"))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_v.str,
|
|
|
|
subst_v.len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_CMX:
|
|
|
|
cv = false;
|
|
|
|
if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
|
|
|
|
break;
|
|
|
|
if (!DEM_PUSH_STR(ddata, " complex"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
if (type_str) {
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v,
|
|
|
|
" complex"))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_v.str,
|
|
|
|
subst_v.len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_IMG:
|
|
|
|
cv = false;
|
|
|
|
if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
|
|
|
|
break;
|
|
|
|
if (!DEM_PUSH_STR(ddata, " imaginary"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
if (type_str) {
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v,
|
|
|
|
" imaginary"))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_v.str,
|
|
|
|
subst_v.len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_EXT:
|
|
|
|
cv = false;
|
|
|
|
if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
|
|
|
|
break;
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v->ext_name.size || e_idx > v->ext_name.size - 1)
|
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(e_len = demangle_strlen(
|
|
|
|
VEC_STR(ddata, (&v->ext_name), e_idx))))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(buf = (char *)demangle_malloc(ddata, 1,
|
|
|
|
e_len + 2)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
buf[0] = ' ';
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_memcpy(buf + 1,
|
|
|
|
VEC_STR(ddata, &v->ext_name, e_idx), e_len + 1);
|
2024-05-07 10:06:12 +00:00
|
|
|
|
|
|
|
if (!DEM_PUSH_STR(ddata, buf))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (type_str) {
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v, buf))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_v.str,
|
|
|
|
subst_v.len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
++e_idx;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_RST:
|
|
|
|
if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
|
|
|
|
cv)
|
|
|
|
break;
|
|
|
|
if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
|
|
|
|
break;
|
|
|
|
if (!DEM_PUSH_STR(ddata, " restrict"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
if (type_str) {
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v,
|
|
|
|
" restrict"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (idx - 1 > 0) {
|
|
|
|
t = v->q_container[idx - 2];
|
|
|
|
if (t == TYPE_RST || t == TYPE_VAT ||
|
|
|
|
t == TYPE_CST)
|
|
|
|
break;
|
|
|
|
}
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_v.str,
|
|
|
|
subst_v.len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_VAT:
|
|
|
|
if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
|
|
|
|
cv)
|
|
|
|
break;
|
|
|
|
if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
|
|
|
|
break;
|
|
|
|
if (!DEM_PUSH_STR(ddata, " volatile"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
if (type_str) {
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v,
|
|
|
|
" volatile"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (idx - 1 > 0) {
|
|
|
|
t = v->q_container[idx - 2];
|
|
|
|
if (t == TYPE_RST || t == TYPE_VAT ||
|
|
|
|
t == TYPE_CST)
|
|
|
|
break;
|
|
|
|
}
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_v.str,
|
|
|
|
subst_v.len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case TYPE_CST:
|
|
|
|
if (ddata->push_qualifier == PUSH_NON_CV_QUALIFIER &&
|
|
|
|
cv)
|
|
|
|
break;
|
|
|
|
if (ddata->push_qualifier == PUSH_CV_QUALIFIER && !cv)
|
|
|
|
break;
|
|
|
|
if (!DEM_PUSH_STR(ddata, " const"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
if (type_str) {
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v,
|
|
|
|
" const"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (idx - 1 > 0) {
|
|
|
|
t = v->q_container[idx - 2];
|
|
|
|
if (t == TYPE_RST || t == TYPE_VAT ||
|
|
|
|
t == TYPE_CST)
|
|
|
|
break;
|
|
|
|
}
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_v.str,
|
|
|
|
subst_v.len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
case TYPE_VEC: {
|
|
|
|
char *p;
|
2023-07-03 04:08:52 +00:00
|
|
|
cv = false;
|
|
|
|
if (ddata->push_qualifier == PUSH_CV_QUALIFIER)
|
|
|
|
break;
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!v->ext_name.size || e_idx > v->ext_name.size - 1)
|
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(e_len = demangle_strlen(
|
|
|
|
VEC_STR(ddata, &v->ext_name, e_idx))))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(buf = (char *)demangle_malloc(ddata, 1,
|
|
|
|
e_len + 12)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
p = buf;
|
2024-06-02 02:57:32 +00:00
|
|
|
p = demangle_stpcpy(p, " __vector(");
|
|
|
|
p = (char *)demangle_mempcpy(p,
|
|
|
|
VEC_STR(ddata, &v->ext_name, e_idx), e_len);
|
|
|
|
p = demangle_stpcpy(p, ")");
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, buf))
|
|
|
|
return 0;
|
|
|
|
if (type_str) {
|
|
|
|
if (!stack_str_append_str(ddata, &subst_v, buf))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_v.str,
|
|
|
|
subst_v.len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
++e_idx;
|
|
|
|
break;
|
|
|
|
}
|
2024-05-07 10:06:12 +00:00
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
--idx;
|
|
|
|
}
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_get_subst(struct cpp_demangle_data *ddata, size_t idx)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata || ddata->subst.size <= idx)
|
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(len = demangle_strlen(VEC_STR(ddata, &ddata->subst, idx))))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!cpp_demangle_push_str(ddata, VEC_STR(ddata, &ddata->subst, idx),
|
|
|
|
len))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
/* skip '_' */
|
|
|
|
++ddata->cur;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_get_tmpl_param(struct cpp_demangle_data *ddata, size_t idx)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata || ddata->tmpl.size <= idx)
|
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(len = demangle_strlen(VEC_STR(ddata, &ddata->tmpl, idx))))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!cpp_demangle_push_str(ddata, VEC_STR(ddata, &ddata->tmpl, idx),
|
|
|
|
len))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
++ddata->cur;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_read_array(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
|
|
|
size_t i, num_len, exp_len, p_idx, idx;
|
|
|
|
const char *num;
|
|
|
|
char *exp;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata || *(++ddata->cur) == '\0')
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
if (*ddata->cur == '_') {
|
|
|
|
if (*(++ddata->cur) == '\0')
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
if (!DEM_PUSH_STR(ddata, " []"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
} else {
|
2024-05-07 10:06:12 +00:00
|
|
|
if (ELFTC_ISDIGIT(*ddata->cur)) {
|
2023-07-03 04:08:52 +00:00
|
|
|
num = ddata->cur;
|
2024-05-07 10:06:12 +00:00
|
|
|
while (ELFTC_ISDIGIT(*ddata->cur))
|
2023-07-03 04:08:52 +00:00
|
|
|
++ddata->cur;
|
|
|
|
if (*ddata->cur != '_')
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
num_len = ddata->cur - num;
|
2024-05-07 10:06:12 +00:00
|
|
|
ASSERT(num_len > 0);
|
2023-07-03 04:08:52 +00:00
|
|
|
if (*(++ddata->cur) == '\0')
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, " ["))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (!cpp_demangle_push_str(ddata, num, num_len))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "]"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
} else {
|
|
|
|
p_idx = ddata->output.size;
|
|
|
|
if (!cpp_demangle_read_expression(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
|
|
|
if (!(exp = vector_str_substr(ddata, &ddata->output,
|
|
|
|
p_idx, ddata->output.size - 1, &exp_len)))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
idx = ddata->output.size;
|
|
|
|
for (i = p_idx; i < idx; ++i)
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!vector_str_pop(&ddata->output))
|
|
|
|
return 0;
|
|
|
|
if (*ddata->cur != '_')
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
++ddata->cur;
|
2024-05-07 10:06:12 +00:00
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
|
|
|
return 0;
|
|
|
|
if (!DEM_PUSH_STR(ddata, " ["))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_str(ddata, exp, exp_len))
|
|
|
|
return 0;
|
|
|
|
if (!DEM_PUSH_STR(ddata, "]"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
#ifndef DEMANGLE_NO_FLOATING_POINT
|
|
|
|
|
|
|
|
/* Simple hex to integer function used by decode_to_* function. */
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-07 10:06:12 +00:00
|
|
|
hex_to_dec(char c)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
switch (c) {
|
|
|
|
case '0':
|
|
|
|
return 0;
|
|
|
|
case '1':
|
|
|
|
return 1;
|
|
|
|
case '2':
|
|
|
|
return 2;
|
|
|
|
case '3':
|
|
|
|
return 3;
|
|
|
|
case '4':
|
|
|
|
return 4;
|
|
|
|
case '5':
|
|
|
|
return 5;
|
|
|
|
case '6':
|
|
|
|
return 6;
|
|
|
|
case '7':
|
|
|
|
return 7;
|
|
|
|
case '8':
|
|
|
|
return 8;
|
|
|
|
case '9':
|
|
|
|
return 9;
|
|
|
|
case 'a':
|
|
|
|
return 10;
|
2023-07-03 04:08:52 +00:00
|
|
|
case 'b':
|
2024-05-07 10:06:12 +00:00
|
|
|
return 11;
|
|
|
|
case 'c':
|
|
|
|
return 12;
|
2023-07-03 04:08:52 +00:00
|
|
|
case 'd':
|
2024-05-07 10:06:12 +00:00
|
|
|
return 13;
|
2023-07-03 04:08:52 +00:00
|
|
|
case 'e':
|
2024-05-07 10:06:12 +00:00
|
|
|
return 14;
|
2023-07-03 04:08:52 +00:00
|
|
|
case 'f':
|
2024-05-07 10:06:12 +00:00
|
|
|
return 15;
|
|
|
|
default:
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
/*
|
|
|
|
* Decode floating point representation to string
|
|
|
|
* Return new allocated string or NULL
|
|
|
|
*
|
|
|
|
* Todo
|
|
|
|
* Replace these functions to macro.
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged char *
|
2024-05-07 10:06:12 +00:00
|
|
|
decode_fp_to_double(struct cpp_demangle_data *ddata, const char *p, size_t len)
|
|
|
|
{
|
|
|
|
double f;
|
|
|
|
size_t rtn_len, limit, i;
|
|
|
|
int byte;
|
|
|
|
char *rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!p || !len || len % 2 || len / 2 > sizeof(double))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
memset(&f, 0, sizeof(double));
|
|
|
|
|
|
|
|
for (i = 0; i < len / 2; ++i) {
|
|
|
|
byte = hex_to_dec(p[len - i * 2 - 1]) +
|
|
|
|
hex_to_dec(p[len - i * 2 - 2]) * 16;
|
|
|
|
|
|
|
|
if (byte < 0 || byte > 255)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
|
|
|
|
((unsigned char *)&f)[i] = (unsigned char)(byte);
|
|
|
|
#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
((unsigned char *)&f)[sizeof(double) - i - 1] =
|
|
|
|
(unsigned char)(byte);
|
|
|
|
#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
}
|
|
|
|
|
|
|
|
rtn_len = 64;
|
|
|
|
limit = 0;
|
|
|
|
again:
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(rtn = (char *)demangle_malloc(ddata, alignof(char),
|
2024-05-07 10:06:12 +00:00
|
|
|
sizeof(char) * rtn_len)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (snprintf(rtn, rtn_len, "%fld", f) >= (int)rtn_len) {
|
|
|
|
if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
|
|
|
|
return 0;
|
|
|
|
rtn_len *= BUFFER_GROWFACTOR;
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rtn;
|
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged char *
|
2024-05-07 10:06:12 +00:00
|
|
|
decode_fp_to_float(struct cpp_demangle_data *ddata, const char *p, size_t len)
|
|
|
|
{
|
|
|
|
size_t i, rtn_len, limit;
|
|
|
|
float f;
|
|
|
|
int byte;
|
|
|
|
char *rtn;
|
|
|
|
|
|
|
|
if (!p || !len || len % 2 || len / 2 > sizeof(float))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
memset(&f, 0, sizeof(float));
|
|
|
|
|
|
|
|
for (i = 0; i < len / 2; ++i) {
|
|
|
|
byte = hex_to_dec(p[len - i * 2 - 1]) +
|
|
|
|
hex_to_dec(p[len - i * 2 - 2]) * 16;
|
|
|
|
if (byte < 0 || byte > 255)
|
|
|
|
return 0;
|
|
|
|
#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
|
|
|
|
((unsigned char *)&f)[i] = (unsigned char)(byte);
|
|
|
|
#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
((unsigned char *)&f)[sizeof(float) - i - 1] =
|
|
|
|
(unsigned char)(byte);
|
|
|
|
#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
}
|
|
|
|
|
|
|
|
rtn_len = 64;
|
|
|
|
limit = 0;
|
|
|
|
again:
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(rtn = (char *)demangle_malloc(ddata, alignof(char),
|
2024-05-07 10:06:12 +00:00
|
|
|
sizeof(char) * rtn_len)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (snprintf(rtn, rtn_len, "%ff", f) >= (int)rtn_len) {
|
|
|
|
if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
|
|
|
|
return 0;
|
|
|
|
rtn_len *= BUFFER_GROWFACTOR;
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rtn;
|
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged char *
|
2024-05-07 10:06:12 +00:00
|
|
|
decode_fp_to_long_double(struct cpp_demangle_data *ddata, const char *p,
|
|
|
|
size_t len)
|
|
|
|
{
|
|
|
|
long double f;
|
|
|
|
size_t rtn_len, limit, i;
|
|
|
|
int byte;
|
|
|
|
char *rtn;
|
|
|
|
|
|
|
|
if (!p || !len || len % 2 || len / 2 > sizeof(long double))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
memset(&f, 0, sizeof(long double));
|
|
|
|
|
|
|
|
for (i = 0; i < len / 2; ++i) {
|
|
|
|
byte = hex_to_dec(p[len - i * 2 - 1]) +
|
|
|
|
hex_to_dec(p[len - i * 2 - 2]) * 16;
|
|
|
|
|
|
|
|
if (byte < 0 || byte > 255)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
|
|
|
|
((unsigned char *)&f)[i] = (unsigned char)(byte);
|
|
|
|
#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
((unsigned char *)&f)[sizeof(long double) - i - 1] =
|
|
|
|
(unsigned char)(byte);
|
|
|
|
#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
}
|
|
|
|
|
|
|
|
rtn_len = 256;
|
|
|
|
limit = 0;
|
|
|
|
again:
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(rtn = (char *)demangle_malloc(ddata, alignof(char),
|
2024-05-07 10:06:12 +00:00
|
|
|
sizeof(char) * rtn_len)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {
|
|
|
|
if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
|
|
|
|
return 0;
|
|
|
|
rtn_len *= BUFFER_GROWFACTOR;
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rtn;
|
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged char *
|
2024-05-07 10:06:12 +00:00
|
|
|
decode_fp_to_float128(struct cpp_demangle_data *ddata, const char *p,
|
|
|
|
size_t len)
|
|
|
|
{
|
|
|
|
long double f;
|
|
|
|
size_t rtn_len, limit, i;
|
|
|
|
int byte;
|
|
|
|
unsigned char buf[FLOAT_QUADRUPLE_BYTES];
|
|
|
|
char *rtn;
|
|
|
|
|
|
|
|
switch (sizeof(long double)) {
|
|
|
|
case FLOAT_QUADRUPLE_BYTES:
|
|
|
|
return decode_fp_to_long_double(ddata, p, len);
|
|
|
|
case FLOAT_EXTENED_BYTES:
|
|
|
|
if (!p || !len || len % 2 || len / 2 > FLOAT_QUADRUPLE_BYTES)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
memset(buf, 0, FLOAT_QUADRUPLE_BYTES);
|
|
|
|
|
|
|
|
for (i = 0; i < len / 2; ++i) {
|
|
|
|
byte = hex_to_dec(p[len - i * 2 - 1]) +
|
|
|
|
hex_to_dec(p[len - i * 2 - 2]) * 16;
|
|
|
|
if (byte < 0 || byte > 255)
|
|
|
|
return 0;
|
|
|
|
#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
|
|
|
|
buf[i] = (unsigned char)(byte);
|
|
|
|
#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
buf[FLOAT_QUADRUPLE_BYTES - i - 1] =
|
|
|
|
(unsigned char)(byte);
|
|
|
|
#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
}
|
|
|
|
memset(&f, 0, FLOAT_EXTENED_BYTES);
|
|
|
|
|
|
|
|
#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_memcpy(&f, buf, FLOAT_EXTENED_BYTES);
|
2024-05-07 10:06:12 +00:00
|
|
|
#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_memcpy(&f, buf + 6, FLOAT_EXTENED_BYTES);
|
2024-05-07 10:06:12 +00:00
|
|
|
#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
|
|
|
|
rtn_len = 256;
|
|
|
|
limit = 0;
|
|
|
|
again:
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(rtn = (char *)demangle_malloc(ddata, alignof(char),
|
2024-05-07 10:06:12 +00:00
|
|
|
sizeof(char) * rtn_len)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {
|
|
|
|
if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
|
|
|
|
return 0;
|
|
|
|
rtn_len *= BUFFER_GROWFACTOR;
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rtn;
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged char *
|
2024-05-07 10:06:12 +00:00
|
|
|
decode_fp_to_float80(struct cpp_demangle_data *ddata, const char *p, size_t len)
|
|
|
|
{
|
|
|
|
long double f;
|
|
|
|
size_t rtn_len, limit, i;
|
|
|
|
int byte;
|
|
|
|
unsigned char buf[FLOAT_EXTENED_BYTES];
|
|
|
|
char *rtn;
|
|
|
|
|
|
|
|
switch (sizeof(long double)) {
|
|
|
|
case FLOAT_QUADRUPLE_BYTES:
|
|
|
|
if (!p || !len || len % 2 || len / 2 > FLOAT_EXTENED_BYTES)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
memset(buf, 0, FLOAT_EXTENED_BYTES);
|
|
|
|
|
|
|
|
for (i = 0; i < len / 2; ++i) {
|
|
|
|
byte = hex_to_dec(p[len - i * 2 - 1]) +
|
|
|
|
hex_to_dec(p[len - i * 2 - 2]) * 16;
|
|
|
|
|
|
|
|
if (byte < 0 || byte > 255)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
|
|
|
|
buf[i] = (unsigned char)(byte);
|
|
|
|
#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
buf[FLOAT_EXTENED_BYTES - i - 1] =
|
|
|
|
(unsigned char)(byte);
|
|
|
|
#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
}
|
|
|
|
|
|
|
|
memset(&f, 0, FLOAT_QUADRUPLE_BYTES);
|
|
|
|
|
|
|
|
#if ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_memcpy(&f, buf, FLOAT_EXTENED_BYTES);
|
2024-05-07 10:06:12 +00:00
|
|
|
#else /* ELFTC_BYTE_ORDER != ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_memcpy((unsigned char *)(&f) + 6, buf,
|
|
|
|
FLOAT_EXTENED_BYTES);
|
2024-05-07 10:06:12 +00:00
|
|
|
#endif /* ELFTC_BYTE_ORDER == ELFTC_BYTE_ORDER_LITTLE_ENDIAN */
|
|
|
|
|
|
|
|
rtn_len = 256;
|
|
|
|
limit = 0;
|
|
|
|
again:
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(rtn = (char *)demangle_malloc(ddata, alignof(char),
|
2024-05-07 10:06:12 +00:00
|
|
|
sizeof(char) * rtn_len)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (snprintf(rtn, rtn_len, "%Lfd", f) >= (int)rtn_len) {
|
|
|
|
if (limit++ > FLOAT_SPRINTF_TRY_LIMIT)
|
|
|
|
return 0;
|
|
|
|
rtn_len *= BUFFER_GROWFACTOR;
|
|
|
|
goto again;
|
|
|
|
}
|
|
|
|
|
|
|
|
return rtn;
|
|
|
|
case FLOAT_EXTENED_BYTES:
|
|
|
|
return decode_fp_to_long_double(ddata, p, len);
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif // DEMANGLE_NO_FLOATING_POINT
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-07 10:06:12 +00:00
|
|
|
cpp_demangle_read_expr_primary(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
|
|
|
const char *num;
|
|
|
|
|
|
|
|
if (!ddata || *(++ddata->cur) == '\0')
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (*ddata->cur == '_' && *(ddata->cur + 1) == 'Z') {
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_encoding(ddata))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (*ddata->cur) {
|
|
|
|
case 'b':
|
|
|
|
if (*(ddata->cur + 2) != 'E')
|
|
|
|
return 0;
|
|
|
|
switch (*(++ddata->cur)) {
|
|
|
|
case '0':
|
|
|
|
ddata->cur += 2;
|
|
|
|
return DEM_PUSH_STR(ddata, "false");
|
|
|
|
case '1':
|
|
|
|
ddata->cur += 2;
|
|
|
|
return DEM_PUSH_STR(ddata, "true");
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef DEMANGLE_NO_FLOATING_POINT
|
|
|
|
|
|
|
|
case 'd':
|
|
|
|
++ddata->cur;
|
|
|
|
return cpp_demangle_push_fp(ddata, decode_fp_to_double);
|
|
|
|
|
|
|
|
case 'e':
|
|
|
|
++ddata->cur;
|
|
|
|
if (sizeof(long double) == 10)
|
|
|
|
return cpp_demangle_push_fp(ddata, decode_fp_to_double);
|
|
|
|
return cpp_demangle_push_fp(ddata, decode_fp_to_float80);
|
|
|
|
|
|
|
|
case 'f':
|
|
|
|
++ddata->cur;
|
|
|
|
return cpp_demangle_push_fp(ddata, decode_fp_to_float);
|
|
|
|
|
|
|
|
case 'g':
|
|
|
|
++ddata->cur;
|
|
|
|
if (sizeof(long double) == 16)
|
|
|
|
return cpp_demangle_push_fp(ddata, decode_fp_to_double);
|
|
|
|
return cpp_demangle_push_fp(ddata, decode_fp_to_float128);
|
|
|
|
|
|
|
|
#endif // DEMANGLE_NO_FLOATING_POINT
|
|
|
|
|
|
|
|
case 'i':
|
2023-07-03 04:08:52 +00:00
|
|
|
case 'j':
|
|
|
|
case 'l':
|
|
|
|
case 'm':
|
|
|
|
case 'n':
|
|
|
|
case 's':
|
|
|
|
case 't':
|
|
|
|
case 'x':
|
|
|
|
case 'y':
|
|
|
|
if (*(++ddata->cur) == 'n') {
|
|
|
|
if (!DEM_PUSH_STR(ddata, "-"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
++ddata->cur;
|
|
|
|
}
|
|
|
|
num = ddata->cur;
|
|
|
|
while (*ddata->cur != 'E') {
|
|
|
|
if (!ELFTC_ISDIGIT(*ddata->cur))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
++ddata->cur;
|
|
|
|
}
|
|
|
|
++ddata->cur;
|
2024-05-07 10:06:12 +00:00
|
|
|
return cpp_demangle_push_str(ddata, num, ddata->cur - num - 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
default:
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/*
|
|
|
|
* Read local source name.
|
|
|
|
*
|
|
|
|
* References:
|
|
|
|
* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
|
|
|
|
* http://gcc.gnu.org/viewcvs?view=rev&revision=124467
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_local_source_name(struct cpp_demangle_data *ddata)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
/* L */
|
|
|
|
if (!ddata || *ddata->cur != 'L')
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* source name */
|
|
|
|
if (!cpp_demangle_read_sname(ddata))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* discriminator */
|
|
|
|
if (*ddata->cur == '_') {
|
|
|
|
++ddata->cur;
|
|
|
|
while (ELFTC_ISDIGIT(*ddata->cur))
|
|
|
|
++ddata->cur;
|
|
|
|
}
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* read unqualified-name, unqualified name are operator-name, ctor-dtor-name,
|
|
|
|
* source-name
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_uqname(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
|
|
|
size_t len;
|
|
|
|
|
|
|
|
if (!ddata || *ddata->cur == '\0')
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* operator name */
|
|
|
|
switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
|
2023-07-03 04:08:52 +00:00
|
|
|
case SIMPLE_HASH('a', 'a'):
|
|
|
|
/* operator && */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator&&"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('a', 'd'):
|
|
|
|
/* operator & (unary) */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator&"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('a', 'n'):
|
|
|
|
/* operator & */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator&"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('a', 'N'):
|
|
|
|
/* operator &= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator&="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('a', 'S'):
|
|
|
|
/* operator = */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('c', 'l'):
|
|
|
|
/* operator () */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator()"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('c', 'm'):
|
|
|
|
/* operator , */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator,"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('c', 'o'):
|
|
|
|
/* operator ~ */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator~"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('c', 'v'):
|
|
|
|
/* operator (cast) */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator(cast)"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_type(ddata, NULL);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('d', 'a'):
|
|
|
|
/* operator delete [] */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator delete []"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('d', 'e'):
|
|
|
|
/* operator * (unary) */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator*"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('d', 'l'):
|
|
|
|
/* operator delete */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator delete"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('d', 'v'):
|
|
|
|
/* operator / */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator/"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('d', 'V'):
|
|
|
|
/* operator /= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator/="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('e', 'o'):
|
|
|
|
/* operator ^ */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator^"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('e', 'O'):
|
|
|
|
/* operator ^= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator^="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('e', 'q'):
|
|
|
|
/* operator == */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator=="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('g', 'e'):
|
|
|
|
/* operator >= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator>="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('g', 't'):
|
|
|
|
/* operator > */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator>"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('i', 'x'):
|
|
|
|
/* operator [] */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator[]"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('l', 'e'):
|
|
|
|
/* operator <= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator<="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('l', 's'):
|
|
|
|
/* operator << */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator<<"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('l', 'S'):
|
|
|
|
/* operator <<= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator<<="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('l', 't'):
|
|
|
|
/* operator < */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator<"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('m', 'i'):
|
|
|
|
/* operator - */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator-"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('m', 'I'):
|
|
|
|
/* operator -= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator-="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('m', 'l'):
|
|
|
|
/* operator * */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator*"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('m', 'L'):
|
|
|
|
/* operator *= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator*="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('m', 'm'):
|
|
|
|
/* operator -- */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator--"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('n', 'a'):
|
|
|
|
/* operator new[] */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator new []"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('n', 'e'):
|
|
|
|
/* operator != */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator!="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('n', 'g'):
|
|
|
|
/* operator - (unary) */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator-"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('n', 't'):
|
|
|
|
/* operator ! */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator!"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('n', 'w'):
|
|
|
|
/* operator new */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator new"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('o', 'o'):
|
|
|
|
/* operator || */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator||"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('o', 'r'):
|
|
|
|
/* operator | */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator|"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('o', 'R'):
|
|
|
|
/* operator |= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator|="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('p', 'l'):
|
|
|
|
/* operator + */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator+"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('p', 'L'):
|
|
|
|
/* operator += */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator+="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('p', 'm'):
|
|
|
|
/* operator ->* */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator->*"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('p', 'p'):
|
|
|
|
/* operator ++ */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator++"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('p', 's'):
|
|
|
|
/* operator + (unary) */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator+"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('p', 't'):
|
|
|
|
/* operator -> */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator->"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('q', 'u'):
|
|
|
|
/* operator ? */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator?"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('r', 'm'):
|
|
|
|
/* operator % */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator%"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('r', 'M'):
|
|
|
|
/* operator %= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator%="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('r', 's'):
|
|
|
|
/* operator >> */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator>>"))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('r', 'S'):
|
|
|
|
/* operator >>= */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator>>="))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
case SIMPLE_HASH('r', 'z'):
|
|
|
|
/* operator sizeof */
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "operator sizeof "))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('s', 'r'):
|
|
|
|
/* scope resolution operator */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "scope resolution operator "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
case SIMPLE_HASH('s', 'v'):
|
|
|
|
/* operator sizeof */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "operator sizeof "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* vendor extened operator */
|
|
|
|
if (*ddata->cur == 'v' && ELFTC_ISDIGIT(*(ddata->cur + 1))) {
|
|
|
|
if (!DEM_PUSH_STR(ddata, "vendor extened operator "))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_str(ddata, ddata->cur + 1, 1))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_sname(ddata);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* ctor-dtor-name */
|
|
|
|
switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
|
|
|
|
case SIMPLE_HASH('C', '1'):
|
|
|
|
case SIMPLE_HASH('C', '2'):
|
|
|
|
case SIMPLE_HASH('C', '3'):
|
|
|
|
if (!ddata->last_sname)
|
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(len = demangle_strlen(ddata->last_sname)))
|
2024-05-26 13:03:50 +00:00
|
|
|
return 0;
|
|
|
|
if (!DEM_PUSH_STR(ddata, "::"))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_str(ddata, ddata->last_sname, len))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
case SIMPLE_HASH('D', '0'):
|
|
|
|
case SIMPLE_HASH('D', '1'):
|
|
|
|
case SIMPLE_HASH('D', '2'):
|
|
|
|
if (!ddata->last_sname)
|
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(len = demangle_strlen(ddata->last_sname)))
|
2024-05-26 13:03:50 +00:00
|
|
|
return 0;
|
|
|
|
if (!DEM_PUSH_STR(ddata, "::~"))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_str(ddata, ddata->last_sname, len))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* source name */
|
|
|
|
if (ELFTC_ISDIGIT(*ddata->cur))
|
|
|
|
return cpp_demangle_read_sname(ddata);
|
|
|
|
|
|
|
|
/* local source name */
|
|
|
|
if (*ddata->cur == 'L')
|
|
|
|
return cpp_demangle_local_source_name(ddata);
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Read template parameter that forms in 'T[number]_'.
|
|
|
|
* This function much like to read_subst but only for types.
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_tmpl_param(struct cpp_demangle_data *ddata)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
long nth;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata || *ddata->cur != 'T')
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur == '_') {
|
|
|
|
return cpp_demangle_get_tmpl_param(ddata, 0);
|
|
|
|
} else {
|
2024-06-02 02:57:32 +00:00
|
|
|
nth = demangle_strtol(ddata->cur, 36);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* T_ is first */
|
|
|
|
++nth;
|
|
|
|
|
|
|
|
while (*ddata->cur != '_')
|
|
|
|
++ddata->cur;
|
|
|
|
|
|
|
|
ASSERT(nth > 0);
|
|
|
|
|
|
|
|
return cpp_demangle_get_tmpl_param(ddata, nth);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* NOTREACHED */
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
vector_read_cmd_push(struct cpp_demangle_data *ddata, struct vector_read_cmd *v,
|
|
|
|
enum read_cmd cmd, void *data)
|
|
|
|
{
|
|
|
|
struct read_cmd_item *tmp_r_ctn;
|
|
|
|
size_t tmp_cap;
|
|
|
|
size_t i;
|
|
|
|
|
|
|
|
if (!v)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (v->size == v->capacity) {
|
|
|
|
tmp_cap = BUFFER_GROW(v->capacity);
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(tmp_r_ctn = (struct read_cmd_item *)demangle_malloc(ddata,
|
2024-05-26 13:03:50 +00:00
|
|
|
alignof(*tmp_r_ctn), sizeof(*tmp_r_ctn) * tmp_cap)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
for (i = 0; i < v->size; ++i)
|
|
|
|
tmp_r_ctn[i] = v->r_container[i];
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_free(ddata, v->r_container);
|
2024-05-26 13:03:50 +00:00
|
|
|
v->r_container = tmp_r_ctn;
|
|
|
|
v->capacity = tmp_cap;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
v->r_container[v->size].cmd = cmd;
|
|
|
|
v->r_container[v->size].data = data;
|
|
|
|
++v->size;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_tmpl_arg(struct cpp_demangle_data *ddata)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata || *ddata->cur == '\0')
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
switch (*ddata->cur) {
|
|
|
|
case 'L':
|
|
|
|
return cpp_demangle_read_expr_primary(ddata);
|
|
|
|
case 'X':
|
|
|
|
++ddata->cur;
|
|
|
|
if (!cpp_demangle_read_expression(ddata))
|
|
|
|
return 0;
|
|
|
|
return *ddata->cur++ == 'E';
|
|
|
|
}
|
|
|
|
|
|
|
|
return cpp_demangle_read_type(ddata, NULL);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_tmpl_args(struct cpp_demangle_data *ddata)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
struct vector_str *v;
|
|
|
|
size_t arg_len, idx, limit;
|
|
|
|
char *arg;
|
|
|
|
|
|
|
|
if (!ddata || *ddata->cur == '\0')
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
|
|
|
|
++ddata->cur;
|
|
|
|
|
|
|
|
if (!vector_read_cmd_push(ddata, &ddata->cmd, READ_TMPL, NULL))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "<"))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
limit = 0;
|
|
|
|
v = ddata->cur_output;
|
|
|
|
for (;;) {
|
|
|
|
idx = v->size;
|
|
|
|
if (!cpp_demangle_read_tmpl_arg(ddata))
|
|
|
|
return 0;
|
|
|
|
if (!(arg = vector_str_substr(ddata, v, idx, v->size - 1,
|
|
|
|
&arg_len)))
|
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!vector_str_find(ddata, &ddata->tmpl, arg, arg_len) &&
|
|
|
|
!vector_str_push(ddata, &ddata->tmpl, arg, arg_len)) {
|
|
|
|
demangle_free(ddata, arg);
|
2024-05-26 13:03:50 +00:00
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
demangle_free(ddata, arg);
|
2024-05-26 13:03:50 +00:00
|
|
|
|
|
|
|
if (*ddata->cur == 'E') {
|
|
|
|
++ddata->cur;
|
|
|
|
if (!DEM_PUSH_STR(ddata, ">"))
|
|
|
|
return 0;
|
|
|
|
ddata->is_tmpl = true;
|
|
|
|
break;
|
|
|
|
} else if (*ddata->cur != 'I' && !DEM_PUSH_STR(ddata, ", "))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return vector_read_cmd_pop(&ddata->cmd);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_read_expression_trinary(struct cpp_demangle_data *ddata,
|
|
|
|
const char *name1, size_t len1, const char *name2, size_t len2)
|
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata || !name1 || !len1 || !name2 || !len2)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
if (!cpp_demangle_read_expression(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (!cpp_demangle_push_str(ddata, name1, len1))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (!cpp_demangle_read_expression(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (!cpp_demangle_push_str(ddata, name2, len2))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return cpp_demangle_read_expression(ddata);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_expression_unary(struct cpp_demangle_data *ddata,
|
|
|
|
const char *name, size_t len)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata || !name || !len)
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_expression(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_push_str(ddata, name, len);
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_expression_binary(struct cpp_demangle_data *ddata,
|
|
|
|
const char *name, size_t len)
|
|
|
|
{
|
|
|
|
if (!ddata || !name || !len)
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_expression(ddata))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_str(ddata, name, len))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression(ddata);
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_expression(struct cpp_demangle_data *ddata)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata || *ddata->cur == '\0')
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('s', 't'):
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_type(ddata, NULL);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('s', 'r'):
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_uqname(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur == 'I')
|
|
|
|
return cpp_demangle_read_tmpl_args(ddata);
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('a', 'a'):
|
|
|
|
/* operator && */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_binary(ddata, "&&", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('a', 'd'):
|
|
|
|
/* operator & (unary) */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_unary(ddata, "&", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('a', 'n'):
|
|
|
|
/* operator & */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_binary(ddata, "&", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('a', 'N'):
|
|
|
|
/* operator &= */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_binary(ddata, "&=", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('a', 'S'):
|
|
|
|
/* operator = */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_binary(ddata, "=", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('c', 'l'):
|
|
|
|
/* operator () */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_binary(ddata, "()", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('c', 'm'):
|
|
|
|
/* operator , */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_binary(ddata, ",", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('c', 'o'):
|
|
|
|
/* operator ~ */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_binary(ddata, "~", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('c', 'v'):
|
|
|
|
/* operator (cast) */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_binary(ddata, "(cast)", 6);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('d', 'a'):
|
|
|
|
/* operator delete [] */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_unary(ddata, "delete []",
|
|
|
|
9);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('d', 'e'):
|
|
|
|
/* operator * (unary) */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_unary(ddata, "*", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('d', 'l'):
|
|
|
|
/* operator delete */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_unary(ddata, "delete", 6);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('d', 'v'):
|
|
|
|
/* operator / */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_binary(ddata, "/", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('d', 'V'):
|
|
|
|
/* operator /= */
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_expression_binary(ddata, "/=", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('e', 'o'):
|
|
|
|
/* operator ^ */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "^", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('e', 'O'):
|
|
|
|
/* operator ^= */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "^=", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('e', 'q'):
|
|
|
|
/* operator == */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "==", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('g', 'e'):
|
|
|
|
/* operator >= */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, ">=", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('g', 't'):
|
|
|
|
/* operator > */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, ">", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('i', 'x'):
|
|
|
|
/* operator [] */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "[]", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('l', 'e'):
|
|
|
|
/* operator <= */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "<=", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('l', 's'):
|
|
|
|
/* operator << */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "<<", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('l', 'S'):
|
|
|
|
/* operator <<= */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "<<=", 3);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('l', 't'):
|
|
|
|
/* operator < */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "<", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('m', 'i'):
|
|
|
|
/* operator - */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "-", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('m', 'I'):
|
|
|
|
/* operator -= */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "-=", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('m', 'l'):
|
|
|
|
/* operator * */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "*", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('m', 'L'):
|
|
|
|
/* operator *= */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "*=", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('m', 'm'):
|
|
|
|
/* operator -- */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "--", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('n', 'a'):
|
|
|
|
/* operator new[] */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_unary(ddata, "new []", 6);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('n', 'e'):
|
|
|
|
/* operator != */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "!=", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('n', 'g'):
|
|
|
|
/* operator - (unary) */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_unary(ddata, "-", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('n', 't'):
|
|
|
|
/* operator ! */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "!", 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('n', 'w'):
|
|
|
|
/* operator new */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_unary(ddata, "new", 3);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('o', 'o'):
|
|
|
|
/* operator || */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "||", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('o', 'r'):
|
|
|
|
/* operator | */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "|", 1);
|
2024-05-07 10:06:12 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('o', 'R'):
|
|
|
|
/* operator |= */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "|=", 2);
|
2024-05-07 10:06:12 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('p', 'l'):
|
|
|
|
/* operator + */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "+", 1);
|
2024-05-07 10:06:12 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('p', 'L'):
|
|
|
|
/* operator += */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "+=", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('p', 'm'):
|
|
|
|
/* operator ->* */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "->*", 3);
|
2024-05-07 10:06:12 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('p', 'p'):
|
|
|
|
/* operator ++ */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "++", 2);
|
2024-05-07 10:06:12 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('p', 's'):
|
|
|
|
/* operator + (unary) */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_unary(ddata, "+", 1);
|
2024-05-07 10:06:12 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('p', 't'):
|
|
|
|
/* operator -> */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "->", 2);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('q', 'u'):
|
|
|
|
/* operator ? */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_trinary(ddata, "?", 1, ":",
|
|
|
|
1);
|
|
|
|
|
|
|
|
case SIMPLE_HASH('r', 'm'):
|
|
|
|
/* operator % */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "%", 1);
|
|
|
|
|
|
|
|
case SIMPLE_HASH('r', 'M'):
|
|
|
|
/* operator %= */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, "%=", 2);
|
|
|
|
|
|
|
|
case SIMPLE_HASH('r', 's'):
|
|
|
|
/* operator >> */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, ">>", 2);
|
|
|
|
|
|
|
|
case SIMPLE_HASH('r', 'S'):
|
|
|
|
/* operator >>= */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_binary(ddata, ">>=", 3);
|
|
|
|
|
|
|
|
case SIMPLE_HASH('r', 'z'):
|
|
|
|
/* operator sizeof */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_unary(ddata, "sizeof", 6);
|
|
|
|
|
|
|
|
case SIMPLE_HASH('s', 'v'):
|
|
|
|
/* operator sizeof */
|
|
|
|
ddata->cur += 2;
|
|
|
|
return cpp_demangle_read_expression_unary(ddata, "sizeof", 6);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (*ddata->cur) {
|
|
|
|
case 'L':
|
|
|
|
return cpp_demangle_read_expr_primary(ddata);
|
|
|
|
case 'T':
|
|
|
|
return cpp_demangle_read_tmpl_param(ddata);
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_expression_flat(struct cpp_demangle_data *ddata, char **str)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
|
|
|
struct vector_str *output;
|
2024-05-26 13:03:50 +00:00
|
|
|
size_t i, p_idx, idx, exp_len;
|
|
|
|
char *exp;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
output = &ddata->output;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
p_idx = output->size;
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_expression(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!(exp = vector_str_substr(ddata, output, p_idx, output->size - 1,
|
|
|
|
&exp_len)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
idx = output->size;
|
2024-05-07 10:06:12 +00:00
|
|
|
for (i = p_idx; i < idx; ++i)
|
|
|
|
if (!vector_str_pop(output))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
*str = exp;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* size, capacity, ext_name */
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
vector_type_qualifier_init(struct cpp_demangle_data *ddata,
|
|
|
|
struct vector_type_qualifier *v)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!v)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
v->size = 0;
|
|
|
|
v->capacity = VECTOR_DEF_CAPACITY;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(v->q_container = (enum type_qualifier *)demangle_malloc(ddata,
|
2024-05-26 13:03:50 +00:00
|
|
|
alignof(enum type_qualifier),
|
|
|
|
sizeof(enum type_qualifier) * v->capacity)))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
ASSERT(v->q_container);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!vector_str_init(ddata, &v->ext_name)) {
|
|
|
|
demangle_free(ddata, v->q_container);
|
2024-05-26 13:03:50 +00:00
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged struct read_cmd_item *
|
2024-05-26 13:03:50 +00:00
|
|
|
vector_read_cmd_find(struct vector_read_cmd *v, enum read_cmd dst)
|
2024-05-07 10:06:12 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
int i;
|
|
|
|
|
|
|
|
if (!v || dst == READ_FAIL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
for (i = (int)v->size - 1; i >= 0; i--)
|
|
|
|
if (v->r_container[i].cmd == dst)
|
|
|
|
return &v->r_container[i];
|
|
|
|
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_function(struct cpp_demangle_data *ddata, int *ext_c,
|
|
|
|
struct vector_type_qualifier *v)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
struct type_delimit td;
|
|
|
|
struct read_cmd_item *rc;
|
|
|
|
size_t class_type_size, class_type_len, limit;
|
|
|
|
const char *class_type;
|
|
|
|
int i;
|
|
|
|
bool paren, non_cv_qualifier;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata || *ddata->cur != 'F' || !v)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
if (*ddata->cur == 'Y') {
|
|
|
|
if (ext_c)
|
|
|
|
*ext_c = 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
++ddata->cur;
|
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* Return type */
|
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur != 'E') {
|
|
|
|
if (!DEM_PUSH_STR(ddata, " "))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
non_cv_qualifier = false;
|
|
|
|
if (v->size > 0) {
|
|
|
|
for (i = 0; (size_t)i < v->size; i++) {
|
|
|
|
if (v->q_container[i] != TYPE_RST &&
|
|
|
|
v->q_container[i] != TYPE_VAT &&
|
|
|
|
v->q_container[i] != TYPE_CST) {
|
|
|
|
non_cv_qualifier = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
paren = false;
|
|
|
|
rc = vector_read_cmd_find(&ddata->cmd, READ_PTRMEM);
|
|
|
|
if (non_cv_qualifier || rc != NULL) {
|
|
|
|
if (!DEM_PUSH_STR(ddata, "("))
|
|
|
|
return 0;
|
|
|
|
paren = true;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* Push non-cv qualifiers. */
|
|
|
|
ddata->push_qualifier = PUSH_NON_CV_QUALIFIER;
|
|
|
|
if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (rc) {
|
|
|
|
if (non_cv_qualifier && !DEM_PUSH_STR(ddata, " "))
|
|
|
|
return 0;
|
|
|
|
if (!(class_type_size = ddata->class_type.size))
|
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
class_type = VEC_STR(ddata, &ddata->class_type,
|
|
|
|
class_type_size - 1);
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!class_type)
|
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(class_type_len = demangle_strlen(class_type)))
|
2024-05-26 13:03:50 +00:00
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_str(ddata, class_type,
|
|
|
|
class_type_len))
|
|
|
|
return 0;
|
|
|
|
if (!DEM_PUSH_STR(ddata, "::*"))
|
|
|
|
return 0;
|
|
|
|
/* Push pointer-to-member qualifiers. */
|
|
|
|
ddata->push_qualifier = PUSH_ALL_QUALIFIER;
|
|
|
|
if (!cpp_demangle_push_type_qualifier(ddata,
|
|
|
|
(struct vector_type_qualifier *)rc->data, NULL))
|
|
|
|
return 0;
|
|
|
|
++ddata->func_type;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (paren) {
|
|
|
|
if (!DEM_PUSH_STR(ddata, ")"))
|
|
|
|
return 0;
|
|
|
|
paren = false;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
td.paren = false;
|
|
|
|
td.firstp = true;
|
|
|
|
limit = 0;
|
|
|
|
ddata->is_functype = true;
|
|
|
|
for (;;) {
|
|
|
|
if (!cpp_demangle_read_type(ddata, &td))
|
|
|
|
return 0;
|
|
|
|
if (*ddata->cur == 'E')
|
|
|
|
break;
|
|
|
|
if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
ddata->is_functype = false;
|
|
|
|
if (td.paren) {
|
|
|
|
if (!DEM_PUSH_STR(ddata, ")"))
|
|
|
|
return 0;
|
|
|
|
td.paren = false;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* Push CV qualifiers. */
|
|
|
|
ddata->push_qualifier = PUSH_CV_QUALIFIER;
|
|
|
|
if (!cpp_demangle_push_type_qualifier(ddata, v, NULL))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->push_qualifier = PUSH_ALL_QUALIFIER;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* Release type qualifier vector. */
|
|
|
|
if (!vector_type_qualifier_init(ddata, v))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* Push ref-qualifiers. */
|
|
|
|
if (ddata->ref_qualifier) {
|
|
|
|
switch (ddata->ref_qualifier_type) {
|
|
|
|
case TYPE_REF:
|
|
|
|
if (!DEM_PUSH_STR(ddata, " &"))
|
|
|
|
return 0;
|
|
|
|
break;
|
|
|
|
case TYPE_RREF:
|
|
|
|
if (!DEM_PUSH_STR(ddata, " &&"))
|
|
|
|
return 0;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
ddata->ref_qualifier = false;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
|
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2023-07-03 04:08:52 +00:00
|
|
|
cpp_demangle_read_offset_number(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
|
|
|
bool negative;
|
|
|
|
const char *start;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!ddata || *ddata->cur == '\0')
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
/* offset could be negative */
|
|
|
|
if (*ddata->cur == 'n') {
|
|
|
|
negative = true;
|
|
|
|
start = ddata->cur + 1;
|
|
|
|
} else {
|
|
|
|
negative = false;
|
|
|
|
start = ddata->cur;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*ddata->cur != '_')
|
|
|
|
++ddata->cur;
|
|
|
|
|
|
|
|
if (negative && !DEM_PUSH_STR(ddata, "-"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
ASSERT(start);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
if (!cpp_demangle_push_str(ddata, start, ddata->cur - start))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, " "))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
|
|
|
++ddata->cur;
|
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_nv_offset(struct cpp_demangle_data *ddata)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "offset : "))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_offset_number(ddata);
|
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_v_offset(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
|
|
|
if (!ddata)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "offset : "))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_offset_number(ddata))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, "virtual offset : "))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return !cpp_demangle_read_offset_number(ddata);
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* read offset, offset are nv-offset, v-offset */
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_offset(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
|
|
|
if (!ddata)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur == 'h') {
|
|
|
|
++ddata->cur;
|
|
|
|
return cpp_demangle_read_nv_offset(ddata);
|
|
|
|
} else if (*ddata->cur == 'v') {
|
|
|
|
++ddata->cur;
|
|
|
|
return cpp_demangle_read_v_offset(ddata);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_type_flat(struct cpp_demangle_data *ddata, char **str)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
struct vector_str *output;
|
|
|
|
size_t i, p_idx, idx, type_len;
|
|
|
|
char *type;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
output = ddata->cur_output;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
p_idx = output->size;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!(type = vector_str_substr(ddata, output, p_idx, output->size - 1,
|
|
|
|
&type_len)))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
idx = output->size;
|
|
|
|
for (i = p_idx; i < idx; ++i)
|
|
|
|
if (!vector_str_pop(output))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
*str = type;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/*
|
|
|
|
* read number
|
|
|
|
* number ::= [n] <decimal>
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_number(struct cpp_demangle_data *ddata, long *rtn)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
long len, negative_factor;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata || !rtn)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
negative_factor = 1;
|
|
|
|
if (*ddata->cur == 'n') {
|
|
|
|
negative_factor = -1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ELFTC_ISDIGIT(*ddata->cur))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
len = demangle_strtol(ddata->cur, 10);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
while (ELFTC_ISDIGIT(*ddata->cur))
|
2023-07-03 04:08:52 +00:00
|
|
|
++ddata->cur;
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
ASSERT(len >= 0);
|
|
|
|
ASSERT(negative_factor == 1 || negative_factor == -1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
*rtn = len * negative_factor;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_number_as_string(struct cpp_demangle_data *ddata, char **str)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
long n;
|
|
|
|
char buf[21];
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_number(ddata, &n)) {
|
|
|
|
*str = NULL;
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_itoa(buf, n);
|
|
|
|
if (!(*str = demangle_strdup(ddata, buf)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* read encoding, encoding are function name, data name, special-name */
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_encoding(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
|
|
|
char *name, *type, *num_str;
|
|
|
|
long offset;
|
2024-06-02 02:57:32 +00:00
|
|
|
int rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata || *ddata->cur == '\0')
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* special name */
|
|
|
|
switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
|
|
|
|
case SIMPLE_HASH('G', 'A'):
|
|
|
|
if (!DEM_PUSH_STR(ddata, "hidden alias for "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
return cpp_demangle_read_encoding(ddata);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('G', 'R'):
|
|
|
|
if (!DEM_PUSH_STR(ddata, "reference temporary #"))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_name_flat(ddata, &name))
|
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
rtn = 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_number_as_string(ddata, &num_str))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean1;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, num_str))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean2;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, " for "))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean2;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!DEM_PUSH_STR(ddata, name))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean2;
|
|
|
|
rtn = 1;
|
|
|
|
clean2:
|
|
|
|
demangle_free(ddata, num_str);
|
|
|
|
clean1:
|
|
|
|
demangle_free(ddata, name);
|
|
|
|
return rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('G', 'T'):
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
switch (*ddata->cur) {
|
|
|
|
case 'n':
|
|
|
|
if (!DEM_PUSH_STR(ddata, "non-transaction clone for "))
|
|
|
|
return 0;
|
|
|
|
break;
|
|
|
|
case 't':
|
|
|
|
default:
|
|
|
|
if (!DEM_PUSH_STR(ddata, "transaction clone for "))
|
|
|
|
return 0;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
++ddata->cur;
|
|
|
|
return cpp_demangle_read_encoding(ddata);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('G', 'V'):
|
|
|
|
/* sentry object for 1 time init */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "guard variable for "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
break;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'c'):
|
|
|
|
/* virtual function covariant override thunk */
|
|
|
|
if (!DEM_PUSH_STR(ddata,
|
|
|
|
"virtual function covariant override "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_offset(ddata))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_offset(ddata))
|
|
|
|
return 0;
|
|
|
|
return cpp_demangle_read_encoding(ddata);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'C'):
|
|
|
|
/* construction vtable */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "construction vtable for "))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_type_flat(ddata, &type))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_number(ddata, &offset))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur++ != '_')
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
|
|
|
return 0;
|
|
|
|
if (!DEM_PUSH_STR(ddata, "-in-"))
|
|
|
|
return 0;
|
|
|
|
if (!DEM_PUSH_STR(ddata, type))
|
|
|
|
return 0;
|
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'D'):
|
|
|
|
/* typeinfo common proxy */
|
|
|
|
break;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'F'):
|
|
|
|
/* typeinfo fn */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "typeinfo fn for "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
return cpp_demangle_read_type(ddata, NULL);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'h'):
|
|
|
|
/* virtual function non-virtual override thunk */
|
|
|
|
if (!DEM_PUSH_STR(ddata,
|
|
|
|
"virtual function non-virtual override "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_nv_offset(ddata))
|
|
|
|
return 0;
|
|
|
|
return cpp_demangle_read_encoding(ddata);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'H'):
|
|
|
|
/* TLS init function */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "TLS init function for "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
break;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'I'):
|
|
|
|
/* typeinfo structure */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "typeinfo for "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
return cpp_demangle_read_type(ddata, NULL);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'J'):
|
|
|
|
/* java class */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "java Class for "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
return cpp_demangle_read_type(ddata, NULL);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'S'):
|
|
|
|
/* RTTI name (NTBS) */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "typeinfo name for "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
return cpp_demangle_read_type(ddata, NULL);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'T'):
|
|
|
|
/* VTT table */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "VTT for "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
return cpp_demangle_read_type(ddata, NULL);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'v'):
|
|
|
|
/* virtual function virtual override thunk */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "virtual function virtual override "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_v_offset(ddata))
|
|
|
|
return 0;
|
|
|
|
return cpp_demangle_read_encoding(ddata);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'V'):
|
|
|
|
/* virtual table */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "vtable for "))
|
|
|
|
return 0;
|
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
return cpp_demangle_read_type(ddata, NULL);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('T', 'W'):
|
|
|
|
/* TLS wrapper function */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "TLS wrapper function for "))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->cur += 2;
|
|
|
|
if (*ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
break;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_read_name(ddata);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_local_name(struct cpp_demangle_data *ddata)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
struct vector_str local_name;
|
|
|
|
struct type_delimit td;
|
|
|
|
size_t limit;
|
|
|
|
bool more_type;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata)
|
|
|
|
return 0;
|
|
|
|
if (*(++ddata->cur) == '\0')
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!vector_str_init(ddata, &local_name))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->cur_output = &local_name;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_encoding(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->cur_output = &ddata->output;
|
|
|
|
|
|
|
|
td.paren = false;
|
|
|
|
td.firstp = true;
|
|
|
|
more_type = false;
|
2023-07-03 04:08:52 +00:00
|
|
|
limit = 0;
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/*
|
|
|
|
* The first type is a return type if we just demangled template
|
|
|
|
* args. (the template args is right next to the function name,
|
|
|
|
* which means it's a template function)
|
|
|
|
*/
|
|
|
|
if (ddata->is_tmpl) {
|
|
|
|
ddata->is_tmpl = false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* Read return type */
|
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
more_type = true;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* Now we can push the name after possible return type is handled. */
|
|
|
|
if (!vector_str_push_vector(ddata, &ddata->output, &local_name))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
while (*ddata->cur != '\0') {
|
|
|
|
if (!cpp_demangle_read_type(ddata, &td))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (more_type)
|
|
|
|
more_type = false;
|
|
|
|
if (*ddata->cur == 'E')
|
|
|
|
break;
|
|
|
|
if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (more_type)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*(++ddata->cur) == '\0')
|
|
|
|
return 0;
|
|
|
|
if (td.paren) {
|
|
|
|
if (!DEM_PUSH_STR(ddata, ")"))
|
|
|
|
return 0;
|
|
|
|
td.paren = false;
|
|
|
|
}
|
|
|
|
if (*ddata->cur == 's')
|
|
|
|
++ddata->cur;
|
|
|
|
else {
|
|
|
|
if (!DEM_PUSH_STR(ddata, "::"))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_read_name(ddata))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (*ddata->cur == '_') {
|
|
|
|
++ddata->cur;
|
|
|
|
while (ELFTC_ISDIGIT(*ddata->cur))
|
2023-07-03 04:08:52 +00:00
|
|
|
++ddata->cur;
|
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_nested_name(struct cpp_demangle_data *ddata)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
struct stack_str v;
|
2024-05-07 10:06:12 +00:00
|
|
|
struct vector_str *output;
|
2024-05-26 13:03:50 +00:00
|
|
|
size_t limit, p_idx, subst_str_len;
|
|
|
|
char *subst_str;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata || *ddata->cur != 'N')
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*(++ddata->cur) == '\0')
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
do {
|
2023-07-03 04:08:52 +00:00
|
|
|
switch (*ddata->cur) {
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'r':
|
|
|
|
ddata->mem_rst = true;
|
2023-07-03 04:08:52 +00:00
|
|
|
break;
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'V':
|
|
|
|
ddata->mem_vat = true;
|
2023-07-03 04:08:52 +00:00
|
|
|
break;
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'K':
|
|
|
|
ddata->mem_cst = true;
|
2023-07-03 04:08:52 +00:00
|
|
|
break;
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'R':
|
|
|
|
ddata->mem_ref = true;
|
2023-07-03 04:08:52 +00:00
|
|
|
break;
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'O':
|
|
|
|
ddata->mem_rref = true;
|
2023-07-03 04:08:52 +00:00
|
|
|
break;
|
2024-05-26 13:03:50 +00:00
|
|
|
default:
|
|
|
|
goto next;
|
|
|
|
}
|
|
|
|
} while (*(++ddata->cur));
|
|
|
|
|
|
|
|
next:
|
|
|
|
output = ddata->cur_output;
|
|
|
|
stack_str_init(&v);
|
|
|
|
|
|
|
|
limit = 0;
|
|
|
|
for (;;) {
|
|
|
|
p_idx = output->size;
|
|
|
|
switch (*ddata->cur) {
|
|
|
|
case 'I':
|
|
|
|
if (!cpp_demangle_read_tmpl_args(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
break;
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'S':
|
|
|
|
if (!cpp_demangle_read_subst(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
break;
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'T':
|
|
|
|
if (!cpp_demangle_read_tmpl_param(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
break;
|
|
|
|
default:
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_uqname(ddata))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (p_idx == output->size)
|
|
|
|
goto next_comp;
|
|
|
|
if (!(subst_str = vector_str_substr(ddata, output, p_idx,
|
|
|
|
output->size - 1, &subst_str_len)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!stack_str_append(ddata, &v, subst_str, subst_str_len)) {
|
|
|
|
demangle_free(ddata, subst_str);
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-06-02 02:57:32 +00:00
|
|
|
}
|
|
|
|
demangle_free(ddata, subst_str);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_push_subst(ddata, v.str, v.len))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
next_comp:
|
|
|
|
if (*ddata->cur == 'E')
|
|
|
|
break;
|
|
|
|
else if (*ddata->cur != 'I' && *ddata->cur != 'C' &&
|
|
|
|
*ddata->cur != 'D' && p_idx != output->size) {
|
|
|
|
if (!DEM_PUSH_STR(ddata, "::"))
|
|
|
|
return 0;
|
|
|
|
if (!stack_str_append_str(ddata, &v, "::"))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
return 1;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_name(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
|
|
|
struct stack_str v;
|
|
|
|
struct vector_str *output;
|
|
|
|
size_t p_idx, subst_str_len;
|
|
|
|
char *subst_str;
|
2024-06-02 02:57:32 +00:00
|
|
|
int rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata || *ddata->cur == '\0')
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
output = ddata->cur_output;
|
|
|
|
|
|
|
|
subst_str = NULL;
|
|
|
|
|
|
|
|
switch (*ddata->cur) {
|
|
|
|
case 'S':
|
|
|
|
return cpp_demangle_read_subst(ddata);
|
|
|
|
case 'N':
|
|
|
|
return cpp_demangle_read_nested_name(ddata);
|
|
|
|
case 'Z':
|
|
|
|
return cpp_demangle_read_local_name(ddata);
|
|
|
|
}
|
|
|
|
|
|
|
|
stack_str_init(&v);
|
|
|
|
|
|
|
|
p_idx = output->size;
|
2024-06-02 02:57:32 +00:00
|
|
|
rtn = 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_uqname(ddata))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!(subst_str = vector_str_substr(ddata, output, p_idx,
|
|
|
|
output->size - 1, &subst_str_len)))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
|
|
|
if (subst_str_len > 8 && demangle_strstr(subst_str, "operator")) {
|
|
|
|
rtn = 1;
|
|
|
|
goto clean;
|
|
|
|
}
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!stack_str_append(ddata, &v, subst_str, subst_str_len))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_push_subst(ddata, v.str, v.len))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
2024-05-26 13:03:50 +00:00
|
|
|
|
|
|
|
if (*ddata->cur == 'I') {
|
2023-07-03 04:08:52 +00:00
|
|
|
p_idx = output->size;
|
|
|
|
if (!cpp_demangle_read_tmpl_args(ddata))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!(subst_str = vector_str_substr(ddata, output, p_idx,
|
|
|
|
output->size - 1, &subst_str_len)))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!stack_str_append(ddata, &v, subst_str, subst_str_len))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_push_subst(ddata, v.str, v.len))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
2024-05-26 13:03:50 +00:00
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
rtn = 1;
|
|
|
|
|
|
|
|
clean:
|
|
|
|
demangle_free(ddata, subst_str);
|
|
|
|
|
|
|
|
return rtn;
|
2024-05-26 13:03:50 +00:00
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_name_flat(struct cpp_demangle_data *ddata, char **str)
|
|
|
|
{
|
|
|
|
struct vector_str *output;
|
|
|
|
size_t i, p_idx, idx, name_len;
|
|
|
|
char *name;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
output = ddata->cur_output;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
p_idx = output->size;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_name(ddata))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!(name = vector_str_substr(ddata, output, p_idx, output->size - 1,
|
|
|
|
&name_len)))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
idx = output->size;
|
|
|
|
for (i = p_idx; i < idx; ++i)
|
|
|
|
if (!vector_str_pop(output))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
*str = name;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_pointer_to_member(struct cpp_demangle_data *ddata,
|
|
|
|
struct vector_type_qualifier *v)
|
|
|
|
{
|
|
|
|
size_t class_type_len, i, idx, p_idx;
|
|
|
|
int p_func_type, rtn;
|
|
|
|
char *class_type;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata || *ddata->cur != 'M' || *(++ddata->cur) == '\0')
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
p_idx = ddata->output.size;
|
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!(class_type = vector_str_substr(ddata, &ddata->output, p_idx,
|
|
|
|
ddata->output.size - 1, &class_type_len)))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
rtn = 0;
|
|
|
|
idx = ddata->output.size;
|
|
|
|
for (i = p_idx; i < idx; ++i)
|
|
|
|
if (!vector_str_pop(&ddata->output))
|
|
|
|
goto clean1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!vector_read_cmd_push(ddata, &ddata->cmd, READ_PTRMEM, v))
|
|
|
|
goto clean1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!vector_str_push(ddata, &ddata->class_type, class_type,
|
|
|
|
class_type_len))
|
|
|
|
goto clean2;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
p_func_type = ddata->func_type;
|
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
|
|
|
goto clean3;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (p_func_type == ddata->func_type) {
|
|
|
|
if (!DEM_PUSH_STR(ddata, " "))
|
|
|
|
goto clean3;
|
|
|
|
if (!cpp_demangle_push_str(ddata, class_type, class_type_len))
|
|
|
|
goto clean3;
|
|
|
|
if (!DEM_PUSH_STR(ddata, "::*"))
|
|
|
|
goto clean3;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
rtn = 1;
|
|
|
|
clean3:
|
|
|
|
if (!vector_str_pop(&ddata->class_type))
|
|
|
|
rtn = 0;
|
|
|
|
clean2:
|
|
|
|
if (!vector_read_cmd_pop(&ddata->cmd))
|
|
|
|
rtn = 0;
|
|
|
|
clean1:
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!vector_type_qualifier_init(ddata, v))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return rtn;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* read source-name, source-name is <len> <ID> */
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_sname(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
|
|
|
long len;
|
|
|
|
int err;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata || !cpp_demangle_read_number(ddata, &len) || len <= 0)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (len == 12 && !demangle_memcmp("_GLOBAL__N_1", ddata->cur, 12))
|
2024-05-26 13:03:50 +00:00
|
|
|
err = DEM_PUSH_STR(ddata, "(anonymous namespace)");
|
|
|
|
else
|
|
|
|
err = cpp_demangle_push_str(ddata, ddata->cur, len);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!err)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
ASSERT(ddata->cur_output->size > 0);
|
|
|
|
if (!vector_read_cmd_find(&ddata->cmd, READ_TMPL))
|
2024-06-02 02:57:32 +00:00
|
|
|
ddata->last_sname = VEC_STR(ddata, ddata->cur_output,
|
|
|
|
ddata->cur_output->size - 1);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->cur += len;
|
|
|
|
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_subst_stdtmpl(struct cpp_demangle_data *ddata,
|
|
|
|
const char *str)
|
|
|
|
{
|
|
|
|
struct vector_str *output;
|
|
|
|
size_t p_idx, substr_len, len;
|
|
|
|
char *subst_str, *substr;
|
|
|
|
|
|
|
|
if (!ddata || !str)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(len = demangle_strlen(str)))
|
2024-05-26 13:03:50 +00:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
output = ddata->cur_output;
|
|
|
|
|
|
|
|
p_idx = output->size;
|
|
|
|
substr = NULL;
|
|
|
|
subst_str = NULL;
|
|
|
|
|
|
|
|
if (!cpp_demangle_read_tmpl_args(ddata))
|
|
|
|
return 0;
|
|
|
|
if (!(substr = vector_str_substr(ddata, output, p_idx, output->size - 1,
|
|
|
|
&substr_len)))
|
|
|
|
return 0;
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(subst_str = (char *)demangle_malloc(ddata, alignof(char),
|
2024-05-26 13:03:50 +00:00
|
|
|
sizeof(char) * (substr_len + len + 1))))
|
|
|
|
return 0;
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_memcpy(subst_str, str, len);
|
|
|
|
demangle_memcpy(subst_str + len, substr, substr_len);
|
2024-05-26 13:03:50 +00:00
|
|
|
subst_str[substr_len + len] = '\0';
|
|
|
|
|
|
|
|
if (!cpp_demangle_push_subst(ddata, subst_str, substr_len + len))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_subst_std(struct cpp_demangle_data *ddata)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-26 13:03:50 +00:00
|
|
|
struct vector_str *output, v;
|
|
|
|
size_t p_idx, subst_str_len;
|
|
|
|
char *subst_str;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!vector_str_init(ddata, &v))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
subst_str = NULL;
|
|
|
|
if (!DEM_PUSH_STR(ddata, "std::"))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!VEC_PUSH_STR(&v, "std::"))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
ddata->cur += 2;
|
|
|
|
|
|
|
|
output = ddata->cur_output;
|
|
|
|
|
|
|
|
p_idx = output->size;
|
|
|
|
if (!cpp_demangle_read_uqname(ddata))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!(subst_str = vector_str_substr(ddata, output, p_idx,
|
|
|
|
output->size - 1, &subst_str_len)))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!vector_str_push(ddata, &v, subst_str, subst_str_len))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!cpp_demangle_push_subst_v(ddata, &v))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (*ddata->cur == 'I') {
|
|
|
|
p_idx = output->size;
|
|
|
|
if (!cpp_demangle_read_tmpl_args(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!(subst_str = vector_str_substr(ddata, output, p_idx,
|
|
|
|
output->size - 1, &subst_str_len)))
|
|
|
|
return 0;
|
|
|
|
if (!vector_str_push(ddata, &v, subst_str, subst_str_len))
|
|
|
|
return 0;
|
|
|
|
if (!cpp_demangle_push_subst_v(ddata, &v))
|
|
|
|
return 0;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_subst(struct cpp_demangle_data *ddata)
|
|
|
|
{
|
|
|
|
long nth;
|
|
|
|
|
|
|
|
if (!ddata || *ddata->cur == '\0')
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
/* abbreviations of the form Sx */
|
|
|
|
switch (SIMPLE_HASH(*ddata->cur, *(ddata->cur + 1))) {
|
|
|
|
case SIMPLE_HASH('S', 'a'):
|
|
|
|
/* std::allocator */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "std::allocator"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur == 'I')
|
|
|
|
return cpp_demangle_read_subst_stdtmpl(ddata,
|
|
|
|
"std::allocator");
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('S', 'b'):
|
|
|
|
/* std::basic_string */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "std::basic_string"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur == 'I')
|
|
|
|
return cpp_demangle_read_subst_stdtmpl(ddata,
|
|
|
|
"std::basic_string");
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('S', 'd'):
|
|
|
|
/* std::basic_iostream<char, std::char_traits<char>> */
|
|
|
|
if (!DEM_PUSH_STR(ddata,
|
|
|
|
"std::basic_iostream<char, "
|
|
|
|
"std::char_traits<char>>"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->last_sname = "basic_iostream";
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur == 'I')
|
|
|
|
return cpp_demangle_read_subst_stdtmpl(ddata,
|
|
|
|
"std::basic_iostream<char, std::char_traits"
|
|
|
|
"<char>>");
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('S', 'i'):
|
|
|
|
/* std::basic_istream<char, std::char_traits<char>> */
|
|
|
|
if (!DEM_PUSH_STR(ddata,
|
|
|
|
"std::basic_istream<char, "
|
|
|
|
"std::char_traits<char>>"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->last_sname = "basic_istream";
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur == 'I')
|
|
|
|
return cpp_demangle_read_subst_stdtmpl(ddata,
|
|
|
|
"std::basic_istream<char, std::char_traits"
|
|
|
|
"<char>>");
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('S', 'o'):
|
|
|
|
/* std::basic_ostream<char, std::char_traits<char>> */
|
|
|
|
if (!DEM_PUSH_STR(ddata,
|
|
|
|
"std::basic_ostream<char, "
|
|
|
|
"std::char_traits<char>>"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->last_sname = "basic_ostream";
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur == 'I')
|
|
|
|
return cpp_demangle_read_subst_stdtmpl(ddata,
|
|
|
|
"std::basic_ostream<char, std::char_traits"
|
|
|
|
"<char>>");
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('S', 's'):
|
|
|
|
/*
|
|
|
|
* std::string<char, std::char_traits<char>,
|
|
|
|
* std::allocator<char>>
|
|
|
|
*
|
|
|
|
* a.k.a std::string
|
|
|
|
*
|
|
|
|
* [jart] made it std::string for consistency with libcxxabi
|
|
|
|
*/
|
|
|
|
if (!DEM_PUSH_STR(ddata, "std::string"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->last_sname = "string";
|
2023-07-03 04:08:52 +00:00
|
|
|
ddata->cur += 2;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*ddata->cur == 'I')
|
|
|
|
return cpp_demangle_read_subst_stdtmpl(ddata,
|
|
|
|
"std::string");
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case SIMPLE_HASH('S', 't'):
|
|
|
|
/* std:: */
|
|
|
|
return cpp_demangle_read_subst_std(ddata);
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (*(++ddata->cur) == '\0')
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* Skip unknown substitution abbreviations. */
|
|
|
|
if (!(*ddata->cur >= '0' && *ddata->cur <= '9') &&
|
|
|
|
!(*ddata->cur >= 'A' && *ddata->cur <= 'Z') && *ddata->cur != '_') {
|
|
|
|
++ddata->cur;
|
2024-05-07 10:06:12 +00:00
|
|
|
return 1;
|
2024-05-26 13:03:50 +00:00
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* substitution */
|
|
|
|
if (*ddata->cur == '_')
|
|
|
|
return cpp_demangle_get_subst(ddata, 0);
|
|
|
|
else {
|
|
|
|
/* substitution number is base 36 */
|
2024-06-02 02:57:32 +00:00
|
|
|
nth = demangle_strtol(ddata->cur, 36);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* first was '_', so increase one */
|
|
|
|
++nth;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
while (*ddata->cur != '_')
|
|
|
|
++ddata->cur;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
ASSERT(nth > 0);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return cpp_demangle_get_subst(ddata, nth);
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
/* NOTREACHED */
|
|
|
|
return 0;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
vector_type_qualifier_push(struct cpp_demangle_data *ddata,
|
|
|
|
struct vector_type_qualifier *v, enum type_qualifier t)
|
|
|
|
{
|
|
|
|
enum type_qualifier *tmp_ctn;
|
|
|
|
size_t tmp_cap;
|
|
|
|
size_t i;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!v)
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (v->size == v->capacity) {
|
|
|
|
tmp_cap = BUFFER_GROW(v->capacity);
|
2024-06-02 02:57:32 +00:00
|
|
|
if (!(tmp_ctn = (enum type_qualifier *)demangle_malloc(ddata,
|
2024-05-26 13:03:50 +00:00
|
|
|
alignof(enum type_qualifier),
|
|
|
|
sizeof(enum type_qualifier) * tmp_cap)))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
for (i = 0; i < v->size; ++i)
|
|
|
|
tmp_ctn[i] = v->q_container[i];
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_free(ddata, v->q_container);
|
2024-05-26 13:03:50 +00:00
|
|
|
v->q_container = tmp_ctn;
|
|
|
|
v->capacity = tmp_cap;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
v->q_container[v->size] = t;
|
|
|
|
++v->size;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
return 1;
|
|
|
|
}
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-26 13:03:50 +00:00
|
|
|
cpp_demangle_read_type(struct cpp_demangle_data *ddata, struct type_delimit *td)
|
|
|
|
{
|
|
|
|
struct vector_type_qualifier v;
|
2024-06-02 02:57:32 +00:00
|
|
|
struct vector_str *output, sv;
|
2024-05-26 13:03:50 +00:00
|
|
|
size_t p_idx, type_str_len, subst_str_len;
|
|
|
|
int extern_c, is_builtin;
|
|
|
|
long len;
|
|
|
|
const char *p;
|
|
|
|
char *type_str, *exp_str, *num_str, *subst_str;
|
|
|
|
bool skip_ref_qualifier, omit_void;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!ddata)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
output = ddata->cur_output;
|
|
|
|
if (td) {
|
|
|
|
if (td->paren == false) {
|
|
|
|
if (!DEM_PUSH_STR(ddata, "("))
|
|
|
|
return 0;
|
|
|
|
if (ddata->output.size < 2)
|
|
|
|
return 0;
|
|
|
|
td->paren = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!td->firstp) {
|
|
|
|
if (*ddata->cur != 'I') {
|
|
|
|
if (!DEM_PUSH_STR(ddata, ", "))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ASSERT(output);
|
|
|
|
/*
|
|
|
|
* [r, V, K] [P, R, O, C, G, U] builtin, function, class-enum, array
|
|
|
|
* pointer-to-member, template-param, template-template-param, subst
|
|
|
|
*/
|
|
|
|
|
|
|
|
if (!vector_type_qualifier_init(ddata, &v))
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
extern_c = 0;
|
|
|
|
is_builtin = 1;
|
|
|
|
p_idx = output->size;
|
|
|
|
type_str = exp_str = num_str = NULL;
|
|
|
|
skip_ref_qualifier = false;
|
|
|
|
|
|
|
|
again:
|
|
|
|
|
|
|
|
/* Clear ref-qualifier flag */
|
|
|
|
if (*ddata->cur != 'R' && *ddata->cur != 'O' && *ddata->cur != 'E')
|
|
|
|
ddata->ref_qualifier = false;
|
|
|
|
|
|
|
|
/* builtin type */
|
|
|
|
switch (*ddata->cur) {
|
|
|
|
case 'a':
|
|
|
|
/* signed char */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "signed char"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'A':
|
|
|
|
/* array type */
|
|
|
|
if (!cpp_demangle_read_array(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
is_builtin = 0;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'b':
|
|
|
|
/* bool */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "bool"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'C':
|
|
|
|
/* complex pair */
|
|
|
|
if (!vector_type_qualifier_push(ddata, &v, TYPE_CMX))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
|
|
|
goto again;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'c':
|
|
|
|
/* char */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "char"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'd':
|
|
|
|
/* double */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "double"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'D':
|
|
|
|
++ddata->cur;
|
|
|
|
switch (*ddata->cur) {
|
|
|
|
case 'a':
|
|
|
|
/* auto */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "auto"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
break;
|
|
|
|
case 'c':
|
|
|
|
/* decltype(auto) */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "decltype(auto)"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
break;
|
|
|
|
case 'd':
|
|
|
|
/* IEEE 754r decimal floating point (64 bits) */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "decimal64"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
break;
|
|
|
|
case 'e':
|
|
|
|
/* IEEE 754r decimal floating point (128 bits) */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "decimal128"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
break;
|
|
|
|
case 'f':
|
|
|
|
/* IEEE 754r decimal floating point (32 bits) */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "decimal32"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
break;
|
|
|
|
case 'h':
|
|
|
|
/* IEEE 754r half-precision floating point (16 bits) */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "half"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
break;
|
|
|
|
case 'i':
|
|
|
|
/* char32_t */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "char32_t"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
break;
|
|
|
|
case 'n':
|
|
|
|
/* std::nullptr_t (i.e., decltype(nullptr)) */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "decltype(nullptr)"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
break;
|
|
|
|
case 's':
|
|
|
|
/* char16_t */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "char16_t"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
break;
|
|
|
|
case 'v':
|
|
|
|
/* gcc vector_size extension. */
|
|
|
|
++ddata->cur;
|
|
|
|
if (*ddata->cur == '_') {
|
|
|
|
++ddata->cur;
|
|
|
|
if (!cpp_demangle_read_expression_flat(ddata,
|
|
|
|
&exp_str))
|
|
|
|
return 0;
|
|
|
|
if (!VEC_PUSH_STR(&v.ext_name, exp_str))
|
|
|
|
return 0;
|
|
|
|
} else {
|
|
|
|
if (!cpp_demangle_read_number_as_string(ddata,
|
|
|
|
&num_str))
|
|
|
|
return 0;
|
|
|
|
if (!VEC_PUSH_STR(&v.ext_name, num_str))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (*ddata->cur != '_')
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
if (!vector_type_qualifier_push(ddata, &v, TYPE_VEC))
|
|
|
|
return 0;
|
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
|
|
|
goto again;
|
|
|
|
default:
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
}
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'e':
|
|
|
|
/* long double */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "long double"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'E':
|
|
|
|
/* unexpected end except ref-qualifiers */
|
|
|
|
if (ddata->ref_qualifier && ddata->is_functype) {
|
|
|
|
skip_ref_qualifier = true;
|
|
|
|
/* Pop the delimiter. */
|
|
|
|
cpp_demangle_pop_str(ddata);
|
|
|
|
goto rtn;
|
|
|
|
}
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'f':
|
|
|
|
/* float */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "float"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'F':
|
|
|
|
/* function */
|
|
|
|
if (!cpp_demangle_read_function(ddata, &extern_c, &v))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
is_builtin = 0;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'g':
|
|
|
|
/* __float128 */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "__float128"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'G':
|
|
|
|
/* imaginary */
|
|
|
|
if (!vector_type_qualifier_push(ddata, &v, TYPE_IMG))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
|
|
|
goto again;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'h':
|
|
|
|
/* unsigned char */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "unsigned char"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'i':
|
|
|
|
/* int */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "int"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'I':
|
|
|
|
/* template args. */
|
|
|
|
/* handles <substitute><template-args> */
|
|
|
|
p_idx = output->size;
|
|
|
|
if (!cpp_demangle_read_tmpl_args(ddata))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!(subst_str = vector_str_substr(ddata, output, p_idx,
|
|
|
|
output->size - 1, &subst_str_len)))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
|
|
|
if (!vector_str_init(ddata, &sv)) {
|
|
|
|
demangle_free(ddata, subst_str);
|
|
|
|
goto clean;
|
|
|
|
}
|
|
|
|
if (!vector_str_push(ddata, &sv, subst_str, subst_str_len)) {
|
|
|
|
demangle_free(ddata, subst_str);
|
|
|
|
vector_str_dest(ddata, &sv);
|
|
|
|
goto clean;
|
|
|
|
}
|
|
|
|
demangle_free(ddata, subst_str);
|
|
|
|
if (!cpp_demangle_push_subst_v(ddata, &sv)) {
|
|
|
|
vector_str_dest(ddata, &sv);
|
|
|
|
goto clean;
|
|
|
|
}
|
|
|
|
vector_str_dest(ddata, &sv);
|
2024-05-26 13:03:50 +00:00
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'j':
|
|
|
|
/* unsigned int */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "unsigned int"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'K':
|
|
|
|
/* const */
|
|
|
|
if (!vector_type_qualifier_push(ddata, &v, TYPE_CST))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
|
|
|
goto again;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'l':
|
|
|
|
/* long */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "long"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'm':
|
|
|
|
/* unsigned long */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "unsigned long"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
|
|
|
|
goto rtn;
|
|
|
|
case 'M':
|
|
|
|
/* pointer to member */
|
|
|
|
if (!cpp_demangle_read_pointer_to_member(ddata, &v))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
is_builtin = 0;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'n':
|
|
|
|
/* __int128 */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "__int128"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'o':
|
|
|
|
/* unsigned __int128 */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "unsigned __int128"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'O':
|
|
|
|
/* rvalue reference */
|
|
|
|
if (ddata->ref_qualifier)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!vector_type_qualifier_push(ddata, &v, TYPE_RREF))
|
|
|
|
return 0;
|
|
|
|
ddata->ref_qualifier = true;
|
|
|
|
ddata->ref_qualifier_type = TYPE_RREF;
|
|
|
|
++ddata->cur;
|
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
|
|
|
goto again;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'P':
|
|
|
|
/* pointer */
|
|
|
|
if (!vector_type_qualifier_push(ddata, &v, TYPE_PTR))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
|
|
|
goto again;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'r':
|
|
|
|
/* restrict */
|
|
|
|
if (!vector_type_qualifier_push(ddata, &v, TYPE_RST))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
|
|
|
goto again;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'R':
|
|
|
|
/* reference */
|
|
|
|
if (ddata->ref_qualifier)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!vector_type_qualifier_push(ddata, &v, TYPE_REF))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->ref_qualifier = true;
|
|
|
|
ddata->ref_qualifier_type = TYPE_REF;
|
|
|
|
++ddata->cur;
|
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
|
|
|
goto again;
|
|
|
|
|
|
|
|
case 's':
|
|
|
|
/* short, local string */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "short"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'S':
|
|
|
|
/* substitution */
|
|
|
|
if (!cpp_demangle_read_subst(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
is_builtin = 0;
|
|
|
|
goto rtn;
|
|
|
|
|
|
|
|
case 't':
|
|
|
|
/* unsigned short */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "unsigned short"))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
|
|
|
|
|
|
|
case 'T':
|
|
|
|
/* template parameter */
|
|
|
|
if (!cpp_demangle_read_tmpl_param(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
is_builtin = 0;
|
|
|
|
goto rtn;
|
|
|
|
|
|
|
|
case 'u':
|
|
|
|
/* vendor extended builtin */
|
|
|
|
++ddata->cur;
|
|
|
|
if (!cpp_demangle_read_sname(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
is_builtin = 0;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'U':
|
|
|
|
/* vendor extended type qualifier */
|
|
|
|
++ddata->cur;
|
|
|
|
if (!cpp_demangle_read_number(ddata, &len))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (len <= 0)
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!vector_str_push(ddata, &v.ext_name, ddata->cur, len))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
ddata->cur += len;
|
|
|
|
if (!vector_type_qualifier_push(ddata, &v, TYPE_EXT))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2024-05-26 13:03:50 +00:00
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
|
|
|
goto again;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'v':
|
|
|
|
/* void */
|
|
|
|
omit_void = false;
|
|
|
|
if (td && td->firstp) {
|
|
|
|
/*
|
|
|
|
* peek into next bytes and see if we should omit
|
|
|
|
* the "void".
|
|
|
|
*/
|
|
|
|
omit_void = true;
|
|
|
|
for (p = ddata->cur + 1; *p != '\0'; p++) {
|
|
|
|
if (*p == 'E')
|
|
|
|
break;
|
|
|
|
if (*p != 'R' && *p != 'O') {
|
|
|
|
omit_void = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!omit_void && !DEM_PUSH_STR(ddata, "void"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'V':
|
|
|
|
/* volatile */
|
|
|
|
if (!vector_type_qualifier_push(ddata, &v, TYPE_VAT))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
|
|
|
goto again;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'w':
|
|
|
|
/* wchar_t */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "wchar_t"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'x':
|
|
|
|
/* long long */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "long long"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'y':
|
|
|
|
/* unsigned long long */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "unsigned long long"))
|
|
|
|
return 0;
|
|
|
|
++ddata->cur;
|
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
case 'z':
|
|
|
|
/* ellipsis */
|
|
|
|
if (!DEM_PUSH_STR(ddata, "..."))
|
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
++ddata->cur;
|
2024-05-26 13:03:50 +00:00
|
|
|
goto rtn;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!cpp_demangle_read_name(ddata))
|
2024-05-07 10:06:12 +00:00
|
|
|
return 0;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
is_builtin = 0;
|
|
|
|
rtn:
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
type_str = vector_str_substr(ddata, output, p_idx, output->size - 1,
|
|
|
|
&type_str_len);
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
if (is_builtin == 0) {
|
|
|
|
if (!vector_str_find(ddata, &ddata->subst, type_str,
|
|
|
|
type_str_len) &&
|
2024-05-26 13:03:50 +00:00
|
|
|
!vector_str_push(ddata, &ddata->subst, type_str,
|
|
|
|
type_str_len))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (!skip_ref_qualifier &&
|
|
|
|
!cpp_demangle_push_type_qualifier(ddata, &v, type_str))
|
2024-06-02 02:57:32 +00:00
|
|
|
goto clean;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-05-26 13:03:50 +00:00
|
|
|
if (td)
|
|
|
|
td->firstp = false;
|
2023-07-03 04:08:52 +00:00
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_free(ddata, type_str);
|
|
|
|
demangle_free(ddata, exp_str);
|
|
|
|
demangle_free(ddata, num_str);
|
|
|
|
vector_type_qualifier_dest(ddata, &v);
|
|
|
|
|
|
|
|
return (1);
|
|
|
|
clean:
|
|
|
|
demangle_free(ddata, type_str);
|
|
|
|
demangle_free(ddata, exp_str);
|
|
|
|
demangle_free(ddata, num_str);
|
|
|
|
vector_type_qualifier_dest(ddata, &v);
|
|
|
|
|
|
|
|
return (0);
|
2024-05-07 10:06:12 +00:00
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
|
|
|
cpp_demangle_copy_output(struct cpp_demangle_data *ddata, char *buf,
|
|
|
|
const struct vector_str *v, size_t buflen)
|
2024-05-07 10:06:12 +00:00
|
|
|
{
|
|
|
|
size_t i, j, len = 0;
|
|
|
|
if (!v)
|
|
|
|
return -1;
|
|
|
|
for (i = 0; i < v->size; ++i)
|
2024-06-02 02:57:32 +00:00
|
|
|
for (j = 0; VEC_STR(ddata, v, i)[j]; ++j) {
|
2024-05-07 10:06:12 +00:00
|
|
|
if (len < buflen)
|
2024-06-02 02:57:32 +00:00
|
|
|
buf[len] = VEC_STR(ddata, v, i)[j];
|
2024-05-07 10:06:12 +00:00
|
|
|
++len;
|
|
|
|
}
|
|
|
|
if (buflen) {
|
|
|
|
i = len;
|
|
|
|
if (i >= buflen)
|
|
|
|
i = buflen - 1;
|
|
|
|
buf[i] = 0;
|
|
|
|
}
|
|
|
|
if (len < buflen)
|
|
|
|
return len;
|
|
|
|
else
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
static privileged int
|
2024-05-07 10:06:12 +00:00
|
|
|
failure(char *buf, const char *org, size_t buflen)
|
|
|
|
{
|
2024-06-02 02:57:32 +00:00
|
|
|
demangle_strlcpy(buf, org, buflen);
|
2024-05-07 10:06:12 +00:00
|
|
|
return -1;
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
|
|
|
|
2023-07-07 17:26:07 +00:00
|
|
|
/**
|
2024-05-07 10:06:12 +00:00
|
|
|
* Decodes IA-64 C++ ABI style symbol.
|
2023-07-07 17:26:07 +00:00
|
|
|
*
|
2024-05-07 10:06:12 +00:00
|
|
|
* This function is designed to be safe to call from asynchronous signal
|
|
|
|
* handlers, since dynamic memory is allocated from the end of `buf`. As
|
|
|
|
* such it's important to provide a very generous amount of memory here.
|
2023-07-07 17:26:07 +00:00
|
|
|
*
|
2024-05-07 10:06:12 +00:00
|
|
|
* If you expect your symbols to be 100 characters long, you should pass
|
2024-06-02 02:57:32 +00:00
|
|
|
* at least 2000 bytes of buffer. If this function runs out of memory it
|
2024-05-07 10:06:12 +00:00
|
|
|
* will still create a NUL-terminated string in buf. On complete failure
|
|
|
|
* this will simply be the original string copied. On truncation it will
|
|
|
|
* be a partially copied result. In both cases, -1 is returned. The size
|
|
|
|
* of the output is only returned if this routine is fully succesful. To
|
|
|
|
* successfully cover nearly all the test cases from libcxxabi use 65536
|
2024-05-08 00:36:17 +00:00
|
|
|
* and to be able to print 99% of the symbols LLVM's libcxx.a, use 5632.
|
2023-07-07 17:26:07 +00:00
|
|
|
*
|
2024-05-07 10:06:12 +00:00
|
|
|
* It's important to call ismangled() before this, since non-c++ symbols
|
|
|
|
* have a special meaning; for example, "g" will return "__float128". It
|
|
|
|
* should be noted that this routine won't decode c++ symbols containing
|
|
|
|
* floating point numbers.
|
2023-07-07 17:26:07 +00:00
|
|
|
*
|
2024-05-07 10:06:12 +00:00
|
|
|
* **WARNING**: This implementation isn't as mature as __cxa_demangle().
|
|
|
|
* It passes 27,124 out of the 29,798 libcxxabi test cases.
|
2023-07-07 17:26:07 +00:00
|
|
|
*
|
2024-05-07 10:06:12 +00:00
|
|
|
* @param buf is where nul-terminated output string is stored
|
|
|
|
* @param buflen should have at least 8192 bytes of memory
|
|
|
|
* @return bytes of output name or -1 upon error or truncation
|
|
|
|
* @asyncsignalsafe
|
2023-07-07 17:26:07 +00:00
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
privileged int
|
2024-05-07 10:06:12 +00:00
|
|
|
__demangle(char *buf, const char *org, size_t buflen)
|
2023-07-03 04:08:52 +00:00
|
|
|
{
|
2024-05-07 10:06:12 +00:00
|
|
|
struct cpp_demangle_data ddata[1];
|
|
|
|
struct vector_str ret_type;
|
|
|
|
struct type_delimit td;
|
|
|
|
ssize_t org_len;
|
|
|
|
unsigned int limit;
|
|
|
|
bool has_ret = false, more_type = false;
|
|
|
|
|
2024-06-02 02:57:32 +00:00
|
|
|
/* Use output buffer as heap memory. */
|
|
|
|
int max_align = sizeof(char *);
|
|
|
|
buflen = buflen > 65536 ? 65536 : buflen;
|
|
|
|
ddata->free = 0;
|
|
|
|
ddata->heap = ((uintptr_t)buf + max_align - 1) & -max_align;
|
|
|
|
ddata->hoff = (buflen & -max_align) - (ddata->heap - (uintptr_t)buf);
|
2024-05-07 10:06:12 +00:00
|
|
|
|
|
|
|
/* Try demangling as a type for short encodings. */
|
2024-06-02 02:57:32 +00:00
|
|
|
org_len = demangle_strlen(org);
|
2024-05-07 10:06:12 +00:00
|
|
|
if ((org_len < 2) || (org[0] != '_' || org[1] != 'Z')) {
|
|
|
|
if (!cpp_demangle_data_init(ddata, org))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (!cpp_demangle_read_type(ddata, 0))
|
|
|
|
return failure(buf, org, buflen);
|
2024-06-02 02:57:32 +00:00
|
|
|
return cpp_demangle_copy_output(ddata, buf, &ddata->output,
|
|
|
|
buflen);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
2024-06-02 02:57:32 +00:00
|
|
|
if (org_len > 11 && !demangle_strncmp(org, "_GLOBAL__I_", 11)) {
|
2024-05-07 10:06:12 +00:00
|
|
|
if (!vector_str_init(ddata, &ret_type))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (!VEC_PUSH_STR(&ret_type, "global constructors keyed to "))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (!VEC_PUSH_STR(&ret_type, org + 11))
|
|
|
|
return failure(buf, org, buflen);
|
2024-06-02 02:57:32 +00:00
|
|
|
return cpp_demangle_copy_output(ddata, buf, &ddata->output,
|
|
|
|
buflen);
|
2024-05-07 10:06:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!cpp_demangle_data_init(ddata, org + 2))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
|
|
|
|
if (!cpp_demangle_read_encoding(ddata))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Pop function name from substitution candidate list.
|
|
|
|
*/
|
|
|
|
if (*ddata->cur && ddata->subst.size >= 1) {
|
|
|
|
if (!vector_str_pop(&ddata->subst))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
}
|
|
|
|
|
|
|
|
td.paren = false;
|
|
|
|
td.firstp = true;
|
|
|
|
limit = 0;
|
|
|
|
|
|
|
|
/*
|
|
|
|
* The first type is a return type if we just demangled template
|
|
|
|
* args. (the template args is right next to the function name,
|
|
|
|
* which means it's a template function)
|
|
|
|
*/
|
|
|
|
if (ddata->is_tmpl) {
|
|
|
|
ddata->is_tmpl = false;
|
|
|
|
if (!vector_str_init(ddata, &ret_type))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
ddata->cur_output = &ret_type;
|
|
|
|
has_ret = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
while (*ddata->cur != '\0') {
|
|
|
|
/*
|
|
|
|
* Breaking at some gcc info at tail. e.g) @@GLIBCXX_3.4
|
|
|
|
*/
|
|
|
|
if (*ddata->cur == '@' && *(ddata->cur + 1) == '@')
|
|
|
|
break;
|
|
|
|
|
|
|
|
if (has_ret) {
|
|
|
|
/* Read return type */
|
|
|
|
if (!cpp_demangle_read_type(ddata, NULL))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
} else {
|
|
|
|
/* Read function arg type */
|
|
|
|
if (!cpp_demangle_read_type(ddata, &td))
|
|
|
|
return failure(buf, org, buflen);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
2024-05-07 10:06:12 +00:00
|
|
|
|
|
|
|
if (has_ret) {
|
|
|
|
/* Push return type to the beginning */
|
|
|
|
if (!VEC_PUSH_STR(&ret_type, " "))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (!vector_str_push_vector_head(ddata, &ddata->output,
|
|
|
|
&ret_type))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
ddata->cur_output = &ddata->output;
|
|
|
|
has_ret = false;
|
|
|
|
more_type = true;
|
|
|
|
} else if (more_type) {
|
|
|
|
more_type = false;
|
|
|
|
}
|
|
|
|
if (limit++ > CPP_DEMANGLE_TRY_LIMIT)
|
|
|
|
return failure(buf, org, buflen);
|
2023-07-03 04:08:52 +00:00
|
|
|
}
|
2024-05-07 10:06:12 +00:00
|
|
|
if (more_type)
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
|
|
|
|
if (!ddata->output.size)
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (td.paren && !VEC_PUSH_STR(&ddata->output, ")"))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (ddata->mem_vat && !VEC_PUSH_STR(&ddata->output, " volatile"))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (ddata->mem_cst && !VEC_PUSH_STR(&ddata->output, " const"))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (ddata->mem_rst && !VEC_PUSH_STR(&ddata->output, " restrict"))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (ddata->mem_ref && !VEC_PUSH_STR(&ddata->output, " &"))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (ddata->mem_rref && !VEC_PUSH_STR(&ddata->output, " &&"))
|
|
|
|
return failure(buf, org, buflen);
|
|
|
|
if (ddata->hoff < 32)
|
|
|
|
return failure(buf, org, buflen);
|
2024-06-02 02:57:32 +00:00
|
|
|
return cpp_demangle_copy_output(ddata, buf, &ddata->output,
|
|
|
|
ddata->hoff);
|
2024-05-07 10:06:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns true if string is mangled by IA-64 C++ ABI style.
|
|
|
|
*
|
|
|
|
* This means it starts with either "_Z" or "_GLOBAL__I_".
|
|
|
|
*/
|
2024-06-02 02:57:32 +00:00
|
|
|
privileged int
|
2024-05-07 10:06:12 +00:00
|
|
|
__is_mangled(const char *org)
|
|
|
|
{
|
2024-06-02 02:57:32 +00:00
|
|
|
return demangle_startswith(org, "_Z") ||
|
|
|
|
demangle_startswith(org, "_GLOBAL__I_");
|
2023-07-07 17:26:07 +00:00
|
|
|
}
|