brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.8 KiB · 1de633f Raw
171 lines · cpp
1//===-- FormatterBytecode.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#include "FormatterBytecode.h"10#include "lldb/Core/Module.h"11#include "lldb/DataFormatters/DataVisualization.h"12#include "lldb/Utility/LLDBLog.h"13 14using namespace lldb;15 16namespace lldb_private {17static void ForEachFormatterInModule(18    Module &module, SectionType section_type,19    std::function<void(llvm::DataExtractor, llvm::StringRef)> fn) {20  auto *sections = module.GetSectionList();21  if (!sections)22    return;23 24  auto section_sp = sections->FindSectionByType(section_type, true);25  if (!section_sp)26    return;27 28  TypeCategoryImplSP category;29  DataVisualization::Categories::GetCategory(ConstString("default"), category);30 31  // The type summary record is serialized as follows.32  //33  // Each record contains, in order:34  //   * Version number of the record format35  //   * The remaining size of the record36  //   * The size of the type identifier37  //   * The type identifier, either a type name, or a regex38  //   * The size of the entry39  //   * The entry40  //41  // Integers are encoded using ULEB.42  //43  // Strings are encoded with first a length (ULEB), then the string contents,44  // and lastly a null terminator. The length includes the null.45 46  DataExtractor lldb_extractor;47  auto section_size = section_sp->GetSectionData(lldb_extractor);48  llvm::DataExtractor section = lldb_extractor.GetAsLLVM();49  bool le = section.isLittleEndian();50  uint8_t addr_size = section.getAddressSize();51  llvm::DataExtractor::Cursor cursor(0);52  while (cursor && cursor.tell() < section_size) {53    while (cursor && cursor.tell() < section_size) {54      // Skip over 0 padding.55      if (section.getU8(cursor) == 0)56        continue;57      cursor.seek(cursor.tell() - 1);58      break;59    }60    uint64_t version = section.getULEB128(cursor);61    uint64_t record_size = section.getULEB128(cursor);62    if (version == 1) {63      llvm::DataExtractor record(section.getData().drop_front(cursor.tell()),64                                 le, addr_size);65      llvm::DataExtractor::Cursor cursor(0);66      uint64_t type_size = record.getULEB128(cursor);67      llvm::StringRef type_name = record.getBytes(cursor, type_size);68      llvm::Error error = cursor.takeError();69      if (!error)70        fn(llvm::DataExtractor(record.getData().drop_front(cursor.tell()), le,71                               addr_size),72           type_name);73      else74        LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), std::move(error),75                       "{0}");76    } else {77      // Skip unsupported record.78      LLDB_LOG(79          GetLog(LLDBLog::DataFormatters),80          "Skipping unsupported embedded type summary of version {0} in {1}.",81          version, module.GetFileSpec());82    }83    section.skip(cursor, record_size);84  }85  if (!cursor)86    LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(), "{0}");87}88 89void LoadTypeSummariesForModule(ModuleSP module_sp) {90  ForEachFormatterInModule(91      *module_sp, eSectionTypeLLDBTypeSummaries,92      [&](llvm::DataExtractor extractor, llvm::StringRef type_name) {93        TypeCategoryImplSP category;94        DataVisualization::Categories::GetCategory(ConstString("default"),95                                                   category);96        // The type summary record is serialized as follows.97        //98        //   * The size of the summary string99        //   * The summary string100        //101        // Integers are encoded using ULEB.102        llvm::DataExtractor::Cursor cursor(0);103        uint64_t summary_size = extractor.getULEB128(cursor);104        llvm::StringRef summary_string =105            extractor.getBytes(cursor, summary_size);106        if (!cursor) {107          LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(),108                         "{0}");109          return;110        }111        if (type_name.empty() || summary_string.empty()) {112          LLDB_LOG(GetLog(LLDBLog::DataFormatters),113                   "Missing string(s) in embedded type summary in {0}, "114                   "type_name={1}, summary={2}",115                   module_sp->GetFileSpec(), type_name, summary_string);116          return;117        }118        TypeSummaryImpl::Flags flags;119        auto summary_sp = std::make_shared<StringSummaryFormat>(120            flags, summary_string.str().c_str());121        FormatterMatchType match_type = eFormatterMatchExact;122        if (type_name.front() == '^')123          match_type = eFormatterMatchRegex;124        category->AddTypeSummary(type_name, match_type, summary_sp);125        LLDB_LOG(GetLog(LLDBLog::DataFormatters),126                 "Loaded embedded type summary for '{0}' from {1}.", type_name,127                 module_sp->GetFileSpec());128      });129}130 131void LoadFormattersForModule(ModuleSP module_sp) {132  ForEachFormatterInModule(133      *module_sp, eSectionTypeLLDBFormatters,134      [&](llvm::DataExtractor extractor, llvm::StringRef type_name) {135        // * Function signature (1 byte)136        // * Length of the program (ULEB128)137        // * The program bytecode138        TypeCategoryImplSP category;139        DataVisualization::Categories::GetCategory(ConstString("default"),140                                                   category);141        llvm::DataExtractor::Cursor cursor(0);142        uint64_t flags = extractor.getULEB128(cursor);143        while (cursor && cursor.tell() < extractor.size()) {144          uint8_t signature = extractor.getU8(cursor);145          uint64_t size = extractor.getULEB128(cursor);146          llvm::StringRef bytecode = extractor.getBytes(cursor, size);147          if (!cursor) {148            LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(),149                           "{0}");150            return;151          }152          if (signature == 0) {153            auto summary_sp = std::make_shared<BytecodeSummaryFormat>(154                TypeSummaryImpl::Flags(flags),155                llvm::MemoryBuffer::getMemBufferCopy(bytecode));156            FormatterMatchType match_type = eFormatterMatchExact;157            if (type_name.front() == '^')158              match_type = eFormatterMatchRegex;159            category->AddTypeSummary(type_name, match_type, summary_sp);160            LLDB_LOG(GetLog(LLDBLog::DataFormatters),161                     "Loaded embedded type summary for '{0}' from {1}.",162                     type_name, module_sp->GetFileSpec());163          } else164            LLDB_LOG(GetLog(LLDBLog::DataFormatters),165                     "Unsupported formatter signature {0} for '{1}' in {2}",166                     signature, type_name, module_sp->GetFileSpec());167        }168      });169}170} // namespace lldb_private171