[LoongArch] Supports FP_TO_SINT operation for fp16 (#118303)
[llvm-project.git] / lldb / source / Plugins / SymbolFile / CTF / SymbolFileCTF.cpp
blob15e8d38e7f334bd98f4a55d92a21fad8e32b5350
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/Config/llvm-config.h" // for LLVM_ENABLE_ZLIB
32 #include "llvm/Support/MemoryBuffer.h"
34 #include "Plugins/ExpressionParser/Clang/ClangASTMetadata.h"
35 #include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
37 #include <memory>
38 #include <optional>
40 #if LLVM_ENABLE_ZLIB
41 #include <zlib.h>
42 #endif
44 using namespace llvm;
45 using namespace lldb;
46 using namespace lldb_private;
48 LLDB_PLUGIN_DEFINE(SymbolFileCTF)
50 char SymbolFileCTF::ID;
52 SymbolFileCTF::SymbolFileCTF(lldb::ObjectFileSP objfile_sp)
53 : SymbolFileCommon(std::move(objfile_sp)) {}
55 void SymbolFileCTF::Initialize() {
56 PluginManager::RegisterPlugin(GetPluginNameStatic(),
57 GetPluginDescriptionStatic(), CreateInstance);
60 void SymbolFileCTF::Terminate() {
61 PluginManager::UnregisterPlugin(CreateInstance);
64 llvm::StringRef SymbolFileCTF::GetPluginDescriptionStatic() {
65 return "Compact C Type Format Symbol Reader";
68 SymbolFile *SymbolFileCTF::CreateInstance(ObjectFileSP objfile_sp) {
69 return new SymbolFileCTF(std::move(objfile_sp));
72 bool SymbolFileCTF::ParseHeader() {
73 if (m_header)
74 return true;
76 Log *log = GetLog(LLDBLog::Symbols);
78 ModuleSP module_sp(m_objfile_sp->GetModule());
79 const SectionList *section_list = module_sp->GetSectionList();
80 if (!section_list)
81 return false;
83 SectionSP section_sp(
84 section_list->FindSectionByType(lldb::eSectionTypeCTF, true));
85 if (!section_sp)
86 return false;
88 m_objfile_sp->ReadSectionData(section_sp.get(), m_data);
90 if (m_data.GetByteSize() == 0)
91 return false;
93 StreamString module_desc;
94 GetObjectFile()->GetModule()->GetDescription(module_desc.AsRawOstream(),
95 lldb::eDescriptionLevelBrief);
96 LLDB_LOG(log, "Parsing Compact C Type format for {0}", module_desc.GetData());
98 lldb::offset_t offset = 0;
100 // Parse CTF header.
101 constexpr size_t ctf_header_size = sizeof(ctf_header_t);
102 if (!m_data.ValidOffsetForDataOfSize(offset, ctf_header_size)) {
103 LLDB_LOG(log, "CTF parsing failed: insufficient data for CTF header");
104 return false;
107 m_header.emplace();
109 ctf_header_t &ctf_header = *m_header;
110 ctf_header.preamble.magic = m_data.GetU16(&offset);
111 ctf_header.preamble.version = m_data.GetU8(&offset);
112 ctf_header.preamble.flags = m_data.GetU8(&offset);
113 ctf_header.parlabel = m_data.GetU32(&offset);
114 ctf_header.parname = m_data.GetU32(&offset);
115 ctf_header.lbloff = m_data.GetU32(&offset);
116 ctf_header.objtoff = m_data.GetU32(&offset);
117 ctf_header.funcoff = m_data.GetU32(&offset);
118 ctf_header.typeoff = m_data.GetU32(&offset);
119 ctf_header.stroff = m_data.GetU32(&offset);
120 ctf_header.strlen = m_data.GetU32(&offset);
122 // Validate the preamble.
123 if (ctf_header.preamble.magic != g_ctf_magic) {
124 LLDB_LOG(log, "CTF parsing failed: invalid magic: {0:x}",
125 ctf_header.preamble.magic);
126 return false;
129 if (ctf_header.preamble.version != g_ctf_version) {
130 LLDB_LOG(log, "CTF parsing failed: unsupported version: {0}",
131 ctf_header.preamble.version);
132 return false;
135 LLDB_LOG(log, "Parsed valid CTF preamble: version {0}, flags {1:x}",
136 ctf_header.preamble.version, ctf_header.preamble.flags);
138 m_body_offset = offset;
140 if (ctf_header.preamble.flags & eFlagCompress) {
141 // The body has been compressed with zlib deflate. Header offsets point into
142 // the decompressed data.
143 #if LLVM_ENABLE_ZLIB
144 const std::size_t decompressed_size = ctf_header.stroff + ctf_header.strlen;
145 DataBufferSP decompressed_data =
146 std::make_shared<DataBufferHeap>(decompressed_size, 0x0);
148 z_stream zstr;
149 memset(&zstr, 0, sizeof(zstr));
150 zstr.next_in = (Bytef *)const_cast<uint8_t *>(m_data.GetDataStart() +
151 sizeof(ctf_header_t));
152 zstr.avail_in = m_data.BytesLeft(offset);
153 zstr.next_out =
154 (Bytef *)const_cast<uint8_t *>(decompressed_data->GetBytes());
155 zstr.avail_out = decompressed_size;
157 int rc = inflateInit(&zstr);
158 if (rc != Z_OK) {
159 LLDB_LOG(log, "CTF parsing failed: inflate initialization error: {0}",
160 zError(rc));
161 return false;
164 rc = inflate(&zstr, Z_FINISH);
165 if (rc != Z_STREAM_END) {
166 LLDB_LOG(log, "CTF parsing failed: inflate error: {0}", zError(rc));
167 return false;
170 rc = inflateEnd(&zstr);
171 if (rc != Z_OK) {
172 LLDB_LOG(log, "CTF parsing failed: inflate end error: {0}", zError(rc));
173 return false;
176 if (zstr.total_out != decompressed_size) {
177 LLDB_LOG(log,
178 "CTF parsing failed: decompressed size ({0}) doesn't match "
179 "expected size ([1})",
180 zstr.total_out, decompressed_size);
181 return false;
184 m_data = DataExtractor(decompressed_data, m_data.GetByteOrder(),
185 m_data.GetAddressByteSize());
186 m_body_offset = 0;
187 #else
188 LLDB_LOG(
189 log,
190 "CTF parsing failed: data is compressed but no zlib inflate support");
191 return false;
192 #endif
195 // Validate the header.
196 if (!m_data.ValidOffset(m_body_offset + ctf_header.lbloff)) {
197 LLDB_LOG(log,
198 "CTF parsing failed: invalid label section offset in header: {0}",
199 ctf_header.lbloff);
200 return false;
203 if (!m_data.ValidOffset(m_body_offset + ctf_header.objtoff)) {
204 LLDB_LOG(log,
205 "CTF parsing failed: invalid object section offset in header: {0}",
206 ctf_header.objtoff);
207 return false;
210 if (!m_data.ValidOffset(m_body_offset + ctf_header.funcoff)) {
211 LLDB_LOG(
212 log,
213 "CTF parsing failed: invalid function section offset in header: {0}",
214 ctf_header.funcoff);
215 return false;
218 if (!m_data.ValidOffset(m_body_offset + ctf_header.typeoff)) {
219 LLDB_LOG(log,
220 "CTF parsing failed: invalid type section offset in header: {0}",
221 ctf_header.typeoff);
222 return false;
225 if (!m_data.ValidOffset(m_body_offset + ctf_header.stroff)) {
226 LLDB_LOG(log,
227 "CTF parsing failed: invalid string section offset in header: {0}",
228 ctf_header.stroff);
229 return false;
232 const lldb::offset_t str_end_offset =
233 m_body_offset + ctf_header.stroff + ctf_header.strlen;
234 if (!m_data.ValidOffset(str_end_offset - 1)) {
235 LLDB_LOG(log,
236 "CTF parsing failed: invalid string section length in header: {0}",
237 ctf_header.strlen);
238 return false;
241 if (m_body_offset + ctf_header.stroff + ctf_header.parlabel >
242 str_end_offset) {
243 LLDB_LOG(log,
244 "CTF parsing failed: invalid parent label offset: {0} exceeds end "
245 "of string section ({1})",
246 ctf_header.parlabel, str_end_offset);
247 return false;
250 if (m_body_offset + ctf_header.stroff + ctf_header.parname > str_end_offset) {
251 LLDB_LOG(log,
252 "CTF parsing failed: invalid parent name offset: {0} exceeds end "
253 "of string section ({1})",
254 ctf_header.parname, str_end_offset);
255 return false;
258 LLDB_LOG(log,
259 "Parsed valid CTF header: lbloff = {0}, objtoff = {1}, funcoff = "
260 "{2}, typeoff = {3}, stroff = {4}, strlen = {5}",
261 ctf_header.lbloff, ctf_header.objtoff, ctf_header.funcoff,
262 ctf_header.typeoff, ctf_header.stroff, ctf_header.strlen);
264 return true;
267 void SymbolFileCTF::InitializeObject() {
268 Log *log = GetLog(LLDBLog::Symbols);
270 auto type_system_or_err = GetTypeSystemForLanguage(lldb::eLanguageTypeC);
271 if (auto err = type_system_or_err.takeError()) {
272 LLDB_LOG_ERROR(log, std::move(err), "Unable to get type system: {0}");
273 return;
276 auto ts = *type_system_or_err;
277 m_ast = llvm::dyn_cast_or_null<TypeSystemClang>(ts.get());
278 LazyBool optimized = eLazyBoolNo;
279 m_comp_unit_sp = std::make_shared<CompileUnit>(
280 m_objfile_sp->GetModule(), nullptr, "", 0, eLanguageTypeC, optimized);
282 ParseTypes(*m_comp_unit_sp);
285 llvm::StringRef SymbolFileCTF::ReadString(lldb::offset_t str_offset) const {
286 lldb::offset_t offset = m_body_offset + m_header->stroff + str_offset;
287 if (!m_data.ValidOffset(offset))
288 return "(invalid)";
289 const char *str = m_data.GetCStr(&offset);
290 if (str && !*str)
291 return "(anon)";
292 return llvm::StringRef(str);
295 /// Return the integer display representation encoded in the given data.
296 static uint32_t GetEncoding(uint32_t data) {
297 // Mask bits 24–31.
298 return ((data)&0xff000000) >> 24;
301 /// Return the integral width in bits encoded in the given data.
302 static uint32_t GetBits(uint32_t data) {
303 // Mask bits 0-15.
304 return (data)&0x0000ffff;
307 /// Return the type kind encoded in the given data.
308 uint32_t GetKind(uint32_t data) {
309 // Mask bits 26–31.
310 return ((data)&0xf800) >> 11;
313 /// Return the variable length encoded in the given data.
314 uint32_t GetVLen(uint32_t data) {
315 // Mask bits 0–24.
316 return (data)&0x3ff;
319 static uint32_t GetBytes(uint32_t bits) { return bits / sizeof(unsigned); }
321 static clang::TagTypeKind TranslateRecordKind(CTFType::Kind type) {
322 switch (type) {
323 case CTFType::Kind::eStruct:
324 return clang::TagTypeKind::Struct;
325 case CTFType::Kind::eUnion:
326 return clang::TagTypeKind::Union;
327 default:
328 lldbassert(false && "Invalid record kind!");
329 return clang::TagTypeKind::Struct;
333 llvm::Expected<TypeSP>
334 SymbolFileCTF::CreateInteger(const CTFInteger &ctf_integer) {
335 lldb::BasicType basic_type =
336 TypeSystemClang::GetBasicTypeEnumeration(ctf_integer.name);
337 if (basic_type == eBasicTypeInvalid)
338 return llvm::make_error<llvm::StringError>(
339 llvm::formatv("unsupported integer type: no corresponding basic clang "
340 "type for '{0}'",
341 ctf_integer.name),
342 llvm::inconvertibleErrorCode());
344 CompilerType compiler_type = m_ast->GetBasicType(basic_type);
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::make_error<llvm::StringError>(
351 llvm::formatv(
352 "Found compiler type for '{0}' but it's not an integer type: {1}",
353 ctf_integer.name,
354 compiler_type.GetDisplayTypeName().GetStringRef()),
355 llvm::inconvertibleErrorCode());
357 // Make sure the signing matches between the CTF and the compiler type.
358 const bool type_is_signed = (ctf_integer.encoding & IntEncoding::eSigned);
359 if (compiler_type_is_signed != type_is_signed)
360 return llvm::make_error<llvm::StringError>(
361 llvm::formatv("Found integer compiler type for {0} but compiler type "
362 "is {1} and {0} is {2}",
363 ctf_integer.name,
364 compiler_type_is_signed ? "signed" : "unsigned",
365 type_is_signed ? "signed" : "unsigned"),
366 llvm::inconvertibleErrorCode());
369 Declaration decl;
370 return MakeType(ctf_integer.uid, ConstString(ctf_integer.name),
371 GetBytes(ctf_integer.bits), nullptr, LLDB_INVALID_UID,
372 lldb_private::Type::eEncodingIsUID, decl, compiler_type,
373 lldb_private::Type::ResolveState::Full);
376 llvm::Expected<lldb::TypeSP>
377 SymbolFileCTF::CreateModifier(const CTFModifier &ctf_modifier) {
378 Type *ref_type = ResolveTypeUID(ctf_modifier.type);
379 if (!ref_type)
380 return llvm::make_error<llvm::StringError>(
381 llvm::formatv("Could not find modified type: {0}", ctf_modifier.type),
382 llvm::inconvertibleErrorCode());
384 CompilerType compiler_type;
386 switch (ctf_modifier.kind) {
387 case CTFType::ePointer:
388 compiler_type = ref_type->GetFullCompilerType().GetPointerType();
389 break;
390 case CTFType::eConst:
391 compiler_type = ref_type->GetFullCompilerType().AddConstModifier();
392 break;
393 case CTFType::eVolatile:
394 compiler_type = ref_type->GetFullCompilerType().AddVolatileModifier();
395 break;
396 case CTFType::eRestrict:
397 compiler_type = ref_type->GetFullCompilerType().AddRestrictModifier();
398 break;
399 default:
400 return llvm::make_error<llvm::StringError>(
401 llvm::formatv("ParseModifier called with unsupported kind: {0}",
402 ctf_modifier.kind),
403 llvm::inconvertibleErrorCode());
406 Declaration decl;
407 return MakeType(ctf_modifier.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
408 Type::eEncodingIsUID, decl, compiler_type,
409 lldb_private::Type::ResolveState::Full);
412 llvm::Expected<lldb::TypeSP>
413 SymbolFileCTF::CreateTypedef(const CTFTypedef &ctf_typedef) {
414 Type *underlying_type = ResolveTypeUID(ctf_typedef.type);
415 if (!underlying_type)
416 return llvm::make_error<llvm::StringError>(
417 llvm::formatv("Could not find typedef underlying type: {0}",
418 ctf_typedef.type),
419 llvm::inconvertibleErrorCode());
421 CompilerType target_ast_type = underlying_type->GetFullCompilerType();
422 clang::DeclContext *decl_ctx = m_ast->GetTranslationUnitDecl();
423 CompilerType ast_typedef = target_ast_type.CreateTypedef(
424 ctf_typedef.name.data(), m_ast->CreateDeclContext(decl_ctx), 0);
426 Declaration decl;
427 return MakeType(ctf_typedef.uid, ConstString(ctf_typedef.name), 0, nullptr,
428 LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
429 ast_typedef, lldb_private::Type::ResolveState::Full);
432 llvm::Expected<lldb::TypeSP>
433 SymbolFileCTF::CreateArray(const CTFArray &ctf_array) {
434 Type *element_type = ResolveTypeUID(ctf_array.type);
435 if (!element_type)
436 return llvm::make_error<llvm::StringError>(
437 llvm::formatv("Could not find array element type: {0}", ctf_array.type),
438 llvm::inconvertibleErrorCode());
440 std::optional<uint64_t> element_size = element_type->GetByteSize(nullptr);
441 if (!element_size)
442 return llvm::make_error<llvm::StringError>(
443 llvm::formatv("could not get element size of type: {0}",
444 ctf_array.type),
445 llvm::inconvertibleErrorCode());
447 uint64_t size = ctf_array.nelems * *element_size;
449 CompilerType compiler_type = m_ast->CreateArrayType(
450 element_type->GetFullCompilerType(), ctf_array.nelems,
451 /*is_gnu_vector*/ false);
453 Declaration decl;
454 return MakeType(ctf_array.uid, ConstString(), size, nullptr, LLDB_INVALID_UID,
455 Type::eEncodingIsUID, decl, compiler_type,
456 lldb_private::Type::ResolveState::Full);
459 llvm::Expected<lldb::TypeSP>
460 SymbolFileCTF::CreateEnum(const CTFEnum &ctf_enum) {
461 Declaration decl;
462 CompilerType enum_type = m_ast->CreateEnumerationType(
463 ctf_enum.name, m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(),
464 decl, m_ast->GetBasicType(eBasicTypeInt),
465 /*is_scoped=*/false);
467 for (const CTFEnum::Value &value : ctf_enum.values) {
468 Declaration value_decl;
469 m_ast->AddEnumerationValueToEnumerationType(
470 enum_type, value_decl, value.name.data(), value.value, ctf_enum.size);
472 TypeSystemClang::CompleteTagDeclarationDefinition(enum_type);
474 return MakeType(ctf_enum.uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
475 Type::eEncodingIsUID, decl, enum_type,
476 lldb_private::Type::ResolveState::Full);
479 llvm::Expected<lldb::TypeSP>
480 SymbolFileCTF::CreateFunction(const CTFFunction &ctf_function) {
481 std::vector<CompilerType> arg_types;
482 for (uint32_t arg : ctf_function.args) {
483 if (Type *arg_type = ResolveTypeUID(arg))
484 arg_types.push_back(arg_type->GetFullCompilerType());
487 Type *ret_type = ResolveTypeUID(ctf_function.return_type);
488 if (!ret_type)
489 return llvm::make_error<llvm::StringError>(
490 llvm::formatv("Could not find function return type: {0}",
491 ctf_function.return_type),
492 llvm::inconvertibleErrorCode());
494 CompilerType func_type = m_ast->CreateFunctionType(
495 ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(),
496 ctf_function.variadic, 0, clang::CallingConv::CC_C);
498 Declaration decl;
499 return MakeType(ctf_function.uid, ConstString(ctf_function.name), 0, nullptr,
500 LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
501 lldb_private::Type::ResolveState::Full);
504 llvm::Expected<lldb::TypeSP>
505 SymbolFileCTF::CreateRecord(const CTFRecord &ctf_record) {
506 const clang::TagTypeKind tag_kind = TranslateRecordKind(ctf_record.kind);
507 CompilerType record_type = m_ast->CreateRecordType(
508 nullptr, OptionalClangModuleID(), eAccessPublic, ctf_record.name.data(),
509 llvm::to_underlying(tag_kind), eLanguageTypeC);
510 m_compiler_types[record_type.GetOpaqueQualType()] = &ctf_record;
511 Declaration decl;
512 return MakeType(ctf_record.uid, ConstString(ctf_record.name), ctf_record.size,
513 nullptr, LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID,
514 decl, record_type, lldb_private::Type::ResolveState::Forward);
517 bool SymbolFileCTF::CompleteType(CompilerType &compiler_type) {
518 // Check if we have a CTF type for the given incomplete compiler type.
519 auto it = m_compiler_types.find(compiler_type.GetOpaqueQualType());
520 if (it == m_compiler_types.end())
521 return false;
523 const CTFType *ctf_type = it->second;
524 assert(ctf_type && "m_compiler_types should only contain valid CTF types");
526 // We only support resolving record types.
527 assert(llvm::isa<CTFRecord>(ctf_type));
529 // Cast to the appropriate CTF type.
530 const CTFRecord *ctf_record = static_cast<const CTFRecord *>(ctf_type);
532 // If any of the fields are incomplete, we cannot complete the type.
533 for (const CTFRecord::Field &field : ctf_record->fields) {
534 if (!ResolveTypeUID(field.type)) {
535 LLDB_LOG(GetLog(LLDBLog::Symbols),
536 "Cannot complete type {0} because field {1} is incomplete",
537 ctf_type->uid, field.type);
538 return false;
542 // Complete the record type.
543 m_ast->StartTagDeclarationDefinition(compiler_type);
544 for (const CTFRecord::Field &field : ctf_record->fields) {
545 Type *field_type = ResolveTypeUID(field.type);
546 assert(field_type && "field must be complete");
547 const uint32_t field_size = field_type->GetByteSize(nullptr).value_or(0);
548 TypeSystemClang::AddFieldToRecordType(compiler_type, field.name,
549 field_type->GetFullCompilerType(),
550 eAccessPublic, field_size);
552 m_ast->CompleteTagDeclarationDefinition(compiler_type);
554 // Now that the compiler type is complete, we don't need to remember it
555 // anymore and can remove the CTF record type.
556 m_compiler_types.erase(compiler_type.GetOpaqueQualType());
557 m_ctf_types.erase(ctf_type->uid);
559 return true;
562 llvm::Expected<lldb::TypeSP>
563 SymbolFileCTF::CreateForward(const CTFForward &ctf_forward) {
564 CompilerType forward_compiler_type = m_ast->CreateRecordType(
565 nullptr, OptionalClangModuleID(), eAccessPublic, ctf_forward.name,
566 llvm::to_underlying(clang::TagTypeKind::Struct), eLanguageTypeC);
567 Declaration decl;
568 return MakeType(ctf_forward.uid, ConstString(ctf_forward.name), 0, nullptr,
569 LLDB_INVALID_UID, Type::eEncodingIsUID, decl,
570 forward_compiler_type, Type::ResolveState::Forward);
573 llvm::Expected<TypeSP> SymbolFileCTF::CreateType(CTFType *ctf_type) {
574 if (!ctf_type)
575 return llvm::make_error<llvm::StringError>(
576 "cannot create type for unparsed type", llvm::inconvertibleErrorCode());
578 switch (ctf_type->kind) {
579 case CTFType::Kind::eInteger:
580 return CreateInteger(*static_cast<CTFInteger *>(ctf_type));
581 case CTFType::Kind::eConst:
582 case CTFType::Kind::ePointer:
583 case CTFType::Kind::eRestrict:
584 case CTFType::Kind::eVolatile:
585 return CreateModifier(*static_cast<CTFModifier *>(ctf_type));
586 case CTFType::Kind::eTypedef:
587 return CreateTypedef(*static_cast<CTFTypedef *>(ctf_type));
588 case CTFType::Kind::eArray:
589 return CreateArray(*static_cast<CTFArray *>(ctf_type));
590 case CTFType::Kind::eEnum:
591 return CreateEnum(*static_cast<CTFEnum *>(ctf_type));
592 case CTFType::Kind::eFunction:
593 return CreateFunction(*static_cast<CTFFunction *>(ctf_type));
594 case CTFType::Kind::eStruct:
595 case CTFType::Kind::eUnion:
596 return CreateRecord(*static_cast<CTFRecord *>(ctf_type));
597 case CTFType::Kind::eForward:
598 return CreateForward(*static_cast<CTFForward *>(ctf_type));
599 case CTFType::Kind::eUnknown:
600 case CTFType::Kind::eFloat:
601 case CTFType::Kind::eSlice:
602 return llvm::make_error<llvm::StringError>(
603 llvm::formatv("unsupported type (uid = {0}, name = {1}, kind = {2})",
604 ctf_type->uid, ctf_type->name, ctf_type->kind),
605 llvm::inconvertibleErrorCode());
607 llvm_unreachable("Unexpected CTF type kind");
610 llvm::Expected<std::unique_ptr<CTFType>>
611 SymbolFileCTF::ParseType(lldb::offset_t &offset, lldb::user_id_t uid) {
612 ctf_stype_t ctf_stype;
613 ctf_stype.name = m_data.GetU32(&offset);
614 ctf_stype.info = m_data.GetU32(&offset);
615 ctf_stype.size = m_data.GetU32(&offset);
617 llvm::StringRef name = ReadString(ctf_stype.name);
618 const uint32_t kind = GetKind(ctf_stype.info);
619 const uint32_t variable_length = GetVLen(ctf_stype.info);
620 const uint32_t type = ctf_stype.GetType();
621 const uint32_t size = ctf_stype.GetSize();
623 switch (kind) {
624 case TypeKind::eInteger: {
625 const uint32_t vdata = m_data.GetU32(&offset);
626 const uint32_t bits = GetBits(vdata);
627 const uint32_t encoding = GetEncoding(vdata);
628 return std::make_unique<CTFInteger>(uid, name, bits, encoding);
630 case TypeKind::eConst:
631 return std::make_unique<CTFConst>(uid, type);
632 case TypeKind::ePointer:
633 return std::make_unique<CTFPointer>(uid, type);
634 case TypeKind::eRestrict:
635 return std::make_unique<CTFRestrict>(uid, type);
636 case TypeKind::eVolatile:
637 return std::make_unique<CTFVolatile>(uid, type);
638 case TypeKind::eTypedef:
639 return std::make_unique<CTFTypedef>(uid, name, type);
640 case TypeKind::eArray: {
641 const uint32_t type = m_data.GetU32(&offset);
642 const uint32_t index = m_data.GetU32(&offset);
643 const uint32_t nelems = m_data.GetU32(&offset);
644 return std::make_unique<CTFArray>(uid, name, type, index, nelems);
646 case TypeKind::eEnum: {
647 std::vector<CTFEnum::Value> values;
648 for (uint32_t i = 0; i < variable_length; ++i) {
649 const uint32_t value_name = m_data.GetU32(&offset);
650 const uint32_t value = m_data.GetU32(&offset);
651 values.emplace_back(ReadString(value_name), value);
653 return std::make_unique<CTFEnum>(uid, name, variable_length, size, values);
655 case TypeKind::eFunction: {
656 std::vector<uint32_t> args;
657 bool variadic = false;
658 for (uint32_t i = 0; i < variable_length; ++i) {
659 const uint32_t arg_uid = m_data.GetU32(&offset);
660 // If the last argument is 0, this is a variadic function.
661 if (arg_uid == 0) {
662 variadic = true;
663 break;
665 args.push_back(arg_uid);
667 // If the number of arguments is odd, a single uint32_t of padding is
668 // inserted to maintain alignment.
669 if (variable_length % 2 == 1)
670 m_data.GetU32(&offset);
671 return std::make_unique<CTFFunction>(uid, name, variable_length, type, args,
672 variadic);
674 case TypeKind::eStruct:
675 case TypeKind::eUnion: {
676 std::vector<CTFRecord::Field> fields;
677 for (uint32_t i = 0; i < variable_length; ++i) {
678 const uint32_t field_name = m_data.GetU32(&offset);
679 const uint32_t type = m_data.GetU32(&offset);
680 uint64_t field_offset = 0;
681 if (size < g_ctf_field_threshold) {
682 field_offset = m_data.GetU16(&offset);
683 m_data.GetU16(&offset); // Padding
684 } else {
685 const uint32_t offset_hi = m_data.GetU32(&offset);
686 const uint32_t offset_lo = m_data.GetU32(&offset);
687 field_offset = (((uint64_t)offset_hi) << 32) | ((uint64_t)offset_lo);
689 fields.emplace_back(ReadString(field_name), type, field_offset);
691 return std::make_unique<CTFRecord>(static_cast<CTFType::Kind>(kind), uid,
692 name, variable_length, size, fields);
694 case TypeKind::eForward:
695 return std::make_unique<CTFForward>(uid, name);
696 case TypeKind::eUnknown:
697 return std::make_unique<CTFType>(static_cast<CTFType::Kind>(kind), uid,
698 name);
699 case TypeKind::eFloat:
700 case TypeKind::eSlice:
701 offset += (variable_length * sizeof(uint32_t));
702 break;
705 return llvm::make_error<llvm::StringError>(
706 llvm::formatv("unsupported type (name = {0}, kind = {1}, vlength = {2})",
707 name, kind, variable_length),
708 llvm::inconvertibleErrorCode());
711 size_t SymbolFileCTF::ParseTypes(CompileUnit &cu) {
712 if (!ParseHeader())
713 return 0;
715 if (!m_types.empty())
716 return 0;
718 if (!m_ast)
719 return 0;
721 Log *log = GetLog(LLDBLog::Symbols);
722 LLDB_LOG(log, "Parsing CTF types");
724 lldb::offset_t type_offset = m_body_offset + m_header->typeoff;
725 const lldb::offset_t type_offset_end = m_body_offset + m_header->stroff;
727 lldb::user_id_t type_uid = 1;
728 while (type_offset < type_offset_end) {
729 llvm::Expected<std::unique_ptr<CTFType>> type_or_error =
730 ParseType(type_offset, type_uid);
731 if (type_or_error) {
732 m_ctf_types[(*type_or_error)->uid] = std::move(*type_or_error);
733 } else {
734 LLDB_LOG_ERROR(log, type_or_error.takeError(),
735 "Failed to parse type {1} at offset {2}: {0}", type_uid,
736 type_offset);
738 type_uid++;
741 LLDB_LOG(log, "Parsed {0} CTF types", m_ctf_types.size());
743 for (lldb::user_id_t uid = 1; uid < type_uid; ++uid)
744 ResolveTypeUID(uid);
746 LLDB_LOG(log, "Created {0} CTF types", m_types.size());
748 return m_types.size();
751 size_t SymbolFileCTF::ParseFunctions(CompileUnit &cu) {
752 if (!ParseHeader())
753 return 0;
755 if (!m_functions.empty())
756 return 0;
758 if (!m_ast)
759 return 0;
761 Symtab *symtab = GetObjectFile()->GetModule()->GetSymtab();
762 if (!symtab)
763 return 0;
765 Log *log = GetLog(LLDBLog::Symbols);
766 LLDB_LOG(log, "Parsing CTF functions");
768 lldb::offset_t function_offset = m_body_offset + m_header->funcoff;
769 const lldb::offset_t function_offset_end = m_body_offset + m_header->typeoff;
771 uint32_t symbol_idx = 0;
772 Declaration decl;
773 while (function_offset < function_offset_end) {
774 const uint32_t info = m_data.GetU32(&function_offset);
775 const uint16_t kind = GetKind(info);
776 const uint16_t variable_length = GetVLen(info);
778 Symbol *symbol = symtab->FindSymbolWithType(
779 eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, symbol_idx);
781 // Skip padding.
782 if (kind == TypeKind::eUnknown && variable_length == 0)
783 continue;
785 // Skip unexpected kinds.
786 if (kind != TypeKind::eFunction)
787 continue;
789 const uint32_t ret_uid = m_data.GetU32(&function_offset);
790 const uint32_t num_args = variable_length;
792 std::vector<CompilerType> arg_types;
793 arg_types.reserve(num_args);
795 bool is_variadic = false;
796 for (uint32_t i = 0; i < variable_length; i++) {
797 const uint32_t arg_uid = m_data.GetU32(&function_offset);
799 // If the last argument is 0, this is a variadic function.
800 if (arg_uid == 0) {
801 is_variadic = true;
802 break;
805 Type *arg_type = ResolveTypeUID(arg_uid);
806 arg_types.push_back(arg_type ? arg_type->GetFullCompilerType()
807 : CompilerType());
810 if (symbol) {
811 Type *ret_type = ResolveTypeUID(ret_uid);
812 AddressRange func_range =
813 AddressRange(symbol->GetFileAddress(), symbol->GetByteSize(),
814 GetObjectFile()->GetModule()->GetSectionList());
816 // Create function type.
817 CompilerType func_type = m_ast->CreateFunctionType(
818 ret_type ? ret_type->GetFullCompilerType() : CompilerType(),
819 arg_types.data(), arg_types.size(), is_variadic, 0,
820 clang::CallingConv::CC_C);
821 lldb::user_id_t function_type_uid = m_types.size() + 1;
822 TypeSP type_sp =
823 MakeType(function_type_uid, symbol->GetName(), 0, nullptr,
824 LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
825 lldb_private::Type::ResolveState::Full);
826 m_types[function_type_uid] = type_sp;
828 // Create function.
829 lldb::user_id_t func_uid = m_functions.size();
830 FunctionSP function_sp = std::make_shared<Function>(
831 &cu, func_uid, function_type_uid, symbol->GetMangled(), type_sp.get(),
832 AddressRanges{func_range});
833 m_functions.emplace_back(function_sp);
834 cu.AddFunction(function_sp);
838 LLDB_LOG(log, "CTF parsed {0} functions", m_functions.size());
840 return m_functions.size();
843 static DWARFExpression CreateDWARFExpression(ModuleSP module_sp,
844 const Symbol &symbol) {
845 if (!module_sp)
846 return DWARFExpression();
848 const ArchSpec &architecture = module_sp->GetArchitecture();
849 ByteOrder byte_order = architecture.GetByteOrder();
850 uint32_t address_size = architecture.GetAddressByteSize();
851 uint32_t byte_size = architecture.GetDataByteSize();
853 StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
854 stream.PutHex8(lldb_private::dwarf::DW_OP_addr);
855 stream.PutMaxHex64(symbol.GetFileAddress(), address_size, byte_order);
857 DataBufferSP buffer =
858 std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
859 lldb_private::DataExtractor extractor(buffer, byte_order, address_size,
860 byte_size);
861 DWARFExpression result(extractor);
862 result.SetRegisterKind(eRegisterKindDWARF);
864 return result;
867 size_t SymbolFileCTF::ParseObjects(CompileUnit &comp_unit) {
868 if (!ParseHeader())
869 return 0;
871 if (!m_variables.empty())
872 return 0;
874 if (!m_ast)
875 return 0;
877 ModuleSP module_sp = GetObjectFile()->GetModule();
878 Symtab *symtab = module_sp->GetSymtab();
879 if (!symtab)
880 return 0;
882 Log *log = GetLog(LLDBLog::Symbols);
883 LLDB_LOG(log, "Parsing CTF objects");
885 lldb::offset_t object_offset = m_body_offset + m_header->objtoff;
886 const lldb::offset_t object_offset_end = m_body_offset + m_header->funcoff;
888 uint32_t symbol_idx = 0;
889 Declaration decl;
890 while (object_offset < object_offset_end) {
891 const uint32_t type_uid = m_data.GetU32(&object_offset);
893 if (Symbol *symbol =
894 symtab->FindSymbolWithType(eSymbolTypeData, Symtab::eDebugYes,
895 Symtab::eVisibilityAny, symbol_idx)) {
896 Variable::RangeList ranges;
897 ranges.Append(symbol->GetFileAddress(), symbol->GetByteSize());
899 auto type_sp = std::make_shared<SymbolFileType>(*this, type_uid);
901 DWARFExpressionList location(
902 module_sp, CreateDWARFExpression(module_sp, *symbol), nullptr);
904 lldb::user_id_t variable_type_uid = m_variables.size();
905 m_variables.emplace_back(std::make_shared<Variable>(
906 variable_type_uid, symbol->GetName().AsCString(),
907 symbol->GetName().AsCString(), type_sp, eValueTypeVariableGlobal,
908 m_comp_unit_sp.get(), ranges, &decl, location, symbol->IsExternal(),
909 /*artificial=*/false,
910 /*location_is_constant_data*/ false));
914 LLDB_LOG(log, "Parsed {0} CTF objects", m_variables.size());
916 return m_variables.size();
919 uint32_t SymbolFileCTF::CalculateAbilities() {
920 if (!m_objfile_sp)
921 return 0;
923 if (!ParseHeader())
924 return 0;
926 return VariableTypes | Functions | GlobalVariables;
929 uint32_t SymbolFileCTF::ResolveSymbolContext(const Address &so_addr,
930 SymbolContextItem resolve_scope,
931 SymbolContext &sc) {
932 std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
933 if (m_objfile_sp->GetSymtab() == nullptr)
934 return 0;
936 uint32_t resolved_flags = 0;
938 // Resolve symbols.
939 if (resolve_scope & eSymbolContextSymbol) {
940 sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
941 so_addr.GetFileAddress());
942 if (sc.symbol)
943 resolved_flags |= eSymbolContextSymbol;
946 // Resolve functions.
947 if (resolve_scope & eSymbolContextFunction) {
948 for (FunctionSP function_sp : m_functions) {
949 if (function_sp->GetAddressRange().ContainsFileAddress(
950 so_addr.GetFileAddress())) {
951 sc.function = function_sp.get();
952 resolved_flags |= eSymbolContextFunction;
953 break;
958 // Resolve variables.
959 if (resolve_scope & eSymbolContextVariable) {
960 for (VariableSP variable_sp : m_variables) {
961 if (variable_sp->LocationIsValidForAddress(so_addr.GetFileAddress())) {
962 sc.variable = variable_sp.get();
963 break;
968 return resolved_flags;
971 CompUnitSP SymbolFileCTF::ParseCompileUnitAtIndex(uint32_t idx) {
972 if (idx == 0)
973 return m_comp_unit_sp;
974 return {};
977 size_t
978 SymbolFileCTF::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
979 return ParseObjects(*m_comp_unit_sp);
982 void SymbolFileCTF::AddSymbols(Symtab &symtab) {
983 // CTF does not encode symbols.
984 // We rely on the existing symbol table to map symbols to type.
987 lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
988 auto type_it = m_types.find(type_uid);
989 if (type_it != m_types.end())
990 return type_it->second.get();
992 auto ctf_type_it = m_ctf_types.find(type_uid);
993 if (ctf_type_it == m_ctf_types.end())
994 return nullptr;
996 CTFType *ctf_type = ctf_type_it->second.get();
997 assert(ctf_type && "m_ctf_types should only contain valid CTF types");
999 Log *log = GetLog(LLDBLog::Symbols);
1001 llvm::Expected<TypeSP> type_or_error = CreateType(ctf_type);
1002 if (!type_or_error) {
1003 LLDB_LOG_ERROR(log, type_or_error.takeError(),
1004 "Failed to create type for {1}: {0}", ctf_type->uid);
1005 return {};
1008 TypeSP type_sp = *type_or_error;
1010 if (log) {
1011 StreamString ss;
1012 type_sp->Dump(&ss, true);
1013 LLDB_LOGV(log, "Adding type {0}: {1}", type_sp->GetID(),
1014 llvm::StringRef(ss.GetString()).rtrim());
1017 m_types[type_uid] = type_sp;
1019 // Except for record types which we'll need to complete later, we don't need
1020 // the CTF type anymore.
1021 if (!isa<CTFRecord>(ctf_type))
1022 m_ctf_types.erase(type_uid);
1024 return type_sp.get();
1027 void SymbolFileCTF::FindTypes(const lldb_private::TypeQuery &match,
1028 lldb_private::TypeResults &results) {
1029 // Make sure we haven't already searched this SymbolFile before.
1030 if (results.AlreadySearched(this))
1031 return;
1033 ConstString name = match.GetTypeBasename();
1034 for (TypeSP type_sp : GetTypeList().Types()) {
1035 if (type_sp && type_sp->GetName() == name) {
1036 results.InsertUnique(type_sp);
1037 if (results.Done(match))
1038 return;
1043 void SymbolFileCTF::FindTypesByRegex(
1044 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1045 lldb_private::TypeMap &types) {
1046 ParseTypes(*m_comp_unit_sp);
1048 size_t matches = 0;
1049 for (TypeSP type_sp : GetTypeList().Types()) {
1050 if (matches == max_matches)
1051 break;
1052 if (type_sp && regex.Execute(type_sp->GetName()))
1053 types.Insert(type_sp);
1054 matches++;
1058 void SymbolFileCTF::FindFunctions(
1059 const lldb_private::Module::LookupInfo &lookup_info,
1060 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1061 bool include_inlines, lldb_private::SymbolContextList &sc_list) {
1062 ParseFunctions(*m_comp_unit_sp);
1064 ConstString name = lookup_info.GetLookupName();
1065 for (FunctionSP function_sp : m_functions) {
1066 if (function_sp && function_sp->GetName() == name) {
1067 lldb_private::SymbolContext sc;
1068 sc.comp_unit = m_comp_unit_sp.get();
1069 sc.function = function_sp.get();
1070 sc_list.Append(sc);
1075 void SymbolFileCTF::FindFunctions(const lldb_private::RegularExpression &regex,
1076 bool include_inlines,
1077 lldb_private::SymbolContextList &sc_list) {
1078 for (FunctionSP function_sp : m_functions) {
1079 if (function_sp && regex.Execute(function_sp->GetName())) {
1080 lldb_private::SymbolContext sc;
1081 sc.comp_unit = m_comp_unit_sp.get();
1082 sc.function = function_sp.get();
1083 sc_list.Append(sc);
1088 void SymbolFileCTF::FindGlobalVariables(
1089 lldb_private::ConstString name,
1090 const lldb_private::CompilerDeclContext &parent_decl_ctx,
1091 uint32_t max_matches, lldb_private::VariableList &variables) {
1092 ParseObjects(*m_comp_unit_sp);
1094 size_t matches = 0;
1095 for (VariableSP variable_sp : m_variables) {
1096 if (matches == max_matches)
1097 break;
1098 if (variable_sp && variable_sp->GetName() == name) {
1099 variables.AddVariable(variable_sp);
1100 matches++;
1105 void SymbolFileCTF::FindGlobalVariables(
1106 const lldb_private::RegularExpression &regex, uint32_t max_matches,
1107 lldb_private::VariableList &variables) {
1108 ParseObjects(*m_comp_unit_sp);
1110 size_t matches = 0;
1111 for (VariableSP variable_sp : m_variables) {
1112 if (matches == max_matches)
1113 break;
1114 if (variable_sp && regex.Execute(variable_sp->GetName())) {
1115 variables.AddVariable(variable_sp);
1116 matches++;