1 //===-- SymbolFileCTF.cpp ----------------------------------------------===//
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
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"
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() {
75 Log
*log
= GetLog(LLDBLog::Symbols
);
77 ModuleSP
module_sp(m_objfile_sp
->GetModule());
78 const SectionList
*section_list
= module_sp
->GetSectionList();
83 section_list
->FindSectionByType(lldb::eSectionTypeCTF
, true));
87 m_objfile_sp
->ReadSectionData(section_sp
.get(), m_data
);
89 if (m_data
.GetByteSize() == 0)
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;
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");
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
);
128 if (ctf_header
.preamble
.version
!= g_ctf_version
) {
129 LLDB_LOG(log
, "CTF parsing failed: unsupported version: {0}",
130 ctf_header
.preamble
.version
);
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.
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);
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
);
153 (Bytef
*)const_cast<uint8_t *>(decompressed_data
->GetBytes());
154 zstr
.avail_out
= decompressed_size
;
156 int rc
= inflateInit(&zstr
);
158 LLDB_LOG(log
, "CTF parsing failed: inflate initialization error: {0}",
163 rc
= inflate(&zstr
, Z_FINISH
);
164 if (rc
!= Z_STREAM_END
) {
165 LLDB_LOG(log
, "CTF parsing failed: inflate error: {0}", zError(rc
));
169 rc
= inflateEnd(&zstr
);
171 LLDB_LOG(log
, "CTF parsing failed: inflate end error: {0}", zError(rc
));
175 if (zstr
.total_out
!= decompressed_size
) {
177 "CTF parsing failed: decompressed size ({0}) doesn't match "
178 "expected size ([1})",
179 zstr
.total_out
, decompressed_size
);
183 m_data
= DataExtractor(decompressed_data
, m_data
.GetByteOrder(),
184 m_data
.GetAddressByteSize());
189 "CTF parsing failed: data is compressed but no zlib inflate support");
194 // Validate the header.
195 if (!m_data
.ValidOffset(m_body_offset
+ ctf_header
.lbloff
)) {
197 "CTF parsing failed: invalid label section offset in header: {0}",
202 if (!m_data
.ValidOffset(m_body_offset
+ ctf_header
.objtoff
)) {
204 "CTF parsing failed: invalid object section offset in header: {0}",
209 if (!m_data
.ValidOffset(m_body_offset
+ ctf_header
.funcoff
)) {
212 "CTF parsing failed: invalid function section offset in header: {0}",
217 if (!m_data
.ValidOffset(m_body_offset
+ ctf_header
.typeoff
)) {
219 "CTF parsing failed: invalid type section offset in header: {0}",
224 if (!m_data
.ValidOffset(m_body_offset
+ ctf_header
.stroff
)) {
226 "CTF parsing failed: invalid string section offset in header: {0}",
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)) {
235 "CTF parsing failed: invalid string section length in header: {0}",
240 if (m_body_offset
+ ctf_header
.stroff
+ ctf_header
.parlabel
>
243 "CTF parsing failed: invalid parent label offset: {0} exceeds end "
244 "of string section ({1})",
245 ctf_header
.parlabel
, str_end_offset
);
249 if (m_body_offset
+ ctf_header
.stroff
+ ctf_header
.parname
> str_end_offset
) {
251 "CTF parsing failed: invalid parent name offset: {0} exceeds end "
252 "of string section ({1})",
253 ctf_header
.parname
, str_end_offset
);
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
);
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}");
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
))
288 const char *str
= m_data
.GetCStr(&offset
);
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
) {
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
) {
318 static uint32_t GetBytes(uint32_t bits
) { return bits
/ sizeof(unsigned); }
320 static clang::TagTypeKind
TranslateRecordKind(CTFType::Kind type
) {
322 case CTFType::Kind::eStruct
:
323 return clang::TTK_Struct
;
324 case CTFType::Kind::eUnion
:
325 return clang::TTK_Union
;
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 "
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
>(
351 "Found compiler type for '{0}' but it's not an integer type: {1}",
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}",
363 compiler_type_is_signed
? "signed" : "unsigned",
364 type_is_signed
? "signed" : "unsigned"),
365 llvm::inconvertibleErrorCode());
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
);
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();
389 case CTFType::eConst
:
390 compiler_type
= ref_type
->GetFullCompilerType().AddConstModifier();
392 case CTFType::eVolatile
:
393 compiler_type
= ref_type
->GetFullCompilerType().AddVolatileModifier();
395 case CTFType::eRestrict
:
396 compiler_type
= ref_type
->GetFullCompilerType().AddRestrictModifier();
399 return llvm::make_error
<llvm::StringError
>(
400 llvm::formatv("ParseModifier called with unsupported kind: {0}",
402 llvm::inconvertibleErrorCode());
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}",
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);
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
);
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);
441 return llvm::make_error
<llvm::StringError
>(
442 llvm::formatv("could not get element size of type: {0}",
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);
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
) {
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
);
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
);
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
;
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())
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
);
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
);
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
);
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
) {
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();
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.
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
,
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
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
,
697 case TypeKind::eFloat
:
698 case TypeKind::eSlice
:
699 offset
+= (variable_length
* sizeof(uint32_t));
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
) {
713 if (!m_types
.empty())
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
);
730 m_ctf_types
[(*type_or_error
)->uid
] = std::move(*type_or_error
);
732 LLDB_LOG_ERROR(log
, type_or_error
.takeError(),
733 "Failed to parse type {1} at offset {2}: {0}", 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
)
744 LLDB_LOG(log
, "Created {0} CTF types", m_types
.size());
746 return m_types
.size();
749 size_t SymbolFileCTF::ParseFunctions(CompileUnit
&cu
) {
753 if (!m_functions
.empty())
759 Symtab
*symtab
= GetObjectFile()->GetModule()->GetSymtab();
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;
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
);
780 if (kind
== TypeKind::eUnknown
&& variable_length
== 0)
783 // Skip unexpected kinds.
784 if (kind
!= TypeKind::eFunction
)
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.
803 Type
*arg_type
= ResolveTypeUID(arg_uid
);
804 arg_types
.push_back(arg_type
->GetFullCompilerType());
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;
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
;
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(),
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
) {
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
,
857 DWARFExpression
result(extractor
);
858 result
.SetRegisterKind(eRegisterKindDWARF
);
863 size_t SymbolFileCTF::ParseObjects(CompileUnit
&comp_unit
) {
867 if (!m_variables
.empty())
873 ModuleSP module_sp
= GetObjectFile()->GetModule();
874 Symtab
*symtab
= module_sp
->GetSymtab();
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;
886 while (object_offset
< object_offset_end
) {
887 const uint32_t type_uid
= m_data
.GetU32(&object_offset
);
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() {
922 return VariableTypes
| Functions
| GlobalVariables
;
925 uint32_t SymbolFileCTF::ResolveSymbolContext(const Address
&so_addr
,
926 SymbolContextItem resolve_scope
,
928 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
929 if (m_objfile_sp
->GetSymtab() == nullptr)
932 uint32_t resolved_flags
= 0;
935 if (resolve_scope
& eSymbolContextSymbol
) {
936 sc
.symbol
= m_objfile_sp
->GetSymtab()->FindSymbolContainingFileAddress(
937 so_addr
.GetFileAddress());
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
;
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();
964 return resolved_flags
;
967 CompUnitSP
SymbolFileCTF::ParseCompileUnitAtIndex(uint32_t idx
) {
969 return m_comp_unit_sp
;
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())
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
);
1004 TypeSP type_sp
= *type_or_error
;
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);
1034 for (TypeSP type_sp
: GetTypeList().Types()) {
1035 if (matches
== max_matches
)
1037 if (type_sp
&& type_sp
->GetName() == name
) {
1038 types
.Insert(type_sp
);
1044 void SymbolFileCTF::FindTypesByRegex(
1045 const lldb_private::RegularExpression
®ex
, uint32_t max_matches
,
1046 lldb_private::TypeMap
&types
) {
1047 ParseTypes(*m_comp_unit_sp
);
1050 for (TypeSP type_sp
: GetTypeList().Types()) {
1051 if (matches
== max_matches
)
1053 if (type_sp
&& regex
.Execute(type_sp
->GetName()))
1054 types
.Insert(type_sp
);
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();
1076 void SymbolFileCTF::FindFunctions(const lldb_private::RegularExpression
®ex
,
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();
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
);
1096 for (VariableSP variable_sp
: m_variables
) {
1097 if (matches
== max_matches
)
1099 if (variable_sp
&& variable_sp
->GetName() == name
) {
1100 variables
.AddVariable(variable_sp
);
1106 void SymbolFileCTF::FindGlobalVariables(
1107 const lldb_private::RegularExpression
®ex
, uint32_t max_matches
,
1108 lldb_private::VariableList
&variables
) {
1109 ParseObjects(*m_comp_unit_sp
);
1112 for (VariableSP variable_sp
: m_variables
) {
1113 if (matches
== max_matches
)
1115 if (variable_sp
&& regex
.Execute(variable_sp
->GetName())) {
1116 variables
.AddVariable(variable_sp
);