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/Core/StreamBuffer.h"
14 #include "lldb/Host/Config.h"
15 #include "lldb/Symbol/CompileUnit.h"
16 #include "lldb/Symbol/Function.h"
17 #include "lldb/Symbol/ObjectFile.h"
18 #include "lldb/Symbol/Symbol.h"
19 #include "lldb/Symbol/SymbolContext.h"
20 #include "lldb/Symbol/Symtab.h"
21 #include "lldb/Symbol/TypeList.h"
22 #include "lldb/Symbol/TypeMap.h"
23 #include "lldb/Symbol/Variable.h"
24 #include "lldb/Symbol/VariableList.h"
25 #include "lldb/Utility/DataExtractor.h"
26 #include "lldb/Utility/LLDBLog.h"
27 #include "lldb/Utility/Log.h"
28 #include "lldb/Utility/RegularExpression.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 
51 SymbolFileCTF::SymbolFileCTF(lldb::ObjectFileSP objfile_sp)
52     : SymbolFileCommon(std::move(objfile_sp)) {}
53 
54 void SymbolFileCTF::Initialize() {
55   PluginManager::RegisterPlugin(GetPluginNameStatic(),
56                                 GetPluginDescriptionStatic(), CreateInstance);
57 }
58 
59 void SymbolFileCTF::Terminate() {
60   PluginManager::UnregisterPlugin(CreateInstance);
61 }
62 
63 llvm::StringRef SymbolFileCTF::GetPluginDescriptionStatic() {
64   return "Compact C Type Format Symbol Reader";
65 }
66 
67 SymbolFile *SymbolFileCTF::CreateInstance(ObjectFileSP objfile_sp) {
68   return new SymbolFileCTF(std::move(objfile_sp));
69 }
70 
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 
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 
284 llvm::StringRef SymbolFileCTF::ReadString(lldb::offset_t str_offset) const {
285   lldb::offset_t offset = m_body_offset + m_header->stroff + str_offset;
286   if (!m_data.ValidOffset(offset))
287     return "(invalid)";
288   const char *str = m_data.GetCStr(&offset);
289   if (str && !*str)
290     return "(anon)";
291   return llvm::StringRef(str);
292 }
293 
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;
298 }
299 
300 /// Return the integral width in bits encoded in the given data.
301 static uint32_t GetBits(uint32_t data) {
302   // Mask bits 0-15.
303   return (data)&0x0000ffff;
304 }
305 
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;
310 }
311 
312 /// Return the variable length encoded in the given data.
313 uint32_t GetVLen(uint32_t data) {
314   // Mask bits 0–24.
315   return (data)&0x3ff;
316 }
317 
318 static uint32_t GetBytes(uint32_t bits) { return bits / sizeof(unsigned); }
319 
320 static clang::TagTypeKind TranslateRecordKind(SymbolFileCTF::TypeKind type) {
321   switch (type) {
322   case SymbolFileCTF::TypeKind::eStruct:
323     return clang::TTK_Struct;
324   case SymbolFileCTF::TypeKind::eUnion:
325     return clang::TTK_Union;
326   default:
327     lldbassert(false && "Invalid record kind!");
328     return clang::TTK_Struct;
329   }
330 }
331 
332 llvm::Expected<TypeSP> SymbolFileCTF::ParseInteger(lldb::offset_t &offset,
333                                                    lldb::user_id_t uid,
334                                                    llvm::StringRef name) {
335   const uint32_t vdata = m_data.GetU32(&offset);
336   const uint32_t bits = GetBits(vdata);
337   const uint32_t encoding = GetEncoding(vdata);
338 
339   lldb::BasicType basic_type = TypeSystemClang::GetBasicTypeEnumeration(name);
340   if (basic_type == eBasicTypeInvalid)
341     return llvm::make_error<llvm::StringError>(
342         llvm::formatv("unsupported integer type: no corresponding basic clang "
343                       "type for '{0}'",
344                       name),
345         llvm::inconvertibleErrorCode());
346 
347   CompilerType compiler_type = m_ast->GetBasicType(basic_type);
348 
349   if (basic_type != eBasicTypeVoid) {
350     // Make sure the type we got is an integer type.
351     bool compiler_type_is_signed = false;
352     if (!compiler_type.IsIntegerType(compiler_type_is_signed))
353       return llvm::make_error<llvm::StringError>(
354           llvm::formatv(
355               "Found compiler type for '{0}' but it's not an integer type: {1}",
356               name, compiler_type.GetDisplayTypeName().GetStringRef()),
357           llvm::inconvertibleErrorCode());
358 
359     // Make sure the signing matches between the CTF and the compiler type.
360     const bool type_is_signed = (encoding & IntEncoding::eSigned);
361     if (compiler_type_is_signed != type_is_signed)
362       return llvm::make_error<llvm::StringError>(
363           llvm::formatv("Found integer compiler type for {0} but compiler type "
364                         "is {1} and {0} is {2}",
365                         name, compiler_type_is_signed ? "signed" : "unsigned",
366                         type_is_signed ? "signed" : "unsigned"),
367           llvm::inconvertibleErrorCode());
368   }
369 
370   Declaration decl;
371   return MakeType(uid, ConstString(name), GetBytes(bits), nullptr,
372                   LLDB_INVALID_UID, lldb_private::Type::eEncodingIsUID, decl,
373                   compiler_type, lldb_private::Type::ResolveState::Full);
374 }
375 
376 llvm::Expected<lldb::TypeSP>
377 SymbolFileCTF::ParseModifierType(lldb::offset_t &offset, lldb::user_id_t uid,
378                                  uint32_t kind, uint32_t type) {
379   TypeSP ref_type = GetTypeForUID(type);
380   if (!ref_type)
381     return llvm::make_error<llvm::StringError>(
382         llvm::formatv("Could not find modified type: {0}", type),
383         llvm::inconvertibleErrorCode());
384 
385   CompilerType compiler_type;
386 
387   switch (kind) {
388   case TypeKind::ePointer:
389     compiler_type = ref_type->GetFullCompilerType().GetPointerType();
390     break;
391   case TypeKind::eConst:
392     compiler_type = ref_type->GetFullCompilerType().AddConstModifier();
393     break;
394   case TypeKind::eVolatile:
395     compiler_type = ref_type->GetFullCompilerType().AddVolatileModifier();
396     break;
397   case TypeKind::eRestrict:
398     compiler_type = ref_type->GetFullCompilerType().AddRestrictModifier();
399     break;
400   default:
401     return llvm::make_error<llvm::StringError>(
402         llvm::formatv("ParseModifierType called with unsupported kind: {0}",
403                       kind),
404         llvm::inconvertibleErrorCode());
405   }
406 
407   Declaration decl;
408   return MakeType(uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
409                   Type::eEncodingIsUID, decl, compiler_type,
410                   lldb_private::Type::ResolveState::Full);
411 }
412 
413 llvm::Expected<lldb::TypeSP> SymbolFileCTF::ParseTypedef(lldb::offset_t &offset,
414                                                          lldb::user_id_t uid,
415                                                          llvm::StringRef name,
416                                                          uint32_t type) {
417   TypeSP underlying_type = GetTypeForUID(type);
418   if (!underlying_type)
419     return llvm::make_error<llvm::StringError>(
420         llvm::formatv("Could not find typedef underlying type: {0}", type),
421         llvm::inconvertibleErrorCode());
422 
423   CompilerType target_ast_type = underlying_type->GetFullCompilerType();
424   clang::DeclContext *decl_ctx = m_ast->GetTranslationUnitDecl();
425   CompilerType ast_typedef = target_ast_type.CreateTypedef(
426       name.data(), m_ast->CreateDeclContext(decl_ctx), 0);
427 
428   Declaration decl;
429   return MakeType(uid, ConstString(name), 0, nullptr, LLDB_INVALID_UID,
430                   lldb_private::Type::eEncodingIsUID, decl, ast_typedef,
431                   lldb_private::Type::ResolveState::Full);
432 }
433 
434 llvm::Expected<lldb::TypeSP> SymbolFileCTF::ParseArray(lldb::offset_t &offset,
435                                                        lldb::user_id_t uid,
436                                                        llvm::StringRef name) {
437   ctf_array_t ctf_array;
438   ctf_array.contents = m_data.GetU32(&offset);
439   ctf_array.index = m_data.GetU32(&offset);
440   ctf_array.nelems = m_data.GetU32(&offset);
441 
442   TypeSP element_type = GetTypeForUID(ctf_array.contents);
443   if (!element_type)
444     return llvm::make_error<llvm::StringError>(
445         llvm::formatv("Could not find array element type: {0}",
446                       ctf_array.contents),
447         llvm::inconvertibleErrorCode());
448 
449   std::optional<uint64_t> element_size = element_type->GetByteSize(nullptr);
450   if (!element_size)
451     return llvm::make_error<llvm::StringError>(
452         llvm::formatv("could not get element size of type: {0}",
453                       ctf_array.contents),
454         llvm::inconvertibleErrorCode());
455 
456   uint64_t size = ctf_array.nelems * *element_size;
457 
458   CompilerType compiler_type = m_ast->CreateArrayType(
459       element_type->GetFullCompilerType(), ctf_array.nelems,
460       /*is_gnu_vector*/ false);
461 
462   Declaration decl;
463   return MakeType(uid, ConstString(), size, nullptr, LLDB_INVALID_UID,
464                   Type::eEncodingIsUID, decl, compiler_type,
465                   lldb_private::Type::ResolveState::Full);
466 }
467 
468 llvm::Expected<lldb::TypeSP> SymbolFileCTF::ParseEnum(lldb::offset_t &offset,
469                                                       lldb::user_id_t uid,
470                                                       llvm::StringRef name,
471                                                       uint32_t elements,
472                                                       uint32_t size) {
473   Declaration decl;
474   CompilerType enum_type = m_ast->CreateEnumerationType(
475       name, m_ast->GetTranslationUnitDecl(), OptionalClangModuleID(), decl,
476       m_ast->GetBasicType(eBasicTypeInt),
477       /*is_scoped=*/false);
478 
479   for (uint32_t i = 0; i < elements; ++i) {
480     ctf_enum_t ctf_enum;
481     ctf_enum.name = m_data.GetU32(&offset);
482     ctf_enum.value = m_data.GetU32(&offset);
483 
484     llvm::StringRef value_name = ReadString(ctf_enum.name);
485     const uint32_t value = ctf_enum.value;
486 
487     Declaration value_decl;
488     m_ast->AddEnumerationValueToEnumerationType(enum_type, value_decl,
489                                                 value_name.data(), value, size);
490   }
491 
492   return MakeType(uid, ConstString(), 0, nullptr, LLDB_INVALID_UID,
493                   Type::eEncodingIsUID, decl, enum_type,
494                   lldb_private::Type::ResolveState::Full);
495 }
496 
497 llvm::Expected<lldb::TypeSP>
498 SymbolFileCTF::ParseFunction(lldb::offset_t &offset, lldb::user_id_t uid,
499                              llvm::StringRef name, uint32_t num_args,
500                              uint32_t type) {
501   std::vector<CompilerType> arg_types;
502   arg_types.reserve(num_args);
503 
504   bool is_variadic = false;
505   for (uint32_t i = 0; i < num_args; ++i) {
506     const uint32_t arg_uid = m_data.GetU32(&offset);
507 
508     // If the last argument is 0, this is a variadic function.
509     if (arg_uid == 0) {
510       is_variadic = true;
511       break;
512     }
513 
514     if (TypeSP arg_type = GetTypeForUID(arg_uid))
515       arg_types.push_back(arg_type->GetFullCompilerType());
516   }
517 
518   // If the number of arguments is odd, a single uint32_t of padding is inserted
519   // to maintain alignment.
520   if (num_args % 2 == 1)
521     m_data.GetU32(&offset);
522 
523   TypeSP ret_type = GetTypeForUID(type);
524   if (!ret_type)
525     return llvm::make_error<llvm::StringError>(
526         llvm::formatv("Could not find function return type: {0}", type),
527         llvm::inconvertibleErrorCode());
528 
529   CompilerType func_type = m_ast->CreateFunctionType(
530       ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(),
531       is_variadic, 0, clang::CallingConv::CC_C);
532 
533   Declaration decl;
534   return MakeType(uid, ConstString(name), 0, nullptr, LLDB_INVALID_UID,
535                   Type::eEncodingIsUID, decl, func_type,
536                   lldb_private::Type::ResolveState::Full);
537 }
538 
539 llvm::Expected<lldb::TypeSP>
540 SymbolFileCTF::ParseRecord(lldb::offset_t &offset, lldb::user_id_t uid,
541                            llvm::StringRef name, uint32_t kind, uint32_t fields,
542                            uint32_t size) {
543   const clang::TagTypeKind tag_kind =
544       TranslateRecordKind(static_cast<TypeKind>(kind));
545 
546   CompilerType union_type =
547       m_ast->CreateRecordType(nullptr, OptionalClangModuleID(), eAccessPublic,
548                               name.data(), tag_kind, eLanguageTypeC);
549 
550   m_ast->StartTagDeclarationDefinition(union_type);
551   for (uint32_t i = 0; i < fields; ++i) {
552     ctf_member_t ctf_member;
553     ctf_member.name = m_data.GetU32(&offset);
554     ctf_member.type = m_data.GetU32(&offset);
555     ctf_member.offset = m_data.GetU16(&offset);
556     ctf_member.padding = m_data.GetU16(&offset);
557 
558     llvm::StringRef member_name = ReadString(ctf_member.name);
559     const uint32_t member_type_uid = ctf_member.type;
560 
561     if (TypeSP member_type = GetTypeForUID(member_type_uid)) {
562       const uint32_t member_size =
563           member_type->GetByteSize(nullptr).value_or(0);
564       TypeSystemClang::AddFieldToRecordType(union_type, member_name,
565                                             member_type->GetFullCompilerType(),
566                                             eAccessPublic, member_size);
567     }
568   }
569   m_ast->CompleteTagDeclarationDefinition(union_type);
570 
571   Declaration decl;
572   return MakeType(uid, ConstString(name), size, nullptr, LLDB_INVALID_UID,
573                   lldb_private::Type::eEncodingIsUID, decl, union_type,
574                   lldb_private::Type::ResolveState::Full);
575 }
576 
577 llvm::Expected<TypeSP> SymbolFileCTF::ParseType(
578     lldb::offset_t &offset, lldb::user_id_t uid, llvm::StringRef name,
579     uint32_t kind, uint32_t variable_length, uint32_t type, uint32_t size) {
580   switch (kind) {
581   case TypeKind::eInteger:
582     return ParseInteger(offset, uid, name);
583   case TypeKind::eConst:
584   case TypeKind::ePointer:
585   case TypeKind::eRestrict:
586   case TypeKind::eVolatile:
587     return ParseModifierType(offset, uid, kind, type);
588   case TypeKind::eTypedef:
589     return ParseTypedef(offset, uid, name, type);
590   case TypeKind::eArray:
591     return ParseArray(offset, uid, name);
592   case TypeKind::eEnum:
593     return ParseEnum(offset, uid, name, variable_length, size);
594   case TypeKind::eFunction:
595     return ParseFunction(offset, uid, name, variable_length, size);
596   case TypeKind::eStruct:
597   case TypeKind::eUnion:
598     return ParseRecord(offset, uid, name, kind, variable_length, size);
599   case TypeKind::eFloat:
600   case TypeKind::eForward:
601   case TypeKind::eSlice:
602   case TypeKind::eUnknown:
603     offset += (variable_length * sizeof(uint32_t));
604     break;
605   }
606   return llvm::make_error<llvm::StringError>(
607       llvm::formatv("unsupported type (name = {0}, kind = {1}, vlength = {2})",
608                     name, kind, variable_length),
609       llvm::inconvertibleErrorCode());
610 }
611 
612 size_t SymbolFileCTF::ParseTypes(CompileUnit &cu) {
613   if (!ParseHeader())
614     return 0;
615 
616   if (!m_types.empty())
617     return 0;
618 
619   if (!m_ast)
620     return 0;
621 
622   Log *log = GetLog(LLDBLog::Symbols);
623   LLDB_LOG(log, "Parsing CTF types");
624 
625   lldb::offset_t type_offset = m_body_offset + m_header->typeoff;
626   const lldb::offset_t type_offset_end = m_body_offset + m_header->stroff;
627 
628   lldb::user_id_t type_uid = 1;
629   while (type_offset < type_offset_end) {
630     ctf_stype_t ctf_stype;
631     ctf_stype.name = m_data.GetU32(&type_offset);
632     ctf_stype.info = m_data.GetU32(&type_offset);
633     ctf_stype.size = m_data.GetU32(&type_offset);
634 
635     llvm::StringRef name = ReadString(ctf_stype.name);
636     const uint32_t kind = GetKind(ctf_stype.info);
637     const uint32_t variable_length = GetVLen(ctf_stype.info);
638     const uint32_t type = ctf_stype.GetType();
639     const uint32_t size = ctf_stype.GetSize();
640 
641     TypeSP type_sp;
642     llvm::Expected<TypeSP> type_or_error = ParseType(
643         type_offset, type_uid, name, kind, variable_length, type, size);
644     if (!type_or_error) {
645       LLDB_LOG_ERROR(log, type_or_error.takeError(),
646                      "Failed to parse type {1} at offset {2}: {0}", type_uid,
647                      type_offset);
648     } else {
649       type_sp = *type_or_error;
650       if (log) {
651         StreamString ss;
652         type_sp->Dump(&ss, true);
653         LLDB_LOGV(log, "Adding type {0}: {1}", type_uid,
654                   llvm::StringRef(ss.GetString()).rtrim());
655       }
656     }
657 
658     AddTypeForUID(type_uid++, type_sp);
659   }
660 
661   if (log) {
662     size_t skipped_types = 0;
663     for (auto &type : m_types) {
664       if (!type)
665         skipped_types++;
666     }
667     LLDB_LOG(log, "Parsed {0} CTF types ({1} skipped)", m_types.size(),
668              skipped_types);
669   }
670 
671   return m_types.size();
672 }
673 
674 size_t SymbolFileCTF::ParseFunctions(CompileUnit &cu) {
675   if (!ParseHeader())
676     return 0;
677 
678   if (!m_functions.empty())
679     return 0;
680 
681   if (!m_ast)
682     return 0;
683 
684   Symtab *symtab = GetObjectFile()->GetModule()->GetSymtab();
685   if (!symtab)
686     return 0;
687 
688   Log *log = GetLog(LLDBLog::Symbols);
689   LLDB_LOG(log, "Parsing CTF functions");
690 
691   lldb::offset_t function_offset = m_body_offset + m_header->funcoff;
692   const lldb::offset_t function_offset_end = m_body_offset + m_header->typeoff;
693 
694   uint32_t symbol_idx = 0;
695   Declaration decl;
696   while (function_offset < function_offset_end) {
697     const uint32_t info = m_data.GetU32(&function_offset);
698     const uint16_t kind = GetKind(info);
699     const uint16_t variable_length = GetVLen(info);
700 
701     Symbol *symbol = symtab->FindSymbolWithType(
702         eSymbolTypeCode, Symtab::eDebugYes, Symtab::eVisibilityAny, symbol_idx);
703 
704     // Skip padding.
705     if (kind == TypeKind::eUnknown && variable_length == 0)
706       continue;
707 
708     // Skip unexpected kinds.
709     if (kind != TypeKind::eFunction)
710       continue;
711 
712     const uint32_t ret_uid = m_data.GetU32(&function_offset);
713     const uint32_t num_args = variable_length;
714 
715     std::vector<CompilerType> arg_types;
716     arg_types.reserve(num_args);
717 
718     bool is_variadic = false;
719     for (uint32_t i = 0; i < variable_length; i++) {
720       const uint32_t arg_uid = m_data.GetU32(&function_offset);
721 
722       // If the last argument is 0, this is a variadic function.
723       if (arg_uid == 0) {
724         is_variadic = true;
725         break;
726       }
727 
728       TypeSP arg_type = GetTypeForUID(arg_uid);
729       arg_types.push_back(arg_type->GetFullCompilerType());
730     }
731 
732     if (symbol) {
733       TypeSP ret_type = GetTypeForUID(ret_uid);
734       AddressRange func_range =
735           AddressRange(symbol->GetFileAddress(), symbol->GetByteSize(),
736                        GetObjectFile()->GetModule()->GetSectionList());
737 
738       // Create function type.
739       CompilerType func_type = m_ast->CreateFunctionType(
740           ret_type->GetFullCompilerType(), arg_types.data(), arg_types.size(),
741           is_variadic, 0, clang::CallingConv::CC_C);
742       lldb::user_id_t function_type_uid = m_types.size() + 1;
743       TypeSP type_sp =
744           MakeType(function_type_uid, symbol->GetName(), 0, nullptr,
745                    LLDB_INVALID_UID, Type::eEncodingIsUID, decl, func_type,
746                    lldb_private::Type::ResolveState::Full);
747       AddTypeForUID(function_type_uid, type_sp);
748 
749       // Create function.
750       lldb::user_id_t func_uid = m_functions.size();
751       FunctionSP function_sp = std::make_shared<Function>(
752           &cu, func_uid, function_type_uid, symbol->GetMangled(), type_sp.get(),
753           func_range);
754       m_functions.emplace_back(function_sp);
755       cu.AddFunction(function_sp);
756     }
757   }
758 
759   LLDB_LOG(log, "CTF parsed {0} functions", m_functions.size());
760 
761   return m_functions.size();
762 }
763 
764 static DWARFExpression CreateDWARFExpression(ModuleSP module_sp,
765                                              const Symbol &symbol) {
766   if (!module_sp)
767     return DWARFExpression();
768 
769   const ArchSpec &architecture = module_sp->GetArchitecture();
770   ByteOrder byte_order = architecture.GetByteOrder();
771   uint32_t address_size = architecture.GetAddressByteSize();
772   uint32_t byte_size = architecture.GetDataByteSize();
773 
774   StreamBuffer<32> stream(Stream::eBinary, address_size, byte_order);
775   stream.PutHex8(lldb_private::dwarf::DW_OP_addr);
776   stream.PutMaxHex64(symbol.GetFileAddress(), address_size, byte_order);
777 
778   DataBufferSP buffer =
779       std::make_shared<DataBufferHeap>(stream.GetData(), stream.GetSize());
780   lldb_private::DataExtractor extractor(buffer, byte_order, address_size,
781                                         byte_size);
782   DWARFExpression result(extractor);
783   result.SetRegisterKind(eRegisterKindDWARF);
784 
785   return result;
786 }
787 
788 size_t SymbolFileCTF::ParseObjects(CompileUnit &comp_unit) {
789   if (!ParseHeader())
790     return 0;
791 
792   if (!m_variables.empty())
793     return 0;
794 
795   if (!m_ast)
796     return 0;
797 
798   ModuleSP module_sp = GetObjectFile()->GetModule();
799   Symtab *symtab = module_sp->GetSymtab();
800   if (!symtab)
801     return 0;
802 
803   Log *log = GetLog(LLDBLog::Symbols);
804   LLDB_LOG(log, "Parsing CTF objects");
805 
806   lldb::offset_t object_offset = m_body_offset + m_header->objtoff;
807   const lldb::offset_t object_offset_end = m_body_offset + m_header->funcoff;
808 
809   uint32_t symbol_idx = 0;
810   Declaration decl;
811   while (object_offset < object_offset_end) {
812     const uint32_t type_uid = m_data.GetU32(&object_offset);
813 
814     if (Symbol *symbol =
815             symtab->FindSymbolWithType(eSymbolTypeData, Symtab::eDebugYes,
816                                        Symtab::eVisibilityAny, symbol_idx)) {
817 
818       Variable::RangeList ranges;
819       ranges.Append(symbol->GetFileAddress(), symbol->GetByteSize());
820 
821       auto type_sp = std::make_shared<SymbolFileType>(*this, type_uid);
822 
823       DWARFExpressionList location(
824           module_sp, CreateDWARFExpression(module_sp, *symbol), nullptr);
825 
826       lldb::user_id_t variable_type_uid = m_variables.size();
827       m_variables.emplace_back(std::make_shared<Variable>(
828           variable_type_uid, symbol->GetName().AsCString(),
829           symbol->GetName().AsCString(), type_sp, eValueTypeVariableGlobal,
830           m_comp_unit_sp.get(), ranges, &decl, location, symbol->IsExternal(),
831           /*artificial=*/false,
832           /*location_is_constant_data*/ false));
833     }
834   }
835 
836   LLDB_LOG(log, "Parsed {0} CTF objects", m_variables.size());
837 
838   return m_variables.size();
839 }
840 
841 uint32_t SymbolFileCTF::CalculateAbilities() {
842   if (!m_objfile_sp)
843     return 0;
844 
845   if (!ParseHeader())
846     return 0;
847 
848   return VariableTypes | Functions | GlobalVariables;
849 }
850 
851 uint32_t SymbolFileCTF::ResolveSymbolContext(const Address &so_addr,
852                                              SymbolContextItem resolve_scope,
853                                              SymbolContext &sc) {
854   std::lock_guard<std::recursive_mutex> guard(GetModuleMutex());
855   if (m_objfile_sp->GetSymtab() == nullptr)
856     return 0;
857 
858   uint32_t resolved_flags = 0;
859 
860   // Resolve symbols.
861   if (resolve_scope & eSymbolContextSymbol) {
862     sc.symbol = m_objfile_sp->GetSymtab()->FindSymbolContainingFileAddress(
863         so_addr.GetFileAddress());
864     if (sc.symbol)
865       resolved_flags |= eSymbolContextSymbol;
866   }
867 
868   // Resolve functions.
869   if (resolve_scope & eSymbolContextFunction) {
870     for (FunctionSP function_sp : m_functions) {
871       if (function_sp->GetAddressRange().ContainsFileAddress(
872               so_addr.GetFileAddress())) {
873         sc.function = function_sp.get();
874         resolved_flags |= eSymbolContextFunction;
875         break;
876       }
877     }
878   }
879 
880   // Resolve variables.
881   if (resolve_scope & eSymbolContextVariable) {
882     for (VariableSP variable_sp : m_variables) {
883       if (variable_sp->LocationIsValidForAddress(so_addr.GetFileAddress())) {
884         sc.variable = variable_sp.get();
885         break;
886       }
887     }
888   }
889 
890   return resolved_flags;
891 }
892 
893 CompUnitSP SymbolFileCTF::ParseCompileUnitAtIndex(uint32_t idx) {
894   if (idx == 0)
895     return m_comp_unit_sp;
896   return {};
897 }
898 
899 size_t
900 SymbolFileCTF::ParseVariablesForContext(const lldb_private::SymbolContext &sc) {
901   return ParseObjects(*m_comp_unit_sp);
902 }
903 
904 void SymbolFileCTF::AddSymbols(Symtab &symtab) {
905   // CTF does not encode symbols.
906   // We rely on the existing symbol table to map symbols to type.
907 }
908 
909 void SymbolFileCTF::AddTypeForUID(lldb::user_id_t type_uid, lldb::TypeSP type) {
910   assert(type_uid == m_types.size() + 1);
911   m_types.emplace_back(type);
912 }
913 
914 TypeSP SymbolFileCTF::GetTypeForUID(lldb::user_id_t type_uid) {
915   if (type_uid > m_types.size())
916     return {};
917 
918   if (type_uid < 1)
919     return {};
920 
921   return m_types[type_uid - 1];
922 }
923 
924 lldb_private::Type *SymbolFileCTF::ResolveTypeUID(lldb::user_id_t type_uid) {
925   return GetTypeForUID(type_uid).get();
926 }
927 
928 void SymbolFileCTF::FindTypes(
929     lldb_private::ConstString name,
930     const lldb_private::CompilerDeclContext &parent_decl_ctx,
931     uint32_t max_matches,
932     llvm::DenseSet<lldb_private::SymbolFile *> &searched_symbol_files,
933     lldb_private::TypeMap &types) {
934 
935   searched_symbol_files.clear();
936   searched_symbol_files.insert(this);
937 
938   size_t matches = 0;
939   for (TypeSP type_sp : m_types) {
940     if (matches == max_matches)
941       break;
942     if (type_sp && type_sp->GetName() == name) {
943       types.Insert(type_sp);
944       matches++;
945     }
946   }
947 }
948 
949 void SymbolFileCTF::FindTypesByRegex(
950     const lldb_private::RegularExpression &regex, uint32_t max_matches,
951     lldb_private::TypeMap &types) {
952   ParseTypes(*m_comp_unit_sp);
953 
954   size_t matches = 0;
955   for (TypeSP type_sp : m_types) {
956     if (matches == max_matches)
957       break;
958     if (type_sp && regex.Execute(type_sp->GetName()))
959       types.Insert(type_sp);
960     matches++;
961   }
962 }
963 
964 void SymbolFileCTF::FindFunctions(
965     const lldb_private::Module::LookupInfo &lookup_info,
966     const lldb_private::CompilerDeclContext &parent_decl_ctx,
967     bool include_inlines, lldb_private::SymbolContextList &sc_list) {
968   ParseFunctions(*m_comp_unit_sp);
969 
970   ConstString name = lookup_info.GetLookupName();
971   for (FunctionSP function_sp : m_functions) {
972     if (function_sp && function_sp->GetName() == name) {
973       lldb_private::SymbolContext sc;
974       sc.comp_unit = m_comp_unit_sp.get();
975       sc.function = function_sp.get();
976       sc_list.Append(sc);
977     }
978   }
979 }
980 
981 void SymbolFileCTF::FindFunctions(const lldb_private::RegularExpression &regex,
982                                   bool include_inlines,
983                                   lldb_private::SymbolContextList &sc_list) {
984   for (FunctionSP function_sp : m_functions) {
985     if (function_sp && regex.Execute(function_sp->GetName())) {
986       lldb_private::SymbolContext sc;
987       sc.comp_unit = m_comp_unit_sp.get();
988       sc.function = function_sp.get();
989       sc_list.Append(sc);
990     }
991   }
992 }
993 
994 void SymbolFileCTF::FindGlobalVariables(
995     lldb_private::ConstString name,
996     const lldb_private::CompilerDeclContext &parent_decl_ctx,
997     uint32_t max_matches, lldb_private::VariableList &variables) {
998   ParseObjects(*m_comp_unit_sp);
999 
1000   size_t matches = 0;
1001   for (VariableSP variable_sp : m_variables) {
1002     if (matches == max_matches)
1003       break;
1004     if (variable_sp && variable_sp->GetName() == name) {
1005       variables.AddVariable(variable_sp);
1006       matches++;
1007     }
1008   }
1009 }
1010 
1011 void SymbolFileCTF::FindGlobalVariables(
1012     const lldb_private::RegularExpression &regex, uint32_t max_matches,
1013     lldb_private::VariableList &variables) {
1014   ParseObjects(*m_comp_unit_sp);
1015 
1016   size_t matches = 0;
1017   for (VariableSP variable_sp : m_variables) {
1018     if (matches == max_matches)
1019       break;
1020     if (variable_sp && regex.Execute(variable_sp->GetName())) {
1021       variables.AddVariable(variable_sp);
1022       matches++;
1023     }
1024   }
1025 }
1026