]>
Commit | Line | Data |
---|---|---|
b667dd70 | 1 | //===-- sanitizer_symbolizer.cpp ------------------------------------------===// |
df77f0e4 | 2 | // |
b667dd70 ML |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. | |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
df77f0e4 KS |
6 | // |
7 | //===----------------------------------------------------------------------===// | |
8 | // | |
9 | // This file is shared between AddressSanitizer and ThreadSanitizer | |
10 | // run-time libraries. | |
11 | //===----------------------------------------------------------------------===// | |
12 | ||
696d846a | 13 | #include "sanitizer_allocator_internal.h" |
df77f0e4 KS |
14 | #include "sanitizer_platform.h" |
15 | #include "sanitizer_internal_defs.h" | |
696d846a | 16 | #include "sanitizer_libc.h" |
df77f0e4 | 17 | #include "sanitizer_placement_new.h" |
696d846a | 18 | #include "sanitizer_symbolizer_internal.h" |
df77f0e4 KS |
19 | |
20 | namespace __sanitizer { | |
21 | ||
696d846a MO |
22 | AddressInfo::AddressInfo() { |
23 | internal_memset(this, 0, sizeof(AddressInfo)); | |
24 | function_offset = kUnknown; | |
25 | } | |
26 | ||
27 | void AddressInfo::Clear() { | |
28 | InternalFree(module); | |
29 | InternalFree(function); | |
30 | InternalFree(file); | |
31 | internal_memset(this, 0, sizeof(AddressInfo)); | |
32 | function_offset = kUnknown; | |
33 | } | |
34 | ||
5d3805fc JJ |
35 | void AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset, |
36 | ModuleArch mod_arch) { | |
696d846a MO |
37 | module = internal_strdup(mod_name); |
38 | module_offset = mod_offset; | |
5d3805fc | 39 | module_arch = mod_arch; |
696d846a MO |
40 | } |
41 | ||
42 | SymbolizedStack::SymbolizedStack() : next(nullptr), info() {} | |
43 | ||
44 | SymbolizedStack *SymbolizedStack::New(uptr addr) { | |
45 | void *mem = InternalAlloc(sizeof(SymbolizedStack)); | |
46 | SymbolizedStack *res = new(mem) SymbolizedStack(); | |
47 | res->info.address = addr; | |
48 | return res; | |
49 | } | |
50 | ||
51 | void SymbolizedStack::ClearAll() { | |
52 | info.Clear(); | |
53 | if (next) | |
54 | next->ClearAll(); | |
55 | InternalFree(this); | |
56 | } | |
57 | ||
58 | DataInfo::DataInfo() { | |
59 | internal_memset(this, 0, sizeof(DataInfo)); | |
60 | } | |
61 | ||
62 | void DataInfo::Clear() { | |
63 | InternalFree(module); | |
10189819 | 64 | InternalFree(file); |
696d846a MO |
65 | InternalFree(name); |
66 | internal_memset(this, 0, sizeof(DataInfo)); | |
67 | } | |
68 | ||
b667dd70 ML |
69 | void FrameInfo::Clear() { |
70 | InternalFree(module); | |
71 | for (LocalInfo &local : locals) { | |
72 | InternalFree(local.function_name); | |
73 | InternalFree(local.name); | |
74 | InternalFree(local.decl_file); | |
75 | } | |
76 | locals.clear(); | |
77 | } | |
78 | ||
df77f0e4 KS |
79 | Symbolizer *Symbolizer::symbolizer_; |
80 | StaticSpinMutex Symbolizer::init_mu_; | |
81 | LowLevelAllocator Symbolizer::symbolizer_allocator_; | |
82 | ||
5d3805fc JJ |
83 | void Symbolizer::InvalidateModuleList() { |
84 | modules_fresh_ = false; | |
85 | } | |
86 | ||
df77f0e4 KS |
87 | void Symbolizer::AddHooks(Symbolizer::StartSymbolizationHook start_hook, |
88 | Symbolizer::EndSymbolizationHook end_hook) { | |
89 | CHECK(start_hook_ == 0 && end_hook_ == 0); | |
90 | start_hook_ = start_hook; | |
91 | end_hook_ = end_hook; | |
92 | } | |
93 | ||
696d846a MO |
94 | const char *Symbolizer::ModuleNameOwner::GetOwnedCopy(const char *str) { |
95 | mu_->CheckLocked(); | |
96 | ||
97 | // 'str' will be the same string multiple times in a row, optimize this case. | |
98 | if (last_match_ && !internal_strcmp(last_match_, str)) | |
99 | return last_match_; | |
100 | ||
101 | // FIXME: this is linear search. | |
102 | // We should optimize this further if this turns out to be a bottleneck later. | |
103 | for (uptr i = 0; i < storage_.size(); ++i) { | |
104 | if (!internal_strcmp(storage_[i], str)) { | |
105 | last_match_ = storage_[i]; | |
106 | return last_match_; | |
107 | } | |
108 | } | |
109 | last_match_ = internal_strdup(str); | |
110 | storage_.push_back(last_match_); | |
111 | return last_match_; | |
112 | } | |
113 | ||
114 | Symbolizer::Symbolizer(IntrusiveList<SymbolizerTool> tools) | |
10189819 | 115 | : module_names_(&mu_), modules_(), modules_fresh_(false), tools_(tools), |
696d846a | 116 | start_hook_(0), end_hook_(0) {} |
df77f0e4 KS |
117 | |
118 | Symbolizer::SymbolizerScope::SymbolizerScope(const Symbolizer *sym) | |
119 | : sym_(sym) { | |
120 | if (sym_->start_hook_) | |
121 | sym_->start_hook_(); | |
122 | } | |
123 | ||
124 | Symbolizer::SymbolizerScope::~SymbolizerScope() { | |
125 | if (sym_->end_hook_) | |
126 | sym_->end_hook_(); | |
127 | } | |
128 | ||
3c6331c2 ML |
129 | void Symbolizer::LateInitializeTools() { |
130 | for (auto &tool : tools_) { | |
131 | tool.LateInitialize(); | |
132 | } | |
133 | } | |
134 | ||
df77f0e4 | 135 | } // namespace __sanitizer |