2018-03-23 19:47:23 +01:00
|
|
|
// Matrix Construct
|
|
|
|
//
|
|
|
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
|
|
|
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
|
|
|
//
|
|
|
|
// Permission to use, copy, modify, and/or distribute this software for any
|
|
|
|
// purpose with or without fee is hereby granted, provided that the above
|
|
|
|
// copyright notice and this permission notice is present in all copies. The
|
|
|
|
// full license for this software is available in the LICENSE file.
|
|
|
|
|
|
|
|
#include <cxxabi.h>
|
|
|
|
|
2018-04-20 06:45:39 +02:00
|
|
|
thread_local char
|
|
|
|
outbuf[8192];
|
2018-03-23 19:47:23 +01:00
|
|
|
|
|
|
|
std::string
|
2019-09-20 01:37:18 +02:00
|
|
|
ircd::demangle(const char *const &symbol)
|
2018-03-23 19:47:23 +01:00
|
|
|
{
|
|
|
|
const string_view demangled
|
|
|
|
{
|
|
|
|
demangle(outbuf, symbol)
|
|
|
|
};
|
|
|
|
|
|
|
|
return std::string(demangled);
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string
|
2019-09-20 01:37:18 +02:00
|
|
|
ircd::demangle(const string_view &symbol)
|
2018-03-23 19:47:23 +01:00
|
|
|
{
|
|
|
|
const string_view demangled
|
|
|
|
{
|
|
|
|
demangle(outbuf, symbol)
|
|
|
|
};
|
|
|
|
|
|
|
|
return std::string(demangled);
|
|
|
|
}
|
|
|
|
|
|
|
|
ircd::string_view
|
2019-09-20 01:37:18 +02:00
|
|
|
ircd::demangle(const mutable_buffer &out,
|
|
|
|
const string_view &symbol_)
|
2018-03-23 19:47:23 +01:00
|
|
|
{
|
|
|
|
assert(size(symbol_) < 4096);
|
|
|
|
thread_local char symbuf[8192];
|
|
|
|
const string_view symbol
|
|
|
|
{
|
|
|
|
symbuf, strlcpy(symbuf, symbol_)
|
|
|
|
};
|
|
|
|
|
|
|
|
return demangle(out, symbol.data());
|
|
|
|
}
|
|
|
|
|
|
|
|
ircd::string_view
|
2019-09-20 01:37:18 +02:00
|
|
|
ircd::demangle(const mutable_buffer &out,
|
|
|
|
const char *const &symbol)
|
2018-03-23 19:47:23 +01:00
|
|
|
{
|
|
|
|
int status(0);
|
|
|
|
size_t len(size(out));
|
|
|
|
const char *const ret
|
|
|
|
{
|
|
|
|
abi::__cxa_demangle(symbol, data(out), &len, &status)
|
|
|
|
};
|
|
|
|
|
|
|
|
switch(status)
|
|
|
|
{
|
|
|
|
case 0: return string_view
|
|
|
|
{
|
|
|
|
ret, strnlen(ret, len)
|
|
|
|
};
|
|
|
|
|
|
|
|
case -1: throw demangle_error
|
|
|
|
{
|
|
|
|
"Demangle failed -1: memory allocation failure"
|
|
|
|
};
|
|
|
|
|
2018-06-11 09:26:20 +02:00
|
|
|
/*
|
2018-03-23 19:47:23 +01:00
|
|
|
case -2: throw not_mangled
|
|
|
|
{
|
|
|
|
"Demangle failed -2: mangled name '%s' is not valid", symbol
|
|
|
|
};
|
2018-06-11 09:26:20 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
// No real use case within IRCd for throwing not_mangled which may
|
|
|
|
// happen for extern "C" related; instead simply copying the input
|
|
|
|
// to the output (as per expectation) is much better behavior.
|
|
|
|
case -2: return string_view
|
|
|
|
{
|
|
|
|
symbol, strlcpy(out, symbol)
|
|
|
|
};
|
2018-03-23 19:47:23 +01:00
|
|
|
|
|
|
|
case -3: throw demangle_error
|
|
|
|
{
|
|
|
|
"Demangle failed -3: invalid argument"
|
|
|
|
};
|
|
|
|
|
|
|
|
default: throw demangle_error
|
|
|
|
{
|
|
|
|
"Demangle failed %d: unknown error", status
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|