bool lldb_private::formatters::swift::SwiftMetatype_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { lldb::addr_t metadata_ptr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); if (metadata_ptr == LLDB_INVALID_ADDRESS || metadata_ptr == 0) { CompilerType compiler_metatype_type(valobj.GetCompilerType()); CompilerType instancetype(compiler_metatype_type.GetInstanceType()); const char* ptr = instancetype.GetDisplayTypeName().AsCString(nullptr); if (ptr && *ptr) { stream.Printf("%s", ptr); return true; } } else { auto swift_runtime = valobj.GetProcessSP()->GetSwiftLanguageRuntime(); if (!swift_runtime) return false; SwiftLanguageRuntime::MetadataPromiseSP metadata_promise_sp = swift_runtime->GetMetadataPromise(metadata_ptr); if (CompilerType resolved_type = metadata_promise_sp->FulfillTypePromise()) { stream.Printf("%s", resolved_type.GetDisplayTypeName().AsCString()); return true; } } return false; }
std::vector<ConstString> ObjCLanguage::GetPossibleFormattersMatches (ValueObject& valobj, lldb::DynamicValueType use_dynamic) { std::vector<ConstString> result; if (use_dynamic == lldb::eNoDynamicValues) return result; CompilerType compiler_type(valobj.GetCompilerType()); const bool check_cpp = false; const bool check_objc = true; bool canBeObjCDynamic = compiler_type.IsPossibleDynamicType(nullptr, check_cpp, check_objc); if (canBeObjCDynamic) { do { lldb::ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) break; ObjCLanguageRuntime* runtime = process_sp->GetObjCLanguageRuntime(); if (runtime == nullptr) break; ObjCLanguageRuntime::ClassDescriptorSP objc_class_sp (runtime->GetClassDescriptor(valobj)); if (!objc_class_sp) break; if (ConstString name = objc_class_sp->GetClassName()) result.push_back(name); } while (false); } return result; }
bool lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stream& stream) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; ReadUTFBufferAndDumpToStreamOptions<UTF32> options; options.SetLocation(valobj_addr); options.SetConversionFunction(ConvertUTF32toUTF8); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken('U'); if (!ReadUTFBufferAndDumpToStream(options)) { stream.Printf("Summary Unavailable"); return true; } return true; }
bool lldb_private::formatters::swift::ObjC_Selector_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { static ConstString g_ptr("ptr"); static ConstString g__rawValue("_rawValue"); ValueObjectSP ptr_sp(valobj.GetChildAtNamePath({ g_ptr, g__rawValue })); if (!ptr_sp) return false; auto ptr_value = ptr_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); if (0 == ptr_value || LLDB_INVALID_ADDRESS == ptr_value) return false; StringPrinter::ReadStringAndDumpToStreamOptions read_options; read_options.SetLocation(ptr_value) .SetProcessSP(valobj.GetProcessSP()) .SetStream(&stream) .SetQuote('"') .SetNeedsZeroTermination(true) .SetLanguage(lldb::eLanguageTypeSwift); return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::ASCII>(read_options); }
bool lldb_private::formatters::swift::Metadata_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { ProcessSP process_sp(valobj.GetProcessSP()); if (!process_sp) return false; SwiftLanguageRuntime *runtime(process_sp->GetSwiftLanguageRuntime()); if (!runtime) return false; SwiftLanguageRuntime::MetadataSP metadata_sp(runtime->GetMetadataForLocation(valobj.GetValueAsUnsigned(0))); if (!metadata_sp) return false; if (SwiftLanguageRuntime::NominalTypeMetadata *nominal_type_metadata = llvm::dyn_cast<SwiftLanguageRuntime::NominalTypeMetadata>(metadata_sp.get())) { stream.Printf("typename=%s",nominal_type_metadata->GetMangledName().c_str()); Mangled mangled( ConstString(nominal_type_metadata->GetMangledName().c_str()) ); ConstString demangled = mangled.GetDemangledName(lldb::eLanguageTypeSwift); if (demangled) stream.Printf(" --> %s", demangled.GetCString()); return true; } if (SwiftLanguageRuntime::TupleMetadata *tuple_metadata = llvm::dyn_cast<SwiftLanguageRuntime::TupleMetadata>(metadata_sp.get())) { stream.Printf("tuple with %zu items",tuple_metadata->GetNumElements()); return true; } // what about other types? not sure return false; }
bool lldb_private::formatters::ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptorFromISA(valobj.GetValueAsUnsigned(0))); if (!descriptor.get() || !descriptor->IsValid()) return false; const char* class_name = descriptor->GetClassName().GetCString(); if (!class_name || !*class_name) return false; stream.Printf("%s",class_name); return true; }
bool lldb_private::formatters::ObjCClassSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptorFromISA(valobj.GetValueAsUnsigned(0))); if (!descriptor || !descriptor->IsValid()) return false; ConstString class_name = descriptor->GetClassName(); if (class_name.IsEmpty()) return false; if (ConstString cs = Mangled(class_name).GetDemangledName(lldb::eLanguageTypeUnknown)) class_name = cs; stream.Printf("%s",class_name.AsCString("<unknown class>")); return true; }
bool lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken('U'); if (!ReadStringAndDumpToStream<StringElementType::UTF32>(options)) { stream.Printf("Summary Unavailable"); return true; } return true; }
bool AppleObjCRuntime::GetObjectDescription (Stream &str, ValueObject &valobj) { CompilerType compiler_type(valobj.GetCompilerType()); bool is_signed; // ObjC objects can only be pointers (or numbers that actually represents pointers // but haven't been typecast, because reasons..) if (!compiler_type.IsIntegerType (is_signed) && !compiler_type.IsPointerType ()) return false; // Make the argument list: we pass one arg, the address of our pointer, to the print function. Value val; if (!valobj.ResolveValue(val.GetScalar())) return false; // Value Objects may not have a process in their ExecutionContextRef. But we need to have one // in the ref we pass down to eventually call description. Get it from the target if it isn't // present. ExecutionContext exe_ctx; if (valobj.GetProcessSP()) { exe_ctx = ExecutionContext(valobj.GetExecutionContextRef()); } else { exe_ctx.SetContext(valobj.GetTargetSP(), true); if (!exe_ctx.HasProcessScope()) return false; } return GetObjectDescription(str, val, exe_ctx.GetBestExecutionContextScope()); }
bool lldb_private::formatters::Char32StringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) return false; StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken("U"); if (!StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF32>(options)) { stream.Printf("Summary Unavailable"); return true; } return true; }
bool lldb_private::formatters::NSNumberSummaryProvider (ValueObject& valobj, Stream& stream) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor.get() || !descriptor->IsValid()) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; const char* class_name = descriptor->GetClassName().GetCString(); if (!class_name || !*class_name) return false; if (!strcmp(class_name,"NSNumber") || !strcmp(class_name,"__NSCFNumber")) { if (descriptor->IsTagged()) { // we have a call to get info and value bits in the tagged descriptor. but we prefer not to cast and replicate them int64_t value = (valobj_addr & ~0x0000000000000000FFL) >> 8; uint64_t i_bits = (valobj_addr & 0xF0) >> 4; switch (i_bits) { case 0: stream.Printf("(char)%hhd",(char)value); break; case 4: stream.Printf("(short)%hd",(short)value); break; case 8: stream.Printf("(int)%d",(int)value); break; case 12: stream.Printf("(long)%" PRId64,value); break; default: stream.Printf("unexpected value:(info=%" PRIu64 ", value=%" PRIu64,i_bits,value); break; } return true; } else {
bool lldb_private::formatters::NSError_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { ProcessSP process_sp(valobj.GetProcessSP()); if (!process_sp) return false; lldb::addr_t ptr_value = LLDB_INVALID_ADDRESS; CompilerType valobj_type(valobj.GetCompilerType()); Flags type_flags(valobj_type.GetTypeInfo()); if (type_flags.AllClear(eTypeHasValue)) { if (valobj.IsBaseClass() && valobj.GetParent()) ptr_value = valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); } else ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); if (ptr_value == LLDB_INVALID_ADDRESS) return false; size_t ptr_size = process_sp->GetAddressByteSize(); lldb::addr_t code_location = ptr_value + 2 * ptr_size; lldb::addr_t domain_location = ptr_value + 3 * ptr_size; Error error; uint64_t code = process_sp->ReadUnsignedIntegerFromMemory(code_location, ptr_size, 0, error); if (error.Fail()) return false; lldb::addr_t domain_str_value = process_sp->ReadPointerFromMemory(domain_location, error); if (error.Fail() || domain_str_value == LLDB_INVALID_ADDRESS) return false; if (!domain_str_value) { stream.Printf("domain: nil - code: %" PRIu64, code); return true; } InferiorSizedWord isw(domain_str_value, *process_sp); ValueObjectSP domain_str_sp = ValueObject::CreateValueObjectFromData("domain_str", isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), process_sp->GetTarget().GetScratchClangASTContext()->GetBasicType(lldb::eBasicTypeVoid).GetPointerType()); if (!domain_str_sp) return false; StreamString domain_str_summary; if (NSStringSummaryProvider(*domain_str_sp, domain_str_summary, options) && !domain_str_summary.Empty()) { stream.Printf("domain: %s - code: %" PRIu64, domain_str_summary.GetData(), code); return true; } else { stream.Printf("domain: nil - code: %" PRIu64, code); return true; } }
AppleObjCRuntimeV1::ClassDescriptorV1::ClassDescriptorV1 (ValueObject &isa_pointer) { ObjCISA ptr_value = isa_pointer.GetValueAsUnsigned(0); lldb::ProcessSP process_sp = isa_pointer.GetProcessSP(); Initialize (ptr_value,process_sp); }
bool lldb_private::formatters::NSDataSummaryProvider (ValueObject& valobj, Stream& stream) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor.get() || !descriptor->IsValid()) return false; bool is_64bit = (process_sp->GetAddressByteSize() == 8); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; uint64_t value = 0; const char* class_name = descriptor->GetClassName().GetCString(); if (!class_name || !*class_name) return false; if (!strcmp(class_name,"NSConcreteData") || !strcmp(class_name,"NSConcreteMutableData") || !strcmp(class_name,"__NSCFData")) { uint32_t offset = (is_64bit ? 16 : 8); Error error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + offset, is_64bit ? 8 : 4, 0, error); if (error.Fail()) return false; } else { if (!ExtractValueFromObjCExpression(valobj, "int", "length", value)) return false; } stream.Printf("%s%" PRIu64 " byte%s%s", (needs_at ? "@\"" : ""), value, (value > 1 ? "s" : ""), (needs_at ? "\"" : "")); return true; }
std::unique_ptr<SwiftHashedContainerBufferHandler> SwiftHashedContainerBufferHandler::CreateBufferHandlerForNativeStorageOwner (ValueObject &valobj, lldb::addr_t storage_ptr, bool fail_on_no_children, NativeCreatorFunction Native) { #if 0 static ConstString g_Native("native"); static ConstString g_nativeStorage("nativeStorage"); static ConstString g_buffer("buffer"); Error error; ProcessSP process_sp(valobj.GetProcessSP()); if (!process_sp) return nullptr; ValueObjectSP native_sp(valobj.GetChildAtNamePath( {g_Native, g_nativeStorage, g_buffer} )); if (!native_sp) { if (fail_on_no_children) return nullptr; else { lldb::addr_t native_storage_ptr = storage_ptr + (3 * process_sp->GetAddressByteSize()); native_storage_ptr = process_sp->ReadPointerFromMemory(native_storage_ptr, error); // (AnyObject,AnyObject)? SwiftASTContext *swift_ast_ctx = process_sp->GetTarget().GetScratchSwiftASTContext(error); if (swift_ast_ctx) { CompilerType element_type(swift_ast_ctx->GetTypeFromMangledTypename("_TtGSqTPs9AnyObject_PS____", error)); auto handler = std::unique_ptr<SwiftHashedContainerBufferHandler>(Native(valobj, native_storage_ptr, element_type)); if (handler && handler->IsValid()) return handler; } return nullptr; } } CompilerType child_type(native_sp->GetCompilerType()); lldb::TemplateArgumentKind kind; CompilerType element_type(child_type.GetTemplateArgument(1, kind)); if (element_type.IsValid() == false || kind != lldb::eTemplateArgumentKindType) return nullptr; lldb::addr_t native_storage_ptr = process_sp->ReadPointerFromMemory(storage_ptr + 2*process_sp->GetAddressByteSize(), error); if (error.Fail() || native_storage_ptr == LLDB_INVALID_ADDRESS) return nullptr; auto handler = std::unique_ptr<SwiftHashedContainerBufferHandler>(Native(valobj, native_storage_ptr, element_type)); if (handler && handler->IsValid()) return handler; #endif return nullptr; }
bool lldb_private::formatters::GoStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; if (valobj.IsPointerType()) { Error err; ValueObjectSP deref = valobj.Dereference(err); if (!err.Success()) return false; return GoStringSummaryProvider(*deref, stream, opts); } ConstString str_name("str"); ConstString len_name("len"); ValueObjectSP data_sp = valobj.GetChildMemberWithName(str_name, true); ValueObjectSP len_sp = valobj.GetChildMemberWithName(len_name, true); if (!data_sp || !len_sp) return false; bool success; lldb::addr_t valobj_addr = data_sp->GetValueAsUnsigned(0, &success); if (!success) return false; uint64_t length = len_sp->GetValueAsUnsigned(0); if (length == 0) { stream.Printf("\"\""); return true; } StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetSourceSize(length); options.SetNeedsZeroTermination(false); options.SetLanguage(eLanguageTypeGo); if (!StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF8>(options)) { stream.Printf("Summary Unavailable"); return true; } return true; }
bool lldb_private::formatters::swift::StaticString_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& summary_options, StringPrinter::ReadStringAndDumpToStreamOptions read_options) { static ConstString g__startPtrOrData("_startPtrOrData"); static ConstString g__byteSize("_utf8CodeUnitCount"); static ConstString g__flags("_flags"); ValueObjectSP flags_sp(valobj.GetChildMemberWithName(g__flags, true)); if (!flags_sp) return false; ProcessSP process_sp(valobj.GetProcessSP()); if (!process_sp) return false; // 0 == pointer representation InferiorSizedWord flags(flags_sp->GetValueAsUnsigned(0), *process_sp); if (0 != (flags & 0x1).GetValue()) return false; ValueObjectSP startptr_sp(valobj.GetChildMemberWithName(g__startPtrOrData, true)); ValueObjectSP bytesize_sp(valobj.GetChildMemberWithName(g__byteSize, true)); if (!startptr_sp || !bytesize_sp) return false; lldb::addr_t start_ptr = startptr_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); uint64_t size = bytesize_sp->GetValueAsUnsigned(0); if (start_ptr == LLDB_INVALID_ADDRESS || start_ptr == 0) return false; if (size == 0) { stream.Printf("\"\""); return true; } read_options.SetProcessSP(process_sp); read_options.SetLocation(start_ptr); read_options.SetSourceSize(size); read_options.SetBinaryZeroIsTerminator(false); read_options.SetNeedsZeroTermination(false); read_options.SetStream(&stream); read_options.SetIgnoreMaxLength(summary_options.GetCapping() == lldb::eTypeSummaryUncapped); read_options.SetLanguage(lldb::eLanguageTypeSwift); return StringPrinter::ReadStringAndDumpToStream<StringPrinter::StringElementType::UTF8>(read_options); }
bool lldb_private::formatters::NSMachPortSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor.get() || !descriptor->IsValid()) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; const char* class_name = descriptor->GetClassName().GetCString(); if (!class_name || !*class_name) return false; uint64_t port_number = 0; do { if (!strcmp(class_name,"NSMachPort")) { uint64_t offset = (ptr_size == 4 ? 12 : 20); Error error; port_number = process_sp->ReadUnsignedIntegerFromMemory(offset+valobj_addr, 4, 0, error); if (error.Success()) break; } if (!ExtractValueFromObjCExpression(valobj, "int", "machPort", port_number)) return false; } while (false); stream.Printf("mach port: %u",(uint32_t)(port_number & 0x00000000FFFFFFFF)); return true; }
bool lldb_private::formatters::JavaStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &opts) { if (valobj.IsPointerOrReferenceType()) { Error error; ValueObjectSP deref = valobj.Dereference(error); if (error.Fail()) return false; return JavaStringSummaryProvider(*deref, stream, opts); } ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ConstString data_name("value"); ConstString length_name("count"); ValueObjectSP length_sp = valobj.GetChildMemberWithName(length_name, true); ValueObjectSP data_sp = valobj.GetChildMemberWithName(data_name, true); if (!data_sp || !length_sp) return false; bool success = false; uint64_t length = length_sp->GetValueAsUnsigned(0, &success); if (!success) return false; if (length == 0) { stream.Printf("\"\""); return true; } lldb::addr_t valobj_addr = data_sp->GetAddressOf(); StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetSourceSize(length); options.SetNeedsZeroTermination(false); options.SetLanguage(eLanguageTypeJava); if (StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF16>(options)) return true; stream.Printf("Summary Unavailable"); return true; }
bool lldb_private::formatters::LibStdcppStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { const bool scalar_is_load_addr = true; AddressType addr_type; lldb::addr_t addr_of_string = valobj.GetAddressOf(scalar_is_load_addr, &addr_type); if (addr_of_string != LLDB_INVALID_ADDRESS) { switch (addr_type) { case eAddressTypeLoad: { ProcessSP process_sp(valobj.GetProcessSP()); if (!process_sp) return false; StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); Error error; lldb::addr_t addr_of_data = process_sp->ReadPointerFromMemory(addr_of_string, error); if (error.Fail() || addr_of_data == 0 || addr_of_data == LLDB_INVALID_ADDRESS) return false; options.SetLocation(addr_of_data); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetNeedsZeroTermination(false); options.SetBinaryZeroIsTerminator(true); lldb::addr_t size_of_data = process_sp->ReadPointerFromMemory( addr_of_string + process_sp->GetAddressByteSize(), error); if (error.Fail()) return false; options.SetSourceSize(size_of_data); if (!StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF8>(options)) { stream.Printf("Summary Unavailable"); return true; } else return true; } break; case eAddressTypeHost: break; case eAddressTypeInvalid: case eAddressTypeFile: break; } } return false; }
bool lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor.get() || !descriptor->IsValid()) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; const char* class_name = descriptor->GetClassName().GetCString(); if (!class_name || !*class_name) return false; if (!strcmp(class_name,"NSBundle")) { uint64_t offset = 5 * ptr_size; ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID), true)); StreamString summary_stream; bool was_nsstring_ok = NSStringSummaryProvider(*text.get(), summary_stream, options); if (was_nsstring_ok && summary_stream.GetSize() > 0) { stream.Printf("%s",summary_stream.GetData()); return true; } } // this is either an unknown subclass or an NSBundle that comes from [NSBundle mainBundle] // which is encoded differently and needs to be handled by running code return ExtractSummaryFromObjCExpression(valobj, "NSString*", "bundlePath", stream); }
bool lldb_private::formatters::NSBundleSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor || !descriptor->IsValid()) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; const char* class_name = descriptor->GetClassName().GetCString(); if (!class_name || !*class_name) return false; if (!strcmp(class_name,"NSBundle")) { uint64_t offset = 5 * ptr_size; ValueObjectSP text(valobj.GetSyntheticChildAtOffset(offset, valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeObjCID), true)); StreamString summary_stream; bool was_nsstring_ok = NSStringSummaryProvider(*text, summary_stream, options); if (was_nsstring_ok && summary_stream.GetSize() > 0) { stream.Printf("%s",summary_stream.GetData()); return true; } } return false; }
bool lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions&) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; lldb::addr_t data_addr = 0; if (valobj.IsPointerType()) data_addr = valobj.GetValueAsUnsigned(0); else if (valobj.IsArrayType()) data_addr = valobj.GetAddressOf(); if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS) return false; clang::ASTContext* ast = valobj.GetClangType().GetASTContext(); if (!ast) return false; ClangASTType wchar_clang_type = ClangASTContext::GetBasicType(ast, lldb::eBasicTypeWChar); const uint32_t wchar_size = wchar_clang_type.GetBitSize(nullptr); // Safe to pass NULL for exe_scope here ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(data_addr); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken('L'); switch (wchar_size) { case 8: return ReadStringAndDumpToStream<StringElementType::UTF8>(options); case 16: return ReadStringAndDumpToStream<StringElementType::UTF16>(options); case 32: return ReadStringAndDumpToStream<StringElementType::UTF32>(options); default: stream.Printf("size for wchar_t is not valid"); return true; } return true; }
bool lldb_private::formatters::WCharStringSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; lldb::addr_t valobj_addr = GetArrayAddressOrPointerValue(valobj); if (valobj_addr == 0 || valobj_addr == LLDB_INVALID_ADDRESS) return false; // Get a wchar_t basic type from the current type system CompilerType wchar_compiler_type = valobj.GetCompilerType().GetBasicTypeFromAST(lldb::eBasicTypeWChar); if (!wchar_compiler_type) return false; const uint32_t wchar_size = wchar_compiler_type.GetBitSize( nullptr); // Safe to pass NULL for exe_scope here StringPrinter::ReadStringAndDumpToStreamOptions options(valobj); options.SetLocation(valobj_addr); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken("L"); switch (wchar_size) { case 8: return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF8>(options); case 16: return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF16>(options); case 32: return StringPrinter::ReadStringAndDumpToStream< StringPrinter::StringElementType::UTF32>(options); default: stream.Printf("size for wchar_t is not valid"); return true; } return true; }
bool lldb_private::formatters::swift::NSContiguousString_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { static ConstString g_StringCoreType("_TtVs11_StringCore"); lldb::addr_t core_location = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); if (core_location == LLDB_INVALID_ADDRESS) return false; ProcessSP process_sp(valobj.GetProcessSP()); if (!process_sp) return false; size_t ptr_size = process_sp->GetAddressByteSize(); core_location += 2*ptr_size; Error error; InferiorSizedWord isw_1(process_sp->ReadPointerFromMemory(core_location, error),*process_sp); InferiorSizedWord isw_2(process_sp->ReadPointerFromMemory(core_location+ptr_size, error),*process_sp); InferiorSizedWord isw_3(process_sp->ReadPointerFromMemory(core_location+ptr_size+ptr_size, error),*process_sp); DataBufferSP buffer_sp(new DataBufferHeap(3*ptr_size, 0)); uint8_t* buffer = buffer_sp->GetBytes(); buffer = isw_1.CopyToBuffer(buffer); buffer = isw_2.CopyToBuffer(buffer); buffer = isw_3.CopyToBuffer(buffer); DataExtractor data(buffer_sp, process_sp->GetByteOrder(), ptr_size); SwiftASTContext* lldb_swift_ast = process_sp->GetTarget().GetScratchSwiftASTContext(error); if (!lldb_swift_ast) return false; CompilerType string_core_type = lldb_swift_ast->GetTypeFromMangledTypename(g_StringCoreType.GetCString(), error); if (string_core_type.IsValid() == false) return false; ValueObjectSP string_core_sp = ValueObject::CreateValueObjectFromData("stringcore", data, valobj.GetExecutionContextRef(), string_core_type); if (string_core_sp) return StringCore_SummaryProvider(*string_core_sp, stream, options); return false; }
static lldb::addr_t DerefToNSErrorPointer(ValueObject &valobj) { CompilerType valobj_type(valobj.GetCompilerType()); Flags type_flags(valobj_type.GetTypeInfo()); if (type_flags.AllClear(eTypeHasValue)) { if (valobj.IsBaseClass() && valobj.GetParent()) return valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); } else { lldb::addr_t ptr_value = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); if (type_flags.AllSet(eTypeIsPointer)) { CompilerType pointee_type(valobj_type.GetPointeeType()); Flags pointee_flags(pointee_type.GetTypeInfo()); if (pointee_flags.AllSet(eTypeIsPointer)) { if (ProcessSP process_sp = valobj.GetProcessSP()) { Status error; ptr_value = process_sp->ReadPointerFromMemory(ptr_value, error); } } } return ptr_value; } return LLDB_INVALID_ADDRESS; }
bool lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor.get() || !descriptor->IsValid()) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; uint32_t count = 0; bool is_type_ok = false; // check to see if this is a CFBag we know about if (descriptor->IsCFType()) { ConstString type_name(valobj.GetTypeName()); if (type_name == ConstString("__CFBag") || type_name == ConstString("const struct __CFBag")) { if (valobj.IsPointerType()) is_type_ok = true; } } if (is_type_ok == false) { StackFrameSP frame_sp(valobj.GetFrameSP()); if (!frame_sp) return false; ValueObjectSP count_sp; StreamString expr; expr.Printf("(int)CFBagGetCount((void*)0x%" PRIx64 ")",valobj.GetPointerValue()); if (process_sp->GetTarget().EvaluateExpression(expr.GetData(), frame_sp.get(), count_sp) != eExecutionCompleted) return false; if (!count_sp) return false; count = count_sp->GetValueAsUnsigned(0); } else { uint32_t offset = 2*ptr_size+4 + valobj_addr; Error error; count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error); if (error.Fail()) return false; } stream.Printf("@\"%u value%s\"", count,(count == 1 ? "" : "s")); return true; }
bool lldb_private::formatters::CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor.get() || !descriptor->IsValid()) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; uint32_t count = 0; bool is_type_ok = false; // check to see if this is a CFBag we know about if (descriptor->IsCFType()) { ConstString type_name(valobj.GetTypeName()); if (type_name == ConstString("__CFMutableBitVector") || type_name == ConstString("__CFBitVector") || type_name == ConstString("CFMutableBitVectorRef") || type_name == ConstString("CFBitVectorRef")) { if (valobj.IsPointerType()) is_type_ok = true; } } if (is_type_ok == false) return false; Error error; count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error); if (error.Fail()) return false; uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0); addr_t data_ptr = process_sp->ReadPointerFromMemory(valobj_addr+2*ptr_size+2*ptr_size, error); if (error.Fail()) return false; // make sure we do not try to read huge amounts of data if (num_bytes > 1024) num_bytes = 1024; DataBufferSP buffer_sp(new DataBufferHeap(num_bytes,0)); num_bytes = process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error); if (error.Fail() || num_bytes == 0) return false; uint8_t *bytes = buffer_sp->GetBytes(); for (uint64_t byte_idx = 0; byte_idx < num_bytes-1; byte_idx++) { uint8_t byte = bytes[byte_idx]; bool bit0 = (byte & 1) == 1; bool bit1 = (byte & 2) == 2; bool bit2 = (byte & 4) == 4; bool bit3 = (byte & 8) == 8; bool bit4 = (byte & 16) == 16; bool bit5 = (byte & 32) == 32; bool bit6 = (byte & 64) == 64; bool bit7 = (byte & 128) == 128; stream.Printf("%c%c%c%c %c%c%c%c ", (bit7 ? '1' : '0'), (bit6 ? '1' : '0'), (bit5 ? '1' : '0'), (bit4 ? '1' : '0'), (bit3 ? '1' : '0'), (bit2 ? '1' : '0'), (bit1 ? '1' : '0'), (bit0 ? '1' : '0')); count -= 8; } { // print the last byte ensuring we do not print spurious bits uint8_t byte = bytes[num_bytes-1]; bool bit0 = (byte & 1) == 1; bool bit1 = (byte & 2) == 2; bool bit2 = (byte & 4) == 4; bool bit3 = (byte & 8) == 8; bool bit4 = (byte & 16) == 16; bool bit5 = (byte & 32) == 32; bool bit6 = (byte & 64) == 64; bool bit7 = (byte & 128) == 128; if (count) { stream.Printf("%c",bit7 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit6 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit5 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit4 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit3 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit2 ? '1' : '0'); count -= 1; } if (count) { stream.Printf("%c",bit1 ? '1' : '0'); count -= 1; } if (count) stream.Printf("%c",bit0 ? '1' : '0'); } return true; }
bool lldb_private::formatters::WCharStringSummaryProvider (ValueObject& valobj, Stream& stream) { ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; lldb::addr_t data_addr = 0; if (valobj.IsPointerType()) data_addr = valobj.GetValueAsUnsigned(0); else if (valobj.IsArrayType()) data_addr = valobj.GetAddressOf(); if (data_addr == 0 || data_addr == LLDB_INVALID_ADDRESS) return false; clang::ASTContext* ast = valobj.GetClangType().GetASTContext(); if (!ast) return false; ClangASTType wchar_clang_type = ClangASTContext::GetBasicType(ast, lldb::eBasicTypeWChar); const uint32_t wchar_size = wchar_clang_type.GetBitSize(); switch (wchar_size) { case 8: { // utf 8 ReadUTFBufferAndDumpToStreamOptions<UTF8> options; options.SetLocation(data_addr); options.SetConversionFunction(nullptr); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken('L'); return ReadUTFBufferAndDumpToStream(options); } case 16: { // utf 16 ReadUTFBufferAndDumpToStreamOptions<UTF16> options; options.SetLocation(data_addr); options.SetConversionFunction(ConvertUTF16toUTF8); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken('L'); return ReadUTFBufferAndDumpToStream(options); } case 32: { // utf 32 ReadUTFBufferAndDumpToStreamOptions<UTF32> options; options.SetLocation(data_addr); options.SetConversionFunction(ConvertUTF32toUTF8); options.SetProcessSP(process_sp); options.SetStream(&stream); options.SetPrefixToken('L'); return ReadUTFBufferAndDumpToStream(options); } default: stream.Printf("size for wchar_t is not valid"); return true; } return true; }
bool lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { static ConstString g_TypeHint("CFBag"); ProcessSP process_sp = valobj.GetProcessSP(); if (!process_sp) return false; ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC); if (!runtime) return false; ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj)); if (!descriptor.get() || !descriptor->IsValid()) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0); if (!valobj_addr) return false; uint32_t count = 0; bool is_type_ok = false; // check to see if this is a CFBag we know about if (descriptor->IsCFType()) { ConstString type_name(valobj.GetTypeName()); static ConstString g___CFBag("__CFBag"); static ConstString g_conststruct__CFBag("const struct __CFBag"); if (type_name == g___CFBag || type_name == g_conststruct__CFBag) { if (valobj.IsPointerType()) is_type_ok = true; } } if (is_type_ok) { lldb::addr_t offset = 2*ptr_size+4 + valobj_addr; Error error; count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error); if (error.Fail()) return false; } else return false; std::string prefix,suffix; if (Language* language = Language::FindPlugin(options.GetLanguage())) { if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix)) { prefix.clear(); suffix.clear(); } } stream.Printf("%s\"%u value%s\"%s", prefix.c_str(), count,(count == 1 ? "" : "s"), suffix.c_str()); return true; }