LLDB mainline
SymbolFileCTF.cpp
Go to the documentation of this file.
1//===-- SymbolFileCTF.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 "SymbolFileCTF.h"
10
11#include "lldb/Core/Module.h"
13#include "lldb/Host/Config.h"
17#include "lldb/Symbol/Symbol.h"
19#include "lldb/Symbol/Symtab.h"
21#include "lldb/Symbol/TypeMap.h"
26#include "lldb/Utility/Log.h"
30#include "lldb/Utility/Timer.h"
31#include "llvm/Config/llvm-config.h" // for LLVM_ENABLE_ZLIB
32#include "llvm/Support/ErrorExtras.h"
33#include "llvm/Support/MemoryBuffer.h"
34
37
38#include <memory>
39#include <optional>
40
41#if LLVM_ENABLE_ZLIB
42#include <zlib.h>
43#endif
44
45using namespace llvm;
46using namespace lldb;
47using namespace lldb_private;
48
50
52
54 : SymbolFileCommon(std::move(objfile_sp)) {}
55
60
64
66 return "Compact C Type Format Symbol Reader";
67}
68
70 return new SymbolFileCTF(std::move(objfile_sp));
71}
72
74 if (m_header)
75 return true;
76
78
79 ModuleSP module_sp(m_objfile_sp->GetModule());
80 const SectionList *section_list = module_sp->GetSectionList();
81 if (!section_list)
82 return false;
83
84 SectionSP section_sp(
85 section_list->FindSectionByType(lldb::eSectionTypeCTF, true));
86 if (!section_sp)
87 return false;
88
89 m_objfile_sp->ReadSectionData(section_sp.get(), m_data);
90
91 if (m_data.GetByteSize() == 0)
92 return false;
93
94 StreamString module_desc;
95 GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),
97 LLDB_LOG(log, "Parsing Compact C Type format for {0}", module_desc.GetData());
98
99 lldb::offset_t offset = 0;
100
101 // Parse CTF header.
102 constexpr size_t ctf_header_size = sizeof(ctf_header_t);
103 if (!m_data.ValidOffsetForDataOfSize(offset, ctf_header_size)) {
104 LLDB_LOG(log, "CTF parsing failed: insufficient data for CTF header");
105 return false;
106 }
107
108 m_header.emplace();
109
110 ctf_header_t &ctf_header = *m_header;
111 ctf_header.preamble.magic = m_data.GetU16(&offset);
112 ctf_header.preamble.version = m_data.GetU8(&offset);
113 ctf_header.preamble.flags = m_data.GetU8(&offset);
114 ctf_header.parlabel = m_data.GetU32(&offset);
115 ctf_header.parname = m_data.GetU32(&offset);
116 ctf_header.lbloff = m_data.GetU32(&offset);
117 ctf_header.objtoff = m_data.GetU32(&offset);
118 ctf_header.funcoff = m_data.GetU32(&offset);
119 ctf_header.typeoff = m_data.GetU32(&offset);
120 ctf_header.stroff = m_data.GetU32(&offset);
121 ctf_header.strlen = m_data.GetU32(&offset);
122
123 // Validate the preamble.
124 if (ctf_header.preamble.magic != g_ctf_magic) {
125 LLDB_LOG(log, "CTF parsing failed: invalid magic: {0:x}",
126 ctf_header.preamble.magic);
127 return false;
128 }
129
130 if (ctf_header.preamble.version != g_ctf_version) {
131 LLDB_LOG(log, "CTF parsing failed: unsupported version: {0}",
132 ctf_header.preamble.version);
133 return false;
134 }
135
136 LLDB_LOG(log, "Parsed valid CTF preamble: version {0}, flags {1:x}",
137 ctf_header.preamble.version, ctf_header.preamble.flags);
138
139 m_body_offset = offset;
140
141 if (ctf_header.preamble.flags & eFlagCompress) {
142 // The body has been compressed with zlib deflate. Header offsets point into
143 // the decompressed data.
144#if LLVM_ENABLE_ZLIB
145 const std::size_t decompressed_size = ctf_header.stroff + ctf_header.strlen;
146 DataBufferSP decompressed_data =
147 std::make_shared<DataBufferHeap>(decompressed_size, 0x0);
148
149 z_stream zstr;
150 memset(&zstr, 0, sizeof(zstr));
151 zstr.next_in = (Bytef *)const_cast<uint8_t *>(m_data.GetDataStart() +
152 sizeof(ctf_header_t));
153 zstr.avail_in = m_data.BytesLeft(offset);
154 zstr.next_out =
155 (Bytef *)const_cast<uint8_t *>(decompressed_data->GetBytes());
156 zstr.avail_out = decompressed_size;
157
158 int rc = inflateInit(&zstr);
159 if (rc != Z_OK) {
160 LLDB_LOG(log, "CTF parsing failed: inflate initialization error: {0}",
161 zError(rc));
162 return false;
163 }
164
165 rc = inflate(&zstr, Z_FINISH);
166 if (rc != Z_STREAM_END) {
167 LLDB_LOG(log, "CTF parsing failed: inflate error: {0}", zError(rc));
168 return false;
169 }
170
171 rc = inflateEnd(&zstr);
172 if (rc != Z_OK) {
173 LLDB_LOG(log, "CTF parsing failed: inflate end error: {0}", zError(rc));
174 return false;
175 }
176
177 if (zstr.total_out != decompressed_size) {
178 LLDB_LOG(log,
179 "CTF parsing failed: decompressed size ({}) doesn't match "
180 "expected size ({})",
181 zstr.total_out, decompressed_size);
182 return false;
183 }
184
185 m_data = DataExtractor(decompressed_data, m_data.GetByteOrder(),
186 m_data.GetAddressByteSize());
187 m_body_offset = 0;
188#else
189 LLDB_LOG(
190 log,
191 "CTF parsing failed: data is compressed but no zlib inflate support");
192 return false;
193#endif
194 }
195
196 // Validate the header.
197 if (!m_data.ValidOffset(m_body_offset + ctf_header.lbloff)) {
198 LLDB_LOG(log,
199 "CTF parsing failed: invalid label section offset in header: {0}",
200 ctf_header.lbloff);
201 return false;
202 }
203
204 if (!m_data.ValidOffset(m_body_offset + ctf_header.objtoff)) {
205 LLDB_LOG(log,
206 "CTF parsing failed: invalid object section offset in header: {0}",
207 ctf_header.objtoff);
208 return false;
209 }
210
211 if (!m_data.ValidOffset(m_body_offset + ctf_header.funcoff)) {
212 LLDB_LOG(
213 log,
214 "CTF parsing failed: invalid function section offset in header: {0}",
215 ctf_header.funcoff);
216 return false;
217 }
218
219 if (!m_data.ValidOffset(m_body_offset + ctf_header.typeoff)) {
220 LLDB_LOG(log,
221 "CTF parsing failed: invalid type section offset in header: {0}",
222 ctf_header.typeoff);
223 return false;
224 }
225
226 if (!m_data.ValidOffset(m_body_offset + ctf_header.stroff)) {
227 LLDB_LOG(log,
228 "CTF parsing failed: invalid string section offset in header: {0}",
229 ctf_header.stroff);
230 return false;
231 }
232
233 const lldb::offset_t str_end_offset =
234 m_body_offset + ctf_header.stroff + ctf_header.strlen;
235 if (!m_data.ValidOffset(str_end_offset - 1)) {
236 LLDB_LOG(log,
237 "CTF parsing failed: invalid string section length in header: {0}",
238 ctf_header.strlen);
239 return false;
240 }
241
242 if (m_body_offset + ctf_header.stroff + ctf_header.parlabel >
243 str_end_offset) {
244 LLDB_LOG(log,
245 "CTF parsing failed: invalid parent label offset: {0} exceeds end "
246 "of string section ({1})",
247 ctf_header.parlabel, str_end_offset);
248 return false;
249 }
250
251 if (m_body_offset + ctf_header.stroff + ctf_header.parname > str_end_offset) {
252 LLDB_LOG(log,
253 "CTF parsing failed: invalid parent name offset: {0} exceeds end "
254 "of string section ({1})",
255 ctf_header.parname, str_end_offset);
256 return false;
257 }
258
259 LLDB_LOG(log,
260 "Parsed valid CTF header: lbloff = {0}, objtoff = {1}, funcoff = "
261 "{2}, typeoff = {3}, stroff = {4}, strlen = {5}",
262 ctf_header.lbloff, ctf_header.objtoff, ctf_header.funcoff,
263 ctf_header.typeoff, ctf_header.stroff, ctf_header.strlen);
264
265 return true;
266}
267
270
271 auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC);
272 if (auto err = type_system_or_err.takeError()) {
273 LLDB_LOG_ERROR(log, std::move(err), "Unable to get type system: {0}");
274 return;
275 }
276
277 auto ts = *type_system_or_err;
278 m_ast = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
279 LazyBool optimized = eLazyBoolNo;
280 m_comp_unit_sp = std::make_shared<CompileUnit>(
281 m_objfile_sp->GetModule(), nullptr, "", 0, eLanguageTypeC, optimized);
282
284}
285
286llvm::StringRef SymbolFileCTF::ReadString(lldb::offset_t str_offset) const {
287 lldb::offset_t offset = m_body_offset + m_header->stroff + str_offset;
288 if (!m_data.ValidOffset(offset))
289 return "(invalid)";
290 const char *str = m_data.GetCStr(&offset);
291 if (str && !*str)
292 return "(anon)";
293 return llvm::StringRef(str);
294}
295
296/// Return the integer display representation encoded in the given data.
297static uint32_t GetEncoding(uint32_t data) {
298 // Mask bits 24–31.
299 return ((data)&0xff000000) >> 24;
300}
301
302/// Return the integral width in bits encoded in the given data.
303static uint32_t GetBits(uint32_t data) {
304 // Mask bits 0-15.
305 return (data)&0x0000ffff;
306}
307
308/// Return the type kind encoded in the given data.
309uint32_t GetKind(uint32_t data) {
310 // Mask bits 26–31.
311 return ((data)&0xf800) >> 11;
312}
313
314/// Return the variable length encoded in the given data.
315uint32_t GetVLen(uint32_t data) {
316 // Mask bits 0–24.
317 return (data)&0x3ff;
318}
319
320static uint32_t GetBytes(uint32_t bits) { return bits / sizeof(unsigned); }
321
322static clang::TagTypeKind TranslateRecordKind(CTFType::Kind type) {
323 switch (type) {
325 return clang::TagTypeKind::Struct;
327 return clang::TagTypeKind::Union;
328 default:
329 lldbassert(false && "Invalid record kind!");
330 return clang::TagTypeKind::Struct;
331 }
332}
333
334llvm::Expected<TypeSP>
336 lldb::BasicType basic_type =
338 if (basic_type == eBasicTypeInvalid)
339 return llvm::createStringErrorV(
340 "unsupported integer type: no corresponding basic clang "
341 "type for '{0}'",
342 ctf_integer.name);
343
344 CompilerType compiler_type = m_ast->GetBasicType(basic_type);
345
346 if (basic_type != eBasicTypeVoid && basic_type != eBasicTypeBool) {
347 // Make sure the type we got is an integer type.
348 bool compiler_type_is_signed = false;
349 if (!compiler_type.IsIntegerType(compiler_type_is_signed))
350 return llvm::createStringErrorV(
351 "Found compiler type for '{0}' but it's not an integer type: {1}",
352 ctf_integer.name, compiler_type.GetDisplayTypeName().GetStringRef());
353
354 // Make sure the signing matches between the CTF and the compiler type.
355 const bool type_is_signed = (ctf_integer.encoding & IntEncoding::eSigned);
356 if (compiler_type_is_signed != type_is_signed)
357 return llvm::createStringErrorV(
358 "Found integer compiler type for {0} but compiler type is {1} and "
359 "{0} is {2}",
360 ctf_integer.name, compiler_type_is_signed ? "signed" : "unsigned",
361 type_is_signed ? "signed" : "unsigned");
362 }
363
364 Declaration decl;
365 return MakeType(ctf_integer.uid, ConstString(ctf_integer.name),
366 GetBytes(ctf_integer.bits), nullptr, LLDB_INVALID_UID,
367 lldb_private::Type::eEncodingIsUID, decl, compiler_type,
369}
370
371llvm::Expected<lldb::TypeSP>
373 Type *ref_type = ResolveTypeUID(ctf_modifier.type);
374 if (!ref_type)
375 return llvm::createStringErrorV("could not find modified type: {0}",
376 ctf_modifier.type);
377
378 CompilerType compiler_type;
379
380 switch (ctf_modifier.kind) {
382 compiler_type = ref_type->GetFullCompilerType().GetPointerType();
383 break;
384 case CTFType::eConst:
385 compiler_type = ref_type->GetFullCompilerType().AddConstModifier();
386 break;
388 compiler_type = ref_type->GetFullCompilerType().AddVolatileModifier();
389 break;
391 compiler_type = ref_type->GetFullCompilerType().AddRestrictModifier();
392 break;
393 default:
394 return llvm::createStringErrorV(
395 "ParseModifier called with unsupported kind: {0}", ctf_modifier.kind);
396 }
397
398 Declaration decl;
399 return MakeType(ctf_modifier.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
400 Type::eEncodingIsUID, decl, compiler_type,
402}
403
404llvm::Expected<lldb::TypeSP>
406 Type *underlying_type = ResolveTypeUID(ctf_typedef.type);
407 if (!underlying_type)
408 return llvm::createStringErrorV(
409 "could not find typedef underlying type: {0}", ctf_typedef.type);
410
411 CompilerType target_ast_type = underlying_type->GetFullCompilerType();
412 clang::DeclContext *decl_ctx = m_ast->GetTranslationUnitDecl();
413 CompilerType ast_typedef = target_ast_type.CreateTypedef(
414 ctf_typedef.name.data(), m_ast->CreateDeclContext(decl_ctx), 0);
415
416 Declaration decl;
417 return MakeType(ctf_typedef.uid, ConstString(ctf_typedef.name), 0, nullptr,
420}
421
422llvm::Expected<lldb::TypeSP>
424 Type *element_type = ResolveTypeUID(ctf_array.type);
425 if (!element_type)
426 return llvm::createStringErrorV("could not find array element type: {0}",
427 ctf_array.type);
428
429 auto element_size_or_err = element_type->GetByteSize(nullptr);
430 if (!element_size_or_err)
431 return element_size_or_err.takeError();
432
433 uint64_t size = ctf_array.nelems * *element_size_or_err;
434
435 CompilerType compiler_type = m_ast->CreateArrayType(
436 element_type->GetFullCompilerType(), ctf_array.nelems,
437 /*is_gnu_vector*/ false);
438
439 Declaration decl;
440 return MakeType(ctf_array.uid, ConstString(), size, nullptr, LLDB_INVALID_UID,
441 Type::eEncodingIsUID, decl, compiler_type,
443}
444
445llvm::Expected<lldb::TypeSP>
447 Declaration decl;
448 CompilerType enum_type = m_ast->CreateEnumerationType(
449 ctf_enum.name, m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(),
450 decl, m_ast->GetBasicType(eBasicTypeInt),
451 /*is_scoped=*/false);
452
453 for (const CTFEnum::Value &value : ctf_enum.values) {
454 Declaration value_decl;
455 m_ast->AddEnumerationValueToEnumerationType(
456 enum_type, value_decl, value.name.data(), value.value, ctf_enum.size);
457 }
459
460 return MakeType(ctf_enum.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
461 Type::eEncodingIsUID, decl, enum_type,
463}
464
465llvm::Expected<lldb::TypeSP>
467 std::vector<CompilerType> arg_types;
468 for (uint32_t arg : ctf_function.args) {
469 if (Type *arg_type = ResolveTypeUID(arg))
470 arg_types.push_back(arg_type->GetFullCompilerType());
471 }
472
473 Type *ret_type = ResolveTypeUID(ctf_function.return_type);
474 if (!ret_type)
475 return llvm::createStringErrorV("could not find function return type: {0}",
476 ctf_function.return_type);
477
478 CompilerType func_type = m_ast->CreateFunctionType(
479 ret_type->GetFullCompilerType(), arg_types, ctf_function.variadic, 0,
480 clang::CallingConv::CC_C);
481
482 Declaration decl;
483 return MakeType(ctf_function.uid, ConstString(ctf_function.name), 0, nullptr,
484 LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
486}
487
488llvm::Expected<lldb::TypeSP>
490 const clang::TagTypeKind tag_kind = TranslateRecordKind(ctf_record.kind);
491 CompilerType record_type = m_ast->CreateRecordType(
492 nullptr, OptionalClangModuleID(), ctf_record.name.data(),
493 llvm::to_underlying(tag_kind), eLanguageTypeC);
494 m_compiler_types[record_type.GetOpaqueQualType()] = &ctf_record;
495 Declaration decl;
496 return MakeType(ctf_record.uid, ConstString(ctf_record.name), ctf_record.size,
499}
500
502 // Check if we have a CTF type for the given incomplete compiler type.
503 auto it = m_compiler_types.find(compiler_type.GetOpaqueQualType());
504 if (it == m_compiler_types.end())
505 return false;
506
507 const CTFType *ctf_type = it->second;
508 assert(ctf_type && "m_compiler_types should only contain valid CTF types");
509
510 // We only support resolving record types.
511 assert(llvm::isa<CTFRecord>(ctf_type));
512
513 // Cast to the appropriate CTF type.
514 const CTFRecord *ctf_record = static_cast<const CTFRecord *>(ctf_type);
515
516 // If any of the fields are incomplete, we cannot complete the type.
517 for (const CTFRecord::Field &field : ctf_record->fields) {
518 if (!ResolveTypeUID(field.type)) {
520 "Cannot complete type {0} because field {1} is incomplete",
521 ctf_type->uid, field.type);
522 return false;
523 }
524 }
525
526 // Complete the record type.
527 m_ast->StartTagDeclarationDefinition(compiler_type);
528 for (const CTFRecord::Field &field : ctf_record->fields) {
529 Type *field_type = ResolveTypeUID(field.type);
530 assert(field_type && "field must be complete");
531 const uint32_t field_size =
532 llvm::expectedToOptional(field_type->GetByteSize(nullptr)).value_or(0);
533 TypeSystemClang::AddFieldToRecordType(compiler_type, field.name,
534 field_type->GetFullCompilerType(),
535 field_size);
536 }
537 m_ast->CompleteTagDeclarationDefinition(compiler_type);
538
539 // Now that the compiler type is complete, we don't need to remember it
540 // anymore and can remove the CTF record type.
541 m_compiler_types.erase(compiler_type.GetOpaqueQualType());
542 m_ctf_types.erase(ctf_type->uid);
543
544 return true;
545}
546
547llvm::Expected<lldb::TypeSP>
549 CompilerType forward_compiler_type = m_ast->CreateRecordType(
550 nullptr, OptionalClangModuleID(), ctf_forward.name,
551 llvm::to_underlying(clang::TagTypeKind::Struct), eLanguageTypeC);
552 Declaration decl;
553 return MakeType(ctf_forward.uid, ConstString(ctf_forward.name), 0, nullptr,
555 forward_compiler_type, Type::ResolveState::Forward);
556}
557
558llvm::Expected<TypeSP> SymbolFileCTF::CreateType(CTFType *ctf_type) {
559 if (!ctf_type)
560 return llvm::createStringError("cannot create type for unparsed type");
561
562 switch (ctf_type->kind) {
564 return CreateInteger(*static_cast<CTFInteger *>(ctf_type));
569 return CreateModifier(*static_cast<CTFModifier *>(ctf_type));
571 return CreateTypedef(*static_cast<CTFTypedef *>(ctf_type));
573 return CreateArray(*static_cast<CTFArray *>(ctf_type));
575 return CreateEnum(*static_cast<CTFEnum *>(ctf_type));
577 return CreateFunction(*static_cast<CTFFunction *>(ctf_type));
580 return CreateRecord(*static_cast<CTFRecord *>(ctf_type));
582 return CreateForward(*static_cast<CTFForward *>(ctf_type));
586 return llvm::createStringErrorV(
587 "unsupported type (uid = {0}, name = {1}, kind = {2})", ctf_type->uid,
588 ctf_type->name, ctf_type->kind);
589 }
590 llvm_unreachable("Unexpected CTF type kind");
591}
592
593llvm::Expected<std::unique_ptr<CTFType>>
595 ctf_stype_t ctf_stype;
596 ctf_stype.name = m_data.GetU32(&offset);
597 ctf_stype.info = m_data.GetU32(&offset);
598 ctf_stype.size = m_data.GetU32(&offset);
599
600 llvm::StringRef name = ReadString(ctf_stype.name);
601 const uint32_t kind = GetKind(ctf_stype.info);
602 const uint32_t variable_length = GetVLen(ctf_stype.info);
603 const uint32_t type = ctf_stype.GetType();
604 const uint32_t size = ctf_stype.GetSize();
605
606 switch (kind) {
607 case TypeKind::eInteger: {
608 const uint32_t vdata = m_data.GetU32(&offset);
609 const uint32_t bits = GetBits(vdata);
610 const uint32_t encoding = GetEncoding(vdata);
611 return std::make_unique<CTFInteger>(uid, name, bits, encoding);
612 }
613 case TypeKind::eConst:
614 return std::make_unique<CTFConst>(uid, type);
616 return std::make_unique<CTFPointer>(uid, type);
618 return std::make_unique<CTFRestrict>(uid, type);
620 return std::make_unique<CTFVolatile>(uid, type);
622 return std::make_unique<CTFTypedef>(uid, name, type);
623 case TypeKind::eArray: {
624 const uint32_t type = m_data.GetU32(&offset);
625 const uint32_t index = m_data.GetU32(&offset);
626 const uint32_t nelems = m_data.GetU32(&offset);
627 return std::make_unique<CTFArray>(uid, name, type, index, nelems);
628 }
629 case TypeKind::eEnum: {
630 std::vector<CTFEnum::Value> values;
631 for (uint32_t i = 0; i < variable_length; ++i) {
632 const uint32_t value_name = m_data.GetU32(&offset);
633 const uint32_t value = m_data.GetU32(&offset);
634 values.emplace_back(ReadString(value_name), value);
635 }
636 return std::make_unique<CTFEnum>(uid, name, variable_length, size, values);
637 }
638 case TypeKind::eFunction: {
639 std::vector<uint32_t> args;
640 bool variadic = false;
641 for (uint32_t i = 0; i < variable_length; ++i) {
642 const uint32_t arg_uid = m_data.GetU32(&offset);
643 // If the last argument is 0, this is a variadic function.
644 if (arg_uid == 0) {
645 variadic = true;
646 break;
647 }
648 args.push_back(arg_uid);
649 }
650 // If the number of arguments is odd, a single uint32_t of padding is
651 // inserted to maintain alignment.
652 if (variable_length % 2 == 1)
653 m_data.GetU32(&offset);
654 return std::make_unique<CTFFunction>(uid, name, variable_length, type, args,
655 variadic);
656 }
658 case TypeKind::eUnion: {
659 std::vector<CTFRecord::Field> fields;
660 for (uint32_t i = 0; i < variable_length; ++i) {
661 const uint32_t field_name = m_data.GetU32(&offset);
662 const uint32_t type = m_data.GetU32(&offset);
663 uint64_t field_offset = 0;
664 if (size < g_ctf_field_threshold) {
665 field_offset = m_data.GetU16(&offset);
666 m_data.GetU16(&offset); // Padding
667 } else {
668 const uint32_t offset_hi = m_data.GetU32(&offset);
669 const uint32_t offset_lo = m_data.GetU32(&offset);
670 field_offset = (((uint64_t)offset_hi) << 32) | ((uint64_t)offset_lo);
671 }
672 fields.emplace_back(ReadString(field_name), type, field_offset);
673 }
674 return std::make_unique<CTFRecord>(static_cast<CTFType::Kind>(kind), uid,
675 name, variable_length, size, fields);
676 }
678 return std::make_unique<CTFForward>(uid, name);
680 return std::make_unique<CTFType>(static_cast<CTFType::Kind>(kind), uid,
681 name);
682 case TypeKind::eFloat:
683 case TypeKind::eSlice:
684 offset += (variable_length * sizeof(uint32_t));
685 break;
686 }
687
688 return llvm::createStringErrorV(
689 "unsupported type (name = {0}, kind = {1}, vlength = {2})", name, kind,
690 variable_length);
691}
692
694 if (!ParseHeader())
695 return 0;
696
697 if (!m_types.empty())
698 return 0;
699
700 if (!m_ast)
701 return 0;
702
704 LLDB_LOG(log, "Parsing CTF types");
705
706 lldb::offset_t type_offset = m_body_offset + m_header->typeoff;
707 const lldb::offset_t type_offset_end = m_body_offset + m_header->stroff;
708
709 lldb::user_id_t type_uid = 1;
710 while (type_offset < type_offset_end) {
711 llvm::Expected<std::unique_ptr<CTFType>> type_or_error =
712 ParseType(type_offset, type_uid);
713 if (type_or_error) {
714 m_ctf_types[(*type_or_error)->uid] = std::move(*type_or_error);
715 } else {
716 LLDB_LOG_ERROR(log, type_or_error.takeError(),
717 "Failed to parse type {1} at offset {2}: {0}", type_uid,
718 type_offset);
719 }
720 type_uid++;
721 }
722
723 LLDB_LOG(log, "Parsed {0} CTF types", m_ctf_types.size());
724
725 for (lldb::user_id_t uid = 1; uid < type_uid; ++uid) {
726 ResolveTypeUID(uid);
727
728 // Remove the CTF type because we don't need it anymore, except for record
729 // types which we may need to complete later.
730 auto ctf_type_it = m_ctf_types.find(uid);
731 if (ctf_type_it != m_ctf_types.end()) {
732 CTFType *ctf_type = ctf_type_it->second.get();
733 if (!llvm::isa<CTFRecord>(ctf_type))
734 m_ctf_types.erase(uid);
735 }
736 }
737
738#ifndef NDEBUG
739 // Verify that the only CTF types left at this point are record types.
740 for (auto &t : m_ctf_types) {
741 CTFType *ctf_type = t.second.get();
742 assert(ctf_type && "invalid type in m_ctf_types");
743 assert(llvm::isa<CTFRecord>(ctf_type) && "leaking non record type");
744 }
745
746#endif
747
748 LLDB_LOG(log, "Created {0} CTF types", m_types.size());
749
750 return m_types.size();
751}
752
754 if (!ParseHeader())
755 return 0;
756
757 if (!m_functions.empty())
758 return 0;
759
760 if (!m_ast)
761 return 0;
762
763 Symtab *symtab = GetObjectFile()->GetModule()->GetSymtab();
764 if (!symtab)
765 return 0;
766
768 LLDB_LOG(log, "Parsing CTF functions");
769
770 lldb::offset_t function_offset = m_body_offset + m_header->funcoff;
771 const lldb::offset_t function_offset_end = m_body_offset + m_header->typeoff;
772
773 uint32_t symbol_idx = 0;
774 Declaration decl;
775 while (function_offset < function_offset_end) {
776 const uint32_t info = m_data.GetU32(&function_offset);
777 const uint16_t kind = GetKind(info);
778 const uint16_t variable_length = GetVLen(info);
779
780 const Symbol *symbol = symtab->FindSymbolWithType(
782
783 // Skip padding.
784 if (kind == TypeKind::eUnknown && variable_length == 0)
785 continue;
786
787 // Skip unexpected kinds.
788 if (kind != TypeKind::eFunction)
789 continue;
790
791 const uint32_t ret_uid = m_data.GetU32(&function_offset);
792 const uint32_t num_args = variable_length;
793
794 std::vector<CompilerType> arg_types;
795 arg_types.reserve(num_args);
796
797 bool is_variadic = false;
798 for (uint32_t i = 0; i < variable_length; i++) {
799 const uint32_t arg_uid = m_data.GetU32(&function_offset);
800
801 // If the last argument is 0, this is a variadic function.
802 if (arg_uid == 0) {
803 is_variadic = true;
804 break;
805 }
806
807 Type *arg_type = ResolveTypeUID(arg_uid);
808 arg_types.push_back(arg_type ? arg_type->GetFullCompilerType()
809 : CompilerType());
810 }
811
812 if (symbol) {
813 Type *ret_type = ResolveTypeUID(ret_uid);
814 AddressRange func_range =
815 AddressRange(symbol->GetFileAddress(), symbol->GetByteSize(),
816 GetObjectFile()->GetModule()->GetSectionList());
817
818 // Create function type.
819 CompilerType func_type = m_ast->CreateFunctionType(
820 ret_type ? ret_type->GetFullCompilerType() : CompilerType(),
821 arg_types, is_variadic, 0, clang::CallingConv::CC_C);
822 lldb::user_id_t function_type_uid = m_types.size() + 1;
823 TypeSP type_sp =
824 MakeType(function_type_uid, symbol->GetName(), 0, nullptr,
825 LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
827 m_types[function_type_uid] = type_sp;
828
829 // Create function.
830 lldb::user_id_t func_uid = m_functions.size();
831 FunctionSP function_sp = std::make_shared<Function>(
832 &cu, func_uid, function_type_uid, symbol->GetMangled(), type_sp.get(),
833 symbol->GetAddress(), AddressRanges{func_range});
834 m_functions.emplace_back(function_sp);
835 cu.AddFunction(function_sp);
836 }
837 }
838
839 LLDB_LOG(log, "CTF parsed {0} functions", m_functions.size());
840
841 return m_functions.size();
842}
843
845 const Symbol &symbol) {
846 if (!module_sp)
847 return DWARFExpression();
848
849 const ArchSpec &architecture = module_sp->GetArchitecture();
850 ByteOrder byte_order = architecture.GetByteOrder();
851 uint32_t address_size = architecture.GetAddressByteSize();
852
853 StreamBuffer<32> stream(Stream::eBinary, byte_order);
854 stream.PutHex8(llvm::dwarf::DW_OP_addr);
855 stream.PutMaxHex64(symbol.GetFileAddress(), address_size, byte_order);
856
857 DataBufferSP buffer =
858 std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
859 lldb_private::DataExtractor extractor(buffer, byte_order, address_size);
860 DWARFExpression result(extractor);
862
863 return result;
864}
865
867 if (!ParseHeader())
868 return 0;
869
870 if (!m_variables.empty())
871 return 0;
872
873 if (!m_ast)
874 return 0;
875
876 ModuleSP module_sp = GetObjectFile()->GetModule();
877 Symtab *symtab = module_sp->GetSymtab();
878 if (!symtab)
879 return 0;
880
882 LLDB_LOG(log, "Parsing CTF objects");
883
884 lldb::offset_t object_offset = m_body_offset + m_header->objtoff;
885 const lldb::offset_t object_offset_end = m_body_offset + m_header->funcoff;
886
887 uint32_t symbol_idx = 0;
888 Declaration decl;
889 while (object_offset < object_offset_end) {
890 const uint32_t type_uid = m_data.GetU32(&object_offset);
891
892 if (const Symbol *symbol =
894 Symtab::eVisibilityAny, symbol_idx)) {
895 Variable::RangeList ranges;
896 ranges.Append(symbol->GetFileAddress(), symbol->GetByteSize());
897
898 auto type_sp = std::make_shared<SymbolFileType>(*this, type_uid);
899
900 DWARFExpressionList location(
901 module_sp, CreateDWARFExpression(module_sp, *symbol), nullptr);
902
903 lldb::user_id_t variable_type_uid = m_variables.size();
904 m_variables.emplace_back(std::make_shared<Variable>(
905 variable_type_uid, symbol->GetName().AsCString(nullptr),
906 symbol->GetName().AsCString(nullptr), type_sp,
907 eValueTypeVariableGlobal, m_comp_unit_sp.get(), ranges, &decl,
908 location, symbol->IsExternal(),
909 /*artificial=*/false,
910 /*location_is_constant_data*/ false));
911 }
912 }
913
914 LLDB_LOG(log, "Parsed {0} CTF objects", m_variables.size());
915
916 return m_variables.size();
917}
918
920 if (!m_objfile_sp)
921 return 0;
922
923 if (!ParseHeader())
924 return 0;
925
927}
928
930 SymbolContextItem resolve_scope,
931 SymbolContext &sc) {
932 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
933 if (m_objfile_sp->GetSymtab() == nullptr)
934 return 0;
935
936 uint32_t resolved_flags = 0;
937
938 // Resolve symbols.
939 if (resolve_scope & eSymbolContextSymbol) {
940 sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
941 so_addr.GetFileAddress());
942 if (sc.symbol)
943 resolved_flags |= eSymbolContextSymbol;
944 }
945
946 // Resolve functions.
947 if (resolve_scope & eSymbolContextFunction) {
948 for (FunctionSP function_sp : m_functions) {
949 if (llvm::any_of(
950 function_sp->GetAddressRanges(), [&](const AddressRange range) {
951 return range.ContainsFileAddress(so_addr.GetFileAddress());
952 })) {
953 sc.function = function_sp.get();
954 resolved_flags |= eSymbolContextFunction;
955 break;
956 }
957 }
958 }
959
960 // Resolve variables.
961 if (resolve_scope & eSymbolContextVariable) {
962 for (VariableSP variable_sp : m_variables) {
963 if (variable_sp->LocationIsValidForAddress(
964 Address(so_addr.GetFileAddress()))) {
965 sc.variable = variable_sp.get();
966 break;
967 }
968 }
969 }
970
971 return resolved_flags;
972}
973
975 if (idx == 0)
976 return m_comp_unit_sp;
977 return {};
978}
979
980size_t
984
986 // CTF does not encode symbols.
987 // We rely on the existing symbol table to map symbols to type.
988}
989
991 auto type_it = m_types.find(type_uid);
992 if (type_it != m_types.end())
993 return type_it->second.get();
994
995 auto ctf_type_it = m_ctf_types.find(type_uid);
996 if (ctf_type_it == m_ctf_types.end())
997 return nullptr;
998
999 CTFType *ctf_type = ctf_type_it->second.get();
1000 assert(ctf_type && "m_ctf_types should only contain valid CTF types");
1001 assert(ctf_type->uid == type_uid &&
1002 "CTF type UID doesn't match UID in m_ctf_types");
1003
1004 Log *log = GetLog(LLDBLog::Symbols);
1005
1006 llvm::Expected<TypeSP> type_or_error = CreateType(ctf_type);
1007 if (!type_or_error) {
1008 LLDB_LOG_ERROR(log, type_or_error.takeError(),
1009 "Failed to create type for {1}: {0}", ctf_type->uid);
1010 return {};
1011 }
1012
1013 TypeSP type_sp = *type_or_error;
1014
1015 if (log) {
1016 StreamString ss;
1017 type_sp->Dump(&ss, true);
1018 LLDB_LOG_VERBOSE(log, "Adding type {0}: {1}", type_sp->GetID(),
1019 llvm::StringRef(ss.GetString()).rtrim());
1020 }
1021
1022 m_types[type_uid] = type_sp;
1023
1024 return type_sp.get();
1025}
1026
1028 lldb_private::TypeResults &results) {
1029 // Make sure we haven't already searched this SymbolFile before.
1030 if (results.AlreadySearched(this))
1031 return;
1032
1033 ConstString name = match.GetTypeBasename();
1034 for (TypeSP type_sp : GetTypeList().Types()) {
1035 if (type_sp && type_sp->GetName() == name) {
1036 results.InsertUnique(type_sp);
1037 if (results.Done(match))
1038 return;
1039 }
1040 }
1041}
1042
1044 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1045 lldb_private::TypeMap &types) {
1047
1048 size_t matches = 0;
1049 for (TypeSP type_sp : GetTypeList().Types()) {
1050 if (matches == max_matches)
1051 break;
1052 if (type_sp && regex.Execute(type_sp->GetName()))
1053 types.Insert(type_sp);
1054 matches++;
1055 }
1056}
1057
1059 const lldb_private::Module::LookupInfo &lookup_info,
1060 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1061 bool include_inlines, lldb_private::SymbolContextList &sc_list) {
1063
1064 ConstString name = lookup_info.GetLookupName();
1065 for (FunctionSP function_sp : m_functions) {
1066 if (function_sp && function_sp->GetName() == name) {
1068 sc.comp_unit = m_comp_unit_sp.get();
1069 sc.function = function_sp.get();
1070 sc_list.Append(sc);
1071 }
1072 }
1073}
1074
1076 bool include_inlines,
1078 for (FunctionSP function_sp : m_functions) {
1079 if (function_sp && regex.Execute(function_sp->GetName())) {
1081 sc.comp_unit = m_comp_unit_sp.get();
1082 sc.function = function_sp.get();
1083 sc_list.Append(sc);
1084 }
1085 }
1086}
1087
1090 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1091 uint32_t max_matches, lldb_private::VariableList &variables) {
1093
1094 size_t matches = 0;
1095 for (VariableSP variable_sp : m_variables) {
1096 if (matches == max_matches)
1097 break;
1098 if (variable_sp && variable_sp->GetName() == name) {
1099 variables.AddVariable(variable_sp);
1100 matches++;
1101 }
1102 }
1103}
1104
1106 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1107 lldb_private::VariableList &variables) {
1109
1110 size_t matches = 0;
1111 for (VariableSP variable_sp : m_variables) {
1112 if (matches == max_matches)
1113 break;
1114 if (variable_sp && regex.Execute(variable_sp->GetName())) {
1115 variables.AddVariable(variable_sp);
1116 matches++;
1117 }
1118 }
1119}
#define lldbassert(x)
Definition LLDBAssert.h:16
#define LLDB_LOG(log,...)
The LLDB_LOG* macros defined below are the way to emit log messages.
Definition Log.h:375
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:405
#define LLDB_LOG_VERBOSE(log,...)
Definition Log.h:382
#define LLDB_PLUGIN_DEFINE(PluginName)
uint32_t GetKind(uint32_t data)
Return the type kind encoded in the given data.
static DWARFExpression CreateDWARFExpression(ModuleSP module_sp, const Symbol &symbol)
uint32_t GetVLen(uint32_t data)
Return the variable length encoded in the given data.
static clang::TagTypeKind TranslateRecordKind(CTFType::Kind type)
static uint32_t GetEncoding(uint32_t data)
Return the integer display representation encoded in the given data.
static uint32_t GetBits(uint32_t data)
Return the integral width in bits encoded in the given data.
static uint32_t GetBytes(uint32_t bits)
A section + offset based address range class.
A section + offset based address class.
Definition Address.h:62
lldb::addr_t GetFileAddress() const
Get the file address.
Definition Address.cpp:283
An architecture specification class.
Definition ArchSpec.h:32
uint32_t GetAddressByteSize() const
Returns the size in bytes of an address of the current architecture.
Definition ArchSpec.cpp:894
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:943
A class that describes a compilation unit.
Definition CompileUnit.h:43
void AddFunction(lldb::FunctionSP &function_sp)
Add a function to this compile unit.
Represents a generic declaration context in a program.
Generic representation of a type in a programming language.
CompilerType AddConstModifier() const
Return a new CompilerType adds a const modifier to this type if this type is valid and the type syste...
ConstString GetDisplayTypeName() const
CompilerType GetPointerType() const
Return a new CompilerType that is a pointer to this type.
lldb::opaque_compiler_type_t GetOpaqueQualType() const
CompilerType AddVolatileModifier() const
Return a new CompilerType adds a volatile modifier to this type if this type is valid and the type sy...
CompilerType AddRestrictModifier() const
Return a new CompilerType adds a restrict modifier to this type if this type is valid and the type sy...
bool IsIntegerType(bool &is_signed) const
CompilerType CreateTypedef(const char *name, const CompilerDeclContext &decl_ctx, uint32_t payload) const
Create a typedef to this type using "name" as the name of the typedef this type is valid and the type...
A uniqued constant string class.
Definition ConstString.h:40
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
"lldb/Expression/DWARFExpressionList.h" Encapsulates a range map from file address range to a single ...
"lldb/Expression/DWARFExpression.h" Encapsulates a DWARF location expression and interprets it.
void SetRegisterKind(lldb::RegisterKind reg_kind)
Set the call-frame-info style register kind.
An data extractor class.
A class that describes the declaration location of a lldb object.
Definition Declaration.h:24
lldb::ModuleSP GetModule() const
Get const accessor for the module pointer.
A class that encapsulates name lookup information.
Definition Module.h:935
ConstString GetLookupName() const
Definition Module.h:974
static bool RegisterPlugin(llvm::StringRef name, llvm::StringRef description, ABICreateInstance create_callback)
static bool UnregisterPlugin(ABICreateInstance create_callback)
void Append(const Entry &entry)
Definition RangeMap.h:179
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
lldb::SectionSP FindSectionByType(lldb::SectionType sect_type, bool check_children, size_t start_idx=0) const
Definition Section.cpp:602
const char * GetData() const
const char * GetData() const
llvm::StringRef GetString() const
llvm::raw_ostream & AsRawOstream()
Returns a raw_ostream that forwards the data to this Stream object.
Definition Stream.h:405
size_t size_t PutHex8(uint8_t uvalue)
Append an uint8_t value in the hexadecimal format to the stream.
Definition Stream.cpp:269
@ eBinary
Get and put data as binary instead of as the default string mode.
Definition Stream.h:32
size_t PutMaxHex64(uint64_t uvalue, size_t byte_size, lldb::ByteOrder byte_order=lldb::eByteOrderInvalid)
Definition Stream.cpp:323
Defines a list of symbol context objects.
void Append(const SymbolContext &sc)
Append a new symbol context to the list.
Defines a symbol context baton that can be handed other debug core functions.
Function * function
The Function for a given query.
CompileUnit * comp_unit
The CompileUnit for a given query.
Variable * variable
The global variable matching the given query.
Symbol * symbol
The Symbol for a given query.
void FindTypesByRegex(const lldb_private::RegularExpression &regex, uint32_t max_matches, lldb_private::TypeMap &types)
Type * ResolveTypeUID(lldb::user_id_t type_uid) override
static constexpr uint16_t g_ctf_magic
llvm::Expected< lldb::TypeSP > CreateFunction(const CTFFunction &ctf_function)
void AddSymbols(Symtab &symtab) override
bool CompleteType(CompilerType &compiler_type) override
lldb::CompUnitSP m_comp_unit_sp
std::vector< lldb::FunctionSP > m_functions
static char ID
LLVM RTTI support.
llvm::Expected< lldb::TypeSP > CreateTypedef(const CTFTypedef &ctf_typedef)
size_t ParseFunctions(CompileUnit &comp_unit) override
static llvm::StringRef GetPluginDescriptionStatic()
llvm::DenseMap< lldb::opaque_compiler_type_t, const CTFType * > m_compiler_types
To complete types, we need a way to map (imcomplete) compiler types back to parsed CTF types.
void FindFunctions(const lldb_private::Module::LookupInfo &lookup_info, const lldb_private::CompilerDeclContext &parent_decl_ctx, bool include_inlines, lldb_private::SymbolContextList &sc_list) override
llvm::Expected< lldb::TypeSP > CreateArray(const CTFArray &ctf_array)
uint32_t CalculateAbilities() override
size_t ParseVariablesForContext(const SymbolContext &sc) override
static lldb_private::SymbolFile * CreateInstance(lldb::ObjectFileSP objfile_sp)
lldb::offset_t m_body_offset
The start offset of the CTF body into m_data.
static constexpr uint16_t g_ctf_field_threshold
lldb::CompUnitSP ParseCompileUnitAtIndex(uint32_t index) override
static llvm::StringRef GetPluginNameStatic()
size_t ParseObjects(CompileUnit &comp_unit)
llvm::Expected< lldb::TypeSP > CreateForward(const CTFForward &ctf_forward)
llvm::Expected< lldb::TypeSP > CreateEnum(const CTFEnum &ctf_enum)
void InitializeObject() override
Initialize the SymbolFile object.
void FindTypes(const lldb_private::TypeQuery &match, lldb_private::TypeResults &results) override
Find types using a type-matching object that contains all search parameters.
llvm::StringRef ReadString(lldb::offset_t offset) const
llvm::Expected< lldb::TypeSP > CreateRecord(const CTFRecord &ctf_record)
void FindGlobalVariables(lldb_private::ConstString name, const lldb_private::CompilerDeclContext &parent_decl_ctx, uint32_t max_matches, lldb_private::VariableList &variables) override
llvm::Expected< lldb::TypeSP > CreateInteger(const CTFInteger &ctf_integer)
static constexpr uint8_t g_ctf_version
llvm::DenseMap< lldb::user_id_t, lldb::TypeSP > m_types
Parsed LLDB types.
std::vector< lldb::VariableSP > m_variables
llvm::DenseMap< lldb::user_id_t, std::unique_ptr< CTFType > > m_ctf_types
Parsed CTF types.
llvm::Expected< lldb::TypeSP > CreateModifier(const CTFModifier &ctf_modifier)
llvm::Expected< lldb::TypeSP > CreateType(CTFType *ctf_type)
SymbolFileCTF(lldb::ObjectFileSP objfile_sp)
uint32_t ResolveSymbolContext(const lldb_private::Address &so_addr, lldb::SymbolContextItem resolve_scope, lldb_private::SymbolContext &sc) override
llvm::Expected< std::unique_ptr< CTFType > > ParseType(lldb::offset_t &offset, lldb::user_id_t uid)
std::optional< ctf_header_t > m_header
size_t ParseTypes(CompileUnit &cu) override
ObjectFile * GetObjectFile() override
Definition SymbolFile.h:595
virtual TypeList & GetTypeList()
Definition SymbolFile.h:668
lldb::ObjectFileSP m_objfile_sp
Definition SymbolFile.h:671
SymbolFileCommon(lldb::ObjectFileSP objfile_sp)
Definition SymbolFile.h:580
llvm::Expected< lldb::TypeSystemSP > GetTypeSystemForLanguage(lldb::LanguageType language) override
lldb::TypeSP MakeType(lldb::user_id_t uid, ConstString name, std::optional< uint64_t > byte_size, SymbolContextScope *context, lldb::user_id_t encoding_uid, Type::EncodingDataType encoding_uid_type, const Declaration &decl, const CompilerType &compiler_qual_type, Type::ResolveState compiler_type_resolve_state, uint32_t opaque_payload=0) override
This function is used to create types that belong to a SymbolFile.
Definition SymbolFile.h:639
Provides public interface for all SymbolFiles.
Definition SymbolFile.h:51
virtual std::recursive_mutex & GetModuleMutex() const
Symbols file subclasses should override this to return the Module that owns the TypeSystem that this ...
lldb::addr_t GetFileAddress() const
Definition Symbol.cpp:598
Mangled & GetMangled()
Definition Symbol.h:162
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:469
ConstString GetName() const
Definition Symbol.cpp:612
Address GetAddress() const
Definition Symbol.h:98
Symbol * FindSymbolWithType(lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx)
Definition Symtab.cpp:776
void Insert(const lldb::TypeSP &type)
Definition TypeMap.cpp:27
A class that contains all state required for type lookups.
ConstString GetTypeBasename() const
Get the type basename to use when searching the type indexes in each SymbolFile object.
This class tracks the state and results of a TypeQuery.
bool InsertUnique(const lldb::TypeSP &type_sp)
When types that match a TypeQuery are found, this API is used to insert the matching types.
bool Done(const TypeQuery &query) const
Check if the type matching has found all of the matches that it needs.
bool AlreadySearched(lldb_private::SymbolFile *sym_file)
Check if a SymbolFile object has already been searched by this type match object.
static lldb::BasicType GetBasicTypeEnumeration(llvm::StringRef name)
static bool CompleteTagDeclarationDefinition(const CompilerType &type)
static clang::FieldDecl * AddFieldToRecordType(const CompilerType &type, llvm::StringRef name, const CompilerType &field_type, uint32_t bitfield_bit_size)
@ eEncodingIsUID
This type is the type whose UID is m_encoding_uid.
CompilerType GetFullCompilerType()
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope)
void AddVariable(const lldb::VariableSP &var_sp)
RangeVector< lldb::addr_t, lldb::addr_t > RangeList
Definition Variable.h:27
#define LLDB_INVALID_UID
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:338
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
Definition ARMUtils.h:265
std::shared_ptr< lldb_private::Function > FunctionSP
@ eDescriptionLevelBrief
BasicType
Basic types enumeration for the public API SBType::GetBasicType().
uint64_t offset_t
Definition lldb-types.h:86
std::shared_ptr< lldb_private::ObjectFile > ObjectFileSP
@ eLanguageTypeC
Non-standardized C, such as K&R.
std::shared_ptr< lldb_private::Type > TypeSP
ByteOrder
Byte ordering definitions.
std::shared_ptr< lldb_private::Variable > VariableSP
@ eValueTypeVariableGlobal
globals variable
uint64_t user_id_t
Definition lldb-types.h:83
std::shared_ptr< lldb_private::DataBuffer > DataBufferSP
std::shared_ptr< lldb_private::Section > SectionSP
std::shared_ptr< lldb_private::Module > ModuleSP
std::shared_ptr< lldb_private::CompileUnit > CompUnitSP
@ eRegisterKindDWARF
the register numbers seen DWARF
std::vector< Value > values
Definition CTFTypes.h:137
std::vector< uint32_t > args
Definition CTFTypes.h:151
std::vector< Field > fields
Definition CTFTypes.h:177
llvm::StringRef name
Definition CTFTypes.h:40
lldb::user_id_t uid
Definition CTFTypes.h:39