1a85fe12eSEd Maste /*-
2a85fe12eSEd Maste * Copyright (c) 2009 Kai Wang
3a85fe12eSEd Maste * All rights reserved.
4a85fe12eSEd Maste *
5a85fe12eSEd Maste * Redistribution and use in source and binary forms, with or without
6a85fe12eSEd Maste * modification, are permitted provided that the following conditions
7a85fe12eSEd Maste * are met:
8a85fe12eSEd Maste * 1. Redistributions of source code must retain the above copyright
9a85fe12eSEd Maste * notice, this list of conditions and the following disclaimer
10a85fe12eSEd Maste * in this position and unchanged.
11a85fe12eSEd Maste * 2. Redistributions in binary form must reproduce the above copyright
12a85fe12eSEd Maste * notice, this list of conditions and the following disclaimer in the
13a85fe12eSEd Maste * documentation and/or other materials provided with the distribution.
14a85fe12eSEd Maste *
15a85fe12eSEd Maste * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR
16a85fe12eSEd Maste * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17a85fe12eSEd Maste * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18a85fe12eSEd Maste * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT,
19a85fe12eSEd Maste * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20a85fe12eSEd Maste * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21a85fe12eSEd Maste * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22a85fe12eSEd Maste * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23a85fe12eSEd Maste * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24a85fe12eSEd Maste * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25a85fe12eSEd Maste */
26a85fe12eSEd Maste
27a85fe12eSEd Maste #include <sys/param.h>
28a85fe12eSEd Maste #include <assert.h>
29a85fe12eSEd Maste #include <errno.h>
30a85fe12eSEd Maste #include <libelftc.h>
31a85fe12eSEd Maste #include <stdlib.h>
32a85fe12eSEd Maste #include <string.h>
33a85fe12eSEd Maste
34a85fe12eSEd Maste #include "_libelftc.h"
35a85fe12eSEd Maste
36*839529caSEd Maste ELFTC_VCSID("$Id: elftc_demangle.c 3296 2016-01-09 14:17:28Z jkoshy $");
37a85fe12eSEd Maste
38*839529caSEd Maste static unsigned int
is_mangled(const char * s,unsigned int style)39*839529caSEd Maste is_mangled(const char *s, unsigned int style)
40a85fe12eSEd Maste {
41a85fe12eSEd Maste
42a85fe12eSEd Maste switch (style) {
43a85fe12eSEd Maste case ELFTC_DEM_ARM: return (is_cpp_mangled_ARM(s) ? style : 0);
44a85fe12eSEd Maste case ELFTC_DEM_GNU2: return (is_cpp_mangled_gnu2(s) ? style : 0);
45a85fe12eSEd Maste case ELFTC_DEM_GNU3: return (is_cpp_mangled_gnu3(s) ? style : 0);
46a85fe12eSEd Maste }
47a85fe12eSEd Maste
48a85fe12eSEd Maste /* No style or invalid style spcified, try to guess. */
49a85fe12eSEd Maste if (is_cpp_mangled_gnu3(s))
50a85fe12eSEd Maste return (ELFTC_DEM_GNU3);
51a85fe12eSEd Maste if (is_cpp_mangled_gnu2(s))
52a85fe12eSEd Maste return (ELFTC_DEM_GNU2);
53a85fe12eSEd Maste if (is_cpp_mangled_ARM(s))
54a85fe12eSEd Maste return (ELFTC_DEM_ARM);
55a85fe12eSEd Maste
56a85fe12eSEd Maste /* Cannot be demangled. */
57a85fe12eSEd Maste return (0);
58a85fe12eSEd Maste }
59a85fe12eSEd Maste
60a85fe12eSEd Maste static char *
demangle(const char * s,unsigned int style,unsigned int rc)61*839529caSEd Maste demangle(const char *s, unsigned int style, unsigned int rc)
62a85fe12eSEd Maste {
63a85fe12eSEd Maste
64a85fe12eSEd Maste (void) rc; /* XXX */
65a85fe12eSEd Maste switch (style) {
66a85fe12eSEd Maste case ELFTC_DEM_ARM: return (cpp_demangle_ARM(s));
67a85fe12eSEd Maste case ELFTC_DEM_GNU2: return (cpp_demangle_gnu2(s));
68a85fe12eSEd Maste case ELFTC_DEM_GNU3: return (cpp_demangle_gnu3(s));
69a85fe12eSEd Maste default:
70a85fe12eSEd Maste assert(0);
71a85fe12eSEd Maste return (NULL);
72a85fe12eSEd Maste }
73a85fe12eSEd Maste }
74a85fe12eSEd Maste
75a85fe12eSEd Maste int
elftc_demangle(const char * mangledname,char * buffer,size_t bufsize,unsigned int flags)76a85fe12eSEd Maste elftc_demangle(const char *mangledname, char *buffer, size_t bufsize,
77a85fe12eSEd Maste unsigned int flags)
78a85fe12eSEd Maste {
79*839529caSEd Maste unsigned int style, rc;
80a85fe12eSEd Maste char *rlt;
81a85fe12eSEd Maste
82a85fe12eSEd Maste style = flags & 0xFFFF;
83a85fe12eSEd Maste rc = flags >> 16;
84a85fe12eSEd Maste
85a85fe12eSEd Maste if (mangledname == NULL ||
86a85fe12eSEd Maste ((style = is_mangled(mangledname, style)) == 0)) {
87a85fe12eSEd Maste errno = EINVAL;
88a85fe12eSEd Maste return (-1);
89a85fe12eSEd Maste }
90a85fe12eSEd Maste
91a85fe12eSEd Maste if ((rlt = demangle(mangledname, style, rc)) == NULL) {
92a85fe12eSEd Maste errno = EINVAL;
93a85fe12eSEd Maste return (-1);
94a85fe12eSEd Maste }
95a85fe12eSEd Maste
96a85fe12eSEd Maste if (buffer == NULL || bufsize < strlen(rlt) + 1) {
97a85fe12eSEd Maste free(rlt);
98a85fe12eSEd Maste errno = ENAMETOOLONG;
99a85fe12eSEd Maste return (-1);
100a85fe12eSEd Maste }
101a85fe12eSEd Maste
102a85fe12eSEd Maste strncpy(buffer, rlt, bufsize);
103a85fe12eSEd Maste buffer[bufsize - 1] = '\0';
104a85fe12eSEd Maste free(rlt);
105a85fe12eSEd Maste
106a85fe12eSEd Maste return (0);
107a85fe12eSEd Maste }
108