xref: /openbsd-src/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_symbolizer.cpp (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrick //===-- sanitizer_symbolizer.cpp ------------------------------------------===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is shared between AddressSanitizer and ThreadSanitizer
103cab2bb3Spatrick // run-time libraries.
113cab2bb3Spatrick //===----------------------------------------------------------------------===//
123cab2bb3Spatrick 
133cab2bb3Spatrick #include "sanitizer_allocator_internal.h"
14*810390e3Srobert #include "sanitizer_common.h"
153cab2bb3Spatrick #include "sanitizer_internal_defs.h"
163cab2bb3Spatrick #include "sanitizer_libc.h"
173cab2bb3Spatrick #include "sanitizer_placement_new.h"
18*810390e3Srobert #include "sanitizer_platform.h"
193cab2bb3Spatrick #include "sanitizer_symbolizer_internal.h"
203cab2bb3Spatrick 
213cab2bb3Spatrick namespace __sanitizer {
223cab2bb3Spatrick 
AddressInfo()233cab2bb3Spatrick AddressInfo::AddressInfo() {
243cab2bb3Spatrick   internal_memset(this, 0, sizeof(AddressInfo));
253cab2bb3Spatrick   function_offset = kUnknown;
263cab2bb3Spatrick }
273cab2bb3Spatrick 
Clear()283cab2bb3Spatrick void AddressInfo::Clear() {
293cab2bb3Spatrick   InternalFree(module);
303cab2bb3Spatrick   InternalFree(function);
313cab2bb3Spatrick   InternalFree(file);
323cab2bb3Spatrick   internal_memset(this, 0, sizeof(AddressInfo));
333cab2bb3Spatrick   function_offset = kUnknown;
34*810390e3Srobert   uuid_size = 0;
353cab2bb3Spatrick }
363cab2bb3Spatrick 
FillModuleInfo(const char * mod_name,uptr mod_offset,ModuleArch mod_arch)373cab2bb3Spatrick void AddressInfo::FillModuleInfo(const char *mod_name, uptr mod_offset,
383cab2bb3Spatrick                                  ModuleArch mod_arch) {
393cab2bb3Spatrick   module = internal_strdup(mod_name);
403cab2bb3Spatrick   module_offset = mod_offset;
413cab2bb3Spatrick   module_arch = mod_arch;
42*810390e3Srobert   uuid_size = 0;
43*810390e3Srobert }
44*810390e3Srobert 
FillModuleInfo(const LoadedModule & mod)45*810390e3Srobert void AddressInfo::FillModuleInfo(const LoadedModule &mod) {
46*810390e3Srobert   module = internal_strdup(mod.full_name());
47*810390e3Srobert   module_offset = address - mod.base_address();
48*810390e3Srobert   module_arch = mod.arch();
49*810390e3Srobert   if (mod.uuid_size())
50*810390e3Srobert     internal_memcpy(uuid, mod.uuid(), mod.uuid_size());
51*810390e3Srobert   uuid_size = mod.uuid_size();
523cab2bb3Spatrick }
533cab2bb3Spatrick 
SymbolizedStack()543cab2bb3Spatrick SymbolizedStack::SymbolizedStack() : next(nullptr), info() {}
553cab2bb3Spatrick 
New(uptr addr)563cab2bb3Spatrick SymbolizedStack *SymbolizedStack::New(uptr addr) {
573cab2bb3Spatrick   void *mem = InternalAlloc(sizeof(SymbolizedStack));
583cab2bb3Spatrick   SymbolizedStack *res = new(mem) SymbolizedStack();
593cab2bb3Spatrick   res->info.address = addr;
603cab2bb3Spatrick   return res;
613cab2bb3Spatrick }
623cab2bb3Spatrick 
ClearAll()633cab2bb3Spatrick void SymbolizedStack::ClearAll() {
643cab2bb3Spatrick   info.Clear();
653cab2bb3Spatrick   if (next)
663cab2bb3Spatrick     next->ClearAll();
673cab2bb3Spatrick   InternalFree(this);
683cab2bb3Spatrick }
693cab2bb3Spatrick 
DataInfo()703cab2bb3Spatrick DataInfo::DataInfo() {
713cab2bb3Spatrick   internal_memset(this, 0, sizeof(DataInfo));
723cab2bb3Spatrick }
733cab2bb3Spatrick 
Clear()743cab2bb3Spatrick void DataInfo::Clear() {
753cab2bb3Spatrick   InternalFree(module);
763cab2bb3Spatrick   InternalFree(file);
773cab2bb3Spatrick   InternalFree(name);
783cab2bb3Spatrick   internal_memset(this, 0, sizeof(DataInfo));
793cab2bb3Spatrick }
803cab2bb3Spatrick 
Clear()813cab2bb3Spatrick void FrameInfo::Clear() {
823cab2bb3Spatrick   InternalFree(module);
833cab2bb3Spatrick   for (LocalInfo &local : locals) {
843cab2bb3Spatrick     InternalFree(local.function_name);
853cab2bb3Spatrick     InternalFree(local.name);
863cab2bb3Spatrick     InternalFree(local.decl_file);
873cab2bb3Spatrick   }
883cab2bb3Spatrick   locals.clear();
893cab2bb3Spatrick }
903cab2bb3Spatrick 
913cab2bb3Spatrick Symbolizer *Symbolizer::symbolizer_;
923cab2bb3Spatrick StaticSpinMutex Symbolizer::init_mu_;
933cab2bb3Spatrick LowLevelAllocator Symbolizer::symbolizer_allocator_;
943cab2bb3Spatrick 
InvalidateModuleList()953cab2bb3Spatrick void Symbolizer::InvalidateModuleList() {
963cab2bb3Spatrick   modules_fresh_ = false;
973cab2bb3Spatrick }
983cab2bb3Spatrick 
AddHooks(Symbolizer::StartSymbolizationHook start_hook,Symbolizer::EndSymbolizationHook end_hook)993cab2bb3Spatrick void Symbolizer::AddHooks(Symbolizer::StartSymbolizationHook start_hook,
1003cab2bb3Spatrick                           Symbolizer::EndSymbolizationHook end_hook) {
1013cab2bb3Spatrick   CHECK(start_hook_ == 0 && end_hook_ == 0);
1023cab2bb3Spatrick   start_hook_ = start_hook;
1033cab2bb3Spatrick   end_hook_ = end_hook;
1043cab2bb3Spatrick }
1053cab2bb3Spatrick 
GetOwnedCopy(const char * str)1063cab2bb3Spatrick const char *Symbolizer::ModuleNameOwner::GetOwnedCopy(const char *str) {
1073cab2bb3Spatrick   mu_->CheckLocked();
1083cab2bb3Spatrick 
1093cab2bb3Spatrick   // 'str' will be the same string multiple times in a row, optimize this case.
1103cab2bb3Spatrick   if (last_match_ && !internal_strcmp(last_match_, str))
1113cab2bb3Spatrick     return last_match_;
1123cab2bb3Spatrick 
1133cab2bb3Spatrick   // FIXME: this is linear search.
1143cab2bb3Spatrick   // We should optimize this further if this turns out to be a bottleneck later.
1153cab2bb3Spatrick   for (uptr i = 0; i < storage_.size(); ++i) {
1163cab2bb3Spatrick     if (!internal_strcmp(storage_[i], str)) {
1173cab2bb3Spatrick       last_match_ = storage_[i];
1183cab2bb3Spatrick       return last_match_;
1193cab2bb3Spatrick     }
1203cab2bb3Spatrick   }
1213cab2bb3Spatrick   last_match_ = internal_strdup(str);
1223cab2bb3Spatrick   storage_.push_back(last_match_);
1233cab2bb3Spatrick   return last_match_;
1243cab2bb3Spatrick }
1253cab2bb3Spatrick 
Symbolizer(IntrusiveList<SymbolizerTool> tools)1263cab2bb3Spatrick Symbolizer::Symbolizer(IntrusiveList<SymbolizerTool> tools)
1273cab2bb3Spatrick     : module_names_(&mu_), modules_(), modules_fresh_(false), tools_(tools),
1283cab2bb3Spatrick       start_hook_(0), end_hook_(0) {}
1293cab2bb3Spatrick 
SymbolizerScope(const Symbolizer * sym)1303cab2bb3Spatrick Symbolizer::SymbolizerScope::SymbolizerScope(const Symbolizer *sym)
1313cab2bb3Spatrick     : sym_(sym) {
1323cab2bb3Spatrick   if (sym_->start_hook_)
1333cab2bb3Spatrick     sym_->start_hook_();
1343cab2bb3Spatrick }
1353cab2bb3Spatrick 
~SymbolizerScope()1363cab2bb3Spatrick Symbolizer::SymbolizerScope::~SymbolizerScope() {
1373cab2bb3Spatrick   if (sym_->end_hook_)
1383cab2bb3Spatrick     sym_->end_hook_();
1393cab2bb3Spatrick }
1403cab2bb3Spatrick 
1413cab2bb3Spatrick }  // namespace __sanitizer
142