LLDB mainline
FormatterSection.cpp
Go to the documentation of this file.
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"
13
14using namespace lldb;
15
16namespace lldb_private {
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;
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
75 "{0}");
76 } else {
77 // Skip unsupported record.
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
92 [&](llvm::DataExtractor extractor, llvm::StringRef type_name) {
93 TypeCategoryImplSP category;
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()) {
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 }
119 auto summary_sp = std::make_shared<StringSummaryFormat>(
120 flags, summary_string.str().c_str());
122 if (type_name.front() == '^')
123 match_type = eFormatterMatchRegex;
124 category->AddTypeSummary(type_name, match_type, summary_sp);
126 "Loaded embedded type summary for '{0}' from {1}.", type_name,
127 module_sp->GetFileSpec());
128 });
129}
130
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;
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>(
155 llvm::MemoryBuffer::getMemBufferCopy(bytecode));
157 if (type_name.front() == '^')
158 match_type = eFormatterMatchRegex;
159 category->AddTypeSummary(type_name, match_type, summary_sp);
161 "Loaded embedded type summary for '{0}' from {1}.",
162 type_name, module_sp->GetFileSpec());
163 } else
165 "Unsupported formatter signature {0} for '{1}' in {2}",
166 signature, type_name, module_sp->GetFileSpec());
167 }
168 });
169}
170} // namespace lldb_private
static llvm::raw_ostream & error(Stream &strm)
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition: Log.h:369
#define LLDB_LOG_ERROR(log, error,...)
Definition: Log.h:392
A uniqued constant string class.
Definition: ConstString.h:40
An data extractor class.
Definition: DataExtractor.h:48
llvm::DataExtractor GetAsLLVM() const
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.
Definition: Module.h:89
virtual SectionList * GetSectionList()
Get the unified section list for the module.
Definition: Module.cpp:1241
const FileSpec & GetFileSpec() const
Get const accessor for the module file specification.
Definition: Module.h:453
lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx=0) const
Definition: Section.cpp:598
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.
Definition: Log.h:332
static void ForEachFormatterInModule(Module &module, SectionType section_type, std::function< void(llvm::DataExtractor, llvm::StringRef)> fn)
void LoadTypeSummariesForModule(lldb::ModuleSP module_sp)
Load type summaries embedded in the binary.
void LoadFormattersForModule(lldb::ModuleSP module_sp)
Load data formatters embedded in the binary.
Definition: SBAddress.h:15
FormatterMatchType
Type of match to be performed when looking for a formatter for a data type.
@ eFormatterMatchExact
@ eFormatterMatchRegex
std::shared_ptr< lldb_private::TypeCategoryImpl > TypeCategoryImplSP
Definition: lldb-forward.h:463
@ eSectionTypeLLDBFormatters
@ eSectionTypeLLDBTypeSummaries
std::shared_ptr< lldb_private::Module > ModuleSP
Definition: lldb-forward.h:373