Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / lldb / source / Plugins / SymbolFile / CTF / SymbolFileCTF.cpp
blob62353be170cfb0c1443d67ac07a1f6dc733d1285
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 //===----------------------------------------------------------------------===//
9 #include "SymbolFileCTF.h"
11 #include "lldb/Core/Module.h"
12 #include "lldb/Core/PluginManager.h"
13 #include "lldb/Host/Config.h"
14 #include "lldb/Symbol/CompileUnit.h"
15 #include "lldb/Symbol/Function.h"
16 #include "lldb/Symbol/ObjectFile.h"
17 #include "lldb/Symbol/Symbol.h"
18 #include "lldb/Symbol/SymbolContext.h"
19 #include "lldb/Symbol/Symtab.h"
20 #include "lldb/Symbol/TypeList.h"
21 #include "lldb/Symbol/TypeMap.h"
22 #include "lldb/Symbol/Variable.h"
23 #include "lldb/Symbol/VariableList.h"
24 #include "lldb/Utility/DataExtractor.h"
25 #include "lldb/Utility/LLDBLog.h"
26 #include "lldb/Utility/Log.h"
27 #include "lldb/Utility/RegularExpression.h"
28 #include "lldb/Utility/StreamBuffer.h"
29 #include "lldb/Utility/StreamString.h"
30 #include "lldb/Utility/Timer.h"
31 #include "llvm/Support/MemoryBuffer.h"
33 #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
34 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
36 #include <memory>
37 #include <optional>
39 #if LLVM_ENABLE_ZLIB
40 #include <zlib.h>
41 #endif
43 using namespace llvm;
44 using namespace lldb;
45 using namespace lldb_private;
47 LLDB_PLUGIN_DEFINE(SymbolFileCTF)
49 char SymbolFileCTF::ID;
51 SymbolFileCTF::SymbolFileCTF(lldb::ObjectFileSP objfile_sp)
52 : SymbolFileCommon(std::move(objfile_sp)) {}
54 void SymbolFileCTF::Initialize() {
55 PluginManager::RegisterPlugin(GetPluginNameStatic(),
56 GetPluginDescriptionStatic(), CreateInstance);
59 void SymbolFileCTF::Terminate() {
60 PluginManager::UnregisterPlugin(CreateInstance);
63 llvm::StringRef SymbolFileCTF::GetPluginDescriptionStatic() {
64 return "Compact C Type Format Symbol Reader";
67 SymbolFile *SymbolFileCTF::CreateInstance(ObjectFileSP objfile_sp) {
68 return new SymbolFileCTF(std::move(objfile_sp));
71 bool SymbolFileCTF::ParseHeader() {
72 if (m_header)
73 return true;
75 Log *log = GetLog(LLDBLog::Symbols);
77 ModuleSP module_sp(m_objfile_sp->GetModule());
78 const SectionList *section_list = module_sp->GetSectionList();
79 if (!section_list)
80 return false;
82 SectionSP section_sp(
83 section_list->FindSectionByType(lldb::eSectionTypeCTF, true));
84 if (!section_sp)
85 return false;
87 m_objfile_sp->ReadSectionData(section_sp.get(), m_data);
89 if (m_data.GetByteSize() == 0)
90 return false;
92 StreamString module_desc;
93 GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),
94 lldb::eDescriptionLevelBrief);
95 LLDB_LOG(log, "Parsing Compact C Type format for {0}", module_desc.GetData());
97 lldb::offset_t offset = 0;
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;
106 m_header.emplace();
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);
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;
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;
134 LLDB_LOG(log, "Parsed valid CTF preamble: version {0}, flags {1:x}",
135 ctf_header.preamble.version, ctf_header.preamble.flags);
137 m_body_offset = offset;
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);
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;
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;
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;
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;
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;
183 m_data = DataExtractor(decompressed_data, m_data.GetByteOrder(),
184 m_data.GetAddressByteSize());
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
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;
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;
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;
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;
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;
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;
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;
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;
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);
263 return true;
266 void SymbolFileCTF::InitializeObject() {
267 Log *log = GetLog(LLDBLog::Symbols);
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;
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);
281 ParseTypes(*m_comp_unit_sp);
284 llvm::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);
294 /// Return the integer display representation encoded in the given data.
295 static uint32_t GetEncoding(uint32_t data) {
296 // Mask bits 24–31.
297 return ((data)&0xff000000) >> 24;
300 /// Return the integral width in bits encoded in the given data.
301 static uint32_t GetBits(uint32_t data) {
302 // Mask bits 0-15.
303 return (data)&0x0000ffff;
306 /// Return the type kind encoded in the given data.
307 uint32_t GetKind(uint32_t data) {
308 // Mask bits 26–31.
309 return ((data)&0xf800) >> 11;
312 /// Return the variable length encoded in the given data.
313 uint32_t GetVLen(uint32_t data) {
314 // Mask bits 0–24.
315 return (data)&0x3ff;
318 static uint32_t GetBytes(uint32_t bits) { return bits / sizeof(unsigned); }
320 static clang::TagTypeKind TranslateRecordKind(CTFType::Kind type) {
321 switch (type) {
322 case CTFType::Kind::eStruct:
323 return clang::TTK_Struct;
324 case CTFType::Kind::eUnion:
325 return clang::TTK_Union;
326 default:
327 lldbassert(false && "Invalid record kind!");
328 return clang::TTK_Struct;
332 llvm::Expected<TypeSP>
333 SymbolFileCTF::CreateInteger(const CTFInteger &ctf_integer) {
334 lldb::BasicType basic_type =
335 TypeSystemClang::GetBasicTypeEnumeration(ctf_integer.name);
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());
343 CompilerType compiler_type = m_ast->GetBasicType(basic_type);
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());
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());
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,
372 lldb_private::Type::ResolveState::Full);
375 llvm::Expected<lldb::TypeSP>
376 SymbolFileCTF::CreateModifier(const CTFModifier &ctf_modifier) {
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());
383 CompilerType compiler_type;
385 switch (ctf_modifier.kind) {
386 case CTFType::ePointer:
387 compiler_type = ref_type->GetFullCompilerType().GetPointerType();
388 break;
389 case CTFType::eConst:
390 compiler_type = ref_type->GetFullCompilerType().AddConstModifier();
391 break;
392 case CTFType::eVolatile:
393 compiler_type = ref_type->GetFullCompilerType().AddVolatileModifier();
394 break;
395 case CTFType::eRestrict:
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());
405 Declaration decl;
406 return MakeType(ctf_modifier.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
407 Type::eEncodingIsUID, decl, compiler_type,
408 lldb_private::Type::ResolveState::Full);
411 llvm::Expected<lldb::TypeSP>
412 SymbolFileCTF::CreateTypedef(const CTFTypedef &ctf_typedef) {
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());
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);
425 Declaration decl;
426 return MakeType(ctf_typedef.uid, ConstString(ctf_typedef.name), 0, nullptr,
427 LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
428 ast_typedef, lldb_private::Type::ResolveState::Full);
431 llvm::Expected<lldb::TypeSP>
432 SymbolFileCTF::CreateArray(const CTFArray &ctf_array) {
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());
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());
446 uint64_t size = ctf_array.nelems * *element_size;
448 CompilerType compiler_type = m_ast->CreateArrayType(
449 element_type->GetFullCompilerType(), ctf_array.nelems,
450 /*is_gnu_vector*/ false);
452 Declaration decl;
453 return MakeType(ctf_array.uid, ConstString(), size, nullptr, LLDB_INVALID_UID,
454 Type::eEncodingIsUID, decl, compiler_type,
455 lldb_private::Type::ResolveState::Full);
458 llvm::Expected<lldb::TypeSP>
459 SymbolFileCTF::CreateEnum(const CTFEnum &ctf_enum) {
460 Declaration decl;
461 CompilerType enum_type = m_ast->CreateEnumerationType(
462 ctf_enum.name, m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(),
463 decl, m_ast->GetBasicType(eBasicTypeInt),
464 /*is_scoped=*/false);
466 for (const CTFEnum::Value &value : ctf_enum.values) {
467 Declaration value_decl;
468 m_ast->AddEnumerationValueToEnumerationType(
469 enum_type, value_decl, value.name.data(), value.value, ctf_enum.size);
471 TypeSystemClang::CompleteTagDeclarationDefinition(enum_type);
473 return MakeType(ctf_enum.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
474 Type::eEncodingIsUID, decl, enum_type,
475 lldb_private::Type::ResolveState::Full);
478 llvm::Expected<lldb::TypeSP>
479 SymbolFileCTF::CreateFunction(const CTFFunction &ctf_function) {
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());
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());
493 CompilerType func_type = m_ast->CreateFunctionType(
494 ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(),
495 ctf_function.variadic, 0, clang::CallingConv::CC_C);
497 Declaration decl;
498 return MakeType(ctf_function.uid, ConstString(ctf_function.name), 0, nullptr,
499 LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
500 lldb_private::Type::ResolveState::Full);
503 llvm::Expected<lldb::TypeSP>
504 SymbolFileCTF::CreateRecord(const CTFRecord &ctf_record) {
505 const clang::TagTypeKind tag_kind = TranslateRecordKind(ctf_record.kind);
506 CompilerType record_type =
507 m_ast->CreateRecordType(nullptr, OptionalClangModuleID(), eAccessPublic,
508 ctf_record.name.data(), 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,
512 nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
513 decl, record_type, lldb_private::Type::ResolveState::Forward);
516 bool SymbolFileCTF::CompleteType(CompilerType &compiler_type) {
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;
522 const CTFType *ctf_type = it->second;
523 assert(ctf_type && "m_compiler_types should only contain valid CTF types");
525 // We only support resolving record types.
526 assert(llvm::isa<CTFRecord>(ctf_type));
528 // Cast to the appropriate CTF type.
529 const CTFRecord *ctf_record = static_cast<const CTFRecord *>(ctf_type);
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)) {
534 LLDB_LOG(GetLog(LLDBLog::Symbols),
535 "Cannot complete type {0} because field {1} is incomplete",
536 ctf_type->uid, field.type);
537 return false;
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);
551 m_ast->CompleteTagDeclarationDefinition(compiler_type);
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);
558 return true;
561 llvm::Expected<lldb::TypeSP>
562 SymbolFileCTF::CreateForward(const CTFForward &ctf_forward) {
563 CompilerType forward_compiler_type = m_ast->CreateRecordType(
564 nullptr, OptionalClangModuleID(), eAccessPublic, ctf_forward.name,
565 clang::TTK_Struct, eLanguageTypeC);
566 Declaration decl;
567 return MakeType(ctf_forward.uid, ConstString(ctf_forward.name), 0, nullptr,
568 LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
569 forward_compiler_type, Type::ResolveState::Forward);
572 llvm::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());
577 switch (ctf_type->kind) {
578 case CTFType::Kind::eInteger:
579 return CreateInteger(*static_cast<CTFInteger *>(ctf_type));
580 case CTFType::Kind::eConst:
581 case CTFType::Kind::ePointer:
582 case CTFType::Kind::eRestrict:
583 case CTFType::Kind::eVolatile:
584 return CreateModifier(*static_cast<CTFModifier *>(ctf_type));
585 case CTFType::Kind::eTypedef:
586 return CreateTypedef(*static_cast<CTFTypedef *>(ctf_type));
587 case CTFType::Kind::eArray:
588 return CreateArray(*static_cast<CTFArray *>(ctf_type));
589 case CTFType::Kind::eEnum:
590 return CreateEnum(*static_cast<CTFEnum *>(ctf_type));
591 case CTFType::Kind::eFunction:
592 return CreateFunction(*static_cast<CTFFunction *>(ctf_type));
593 case CTFType::Kind::eStruct:
594 case CTFType::Kind::eUnion:
595 return CreateRecord(*static_cast<CTFRecord *>(ctf_type));
596 case CTFType::Kind::eForward:
597 return CreateForward(*static_cast<CTFForward *>(ctf_type));
598 case CTFType::Kind::eUnknown:
599 case CTFType::Kind::eFloat:
600 case CTFType::Kind::eSlice:
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());
608 llvm::Expected<std::unique_ptr<CTFType>>
609 SymbolFileCTF::ParseType(lldb::offset_t &offset, lldb::user_id_t uid) {
610 ctf_stype_t ctf_stype;
611 ctf_stype.name = m_data.GetU32(&offset);
612 ctf_stype.info = m_data.GetU32(&offset);
613 ctf_stype.size = m_data.GetU32(&offset);
615 llvm::StringRef name = ReadString(ctf_stype.name);
616 const uint32_t kind = GetKind(ctf_stype.info);
617 const uint32_t variable_length = GetVLen(ctf_stype.info);
618 const uint32_t type = ctf_stype.GetType();
619 const uint32_t size = ctf_stype.GetSize();
621 switch (kind) {
622 case TypeKind::eInteger: {
623 const uint32_t vdata = m_data.GetU32(&offset);
624 const uint32_t bits = GetBits(vdata);
625 const uint32_t encoding = GetEncoding(vdata);
626 return std::make_unique<CTFInteger>(uid, name, bits, encoding);
628 case TypeKind::eConst:
629 return std::make_unique<CTFConst>(uid, type);
630 case TypeKind::ePointer:
631 return std::make_unique<CTFPointer>(uid, type);
632 case TypeKind::eRestrict:
633 return std::make_unique<CTFRestrict>(uid, type);
634 case TypeKind::eVolatile:
635 return std::make_unique<CTFVolatile>(uid, type);
636 case TypeKind::eTypedef:
637 return std::make_unique<CTFTypedef>(uid, name, type);
638 case TypeKind::eArray: {
639 const uint32_t type = m_data.GetU32(&offset);
640 const uint32_t index = m_data.GetU32(&offset);
641 const uint32_t nelems = m_data.GetU32(&offset);
642 return std::make_unique<CTFArray>(uid, name, type, index, nelems);
644 case TypeKind::eEnum: {
645 std::vector<CTFEnum::Value> values;
646 for (uint32_t i = 0; i < variable_length; ++i) {
647 const uint32_t value_name = m_data.GetU32(&offset);
648 const uint32_t value = m_data.GetU32(&offset);
649 values.emplace_back(ReadString(value_name), value);
651 return std::make_unique<CTFEnum>(uid, name, variable_length, size, values);
653 case TypeKind::eFunction: {
654 std::vector<uint32_t> args;
655 bool variadic = false;
656 for (uint32_t i = 0; i < variable_length; ++i) {
657 const uint32_t arg_uid = m_data.GetU32(&offset);
658 // If the last argument is 0, this is a variadic function.
659 if (arg_uid == 0) {
660 variadic = true;
661 break;
663 args.push_back(arg_uid);
665 // If the number of arguments is odd, a single uint32_t of padding is
666 // inserted to maintain alignment.
667 if (variable_length % 2 == 1)
668 m_data.GetU32(&offset);
669 return std::make_unique<CTFFunction>(uid, name, variable_length, type, args,
670 variadic);
672 case TypeKind::eStruct:
673 case TypeKind::eUnion: {
674 std::vector<CTFRecord::Field> fields;
675 for (uint32_t i = 0; i < variable_length; ++i) {
676 const uint32_t field_name = m_data.GetU32(&offset);
677 const uint32_t type = m_data.GetU32(&offset);
678 uint64_t field_offset = 0;
679 if (size < g_ctf_field_threshold) {
680 field_offset = m_data.GetU16(&offset);
681 m_data.GetU16(&offset); // Padding
682 } else {
683 const uint32_t offset_hi = m_data.GetU32(&offset);
684 const uint32_t offset_lo = m_data.GetU32(&offset);
685 field_offset = (((uint64_t)offset_hi) << 32) | ((uint64_t)offset_lo);
687 fields.emplace_back(ReadString(field_name), type, field_offset);
689 return std::make_unique<CTFRecord>(static_cast<CTFType::Kind>(kind), uid,
690 name, variable_length, size, fields);
692 case TypeKind::eForward:
693 return std::make_unique<CTFForward>(uid, name);
694 case TypeKind::eUnknown:
695 return std::make_unique<CTFType>(static_cast<CTFType::Kind>(kind), uid,
696 name);
697 case TypeKind::eFloat:
698 case TypeKind::eSlice:
699 offset += (variable_length * sizeof(uint32_t));
700 break;
703 return llvm::make_error<llvm::StringError>(
704 llvm::formatv("unsupported type (name = {0}, kind = {1}, vlength = {2})",
705 name, kind, variable_length),
706 llvm::inconvertibleErrorCode());
709 size_t SymbolFileCTF::ParseTypes(CompileUnit &cu) {
710 if (!ParseHeader())
711 return 0;
713 if (!m_types.empty())
714 return 0;
716 if (!m_ast)
717 return 0;
719 Log *log = GetLog(LLDBLog::Symbols);
720 LLDB_LOG(log, "Parsing CTF types");
722 lldb::offset_t type_offset = m_body_offset + m_header->typeoff;
723 const lldb::offset_t type_offset_end = m_body_offset + m_header->stroff;
725 lldb::user_id_t type_uid = 1;
726 while (type_offset < type_offset_end) {
727 llvm::Expected<std::unique_ptr<CTFType>> type_or_error =
728 ParseType(type_offset, type_uid);
729 if (type_or_error) {
730 m_ctf_types[(*type_or_error)->uid] = std::move(*type_or_error);
731 } else {
732 LLDB_LOG_ERROR(log, type_or_error.takeError(),
733 "Failed to parse type {1} at offset {2}: {0}", type_uid,
734 type_offset);
736 type_uid++;
739 LLDB_LOG(log, "Parsed {0} CTF types", m_ctf_types.size());
741 for (lldb::user_id_t uid = 1; uid < type_uid; ++uid)
742 ResolveTypeUID(uid);
744 LLDB_LOG(log, "Created {0} CTF types", m_types.size());
746 return m_types.size();
749 size_t SymbolFileCTF::ParseFunctions(CompileUnit &cu) {
750 if (!ParseHeader())
751 return 0;
753 if (!m_functions.empty())
754 return 0;
756 if (!m_ast)
757 return 0;
759 Symtab *symtab = GetObjectFile()->GetModule()->GetSymtab();
760 if (!symtab)
761 return 0;
763 Log *log = GetLog(LLDBLog::Symbols);
764 LLDB_LOG(log, "Parsing CTF functions");
766 lldb::offset_t function_offset = m_body_offset + m_header->funcoff;
767 const lldb::offset_t function_offset_end = m_body_offset + m_header->typeoff;
769 uint32_t symbol_idx = 0;
770 Declaration decl;
771 while (function_offset < function_offset_end) {
772 const uint32_t info = m_data.GetU32(&function_offset);
773 const uint16_t kind = GetKind(info);
774 const uint16_t variable_length = GetVLen(info);
776 Symbol *symbol = symtab->FindSymbolWithType(
777 eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, symbol_idx);
779 // Skip padding.
780 if (kind == TypeKind::eUnknown && variable_length == 0)
781 continue;
783 // Skip unexpected kinds.
784 if (kind != TypeKind::eFunction)
785 continue;
787 const uint32_t ret_uid = m_data.GetU32(&function_offset);
788 const uint32_t num_args = variable_length;
790 std::vector<CompilerType> arg_types;
791 arg_types.reserve(num_args);
793 bool is_variadic = false;
794 for (uint32_t i = 0; i < variable_length; i++) {
795 const uint32_t arg_uid = m_data.GetU32(&function_offset);
797 // If the last argument is 0, this is a variadic function.
798 if (arg_uid == 0) {
799 is_variadic = true;
800 break;
803 Type *arg_type = ResolveTypeUID(arg_uid);
804 arg_types.push_back(arg_type->GetFullCompilerType());
807 if (symbol) {
808 Type *ret_type = ResolveTypeUID(ret_uid);
809 AddressRange func_range =
810 AddressRange(symbol->GetFileAddress(), symbol->GetByteSize(),
811 GetObjectFile()->GetModule()->GetSectionList());
813 // Create function type.
814 CompilerType func_type = m_ast->CreateFunctionType(
815 ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(),
816 is_variadic, 0, clang::CallingConv::CC_C);
817 lldb::user_id_t function_type_uid = m_types.size() + 1;
818 TypeSP type_sp =
819 MakeType(function_type_uid, symbol->GetName(), 0, nullptr,
820 LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
821 lldb_private::Type::ResolveState::Full);
822 m_types[function_type_uid] = type_sp;
824 // Create function.
825 lldb::user_id_t func_uid = m_functions.size();
826 FunctionSP function_sp = std::make_shared<Function>(
827 &cu, func_uid, function_type_uid, symbol->GetMangled(), type_sp.get(),
828 func_range);
829 m_functions.emplace_back(function_sp);
830 cu.AddFunction(function_sp);
834 LLDB_LOG(log, "CTF parsed {0} functions", m_functions.size());
836 return m_functions.size();
839 static DWARFExpression CreateDWARFExpression(ModuleSP module_sp,
840 const Symbol &symbol) {
841 if (!module_sp)
842 return DWARFExpression();
844 const ArchSpec &architecture = module_sp->GetArchitecture();
845 ByteOrder byte_order = architecture.GetByteOrder();
846 uint32_t address_size = architecture.GetAddressByteSize();
847 uint32_t byte_size = architecture.GetDataByteSize();
849 StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
850 stream.PutHex8(lldb_private::dwarf::DW_OP_addr);
851 stream.PutMaxHex64(symbol.GetFileAddress(), address_size, byte_order);
853 DataBufferSP buffer =
854 std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
855 lldb_private::DataExtractor extractor(buffer, byte_order, address_size,
856 byte_size);
857 DWARFExpression result(extractor);
858 result.SetRegisterKind(eRegisterKindDWARF);
860 return result;
863 size_t SymbolFileCTF::ParseObjects(CompileUnit &comp_unit) {
864 if (!ParseHeader())
865 return 0;
867 if (!m_variables.empty())
868 return 0;
870 if (!m_ast)
871 return 0;
873 ModuleSP module_sp = GetObjectFile()->GetModule();
874 Symtab *symtab = module_sp->GetSymtab();
875 if (!symtab)
876 return 0;
878 Log *log = GetLog(LLDBLog::Symbols);
879 LLDB_LOG(log, "Parsing CTF objects");
881 lldb::offset_t object_offset = m_body_offset + m_header->objtoff;
882 const lldb::offset_t object_offset_end = m_body_offset + m_header->funcoff;
884 uint32_t symbol_idx = 0;
885 Declaration decl;
886 while (object_offset < object_offset_end) {
887 const uint32_t type_uid = m_data.GetU32(&object_offset);
889 if (Symbol *symbol =
890 symtab->FindSymbolWithType(eSymbolTypeData, Symtab::eDebugYes,
891 Symtab::eVisibilityAny, symbol_idx)) {
892 Variable::RangeList ranges;
893 ranges.Append(symbol->GetFileAddress(), symbol->GetByteSize());
895 auto type_sp = std::make_shared<SymbolFileType>(*this, type_uid);
897 DWARFExpressionList location(
898 module_sp, CreateDWARFExpression(module_sp, *symbol), nullptr);
900 lldb::user_id_t variable_type_uid = m_variables.size();
901 m_variables.emplace_back(std::make_shared<Variable>(
902 variable_type_uid, symbol->GetName().AsCString(),
903 symbol->GetName().AsCString(), type_sp, eValueTypeVariableGlobal,
904 m_comp_unit_sp.get(), ranges, &decl, location, symbol->IsExternal(),
905 /*artificial=*/false,
906 /*location_is_constant_data*/ false));
910 LLDB_LOG(log, "Parsed {0} CTF objects", m_variables.size());
912 return m_variables.size();
915 uint32_t SymbolFileCTF::CalculateAbilities() {
916 if (!m_objfile_sp)
917 return 0;
919 if (!ParseHeader())
920 return 0;
922 return VariableTypes | Functions | GlobalVariables;
925 uint32_t SymbolFileCTF::ResolveSymbolContext(const Address &so_addr,
926 SymbolContextItem resolve_scope,
927 SymbolContext &sc) {
928 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
929 if (m_objfile_sp->GetSymtab() == nullptr)
930 return 0;
932 uint32_t resolved_flags = 0;
934 // Resolve symbols.
935 if (resolve_scope & eSymbolContextSymbol) {
936 sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
937 so_addr.GetFileAddress());
938 if (sc.symbol)
939 resolved_flags |= eSymbolContextSymbol;
942 // Resolve functions.
943 if (resolve_scope & eSymbolContextFunction) {
944 for (FunctionSP function_sp : m_functions) {
945 if (function_sp->GetAddressRange().ContainsFileAddress(
946 so_addr.GetFileAddress())) {
947 sc.function = function_sp.get();
948 resolved_flags |= eSymbolContextFunction;
949 break;
954 // Resolve variables.
955 if (resolve_scope & eSymbolContextVariable) {
956 for (VariableSP variable_sp : m_variables) {
957 if (variable_sp->LocationIsValidForAddress(so_addr.GetFileAddress())) {
958 sc.variable = variable_sp.get();
959 break;
964 return resolved_flags;
967 CompUnitSP SymbolFileCTF::ParseCompileUnitAtIndex(uint32_t idx) {
968 if (idx == 0)
969 return m_comp_unit_sp;
970 return {};
973 size_t
974 SymbolFileCTF::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
975 return ParseObjects(*m_comp_unit_sp);
978 void SymbolFileCTF::AddSymbols(Symtab &symtab) {
979 // CTF does not encode symbols.
980 // We rely on the existing symbol table to map symbols to type.
983 lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
984 auto type_it = m_types.find(type_uid);
985 if (type_it != m_types.end())
986 return type_it->second.get();
988 auto ctf_type_it = m_ctf_types.find(type_uid);
989 if (ctf_type_it == m_ctf_types.end())
990 return nullptr;
992 CTFType *ctf_type = ctf_type_it->second.get();
993 assert(ctf_type && "m_ctf_types should only contain valid CTF types");
995 Log *log = GetLog(LLDBLog::Symbols);
997 llvm::Expected<TypeSP> type_or_error = CreateType(ctf_type);
998 if (!type_or_error) {
999 LLDB_LOG_ERROR(log, type_or_error.takeError(),
1000 "Failed to create type for {1}: {0}", ctf_type->uid);
1001 return {};
1004 TypeSP type_sp = *type_or_error;
1006 if (log) {
1007 StreamString ss;
1008 type_sp->Dump(&ss, true);
1009 LLDB_LOGV(log, "Adding type {0}: {1}", type_sp->GetID(),
1010 llvm::StringRef(ss.GetString()).rtrim());
1013 m_types[type_uid] = type_sp;
1015 // Except for record types which we'll need to complete later, we don't need
1016 // the CTF type anymore.
1017 if (!isa<CTFRecord>(ctf_type))
1018 m_ctf_types.erase(type_uid);
1020 return type_sp.get();
1023 void SymbolFileCTF::FindTypes(
1024 lldb_private::ConstString name,
1025 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1026 uint32_t max_matches,
1027 llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
1028 lldb_private::TypeMap &types) {
1030 searched_symbol_files.clear();
1031 searched_symbol_files.insert(this);
1033 size_t matches = 0;
1034 for (TypeSP type_sp : GetTypeList().Types()) {
1035 if (matches == max_matches)
1036 break;
1037 if (type_sp && type_sp->GetName() == name) {
1038 types.Insert(type_sp);
1039 matches++;
1044 void SymbolFileCTF::FindTypesByRegex(
1045 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1046 lldb_private::TypeMap &types) {
1047 ParseTypes(*m_comp_unit_sp);
1049 size_t matches = 0;
1050 for (TypeSP type_sp : GetTypeList().Types()) {
1051 if (matches == max_matches)
1052 break;
1053 if (type_sp && regex.Execute(type_sp->GetName()))
1054 types.Insert(type_sp);
1055 matches++;
1059 void SymbolFileCTF::FindFunctions(
1060 const lldb_private::Module::LookupInfo &lookup_info,
1061 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1062 bool include_inlines, lldb_private::SymbolContextList &sc_list) {
1063 ParseFunctions(*m_comp_unit_sp);
1065 ConstString name = lookup_info.GetLookupName();
1066 for (FunctionSP function_sp : m_functions) {
1067 if (function_sp && function_sp->GetName() == name) {
1068 lldb_private::SymbolContext sc;
1069 sc.comp_unit = m_comp_unit_sp.get();
1070 sc.function = function_sp.get();
1071 sc_list.Append(sc);
1076 void SymbolFileCTF::FindFunctions(const lldb_private::RegularExpression &regex,
1077 bool include_inlines,
1078 lldb_private::SymbolContextList &sc_list) {
1079 for (FunctionSP function_sp : m_functions) {
1080 if (function_sp && regex.Execute(function_sp->GetName())) {
1081 lldb_private::SymbolContext sc;
1082 sc.comp_unit = m_comp_unit_sp.get();
1083 sc.function = function_sp.get();
1084 sc_list.Append(sc);
1089 void SymbolFileCTF::FindGlobalVariables(
1090 lldb_private::ConstString name,
1091 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1092 uint32_t max_matches, lldb_private::VariableList &variables) {
1093 ParseObjects(*m_comp_unit_sp);
1095 size_t matches = 0;
1096 for (VariableSP variable_sp : m_variables) {
1097 if (matches == max_matches)
1098 break;
1099 if (variable_sp && variable_sp->GetName() == name) {
1100 variables.AddVariable(variable_sp);
1101 matches++;
1106 void SymbolFileCTF::FindGlobalVariables(
1107 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1108 lldb_private::VariableList &variables) {
1109 ParseObjects(*m_comp_unit_sp);
1111 size_t matches = 0;
1112 for (VariableSP variable_sp : m_variables) {
1113 if (matches == max_matches)
1114 break;
1115 if (variable_sp && regex.Execute(variable_sp->GetName())) {
1116 variables.AddVariable(variable_sp);
1117 matches++;