[AArch64] Add cost handling of CALLER_SAVE_REGS and POINTER_REGS
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_symbolizer_win.cc
blobc014c6af42bd90e7d4a7ff36df69e60bfc7610ef
1 //===-- sanitizer_symbolizer_win.cc ---------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is shared between AddressSanitizer and ThreadSanitizer
9 // run-time libraries.
10 // Windows-specific implementation of symbolizer parts.
11 //===----------------------------------------------------------------------===//
13 #include "sanitizer_platform.h"
14 #if SANITIZER_WINDOWS
15 #include <windows.h>
16 #include <dbghelp.h>
17 #pragma comment(lib, "dbghelp.lib")
19 #include "sanitizer_symbolizer.h"
21 namespace __sanitizer {
23 class WinSymbolizer : public Symbolizer {
24 public:
25 WinSymbolizer() : initialized_(false) {}
27 uptr SymbolizePC(uptr addr, AddressInfo *frames, uptr max_frames) {
28 if (max_frames == 0)
29 return 0;
31 BlockingMutexLock l(&dbghelp_mu_);
32 if (!initialized_) {
33 SymSetOptions(SYMOPT_DEFERRED_LOADS |
34 SYMOPT_UNDNAME |
35 SYMOPT_LOAD_LINES);
36 CHECK(SymInitialize(GetCurrentProcess(), 0, TRUE));
37 // FIXME: We don't call SymCleanup() on exit yet - should we?
38 initialized_ = true;
41 // See http://msdn.microsoft.com/en-us/library/ms680578(VS.85).aspx
42 char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(CHAR)];
43 PSYMBOL_INFO symbol = (PSYMBOL_INFO)buffer;
44 symbol->SizeOfStruct = sizeof(SYMBOL_INFO);
45 symbol->MaxNameLen = MAX_SYM_NAME;
46 DWORD64 offset = 0;
47 BOOL got_objname = SymFromAddr(GetCurrentProcess(),
48 (DWORD64)addr, &offset, symbol);
49 if (!got_objname)
50 return 0;
52 DWORD unused;
53 IMAGEHLP_LINE64 line_info;
54 line_info.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
55 BOOL got_fileline = SymGetLineFromAddr64(GetCurrentProcess(), (DWORD64)addr,
56 &unused, &line_info);
57 AddressInfo *info = &frames[0];
58 info->Clear();
59 info->function = internal_strdup(symbol->Name);
60 info->function_offset = (uptr)offset;
61 if (got_fileline) {
62 info->file = internal_strdup(line_info.FileName);
63 info->line = line_info.LineNumber;
66 IMAGEHLP_MODULE64 mod_info;
67 internal_memset(&mod_info, 0, sizeof(mod_info));
68 mod_info.SizeOfStruct = sizeof(mod_info);
69 if (SymGetModuleInfo64(GetCurrentProcess(), addr, &mod_info))
70 info->FillAddressAndModuleInfo(addr, mod_info.ImageName,
71 addr - (uptr)mod_info.BaseOfImage);
72 return 1;
75 bool CanReturnFileLineInfo() {
76 return true;
79 const char *Demangle(const char *name) {
80 CHECK(initialized_);
81 static char demangle_buffer[1000];
82 if (name[0] == '\01' &&
83 UnDecorateSymbolName(name + 1, demangle_buffer, sizeof(demangle_buffer),
84 UNDNAME_NAME_ONLY))
85 return demangle_buffer;
86 else
87 return name;
90 // FIXME: Implement GetModuleNameAndOffsetForPC().
92 private:
93 // All DbgHelp functions are single threaded, so we should use a mutex to
94 // serialize accesses.
95 BlockingMutex dbghelp_mu_;
96 bool initialized_;
99 Symbolizer *Symbolizer::PlatformInit(const char *path_to_external) {
100 static bool called_once = false;
101 CHECK(!called_once && "Shouldn't create more than one symbolizer");
102 called_once = true;
103 return new(symbolizer_allocator_) WinSymbolizer();
106 } // namespace __sanitizer
108 #endif // _WIN32