1254721Semaste//===-- ItaniumABILanguageRuntime.cpp --------------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "ItaniumABILanguageRuntime.h" 11254721Semaste 12254721Semaste#include "lldb/Breakpoint/BreakpointLocation.h" 13254721Semaste#include "lldb/Core/ConstString.h" 14254721Semaste#include "lldb/Core/Error.h" 15254721Semaste#include "lldb/Core/Log.h" 16254721Semaste#include "lldb/Core/Module.h" 17254721Semaste#include "lldb/Core/PluginManager.h" 18254721Semaste#include "lldb/Core/Scalar.h" 19254721Semaste#include "lldb/Core/ValueObject.h" 20254721Semaste#include "lldb/Core/ValueObjectMemory.h" 21254721Semaste#include "lldb/Symbol/ClangASTContext.h" 22254721Semaste#include "lldb/Symbol/Symbol.h" 23254721Semaste#include "lldb/Symbol/TypeList.h" 24254721Semaste#include "lldb/Target/Process.h" 25254721Semaste#include "lldb/Target/RegisterContext.h" 26269024Semaste#include "lldb/Target/SectionLoadList.h" 27254721Semaste#include "lldb/Target/StopInfo.h" 28254721Semaste#include "lldb/Target/Target.h" 29254721Semaste#include "lldb/Target/Thread.h" 30254721Semaste 31254721Semaste#include <vector> 32254721Semaste 33254721Semasteusing namespace lldb; 34254721Semasteusing namespace lldb_private; 35254721Semaste 36254721Semastestatic const char *vtable_demangled_prefix = "vtable for "; 37254721Semaste 38254721Semastebool 39254721SemasteItaniumABILanguageRuntime::CouldHaveDynamicValue (ValueObject &in_value) 40254721Semaste{ 41254721Semaste const bool check_cxx = true; 42254721Semaste const bool check_objc = false; 43254721Semaste return in_value.GetClangType().IsPossibleDynamicType (NULL, check_cxx, check_objc); 44254721Semaste} 45254721Semaste 46254721Semastebool 47254721SemasteItaniumABILanguageRuntime::GetDynamicTypeAndAddress (ValueObject &in_value, 48254721Semaste lldb::DynamicValueType use_dynamic, 49254721Semaste TypeAndOrName &class_type_or_name, 50254721Semaste Address &dynamic_address) 51254721Semaste{ 52254721Semaste // For Itanium, if the type has a vtable pointer in the object, it will be at offset 0 53254721Semaste // in the object. That will point to the "address point" within the vtable (not the beginning of the 54254721Semaste // vtable.) We can then look up the symbol containing this "address point" and that symbol's name 55254721Semaste // demangled will contain the full class name. 56254721Semaste // The second pointer above the "address point" is the "offset_to_top". We'll use that to get the 57254721Semaste // start of the value object which holds the dynamic type. 58254721Semaste // 59254721Semaste 60254721Semaste class_type_or_name.Clear(); 61254721Semaste 62254721Semaste // Only a pointer or reference type can have a different dynamic and static type: 63254721Semaste if (CouldHaveDynamicValue (in_value)) 64254721Semaste { 65254721Semaste // First job, pull out the address at 0 offset from the object. 66254721Semaste AddressType address_type; 67254721Semaste lldb::addr_t original_ptr = in_value.GetPointerValue(&address_type); 68254721Semaste if (original_ptr == LLDB_INVALID_ADDRESS) 69254721Semaste return false; 70254721Semaste 71254721Semaste ExecutionContext exe_ctx (in_value.GetExecutionContextRef()); 72254721Semaste 73254721Semaste Target *target = exe_ctx.GetTargetPtr(); 74254721Semaste Process *process = exe_ctx.GetProcessPtr(); 75254721Semaste 76254721Semaste char memory_buffer[16]; 77254721Semaste DataExtractor data(memory_buffer, sizeof(memory_buffer), 78254721Semaste process->GetByteOrder(), 79254721Semaste process->GetAddressByteSize()); 80254721Semaste size_t address_byte_size = process->GetAddressByteSize(); 81254721Semaste Error error; 82254721Semaste size_t bytes_read = process->ReadMemory (original_ptr, 83254721Semaste memory_buffer, 84254721Semaste address_byte_size, 85254721Semaste error); 86254721Semaste if (!error.Success() || (bytes_read != address_byte_size)) 87254721Semaste { 88254721Semaste return false; 89254721Semaste } 90254721Semaste 91254721Semaste lldb::offset_t offset = 0; 92254721Semaste lldb::addr_t vtable_address_point = data.GetAddress (&offset); 93254721Semaste 94254721Semaste if (offset == 0) 95254721Semaste return false; 96254721Semaste 97254721Semaste // Now find the symbol that contains this address: 98254721Semaste 99254721Semaste SymbolContext sc; 100254721Semaste Address address_point_address; 101254721Semaste if (target && !target->GetSectionLoadList().IsEmpty()) 102254721Semaste { 103254721Semaste if (target->GetSectionLoadList().ResolveLoadAddress (vtable_address_point, address_point_address)) 104254721Semaste { 105254721Semaste target->GetImages().ResolveSymbolContextForAddress (address_point_address, eSymbolContextSymbol, sc); 106254721Semaste Symbol *symbol = sc.symbol; 107254721Semaste if (symbol != NULL) 108254721Semaste { 109254721Semaste const char *name = symbol->GetMangled().GetDemangledName().AsCString(); 110254721Semaste if (strstr(name, vtable_demangled_prefix) == name) 111254721Semaste { 112254721Semaste Log *log (lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT)); 113254721Semaste if (log) 114254721Semaste log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has vtable symbol '%s'\n", 115254721Semaste original_ptr, 116254721Semaste in_value.GetTypeName().GetCString(), 117254721Semaste name); 118254721Semaste // We are a C++ class, that's good. Get the class name and look it up: 119254721Semaste const char *class_name = name + strlen(vtable_demangled_prefix); 120254721Semaste class_type_or_name.SetName (class_name); 121254721Semaste const bool exact_match = true; 122254721Semaste TypeList class_types; 123254721Semaste 124254721Semaste uint32_t num_matches = 0; 125254721Semaste // First look in the module that the vtable symbol came from 126254721Semaste // and look for a single exact match. 127254721Semaste if (sc.module_sp) 128254721Semaste { 129254721Semaste num_matches = sc.module_sp->FindTypes (sc, 130254721Semaste ConstString(class_name), 131254721Semaste exact_match, 132254721Semaste 1, 133254721Semaste class_types); 134254721Semaste } 135254721Semaste 136254721Semaste // If we didn't find a symbol, then move on to the entire 137254721Semaste // module list in the target and get as many unique matches 138254721Semaste // as possible 139254721Semaste if (num_matches == 0) 140254721Semaste { 141254721Semaste num_matches = target->GetImages().FindTypes (sc, 142254721Semaste ConstString(class_name), 143254721Semaste exact_match, 144254721Semaste UINT32_MAX, 145254721Semaste class_types); 146254721Semaste } 147254721Semaste 148254721Semaste lldb::TypeSP type_sp; 149254721Semaste if (num_matches == 0) 150254721Semaste { 151254721Semaste if (log) 152254721Semaste log->Printf("0x%16.16" PRIx64 ": is not dynamic\n", original_ptr); 153254721Semaste return false; 154254721Semaste } 155254721Semaste if (num_matches == 1) 156254721Semaste { 157254721Semaste type_sp = class_types.GetTypeAtIndex(0); 158254721Semaste if (log) 159254721Semaste log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has dynamic type: uid={0x%" PRIx64 "}, type-name='%s'\n", 160254721Semaste original_ptr, 161254721Semaste in_value.GetTypeName().AsCString(), 162254721Semaste type_sp->GetID(), 163254721Semaste type_sp->GetName().GetCString()); 164254721Semaste 165254721Semaste class_type_or_name.SetTypeSP(class_types.GetTypeAtIndex(0)); 166254721Semaste } 167254721Semaste else if (num_matches > 1) 168254721Semaste { 169254721Semaste size_t i; 170254721Semaste if (log) 171254721Semaste { 172254721Semaste for (i = 0; i < num_matches; i++) 173254721Semaste { 174254721Semaste type_sp = class_types.GetTypeAtIndex(i); 175254721Semaste if (type_sp) 176254721Semaste { 177254721Semaste if (log) 178254721Semaste log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types: uid={0x%" PRIx64 "}, type-name='%s'\n", 179254721Semaste original_ptr, 180254721Semaste in_value.GetTypeName().AsCString(), 181254721Semaste type_sp->GetID(), 182254721Semaste type_sp->GetName().GetCString()); 183254721Semaste } 184254721Semaste } 185254721Semaste } 186254721Semaste 187254721Semaste for (i = 0; i < num_matches; i++) 188254721Semaste { 189254721Semaste type_sp = class_types.GetTypeAtIndex(i); 190254721Semaste if (type_sp) 191254721Semaste { 192254721Semaste if (type_sp->GetClangFullType().IsCXXClassType()) 193254721Semaste { 194254721Semaste if (log) 195254721Semaste log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, picking this one: uid={0x%" PRIx64 "}, type-name='%s'\n", 196254721Semaste original_ptr, 197254721Semaste in_value.GetTypeName().AsCString(), 198254721Semaste type_sp->GetID(), 199254721Semaste type_sp->GetName().GetCString()); 200254721Semaste class_type_or_name.SetTypeSP(type_sp); 201254721Semaste break; 202254721Semaste } 203254721Semaste } 204254721Semaste } 205254721Semaste 206254721Semaste if (i == num_matches) 207254721Semaste { 208254721Semaste if (log) 209254721Semaste log->Printf ("0x%16.16" PRIx64 ": static-type = '%s' has multiple matching dynamic types, didn't find a C++ match\n", 210254721Semaste original_ptr, 211254721Semaste in_value.GetTypeName().AsCString()); 212254721Semaste return false; 213254721Semaste } 214254721Semaste } 215254721Semaste 216254721Semaste // There can only be one type with a given name, 217254721Semaste // so we've just found duplicate definitions, and this 218254721Semaste // one will do as well as any other. 219254721Semaste // We don't consider something to have a dynamic type if 220254721Semaste // it is the same as the static type. So compare against 221254721Semaste // the value we were handed. 222254721Semaste if (type_sp) 223254721Semaste { 224254721Semaste if (ClangASTContext::AreTypesSame (in_value.GetClangType(), 225254721Semaste type_sp->GetClangFullType())) 226254721Semaste { 227254721Semaste // The dynamic type we found was the same type, 228254721Semaste // so we don't have a dynamic type here... 229254721Semaste return false; 230254721Semaste } 231254721Semaste 232254721Semaste // The offset_to_top is two pointers above the address. 233254721Semaste Address offset_to_top_address = address_point_address; 234254721Semaste int64_t slide = -2 * ((int64_t) target->GetArchitecture().GetAddressByteSize()); 235254721Semaste offset_to_top_address.Slide (slide); 236254721Semaste 237254721Semaste Error error; 238254721Semaste lldb::addr_t offset_to_top_location = offset_to_top_address.GetLoadAddress(target); 239254721Semaste 240254721Semaste size_t bytes_read = process->ReadMemory (offset_to_top_location, 241254721Semaste memory_buffer, 242254721Semaste address_byte_size, 243254721Semaste error); 244254721Semaste 245254721Semaste if (!error.Success() || (bytes_read != address_byte_size)) 246254721Semaste { 247254721Semaste return false; 248254721Semaste } 249254721Semaste 250254721Semaste offset = 0; 251254721Semaste int64_t offset_to_top = data.GetMaxS64(&offset, process->GetAddressByteSize()); 252254721Semaste 253254721Semaste // So the dynamic type is a value that starts at offset_to_top 254254721Semaste // above the original address. 255254721Semaste lldb::addr_t dynamic_addr = original_ptr + offset_to_top; 256254721Semaste if (!target->GetSectionLoadList().ResolveLoadAddress (dynamic_addr, dynamic_address)) 257254721Semaste { 258254721Semaste dynamic_address.SetRawAddress(dynamic_addr); 259254721Semaste } 260254721Semaste return true; 261254721Semaste } 262254721Semaste } 263254721Semaste } 264254721Semaste } 265254721Semaste } 266254721Semaste } 267254721Semaste 268254721Semaste return class_type_or_name.IsEmpty() == false; 269254721Semaste} 270254721Semaste 271254721Semastebool 272254721SemasteItaniumABILanguageRuntime::IsVTableName (const char *name) 273254721Semaste{ 274254721Semaste if (name == NULL) 275254721Semaste return false; 276254721Semaste 277254721Semaste // Can we maybe ask Clang about this? 278254721Semaste if (strstr (name, "_vptr$") == name) 279254721Semaste return true; 280254721Semaste else 281254721Semaste return false; 282254721Semaste} 283254721Semaste 284254721Semaste//------------------------------------------------------------------ 285254721Semaste// Static Functions 286254721Semaste//------------------------------------------------------------------ 287254721SemasteLanguageRuntime * 288254721SemasteItaniumABILanguageRuntime::CreateInstance (Process *process, lldb::LanguageType language) 289254721Semaste{ 290254721Semaste // FIXME: We have to check the process and make sure we actually know that this process supports 291254721Semaste // the Itanium ABI. 292254721Semaste if (language == eLanguageTypeC_plus_plus) 293254721Semaste return new ItaniumABILanguageRuntime (process); 294254721Semaste else 295254721Semaste return NULL; 296254721Semaste} 297254721Semaste 298254721Semastevoid 299254721SemasteItaniumABILanguageRuntime::Initialize() 300254721Semaste{ 301254721Semaste PluginManager::RegisterPlugin (GetPluginNameStatic(), 302254721Semaste "Itanium ABI for the C++ language", 303254721Semaste CreateInstance); 304254721Semaste} 305254721Semaste 306254721Semastevoid 307254721SemasteItaniumABILanguageRuntime::Terminate() 308254721Semaste{ 309254721Semaste PluginManager::UnregisterPlugin (CreateInstance); 310254721Semaste} 311254721Semaste 312254721Semastelldb_private::ConstString 313254721SemasteItaniumABILanguageRuntime::GetPluginNameStatic() 314254721Semaste{ 315254721Semaste static ConstString g_name("itanium"); 316254721Semaste return g_name; 317254721Semaste} 318254721Semaste 319254721Semaste//------------------------------------------------------------------ 320254721Semaste// PluginInterface protocol 321254721Semaste//------------------------------------------------------------------ 322254721Semastelldb_private::ConstString 323254721SemasteItaniumABILanguageRuntime::GetPluginName() 324254721Semaste{ 325254721Semaste return GetPluginNameStatic(); 326254721Semaste} 327254721Semaste 328254721Semasteuint32_t 329254721SemasteItaniumABILanguageRuntime::GetPluginVersion() 330254721Semaste{ 331254721Semaste return 1; 332254721Semaste} 333254721Semaste 334254721SemasteBreakpointResolverSP 335254721SemasteItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp) 336254721Semaste{ 337254721Semaste return CreateExceptionResolver (bkpt, catch_bp, throw_bp, false); 338254721Semaste} 339254721Semaste 340254721SemasteBreakpointResolverSP 341254721SemasteItaniumABILanguageRuntime::CreateExceptionResolver (Breakpoint *bkpt, bool catch_bp, bool throw_bp, bool for_expressions) 342254721Semaste{ 343254721Semaste // One complication here is that most users DON'T want to stop at __cxa_allocate_expression, but until we can do 344254721Semaste // anything better with predicting unwinding the expression parser does. So we have two forms of the exception 345254721Semaste // breakpoints, one for expressions that leaves out __cxa_allocate_exception, and one that includes it. 346254721Semaste // The SetExceptionBreakpoints does the latter, the CreateExceptionBreakpoint in the runtime the former. 347254721Semaste static const char *g_catch_name = "__cxa_begin_catch"; 348254721Semaste static const char *g_throw_name1 = "__cxa_throw"; 349254721Semaste static const char *g_throw_name2 = "__cxa_rethrow"; 350254721Semaste static const char *g_exception_throw_name = "__cxa_allocate_exception"; 351254721Semaste std::vector<const char *> exception_names; 352254721Semaste exception_names.reserve(4); 353254721Semaste if (catch_bp) 354254721Semaste exception_names.push_back(g_catch_name); 355254721Semaste 356254721Semaste if (throw_bp) 357254721Semaste { 358254721Semaste exception_names.push_back(g_throw_name1); 359254721Semaste exception_names.push_back(g_throw_name2); 360254721Semaste } 361254721Semaste 362254721Semaste if (for_expressions) 363254721Semaste exception_names.push_back(g_exception_throw_name); 364254721Semaste 365254721Semaste BreakpointResolverSP resolver_sp (new BreakpointResolverName (bkpt, 366254721Semaste exception_names.data(), 367254721Semaste exception_names.size(), 368254721Semaste eFunctionNameTypeBase, 369254721Semaste eLazyBoolNo)); 370254721Semaste 371254721Semaste return resolver_sp; 372254721Semaste} 373254721Semaste 374254721Semaste 375254721Semaste 376254721Semastelldb::SearchFilterSP 377254721SemasteItaniumABILanguageRuntime::CreateExceptionSearchFilter () 378254721Semaste{ 379254721Semaste Target &target = m_process->GetTarget(); 380254721Semaste 381254721Semaste if (target.GetArchitecture().GetTriple().getVendor() == llvm::Triple::Apple) 382254721Semaste { 383254721Semaste // Limit the number of modules that are searched for these breakpoints for 384254721Semaste // Apple binaries. 385254721Semaste FileSpecList filter_modules; 386254721Semaste filter_modules.Append(FileSpec("libc++abi.dylib", false)); 387254721Semaste filter_modules.Append(FileSpec("libSystem.B.dylib", false)); 388254721Semaste return target.GetSearchFilterForModuleList(&filter_modules); 389254721Semaste } 390254721Semaste else 391254721Semaste { 392254721Semaste return LanguageRuntime::CreateExceptionSearchFilter(); 393254721Semaste } 394254721Semaste} 395254721Semaste 396254721Semastelldb::BreakpointSP 397254721SemasteItaniumABILanguageRuntime::CreateExceptionBreakpoint (bool catch_bp, 398254721Semaste bool throw_bp, 399254721Semaste bool for_expressions, 400254721Semaste bool is_internal) 401254721Semaste{ 402254721Semaste Target &target = m_process->GetTarget(); 403254721Semaste FileSpecList filter_modules; 404254721Semaste BreakpointResolverSP exception_resolver_sp = CreateExceptionResolver (NULL, catch_bp, throw_bp, for_expressions); 405254721Semaste SearchFilterSP filter_sp (CreateExceptionSearchFilter ()); 406269024Semaste const bool hardware = false; 407269024Semaste const bool resolve_indirect_functions = false; 408269024Semaste return target.CreateBreakpoint (filter_sp, exception_resolver_sp, is_internal, hardware, resolve_indirect_functions); 409254721Semaste} 410254721Semaste 411254721Semastevoid 412254721SemasteItaniumABILanguageRuntime::SetExceptionBreakpoints () 413254721Semaste{ 414254721Semaste if (!m_process) 415254721Semaste return; 416254721Semaste 417254721Semaste const bool catch_bp = false; 418254721Semaste const bool throw_bp = true; 419254721Semaste const bool is_internal = true; 420254721Semaste const bool for_expressions = true; 421254721Semaste 422254721Semaste // For the exception breakpoints set by the Expression parser, we'll be a little more aggressive and 423254721Semaste // stop at exception allocation as well. 424254721Semaste 425254721Semaste if (m_cxx_exception_bp_sp) 426254721Semaste { 427254721Semaste m_cxx_exception_bp_sp->SetEnabled (true); 428254721Semaste } 429254721Semaste else 430254721Semaste { 431254721Semaste m_cxx_exception_bp_sp = CreateExceptionBreakpoint (catch_bp, throw_bp, for_expressions, is_internal); 432254721Semaste if (m_cxx_exception_bp_sp) 433254721Semaste m_cxx_exception_bp_sp->SetBreakpointKind("c++ exception"); 434254721Semaste } 435254721Semaste 436254721Semaste} 437254721Semaste 438254721Semastevoid 439254721SemasteItaniumABILanguageRuntime::ClearExceptionBreakpoints () 440254721Semaste{ 441254721Semaste if (!m_process) 442254721Semaste return; 443254721Semaste 444254721Semaste if (m_cxx_exception_bp_sp) 445254721Semaste { 446254721Semaste m_cxx_exception_bp_sp->SetEnabled (false); 447254721Semaste } 448254721Semaste} 449254721Semaste 450254721Semastebool 451263367SemasteItaniumABILanguageRuntime::ExceptionBreakpointsAreSet () 452263367Semaste{ 453263367Semaste return m_cxx_exception_bp_sp && m_cxx_exception_bp_sp->IsEnabled(); 454263367Semaste} 455263367Semaste 456263367Semastebool 457254721SemasteItaniumABILanguageRuntime::ExceptionBreakpointsExplainStop (lldb::StopInfoSP stop_reason) 458254721Semaste{ 459254721Semaste if (!m_process) 460254721Semaste return false; 461254721Semaste 462254721Semaste if (!stop_reason || 463254721Semaste stop_reason->GetStopReason() != eStopReasonBreakpoint) 464254721Semaste return false; 465254721Semaste 466254721Semaste uint64_t break_site_id = stop_reason->GetValue(); 467254721Semaste return m_process->GetBreakpointSiteList().BreakpointSiteContainsBreakpoint(break_site_id, 468254721Semaste m_cxx_exception_bp_sp->GetID()); 469254721Semaste 470254721Semaste} 471