16#include "llvm/Support/MemoryBuffer.h"
24 llvm::DataExtractor::Cursor &cursor) {
25 while (!section.eof(cursor)) {
26 if (section.getU8(cursor) == 0)
29 cursor.seek(cursor.tell() - 1);
38 std::function<
void(llvm::DataExtractor, llvm::StringRef, uint32_t)> fn) {
39 auto *sections =
module.GetSectionList();
43 auto section_sp = sections->FindSectionByType(section_type,
true);
69 auto section_size = section_sp->GetSectionData(lldb_extractor);
70 llvm::DataExtractor section = lldb_extractor.
GetAsLLVM();
71 bool le = section.isLittleEndian();
72 llvm::DataExtractor::Cursor cursor(0);
73 while (cursor && cursor.tell() < section_size) {
77 uint64_t version = section.getULEB128(cursor);
78 uint64_t record_size = section.getULEB128(cursor);
79 if (cursor && record_size > section_size - cursor.tell()) {
81 "Record size {0} exceeds the remaining size of the embedded "
82 "formatter section in {1}; ignoring the rest of the section.",
86 if (version == 1 || version == 2) {
87 llvm::DataExtractor record(
88 section.getData().drop_front(cursor.tell()).take_front(record_size),
90 llvm::DataExtractor::Cursor cursor(0);
91 uint64_t type_size = record.getULEB128(cursor);
92 llvm::StringRef type_name = record.getBytes(cursor, type_size);
93 llvm::Error
error = cursor.takeError();
95 fn(llvm::DataExtractor(record.getData().drop_front(cursor.tell()), le),
104 "Skipping unsupported embedded type summary of version {0} in {1}.",
107 section.skip(cursor, record_size);
116 [&](llvm::DataExtractor extractor, llvm::StringRef type_name,
127 llvm::DataExtractor::Cursor cursor(0);
128 uint64_t summary_size = extractor.getULEB128(cursor);
129 llvm::StringRef summary_string =
130 extractor.getBytes(cursor, summary_size);
136 if (type_name.empty() || summary_string.empty()) {
138 "Missing string(s) in embedded type summary in {0}, "
139 "type_name={1}, summary={2}",
140 module_sp->GetFileSpec(), type_name, summary_string);
144 auto summary_sp = std::make_shared<StringSummaryFormat>(
145 flags, summary_string.str().c_str());
147 if (type_name.front() ==
'^')
149 category->AddTypeSummary(type_name, match_type, summary_sp);
151 "Loaded embedded type summary for '{0}' from {1}.", type_name,
152 module_sp->GetFileSpec());
156static BytecodeSyntheticChildren::SyntheticBytecodeImplementation
158 llvm::MutableArrayRef<std::unique_ptr<llvm::MemoryBuffer>> methods,
163 impl.
init = std::move(methods[Signatures::sig_init]);
164 impl.
update = std::move(methods[Signatures::sig_update]);
165 impl.
num_children = std::move(methods[Signatures::sig_get_num_children]);
167 std::move(methods[Signatures::sig_get_child_at_index]);
168 impl.
get_child_index = std::move(methods[Signatures::sig_get_child_index]);
175 [&](llvm::DataExtractor extractor, llvm::StringRef type_name,
184 llvm::DataExtractor::Cursor cursor(0);
185 uint64_t flags = extractor.getULEB128(cursor);
187 std::unique_ptr<llvm::MemoryBuffer> summary_func_up;
190 bool has_synthetic_method =
false;
192 while (cursor && cursor.tell() < extractor.size()) {
193 auto signature =
static_cast<Signatures
>(extractor.getU8(cursor));
194 uint64_t size = extractor.getULEB128(cursor);
195 llvm::StringRef bytecode = extractor.getBytes(cursor, size);
198 auto buffer_up = llvm::MemoryBuffer::getMemBufferCopy(bytecode);
199 if (signature == Signatures::sig_summary)
200 summary_func_up = std::move(buffer_up);
201 else if (signature <= Signatures::sig_update) {
202 synthetic_methods[signature] = std::move(buffer_up);
203 has_synthetic_method =
true;
206 "Unsupported formatter signature {0} for '{1}' in {2}",
207 signature, type_name, module_sp->GetFileSpec());
216 if (type_name.front() ==
'^')
219 if (summary_func_up) {
220 auto summary_sp = std::make_shared<BytecodeSummaryFormat>(
223 category->AddTypeSummary(type_name, match_type, summary_sp);
225 "Loaded embedded type summary for '{0}' from {1}.",
226 type_name, module_sp->GetFileSpec());
227 }
else if (has_synthetic_method) {
230 auto synthetic_children_sp =
231 std::make_shared<BytecodeSyntheticChildren>(std::move(impl));
232 category->AddTypeSynthetic(type_name, match_type,
233 synthetic_children_sp);
235 "Loaded embedded type synthetic for '{0}' from {1}.",
236 type_name, module_sp->GetFileSpec());
239 "No summary or synthetic methods found for '{0}' in {1}, "
240 "not registering a formatter.",
241 type_name, module_sp->GetFileSpec());
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
#define LLDB_LOG_ERROR(log, error,...)
#define LLDB_LOG_VERBOSE(log,...)
A uniqued constant string class.
static bool GetCategory(ConstString category, lldb::TypeCategoryImplSP &entry, bool allow_create=true)
A class that describes an executable image and its associated object and symbol files.
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
A class that represents a running process on the host machine.
Log * GetLog(Cat mask)
Retrieve the Log object for the channel associated with the given log enum.
static bool skipPadding(llvm::DataExtractor §ion, llvm::DataExtractor::Cursor &cursor)
void LoadTypeSummariesForModule(lldb::ModuleSP module_sp)
Load type summaries embedded in the binary.
static BytecodeSyntheticChildren::SyntheticBytecodeImplementation CreateSyntheticImpl(llvm::MutableArrayRef< std::unique_ptr< llvm::MemoryBuffer > > methods, uint32_t version)
static void ForEachFormatterInModule(Module &module, SectionType section_type, std::function< void(llvm::DataExtractor, llvm::StringRef, uint32_t)> fn)
void LoadFormattersForModule(lldb::ModuleSP module_sp)
Load data formatters embedded in the binary.
FormatterMatchType
Type of match to be performed when looking for a formatter for a data type.
std::shared_ptr< lldb_private::TypeCategoryImpl > TypeCategoryImplSP
@ eSectionTypeLLDBFormatters
@ eSectionTypeLLDBTypeSummaries
std::shared_ptr< lldb_private::Module > ModuleSP
std::unique_ptr< llvm::MemoryBuffer > update
uint32_t version
The version of this record. Specs are found in formatterbytecode.md.
std::unique_ptr< llvm::MemoryBuffer > get_child_index
std::unique_ptr< llvm::MemoryBuffer > init
std::unique_ptr< llvm::MemoryBuffer > num_children
std::unique_ptr< llvm::MemoryBuffer > get_child_at_index