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