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