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 ®ex, 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 ®ex, 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 ®ex, 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