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 (size_t i = 0; i < command.GetArgumentCount(); i++) { 366 auto arg = command.GetArgumentAtIndex(i); 367 if (arg && *arg) { 368 ConstString mangled_cs(arg); 369 370 // the actual Mangled class should be strict about this, but on the 371 // command line 372 // if you're copying mangled names out of 'nm' on Darwin, they will come 373 // out with 374 // an extra underscore - be willing to strip this on behalf of the user 375 // This is the moral equivalent of the -_/-n options to c++filt 376 if (mangled_cs.GetStringRef().startswith("__Z")) 377 mangled_cs.SetCString(arg + 1); 378 379 Mangled mangled(mangled_cs, true); 380 if (mangled.GuessLanguage() == lldb::eLanguageTypeC_plus_plus) { 381 ConstString demangled( 382 mangled.GetDisplayDemangledName(lldb::eLanguageTypeC_plus_plus)); 383 demangled_any = true; 384 result.AppendMessageWithFormat("%s ---> %s\n", arg, 385 demangled.GetCString()); 386 } else { 387 error_any = true; 388 result.AppendErrorWithFormat("%s is not a valid C++ mangled name\n", 389 arg); 390 } 391 } 392 } 393 394 result.SetStatus( 395 error_any ? lldb::eReturnStatusFailed 396 : (demangled_any ? lldb::eReturnStatusSuccessFinishResult 397 : lldb::eReturnStatusSuccessFinishNoResult)); 398 return result.Succeeded(); 399 } 400 }; 401 402 class CommandObjectMultiwordItaniumABI : public CommandObjectMultiword { 403 public: 404 CommandObjectMultiwordItaniumABI(CommandInterpreter &interpreter) 405 : CommandObjectMultiword( 406 interpreter, "cplusplus", 407 "Commands for operating on the C++ language runtime.", 408 "cplusplus <subcommand> [<subcommand-options>]") { 409 LoadSubCommand( 410 "demangle", 411 CommandObjectSP( 412 new CommandObjectMultiwordItaniumABI_Demangle(interpreter))); 413 } 414 415 ~CommandObjectMultiwordItaniumABI() override = default; 416 }; 417 418 void ItaniumABILanguageRuntime::Initialize() { 419 PluginManager::RegisterPlugin( 420 GetPluginNameStatic(), "Itanium ABI for the C++ language", CreateInstance, 421 [](CommandInterpreter &interpreter) -> lldb::CommandObjectSP { 422 return CommandObjectSP( 423 new CommandObjectMultiwordItaniumABI(interpreter)); 424 }); 425 } 426 427 void ItaniumABILanguageRuntime::Terminate() { 428 PluginManager::UnregisterPlugin(CreateInstance); 429 } 430 431 lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginNameStatic() { 432 static ConstString g_name("itanium"); 433 return g_name; 434 } 435 436 //------------------------------------------------------------------ 437 // PluginInterface protocol 438 //------------------------------------------------------------------ 439 lldb_private::ConstString ItaniumABILanguageRuntime::GetPluginName() { 440 return GetPluginNameStatic(); 441 } 442 443 uint32_t ItaniumABILanguageRuntime::GetPluginVersion() { return 1; } 444 445 BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver( 446 Breakpoint *bkpt, bool catch_bp, bool throw_bp) { 447 return CreateExceptionResolver(bkpt, catch_bp, throw_bp, false); 448 } 449 450 BreakpointResolverSP ItaniumABILanguageRuntime::CreateExceptionResolver( 451 Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions) { 452 // One complication here is that most users DON'T want to stop at 453 // __cxa_allocate_expression, but until we can do 454 // anything better with predicting unwinding the expression parser does. So 455 // we have two forms of the exception 456 // breakpoints, one for expressions that leaves out __cxa_allocate_exception, 457 // and one that includes it. 458 // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint 459 // in the runtime the former. 460 static const char *g_catch_name = "__cxa_begin_catch"; 461 static const char *g_throw_name1 = "__cxa_throw"; 462 static const char *g_throw_name2 = "__cxa_rethrow"; 463 static const char *g_exception_throw_name = "__cxa_allocate_exception"; 464 std::vector<const char *> exception_names; 465 exception_names.reserve(4); 466 if (catch_bp) 467 exception_names.push_back(g_catch_name); 468 469 if (throw_bp) { 470 exception_names.push_back(g_throw_name1); 471 exception_names.push_back(g_throw_name2); 472 } 473 474 if (for_expressions) 475 exception_names.push_back(g_exception_throw_name); 476 477 BreakpointResolverSP resolver_sp(new BreakpointResolverName( 478 bkpt, exception_names.data(), exception_names.size(), 479 eFunctionNameTypeBase, eLanguageTypeUnknown, 0, eLazyBoolNo)); 480 481 return resolver_sp; 482 } 483 484 lldb::SearchFilterSP ItaniumABILanguageRuntime::CreateExceptionSearchFilter() { 485 Target &target = m_process->GetTarget(); 486 487 if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) { 488 // Limit the number of modules that are searched for these breakpoints for 489 // Apple binaries. 490 FileSpecList filter_modules; 491 filter_modules.Append(FileSpec("libc++abi.dylib", false)); 492 filter_modules.Append(FileSpec("libSystem.B.dylib", false)); 493 return target.GetSearchFilterForModuleList(&filter_modules); 494 } else { 495 return LanguageRuntime::CreateExceptionSearchFilter(); 496 } 497 } 498 499 lldb::BreakpointSP ItaniumABILanguageRuntime::CreateExceptionBreakpoint( 500 bool catch_bp, bool throw_bp, bool for_expressions, bool is_internal) { 501 Target &target = m_process->GetTarget(); 502 FileSpecList filter_modules; 503 BreakpointResolverSP exception_resolver_sp = 504 CreateExceptionResolver(NULL, catch_bp, throw_bp, for_expressions); 505 SearchFilterSP filter_sp(CreateExceptionSearchFilter()); 506 const bool hardware = false; 507 const bool resolve_indirect_functions = false; 508 return target.CreateBreakpoint(filter_sp, exception_resolver_sp, is_internal, 509 hardware, resolve_indirect_functions); 510 } 511 512 void ItaniumABILanguageRuntime::SetExceptionBreakpoints() { 513 if (!m_process) 514 return; 515 516 const bool catch_bp = false; 517 const bool throw_bp = true; 518 const bool is_internal = true; 519 const bool for_expressions = true; 520 521 // For the exception breakpoints set by the Expression parser, we'll be a 522 // little more aggressive and 523 // stop at exception allocation as well. 524 525 if (m_cxx_exception_bp_sp) { 526 m_cxx_exception_bp_sp->SetEnabled(true); 527 } else { 528 m_cxx_exception_bp_sp = CreateExceptionBreakpoint( 529 catch_bp, throw_bp, for_expressions, is_internal); 530 if (m_cxx_exception_bp_sp) 531 m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception"); 532 } 533 } 534 535 void ItaniumABILanguageRuntime::ClearExceptionBreakpoints() { 536 if (!m_process) 537 return; 538 539 if (m_cxx_exception_bp_sp) { 540 m_cxx_exception_bp_sp->SetEnabled(false); 541 } 542 } 543 544 bool ItaniumABILanguageRuntime::ExceptionBreakpointsAreSet() { 545 return m_cxx_exception_bp_sp && m_cxx_exception_bp_sp->IsEnabled(); 546 } 547 548 bool ItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop( 549 lldb::StopInfoSP stop_reason) { 550 if (!m_process) 551 return false; 552 553 if (!stop_reason || stop_reason->GetStopReason() != eStopReasonBreakpoint) 554 return false; 555 556 uint64_t break_site_id = stop_reason->GetValue(); 557 return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint( 558 break_site_id, m_cxx_exception_bp_sp->GetID()); 559 } 560 561 TypeAndOrName ItaniumABILanguageRuntime::GetDynamicTypeInfo( 562 const lldb_private::Address &vtable_addr) { 563 std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex); 564 DynamicTypeCache::const_iterator pos = m_dynamic_type_map.find(vtable_addr); 565 if (pos == m_dynamic_type_map.end()) 566 return TypeAndOrName(); 567 else 568 return pos->second; 569 } 570 571 void ItaniumABILanguageRuntime::SetDynamicTypeInfo( 572 const lldb_private::Address &vtable_addr, const TypeAndOrName &type_info) { 573 std::lock_guard<std::mutex> locker(m_dynamic_type_map_mutex); 574 m_dynamic_type_map[vtable_addr] = type_info; 575 } 576