Back to index

cell-binutils  2.17cvs20070401
budemang.c
Go to the documentation of this file.
00001 /* demangle.c -- A wrapper calling libiberty cplus_demangle
00002    Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
00003 
00004    This file is part of GNU Binutils.
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014    GNU General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; if not, write to the Free Software
00018    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
00019    02110-1301, USA.  */
00020 
00021 #include "config.h"
00022 #include <stdlib.h>
00023 #ifdef HAVE_STRING_H
00024 #include <string.h>
00025 #else
00026 #ifdef HAVE_STRINGS_H
00027 #include <strings.h>
00028 #endif
00029 #endif
00030 #include "bfd.h"
00031 #include "libiberty.h"
00032 #include "demangle.h"
00033 #include "budemang.h"
00034 
00035 /* Wrapper around cplus_demangle.  Strips leading underscores and
00036    other such chars that would otherwise confuse the demangler.  */
00037 
00038 char *
00039 demangle (bfd *abfd, const char *name)
00040 {
00041   char *res, *alloc;
00042   const char *pre, *suf;
00043   size_t pre_len;
00044 
00045   if (abfd != NULL && bfd_get_symbol_leading_char (abfd) == name[0])
00046     ++name;
00047 
00048   /* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
00049      or the MS PE format.  These formats have a number of leading '.'s
00050      on at least some symbols, so we remove all dots to avoid
00051      confusing the demangler.  */
00052   pre = name;
00053   while (*name == '.')
00054     ++name;
00055   pre_len = name - pre;
00056 
00057   alloc = NULL;
00058   suf = strchr (name, '@');
00059   if (suf != NULL)
00060     {
00061       alloc = xmalloc (suf - name + 1);
00062       memcpy (alloc, name, suf - name);
00063       alloc[suf - name] = '\0';
00064       name = alloc;
00065     }
00066 
00067   res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
00068   if (res != NULL)
00069     {
00070       /* Now put back any suffix, or stripped dots.  */
00071       if (pre_len != 0 || suf != NULL)
00072        {
00073          size_t len;
00074          size_t suf_len;
00075          char *final;
00076 
00077          if (alloc != NULL)
00078            free (alloc);
00079 
00080          len = strlen (res);
00081          if (suf == NULL)
00082            suf = res + len;
00083          suf_len = strlen (suf) + 1;
00084          final = xmalloc (pre_len + len + suf_len);
00085 
00086          memcpy (final, pre, pre_len);
00087          memcpy (final + pre_len, res, len);
00088          memcpy (final + pre_len + len, suf, suf_len);
00089          free (res);
00090          res = final;
00091        }
00092 
00093       return res;
00094     }
00095 
00096   if (alloc != NULL)
00097     free (alloc);
00098 
00099   return xstrdup (pre);
00100 }