]>
Commit | Line | Data |
---|---|---|
a6637ec0 | 1 | /* demangle.c -- A wrapper calling libiberty cplus_demangle |
aef6203b | 2 | Copyright 2002, 2003, 2004 Free Software Foundation, Inc. |
a6637ec0 AM |
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 | |
b43b5d5f NC |
18 | Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA |
19 | 02110-1301, USA. */ | |
a6637ec0 | 20 | |
63eb0809 | 21 | #include "config.h" |
a6637ec0 | 22 | #include <stdlib.h> |
63eb0809 | 23 | #ifdef HAVE_STRING_H |
2c205ff2 | 24 | #include <string.h> |
63eb0809 AM |
25 | #else |
26 | #ifdef HAVE_STRINGS_H | |
27 | #include <strings.h> | |
28 | #endif | |
29 | #endif | |
a6637ec0 AM |
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 * | |
2da42df6 | 39 | demangle (bfd *abfd, const char *name) |
a6637ec0 | 40 | { |
2bb2d727 AM |
41 | char *res, *alloc; |
42 | const char *pre, *suf; | |
43 | size_t pre_len; | |
a6637ec0 AM |
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. */ | |
2bb2d727 AM |
52 | pre = name; |
53 | while (*name == '.') | |
54 | ++name; | |
7f67d4c9 | 55 | pre_len = name - pre; |
a6637ec0 | 56 | |
2bb2d727 AM |
57 | alloc = NULL; |
58 | suf = strchr (name, '@'); | |
59 | if (suf != NULL) | |
a6637ec0 | 60 | { |
2bb2d727 AM |
61 | alloc = xmalloc (suf - name + 1); |
62 | memcpy (alloc, name, suf - name); | |
63 | alloc[suf - name] = '\0'; | |
64 | name = alloc; | |
65 | } | |
a6637ec0 | 66 | |
2bb2d727 AM |
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) | |
a6637ec0 | 72 | { |
2bb2d727 AM |
73 | size_t len; |
74 | size_t suf_len; | |
75 | char *final; | |
76 | ||
77 | if (alloc != NULL) | |
78 | free (alloc); | |
a6637ec0 | 79 | |
2bb2d727 AM |
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); | |
a6637ec0 | 89 | free (res); |
2bb2d727 | 90 | res = final; |
a6637ec0 | 91 | } |
2bb2d727 | 92 | |
a6637ec0 AM |
93 | return res; |
94 | } | |
95 | ||
2bb2d727 AM |
96 | if (alloc != NULL) |
97 | free (alloc); | |
98 | ||
99 | return xstrdup (pre); | |
a6637ec0 | 100 | } |