5aefb6555731130ca4fd295960123d71f2d21fe8rie * CDDL HEADER START
5aefb6555731130ca4fd295960123d71f2d21fe8rie * The contents of this file are subject to the terms of the
5aefb6555731130ca4fd295960123d71f2d21fe8rie * Common Development and Distribution License (the "License").
5aefb6555731130ca4fd295960123d71f2d21fe8rie * You may not use this file except in compliance with the License.
5aefb6555731130ca4fd295960123d71f2d21fe8rie * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
5aefb6555731130ca4fd295960123d71f2d21fe8rie * See the License for the specific language governing permissions
5aefb6555731130ca4fd295960123d71f2d21fe8rie * and limitations under the License.
5aefb6555731130ca4fd295960123d71f2d21fe8rie * When distributing Covered Code, include this CDDL HEADER in each
5aefb6555731130ca4fd295960123d71f2d21fe8rie * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
5aefb6555731130ca4fd295960123d71f2d21fe8rie * If applicable, add the following below this CDDL HEADER, with the
5aefb6555731130ca4fd295960123d71f2d21fe8rie * fields enclosed by brackets "[]" replaced with your own identifying
5aefb6555731130ca4fd295960123d71f2d21fe8rie * information: Portions Copyright [yyyy] [name of copyright owner]
5aefb6555731130ca4fd295960123d71f2d21fe8rie * CDDL HEADER END
23a1ccea6aac035f084a7a4cdc968687d1b02dafRoger A. Faulkner * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
5aefb6555731130ca4fd295960123d71f2d21fe8rie * Demangle C++ symbols.
5aefb6555731130ca4fd295960123d71f2d21fe8rie * This routine acts as a generic routine for use by liblddbg (and hence tools
5aefb6555731130ca4fd295960123d71f2d21fe8rie * like elfdump(1) and pvs(1)), ld(1) and ld.so.1(1).
5aefb6555731130ca4fd295960123d71f2d21fe8rie * The C++ ABI-2 places no limits on symbol names, thus when demangling a name
5aefb6555731130ca4fd295960123d71f2d21fe8rie * it's possible the buffer won't be big enough (DEMANGLE_ESPACE) so here we
5aefb6555731130ca4fd295960123d71f2d21fe8rie * try to allocate bigger buffers. However, we place a limit on this buffer
5aefb6555731130ca4fd295960123d71f2d21fe8rie * size for fear of a C++ error sending us into an infinit loop.
5aefb6555731130ca4fd295960123d71f2d21fe8rie * NOTE. we create and use a common buffer for use by cplus_demangle(), thus
5aefb6555731130ca4fd295960123d71f2d21fe8rie * each call to this routine will override the contents of any existing call.
5aefb6555731130ca4fd295960123d71f2d21fe8rie * Normally this is sufficient for typical error diagnostics referencing one
5aefb6555731130ca4fd295960123d71f2d21fe8rie * symbol. For those diagnostics using more than one symbol name, all but the
5aefb6555731130ca4fd295960123d71f2d21fe8rie * last name must be copied to a temporary buffer (regardless of whether
5aefb6555731130ca4fd295960123d71f2d21fe8rie * demangling occurred, as the process of attempting to demangle may damage the
5aefb6555731130ca4fd295960123d71f2d21fe8rie * buffer). One model is:
5aefb6555731130ca4fd295960123d71f2d21fe8rie * if ((_name1 = demangle(name1)) != name1) {
23a1ccea6aac035f084a7a4cdc968687d1b02dafRoger A. Faulkner * char * __name1 = strdupa(_name1);
5aefb6555731130ca4fd295960123d71f2d21fe8rie * name1 = (const char *)__name1;
5aefb6555731130ca4fd295960123d71f2d21fe8rie * name2 = demangle(name2);
5aefb6555731130ca4fd295960123d71f2d21fe8rie * eprintf(format, name1, name2);
5aefb6555731130ca4fd295960123d71f2d21fe8rieconst char *
5aefb6555731130ca4fd295960123d71f2d21fe8rie static int (*fptr)() = 0;
5aefb6555731130ca4fd295960123d71f2d21fe8rie * If we haven't located the demangler yet try now (we do this rather
5aefb6555731130ca4fd295960123d71f2d21fe8rie * than maintain a static dependency on libdemangle as it's part of an
5aefb6555731130ca4fd295960123d71f2d21fe8rie * optional package). Null the str element out to reject any other
5aefb6555731130ca4fd295960123d71f2d21fe8rie * callers until this operation is complete - under ld.so.1 we can get
5aefb6555731130ca4fd295960123d71f2d21fe8rie * into serious recursion without this.
5aefb6555731130ca4fd295960123d71f2d21fe8rie if (fptr == 0) {
5aefb6555731130ca4fd295960123d71f2d21fe8rie if (!(hdl = dlopen(MSG_ORIG(MSG_DEM_LIB), RTLD_LAZY)) ||
5aefb6555731130ca4fd295960123d71f2d21fe8rie return ((const char *)str);
5aefb6555731130ca4fd295960123d71f2d21fe8rie * If we haven't allocated our maximum try incrementing the
5aefb6555731130ca4fd295960123d71f2d21fe8rie * present buffer size. Use malloc() rather than realloc() so
5aefb6555731130ca4fd295960123d71f2d21fe8rie * that we at least have the old buffer on failure.
5aefb6555731130ca4fd295960123d71f2d21fe8rie return ((const char *)str);