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