[libc] Switch to using the generic `<gpuintrin.h>` implementations (#121810)
[llvm-project.git] / lldb / source / DataFormatters / FormatterSection.cpp
blob1de633f4998e056c0db0065b5009504c387b554b
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-exception
6 //
7 //===----------------------------------------------------------------------===//
9 #include "FormatterBytecode.h"
10 #include "lldb/Core/Module.h"
11 #include "lldb/DataFormatters/DataVisualization.h"
12 #include "lldb/Utility/LLDBLog.h"
14 using namespace lldb;
16 namespace lldb_private {
17 static 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;
24 auto section_sp = sections->FindSectionByType(section_type, true);
25 if (!section_sp)
26 return;
28 TypeCategoryImplSP category;
29 DataVisualization::Categories::GetCategory(ConstString("default"), category);
31 // The type summary record is serialized as follows.
33 // Each record contains, in order:
34 // * Version number of the record format
35 // * The remaining size of the record
36 // * The size of the type identifier
37 // * The type identifier, either a type name, or a regex
38 // * The size of the entry
39 // * The entry
41 // Integers are encoded using ULEB.
43 // Strings are encoded with first a length (ULEB), then the string contents,
44 // and lastly a null terminator. The length includes the null.
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;
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 else
74 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());
83 section.skip(cursor, record_size);
85 if (!cursor)
86 LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(), "{0}");
89 void 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.
98 // * The size of the summary string
99 // * The summary string
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;
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;
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());
131 void 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 bytecode
138 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;
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 } else
164 LLDB_LOG(GetLog(LLDBLog::DataFormatters),
165 "Unsupported formatter signature {0} for '{1}' in {2}",
166 signature, type_name, module_sp->GetFileSpec());
170 } // namespace lldb_private