Home | History | Annotate | Line # | Download | only in sanitizer_common
      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