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