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