Path: blob/main/contrib/elftoolchain/cxxfilt/cxxfilt.c
39507 views
/*-1* Copyright (c) 2009 Kai Wang2* All rights reserved.3*4* Redistribution and use in source and binary forms, with or without5* modification, are permitted provided that the following conditions6* are met:7* 1. Redistributions of source code must retain the above copyright8* notice, this list of conditions and the following disclaimer9* in this position and unchanged.10* 2. Redistributions in binary form must reproduce the above copyright11* notice, this list of conditions and the following disclaimer in the12* documentation and/or other materials provided with the distribution.13*14* THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR15* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES16* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.17* IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,18* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT19* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,20* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY21* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT22* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF23* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.24*/2526#include <sys/param.h>2728#include <capsicum_helpers.h>29#include <ctype.h>30#include <err.h>31#include <getopt.h>32#include <libelftc.h>33#include <stdlib.h>34#include <stdio.h>35#include <string.h>3637#include "_elftc.h"3839ELFTC_VCSID("$Id: cxxfilt.c 3499 2016-11-25 16:06:29Z emaste $");4041#define STRBUFSZ 81924243static int stripus = 0;44static int noparam = 0;45static int format = 0;4647enum options48{49OPTION_HELP,50OPTION_VERSION51};5253static struct option longopts[] =54{55{"format", required_argument, NULL, 's'},56{"help", no_argument, NULL, OPTION_HELP},57{"no-params", no_argument, NULL, 'p'},58{"no-strip-underscores", no_argument, NULL, 'n'},59{"strip-underscores", no_argument, NULL, '_'},60{"version", no_argument, NULL, 'V'},61{NULL, 0, NULL, 0}62};6364static struct {65const char *fname;66int fvalue;67} flist[] = {68{"auto", 0},69{"arm", ELFTC_DEM_ARM},70{"gnu", ELFTC_DEM_GNU2},71{"gnu-v3", ELFTC_DEM_GNU3}72};7374#define USAGE_MESSAGE "\75Usage: %s [options] [encoded-names...]\n\76Translate C++ symbol names to human-readable form.\n\n\77Options:\n\78-_ | --strip-underscores Remove leading underscores prior to decoding.\n\79-n | --no-strip-underscores Do not remove leading underscores.\n\80-p | --no-params (Accepted but ignored).\n\81-s SCHEME | --format=SCHEME Select the encoding scheme to use.\n\82Valid schemes are: 'arm', 'auto', 'gnu' and\n\83'gnu-v3'.\n\84--help Print a help message.\n\85--version Print a version identifier and exit.\n"8687static void88usage(void)89{9091(void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME());92exit(1);93}9495static void96version(void)97{98fprintf(stderr, "%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version());99exit(0);100}101102static int103find_format(const char *fstr)104{105int i;106107for (i = 0; (size_t) i < sizeof(flist) / sizeof(flist[0]); i++) {108if (!strcmp(fstr, flist[i].fname))109return (flist[i].fvalue);110}111112return (-1);113}114115static char *116demangle(char *name)117{118static char dem[STRBUFSZ];119120if (stripus && *name == '_')121name++;122123if (strlen(name) == 0)124return (NULL);125126if (elftc_demangle(name, dem, sizeof(dem), (unsigned) format) < 0)127return (NULL);128129return (dem);130}131132int133main(int argc, char **argv)134{135char *dem, buf[STRBUFSZ];136size_t p;137int c, n, opt;138139while ((opt = getopt_long(argc, argv, "_nps:V", longopts, NULL)) !=140-1) {141switch (opt) {142case '_':143stripus = 1;144break;145case 'n':146stripus = 0;147break;148case 'p':149noparam = 1;150break;151case 's':152if ((format = find_format(optarg)) < 0)153errx(EXIT_FAILURE, "unsupported format: %s",154optarg);155break;156case 'V':157version();158/* NOT REACHED */159case OPTION_HELP:160default:161usage();162/* NOT REACHED */163}164}165166argv += optind;167argc -= optind;168169if (caph_limit_stdio() < 0)170err(EXIT_FAILURE, "failed to limit stdio rights");171if (caph_enter() < 0)172err(EXIT_FAILURE, "failed to enter capability mode");173174if (*argv != NULL) {175for (n = 0; n < argc; n++) {176if ((dem = demangle(argv[n])) == NULL)177printf("%s\n", argv[n]);178else179printf("%s\n", dem);180}181} else {182p = 0;183for (;;) {184setvbuf(stdout, NULL, _IOLBF, 0);185c = fgetc(stdin);186if (c == EOF || !(isalnum(c) || strchr(".$_", c))) {187if (p > 0) {188buf[p] = '\0';189if ((dem = demangle(buf)) == NULL)190printf("%s", buf);191else192printf("%s", dem);193p = 0;194}195if (c == EOF)196break;197putchar(c);198} else {199if ((size_t) p >= sizeof(buf) - 1)200warnx("buffer overflowed");201else202buf[p++] = (char) c;203}204205}206}207208exit(0);209}210211212