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