Initial merge of some of the iOS 8 / Mac OS X Yosemite specific
lldb support. I'll be doing more testing & cleanup but I wanted to
get the initial checkin done.
This adds a new SBExpressionOptions::SetLanguage API for selecting a
language of an expression.
I added adds a new SBThread::GetInfoItemByPathString for retriving
information about a thread from that thread's StructuredData.
I added a new StructuredData class for representing
key-value/array/dictionary information (e.g. JSON formatted data).
Helper functions to read JSON and create a StructuredData object,
and to print a StructuredData object in JSON format are included.
A few Cocoa / Cocoa Touch data formatters were updated by Enrico
to track changes in iOS 8 / Yosemite.
Before we query a thread's extended information, the system runtime may
provide hints to the remote debug stub that it will use to retrieve values
out of runtime structures. I added a new SystemRuntime method
AddThreadExtendedInfoPacketHints which allows the SystemRuntime to add
key-value type data to the initial request that we send to the remote stub.
The thread-format formatter string can now retrieve values out of a thread's
extended info structured data. The default thread-format string picks up
two of these - thread.info.activity.name and thread.info.trace_messages.
I added a new "jThreadExtendedInfo" packet in debugserver; I will
add documentation to the lldb-gdb-remote.txt doc soon. It accepts
JSON formatted arguments (most importantly, "thread":threadnum) and
it returns a variety of information regarding the thread to lldb
in JSON format. This JSON return is scanned into a StructuredData
object that is associated with the thread; UI layers can query the
thread's StructuredData to see if key-values are present, and if
so, show them to the user. These key-values are likely to be
specific to different targets with some commonality among many
targets. For instance, many targets will be able to advertise the
pthread_t value for a thread.
I added an initial rough cut of "thread info" command which will print
the information about a thread from the jThreadExtendedInfo result.
I need to do more work to make this format reasonably.
Han Ming added calls into the pmenergy and pmsample libraries if
debugserver is run on Mac OS X Yosemite to get information about the
inferior's power use.
I added support to debugserver for gathering the Genealogy information
about threads, if it exists, and returning it in the jThreadExtendedInfo
JSON result.
llvm-svn: 210874
diff --git a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
index 04f090d..ac535ef 100644
--- a/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
+++ b/lldb/source/DataFormatters/CXXFormatterFunctions.cpp
@@ -20,7 +20,6 @@
#include "lldb/Core/ValueObjectConstResult.h"
#include "lldb/Host/Endian.h"
#include "lldb/Symbol/ClangASTContext.h"
-#include "lldb/Target/ObjCLanguageRuntime.h"
#include "lldb/Target/Target.h"
#include <algorithm>
@@ -966,6 +965,61 @@
}
bool
+lldb_private::formatters::NSTaggedString_SummaryProvider (ObjCLanguageRuntime::ClassDescriptorSP descriptor, Stream& stream)
+{
+ if (!descriptor)
+ return false;
+ uint64_t len_bits = 0, data_bits = 0;
+ if (!descriptor->GetTaggedPointerInfo(&len_bits,&data_bits,nullptr))
+ return false;
+
+ static const int g_MaxNonBitmaskedLen = 7; //TAGGED_STRING_UNPACKED_MAXLEN
+ static const int g_SixbitMaxLen = 9;
+ static const int g_fiveBitMaxLen = 11;
+
+ static const char *sixBitToCharLookup = "eilotrm.apdnsIc ufkMShjTRxgC4013" "bDNvwyUL2O856P-B79AFKEWV_zGJ/HYX";
+
+ if (len_bits > g_fiveBitMaxLen)
+ return false;
+
+ // this is a fairly ugly trick - pretend that the numeric value is actually a char*
+ // this works under a few assumptions:
+ // little endian architecture
+ // sizeof(uint64_t) > g_MaxNonBitmaskedLen
+ if (len_bits <= g_MaxNonBitmaskedLen)
+ {
+ stream.Printf("@\"%s\"",(const char*)&data_bits);
+ return true;
+ }
+
+ // if the data is bitmasked, we need to actually process the bytes
+ uint8_t bitmask = 0;
+ uint8_t shift_offset = 0;
+
+ if (len_bits <= g_SixbitMaxLen)
+ {
+ bitmask = 0x03f;
+ shift_offset = 6;
+ }
+ else
+ {
+ bitmask = 0x01f;
+ shift_offset = 5;
+ }
+
+ std::vector<uint8_t> bytes;
+ bytes.resize(len_bits);
+ for (; len_bits > 0; data_bits >>= shift_offset, --len_bits)
+ {
+ uint8_t packed = data_bits & bitmask;
+ bytes.insert(bytes.begin(), sixBitToCharLookup[packed]);
+ }
+
+ stream.Printf("@\"%s\"",&bytes[0]);
+ return true;
+}
+
+bool
lldb_private::formatters::NSStringSummaryProvider (ValueObject& valobj, Stream& stream)
{
ProcessSP process_sp = valobj.GetProcessSP();
@@ -994,6 +1048,12 @@
if (!class_name || !*class_name)
return false;
+ bool is_tagged_ptr = (0 == strcmp(class_name,"NSTaggedPointerString")) && descriptor->GetTaggedPointerInfo();
+ // for a tagged pointer, the descriptor has everything we need
+ if (is_tagged_ptr)
+ return NSTaggedString_SummaryProvider(descriptor, stream);
+
+ // if not a tagged pointer that we know about, try the normal route
uint64_t info_bits_location = valobj_addr + ptr_size;
if (process_sp->GetByteOrder() != lldb::eByteOrderLittle)
info_bits_location += 3;