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.4 mrg #include <errno.h> 14 1.4 mrg 15 1.1 mrg #include "sanitizer_allocator_internal.h" 16 1.4 mrg #include "sanitizer_common.h" 17 1.1 mrg #include "sanitizer_internal_defs.h" 18 1.1 mrg #include "sanitizer_libc.h" 19 1.1 mrg #include "sanitizer_placement_new.h" 20 1.4 mrg #include "sanitizer_platform.h" 21 1.1 mrg #include "sanitizer_symbolizer_internal.h" 22 1.1 mrg 23 1.1 mrg namespace __sanitizer { 24 1.1 mrg 25 1.1 mrg AddressInfo::AddressInfo() { 26 1.1 mrg internal_memset(this, 0, sizeof(AddressInfo)); 27 1.1 mrg function_offset = kUnknown; 28 1.1 mrg } 29 1.1 mrg 30 1.1 mrg void AddressInfo::Clear() { 31 1.1 mrg InternalFree(module); 32 1.1 mrg InternalFree(function); 33 1.1 mrg InternalFree(file); 34 1.1 mrg internal_memset(this, 0, sizeof(AddressInfo)); 35 1.1 mrg function_offset = kUnknown; 36 1.4 mrg uuid_size = 0; 37 1.1 mrg } 38 1.1 mrg 39 1.1 mrg void AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset, 40 1.1 mrg ModuleArch mod_arch) { 41 1.1 mrg module = internal_strdup(mod_name); 42 1.1 mrg module_offset = mod_offset; 43 1.1 mrg module_arch = mod_arch; 44 1.4 mrg uuid_size = 0; 45 1.4 mrg } 46 1.4 mrg 47 1.4 mrg void AddressInfo::FillModuleInfo(const LoadedModule &mod) { 48 1.4 mrg module = internal_strdup(mod.full_name()); 49 1.4 mrg module_offset = address - mod.base_address(); 50 1.4 mrg module_arch = mod.arch(); 51 1.4 mrg if (mod.uuid_size()) 52 1.4 mrg internal_memcpy(uuid, mod.uuid(), mod.uuid_size()); 53 1.4 mrg uuid_size = mod.uuid_size(); 54 1.1 mrg } 55 1.1 mrg 56 1.1 mrg SymbolizedStack::SymbolizedStack() : next(nullptr), info() {} 57 1.1 mrg 58 1.1 mrg SymbolizedStack *SymbolizedStack::New(uptr addr) { 59 1.1 mrg void *mem = InternalAlloc(sizeof(SymbolizedStack)); 60 1.1 mrg SymbolizedStack *res = new(mem) SymbolizedStack(); 61 1.1 mrg res->info.address = addr; 62 1.1 mrg return res; 63 1.1 mrg } 64 1.1 mrg 65 1.1 mrg void SymbolizedStack::ClearAll() { 66 1.1 mrg info.Clear(); 67 1.1 mrg if (next) 68 1.1 mrg next->ClearAll(); 69 1.1 mrg InternalFree(this); 70 1.1 mrg } 71 1.1 mrg 72 1.1 mrg DataInfo::DataInfo() { 73 1.1 mrg internal_memset(this, 0, sizeof(DataInfo)); 74 1.1 mrg } 75 1.1 mrg 76 1.1 mrg void DataInfo::Clear() { 77 1.1 mrg InternalFree(module); 78 1.1 mrg InternalFree(file); 79 1.1 mrg InternalFree(name); 80 1.1 mrg internal_memset(this, 0, sizeof(DataInfo)); 81 1.1 mrg } 82 1.1 mrg 83 1.1 mrg void FrameInfo::Clear() { 84 1.1 mrg InternalFree(module); 85 1.1 mrg for (LocalInfo &local : locals) { 86 1.1 mrg InternalFree(local.function_name); 87 1.1 mrg InternalFree(local.name); 88 1.1 mrg InternalFree(local.decl_file); 89 1.1 mrg } 90 1.1 mrg locals.clear(); 91 1.1 mrg } 92 1.1 mrg 93 1.1 mrg Symbolizer *Symbolizer::symbolizer_; 94 1.1 mrg StaticSpinMutex Symbolizer::init_mu_; 95 1.1 mrg LowLevelAllocator Symbolizer::symbolizer_allocator_; 96 1.1 mrg 97 1.1 mrg void Symbolizer::InvalidateModuleList() { 98 1.1 mrg modules_fresh_ = false; 99 1.1 mrg } 100 1.1 mrg 101 1.1 mrg void Symbolizer::AddHooks(Symbolizer::StartSymbolizationHook start_hook, 102 1.1 mrg Symbolizer::EndSymbolizationHook end_hook) { 103 1.1 mrg CHECK(start_hook_ == 0 && end_hook_ == 0); 104 1.1 mrg start_hook_ = start_hook; 105 1.1 mrg end_hook_ = end_hook; 106 1.1 mrg } 107 1.1 mrg 108 1.1 mrg const char *Symbolizer::ModuleNameOwner::GetOwnedCopy(const char *str) { 109 1.1 mrg mu_->CheckLocked(); 110 1.1 mrg 111 1.1 mrg // 'str' will be the same string multiple times in a row, optimize this case. 112 1.1 mrg if (last_match_ && !internal_strcmp(last_match_, str)) 113 1.1 mrg return last_match_; 114 1.1 mrg 115 1.1 mrg // FIXME: this is linear search. 116 1.1 mrg // We should optimize this further if this turns out to be a bottleneck later. 117 1.1 mrg for (uptr i = 0; i < storage_.size(); ++i) { 118 1.1 mrg if (!internal_strcmp(storage_[i], str)) { 119 1.1 mrg last_match_ = storage_[i]; 120 1.1 mrg return last_match_; 121 1.1 mrg } 122 1.1 mrg } 123 1.1 mrg last_match_ = internal_strdup(str); 124 1.1 mrg storage_.push_back(last_match_); 125 1.1 mrg return last_match_; 126 1.1 mrg } 127 1.1 mrg 128 1.1 mrg Symbolizer::Symbolizer(IntrusiveList<SymbolizerTool> tools) 129 1.1 mrg : module_names_(&mu_), modules_(), modules_fresh_(false), tools_(tools), 130 1.1 mrg start_hook_(0), end_hook_(0) {} 131 1.1 mrg 132 1.1 mrg Symbolizer::SymbolizerScope::SymbolizerScope(const Symbolizer *sym) 133 1.4 mrg : sym_(sym), errno_(errno) { 134 1.1 mrg if (sym_->start_hook_) 135 1.1 mrg sym_->start_hook_(); 136 1.1 mrg } 137 1.1 mrg 138 1.1 mrg Symbolizer::SymbolizerScope::~SymbolizerScope() { 139 1.1 mrg if (sym_->end_hook_) 140 1.1 mrg sym_->end_hook_(); 141 1.4 mrg errno = errno_; 142 1.3 mrg } 143 1.3 mrg 144 1.1 mrg } // namespace __sanitizer 145