1 //===-- CF.cpp ----------------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
12 #include "lldb/Core/DataBufferHeap.h"
13 #include "lldb/Core/Error.h"
14 #include "lldb/Core/Stream.h"
15 #include "lldb/Core/ValueObject.h"
16 #include "lldb/Core/ValueObjectConstResult.h"
17 #include "lldb/DataFormatters/FormattersHelpers.h"
18 #include "lldb/Host/Endian.h"
19 #include "lldb/Symbol/ClangASTContext.h"
20 #include "lldb/Target/Language.h"
21 #include "lldb/Target/ObjCLanguageRuntime.h"
22 #include "lldb/Target/StackFrame.h"
23 #include "lldb/Target/Target.h"
26 using namespace lldb_private;
27 using namespace lldb_private::formatters;
30 lldb_private::formatters::CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
32 time_t epoch = GetOSXEpoch();
33 epoch = epoch + (time_t)valobj.GetValueAsUnsigned(0);
34 tm *tm_date = localtime(&epoch);
37 std::string buffer(1024,0);
38 if (strftime (&buffer[0], 1023, "%Z", tm_date) == 0)
40 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());
45 lldb_private::formatters::CFBagSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
47 static ConstString g_TypeHint("CFBag");
49 ProcessSP process_sp = valobj.GetProcessSP();
53 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
58 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
60 if (!descriptor.get() || !descriptor->IsValid())
63 uint32_t ptr_size = process_sp->GetAddressByteSize();
65 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
72 bool is_type_ok = false; // check to see if this is a CFBag we know about
73 if (descriptor->IsCFType())
75 ConstString type_name(valobj.GetTypeName());
77 static ConstString g___CFBag("__CFBag");
78 static ConstString g_conststruct__CFBag("const struct __CFBag");
80 if (type_name == g___CFBag ||
81 type_name == g_conststruct__CFBag)
83 if (valobj.IsPointerType())
90 lldb::addr_t offset = 2*ptr_size+4 + valobj_addr;
92 count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
99 std::string prefix,suffix;
100 if (Language* language = Language::FindPlugin(options.GetLanguage()))
102 if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
109 stream.Printf("%s\"%u value%s\"%s",
111 count,(count == 1 ? "" : "s"),
117 lldb_private::formatters::CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
119 ProcessSP process_sp = valobj.GetProcessSP();
123 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
128 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
130 if (!descriptor.get() || !descriptor->IsValid())
133 uint32_t ptr_size = process_sp->GetAddressByteSize();
135 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
142 bool is_type_ok = false; // check to see if this is a CFBag we know about
143 if (descriptor->IsCFType())
145 ConstString type_name(valobj.GetTypeName());
146 if (type_name == ConstString("__CFMutableBitVector") || type_name == ConstString("__CFBitVector") || type_name == ConstString("CFMutableBitVectorRef") || type_name == ConstString("CFBitVectorRef"))
148 if (valobj.IsPointerType())
153 if (is_type_ok == false)
157 count = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, ptr_size, 0, error);
160 uint64_t num_bytes = count / 8 + ((count & 7) ? 1 : 0);
161 addr_t data_ptr = process_sp->ReadPointerFromMemory(valobj_addr+2*ptr_size+2*ptr_size, error);
164 // make sure we do not try to read huge amounts of data
165 if (num_bytes > 1024)
167 DataBufferSP buffer_sp(new DataBufferHeap(num_bytes,0));
168 num_bytes = process_sp->ReadMemory(data_ptr, buffer_sp->GetBytes(), num_bytes, error);
169 if (error.Fail() || num_bytes == 0)
171 uint8_t *bytes = buffer_sp->GetBytes();
172 for (uint64_t byte_idx = 0; byte_idx < num_bytes-1; byte_idx++)
174 uint8_t byte = bytes[byte_idx];
175 bool bit0 = (byte & 1) == 1;
176 bool bit1 = (byte & 2) == 2;
177 bool bit2 = (byte & 4) == 4;
178 bool bit3 = (byte & 8) == 8;
179 bool bit4 = (byte & 16) == 16;
180 bool bit5 = (byte & 32) == 32;
181 bool bit6 = (byte & 64) == 64;
182 bool bit7 = (byte & 128) == 128;
183 stream.Printf("%c%c%c%c %c%c%c%c ",
195 // print the last byte ensuring we do not print spurious bits
196 uint8_t byte = bytes[num_bytes-1];
197 bool bit0 = (byte & 1) == 1;
198 bool bit1 = (byte & 2) == 2;
199 bool bit2 = (byte & 4) == 4;
200 bool bit3 = (byte & 8) == 8;
201 bool bit4 = (byte & 16) == 16;
202 bool bit5 = (byte & 32) == 32;
203 bool bit6 = (byte & 64) == 64;
204 bool bit7 = (byte & 128) == 128;
207 stream.Printf("%c",bit7 ? '1' : '0');
212 stream.Printf("%c",bit6 ? '1' : '0');
217 stream.Printf("%c",bit5 ? '1' : '0');
222 stream.Printf("%c",bit4 ? '1' : '0');
227 stream.Printf("%c",bit3 ? '1' : '0');
232 stream.Printf("%c",bit2 ? '1' : '0');
237 stream.Printf("%c",bit1 ? '1' : '0');
241 stream.Printf("%c",bit0 ? '1' : '0');
247 lldb_private::formatters::CFBinaryHeapSummaryProvider (ValueObject& valobj, Stream& stream, const TypeSummaryOptions& options)
249 static ConstString g_TypeHint("CFBinaryHeap");
251 ProcessSP process_sp = valobj.GetProcessSP();
255 ObjCLanguageRuntime* runtime = (ObjCLanguageRuntime*)process_sp->GetLanguageRuntime(lldb::eLanguageTypeObjC);
260 ObjCLanguageRuntime::ClassDescriptorSP descriptor(runtime->GetClassDescriptor(valobj));
262 if (!descriptor.get() || !descriptor->IsValid())
265 uint32_t ptr_size = process_sp->GetAddressByteSize();
267 lldb::addr_t valobj_addr = valobj.GetValueAsUnsigned(0);
274 bool is_type_ok = false; // check to see if this is a CFBinaryHeap we know about
275 if (descriptor->IsCFType())
277 ConstString type_name(valobj.GetTypeName());
279 static ConstString g___CFBinaryHeap("__CFBinaryHeap");
280 static ConstString g_conststruct__CFBinaryHeap("const struct __CFBinaryHeap");
281 static ConstString g_CFBinaryHeapRef("CFBinaryHeapRef");
283 if (type_name == g___CFBinaryHeap ||
284 type_name == g_conststruct__CFBinaryHeap ||
285 type_name == g_CFBinaryHeapRef)
287 if (valobj.IsPointerType())
294 lldb::addr_t offset = 2*ptr_size + valobj_addr;
296 count = process_sp->ReadUnsignedIntegerFromMemory(offset, 4, 0, error);
303 std::string prefix,suffix;
304 if (Language* language = Language::FindPlugin(options.GetLanguage()))
306 if (!language->GetFormatterPrefixSuffix(valobj, g_TypeHint, prefix, suffix))
313 stream.Printf("%s\"%u item%s\"%s",
315 count,(count == 1 ? "" : "s"),