1 //===-- ItaniumABILanguageRuntime.cpp --------------------------------------*- 2 //C++ -*-===// 3 // 4 // The LLVM Compiler Infrastructure 5 // 6 // This file is distributed under the University of Illinois Open Source 7 // License. See LICENSE.TXT for details. 8 // 9 //===----------------------------------------------------------------------===// 10 11 #include "ItaniumABILanguageRuntime.h" 12 13 #include "lldb/Breakpoint/BreakpointLocation.h" 14 #include "lldb/Core/ConstString.h" 15 #include "lldb/Core/Error.h" 16 #include "lldb/Core/Log.h" 17 #include "lldb/Core/Mangled.h" 18 #include "lldb/Core/Module.h" 19 #include "lldb/Core/PluginManager.h" 20 #include "lldb/Core/Scalar.h" 21 #include "lldb/Core/ValueObject.h" 22 #include "lldb/Core/ValueObjectMemory.h" 23 #include "lldb/Interpreter/CommandObject.h" 24 #include "lldb/Interpreter/CommandObjectMultiword.h" 25 #include "lldb/Interpreter/CommandReturnObject.h" 26 #include "lldb/Symbol/ClangASTContext.h" 27 #include "lldb/Symbol/Symbol.h" 28 #include "lldb/Symbol/SymbolFile.h" 29 #include "lldb/Symbol/TypeList.h" 30 #include "lldb/Target/Process.h" 31 #include "lldb/Target/RegisterContext.h" 32 #include "lldb/Target/SectionLoadList.h" 33 #include "lldb/Target/StopInfo.h" 34 #include "lldb/Target/Target.h" 35 #include "lldb/Target/Thread.h" 36 37 #include <vector> 38 39 using namespace lldb; 40 using namespace lldb_private; 41 42 static const char *vtable_demangled_prefix = "vtable for "; 43 44 bool ItaniumABILanguageRuntime::CouldHaveDynamicValue(ValueObject &in_value) { 45 const bool check_cxx = true; 46 const bool check_objc = false; 47 return in_value.GetCompilerType().IsPossibleDynamicType(NULL, check_cxx, 48 check_objc); 49 } 50 51 TypeAndOrName ItaniumABILanguageRuntime::GetTypeInfoFromVTableAddress( 52 ValueObject &in_value, lldb::addr_t original_ptr, 53 lldb::addr_t vtable_load_addr) { 54 if (m_process && vtable_load_addr != LLDB_INVALID_ADDRESS) { 55 // Find the symbol that contains the "vtable_load_addr" address 56 Address vtable_addr; 57 Target &target = m_process->GetTarget(); 58 if (!target.GetSectionLoadList().IsEmpty()) { 59 if (target.GetSectionLoadList().ResolveLoadAddress(vtable_load_addr, 60 vtable_addr)) { 61 // See if we have cached info for this type already 62 TypeAndOrName type_info = GetDynamicTypeInfo(vtable_addr); 63 if (type_info) 64 return type_info; 65 66 SymbolContext sc; 67 target.GetImages().ResolveSymbolContextForAddress( 68 vtable_addr, eSymbolContextSymbol, sc); 69 Symbol *symbol = sc.symbol; 70 if (symbol != NULL) { 71 const char *name = 72 symbol->GetMangled() 73 .GetDemangledName(lldb::eLanguageTypeC_plus_plus) 74 .AsCString(); 75 if (name && strstr(name, vtable_demangled_prefix) == name) { 76 Log *log( 77 lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_OBJECT)); 78 if (log) 79 log->Printf("0x%16.16" PRIx64 80 ": static-type = '%s' has vtable symbol '%s'\n", 81 original_ptr, in_value.GetTypeName().GetCString(), 82 name); 83 // We are a C++ class, that's good. Get the class name and look it 84 // up: 85 const char *class_name = name + strlen(vtable_demangled_prefix); 86 type_info.SetName(class_name); 87 const bool exact_match = true; 88 TypeList class_types; 89 90 uint32_t num_matches = 0; 91 // First look in the module that the vtable symbol came from 92 // and look for a single exact match. 93 llvm::DenseSet<SymbolFile *> searched_symbol_files; 94 if (sc.module_sp) { 95 num_matches = sc.module_sp->FindTypes( 96 sc, ConstString(class_name), exact_match, 1, 97 searched_symbol_files, class_types); 98 } 99 100 // If we didn't find a symbol, then move on to the entire 101 // module list in the target and get as many unique matches 102 // as possible 103 if (num_matches == 0) { 104 num_matches = target.GetImages().FindTypes( 105 sc, ConstString(class_name), exact_match, UINT32_MAX, 106 searched_symbol_files, class_types); 107 } 108 109 lldb::TypeSP type_sp; 110 if (num_matches == 0) { 111 if (log) 112 log->Printf("0x%16.16" PRIx64 ": is not dynamic\n", 113 original_ptr); 114 return TypeAndOrName(); 115 } 116 if (num_matches == 1) { 117 type_sp = class_types.GetTypeAtIndex(0); 118 if (type_sp) { 119 if (ClangASTContext::IsCXXClassType( 120 type_sp->GetForwardCompilerType())) { 121 if (log) 122 log->Printf( 123 "0x%16.16" PRIx64 124 ": static-type = '%s' has dynamic type: uid={0x%" PRIx64 125 "}, type-name='%s'\n", 126 original_ptr, in_value.GetTypeName().AsCString(), 127 type_sp->GetID(), type_sp->GetName().GetCString()); 128 type_info.SetTypeSP(type_sp); 129 } 130 } 131 } else if (num_matches > 1) { 132 size_t i; 133 if (log) { 134 for (i = 0; i < num_matches; i++) { 135 type_sp = class_types.GetTypeAtIndex(i); 136 if (type_sp) { 137 if (log) 138 log->Printf( 139 "0x%16.16" PRIx64 140 ": static-type = '%s' has multiple matching dynamic " 141 "types: uid={0x%" PRIx64 "}, type-name='%s'\n", 142 original_ptr, in_value.GetTypeName().AsCString(), 143 type_sp->GetID(), type_sp->GetName().GetCString()); 144 } 145 } 146 } 147 148 for (i = 0; i < num_matches; i++) { 149 type_sp = class_types.GetTypeAtIndex(i); 150 if (type_sp) { 151 if (ClangASTContext::IsCXXClassType( 152 type_sp->GetForwardCompilerType())) { 153 if (log) 154 log->Printf( 155 "0x%16.16" PRIx64 ": static-type = '%s' has multiple " 156 "matching dynamic types, picking " 157 "this one: uid={0x%" PRIx64 158 "}, type-name='%s'\n", 159 original_ptr, in_value.GetTypeName().AsCString(), 160 type_sp->GetID(), type_sp->GetName().GetCString()); 161 type_info.SetTypeSP(type_sp); 162 } 163 } 164 } 165 166 if (log && i == num_matches) { 167 log->Printf( 168 "0x%16.16" PRIx64 169 ": static-type = '%s' has multiple matching dynamic " 170 "types, didn't find a C++ match\n", 171 original_ptr, in_value.GetTypeName().AsCString()); 172 } 173 } 174 if (type_info) 175 SetDynamicTypeInfo(vtable_addr, type_info); 176 return type_info; 177 } 178 } 179 } 180 } 181 } 182 return TypeAndOrName(); 183 } 184 185 bool ItaniumABILanguageRuntime::GetDynamicTypeAndAddress( 186 ValueObject &in_value, lldb::DynamicValueType use_dynamic, 187 TypeAndOrName &class_type_or_name, Address &dynamic_address, 188 Value::ValueType &value_type) { 189 // For Itanium, if the type has a vtable pointer in the object, it will be at 190 // offset 0 191 // in the object. That will point to the "address point" within the vtable 192 // (not the beginning of the 193 // vtable.) We can then look up the symbol containing this "address point" 194 // and that symbol's name 195 // demangled will contain the full class name. 196 // The second pointer above the "address point" is the "offset_to_top". We'll 197 // use that to get the 198 // start of the value object which holds the dynamic type. 199 // 200 201 class_type_or_name.Clear(); 202 value_type = Value::ValueType::eValueTypeScalar; 203 204 // Only a pointer or reference type can have a different dynamic and static 205 // type: 206 if (CouldHaveDynamicValue(in_value)) { 207 // First job, pull out the address at 0 offset from the object. 208 AddressType address_type; 209 lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type); 210 if (original_ptr == LLDB_INVALID_ADDRESS) 211 return false; 212 213 ExecutionContext exe_ctx(in_value.GetExecutionContextRef()); 214 215 Process *process = exe_ctx.GetProcessPtr(); 216 217 if (process == nullptr) 218 return false; 219 220 Error error; 221 const lldb::addr_t vtable_address_point = 222 process->ReadPointerFromMemory(original_ptr, error); 223 224 if (!error.Success() || vtable_address_point == LLDB_INVALID_ADDRESS) { 225 return false; 226 } 227 228 class_type_or_name = GetTypeInfoFromVTableAddress(in_value, original_ptr, 229 vtable_address_point); 230 231 if (class_type_or_name) { 232 TypeSP type_sp = class_type_or_name.GetTypeSP(); 233 // There can only be one type with a given name, 234 // so we've just found duplicate definitions, and this 235 // one will do as well as any other. 236 // We don't consider something to have a dynamic type if 237 // it is the same as the static type. So compare against 238 // the value we were handed. 239 if (type_sp) { 240 if (ClangASTContext::AreTypesSame(in_value.GetCompilerType(), 241 type_sp->GetForwardCompilerType())) { 242 // The dynamic type we found was the same type, 243 // so we don't have a dynamic type here... 244 return false; 245 } 246 247 // The offset_to_top is two pointers above the vtable pointer. 248 const uint32_t addr_byte_size = process->GetAddressByteSize(); 249 const lldb::addr_t offset_to_top_location = 250 vtable_address_point - 2 * addr_byte_size; 251 // Watch for underflow, offset_to_top_location should be less than 252 // vtable_address_point 253 if (offset_to_top_location >= vtable_address_point) 254 return false; 255 const int64_t offset_to_top = process->ReadSignedIntegerFromMemory( 256 offset_to_top_location, addr_byte_size, INT64_MIN, error); 257 258 if (offset_to_top == INT64_MIN) 259 return false; 260 // So the dynamic type is a value that starts at offset_to_top 261 // above the original address. 262 lldb::addr_t dynamic_addr = original_ptr + offset_to_top; 263 if (!process->GetTarget().GetSectionLoadList().ResolveLoadAddress( 264 dynamic_addr, dynamic_address)) { 265 dynamic_address.SetRawAddress(dynamic_addr); 266 } 267 return true; 268 } 269 } 270 } 271 272 return class_type_or_name.IsEmpty() == false; 273 } 274 275 TypeAndOrName ItaniumABILanguageRuntime::FixUpDynamicType( 276 const TypeAndOrName &type_and_or_name, ValueObject &static_value) { 277 CompilerType static_type(static_value.GetCompilerType()); 278 Flags static_type_flags(static_type.GetTypeInfo()); 279 280 TypeAndOrName ret(type_and_or_name); 281 if (type_and_or_name.HasType()) { 282 // The type will always be the type of the dynamic object. If our parent's 283 // type was a pointer, 284 // then our type should be a pointer to the type of the dynamic object. If 285 // a reference, then the original type 286 // should be okay... 287 CompilerType orig_type = type_and_or_name.GetCompilerType(); 288 CompilerType corrected_type = orig_type; 289 if (static_type_flags.AllSet(eTypeIsPointer)) 290 corrected_type = orig_type.GetPointerType(); 291 else if (static_type_flags.AllSet(eTypeIsReference)) 292 corrected_type = orig_type.GetLValueReferenceType(); 293 ret.SetCompilerType(corrected_type); 294 } else { 295 // If we are here we need to adjust our dynamic type name to include the 296 // correct & or * symbol 297 std::string corrected_name(type_and_or_name.GetName().GetCString()); 298 if (static_type_flags.AllSet(eTypeIsPointer)) 299 corrected_name.append(" *"); 300 else if (static_type_flags.AllSet(eTypeIsReference)) 301 corrected_name.append(" &"); 302 // the parent type should be a correctly pointer'ed or referenc'ed type 303 ret.SetCompilerType(static_type); 304 ret.SetName(corrected_name.c_str()); 305 } 306 return ret; 307 } 308 309 bool ItaniumABILanguageRuntime::IsVTableName(const char *name) { 310 if (name == NULL) 311 return false; 312 313 // Can we maybe ask Clang about this? 314 if (strstr(name, "_vptr$") == name) 315 return true; 316 else 317 return false; 318 } 319 320 //------------------------------------------------------------------ 321 // Static Functions 322 //------------------------------------------------------------------ 323 LanguageRuntime * 324 ItaniumABILanguageRuntime::CreateInstance(Process *process, 325 lldb::LanguageType language) { 326 // FIXME: We have to check the process and make sure we actually know that 327 // this process supports 328 // the Itanium ABI. 329 if (language == eLanguageTypeC_plus_plus || 330 language == eLanguageTypeC_plus_plus_03 || 331 language == eLanguageTypeC_plus_plus_11 || 332 language == eLanguageTypeC_plus_plus_14) 333 return new ItaniumABILanguageRuntime(process); 334 else 335 return NULL; 336 } 337 338 class CommandObjectMultiwordItaniumABI_Demangle : public CommandObjectParsed { 339 public: 340 CommandObjectMultiwordItaniumABI_Demangle(CommandInterpreter &interpreter) 341 : CommandObjectParsed(interpreter, "demangle", 342 "Demangle a C++ mangled name.", 343 "language cplusplus demangle") { 344 CommandArgumentEntry arg; 345 CommandArgumentData index_arg; 346 347 // Define the first (and only) variant of this arg. 348 index_arg.arg_type = eArgTypeSymbol; 349 index_arg.arg_repetition = eArgRepeatPlus; 350 351 // There is only one variant this argument could be; put it into the 352 // argument entry. 353 arg.push_back(index_arg); 354 355 // Push the data for the first argument into the m_arguments vector. 356 m_arguments.push_back(arg); 357 } 358 359 ~CommandObjectMultiwordItaniumABI_Demangle() override = default; 360 361 protected: 362 bool DoExecute(Args &command, CommandReturnObject &result) override { 363 bool demangled_any = false; 364 bool error_any = false; 365 for (auto &entry : command.entries()) { 366 if (entry.ref.empty()) 367 continue; 368 369 // the actual Mangled class should be strict about this, but on the 370 // command line if you're copying mangled names out of 'nm' on Darwin, 371 // they will come out with an extra underscore - be willing to strip 372 // this on behalf of the user. This is the moral equivalent of the -_/-n 373 // options to c++filt 374 auto name = entry.ref; 375 if (name.startswith("__Z")) 376 name = name.drop_front(); 377 378 Mangled mangled(name, true); 379 if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) { 380 ConstString demangled( 381 mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus)); 382 demangled_any = true; 383 result.AppendMessageWithFormat("%s ---> %s\n", entry.ref.str().c_str(), 384 demangled.GetCString()); 385 } else { 386 error_any = true; 387 result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n", 388 entry.ref.str().c_str()); 389 } 390 } 391 392 result.SetStatus( 393 error_any ? lldb::eReturnStatusFailed 394 : (demangled_any ? lldb::eReturnStatusSuccessFinishResult 395 : lldb::eReturnStatusSuccessFinishNoResult)); 396 return result.Succeeded(); 397 } 398 }; 399 400 class CommandObjectMultiwordItaniumABI : public CommandObjectMultiword { 401 public: 402 CommandObjectMultiwordItaniumABI(CommandInterpreter &interpreter) 403 : CommandObjectMultiword( 404 interpreter, "cplusplus", 405 "Commands for operating on the C++ language runtime.", 406 "cplusplus <subcommand> [<subcommand-options>]") { 407 LoadSubCommand( 408 "demangle", 409 CommandObjectSP( 410 new CommandObjectMultiwordItaniumABI_Demangle(interpreter))); 411 } 412 413 ~CommandObjectMultiwordItaniumABI() override = default; 414 }; 415 416 void ItaniumABILanguageRuntime::Initialize() { 417 PluginManager::RegisterPlugin( 418 GetPluginNameStatic(), "Itanium ABI for the C++ language", CreateInstance, 419 [](CommandInterpreter &interpreter) -> lldb::CommandObjectSP { 420 return CommandObjectSP( 421 new CommandObjectMultiwordItaniumABI(interpreter)); 422 }); 423 } 424 425 void ItaniumABILanguageRuntime::Terminate() { 426 PluginManager::UnregisterPlugin(CreateInstance); 427 } 428 429 lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginNameStatic() { 430 static ConstString g_name("itanium"); 431 return g_name; 432 } 433 434 //------------------------------------------------------------------ 435 // PluginInterface protocol 436 //------------------------------------------------------------------ 437 lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginName() { 438 return GetPluginNameStatic(); 439 } 440 441 uint32_t ItaniumABILanguageRuntime::GetPluginVersion() { return 1; } 442 443 BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver( 444 Breakpoint *bkpt, bool catch_bp, bool throw_bp) { 445 return CreateExceptionResolver(bkpt, catch_bp, throw_bp, false); 446 } 447 448 BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver( 449 Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions) { 450 // One complication here is that most users DON'T want to stop at 451 // __cxa_allocate_expression, but until we can do 452 // anything better with predicting unwinding the expression parser does. So 453 // we have two forms of the exception 454 // breakpoints, one for expressions that leaves out __cxa_allocate_exception, 455 // and one that includes it. 456 // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint 457 // in the runtime the former. 458 static const char *g_catch_name = "__cxa_begin_catch"; 459 static const char *g_throw_name1 = "__cxa_throw"; 460 static const char *g_throw_name2 = "__cxa_rethrow"; 461 static const char *g_exception_throw_name = "__cxa_allocate_exception"; 462 std::vector<const char *> exception_names; 463 exception_names.reserve(4); 464 if (catch_bp) 465 exception_names.push_back(g_catch_name); 466 467 if (throw_bp) { 468 exception_names.push_back(g_throw_name1); 469 exception_names.push_back(g_throw_name2); 470 } 471 472 if (for_expressions) 473 exception_names.push_back(g_exception_throw_name); 474 475 BreakpointResolverSP resolver_sp(new BreakpointResolverName( 476 bkpt, exception_names.data(), exception_names.size(), 477 eFunctionNameTypeBase, eLanguageTypeUnknown, 0, eLazyBoolNo)); 478 479 return resolver_sp; 480 } 481 482 lldb::SearchFilterSP ItaniumABILanguageRuntime::CreateExceptionSearchFilter() { 483 Target &target = m_process->GetTarget(); 484 485 if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) { 486 // Limit the number of modules that are searched for these breakpoints for 487 // Apple binaries. 488 FileSpecList filter_modules; 489 filter_modules.Append(FileSpec("libc++abi.dylib", false)); 490 filter_modules.Append(FileSpec("libSystem.B.dylib", false)); 491 return target.GetSearchFilterForModuleList(&filter_modules); 492 } else { 493 return LanguageRuntime::CreateExceptionSearchFilter(); 494 } 495 } 496 497 lldb::BreakpointSP ItaniumABILanguageRuntime::CreateExceptionBreakpoint( 498 bool catch_bp, bool throw_bp, bool for_expressions, bool is_internal) { 499 Target &target = m_process->GetTarget(); 500 FileSpecList filter_modules; 501 BreakpointResolverSP exception_resolver_sp = 502 CreateExceptionResolver(NULL, catch_bp, throw_bp, for_expressions); 503 SearchFilterSP filter_sp(CreateExceptionSearchFilter()); 504 const bool hardware = false; 505 const bool resolve_indirect_functions = false; 506 return target.CreateBreakpoint(filter_sp, exception_resolver_sp, is_internal, 507 hardware, resolve_indirect_functions); 508 } 509 510 void ItaniumABILanguageRuntime::SetExceptionBreakpoints() { 511 if (!m_process) 512 return; 513 514 const bool catch_bp = false; 515 const bool throw_bp = true; 516 const bool is_internal = true; 517 const bool for_expressions = true; 518 519 // For the exception breakpoints set by the Expression parser, we'll be a 520 // little more aggressive and 521 // stop at exception allocation as well. 522 523 if (m_cxx_exception_bp_sp) { 524 m_cxx_exception_bp_sp->SetEnabled(true); 525 } else { 526 m_cxx_exception_bp_sp = CreateExceptionBreakpoint( 527 catch_bp, throw_bp, for_expressions, is_internal); 528 if (m_cxx_exception_bp_sp) 529 m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception"); 530 } 531 } 532 533 void ItaniumABILanguageRuntime::ClearExceptionBreakpoints() { 534 if (!m_process) 535 return; 536 537 if (m_cxx_exception_bp_sp) { 538 m_cxx_exception_bp_sp->SetEnabled(false); 539 } 540 } 541 542 bool ItaniumABILanguageRuntime::ExceptionBreakpointsAreSet() { 543 return m_cxx_exception_bp_sp && m_cxx_exception_bp_sp->IsEnabled(); 544 } 545 546 bool ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop( 547 lldb::StopInfoSP stop_reason) { 548 if (!m_process) 549 return false; 550 551 if (!stop_reason || stop_reason->GetStopReason() != eStopReasonBreakpoint) 552 return false; 553 554 uint64_t break_site_id = stop_reason->GetValue(); 555 return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint( 556 break_site_id, m_cxx_exception_bp_sp->GetID()); 557 } 558 559 TypeAndOrName ItaniumABILanguageRuntime::GetDynamicTypeInfo( 560 const lldb_private::Address &vtable_addr) { 561 std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex); 562 DynamicTypeCache::const_iterator pos = m_dynamic_type_map.find(vtable_addr); 563 if (pos == m_dynamic_type_map.end()) 564 return TypeAndOrName(); 565 else 566 return pos->second; 567 } 568 569 void ItaniumABILanguageRuntime::SetDynamicTypeInfo( 570 const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info) { 571 std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex); 572 m_dynamic_type_map[vtable_addr] = type_info; 573 } 574