missed from last commit

This commit is contained in:
Alan Modra 2007-04-19 10:51:34 +00:00
parent 5c068be831
commit 3fad56a3d4
3 changed files with 84 additions and 126 deletions

View File

@ -1,6 +1,6 @@
/* Generic BFD library interface and support routines.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2005, 2006
2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
Written by Cygnus Support.
@ -207,6 +207,7 @@ CODE_FRAGMENT
#include "sysdep.h"
#include <stdarg.h>
#include "libiberty.h"
#include "demangle.h"
#include "safe-ctype.h"
#include "bfdlink.h"
#include "libbfd.h"
@ -1702,3 +1703,85 @@ bfd_emul_set_commonpagesize (const char *emul, bfd_vma size)
offsetof (struct elf_backend_data,
commonpagesize), target);
}
/*
FUNCTION
bfd_demangle
SYNOPSIS
char *bfd_demangle (bfd *, const char *, int);
DESCRIPTION
Wrapper around cplus_demangle. Strips leading underscores and
other such chars that would otherwise confuse the demangler.
If passed a g++ v3 ABI mangled name, returns a buffer allocated
with malloc holding the demangled name. Returns NULL otherwise
and on memory alloc failure.
*/
char *
bfd_demangle (bfd *abfd, const char *name, int options)
{
char *res, *alloc;
const char *pre, *suf;
size_t pre_len;
if (abfd != NULL
&& *name != '\0'
&& bfd_get_symbol_leading_char (abfd) == *name)
++name;
/* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
or the MS PE format. These formats have a number of leading '.'s
on at least some symbols, so we remove all dots to avoid
confusing the demangler. */
pre = name;
while (*name == '.' || *name == '$')
++name;
pre_len = name - pre;
/* Strip off @plt and suchlike too. */
alloc = NULL;
suf = strchr (name, '@');
if (suf != NULL)
{
alloc = bfd_malloc (suf - name + 1);
if (alloc == NULL)
return NULL;
memcpy (alloc, name, suf - name);
alloc[suf - name] = '\0';
name = alloc;
}
res = cplus_demangle (name, options);
if (alloc != NULL)
free (alloc);
if (res == NULL)
return NULL;
/* Put back any prefix or suffix. */
if (pre_len != 0 || suf != NULL)
{
size_t len;
size_t suf_len;
char *final;
len = strlen (res);
if (suf == NULL)
suf = res + len;
suf_len = strlen (suf) + 1;
final = bfd_malloc (pre_len + len + suf_len);
if (final == NULL)
return NULL;
memcpy (final, pre, pre_len);
memcpy (final + pre_len, res, len);
memcpy (final + pre_len + len, suf, suf_len);
free (res);
res = final;
}
return res;
}

View File

@ -1,100 +0,0 @@
/* demangle.c -- A wrapper calling libiberty cplus_demangle
Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of GNU Binutils.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
#include "config.h"
#include <stdlib.h>
#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif
#include "bfd.h"
#include "libiberty.h"
#include "demangle.h"
#include "budemang.h"
/* Wrapper around cplus_demangle. Strips leading underscores and
other such chars that would otherwise confuse the demangler. */
char *
demangle (bfd *abfd, const char *name)
{
char *res, *alloc;
const char *pre, *suf;
size_t pre_len;
if (abfd != NULL && bfd_get_symbol_leading_char (abfd) == name[0])
++name;
/* This is a hack for better error reporting on XCOFF, PowerPC64-ELF
or the MS PE format. These formats have a number of leading '.'s
on at least some symbols, so we remove all dots to avoid
confusing the demangler. */
pre = name;
while (*name == '.')
++name;
pre_len = name - pre;
alloc = NULL;
suf = strchr (name, '@');
if (suf != NULL)
{
alloc = xmalloc (suf - name + 1);
memcpy (alloc, name, suf - name);
alloc[suf - name] = '\0';
name = alloc;
}
res = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
if (res != NULL)
{
/* Now put back any suffix, or stripped dots. */
if (pre_len != 0 || suf != NULL)
{
size_t len;
size_t suf_len;
char *final;
if (alloc != NULL)
free (alloc);
len = strlen (res);
if (suf == NULL)
suf = res + len;
suf_len = strlen (suf) + 1;
final = xmalloc (pre_len + len + suf_len);
memcpy (final, pre, pre_len);
memcpy (final + pre_len, res, len);
memcpy (final + pre_len + len, suf, suf_len);
free (res);
res = final;
}
return res;
}
if (alloc != NULL)
free (alloc);
return xstrdup (pre);
}

View File

@ -1,25 +0,0 @@
/* demangle.h -- A wrapper calling libiberty cplus_demangle
Copyright 2002, 2003 Free Software Foundation, Inc.
This file is part of GNU Binutils.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
#ifndef BUDEMANG_H
#define BUDEMANG_H
char *demangle (bfd *, const char *);
#endif