brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.7 KiB · 31d91ef Raw
163 lines · cpp
1//===-- sanitizer_symbolizer_markup.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-exception6//7//===----------------------------------------------------------------------===//8//9// This file is shared between various sanitizers' runtime libraries.10//11// This generic support for offline symbolizing is based on the12// Fuchsia port.  We don't do any actual symbolization per se.13// Instead, we emit text containing raw addresses and raw linkage14// symbol names, embedded in Fuchsia's symbolization markup format.15// See the spec at:16// https://llvm.org/docs/SymbolizerMarkupFormat.html17//===----------------------------------------------------------------------===//18 19#include "sanitizer_symbolizer_markup.h"20 21#include "sanitizer_common.h"22#include "sanitizer_symbolizer.h"23#include "sanitizer_symbolizer_markup_constants.h"24 25namespace __sanitizer {26 27void MarkupStackTracePrinter::RenderData(InternalScopedString *buffer,28                                         const char *format, const DataInfo *DI,29                                         const char *strip_path_prefix) {30  RenderContext(buffer);31  buffer->AppendF(kFormatData, reinterpret_cast<void *>(DI->start));32}33 34bool MarkupStackTracePrinter::RenderNeedsSymbolization(const char *format) {35  return false;36}37 38// We don't support the stack_trace_format flag at all.39void MarkupStackTracePrinter::RenderFrame(InternalScopedString *buffer,40                                          const char *format, int frame_no,41                                          uptr address, const AddressInfo *info,42                                          bool vs_style,43                                          const char *strip_path_prefix) {44  CHECK(!RenderNeedsSymbolization(format));45  RenderContext(buffer);46  buffer->AppendF(kFormatFrame, frame_no, reinterpret_cast<void *>(address));47}48 49bool MarkupSymbolizerTool::SymbolizePC(uptr addr, SymbolizedStack *stack) {50  char buffer[kFormatFunctionMax];51  internal_snprintf(buffer, sizeof(buffer), kFormatFunction,52                    reinterpret_cast<void *>(addr));53  stack->info.function = internal_strdup(buffer);54  return true;55}56 57bool MarkupSymbolizerTool::SymbolizeData(uptr addr, DataInfo *info) {58  info->Clear();59  info->start = addr;60  return true;61}62 63const char *MarkupSymbolizerTool::Demangle(const char *name) {64  static char buffer[kFormatDemangleMax];65  internal_snprintf(buffer, sizeof(buffer), kFormatDemangle, name);66  return buffer;67}68 69// Fuchsia's implementation of symbolizer markup doesn't need to emit contextual70// elements at this point.71// Fuchsia's logging infrastructure emits enough information about72// process memory layout that a post-processing filter can do the73// symbolization and pretty-print the markup.74#if !SANITIZER_FUCHSIA75 76static bool ModulesEq(const LoadedModule &module,77                      const RenderedModule &renderedModule) {78  return module.base_address() == renderedModule.base_address &&79         internal_memcmp(module.uuid(), renderedModule.uuid,80                         module.uuid_size()) == 0 &&81         internal_strcmp(module.full_name(), renderedModule.full_name) == 0;82}83 84static bool ModuleHasBeenRendered(85    const LoadedModule &module,86    const InternalMmapVectorNoCtor<RenderedModule> &renderedModules) {87  for (const auto &renderedModule : renderedModules)88    if (ModulesEq(module, renderedModule))89      return true;90 91  return false;92}93 94static void RenderModule(InternalScopedString *buffer,95                         const LoadedModule &module, uptr moduleId) {96  InternalScopedString buildIdBuffer;97  for (uptr i = 0; i < module.uuid_size(); i++)98    buildIdBuffer.AppendF("%02x", module.uuid()[i]);99 100  buffer->AppendF(kFormatModule, moduleId, module.full_name(),101                  buildIdBuffer.data());102  buffer->Append("\n");103}104 105static void RenderMmaps(InternalScopedString *buffer,106                        const LoadedModule &module, uptr moduleId) {107  InternalScopedString accessBuffer;108 109  // All module mmaps are readable at least110  for (const auto &range : module.ranges()) {111    accessBuffer.Append("r");112    if (range.writable)113      accessBuffer.Append("w");114    if (range.executable)115      accessBuffer.Append("x");116 117    //{{{mmap:%starting_addr:%size_in_hex:load:%moduleId:r%(w|x):%relative_addr}}}118 119    // module.base_address == dlpi_addr120    // range.beg == dlpi_addr + p_vaddr121    // relative address == p_vaddr == range.beg - module.base_address122    buffer->AppendF(kFormatMmap, reinterpret_cast<void *>(range.beg),123                    range.end - range.beg, static_cast<int>(moduleId),124                    accessBuffer.data(), range.beg - module.base_address());125 126    buffer->Append("\n");127    accessBuffer.clear();128  }129}130 131void MarkupStackTracePrinter::RenderContext(InternalScopedString *buffer) {132  if (renderedModules_.size() == 0)133    buffer->Append("{{{reset}}}\n");134 135  const auto &modules = Symbolizer::GetOrInit()->GetRefreshedListOfModules();136 137  for (const auto &module : modules) {138    if (ModuleHasBeenRendered(module, renderedModules_))139      continue;140 141    // symbolizer markup id, used to refer to this modules from other contextual142    // elements143    uptr moduleId = renderedModules_.size();144 145    RenderModule(buffer, module, moduleId);146    RenderMmaps(buffer, module, moduleId);147 148    renderedModules_.push_back({149        internal_strdup(module.full_name()),150        module.base_address(),151        {},152    });153 154    // kModuleUUIDSize is the size of curModule.uuid155    CHECK_GE(kModuleUUIDSize, module.uuid_size());156    internal_memcpy(renderedModules_.back().uuid, module.uuid(),157                    module.uuid_size());158  }159}160#endif  // !SANITIZER_FUCHSIA161 162}  // namespace __sanitizer163