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