1 /* demangle.c -- A wrapper calling libiberty cplus_demangle 2 Copyright 2002, 2003, 2004 Free Software Foundation, Inc. 3 4 This file is part of GNU Binutils. 5 6 This program is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 2 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 19 02110-1301, USA. */ 20 21 #include "config.h" 22 #include <stdlib.h> 23 #ifdef HAVE_STRING_H 24 #include <string.h> 25 #else 26 #ifdef HAVE_STRINGS_H 27 #include <strings.h> 28 #endif 29 #endif 30 #include "bfd.h" 31 #include "libiberty.h" 32 #include "demangle.h" 33 #include "budemang.h" 34 35 /* Wrapper around cplus_demangle. Strips leading underscores and 36 other such chars that would otherwise confuse the demangler. */ 37 38 char * 39 demangle (bfd *abfd, const char *name) 40 { 41 char *res, *alloc; 42 const char *pre, *suf; 43 size_t pre_len; 44 45 if (abfd != NULL && bfd_get_symbol_leading_char (abfd) == name[0]) 46 ++name; 47 48 /* This is a hack for better error reporting on XCOFF, PowerPC64-ELF 49 or the MS PE format. These formats have a number of leading '.'s 50 on at least some symbols, so we remove all dots to avoid 51 confusing the demangler. */ 52 pre = name; 53 while (*name == '.') 54 ++name; 55 pre_len = name - pre; 56 57 alloc = NULL; 58 suf = strchr (name, '@'); 59 if (suf != NULL) 60 { 61 alloc = xmalloc (suf - name + 1); 62 memcpy (alloc, name, suf - name); 63 alloc[suf - name] = '\0'; 64 name = alloc; 65 } 66 67 res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS); 68 if (res != NULL) 69 { 70 /* Now put back any suffix, or stripped dots. */ 71 if (pre_len != 0 || suf != NULL) 72 { 73 size_t len; 74 size_t suf_len; 75 char *final; 76 77 if (alloc != NULL) 78 free (alloc); 79 80 len = strlen (res); 81 if (suf == NULL) 82 suf = res + len; 83 suf_len = strlen (suf) + 1; 84 final = xmalloc (pre_len + len + suf_len); 85 86 memcpy (final, pre, pre_len); 87 memcpy (final + pre_len, res, len); 88 memcpy (final + pre_len + len, suf, suf_len); 89 free (res); 90 res = final; 91 } 92 93 return res; 94 } 95 96 if (alloc != NULL) 97 free (alloc); 98 99 return xstrdup (pre); 100 } 101