Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/lldb/source/DataFormatters/FormatterSection.cpp
213764 views
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
//===----------------------------------------------------------------------===//
8
9
#include "FormatterBytecode.h"
10
#include "lldb/Core/Module.h"
11
#include "lldb/DataFormatters/DataVisualization.h"
12
#include "lldb/Utility/LLDBLog.h"
13
14
using namespace lldb;
15
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;
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 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
40
//
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
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());
82
}
83
section.skip(cursor, record_size);
84
}
85
if (!cursor)
86
LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters), cursor.takeError(), "{0}");
87
}
88
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.
97
//
98
// * The size of the summary string
99
// * The summary string
100
//
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
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;
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
} else
164
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_private
171
172