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; }
bool lldb_private::formatters::swift::BuiltinObjC_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { stream.Printf("0x%" PRIx64 " ",valobj.GetValueAsUnsigned(0)); stream.Printf("%s",valobj.GetObjectDescription()); return true; }
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::NSAttributedStringSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { TargetSP target_sp(valobj.GetTargetSP()); if (!target_sp) return false; uint32_t addr_size = target_sp->GetArchitecture().GetAddressByteSize(); uint64_t pointer_value = valobj.GetValueAsUnsigned(0); if (!pointer_value) return false; pointer_value += addr_size; CompilerType type(valobj.GetCompilerType()); ExecutionContext exe_ctx(target_sp,false); ValueObjectSP child_ptr_sp(valobj.CreateValueObjectFromAddress("string_ptr", pointer_value, exe_ctx, type)); if (!child_ptr_sp) return false; DataExtractor data; Error error; child_ptr_sp->GetData(data, error); if (error.Fail()) return false; ValueObjectSP child_sp(child_ptr_sp->CreateValueObjectFromData("string_data", data, exe_ctx, type)); child_sp->GetValueAsUnsigned(0); if (child_sp) return NSStringSummaryProvider(*child_sp, stream, options); return false; }
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::ObjCSELSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { lldb::ValueObjectSP valobj_sp; CompilerType charstar (valobj.GetCompilerType().GetBasicTypeFromAST(eBasicTypeChar).GetPointerType()); if (!charstar) return false; ExecutionContext exe_ctx(valobj.GetExecutionContextRef()); if (is_sel_ptr) { lldb::addr_t data_address = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); if (data_address == LLDB_INVALID_ADDRESS) return false; valobj_sp = ValueObject::CreateValueObjectFromAddress("text", data_address, exe_ctx, charstar); } else { DataExtractor data; Error error; valobj.GetData(data, error); if (error.Fail()) return false; valobj_sp = ValueObject::CreateValueObjectFromData("text", data, exe_ctx, charstar); } if (!valobj_sp) return false; stream.Printf("%s",valobj_sp->GetSummaryAsCString()); 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 OCamlLanguage::IsNilReference(ValueObject &valobj) { if (!valobj.GetCompilerType().IsReferenceType()) return false; // If we failed to read the value then it is not a nil reference. return valobj.GetValueAsUnsigned(UINT64_MAX) == 0; }
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::LibcxxContainerSummaryProvider( ValueObject &valobj, Stream &stream, const TypeSummaryOptions &options) { if (valobj.IsPointerType()) { uint64_t value = valobj.GetValueAsUnsigned(0); if (!value) return false; stream.Printf("0x%016" PRIx64 " ", value); } return FormatEntity::FormatStringRef("size=${svar%#}", stream, nullptr, nullptr, nullptr, &valobj, false, false); }
bool ObjCLanguage::IsNilReference (ValueObject& valobj) { const uint32_t mask = eTypeIsObjC | eTypeIsPointer; bool isObjCpointer = (((valobj.GetCompilerType().GetTypeInfo(nullptr)) & mask) == mask); if (!isObjCpointer) return false; bool canReadValue = true; bool isZero = valobj.GetValueAsUnsigned(0,&canReadValue) == 0; return canReadValue && isZero; }
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; }
lldb::addr_t lldb_private::formatters::GetArrayAddressOrPointerValue(ValueObject &valobj) { lldb::addr_t data_addr = LLDB_INVALID_ADDRESS; if (valobj.IsPointerType()) data_addr = valobj.GetValueAsUnsigned(0); else if (valobj.IsArrayType()) data_addr = valobj.GetAddressOf(); return data_addr; }
bool lldb_private::formatters::CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream) { time_t epoch = GetOSXEpoch(); epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0); tm *tm_date = localtime(&epoch); if (!tm_date) return false; std::string buffer(1024,0); if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0) return false; stream.Printf("%04d-%02d-%02d %02d:%02d:%02d %s", tm_date->tm_year+1900, tm_date->tm_mon+1, tm_date->tm_mday, tm_date->tm_hour, tm_date->tm_min, tm_date->tm_sec, buffer.c_str()); return true; }
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::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::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::swift::TypePreservingNSNumber_SummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options) { lldb::addr_t ptr_value(valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS)); if (ptr_value == LLDB_INVALID_ADDRESS) return false; ProcessSP process_sp(valobj.GetProcessSP()); if (!process_sp) return false; uint32_t ptr_size = process_sp->GetAddressByteSize(); const uint32_t size_of_tag = 4; const uint32_t size_of_payload = 8; lldb::addr_t addr_of_tag = ptr_value + ptr_size; lldb::addr_t addr_of_payload = addr_of_tag + size_of_tag; Error read_error; uint64_t tag = process_sp->ReadUnsignedIntegerFromMemory(addr_of_tag, size_of_tag, 0, read_error); if (read_error.Fail() || tag == 0 || tag > 6) return false; DataBufferSP buffer_sp(new DataBufferHeap(size_of_payload,0)); process_sp->ReadMemoryFromInferior(addr_of_payload, buffer_sp->GetBytes(), size_of_payload, read_error); if (read_error.Fail()) return false; switch (tag) { case 1: // Int { uint64_t payload = 0; memcpy(&payload, buffer_sp->GetBytes(), sizeof(payload)); stream.Printf("Int(%" PRId64 ")", payload); return true; } case 2: // UInt { uint64_t payload = 0; memcpy(&payload, buffer_sp->GetBytes(), sizeof(payload)); stream.Printf("UInt(%" PRIu64 ")", payload); return true; } case 3: // Float { float payload = 0; memcpy(&payload, buffer_sp->GetBytes(), sizeof(payload)); stream.Printf("Float(%f)", payload); return true; } case 4: // Double { double payload = 0; memcpy(&payload, buffer_sp->GetBytes(), sizeof(payload)); stream.Printf("Double(%f)", payload); return true; } case 5: // CGFloat { if (ptr_size == 4) { float payload = 0; memcpy(&payload, buffer_sp->GetBytes(), sizeof(payload)); stream.Printf("CGFloat(%f)", payload); return true; } else if (ptr_size == 8) { double payload = 0; memcpy(&payload, buffer_sp->GetBytes(), sizeof(payload)); stream.Printf("CGFloat(%f)", payload); return true; } break; } case 6: // Bool { bool payload = 0; memcpy(&payload, buffer_sp->GetBytes(), sizeof(payload)); stream.PutCString(payload ? "true" : "false"); return true; } default: break; } return false; }
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::NSDictionarySummaryProvider (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(); bool is_64bit = (ptr_size == 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,"__NSDictionaryI")) { Error error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); if (error.Fail()) return false; value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } else if (!strcmp(class_name,"__NSDictionaryM")) { Error error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); if (error.Fail()) return false; value &= (is_64bit ? ~0xFC00000000000000UL : ~0xFC000000U); } else if (!strcmp(class_name,"__NSCFDictionary")) { Error error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + (is_64bit ? 20 : 12), ptr_size, 0, error); if (error.Fail()) return false; if (is_64bit) value &= ~0x0f1f000000000000UL; } else { if (!ExtractValueFromObjCExpression(valobj, "int", "count", value)) return false; } stream.Printf("%s%" PRIu64 " %s%s", (name_entries ? "@\"" : ""), value, (name_entries ? (value == 1 ? "entry" : "entries") : (value == 1 ? "key/value pair" : "key/value pairs")), (name_entries ? "\"" : "")); 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; }
static bool ExtractFields(ValueObject &valobj, ValueObjectSP *name_sp, ValueObjectSP *reason_sp, ValueObjectSP *userinfo_sp, ValueObjectSP *reserved_sp) { ProcessSP process_sp(valobj.GetProcessSP()); if (!process_sp) return false; lldb::addr_t ptr = 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 = valobj.GetParent()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS); } else { ptr = valobj.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); } if (ptr == LLDB_INVALID_ADDRESS) return false; size_t ptr_size = process_sp->GetAddressByteSize(); Status error; auto name = process_sp->ReadPointerFromMemory(ptr + 1 * ptr_size, error); if (error.Fail() || name == LLDB_INVALID_ADDRESS) return false; auto reason = process_sp->ReadPointerFromMemory(ptr + 2 * ptr_size, error); if (error.Fail() || reason == LLDB_INVALID_ADDRESS) return false; auto userinfo = process_sp->ReadPointerFromMemory(ptr + 3 * ptr_size, error); if (error.Fail() || userinfo == LLDB_INVALID_ADDRESS) return false; auto reserved = process_sp->ReadPointerFromMemory(ptr + 4 * ptr_size, error); if (error.Fail() || reserved == LLDB_INVALID_ADDRESS) return false; InferiorSizedWord name_isw(name, *process_sp); InferiorSizedWord reason_isw(reason, *process_sp); InferiorSizedWord userinfo_isw(userinfo, *process_sp); InferiorSizedWord reserved_isw(reserved, *process_sp); CompilerType voidstar = process_sp->GetTarget() .GetScratchClangASTContext() ->GetBasicType(lldb::eBasicTypeVoid) .GetPointerType(); if (name_sp) *name_sp = ValueObject::CreateValueObjectFromData( "name", name_isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), voidstar); if (reason_sp) *reason_sp = ValueObject::CreateValueObjectFromData( "reason", reason_isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), voidstar); if (userinfo_sp) *userinfo_sp = ValueObject::CreateValueObjectFromData( "userInfo", userinfo_isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), voidstar); if (reserved_sp) *reserved_sp = ValueObject::CreateValueObjectFromData( "reserved", reserved_isw.GetAsData(process_sp->GetByteOrder()), valobj.GetExecutionContextRef(), voidstar); return true; }
bool lldb_private::formatters::NSArraySummaryProvider (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; uint64_t value = 0; const char* class_name = descriptor->GetClassName().GetCString(); if (!class_name || !*class_name) return false; if (!strcmp(class_name,"__NSArrayI")) { Error error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); if (error.Fail()) return false; } else if (!strcmp(class_name,"__NSArrayM")) { Error error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + ptr_size, ptr_size, 0, error); if (error.Fail()) return false; } else if (!strcmp(class_name,"__NSCFArray")) { Error error; value = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr + 2 * ptr_size, ptr_size, 0, error); if (error.Fail()) return false; } else { if (!ExtractValueFromObjCExpression(valobj, "int", "count", value)) return false; } stream.Printf("@\"%" PRIu64 " object%s\"", value, value == 1 ? "" : "s"); return true; }