1260684Skaiw/*- 2260684Skaiw * Copyright (c) 2009 Kai Wang 3260684Skaiw * All rights reserved. 4260684Skaiw * 5260684Skaiw * Redistribution and use in source and binary forms, with or without 6260684Skaiw * modification, are permitted provided that the following conditions 7260684Skaiw * are met: 8260684Skaiw * 1. Redistributions of source code must retain the above copyright 9260684Skaiw * notice, this list of conditions and the following disclaimer 10260684Skaiw * in this position and unchanged. 11260684Skaiw * 2. Redistributions in binary form must reproduce the above copyright 12260684Skaiw * notice, this list of conditions and the following disclaimer in the 13260684Skaiw * documentation and/or other materials provided with the distribution. 14260684Skaiw * 15260684Skaiw * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR 16260684Skaiw * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17260684Skaiw * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18260684Skaiw * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, 19260684Skaiw * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20260684Skaiw * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21260684Skaiw * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22260684Skaiw * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23260684Skaiw * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24260684Skaiw * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25260684Skaiw */ 26260684Skaiw 27260684Skaiw#include <sys/param.h> 28260684Skaiw#include <ctype.h> 29260684Skaiw#include <err.h> 30260684Skaiw#include <getopt.h> 31260684Skaiw#include <libelftc.h> 32260684Skaiw#include <stdlib.h> 33260684Skaiw#include <stdio.h> 34260684Skaiw#include <string.h> 35260684Skaiw 36260684Skaiw#include "_elftc.h" 37260684Skaiw 38300311SemasteELFTC_VCSID("$Id: cxxfilt.c 3454 2016-05-07 17:11:05Z kaiwang27 $"); 39260684Skaiw 40260684Skaiw#define STRBUFSZ 8192 41260684Skaiw 42260684Skaiwstatic int stripus = 0; 43260684Skaiwstatic int noparam = 0; 44260684Skaiwstatic int format = 0; 45260684Skaiw 46260684Skaiwenum options 47260684Skaiw{ 48260684Skaiw OPTION_HELP, 49260684Skaiw OPTION_VERSION 50260684Skaiw}; 51260684Skaiw 52260684Skaiwstatic struct option longopts[] = 53260684Skaiw{ 54260684Skaiw {"format", required_argument, NULL, 's'}, 55260684Skaiw {"help", no_argument, NULL, OPTION_HELP}, 56260684Skaiw {"no-params", no_argument, NULL, 'p'}, 57260684Skaiw {"no-strip-underscores", no_argument, NULL, 'n'}, 58260684Skaiw {"strip-underscores", no_argument, NULL, '_'}, 59260684Skaiw {"version", no_argument, NULL, 'V'}, 60260684Skaiw {NULL, 0, NULL, 0} 61260684Skaiw}; 62260684Skaiw 63260684Skaiwstatic struct { 64260684Skaiw const char *fname; 65260684Skaiw int fvalue; 66260684Skaiw} flist[] = { 67260684Skaiw {"auto", 0}, 68260684Skaiw {"arm", ELFTC_DEM_ARM}, 69260684Skaiw {"gnu", ELFTC_DEM_GNU2}, 70260684Skaiw {"gnu-v3", ELFTC_DEM_GNU3} 71260684Skaiw}; 72260684Skaiw 73260684Skaiw#define USAGE_MESSAGE "\ 74260684SkaiwUsage: %s [options] [encoded-names...]\n\ 75260684Skaiw Translate C++ symbol names to human-readable form.\n\n\ 76260684Skaiw Options:\n\ 77260684Skaiw -_ | --strip-underscores Remove leading underscores prior to decoding.\n\ 78260684Skaiw -n | --no-strip-underscores Do not remove leading underscores.\n\ 79260684Skaiw -p | --no-params (Accepted but ignored).\n\ 80260684Skaiw -s SCHEME | --format=SCHEME Select the encoding scheme to use.\n\ 81260684Skaiw Valid schemes are: 'arm', 'auto', 'gnu' and\n\ 82260684Skaiw 'gnu-v3'.\n\ 83260684Skaiw --help Print a help message.\n\ 84260684Skaiw --version Print a version identifier and exit.\n" 85260684Skaiw 86260684Skaiwstatic void 87260684Skaiwusage(void) 88260684Skaiw{ 89260684Skaiw 90260684Skaiw (void) fprintf(stderr, USAGE_MESSAGE, ELFTC_GETPROGNAME()); 91260684Skaiw exit(1); 92260684Skaiw} 93260684Skaiw 94260684Skaiwstatic void 95260684Skaiwversion(void) 96260684Skaiw{ 97260684Skaiw fprintf(stderr, "%s (%s)\n", ELFTC_GETPROGNAME(), elftc_version()); 98260684Skaiw exit(0); 99260684Skaiw} 100260684Skaiw 101260684Skaiwstatic int 102260684Skaiwfind_format(const char *fstr) 103260684Skaiw{ 104260684Skaiw int i; 105260684Skaiw 106260684Skaiw for (i = 0; (size_t) i < sizeof(flist) / sizeof(flist[0]); i++) { 107260684Skaiw if (!strcmp(fstr, flist[i].fname)) 108260684Skaiw return (flist[i].fvalue); 109260684Skaiw } 110260684Skaiw 111260684Skaiw return (-1); 112260684Skaiw} 113260684Skaiw 114260684Skaiwstatic char * 115300311Semastedemangle(char *name) 116260684Skaiw{ 117260684Skaiw static char dem[STRBUFSZ]; 118260684Skaiw 119300311Semaste if (stripus && *name == '_') 120300311Semaste name++; 121260684Skaiw 122300311Semaste if (strlen(name) == 0) 123300311Semaste return (NULL); 124260684Skaiw 125300311Semaste if (elftc_demangle(name, dem, sizeof(dem), (unsigned) format) < 0) 126300311Semaste return (NULL); 127260684Skaiw 128260684Skaiw return (dem); 129260684Skaiw} 130260684Skaiw 131260684Skaiwint 132260684Skaiwmain(int argc, char **argv) 133260684Skaiw{ 134260684Skaiw char *dem, buf[STRBUFSZ]; 135300311Semaste size_t p; 136295577Semaste int c, n, opt; 137260684Skaiw 138260684Skaiw while ((opt = getopt_long(argc, argv, "_nps:V", longopts, NULL)) != 139260684Skaiw -1) { 140260684Skaiw switch (opt) { 141260684Skaiw case '_': 142260684Skaiw stripus = 1; 143260684Skaiw break; 144260684Skaiw case 'n': 145260684Skaiw stripus = 0; 146260684Skaiw break; 147260684Skaiw case 'p': 148260684Skaiw noparam = 1; 149260684Skaiw break; 150260684Skaiw case 's': 151260684Skaiw if ((format = find_format(optarg)) < 0) 152260684Skaiw errx(EXIT_FAILURE, "unsupported format: %s", 153260684Skaiw optarg); 154260684Skaiw break; 155260684Skaiw case 'V': 156260684Skaiw version(); 157260684Skaiw /* NOT REACHED */ 158260684Skaiw case OPTION_HELP: 159260684Skaiw default: 160260684Skaiw usage(); 161260684Skaiw /* NOT REACHED */ 162260684Skaiw } 163260684Skaiw } 164260684Skaiw 165260684Skaiw argv += optind; 166260684Skaiw argc -= optind; 167260684Skaiw 168260684Skaiw if (*argv != NULL) { 169295577Semaste for (n = 0; n < argc; n++) { 170300311Semaste if ((dem = demangle(argv[n])) == NULL) 171300311Semaste printf("%s\n", argv[n]); 172260684Skaiw else 173260684Skaiw printf("%s\n", dem); 174260684Skaiw } 175260684Skaiw } else { 176260684Skaiw p = 0; 177260684Skaiw for (;;) { 178260684Skaiw c = fgetc(stdin); 179300311Semaste if (c == EOF || !(isalnum(c) || strchr(".$_", c))) { 180260684Skaiw if (p > 0) { 181260684Skaiw buf[p] = '\0'; 182300311Semaste if ((dem = demangle(buf)) == NULL) 183260684Skaiw printf("%s", buf); 184300311Semaste else 185260684Skaiw printf("%s", dem); 186260684Skaiw p = 0; 187260684Skaiw } 188260684Skaiw if (c == EOF) 189260684Skaiw break; 190300311Semaste putchar(c); 191260684Skaiw } else { 192260684Skaiw if ((size_t) p >= sizeof(buf) - 1) 193260684Skaiw warnx("buffer overflowed"); 194260684Skaiw else 195295577Semaste buf[p++] = (char) c; 196260684Skaiw } 197260684Skaiw 198260684Skaiw } 199260684Skaiw } 200260684Skaiw 201260684Skaiw exit(0); 202260684Skaiw} 203