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