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/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"
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() {
76 Log
*log
= GetLog(LLDBLog::Symbols
);
78 ModuleSP
module_sp(m_objfile_sp
->GetModule());
79 const SectionList
*section_list
= module_sp
->GetSectionList();
84 section_list
->FindSectionByType(lldb::eSectionTypeCTF
, true));
88 m_objfile_sp
->ReadSectionData(section_sp
.get(), m_data
);
90 if (m_data
.GetByteSize() == 0)
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;
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");
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
);
129 if (ctf_header
.preamble
.version
!= g_ctf_version
) {
130 LLDB_LOG(log
, "CTF parsing failed: unsupported version: {0}",
131 ctf_header
.preamble
.version
);
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.
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);
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
);
154 (Bytef
*)const_cast<uint8_t *>(decompressed_data
->GetBytes());
155 zstr
.avail_out
= decompressed_size
;
157 int rc
= inflateInit(&zstr
);
159 LLDB_LOG(log
, "CTF parsing failed: inflate initialization error: {0}",
164 rc
= inflate(&zstr
, Z_FINISH
);
165 if (rc
!= Z_STREAM_END
) {
166 LLDB_LOG(log
, "CTF parsing failed: inflate error: {0}", zError(rc
));
170 rc
= inflateEnd(&zstr
);
172 LLDB_LOG(log
, "CTF parsing failed: inflate end error: {0}", zError(rc
));
176 if (zstr
.total_out
!= decompressed_size
) {
178 "CTF parsing failed: decompressed size ({0}) doesn't match "
179 "expected size ([1})",
180 zstr
.total_out
, decompressed_size
);
184 m_data
= DataExtractor(decompressed_data
, m_data
.GetByteOrder(),
185 m_data
.GetAddressByteSize());
190 "CTF parsing failed: data is compressed but no zlib inflate support");
195 // Validate the header.
196 if (!m_data
.ValidOffset(m_body_offset
+ ctf_header
.lbloff
)) {
198 "CTF parsing failed: invalid label section offset in header: {0}",
203 if (!m_data
.ValidOffset(m_body_offset
+ ctf_header
.objtoff
)) {
205 "CTF parsing failed: invalid object section offset in header: {0}",
210 if (!m_data
.ValidOffset(m_body_offset
+ ctf_header
.funcoff
)) {
213 "CTF parsing failed: invalid function section offset in header: {0}",
218 if (!m_data
.ValidOffset(m_body_offset
+ ctf_header
.typeoff
)) {
220 "CTF parsing failed: invalid type section offset in header: {0}",
225 if (!m_data
.ValidOffset(m_body_offset
+ ctf_header
.stroff
)) {
227 "CTF parsing failed: invalid string section offset in header: {0}",
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)) {
236 "CTF parsing failed: invalid string section length in header: {0}",
241 if (m_body_offset
+ ctf_header
.stroff
+ ctf_header
.parlabel
>
244 "CTF parsing failed: invalid parent label offset: {0} exceeds end "
245 "of string section ({1})",
246 ctf_header
.parlabel
, str_end_offset
);
250 if (m_body_offset
+ ctf_header
.stroff
+ ctf_header
.parname
> str_end_offset
) {
252 "CTF parsing failed: invalid parent name offset: {0} exceeds end "
253 "of string section ({1})",
254 ctf_header
.parname
, str_end_offset
);
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
);
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}");
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
))
289 const char *str
= m_data
.GetCStr(&offset
);
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
) {
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
) {
319 static uint32_t GetBytes(uint32_t bits
) { return bits
/ sizeof(unsigned); }
321 static clang::TagTypeKind
TranslateRecordKind(CTFType::Kind type
) {
323 case CTFType::Kind::eStruct
:
324 return clang::TagTypeKind::Struct
;
325 case CTFType::Kind::eUnion
:
326 return clang::TagTypeKind::Union
;
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 "
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
>(
352 "Found compiler type for '{0}' but it's not an integer type: {1}",
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}",
364 compiler_type_is_signed
? "signed" : "unsigned",
365 type_is_signed
? "signed" : "unsigned"),
366 llvm::inconvertibleErrorCode());
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
);
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();
390 case CTFType::eConst
:
391 compiler_type
= ref_type
->GetFullCompilerType().AddConstModifier();
393 case CTFType::eVolatile
:
394 compiler_type
= ref_type
->GetFullCompilerType().AddVolatileModifier();
396 case CTFType::eRestrict
:
397 compiler_type
= ref_type
->GetFullCompilerType().AddRestrictModifier();
400 return llvm::make_error
<llvm::StringError
>(
401 llvm::formatv("ParseModifier called with unsupported kind: {0}",
403 llvm::inconvertibleErrorCode());
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}",
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);
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
);
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);
442 return llvm::make_error
<llvm::StringError
>(
443 llvm::formatv("could not get element size of type: {0}",
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);
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
) {
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
);
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
);
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
;
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())
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
);
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
);
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
);
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
) {
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();
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.
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
,
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
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
,
699 case TypeKind::eFloat
:
700 case TypeKind::eSlice
:
701 offset
+= (variable_length
* sizeof(uint32_t));
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
) {
715 if (!m_types
.empty())
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
);
732 m_ctf_types
[(*type_or_error
)->uid
] = std::move(*type_or_error
);
734 LLDB_LOG_ERROR(log
, type_or_error
.takeError(),
735 "Failed to parse type {1} at offset {2}: {0}", 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
)
746 LLDB_LOG(log
, "Created {0} CTF types", m_types
.size());
748 return m_types
.size();
751 size_t SymbolFileCTF::ParseFunctions(CompileUnit
&cu
) {
755 if (!m_functions
.empty())
761 Symtab
*symtab
= GetObjectFile()->GetModule()->GetSymtab();
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;
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
);
782 if (kind
== TypeKind::eUnknown
&& variable_length
== 0)
785 // Skip unexpected kinds.
786 if (kind
!= TypeKind::eFunction
)
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.
805 Type
*arg_type
= ResolveTypeUID(arg_uid
);
806 arg_types
.push_back(arg_type
? arg_type
->GetFullCompilerType()
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;
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
;
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
) {
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
,
861 DWARFExpression
result(extractor
);
862 result
.SetRegisterKind(eRegisterKindDWARF
);
867 size_t SymbolFileCTF::ParseObjects(CompileUnit
&comp_unit
) {
871 if (!m_variables
.empty())
877 ModuleSP module_sp
= GetObjectFile()->GetModule();
878 Symtab
*symtab
= module_sp
->GetSymtab();
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;
890 while (object_offset
< object_offset_end
) {
891 const uint32_t type_uid
= m_data
.GetU32(&object_offset
);
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() {
926 return VariableTypes
| Functions
| GlobalVariables
;
929 uint32_t SymbolFileCTF::ResolveSymbolContext(const Address
&so_addr
,
930 SymbolContextItem resolve_scope
,
932 std::lock_guard
<std::recursive_mutex
> guard(GetModuleMutex());
933 if (m_objfile_sp
->GetSymtab() == nullptr)
936 uint32_t resolved_flags
= 0;
939 if (resolve_scope
& eSymbolContextSymbol
) {
940 sc
.symbol
= m_objfile_sp
->GetSymtab()->FindSymbolContainingFileAddress(
941 so_addr
.GetFileAddress());
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
;
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();
968 return resolved_flags
;
971 CompUnitSP
SymbolFileCTF::ParseCompileUnitAtIndex(uint32_t idx
) {
973 return m_comp_unit_sp
;
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())
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
);
1008 TypeSP type_sp
= *type_or_error
;
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))
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
))
1043 void SymbolFileCTF::FindTypesByRegex(
1044 const lldb_private::RegularExpression
®ex
, uint32_t max_matches
,
1045 lldb_private::TypeMap
&types
) {
1046 ParseTypes(*m_comp_unit_sp
);
1049 for (TypeSP type_sp
: GetTypeList().Types()) {
1050 if (matches
== max_matches
)
1052 if (type_sp
&& regex
.Execute(type_sp
->GetName()))
1053 types
.Insert(type_sp
);
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();
1075 void SymbolFileCTF::FindFunctions(const lldb_private::RegularExpression
®ex
,
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();
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
);
1095 for (VariableSP variable_sp
: m_variables
) {
1096 if (matches
== max_matches
)
1098 if (variable_sp
&& variable_sp
->GetName() == name
) {
1099 variables
.AddVariable(variable_sp
);
1105 void SymbolFileCTF::FindGlobalVariables(
1106 const lldb_private::RegularExpression
®ex
, uint32_t max_matches
,
1107 lldb_private::VariableList
&variables
) {
1108 ParseObjects(*m_comp_unit_sp
);
1111 for (VariableSP variable_sp
: m_variables
) {
1112 if (matches
== max_matches
)
1114 if (variable_sp
&& regex
.Execute(variable_sp
->GetName())) {
1115 variables
.AddVariable(variable_sp
);