summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/sanitizer_common/CMakeLists.txt4
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer.cc23
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer.h11
-rw-r--r--lib/sanitizer_common/sanitizer_symbolizer_llvm.cc104
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 &section) {
+ 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