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