diff options
author | Ben Cheng <bccheng@google.com> | 2014-03-25 22:37:19 -0700 |
---|---|---|
committer | Ben Cheng <bccheng@google.com> | 2014-03-25 22:37:19 -0700 |
commit | 1bc5aee63eb72b341f506ad058502cd0361f0d10 (patch) | |
tree | c607e8252f3405424ff15bc2d00aa38dadbb2518 /gcc-4.9/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc | |
parent | 283a0bf58fcf333c58a2a92c3ebbc41fb9eb1fdb (diff) | |
download | toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.gz toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.tar.bz2 toolchain_gcc-1bc5aee63eb72b341f506ad058502cd0361f0d10.zip |
Initial checkin of GCC 4.9.0 from trunk (r208799).
Change-Id: I48a3c08bb98542aa215912a75f03c0890e497dba
Diffstat (limited to 'gcc-4.9/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc')
-rw-r--r-- | gcc-4.9/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc | 217 |
1 files changed, 217 insertions, 0 deletions
diff --git a/gcc-4.9/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc b/gcc-4.9/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc new file mode 100644 index 000000000..3023002af --- /dev/null +++ b/gcc-4.9/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc @@ -0,0 +1,217 @@ +//===-- sanitizer_symbolizer_libbacktrace.cc ------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between AddressSanitizer and ThreadSanitizer +// run-time libraries. +// Libbacktrace implementation of symbolizer parts. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#include "sanitizer_internal_defs.h" +#include "sanitizer_symbolizer.h" +#include "sanitizer_symbolizer_libbacktrace.h" + +#if SANITIZER_LIBBACKTRACE +# include "backtrace-supported.h" +# if SANITIZER_POSIX && BACKTRACE_SUPPORTED && !BACKTRACE_USES_MALLOC +# include "backtrace.h" +# if SANITIZER_CP_DEMANGLE +# undef ARRAY_SIZE +# include "demangle.h" +# endif +# else +# define SANITIZER_LIBBACKTRACE 0 +# endif +#endif + +namespace __sanitizer { + +#if SANITIZER_LIBBACKTRACE + +namespace { + +#if SANITIZER_CP_DEMANGLE +struct CplusV3DemangleData { + char *buf; + uptr size, allocated; +}; + +extern "C" { +static void CplusV3DemangleCallback(const char *s, size_t l, void *vdata) { + CplusV3DemangleData *data = (CplusV3DemangleData *)vdata; + uptr needed = data->size + l + 1; + if (needed > data->allocated) { + data->allocated *= 2; + if (needed > data->allocated) + data->allocated = needed; + char *buf = (char *)InternalAlloc(data->allocated); + if (data->buf) { + internal_memcpy(buf, data->buf, data->size); + InternalFree(data->buf); + } + data->buf = buf; + } + internal_memcpy(data->buf + data->size, s, l); + data->buf[data->size + l] = '\0'; + data->size += l; +} +} // extern "C" + +char *CplusV3Demangle(const char *name, bool always_alloc) { + CplusV3DemangleData data; + data.buf = 0; + data.size = 0; + data.allocated = 0; + if (cplus_demangle_v3_callback(name, DMGL_PARAMS | DMGL_ANSI, + CplusV3DemangleCallback, &data)) { + if (data.size + 64 > data.allocated) + return data.buf; + char *buf = internal_strdup(data.buf); + InternalFree(data.buf); + return buf; + } + if (data.buf) + InternalFree(data.buf); + if (always_alloc) + return internal_strdup(name); + return 0; +} +#else +const char *CplusV3Demangle(const char *name, bool always_alloc) { + if (always_alloc) + return internal_strdup(name); + return 0; +} +#endif + +struct SymbolizeCodeData { + AddressInfo *frames; + uptr n_frames; + uptr max_frames; + const char *module_name; + uptr module_offset; +}; + +extern "C" { +static int SymbolizeCodePCInfoCallback(void *vdata, uintptr_t addr, + const char *filename, int lineno, + const char *function) { + SymbolizeCodeData *cdata = (SymbolizeCodeData *)vdata; + if (function) { + AddressInfo *info = &cdata->frames[cdata->n_frames++]; + info->Clear(); + info->FillAddressAndModuleInfo(addr, cdata->module_name, + cdata->module_offset); + info->function = CplusV3Demangle(function, true); + if (filename) + info->file = internal_strdup(filename); + info->line = lineno; + if (cdata->n_frames == cdata->max_frames) + return 1; + } + return 0; +} + +static void SymbolizeCodeCallback(void *vdata, uintptr_t addr, + const char *symname, uintptr_t, uintptr_t) { + SymbolizeCodeData *cdata = (SymbolizeCodeData *)vdata; + if (symname) { + AddressInfo *info = &cdata->frames[0]; + info->Clear(); + info->FillAddressAndModuleInfo(addr, cdata->module_name, + cdata->module_offset); + info->function = CplusV3Demangle(symname, true); + cdata->n_frames = 1; + } +} + +static void SymbolizeDataCallback(void *vdata, uintptr_t, const char *symname, + uintptr_t symval, uintptr_t symsize) { + DataInfo *info = (DataInfo *)vdata; + if (symname && symval) { + info->name = CplusV3Demangle(symname, true); + info->start = symval; + info->size = symsize; + } +} + +static void ErrorCallback(void *, const char *, int) {} +} // extern "C" + +} // namespace + +LibbacktraceSymbolizer *LibbacktraceSymbolizer::get(LowLevelAllocator *alloc) { + // State created in backtrace_create_state is leaked. + void *state = (void *)(backtrace_create_state("/proc/self/exe", 0, + ErrorCallback, NULL)); + if (!state) + return 0; + return new(*alloc) LibbacktraceSymbolizer(state); +} + +uptr LibbacktraceSymbolizer::SymbolizeCode(uptr addr, AddressInfo *frames, + uptr max_frames, + const char *module_name, + uptr module_offset) { + SymbolizeCodeData data; + data.frames = frames; + data.n_frames = 0; + data.max_frames = max_frames; + data.module_name = module_name; + data.module_offset = module_offset; + backtrace_pcinfo((backtrace_state *)state_, addr, SymbolizeCodePCInfoCallback, + ErrorCallback, &data); + if (data.n_frames) + return data.n_frames; + backtrace_syminfo((backtrace_state *)state_, addr, SymbolizeCodeCallback, + ErrorCallback, &data); + return data.n_frames; +} + +bool LibbacktraceSymbolizer::SymbolizeData(DataInfo *info) { + backtrace_syminfo((backtrace_state *)state_, info->address, + SymbolizeDataCallback, ErrorCallback, info); + return true; +} + +const char *LibbacktraceSymbolizer::Demangle(const char *name) { +#if SANITIZER_CP_DEMANGLE + const char *demangled = CplusV3Demangle(name, false); + if (demangled) + return demangled; + return name; +#else + return 0; +#endif +} + +#else // SANITIZER_LIBBACKTRACE + +LibbacktraceSymbolizer *LibbacktraceSymbolizer::get(LowLevelAllocator *alloc) { + return 0; +} + +uptr LibbacktraceSymbolizer::SymbolizeCode(uptr addr, AddressInfo *frames, + uptr max_frames, + const char *module_name, + uptr module_offset) { + (void)state_; + return 0; +} + +bool LibbacktraceSymbolizer::SymbolizeData(DataInfo *info) { + return false; +} + +const char *LibbacktraceSymbolizer::Demangle(const char *name) { + return 0; +} + +#endif // SANITIZER_LIBBACKTRACE + +} // namespace __sanitizer |