diff options
-rw-r--r-- | lib/sanitizer_common/CMakeLists.txt | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer.cc | 23 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer.h | 11 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_llvm.cc | 104 |
4 files changed, 126 insertions, 16 deletions
diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt index d797a56da..5c55f430a 100644 --- a/lib/sanitizer_common/CMakeLists.txt +++ b/lib/sanitizer_common/CMakeLists.txt @@ -11,13 +11,15 @@ set(SANITIZER_SOURCES sanitizer_posix.cc sanitizer_printf.cc sanitizer_symbolizer.cc + sanitizer_symbolizer_llvm.cc sanitizer_win.cc ) set(SANITIZER_CFLAGS "-fPIC -fno-exceptions -funwind-tables -fvisibility=hidden") set(SANITIZER_COMMON_DEFINITIONS - SANITIZER_HAS_EXCEPTIONS=1) + SANITIZER_HAS_EXCEPTIONS=1 + ) if(CAN_TARGET_X86_64) add_library(RTSanitizerCommon.x86_64 OBJECT ${SANITIZER_SOURCES}) diff --git a/lib/sanitizer_common/sanitizer_symbolizer.cc b/lib/sanitizer_common/sanitizer_symbolizer.cc index 85eb0764f..5bfc957af 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer.cc @@ -7,13 +7,11 @@ // //===----------------------------------------------------------------------===// // -// This is a stub for LLVM-based symbolizer. // This file is shared between AddressSanitizer and ThreadSanitizer -// run-time libraries. See sanitizer.h for details. +// run-time libraries. See sanitizer_symbolizer.h for details. //===----------------------------------------------------------------------===// #include "sanitizer_common.h" -#include "sanitizer_placement_new.h" #include "sanitizer_procmaps.h" #include "sanitizer_symbolizer.h" @@ -50,6 +48,7 @@ ModuleDIContext::ModuleDIContext(const char *module_name, uptr base_address) { n_ranges_ = 0; mapped_addr_ = 0; mapped_size_ = 0; + dwarf_context_ = 0; } void ModuleDIContext::addAddressRange(uptr beg, uptr end) { @@ -71,29 +70,25 @@ void ModuleDIContext::getAddressInfo(AddressInfo *info) { info->module = internal_strdup(full_name_); info->module_offset = info->address - base_address_; if (mapped_addr_ == 0) - CreateDIContext(); - // FIXME: Use the actual debug info context here. - info->function = 0; - info->file = 0; - info->line = 0; - info->column = 0; + CreateDWARFContext(); + getLineInfoFromContext(dwarf_context_, info); } -void ModuleDIContext::CreateDIContext() { +void ModuleDIContext::CreateDWARFContext() { mapped_addr_ = (uptr)MapFileToMemory(full_name_, &mapped_size_); CHECK(mapped_addr_); DWARFSection debug_info; DWARFSection debug_abbrev; - DWARFSection debug_line; DWARFSection debug_aranges; + DWARFSection debug_line; DWARFSection debug_str; FindDWARFSection(mapped_addr_, "debug_info", &debug_info); FindDWARFSection(mapped_addr_, "debug_abbrev", &debug_abbrev); - FindDWARFSection(mapped_addr_, "debug_line", &debug_line); FindDWARFSection(mapped_addr_, "debug_aranges", &debug_aranges); + FindDWARFSection(mapped_addr_, "debug_line", &debug_line); FindDWARFSection(mapped_addr_, "debug_str", &debug_str); - // FIXME: Construct actual debug info context using mapped_addr, - // mapped_size and pointers to DWARF sections in memory. + dwarf_context_ = getDWARFContext(debug_info, debug_abbrev, debug_aranges, + debug_line, debug_str); } class Symbolizer { diff --git a/lib/sanitizer_common/sanitizer_symbolizer.h b/lib/sanitizer_common/sanitizer_symbolizer.h index c813e8088..d5574b244 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer.h +++ b/lib/sanitizer_common/sanitizer_symbolizer.h @@ -66,6 +66,14 @@ bool FindDWARFSection(uptr object_file_addr, const char *section_name, DWARFSection *section); bool IsFullNameOfDWARFSection(const char *full_name, const char *short_name); +class DWARFContext; +DWARFContext *getDWARFContext(DWARFSection debug_info, + DWARFSection debug_abbrev, + DWARFSection debug_aranges, + DWARFSection debug_line, + DWARFSection debug_str); +void getLineInfoFromContext(DWARFContext *context, AddressInfo *info); + class ModuleDIContext { public: ModuleDIContext(const char *module_name, uptr base_address); @@ -76,7 +84,7 @@ class ModuleDIContext { const char *full_name() const { return full_name_; } private: - void CreateDIContext(); + void CreateDWARFContext(); struct AddressRange { uptr beg; @@ -90,6 +98,7 @@ class ModuleDIContext { uptr n_ranges_; uptr mapped_addr_; uptr mapped_size_; + DWARFContext *dwarf_context_; }; // OS-dependent function that gets the linked list of all loaded modules. diff --git a/lib/sanitizer_common/sanitizer_symbolizer_llvm.cc b/lib/sanitizer_common/sanitizer_symbolizer_llvm.cc new file mode 100644 index 000000000..5dd1ad8dd --- /dev/null +++ b/lib/sanitizer_common/sanitizer_symbolizer_llvm.cc @@ -0,0 +1,104 @@ +//===-- sanitizer_symbolizer_llvm.cc --------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This is a wrapper around llvm::DIContext, moved to separate file to +// include LLVM headers in a single place in sanitizer library. If macro +// SANITIZER_USES_LLVM_LIBS is not defined, then sanitizer runtime +// will not include LLVM headers and will not require static +// LLVM libraries to link with. +// In this case, the symbolizer will just return zeroes instead of +// valid file/line info. +// +// This file is shared between AddressSanitizer and ThreadSanitizer +// run-time libraries. +//===----------------------------------------------------------------------===// + +#include "sanitizer_common.h" +#include "sanitizer_symbolizer.h" + +#ifdef SANITIZER_USES_LLVM_LIBS +# ifndef __STDC_LIMIT_MACROS +# define __STDC_LIMIT_MACROS 1 +# endif +# ifndef __STDC_CONSTANT_MACROS +# define __STDC_CONSTANT_MACROS 1 +# endif +# include "llvm/ADT/StringRef.h" +# include "llvm/DebugInfo/DIContext.h" + +namespace __sanitizer { + +static llvm::StringRef ToStringRef(const DWARFSection §ion) { + return llvm::StringRef(section.data, section.size); +} + +class DWARFContext : public llvm::DIContext {}; + +DWARFContext *getDWARFContext(DWARFSection debug_info, + DWARFSection debug_abbrev, + DWARFSection debug_aranges, + DWARFSection debug_line, + DWARFSection debug_str) { + return (DWARFContext*)llvm::DIContext::getDWARFContext( + true, ToStringRef(debug_info), ToStringRef(debug_abbrev), + llvm::StringRef(), // don't use .debug_aranges for now. + ToStringRef(debug_line), ToStringRef(debug_str)); +} + +void getLineInfoFromContext(DWARFContext *context, AddressInfo *info) { + CHECK(context); + uint32_t flags = llvm::DILineInfoSpecifier::FileLineInfo | + llvm::DILineInfoSpecifier::AbsoluteFilePath | + llvm::DILineInfoSpecifier::FunctionName; + llvm::DILineInfo line_info = context->getLineInfoForAddress( + info->module_offset, flags); + + const char *function = line_info.getFunctionName(); + CHECK(function); + if (0 != internal_strcmp("<invalid>", function)) + info->function = internal_strdup(function); + else + info->function = 0; + + const char *file = line_info.getFileName(); + CHECK(file); + if (0 != internal_strcmp("<invalid>", file)) + info->file = internal_strdup(file); + else + info->file = 0; + + info->line = line_info.getLine(); + info->column = line_info.getColumn(); +} + +} // namespace __sanitizer + +#else // SANITIZER_USES_LLVM_LIBS +namespace __sanitizer { + +class DWARFContext {}; + +DWARFContext *getDWARFContext(DWARFSection debug_info, + DWARFSection debug_abbrev, + DWARFSection debug_aranges, + DWARFSection debug_line, + DWARFSection debug_str) { + return 0; +} + +void getLineInfoFromContext(DWARFContext *context, AddressInfo *info) { + (void)context; + info->function = 0; + info->file = 0; + info->line = 0; + info->column = 0; +} + +} // namespace __sanitizer +#endif // SANITIZER_USES_LLVM_LIBS |