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