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 ({0}) doesn't match "
180 "expected size ([1})",
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, address_size, 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(),
906 symbol->GetName().AsCString(), type_sp, eValueTypeVariableGlobal,
907 m_comp_unit_sp.get(), ranges, &decl, location, symbol->IsExternal(),
908 /*artificial=*/false,
909 /*location_is_constant_data*/ false));
910 }
911 }
912
913 LLDB_LOG(log, "Parsed {0} CTF objects", m_variables.size());
914
915 return m_variables.size();
916}
917
919 if (!m_objfile_sp)
920 return 0;
921
922 if (!ParseHeader())
923 return 0;
924
926}
927
929 SymbolContextItem resolve_scope,
930 SymbolContext &sc) {
931 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
932 if (m_objfile_sp->GetSymtab() == nullptr)
933 return 0;
934
935 uint32_t resolved_flags = 0;
936
937 // Resolve symbols.
938 if (resolve_scope & eSymbolContextSymbol) {
939 sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
940 so_addr.GetFileAddress());
941 if (sc.symbol)
942 resolved_flags |= eSymbolContextSymbol;
943 }
944
945 // Resolve functions.
946 if (resolve_scope & eSymbolContextFunction) {
947 for (FunctionSP function_sp : m_functions) {
948 if (llvm::any_of(
949 function_sp->GetAddressRanges(), [&](const AddressRange range) {
950 return range.ContainsFileAddress(so_addr.GetFileAddress());
951 })) {
952 sc.function = function_sp.get();
953 resolved_flags |= eSymbolContextFunction;
954 break;
955 }
956 }
957 }
958
959 // Resolve variables.
960 if (resolve_scope & eSymbolContextVariable) {
961 for (VariableSP variable_sp : m_variables) {
962 if (variable_sp->LocationIsValidForAddress(so_addr.GetFileAddress())) {
963 sc.variable = variable_sp.get();
964 break;
965 }
966 }
967 }
968
969 return resolved_flags;
970}
971
973 if (idx == 0)
974 return m_comp_unit_sp;
975 return {};
976}
977
978size_t
982
984 // CTF does not encode symbols.
985 // We rely on the existing symbol table to map symbols to type.
986}
987
989 auto type_it = m_types.find(type_uid);
990 if (type_it != m_types.end())
991 return type_it->second.get();
992
993 auto ctf_type_it = m_ctf_types.find(type_uid);
994 if (ctf_type_it == m_ctf_types.end())
995 return nullptr;
996
997 CTFType *ctf_type = ctf_type_it->second.get();
998 assert(ctf_type && "m_ctf_types should only contain valid CTF types");
999 assert(ctf_type->uid == type_uid &&
1000 "CTF type UID doesn't match UID in m_ctf_types");
1001
1002 Log *log = GetLog(LLDBLog::Symbols);
1003
1004 llvm::Expected<TypeSP> type_or_error = CreateType(ctf_type);
1005 if (!type_or_error) {
1006 LLDB_LOG_ERROR(log, type_or_error.takeError(),
1007 "Failed to create type for {1}: {0}", ctf_type->uid);
1008 return {};
1009 }
1010
1011 TypeSP type_sp = *type_or_error;
1012
1013 if (log) {
1014 StreamString ss;
1015 type_sp->Dump(&ss, true);
1016 LLDB_LOGV(log, "Adding type {0}: {1}", type_sp->GetID(),
1017 llvm::StringRef(ss.GetString()).rtrim());
1018 }
1019
1020 m_types[type_uid] = type_sp;
1021
1022 return type_sp.get();
1023}
1024
1026 lldb_private::TypeResults &results) {
1027 // Make sure we haven't already searched this SymbolFile before.
1028 if (results.AlreadySearched(this))
1029 return;
1030
1031 ConstString name = match.GetTypeBasename();
1032 for (TypeSP type_sp : GetTypeList().Types()) {
1033 if (type_sp && type_sp->GetName() == name) {
1034 results.InsertUnique(type_sp);
1035 if (results.Done(match))
1036 return;
1037 }
1038 }
1039}
1040
1042 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1043 lldb_private::TypeMap &types) {
1045
1046 size_t matches = 0;
1047 for (TypeSP type_sp : GetTypeList().Types()) {
1048 if (matches == max_matches)
1049 break;
1050 if (type_sp && regex.Execute(type_sp->GetName()))
1051 types.Insert(type_sp);
1052 matches++;
1053 }
1054}
1055
1057 const lldb_private::Module::LookupInfo &lookup_info,
1058 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1059 bool include_inlines, lldb_private::SymbolContextList &sc_list) {
1061
1062 ConstString name = lookup_info.GetLookupName();
1063 for (FunctionSP function_sp : m_functions) {
1064 if (function_sp && function_sp->GetName() == name) {
1066 sc.comp_unit = m_comp_unit_sp.get();
1067 sc.function = function_sp.get();
1068 sc_list.Append(sc);
1069 }
1070 }
1071}
1072
1074 bool include_inlines,
1076 for (FunctionSP function_sp : m_functions) {
1077 if (function_sp && regex.Execute(function_sp->GetName())) {
1079 sc.comp_unit = m_comp_unit_sp.get();
1080 sc.function = function_sp.get();
1081 sc_list.Append(sc);
1082 }
1083 }
1084}
1085
1088 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1089 uint32_t max_matches, lldb_private::VariableList &variables) {
1091
1092 size_t matches = 0;
1093 for (VariableSP variable_sp : m_variables) {
1094 if (matches == max_matches)
1095 break;
1096 if (variable_sp && variable_sp->GetName() == name) {
1097 variables.AddVariable(variable_sp);
1098 matches++;
1099 }
1100 }
1101}
1102
1104 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1105 lldb_private::VariableList &variables) {
1107
1108 size_t matches = 0;
1109 for (VariableSP variable_sp : m_variables) {
1110 if (matches == max_matches)
1111 break;
1112 if (variable_sp && regex.Execute(variable_sp->GetName())) {
1113 variables.AddVariable(variable_sp);
1114 matches++;
1115 }
1116 }
1117}
#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:369
#define LLDB_LOG_ERROR(log, error,...)
Definition Log.h:392
#define LLDB_LOGV(log,...)
Definition Log.h:383
#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:281
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:681
lldb::ByteOrder GetByteOrder() const
Returns the byte order for the architecture specification.
Definition ArchSpec.cpp:730
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:908
ConstString GetLookupName() const
Definition Module.h:947
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:600
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:406
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:570
virtual TypeList & GetTypeList()
Definition SymbolFile.h:643
lldb::ObjectFileSP m_objfile_sp
Definition SymbolFile.h:646
SymbolFileCommon(lldb::ObjectFileSP objfile_sp)
Definition SymbolFile.h:555
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:614
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:497
Mangled & GetMangled()
Definition Symbol.h:147
lldb::addr_t GetByteSize() const
Definition Symbol.cpp:431
ConstString GetName() const
Definition Symbol.cpp:511
Address GetAddress() const
Definition Symbol.h:89
Symbol * FindSymbolWithType(lldb::SymbolType symbol_type, Debug symbol_debug_type, Visibility symbol_visibility, uint32_t &start_idx)
Definition Symtab.cpp:799
void Insert(const lldb::TypeSP &type)
Definition TypeMap.cpp:27
A class that contains all state required for type lookups.
Definition Type.h:104
ConstString GetTypeBasename() const
Get the type basename to use when searching the type indexes in each SymbolFile object.
Definition Type.cpp:113
This class tracks the state and results of a TypeQuery.
Definition Type.h:344
bool InsertUnique(const lldb::TypeSP &type_sp)
When types that match a TypeQuery are found, this API is used to insert the matching types.
Definition Type.cpp:194
bool Done(const TypeQuery &query) const
Check if the type matching has found all of the matches that it needs.
Definition Type.cpp:200
bool AlreadySearched(lldb_private::SymbolFile *sym_file)
Check if a SymbolFile object has already been searched by this type match object.
Definition Type.cpp:190
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.
Definition Type.h:423
CompilerType GetFullCompilerType()
Definition Type.cpp:772
llvm::Expected< uint64_t > GetByteSize(ExecutionContextScope *exe_scope)
Definition Type.cpp:459
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:332
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:85
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
uint64_t user_id_t
Definition lldb-types.h:82
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
@ eValueTypeVariableGlobal
globals variable
@ eRegisterKindDWARF
the register numbers seen DWARF
std::vector< Value > values
Definition CTFTypes.h:135
std::vector< uint32_t > args
Definition CTFTypes.h:149
std::vector< Field > fields
Definition CTFTypes.h:175
llvm::StringRef name
Definition CTFTypes.h:38
lldb::user_id_t uid
Definition CTFTypes.h:37