diff options
| author | Michael Kruse <llvm-project@meinersbur.de> | 2025-01-03 10:22:51 +0100 |
|---|---|---|
| committer | Michael Kruse <llvm-project@meinersbur.de> | 2025-01-03 10:22:51 +0100 |
| commit | 38500d63e14ce340236840f60d356cdefb56a52c (patch) | |
| tree | 17edbec446ce9b50d2f215a483b83afb293a635d /lldb/source/DataFormatters/FormatterSection.cpp | |
| parent | 1a3d5daaef7a6a63448a497da3eff7fc9e23df26 (diff) | |
| parent | 27f30029741ecf023baece7b3dde1ff9011ffefc (diff) | |
Merge branch 'main' into users/meinersbur/flang_runtime_split-headersusers/meinersbur/flang_runtime_split-headers
Diffstat (limited to 'lldb/source/DataFormatters/FormatterSection.cpp')
| -rw-r--r-- | lldb/source/DataFormatters/FormatterSection.cpp | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/lldb/source/DataFormatters/FormatterSection.cpp b/lldb/source/DataFormatters/FormatterSection.cpp new file mode 100644 index 000000000000..1de633f4998e --- /dev/null +++ b/lldb/source/DataFormatters/FormatterSection.cpp @@ -0,0 +1,170 @@ +//===-- FormatterBytecode.cpp ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "FormatterBytecode.h" +#include "lldb/Core/Module.h" +#include "lldb/DataFormatters/DataVisualization.h" +#include "lldb/Utility/LLDBLog.h" + +using namespace lldb; + +namespace lldb_private { +static void ForEachFormatterInModule( + Module &module, SectionType section_type, + std::function<void(llvm::DataExtractor, llvm::StringRef)> fn) { + auto *sections = module.GetSectionList(); + if (!sections) + return; + + auto section_sp = sections->FindSectionByType(section_type, true); + if (!section_sp) + return; + + TypeCategoryImplSP category; + DataVisualization::Categories::GetCategory(ConstString("default"), category); + + // The type summary record is serialized as follows. + // + // Each record contains, in order: + // * Version number of the record format + // * The remaining size of the record + // * The size of the type identifier + // * The type identifier, either a type name, or a regex + // * The size of the entry + // * The entry + // + // Integers are encoded using ULEB. + // + // Strings are encoded with first a length (ULEB), then the string contents, + // and lastly a null terminator. The length includes the null. + + DataExtractor lldb_extractor; + auto section_size = section_sp->GetSectionData(lldb_extractor); + llvm::DataExtractor section = lldb_extractor.GetAsLLVM(); + bool le = section.isLittleEndian(); + uint8_t addr_size = section.getAddressSize(); + llvm::DataExtractor::Cursor cursor(0); + while (cursor && cursor.tell() < section_size) { + while (cursor && cursor.tell() < section_size) { + // Skip over 0 padding. + if (section.getU8(cursor) == 0) + continue; + cursor.seek(cursor.tell() - 1); + break; + } + uint64_t version = section.getULEB128(cursor); + uint64_t record_size = section.getULEB128(cursor); + if (version == 1) { + llvm::DataExtractor record(section.getData().drop_front(cursor.tell()), + le, addr_size); + llvm::DataExtractor::Cursor cursor(0); + uint64_t type_size = record.getULEB128(cursor); + llvm::StringRef type_name = record.getBytes(cursor, type_size); + llvm::Error error = cursor.takeError(); + if (!error) + fn(llvm::DataExtractor(record.getData().drop_front(cursor.tell()), le, + addr_size), + type_name); + else + LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), std::move(error), + "{0}"); + } else { + // Skip unsupported record. + LLDB_LOG( + GetLog(LLDBLog::DataFormatters), + "Skipping unsupported embedded type summary of version {0} in {1}.", + version, module.GetFileSpec()); + } + section.skip(cursor, record_size); + } + if (!cursor) + LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(), "{0}"); +} + +void LoadTypeSummariesForModule(ModuleSP module_sp) { + ForEachFormatterInModule( + *module_sp, eSectionTypeLLDBTypeSummaries, + [&](llvm::DataExtractor extractor, llvm::StringRef type_name) { + TypeCategoryImplSP category; + DataVisualization::Categories::GetCategory(ConstString("default"), + category); + // The type summary record is serialized as follows. + // + // * The size of the summary string + // * The summary string + // + // Integers are encoded using ULEB. + llvm::DataExtractor::Cursor cursor(0); + uint64_t summary_size = extractor.getULEB128(cursor); + llvm::StringRef summary_string = + extractor.getBytes(cursor, summary_size); + if (!cursor) { + LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(), + "{0}"); + return; + } + if (type_name.empty() || summary_string.empty()) { + LLDB_LOG(GetLog(LLDBLog::DataFormatters), + "Missing string(s) in embedded type summary in {0}, " + "type_name={1}, summary={2}", + module_sp->GetFileSpec(), type_name, summary_string); + return; + } + TypeSummaryImpl::Flags flags; + auto summary_sp = std::make_shared<StringSummaryFormat>( + flags, summary_string.str().c_str()); + FormatterMatchType match_type = eFormatterMatchExact; + if (type_name.front() == '^') + match_type = eFormatterMatchRegex; + category->AddTypeSummary(type_name, match_type, summary_sp); + LLDB_LOG(GetLog(LLDBLog::DataFormatters), + "Loaded embedded type summary for '{0}' from {1}.", type_name, + module_sp->GetFileSpec()); + }); +} + +void LoadFormattersForModule(ModuleSP module_sp) { + ForEachFormatterInModule( + *module_sp, eSectionTypeLLDBFormatters, + [&](llvm::DataExtractor extractor, llvm::StringRef type_name) { + // * Function signature (1 byte) + // * Length of the program (ULEB128) + // * The program bytecode + TypeCategoryImplSP category; + DataVisualization::Categories::GetCategory(ConstString("default"), + category); + llvm::DataExtractor::Cursor cursor(0); + uint64_t flags = extractor.getULEB128(cursor); + while (cursor && cursor.tell() < extractor.size()) { + uint8_t signature = extractor.getU8(cursor); + uint64_t size = extractor.getULEB128(cursor); + llvm::StringRef bytecode = extractor.getBytes(cursor, size); + if (!cursor) { + LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(), + "{0}"); + return; + } + if (signature == 0) { + auto summary_sp = std::make_shared<BytecodeSummaryFormat>( + TypeSummaryImpl::Flags(flags), + llvm::MemoryBuffer::getMemBufferCopy(bytecode)); + FormatterMatchType match_type = eFormatterMatchExact; + if (type_name.front() == '^') + match_type = eFormatterMatchRegex; + category->AddTypeSummary(type_name, match_type, summary_sp); + LLDB_LOG(GetLog(LLDBLog::DataFormatters), + "Loaded embedded type summary for '{0}' from {1}.", + type_name, module_sp->GetFileSpec()); + } else + LLDB_LOG(GetLog(LLDBLog::DataFormatters), + "Unsupported formatter signature {0} for '{1}' in {2}", + signature, type_name, module_sp->GetFileSpec()); + } + }); +} +} // namespace lldb_private |
