1*4226f635SJason King /* 2*4226f635SJason King * This file and its contents are supplied under the terms of the 3*4226f635SJason King * Common Development and Distribution License ("CDDL"), version 1.0. 4*4226f635SJason King * You may only use this file in accordance with the terms of version 5*4226f635SJason King * 1.0 of the CDDL. 6*4226f635SJason King * 7*4226f635SJason King * A full copy of the text of the CDDL should have accompanied this 8*4226f635SJason King * source. A copy of the CDDL is also available via the Internet at 9*4226f635SJason King * http://www.illumos.org/license/CDDL. 10*4226f635SJason King */ 11*4226f635SJason King 12*4226f635SJason King /* 13*4226f635SJason King * Copyright 2018 Jason King 14*4226f635SJason King */ 15*4226f635SJason King 16*4226f635SJason King #include <stdlib.h> 17*4226f635SJason King #include <string.h> 18*4226f635SJason King #include <errno.h> 19*4226f635SJason King #include <pthread.h> 20*4226f635SJason King #include <sys/debug.h> 21*4226f635SJason King #include "demangle-sys.h" 22*4226f635SJason King #include "demangle_int.h" 23*4226f635SJason King 24*4226f635SJason King #define DEMANGLE_DEBUG "DEMANGLE_DEBUG" 25*4226f635SJason King 26*4226f635SJason King static pthread_once_t debug_once = PTHREAD_ONCE_INIT; 27*4226f635SJason King volatile boolean_t demangle_debug; 28*4226f635SJason King 29*4226f635SJason King static sysdem_lang_t 30*4226f635SJason King detect_lang(const char *str) 31*4226f635SJason King { 32*4226f635SJason King size_t n = strlen(str); 33*4226f635SJason King 34*4226f635SJason King if (n < 3 || str[0] != '_') 35*4226f635SJason King return (SYSDEM_LANG_AUTO); 36*4226f635SJason King 37*4226f635SJason King switch (str[1]) { 38*4226f635SJason King case 'Z': 39*4226f635SJason King return (SYSDEM_LANG_CPP); 40*4226f635SJason King 41*4226f635SJason King case '_': 42*4226f635SJason King break; 43*4226f635SJason King 44*4226f635SJason King default: 45*4226f635SJason King return (SYSDEM_LANG_AUTO); 46*4226f635SJason King } 47*4226f635SJason King 48*4226f635SJason King /* why they use ___Z sometimes is puzzling... *sigh* */ 49*4226f635SJason King if (str[2] == '_' && str[3] == 'Z') 50*4226f635SJason King return (SYSDEM_LANG_CPP); 51*4226f635SJason King 52*4226f635SJason King return (SYSDEM_LANG_AUTO); 53*4226f635SJason King } 54*4226f635SJason King 55*4226f635SJason King static void 56*4226f635SJason King check_debug(void) 57*4226f635SJason King { 58*4226f635SJason King if (getenv(DEMANGLE_DEBUG)) 59*4226f635SJason King demangle_debug = B_TRUE; 60*4226f635SJason King } 61*4226f635SJason King 62*4226f635SJason King char * 63*4226f635SJason King sysdemangle(const char *str, sysdem_lang_t lang, sysdem_ops_t *ops) 64*4226f635SJason King { 65*4226f635SJason King VERIFY0(pthread_once(&debug_once, check_debug)); 66*4226f635SJason King 67*4226f635SJason King if (ops == NULL) 68*4226f635SJason King ops = sysdem_ops_default; 69*4226f635SJason King 70*4226f635SJason King if (lang == SYSDEM_LANG_AUTO) { 71*4226f635SJason King lang = detect_lang(str); 72*4226f635SJason King if (lang == SYSDEM_LANG_AUTO) { 73*4226f635SJason King errno = ENOTSUP; 74*4226f635SJason King return (NULL); 75*4226f635SJason King } 76*4226f635SJason King } 77*4226f635SJason King 78*4226f635SJason King switch (lang) { 79*4226f635SJason King case SYSDEM_LANG_AUTO: 80*4226f635SJason King break; 81*4226f635SJason King case SYSDEM_LANG_CPP: 82*4226f635SJason King return (cpp_demangle(str, ops)); 83*4226f635SJason King } 84*4226f635SJason King 85*4226f635SJason King errno = ENOTSUP; 86*4226f635SJason King return (NULL); 87*4226f635SJason King } 88