summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lldb/examples/summaries/cocoa/NSDate.py3
-rw-r--r--lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h6
-rwxr-xr-xlldb/scripts/Python/finish-swig-Python-LLDB.sh27
-rw-r--r--lldb/source/DataFormatters/CXXFormatterFunctions.cpp127
-rw-r--r--lldb/source/DataFormatters/FormatManager.cpp10
-rw-r--r--lldb/source/Interpreter/ScriptInterpreterPython.cpp2
-rw-r--r--lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp21
7 files changed, 150 insertions, 46 deletions
diff --git a/lldb/examples/summaries/cocoa/NSDate.py b/lldb/examples/summaries/cocoa/NSDate.py
index ae1ff6b432b..4dd63b4a5c3 100644
--- a/lldb/examples/summaries/cocoa/NSDate.py
+++ b/lldb/examples/summaries/cocoa/NSDate.py
@@ -5,7 +5,8 @@ part of The LLVM Compiler Infrastructure
This file is distributed under the University of Illinois Open Source
License. See LICENSE.TXT for details.
"""
-# summary provider for NSDate
+# example summary provider for NSDate
+# the real summary is now C++ code built into LLDB
import lldb
import ctypes
import lldb.runtime.objc.objc_runtime
diff --git a/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h b/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h
index 61757891189..1b3360e9161 100644
--- a/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h
+++ b/lldb/include/lldb/DataFormatters/CXXFormatterFunctions.h
@@ -116,6 +116,12 @@ namespace lldb_private {
CFBitVectorSummaryProvider (ValueObject& valobj, Stream& stream);
bool
+ NSDateSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
+ CFAbsoluteTimeSummaryProvider (ValueObject& valobj, Stream& stream);
+
+ bool
NSBundleSummaryProvider (ValueObject& valobj, Stream& stream);
bool
diff --git a/lldb/scripts/Python/finish-swig-Python-LLDB.sh b/lldb/scripts/Python/finish-swig-Python-LLDB.sh
index d0f3c251a22..e87d44a9f50 100755
--- a/lldb/scripts/Python/finish-swig-Python-LLDB.sh
+++ b/lldb/scripts/Python/finish-swig-Python-LLDB.sh
@@ -223,38 +223,11 @@ package_files="${SRC_ROOT}/examples/synthetic/gnu_libstdcpp.py
${SRC_ROOT}/examples/synthetic/libcxx.py"
create_python_package "/formatters/cpp" "${package_files}"
-# lldb/formatters/objc
-package_files="${SRC_ROOT}/examples/summaries/cocoa/Selector.py
-${SRC_ROOT}/examples/summaries/objc.py
-${SRC_ROOT}/examples/summaries/cocoa/Class.py
-${SRC_ROOT}/examples/summaries/cocoa/CFArray.py
-${SRC_ROOT}/examples/summaries/cocoa/CFBag.py
-${SRC_ROOT}/examples/summaries/cocoa/CFBinaryHeap.py
-${SRC_ROOT}/examples/summaries/cocoa/CFBitVector.py
-${SRC_ROOT}/examples/summaries/cocoa/CFDictionary.py
-${SRC_ROOT}/examples/summaries/cocoa/CFString.py
-${SRC_ROOT}/examples/summaries/cocoa/NSBundle.py
-${SRC_ROOT}/examples/summaries/cocoa/NSData.py
-${SRC_ROOT}/examples/summaries/cocoa/NSDate.py
-${SRC_ROOT}/examples/summaries/cocoa/NSException.py
-${SRC_ROOT}/examples/summaries/cocoa/NSIndexSet.py
-${SRC_ROOT}/examples/summaries/cocoa/NSMachPort.py
-${SRC_ROOT}/examples/summaries/cocoa/NSNotification.py
-${SRC_ROOT}/examples/summaries/cocoa/NSNumber.py
-${SRC_ROOT}/examples/summaries/cocoa/NSSet.py
-${SRC_ROOT}/examples/summaries/cocoa/NSURL.py"
-create_python_package "/formatters/objc" "${package_files}"
-
-
# make an empty __init__.py in lldb/runtime
# this is required for Python to recognize lldb.runtime as a valid package
# (and hence, lldb.runtime.objc as a valid contained package)
create_python_package "/runtime" ""
-# lldb/runtime/objc
-package_files="${SRC_ROOT}/examples/summaries/cocoa/objc_runtime.py"
-create_python_package "/runtime/objc" "${package_files}"
-
# lldb/formatters
# having these files copied here ensures that lldb/formatters is a valid package itself
package_files="${SRC_ROOT}/examples/summaries/cocoa/cache.py
diff --git a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
index c0c9dcbb4a6..2df6524c365 100644
--- a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
+++ b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
@@ -9,6 +9,8 @@
#include "lldb/lldb-python.h"
+#include <time.h>
+
#include "lldb/DataFormatters/CXXFormatterFunctions.h"
#include "llvm/Support/ConvertUTF.h"
@@ -1618,6 +1620,131 @@ lldb_private::formatters::ObjCSELSummaryProvider (ValueObject& valobj, Stream& s
return true;
}
+// POSIX has an epoch on Jan-1-1970, but Cocoa prefers Jan-1-2001
+// this call gives the POSIX equivalent of the Cocoa epoch
+time_t
+GetOSXEpoch ()
+{
+ static time_t epoch = 0;
+ if (!epoch)
+ {
+ tzset();
+ tm tm_epoch;
+ tm_epoch.tm_sec = 0;
+ tm_epoch.tm_hour = 0;
+ tm_epoch.tm_min = 0;
+ tm_epoch.tm_mon = 0;
+ tm_epoch.tm_mday = 1;
+ tm_epoch.tm_year = 2001-1900; // for some reason, we need to subtract 1900 from this field. not sure why.
+ tm_epoch.tm_isdst = -1;
+ tm_epoch.tm_gmtoff = 0;
+ tm_epoch.tm_zone = NULL;
+ epoch = timegm(&tm_epoch);
+ }
+ return epoch;
+}
+
+bool
+lldb_private::formatters::NSDateSummaryProvider (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 date_value_bits = 0;
+ double date_value = 0.0;
+
+ const char* class_name = descriptor->GetClassName().GetCString();
+
+ if (!class_name || !*class_name)
+ return false;
+
+ if (strcmp(class_name,"NSDate") == 0 ||
+ strcmp(class_name,"__NSDate") == 0 ||
+ strcmp(class_name,"__NSTaggedDate") == 0)
+ {
+ if (descriptor->IsTagged())
+ {
+ uint64_t info_bits = (valobj_addr & 0xF0ULL) >> 4;
+ uint64_t value_bits = (valobj_addr & ~0x0000000000000000FFULL) >> 8;
+ date_value_bits = ((value_bits << 8) | (info_bits << 4));
+ date_value = *((double*)&date_value_bits);
+ }
+ else
+ {
+ Error error;
+ date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+ptr_size, 8, 0, error);
+ date_value = *((double*)&date_value_bits);
+ if (error.Fail())
+ return false;
+ }
+ }
+ else if (!strcmp(class_name,"NSCalendarDate"))
+ {
+ Error error;
+ date_value_bits = process_sp->ReadUnsignedIntegerFromMemory(valobj_addr+2*ptr_size, 8, 0, error);
+ date_value = *((double*)&date_value_bits);
+ if (error.Fail())
+ return false;
+ }
+ else
+ {
+ if (ExtractValueFromObjCExpression(valobj, "NSTimeInterval", "ExtractValueFromObjCExpression", date_value_bits) == false)
+ return false;
+ date_value = *((double*)&date_value_bits);
+ }
+ if (date_value == -63114076800)
+ {
+ stream.Printf("0001-12-30 00:00:00 +0000");
+ return true;
+ }
+ // this snippet of code assumes that time_t == seconds since Jan-1-1970
+ // this is generally true and POSIXly happy, but might break if a library
+ // vendor decides to get creative
+ time_t epoch = GetOSXEpoch();
+ epoch = epoch + (time_t)date_value;
+ 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::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;
+}
+
size_t
lldb_private::formatters::ExtractIndexFromString (const char* item_name)
{
diff --git a/lldb/source/DataFormatters/FormatManager.cpp b/lldb/source/DataFormatters/FormatManager.cpp
index f10d16e714b..e4937ceebcf 100644
--- a/lldb/source/DataFormatters/FormatManager.cpp
+++ b/lldb/source/DataFormatters/FormatManager.cpp
@@ -974,10 +974,10 @@ FormatManager::LoadObjCFormatters()
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("NSURL"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSURLSummaryProvider, "NSURL summary provider", ConstString("CFURLRef"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("NSDate"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("__NSDate"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("__NSTaggedDate"), appkit_flags);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.NSDate_SummaryProvider", ConstString("NSCalendarDate"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("NSDate"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("__NSDate"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("__NSTaggedDate"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSDateSummaryProvider, "NSDate summary provider", ConstString("NSCalendarDate"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("NSTimeZone"), appkit_flags);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSTimeZoneSummaryProvider, "NSTimeZone summary provider", ConstString("CFTimeZoneRef"), appkit_flags);
@@ -986,7 +986,7 @@ FormatManager::LoadObjCFormatters()
// CFAbsoluteTime is actually a double rather than a pointer to an object
// we do not care about the numeric value, since it is probably meaningless to users
appkit_flags.SetDontShowValue(true);
- AddScriptSummary(appkit_category_sp, "lldb.formatters.objc.NSDate.CFAbsoluteTime_SummaryProvider", ConstString("CFAbsoluteTime"), appkit_flags);
+ AddCXXSummary(appkit_category_sp, lldb_private::formatters::CFAbsoluteTimeSummaryProvider, "CFAbsoluteTime summary provider", ConstString("CFAbsoluteTime"), appkit_flags);
appkit_flags.SetDontShowValue(false);
AddCXXSummary(appkit_category_sp, lldb_private::formatters::NSIndexSetSummaryProvider, "NSIndexSet summary provider", ConstString("NSIndexSet"), appkit_flags);
diff --git a/lldb/source/Interpreter/ScriptInterpreterPython.cpp b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
index 0b0aec1ae68..5a97107ac10 100644
--- a/lldb/source/Interpreter/ScriptInterpreterPython.cpp
+++ b/lldb/source/Interpreter/ScriptInterpreterPython.cpp
@@ -489,7 +489,7 @@ ScriptInterpreterPython::ScriptInterpreterPython (CommandInterpreter &interprete
// WARNING: temporary code that loads Cocoa formatters - this should be done on a per-platform basis rather than loading the whole set
// and letting the individual formatter classes exploit APIs to check whether they can/cannot do their task
run_string.Clear();
- run_string.Printf ("run_one_line (%s, 'import lldb.runtime.objc, lldb.formatters, lldb.formatters.objc, lldb.formatters.cpp, pydoc')", m_dictionary_name.c_str());
+ run_string.Printf ("run_one_line (%s, 'import lldb.formatters, lldb.formatters.cpp, pydoc')", m_dictionary_name.c_str());
PyRun_SimpleString (run_string.GetData());
int new_count = Debugger::TestDebuggerRefCount();
diff --git a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
index ae1eca83d60..f116bc79ec1 100644
--- a/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
+++ b/lldb/source/Plugins/LanguageRuntime/ObjC/AppleObjCRuntime/AppleObjCRuntimeV2.cpp
@@ -1433,16 +1433,16 @@ public:
m_class_bits = (value & 0xE) >> 1;
lldb::TargetSP target_sp = isa_pointer.GetTargetSP();
- LazyBool is_lion = IsLion(target_sp);
+ uint32_t foundation_version = GetFoundationVersion(target_sp);
// TODO: check for OSX version - for now assume Mtn Lion
- if (is_lion == eLazyBoolCalculate)
+ if (foundation_version == UINT32_MAX)
{
// if we can't determine the matching table (e.g. we have no Foundation),
// assume this is not a valid tagged pointer
m_valid = false;
}
- else if (is_lion == eLazyBoolNo)
+ else if (foundation_version >= 900)
{
switch (m_class_bits)
{
@@ -1571,13 +1571,14 @@ public:
{}
protected:
- // TODO make this into a smarter OS version detector
- LazyBool
- IsLion (lldb::TargetSP &target_sp)
+ // we use the version of Foundation to make assumptions about the ObjC runtime on a target
+ uint32_t
+ GetFoundationVersion (lldb::TargetSP &target_sp)
{
if (!target_sp)
return eLazyBoolCalculate;
const ModuleList& modules = target_sp->GetImages();
+ uint32_t major = UINT32_MAX;
for (uint32_t idx = 0; idx < modules.GetSize(); idx++)
{
lldb::ModuleSP module_sp = modules.GetModuleAtIndex(idx);
@@ -1585,15 +1586,11 @@ protected:
continue;
if (strcmp(module_sp->GetFileSpec().GetFilename().AsCString(""),"Foundation") == 0)
{
- uint32_t major = UINT32_MAX;
module_sp->GetVersion(&major,1);
- if (major == UINT32_MAX)
- return eLazyBoolCalculate;
-
- return (major > 900 ? eLazyBoolNo : eLazyBoolYes);
+ break;
}
}
- return eLazyBoolCalculate;
+ return major;
}
private:
OpenPOWER on IntegriCloud