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 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 * 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 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