[Lldb-commits] [lldb] r238224 - Added XML to the host layer.

Greg Clayton gclayton at apple.com
Tue May 26 11:00:52 PDT 2015


Author: gclayton
Date: Tue May 26 13:00:51 2015
New Revision: 238224

URL: http://llvm.org/viewvc/llvm-project?rev=238224&view=rev
Log:
Added XML to the host layer.

We know have on API we should use for all XML within LLDB in XML.h. This API will be easy back the XML parsing by different libraries in case libxml2 doesn't work on all platforms. It also allows the only place for #ifdef ...XML... to be in XML.h and XML.cpp. The API is designed so it will still compile with or without XML support and there is a static function "bool XMLDocument::XMLEnabled()" that can be called to see if XML is currently supported. All APIs will return errors, false, or nothing when XML isn't enabled.

Converted all locations that used XML over to using the host XML implementation.

Added target.xml support to debugserver. Extended the XML register format to work for LLDB by including extra attributes and elements where needed. This allows the target.xml to replace the qRegisterInfo packets and allows us to fetch all register info in a single packet.

<rdar://problem/21090173>


Added:
    lldb/trunk/include/lldb/Host/XML.h
    lldb/trunk/source/Host/common/XML.cpp
Modified:
    lldb/trunk/lldb.xcodeproj/project.pbxproj
    lldb/trunk/source/Host/CMakeLists.txt
    lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
    lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp
    lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
    lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.h
    lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
    lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
    lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
    lldb/trunk/tools/debugserver/source/DNB.cpp
    lldb/trunk/tools/debugserver/source/DNB.h
    lldb/trunk/tools/debugserver/source/DNBArch.cpp
    lldb/trunk/tools/debugserver/source/DNBArch.h
    lldb/trunk/tools/debugserver/source/RNBRemote.cpp
    lldb/trunk/tools/debugserver/source/RNBRemote.h

Added: lldb/trunk/include/lldb/Host/XML.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Host/XML.h?rev=238224&view=auto
==============================================================================
--- lldb/trunk/include/lldb/Host/XML.h (added)
+++ lldb/trunk/include/lldb/Host/XML.h Tue May 26 13:00:51 2015
@@ -0,0 +1,216 @@
+//===-- XML.h ---------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_XML_h_
+#define liblldb_XML_h_
+
+// C Includes
+
+#if defined( LIBXML2_DEFINED )
+#include <libxml/xmlreader.h>
+#endif
+
+// C++ Includes
+
+#include <functional>
+#include <string>
+#include <vector>
+
+// Other libraries and framework includes
+// Project includes
+#include "lldb/lldb-private.h"
+#include "llvm/ADT/StringRef.h"
+#include "lldb/Core/StreamString.h"
+
+
+namespace lldb_private {
+
+#if defined( LIBXML2_DEFINED )
+    typedef xmlNodePtr XMLNodeImpl;
+    typedef xmlDocPtr  XMLDocumentImpl;
+#else
+    typedef void * XMLNodeImpl;
+    typedef void * XMLDocumentImpl;
+#endif
+
+    class XMLNode;
+    
+    typedef std::vector<std::string> NamePath;
+    typedef std::function <bool(const XMLNode &node)> NodeCallback;
+    typedef std::function <bool(const llvm::StringRef &name, const llvm::StringRef &value)> AttributeCallback;
+
+    class XMLNode
+    {
+    public:
+        XMLNode();
+        
+        XMLNode(XMLNodeImpl node);
+        
+        ~XMLNode();
+        
+        explicit operator bool() const
+        {
+            return IsValid();
+        }
+        
+        void
+        Clear();
+        
+        bool
+        IsValid() const;
+        
+        bool
+        IsElement () const;
+
+        llvm::StringRef
+        GetName() const;
+        
+        bool
+        GetElementText (std::string &text) const;
+        
+        bool
+        NameIs (const char *name) const;
+        
+        XMLNode
+        GetParent() const;
+        
+        XMLNode
+        GetSibling() const;
+        
+        XMLNode
+        GetChild () const;
+        
+        llvm::StringRef
+        GetAttributeValue(const char *name, const char *fail_value = NULL) const;
+        
+        XMLNode
+        FindFirstChildElementWithName (const char *name) const;
+        
+        XMLNode
+        GetElementForPath (const NamePath &path);
+        
+        //----------------------------------------------------------------------
+        // Iterate through all sibling nodes of any type
+        //----------------------------------------------------------------------
+        void
+        ForEachSiblingNode (NodeCallback const &callback) const;
+
+        //----------------------------------------------------------------------
+        // Iterate through only the sibling nodes that are elements
+        //----------------------------------------------------------------------
+        void
+        ForEachSiblingElement (NodeCallback const &callback) const;
+
+        //----------------------------------------------------------------------
+        // Iterate through only the sibling nodes that are elements and whose
+        // name matches \a name.
+        //----------------------------------------------------------------------
+        void
+        ForEachSiblingElementWithName (const char *name, NodeCallback const &callback) const;
+        
+        void
+        ForEachChildNode (NodeCallback const &callback) const;
+        
+        void
+        ForEachChildElement (NodeCallback const &callback) const;
+        
+        void
+        ForEachChildElementWithName (const char *name, NodeCallback const &callback) const;
+        
+        void
+        ForEachAttribute (AttributeCallback const &callback) const;
+        
+    protected:
+        XMLNodeImpl m_node;
+    };
+
+    class XMLDocument
+    {
+    public:
+        
+        XMLDocument ();
+        
+        ~XMLDocument ();
+        
+        explicit operator bool() const
+        {
+            return IsValid();
+        }
+        
+        bool
+        IsValid() const;
+        
+        void
+        Clear();
+        
+        bool
+        ParseFile (const char *path);
+        
+        bool
+        ParseMemory (const char *xml, size_t xml_length, const char *url = "untitled.xml");
+
+        //----------------------------------------------------------------------
+        // If \a name is NULL, just get the root element node, else only return
+        // a value XMLNode if the name of the root element matches \a name.
+        //----------------------------------------------------------------------
+        XMLNode
+        GetRootElement(const char *required_name = nullptr);
+        
+        static void
+        ErrorCallback (void *ctx, const char *format, ...);
+
+        static bool
+        XMLEnabled ();
+        
+    protected:
+        XMLDocumentImpl m_document;
+        StreamString m_errors;
+    };
+
+    class ApplePropertyList
+    {
+    public:
+        ApplePropertyList();
+
+        ApplePropertyList(const char *path);
+
+        bool
+        ParseFile (const char *path);
+
+        explicit operator bool() const
+        {
+            return IsValid();
+        }
+        
+        bool
+        IsValid() const;
+        
+        XMLNode
+        GetValueNode (const char *key) const;
+
+        bool
+        GetValueAsString (const char *key, std::string &value) const;
+
+    protected:
+
+        // Using a node returned from GetValueNode() extract its value as a
+        // string (if possible). Array and dictionary nodes will return false
+        // as they have no string value. Boolean nodes will return true and
+        // \a value will be "true" or "false" as the string value comes from
+        // the element name itself. All other nodes will return the text
+        // content of the XMLNode.
+        static bool
+        ExtractStringFromValueNode (const XMLNode &node, std::string &value);
+
+        XMLDocument m_xml_doc;
+        XMLNode m_dict_node;
+    };
+} // namespace lldb_private
+
+#endif  // liblldb_XML_h_

Modified: lldb/trunk/lldb.xcodeproj/project.pbxproj
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/lldb.xcodeproj/project.pbxproj?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/lldb.xcodeproj/project.pbxproj (original)
+++ lldb/trunk/lldb.xcodeproj/project.pbxproj Tue May 26 13:00:51 2015
@@ -71,15 +71,10 @@
 		23059A101958B319007B8189 /* SBUnixSignals.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 23059A0F1958B319007B8189 /* SBUnixSignals.cpp */; };
 		23059A121958B3B2007B8189 /* SBUnixSignals.h in Headers */ = {isa = PBXBuildFile; fileRef = 23059A111958B37B007B8189 /* SBUnixSignals.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		232CB615191E00CD00EF39FC /* NativeBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 232CB60B191E00CC00EF39FC /* NativeBreakpoint.cpp */; };
-		232CB616191E00CD00EF39FC /* NativeBreakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 232CB60C191E00CC00EF39FC /* NativeBreakpoint.h */; };
 		232CB617191E00CD00EF39FC /* NativeBreakpointList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 232CB60D191E00CC00EF39FC /* NativeBreakpointList.cpp */; };
-		232CB618191E00CD00EF39FC /* NativeBreakpointList.h in Headers */ = {isa = PBXBuildFile; fileRef = 232CB60E191E00CC00EF39FC /* NativeBreakpointList.h */; };
 		232CB619191E00CD00EF39FC /* NativeProcessProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 232CB60F191E00CC00EF39FC /* NativeProcessProtocol.cpp */; };
-		232CB61A191E00CD00EF39FC /* NativeProcessProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 232CB610191E00CC00EF39FC /* NativeProcessProtocol.h */; };
 		232CB61B191E00CD00EF39FC /* NativeThreadProtocol.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 232CB611191E00CC00EF39FC /* NativeThreadProtocol.cpp */; };
-		232CB61C191E00CD00EF39FC /* NativeThreadProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = 232CB612191E00CC00EF39FC /* NativeThreadProtocol.h */; };
 		232CB61D191E00CD00EF39FC /* SoftwareBreakpoint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 232CB613191E00CC00EF39FC /* SoftwareBreakpoint.cpp */; };
-		232CB61E191E00CD00EF39FC /* SoftwareBreakpoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 232CB614191E00CD00EF39FC /* SoftwareBreakpoint.h */; };
 		233B007D1960C9F90090E598 /* ProcessInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B007B1960C9E60090E598 /* ProcessInfo.cpp */; };
 		233B007F1960CB280090E598 /* ProcessLaunchInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 233B007E1960CB280090E598 /* ProcessLaunchInfo.cpp */; };
 		236124A41986B4E2004EFC37 /* IOObject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 236124A21986B4E2004EFC37 /* IOObject.cpp */; };
@@ -336,6 +331,10 @@
 		26744EF11338317700EF765A /* GDBRemoteCommunicationClient.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EED1338317700EF765A /* GDBRemoteCommunicationClient.cpp */; };
 		26744EF31338317700EF765A /* GDBRemoteCommunicationServer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26744EEF1338317700EF765A /* GDBRemoteCommunicationServer.cpp */; };
 		26780C611867C33D00234593 /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 2670F8111862B44A006B332C /* libncurses.dylib */; };
+		267A47FB1B1411C40021A5BC /* NativeRegisterContext.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267A47FA1B1411C40021A5BC /* NativeRegisterContext.cpp */; };
+		267A47FD1B1411CC0021A5BC /* NativeRegisterContextRegisterInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267A47FC1B1411CC0021A5BC /* NativeRegisterContextRegisterInfo.cpp */; };
+		267A47FF1B1411D90021A5BC /* NativeWatchpointList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267A47FE1B1411D90021A5BC /* NativeWatchpointList.cpp */; };
+		267A48011B1411E40021A5BC /* XML.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267A48001B1411E40021A5BC /* XML.cpp */; };
 		267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */; };
 		267C01371368C49C006E963E /* OptionGroupOutputFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 26BCFC531368B3E4006DC050 /* OptionGroupOutputFile.cpp */; };
 		267DFB461B06752A00000FB7 /* MICmdArgValPrintValues.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 267DFB441B06752A00000FB7 /* MICmdArgValPrintValues.cpp */; };
@@ -1196,15 +1195,10 @@
 		23059A111958B37B007B8189 /* SBUnixSignals.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SBUnixSignals.h; path = include/lldb/API/SBUnixSignals.h; sourceTree = "<group>"; };
 		23173F8B192BA93F005C708F /* lldb-x86-register-enums.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "lldb-x86-register-enums.h"; path = "Utility/lldb-x86-register-enums.h"; sourceTree = "<group>"; };
 		232CB60B191E00CC00EF39FC /* NativeBreakpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NativeBreakpoint.cpp; path = source/Host/common/NativeBreakpoint.cpp; sourceTree = "<group>"; };
-		232CB60C191E00CC00EF39FC /* NativeBreakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NativeBreakpoint.h; path = source/Host/common/NativeBreakpoint.h; sourceTree = "<group>"; };
 		232CB60D191E00CC00EF39FC /* NativeBreakpointList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NativeBreakpointList.cpp; path = source/Host/common/NativeBreakpointList.cpp; sourceTree = "<group>"; };
-		232CB60E191E00CC00EF39FC /* NativeBreakpointList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NativeBreakpointList.h; path = source/Host/common/NativeBreakpointList.h; sourceTree = "<group>"; };
 		232CB60F191E00CC00EF39FC /* NativeProcessProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; lineEnding = 0; name = NativeProcessProtocol.cpp; path = source/Host/common/NativeProcessProtocol.cpp; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.cpp; };
-		232CB610191E00CC00EF39FC /* NativeProcessProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NativeProcessProtocol.h; path = source/Host/common/NativeProcessProtocol.h; sourceTree = "<group>"; };
 		232CB611191E00CC00EF39FC /* NativeThreadProtocol.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NativeThreadProtocol.cpp; path = source/Host/common/NativeThreadProtocol.cpp; sourceTree = "<group>"; };
-		232CB612191E00CC00EF39FC /* NativeThreadProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NativeThreadProtocol.h; path = source/Host/common/NativeThreadProtocol.h; sourceTree = "<group>"; };
 		232CB613191E00CC00EF39FC /* SoftwareBreakpoint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SoftwareBreakpoint.cpp; path = source/Host/common/SoftwareBreakpoint.cpp; sourceTree = "<group>"; };
-		232CB614191E00CD00EF39FC /* SoftwareBreakpoint.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SoftwareBreakpoint.h; path = source/Host/common/SoftwareBreakpoint.h; sourceTree = "<group>"; };
 		232CB62B19213AC200EF39FC /* NativeProcessLinux.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NativeProcessLinux.cpp; sourceTree = "<group>"; };
 		232CB62C19213AC200EF39FC /* NativeProcessLinux.h */ = {isa = PBXFileReference; explicitFileType = sourcecode.c.h; path = NativeProcessLinux.h; sourceTree = "<group>"; };
 		232CB62D19213AC200EF39FC /* NativeThreadLinux.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = NativeThreadLinux.cpp; sourceTree = "<group>"; };
@@ -1737,6 +1731,19 @@
 		2675F6FF1332BE690067997B /* PlatformRemoteiOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformRemoteiOS.h; sourceTree = "<group>"; };
 		2676A093119C93C8008A98EF /* StringExtractorGDBRemote.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = StringExtractorGDBRemote.cpp; path = source/Utility/StringExtractorGDBRemote.cpp; sourceTree = "<group>"; };
 		2676A094119C93C8008A98EF /* StringExtractorGDBRemote.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = StringExtractorGDBRemote.h; path = source/Utility/StringExtractorGDBRemote.h; sourceTree = "<group>"; };
+		267A47F21B14115A0021A5BC /* SoftwareBreakpoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SoftwareBreakpoint.h; path = include/lldb/Host/common/SoftwareBreakpoint.h; sourceTree = "<group>"; };
+		267A47F31B14116E0021A5BC /* NativeBreakpoint.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NativeBreakpoint.h; path = include/lldb/Host/common/NativeBreakpoint.h; sourceTree = "<group>"; };
+		267A47F41B1411750021A5BC /* NativeBreakpointList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NativeBreakpointList.h; path = include/lldb/Host/common/NativeBreakpointList.h; sourceTree = "<group>"; };
+		267A47F51B14117F0021A5BC /* NativeProcessProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NativeProcessProtocol.h; path = include/lldb/Host/common/NativeProcessProtocol.h; sourceTree = "<group>"; };
+		267A47F61B14118F0021A5BC /* NativeRegisterContext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NativeRegisterContext.h; path = include/lldb/Host/common/NativeRegisterContext.h; sourceTree = "<group>"; };
+		267A47F71B14119A0021A5BC /* NativeRegisterContextRegisterInfo.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NativeRegisterContextRegisterInfo.h; path = include/lldb/Host/common/NativeRegisterContextRegisterInfo.h; sourceTree = "<group>"; };
+		267A47F81B1411A40021A5BC /* NativeThreadProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NativeThreadProtocol.h; path = include/lldb/Host/common/NativeThreadProtocol.h; sourceTree = "<group>"; };
+		267A47F91B1411AC0021A5BC /* NativeWatchpointList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = NativeWatchpointList.h; path = include/lldb/Host/common/NativeWatchpointList.h; sourceTree = "<group>"; };
+		267A47FA1B1411C40021A5BC /* NativeRegisterContext.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NativeRegisterContext.cpp; path = source/Host/common/NativeRegisterContext.cpp; sourceTree = "<group>"; };
+		267A47FC1B1411CC0021A5BC /* NativeRegisterContextRegisterInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NativeRegisterContextRegisterInfo.cpp; path = source/Host/common/NativeRegisterContextRegisterInfo.cpp; sourceTree = "<group>"; };
+		267A47FE1B1411D90021A5BC /* NativeWatchpointList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NativeWatchpointList.cpp; path = source/Host/common/NativeWatchpointList.cpp; sourceTree = "<group>"; };
+		267A48001B1411E40021A5BC /* XML.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = XML.cpp; path = source/Host/common/XML.cpp; sourceTree = "<group>"; };
+		267A48031B1416080021A5BC /* XML.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = XML.h; path = include/lldb/Host/XML.h; sourceTree = "<group>"; };
 		267C0128136880C7006E963E /* OptionGroupValueObjectDisplay.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = OptionGroupValueObjectDisplay.h; path = include/lldb/Interpreter/OptionGroupValueObjectDisplay.h; sourceTree = "<group>"; };
 		267C012A136880DF006E963E /* OptionGroupValueObjectDisplay.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = OptionGroupValueObjectDisplay.cpp; path = source/Interpreter/OptionGroupValueObjectDisplay.cpp; sourceTree = "<group>"; };
 		267DFB441B06752A00000FB7 /* MICmdArgValPrintValues.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = MICmdArgValPrintValues.cpp; path = "tools/lldb-mi/MICmdArgValPrintValues.cpp"; sourceTree = SOURCE_ROOT; };
@@ -4418,14 +4425,20 @@
 				3FDFE57519AFABFD009756A7 /* HostThread.h */,
 				236124A61986B50E004EFC37 /* IOObject.h */,
 				26BC7DD510F1B7D500F91463 /* Mutex.h */,
+				267A47F31B14116E0021A5BC /* NativeBreakpoint.h */,
 				232CB60B191E00CC00EF39FC /* NativeBreakpoint.cpp */,
-				232CB60C191E00CC00EF39FC /* NativeBreakpoint.h */,
+				267A47F41B1411750021A5BC /* NativeBreakpointList.h */,
 				232CB60D191E00CC00EF39FC /* NativeBreakpointList.cpp */,
-				232CB60E191E00CC00EF39FC /* NativeBreakpointList.h */,
+				267A47F51B14117F0021A5BC /* NativeProcessProtocol.h */,
 				232CB60F191E00CC00EF39FC /* NativeProcessProtocol.cpp */,
-				232CB610191E00CC00EF39FC /* NativeProcessProtocol.h */,
+				267A47F61B14118F0021A5BC /* NativeRegisterContext.h */,
+				267A47FA1B1411C40021A5BC /* NativeRegisterContext.cpp */,
+				267A47F71B14119A0021A5BC /* NativeRegisterContextRegisterInfo.h */,
+				267A47FC1B1411CC0021A5BC /* NativeRegisterContextRegisterInfo.cpp */,
+				267A47F81B1411A40021A5BC /* NativeThreadProtocol.h */,
 				232CB611191E00CC00EF39FC /* NativeThreadProtocol.cpp */,
-				232CB612191E00CC00EF39FC /* NativeThreadProtocol.h */,
+				267A47F91B1411AC0021A5BC /* NativeWatchpointList.h */,
+				267A47FE1B1411D90021A5BC /* NativeWatchpointList.cpp */,
 				A36FF33D17D8E98800244D40 /* OptionParser.h */,
 				260A39A519647A3A004B4130 /* Pipe.h */,
 				3F5E8AF31A40D4A500A73232 /* PipeBase.h */,
@@ -4434,14 +4447,16 @@
 				236124A71986B50E004EFC37 /* Socket.h */,
 				26D7E45B13D5E2F9007FD12B /* SocketAddress.h */,
 				26D7E45C13D5E30A007FD12B /* SocketAddress.cpp */,
+				267A47F21B14115A0021A5BC /* SoftwareBreakpoint.h */,
 				232CB613191E00CC00EF39FC /* SoftwareBreakpoint.cpp */,
-				232CB614191E00CD00EF39FC /* SoftwareBreakpoint.h */,
 				2689B0A4113EE3CD00A4AEDB /* Symbols.h */,
 				268DA871130095D000C9483A /* Terminal.h */,
 				3FDFED0D19B7D269009756A7 /* ThisThread.cpp */,
 				3FDFED0919B7C8C7009756A7 /* ThisThread.h */,
 				3FDFED2319BA6D55009756A7 /* ThreadLauncher.h */,
 				26B4E26E112F35F700AB3F64 /* TimeValue.h */,
+				267A48031B1416080021A5BC /* XML.h */,
+				267A48001B1411E40021A5BC /* XML.cpp */,
 			);
 			name = Host;
 			sourceTree = "<group>";
@@ -5435,7 +5450,6 @@
 				AF1F7B08189C904B0087DB9C /* AppleGetPendingItemsHandler.h in Headers */,
 				AF77E0AA1A033D740096C0EA /* RegisterContextPOSIXCore_powerpc.h in Headers */,
 				AF2BCA6D18C7EFDE005B4526 /* JITLoaderGDB.h in Headers */,
-				232CB61E191E00CD00EF39FC /* SoftwareBreakpoint.h in Headers */,
 				B5EFAE871AE53B1D007059F3 /* RegisterContextFreeBSD_arm.h in Headers */,
 				26BC17B218C7F4CB00D2196D /* ThreadElfCore.h in Headers */,
 				AF77E0A51A033D360096C0EA /* RegisterContextPOSIX_powerpc.h in Headers */,
@@ -5461,7 +5475,6 @@
 				260CC63115D04377002BF2E0 /* OptionValueProperties.h in Headers */,
 				260CC63215D04377002BF2E0 /* OptionValueDictionary.h in Headers */,
 				262173A118395D3800C52091 /* SectionLoadHistory.h in Headers */,
-				232CB61A191E00CD00EF39FC /* NativeProcessProtocol.h in Headers */,
 				260CC63315D04377002BF2E0 /* OptionValueEnumeration.h in Headers */,
 				AF45FDE618A1F3AC0007051C /* AppleGetThreadItemInfoHandler.h in Headers */,
 				260A63171861008E00FECF8E /* IOHandler.h in Headers */,
@@ -5515,10 +5528,7 @@
 				49724D9A1AD6ED390033C538 /* RenderScriptRuntime.h in Headers */,
 				4C73152219B7D71700F865A4 /* Iterable.h in Headers */,
 				2698699D15E6CBD0002415FF /* OperatingSystemPython.h in Headers */,
-				232CB618191E00CD00EF39FC /* NativeBreakpointList.h in Headers */,
 				260D9B2715EC369500960137 /* ModuleSpec.h in Headers */,
-				232CB61C191E00CD00EF39FC /* NativeThreadProtocol.h in Headers */,
-				232CB616191E00CD00EF39FC /* NativeBreakpoint.h in Headers */,
 				947A1D651616476B0017C8D1 /* CommandObjectPlugin.h in Headers */,
 				262ED0051631FA2800879631 /* OptionGroupString.h in Headers */,
 				26474CA918D0CB070073DEBA /* RegisterContextFreeBSD_i386.h in Headers */,
@@ -6029,6 +6039,7 @@
 				2689FFDA13353D9D00698AC0 /* lldb.cpp in Sources */,
 				26474CCD18D0CB5B0073DEBA /* RegisterContextPOSIX_x86.cpp in Sources */,
 				2689FFEF13353DB600698AC0 /* Breakpoint.cpp in Sources */,
+				267A47FB1B1411C40021A5BC /* NativeRegisterContext.cpp in Sources */,
 				2689FFF113353DB600698AC0 /* BreakpointID.cpp in Sources */,
 				AF77E0A91A033D740096C0EA /* RegisterContextPOSIXCore_powerpc.cpp in Sources */,
 				2689FFF313353DB600698AC0 /* BreakpointIDList.cpp in Sources */,
@@ -6088,6 +6099,7 @@
 				2689002413353DDE00698AC0 /* CommandObjectSettings.cpp in Sources */,
 				2689002513353DDE00698AC0 /* CommandObjectSource.cpp in Sources */,
 				2689002613353DDE00698AC0 /* CommandObjectSyntax.cpp in Sources */,
+				267A48011B1411E40021A5BC /* XML.cpp in Sources */,
 				3F8169331ABB7A6D001DA9DF /* SystemLifetimeManager.cpp in Sources */,
 				4959511F1A1BC4BC00F6F8FC /* ClangModulesDeclVendor.cpp in Sources */,
 				26BC179918C7F2B300D2196D /* JITLoader.cpp in Sources */,
@@ -6256,6 +6268,7 @@
 				3FDFE56C19AF9C44009756A7 /* HostProcessPosix.cpp in Sources */,
 				268900B413353E5000698AC0 /* RegisterContextMacOSXFrameBackchain.cpp in Sources */,
 				3F8169311ABB7A6D001DA9DF /* SystemInitializer.cpp in Sources */,
+				267A47FD1B1411CC0021A5BC /* NativeRegisterContextRegisterInfo.cpp in Sources */,
 				3FDFED2D19C257A0009756A7 /* HostProcess.cpp in Sources */,
 				268900B513353E5000698AC0 /* StopInfoMachException.cpp in Sources */,
 				268900B613353E5000698AC0 /* UnwindMacOSXFrameBackchain.cpp in Sources */,
@@ -6467,6 +6480,7 @@
 				26D7E45D13D5E30A007FD12B /* SocketAddress.cpp in Sources */,
 				94CD7D0C19A3FBCE00908B7C /* AppleObjCTypeEncodingParser.cpp in Sources */,
 				94B6E76213D88365005F417F /* ValueObjectSyntheticFilter.cpp in Sources */,
+				267A47FF1B1411D90021A5BC /* NativeWatchpointList.cpp in Sources */,
 				26F4A21C13FBA31A0064B613 /* ThreadMemory.cpp in Sources */,
 				94EA27CE17DE91750070F505 /* LibCxxUnorderedMap.cpp in Sources */,
 				266DFE9713FD656E00D0C574 /* OperatingSystem.cpp in Sources */,

Modified: lldb/trunk/source/Host/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/CMakeLists.txt?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/source/Host/CMakeLists.txt (original)
+++ lldb/trunk/source/Host/CMakeLists.txt Tue May 26 13:00:51 2015
@@ -37,6 +37,7 @@ add_host_subdirectory(common
   common/ThisThread.cpp
   common/ThreadLauncher.cpp
   common/TimeValue.cpp
+  common/XML.cpp
   )
 
 if (NOT LLDB_DISABLE_LIBEDIT)

Added: lldb/trunk/source/Host/common/XML.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Host/common/XML.cpp?rev=238224&view=auto
==============================================================================
--- lldb/trunk/source/Host/common/XML.cpp (added)
+++ lldb/trunk/source/Host/common/XML.cpp Tue May 26 13:00:51 2015
@@ -0,0 +1,548 @@
+//===-- XML.cpp -------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lldb/Host/XML.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+
+#pragma mark -- XMLDocument
+
+XMLDocument::XMLDocument () :
+    m_document (nullptr)
+{
+}
+
+XMLDocument::~XMLDocument ()
+{
+    Clear();
+}
+
+void
+XMLDocument::Clear()
+{
+#if defined( LIBXML2_DEFINED )
+    if (m_document)
+    {
+        xmlDocPtr doc = m_document;
+        m_document = nullptr;
+        xmlFreeDoc(doc);
+    }
+#endif
+}
+
+bool
+XMLDocument::IsValid() const
+{
+    return m_document != nullptr;
+}
+
+void
+XMLDocument::ErrorCallback (void *ctx, const char *format, ...)
+{
+    XMLDocument *document = (XMLDocument *)ctx;
+    va_list args;
+    va_start (args, format);
+    document->m_errors.PrintfVarArg(format, args);
+    document->m_errors.EOL();
+    va_end (args);
+}
+
+bool
+XMLDocument::ParseFile (const char *path)
+{
+#if defined( LIBXML2_DEFINED )
+    Clear();
+    xmlSetGenericErrorFunc( (void *)this, XMLDocument::ErrorCallback );
+    m_document = xmlParseFile(path);
+    xmlSetGenericErrorFunc(nullptr, nullptr);
+#endif
+    return IsValid();
+}
+
+bool
+XMLDocument::ParseMemory (const char *xml, size_t xml_length, const char *url)
+{
+#if defined( LIBXML2_DEFINED )
+    Clear();
+    xmlSetGenericErrorFunc( (void *)this, XMLDocument::ErrorCallback );
+    m_document = xmlReadMemory(xml, (int)xml_length, url, nullptr, 0);
+    xmlSetGenericErrorFunc(nullptr, nullptr);
+#endif
+    return IsValid();
+    
+}
+
+XMLNode
+XMLDocument::GetRootElement(const char *required_name)
+{
+#if defined( LIBXML2_DEFINED )
+    if (IsValid())
+    {
+        XMLNode root_node(xmlDocGetRootElement(m_document));
+        if (required_name)
+        {
+            llvm::StringRef actual_name = root_node.GetName();
+            if (actual_name == required_name)
+                return root_node;
+        }
+        else
+        {
+            return root_node;
+        }
+    }
+#endif
+    return XMLNode();
+}
+
+bool
+XMLDocument::XMLEnabled ()
+{
+#if defined( LIBXML2_DEFINED )
+    return true;
+#else
+    return false;
+#endif
+}
+
+#pragma mark -- XMLNode
+
+XMLNode::XMLNode() :
+    m_node(nullptr)
+{
+}
+
+XMLNode::XMLNode(XMLNodeImpl node) :
+    m_node(node)
+{
+}
+
+XMLNode::~XMLNode()
+{
+    
+}
+
+void
+XMLNode::Clear()
+{
+    m_node = nullptr;
+}
+
+XMLNode
+XMLNode::GetParent() const
+{
+#if defined( LIBXML2_DEFINED )
+    if (IsValid())
+        return XMLNode(m_node->parent);
+    else
+        return XMLNode();
+#else
+    return XMLNode();
+#endif
+
+}
+
+XMLNode
+XMLNode::GetSibling() const
+{
+#if defined( LIBXML2_DEFINED )
+    if (IsValid())
+        return XMLNode(m_node->next);
+    else
+        return XMLNode();
+#else
+    return XMLNode();
+#endif
+
+}
+
+XMLNode
+XMLNode::GetChild () const
+{
+#if defined( LIBXML2_DEFINED )
+
+    if (IsValid())
+        return XMLNode(m_node->children);
+    else
+        return XMLNode();
+#else
+    return XMLNode();
+#endif
+
+}
+
+llvm::StringRef
+XMLNode::GetAttributeValue(const char *name, const char *fail_value) const
+{
+    const char *attr_value = NULL;
+#if defined( LIBXML2_DEFINED )
+
+    if (IsValid())
+        attr_value = (const char *)xmlGetProp(m_node, (const xmlChar *)name);
+    else
+        attr_value = fail_value;
+#else
+    attr_value = fail_value;
+#endif
+    if (attr_value)
+        return llvm::StringRef(attr_value);
+    else
+        return llvm::StringRef();
+}
+
+
+
+
+void
+XMLNode::ForEachChildNode (NodeCallback const &callback) const
+{
+#if defined( LIBXML2_DEFINED )
+    if (IsValid())
+        GetChild().ForEachSiblingNode(callback);
+#endif
+}
+
+void
+XMLNode::ForEachChildElement (NodeCallback const &callback) const
+{
+#if defined( LIBXML2_DEFINED )
+    XMLNode child = GetChild();
+    if (child)
+        child.ForEachSiblingElement(callback);
+#endif
+}
+
+void
+XMLNode::ForEachChildElementWithName (const char *name, NodeCallback const &callback) const
+{
+#if defined( LIBXML2_DEFINED )
+    XMLNode child = GetChild();
+    if (child)
+        child.ForEachSiblingElementWithName(name, callback);
+#endif
+}
+
+void
+XMLNode::ForEachAttribute (AttributeCallback const &callback) const
+{
+#if defined( LIBXML2_DEFINED )
+
+    if (IsValid())
+    {
+        for (xmlAttrPtr attr = m_node->properties; attr != nullptr; attr=attr->next)
+        {
+            // check if name matches
+            if (attr->name)
+            {
+                // check child is a text node
+                xmlNodePtr child = attr->children;
+                if (child->type == XML_TEXT_NODE)
+                {
+                    llvm::StringRef attr_value;
+                    if (child->content)
+                        attr_value = llvm::StringRef((const char *)child->content);
+                    if (callback(llvm::StringRef((const char *)attr->name), attr_value) == false)
+                        return;
+                }
+            }
+        }
+    }
+#endif
+}
+
+
+void
+XMLNode::ForEachSiblingNode (NodeCallback const &callback) const
+{
+#if defined( LIBXML2_DEFINED )
+
+    if (IsValid())
+    {
+        // iterate through all siblings
+        for (xmlNodePtr node = m_node; node; node=node->next)
+        {
+            if (callback(XMLNode(node)) == false)
+                return;
+        }
+    }
+#endif
+}
+
+void
+XMLNode::ForEachSiblingElement (NodeCallback const &callback) const
+{
+#if defined( LIBXML2_DEFINED )
+    
+    if (IsValid())
+    {
+        // iterate through all siblings
+        for (xmlNodePtr node = m_node; node; node=node->next)
+        {
+            // we are looking for element nodes only
+            if (node->type != XML_ELEMENT_NODE)
+                continue;
+            
+            if (callback(XMLNode(node)) == false)
+                return;
+        }
+    }
+#endif
+}
+
+void
+XMLNode::ForEachSiblingElementWithName (const char *name, NodeCallback const &callback) const
+{
+#if defined( LIBXML2_DEFINED )
+    
+    if (IsValid())
+    {
+        // iterate through all siblings
+        for (xmlNodePtr node = m_node; node; node=node->next)
+        {
+            // we are looking for element nodes only
+            if (node->type != XML_ELEMENT_NODE)
+                continue;
+            
+            // If name is nullptr, we take all nodes of type "t", else
+            // just the ones whose name matches
+            if (name)
+            {
+                if (strcmp((const char *)node->name, name) != 0)
+                    continue; // Name mismatch, ignore this one
+            }
+            else
+            {
+                if (node->name)
+                    continue; // nullptr name specified and this elemnt has a name, ignore this one
+            }
+            
+            if (callback(XMLNode(node)) == false)
+                return;
+        }
+    }
+#endif
+}
+
+llvm::StringRef
+XMLNode::GetName() const
+{
+#if defined( LIBXML2_DEFINED )
+    if (IsValid())
+    {
+        if (m_node->name)
+            return llvm::StringRef((const char *)m_node->name);
+    }
+#endif
+    return llvm::StringRef();
+}
+
+bool
+XMLNode::GetElementText (std::string &text) const
+{
+    text.clear();
+#if defined( LIBXML2_DEFINED )
+    if (IsValid())
+    {
+        bool success = false;
+        if (m_node->type == XML_ELEMENT_NODE)
+        {
+            // check child is a text node
+            for (xmlNodePtr node = m_node->children;
+                 node != nullptr;
+                 node = node->next)
+            {
+                if (node->type == XML_TEXT_NODE)
+                {
+                    text.append((const char *)node->content);
+                    success = true;
+                }
+            }
+        }
+        return success;
+    }
+#endif
+    return false;
+}
+
+
+
+bool
+XMLNode::NameIs (const char *name) const
+{
+#if defined( LIBXML2_DEFINED )
+
+    if (IsValid())
+    {
+        // In case we are looking for a nullptr name or an exact pointer match
+        if (m_node->name == (const xmlChar *)name)
+            return true;
+        if (m_node->name)
+            return strcmp((const char *)m_node->name, name) == 0;
+    }
+#endif
+    return false;
+}
+
+XMLNode
+XMLNode::FindFirstChildElementWithName (const char *name) const
+{
+    XMLNode result_node;
+
+#if defined( LIBXML2_DEFINED )
+    ForEachChildElementWithName(name, [&result_node, name](const XMLNode& node) -> bool {
+        result_node = node;
+        // Stop iterating, we found the node we wanted
+        return false;
+    });
+#endif
+
+    return result_node;
+}
+
+bool
+XMLNode::IsValid() const
+{
+    return m_node != nullptr;
+}
+
+bool
+XMLNode::IsElement () const
+{
+#if defined( LIBXML2_DEFINED )
+    if (IsValid())
+        return m_node->type == XML_ELEMENT_NODE;
+#endif
+    return false;
+}
+
+
+XMLNode
+XMLNode::GetElementForPath (const NamePath &path)
+{
+#if defined( LIBXML2_DEFINED )
+
+    if (IsValid())
+    {
+        if (path.empty())
+            return *this;
+        else
+        {
+            XMLNode node = FindFirstChildElementWithName(path[0].c_str());
+            const size_t n = path.size();
+            for (size_t i=1; node && i<n; ++i)
+                node = node.FindFirstChildElementWithName(path[i].c_str());
+            return node;
+        }
+    }
+#endif
+
+    return XMLNode();
+}
+
+
+#pragma mark -- ApplePropertyList
+
+ApplePropertyList::ApplePropertyList() :
+    m_xml_doc(),
+    m_dict_node()
+{
+    
+}
+
+ApplePropertyList::ApplePropertyList (const char *path) :
+    m_xml_doc(),
+    m_dict_node()
+{
+    ParseFile(path);
+}
+
+bool
+ApplePropertyList::ParseFile (const char *path)
+{
+    if (m_xml_doc.ParseFile(path))
+    {
+        XMLNode plist = m_xml_doc.GetRootElement("plist");
+        if (plist)
+        {
+            plist.ForEachChildElementWithName("dict", [this](const XMLNode &dict) -> bool {
+                this->m_dict_node = dict;
+                return false; // Stop iterating
+            });
+            return (bool)m_dict_node;
+        }
+    }
+    return false;
+}
+
+bool
+ApplePropertyList::IsValid() const
+{
+    return (bool)m_dict_node;
+}
+
+bool
+ApplePropertyList::GetValueAsString (const char *key, std::string &value) const
+{
+    XMLNode value_node = GetValueNode (key);
+    if (value_node)
+        return ApplePropertyList::ExtractStringFromValueNode(value_node, value);
+    return false;
+}
+
+XMLNode
+ApplePropertyList::GetValueNode (const char *key) const
+{
+    XMLNode value_node;
+#if defined( LIBXML2_DEFINED )
+    
+    if (IsValid())
+    {
+        m_dict_node.ForEachChildElementWithName("key", [key, &value_node](const XMLNode &key_node) -> bool {
+            std::string key_name;
+            if (key_node.GetElementText(key_name))
+            {
+                if (key_name.compare(key) == 0)
+                {
+                    value_node = key_node.GetSibling();
+                    while (value_node && !value_node.IsElement())
+                        value_node = value_node.GetSibling();
+                    return false; // Stop iterating
+                }
+            }
+            return true; // Keep iterating
+        });
+    }
+#endif
+    return value_node;
+}
+
+bool
+ApplePropertyList::ExtractStringFromValueNode (const XMLNode &node, std::string &value)
+{
+    value.clear();
+#if defined( LIBXML2_DEFINED )
+    if (node.IsValid())
+    {
+        llvm::StringRef element_name = node.GetName();
+        if (element_name == "true" or element_name == "false")
+        {
+            // The text value _is_ the element name itself...
+            value = std::move(element_name.str());
+            return true;
+        }
+        else if (element_name == "dict" or element_name == "array")
+            return false; // dictionaries and arrays have no text value, so we fail
+        else
+            return node.GetElementText(value);
+    }
+#endif
+    return false;
+}
+

Modified: lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp (original)
+++ lldb/trunk/source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp Tue May 26 13:00:51 2015
@@ -146,7 +146,7 @@ OperatingSystemPython::GetDynamicRegiste
         if (!dictionary)
             return NULL;
 
-        m_register_info_ap.reset(new DynamicRegisterInfo(*dictionary, m_process->GetTarget().GetArchitecture().GetByteOrder()));
+        m_register_info_ap.reset(new DynamicRegisterInfo(*dictionary, m_process->GetTarget().GetArchitecture()));
         assert (m_register_info_ap->GetNumRegisters() > 0);
         assert (m_register_info_ap->GetNumRegisterSets() > 0);
     }

Modified: lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp (original)
+++ lldb/trunk/source/Plugins/Platform/Windows/PlatformWindows.cpp Tue May 26 13:00:51 2015
@@ -742,4 +742,4 @@ PlatformWindows::GetEnvironment(StringLi
     }
 
     return Host::GetEnvironment(env);
-}
\ No newline at end of file
+}

Modified: lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp (original)
+++ lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.cpp Tue May 26 13:00:51 2015
@@ -15,11 +15,12 @@
 // C++ Includes
 // Other libraries and framework includes
 // Project includes
-#include "lldb/Host/StringConvert.h"
+#include "lldb/Core/ArchSpec.h"
 #include "lldb/Core/RegularExpression.h"
 #include "lldb/Core/StreamFile.h"
 #include "lldb/Core/StructuredData.h"
 #include "lldb/DataFormatters/FormatManager.h"
+#include "lldb/Host/StringConvert.h"
 
 using namespace lldb;
 using namespace lldb_private;
@@ -36,17 +37,18 @@ DynamicRegisterInfo::DynamicRegisterInfo
 {
 }
 
-DynamicRegisterInfo::DynamicRegisterInfo(const StructuredData::Dictionary &dict, ByteOrder byte_order)
-    : m_regs()
-    , m_sets()
-    , m_set_reg_nums()
-    , m_set_names()
-    , m_value_regs_map()
-    , m_invalidate_regs_map()
-    , m_reg_data_byte_size(0)
-    , m_finalized(false)
+DynamicRegisterInfo::DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
+                                         const lldb_private::ArchSpec &arch) :
+    m_regs (),
+    m_sets (),
+    m_set_reg_nums (),
+    m_set_names (),
+    m_value_regs_map (),
+    m_invalidate_regs_map (),
+    m_reg_data_byte_size (0),
+    m_finalized (false)
 {
-    SetRegisterInfo (dict, byte_order);
+    SetRegisterInfo (dict, arch);
 }
 
 DynamicRegisterInfo::~DynamicRegisterInfo ()
@@ -54,7 +56,7 @@ DynamicRegisterInfo::~DynamicRegisterInf
 }
 
 size_t
-DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, ByteOrder byte_order)
+DynamicRegisterInfo::SetRegisterInfo(const StructuredData::Dictionary &dict, const ArchSpec &arch)
 {
     assert(!m_finalized);
     StructuredData::Array *sets = nullptr;
@@ -121,6 +123,8 @@ DynamicRegisterInfo::SetRegisterInfo(con
 
         reg_info_dict->GetValueForKeyAsInteger("offset", reg_info.byte_offset, UINT32_MAX);
 
+        const ByteOrder byte_order = arch.GetByteOrder();
+        
         if (reg_info.byte_offset == UINT32_MAX)
         {
             // No offset for this register, see if the register has a value expression
@@ -384,7 +388,7 @@ DynamicRegisterInfo::SetRegisterInfo(con
         m_regs.push_back(reg_info);
         m_set_reg_nums[set].push_back(i);
     }
-    Finalize();
+    Finalize(arch);
     return m_regs.size();
 }
 
@@ -423,7 +427,7 @@ DynamicRegisterInfo::AddRegister (Regist
 }
 
 void
-DynamicRegisterInfo::Finalize ()
+DynamicRegisterInfo::Finalize (const ArchSpec &arch)
 {
     if (m_finalized)
         return;
@@ -518,6 +522,95 @@ DynamicRegisterInfo::Finalize ()
         else
             m_regs[i].invalidate_regs = NULL;
     }
+    
+    // Check if we need to automatically set the generic registers in case
+    // they weren't set
+    bool generic_regs_specified = false;
+    for (const auto &reg: m_regs)
+    {
+        if (reg.kinds[eRegisterKindGeneric] != LLDB_INVALID_REGNUM)
+        {
+            generic_regs_specified = true;
+            break;
+        }
+    }
+
+    if (!generic_regs_specified)
+    {
+        switch (arch.GetMachine())
+        {
+        case llvm::Triple::aarch64:
+        case llvm::Triple::aarch64_be:
+            for (auto &reg: m_regs)
+            {
+                if (strcmp(reg.name, "pc") == 0)
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+                else if ((strcmp(reg.name, "fp") == 0) || (strcmp(reg.name, "x29") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+                else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "x30") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+                else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "x31") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+                else if (strcmp(reg.name, "cpsr") == 0)
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+            }
+            break;
+            
+        case llvm::Triple::arm:
+        case llvm::Triple::armeb:
+        case llvm::Triple::thumb:
+        case llvm::Triple::thumbeb:
+            for (auto &reg: m_regs)
+            {
+                if ((strcmp(reg.name, "pc") == 0) || (strcmp(reg.name, "r15") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+                else if ((strcmp(reg.name, "sp") == 0) || (strcmp(reg.name, "r13") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+                else if ((strcmp(reg.name, "lr") == 0) || (strcmp(reg.name, "r14") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_RA;
+                else if ((strcmp(reg.name, "r7") == 0) && arch.GetTriple().getVendor() == llvm::Triple::Apple)
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+                else if ((strcmp(reg.name, "r11") == 0) && arch.GetTriple().getVendor() != llvm::Triple::Apple)
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+                else if (strcmp(reg.name, "fp") == 0)
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+                else if (strcmp(reg.name, "cpsr") == 0)
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+            }
+            break;
+            
+        case llvm::Triple::x86:
+            for (auto &reg: m_regs)
+            {
+                if ((strcmp(reg.name, "eip") == 0) || (strcmp(reg.name, "pc") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+                else if ((strcmp(reg.name, "esp") == 0) || (strcmp(reg.name, "sp") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+                else if ((strcmp(reg.name, "ebp") == 0) || (strcmp(reg.name, "fp") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+                else if ((strcmp(reg.name, "eflags") == 0) || (strcmp(reg.name, "flags") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+            }
+            break;
+
+        case llvm::Triple::x86_64:
+            for (auto &reg: m_regs)
+            {
+                if ((strcmp(reg.name, "rip") == 0) || (strcmp(reg.name, "pc") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_PC;
+                else if ((strcmp(reg.name, "rsp") == 0) || (strcmp(reg.name, "sp") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_SP;
+                else if ((strcmp(reg.name, "rbp") == 0) || (strcmp(reg.name, "fp") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FP;
+                else if ((strcmp(reg.name, "rflags") == 0) || (strcmp(reg.name, "flags") == 0))
+                    reg.kinds[eRegisterKindGeneric] = LLDB_REGNUM_GENERIC_FLAGS;
+            }
+            break;
+
+        default:
+            break;
+        }
+    }
 }
 
 size_t

Modified: lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.h?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.h (original)
+++ lldb/trunk/source/Plugins/Process/Utility/DynamicRegisterInfo.h Tue May 26 13:00:51 2015
@@ -26,12 +26,14 @@ class DynamicRegisterInfo
 public:
     DynamicRegisterInfo ();
 
-    DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, lldb::ByteOrder byte_order);
+    DynamicRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
+                        const lldb_private::ArchSpec &arch);
 
     virtual 
     ~DynamicRegisterInfo ();
 
-    size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict, lldb::ByteOrder byte_order);
+    size_t SetRegisterInfo(const lldb_private::StructuredData::Dictionary &dict,
+                           const lldb_private::ArchSpec &arch);
 
     void
     AddRegister (lldb_private::RegisterInfo &reg_info, 
@@ -40,7 +42,7 @@ public:
                  lldb_private::ConstString &set_name);
 
     void
-    Finalize ();
+    Finalize (const lldb_private::ArchSpec &arch);
 
     size_t
     GetNumRegisters() const;

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp Tue May 26 13:00:51 2015
@@ -3929,9 +3929,12 @@ GDBRemoteCommunicationClient::ReadExtFea
     std::stringstream output;
     StringExtractorGDBRemote chunk;
 
-    const int size   = 0xfff;
-    int       offset = 0;
-    bool      active = true;
+    uint64_t size = GetRemoteMaxPacketSize();
+    if (size == 0)
+        size = 0x1000;
+    size = size - 1; // Leave space for the 'm' or 'l' character in the response
+    int offset = 0;
+    bool active = true;
 
     // loop until all data has been read
     while ( active ) {

Modified: lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (original)
+++ lldb/trunk/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp Tue May 26 13:00:51 2015
@@ -26,11 +26,6 @@
 #include <map>
 #include <mutex>
 
-// Other libraries and framework includes
-#if defined( LIBXML2_DEFINED )
-#include <libxml/xmlreader.h>
-#endif
-
 #include "lldb/Breakpoint/Watchpoint.h"
 #include "lldb/Interpreter/Args.h"
 #include "lldb/Core/ArchSpec.h"
@@ -45,11 +40,13 @@
 #include "lldb/Core/StreamString.h"
 #include "lldb/Core/Timer.h"
 #include "lldb/Core/Value.h"
+#include "lldb/DataFormatters/FormatManager.h"
 #include "lldb/Host/HostThread.h"
 #include "lldb/Host/StringConvert.h"
 #include "lldb/Host/Symbols.h"
 #include "lldb/Host/ThreadLauncher.h"
 #include "lldb/Host/TimeValue.h"
+#include "lldb/Host/XML.h"
 #include "lldb/Interpreter/CommandInterpreter.h"
 #include "lldb/Interpreter/CommandObject.h"
 #include "lldb/Interpreter/CommandObjectMultiword.h"
@@ -478,7 +475,7 @@ ProcessGDBRemote::ParsePythonTargetDefin
                     m_breakpoint_pc_offset = breakpoint_pc_int_value->GetValue();
             }
 
-            if (m_register_info.SetRegisterInfo(*target_definition_sp, GetTarget().GetArchitecture().GetByteOrder()) > 0)
+            if (m_register_info.SetRegisterInfo(*target_definition_sp, GetTarget().GetArchitecture()) > 0)
             {
                 return true;
             }
@@ -487,6 +484,25 @@ ProcessGDBRemote::ParsePythonTargetDefin
     return false;
 }
 
+static size_t
+SplitCommaSeparatedRegisterNumberString(const llvm::StringRef &comma_separated_regiter_numbers, std::vector<uint32_t> &regnums, int base)
+{
+    regnums.clear();
+    std::pair<llvm::StringRef, llvm::StringRef> value_pair;
+    value_pair.second = comma_separated_regiter_numbers;
+    do
+    {
+        value_pair = value_pair.second.split(',');
+        if (!value_pair.first.empty())
+        {
+            uint32_t reg = StringConvert::ToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, base);
+            if (reg != LLDB_INVALID_REGNUM)
+                regnums.push_back (reg);
+        }
+    } while (!value_pair.second.empty());
+    return regnums.size();
+}
+
 
 void
 ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
@@ -494,8 +510,21 @@ ProcessGDBRemote::BuildDynamicRegisterIn
     if (!force && m_register_info.GetNumRegisters() > 0)
         return;
 
-    char packet[128];
     m_register_info.Clear();
+
+    // Check if qHostInfo specified a specific packet timeout for this connection.
+    // If so then lets update our setting so the user knows what the timeout is
+    // and can see it.
+    const uint32_t host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout();
+    if (host_packet_timeout)
+    {
+        GetGlobalPluginProperties()->SetPacketTimeout(host_packet_timeout);
+    }
+
+    if (GetGDBServerRegisterInfo ())
+        return;
+    
+    char packet[128];
     uint32_t reg_offset = 0;
     uint32_t reg_num = 0;
     for (StringExtractorGDBRemote::ResponseType response_type = StringExtractorGDBRemote::eResponse;
@@ -610,33 +639,11 @@ ProcessGDBRemote::BuildDynamicRegisterIn
                     }
                     else if (name.compare("container-regs") == 0)
                     {
-                        std::pair<llvm::StringRef, llvm::StringRef> value_pair;
-                        value_pair.second = value;
-                        do
-                        {
-                            value_pair = value_pair.second.split(',');
-                            if (!value_pair.first.empty())
-                            {
-                                uint32_t reg = StringConvert::ToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
-                                if (reg != LLDB_INVALID_REGNUM)
-                                    value_regs.push_back (reg);
-                            }
-                        } while (!value_pair.second.empty());
+                        SplitCommaSeparatedRegisterNumberString(value, value_regs, 16);
                     }
                     else if (name.compare("invalidate-regs") == 0)
                     {
-                        std::pair<llvm::StringRef, llvm::StringRef> value_pair;
-                        value_pair.second = value;
-                        do
-                        {
-                            value_pair = value_pair.second.split(',');
-                            if (!value_pair.first.empty())
-                            {
-                                uint32_t reg = StringConvert::ToUInt32 (value_pair.first.str().c_str(), LLDB_INVALID_REGNUM, 16);
-                                if (reg != LLDB_INVALID_REGNUM)
-                                    invalidate_regs.push_back (reg);
-                            }
-                        } while (!value_pair.second.empty());
+                        SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 16);
                     }
                 }
 
@@ -667,30 +674,19 @@ ProcessGDBRemote::BuildDynamicRegisterIn
         }
     }
 
-    // Check if qHostInfo specified a specific packet timeout for this connection.
-    // If so then lets update our setting so the user knows what the timeout is
-    // and can see it.
-    const uint32_t host_packet_timeout = m_gdb_comm.GetHostDefaultPacketTimeout();
-    if (host_packet_timeout)
+    if (m_register_info.GetNumRegisters() > 0)
     {
-        GetGlobalPluginProperties()->SetPacketTimeout(host_packet_timeout);
+        m_register_info.Finalize(GetTarget().GetArchitecture());
+        return;
     }
-    
 
-    if (reg_num == 0)
+    FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile ();
+        
+    if (target_definition_fspec)
     {
-        // try to extract information from servers target.xml
-        if (GetGDBServerRegisterInfo ())
+        // See if we can get register definitions from a python file
+        if (ParsePythonTargetDefinition (target_definition_fspec))
             return;
-
-        FileSpec target_definition_fspec = GetGlobalPluginProperties()->GetTargetDefinitionFile ();
-        
-        if (target_definition_fspec)
-        {
-            // See if we can get register definitions from a python file
-            if (ParsePythonTargetDefinition (target_definition_fspec))
-                return;
-        }
     }
 
     // We didn't get anything if the accumulated reg_num is zero.  See if we are
@@ -698,7 +694,7 @@ ProcessGDBRemote::BuildDynamicRegisterIn
     // updated debugserver down on the devices.
     // On the other hand, if the accumulated reg_num is positive, see if we can
     // add composite registers to the existing primordial ones.
-    bool from_scratch = (reg_num == 0);
+    bool from_scratch = (m_register_info.GetNumRegisters() == 0);
 
     const ArchSpec &target_arch = GetTarget().GetArchitecture();
     const ArchSpec &remote_host_arch = m_gdb_comm.GetHostArchitecture();
@@ -724,7 +720,7 @@ ProcessGDBRemote::BuildDynamicRegisterIn
     }
 
     // At this point, we can finalize our register info.
-    m_register_info.Finalize ();
+    m_register_info.Finalize (GetTarget().GetArchitecture());
 }
 
 Error
@@ -3595,420 +3591,208 @@ ProcessGDBRemote::GetModuleSpec(const Fi
     return true;
 }
 
-#if defined( LIBXML2_DEFINED )
 namespace {
 
 typedef std::vector<std::string> stringVec;
-typedef std::vector<xmlNodePtr> xmlNodePtrVec;
-
-struct GdbServerRegisterInfo
-{
-
-    struct
-    {
-        bool m_has_name     : 1;
-        bool m_has_bitSize  : 1;
-        bool m_has_type     : 1;
-        bool m_has_group    : 1;
-        bool m_has_regNum   : 1;
-    }
-    m_flags;
-
-    std::string m_name;
-    std::string m_group;
-    uint32_t    m_bitSize;
-    uint32_t    m_regNum;
-
-    enum RegType
-    {
-        eUnknown   ,
-        eCodePtr   ,
-        eDataPtr   ,
-        eInt32     ,
-        eI387Ext   ,
-    }
-    m_type;
-
-    void clear()
-    {
-        memset(&m_flags, 0, sizeof(m_flags));
-    }
-};
 
 typedef std::vector<struct GdbServerRegisterInfo> GDBServerRegisterVec;
-
-struct GdbServerTargetInfo
+struct RegisterSetInfo
 {
-    std::string m_arch;
-    std::string m_osabi;
+    ConstString name;
 };
 
-// conversion table between gdb register type and enum
-struct
-{
-    const char * m_name;
-    GdbServerRegisterInfo::RegType m_type;
-}
-RegTypeTable[] =
+typedef std::map<uint32_t, RegisterSetInfo> RegisterSetMap;
+ 
+struct GdbServerTargetInfo
 {
-    { "int32"   , GdbServerRegisterInfo::eInt32    },
-    { "int"     , GdbServerRegisterInfo::eInt32    },
-    { "data_ptr", GdbServerRegisterInfo::eDataPtr  },
-    { "code_ptr", GdbServerRegisterInfo::eCodePtr  },
-    { "i387_ext", GdbServerRegisterInfo::eI387Ext  }, // 80bit fpu
-    { nullptr   , GdbServerRegisterInfo::eUnknown  }  // sentinel
+    std::string arch;
+    std::string osabi;
+    stringVec includes;
+    RegisterSetMap reg_set_map;
+    XMLNode feature_node;
 };
-
-// find the first sibling with a matching name
-xmlNodePtr
-xmlExFindSibling (xmlNodePtr node,
-                  const std::string & name)
-{
-
-    if ( !node ) return nullptr;
-    // iterate through all siblings
-    for ( xmlNodePtr temp = node; temp; temp=temp->next ) {
-        // we are looking for elements
-        if ( temp->type != XML_ELEMENT_NODE )
-            continue;
-        // check element name matches
-        if ( !temp->name ) continue;
-        if ( std::strcmp((const char*)temp->name, name.c_str() ) == 0 )
-            return temp;
-    }
-    // no sibling found
-    return nullptr;
-}
-
-// find an element from a given element path
-xmlNodePtr
-xmlExFindElement (xmlNodePtr node,
-                  const stringVec & path)
-{
-
-    if (!node)
-        return nullptr;
-    xmlNodePtr temp = node;
-    // iterate all elements in path
-    for (uint32_t i = 0; i < path.size(); i++)
-    {
-
-        // search for a sibling with this name
-        temp = xmlExFindSibling(temp, path[i]);
-        if (!temp)
-            return nullptr;
-        // enter this node if we still need to search
-        if ((i + 1) < path.size())
-            // enter the node we have found
-            temp = temp->children;
-    }
-    // note: node may still be nullptr at this step
-    return temp;
-}
-
-// locate a specific attribute in an element
-xmlAttr *
-xmlExFindAttribute (xmlNodePtr node,
-                    const std::string & name)
-{
-
-    if (!node)
-        return nullptr;
-    if (node->type != XML_ELEMENT_NODE)
-        return nullptr;
-    // iterate over all attributes
-    for (xmlAttrPtr attr = node->properties; attr != nullptr; attr=attr->next)
-    {
-        // check if name matches
-        if (!attr->name)
-            continue;
-        if (std::strcmp((const char*) attr->name, name.c_str()) == 0)
-            return attr;
-    }
-    return nullptr;
-}
-
-// find all child elements with given name and add them to a vector
-//
-// input:   node = xml element to search
-//          name = name used when matching child elements
-// output:  out  = list of matches
-// return:  number of children added to 'out'
-int
-xmlExFindChildren (xmlNodePtr node,
-                   const std::string & name,
-                   xmlNodePtrVec & out)
-{
-
-    if (!node)
-        return 0;
-    int count = 0;
-    // iterate over all children
-    for (xmlNodePtr child = node->children; child; child = child->next)
-    {
-        // if name matches
-        if (!child->name)
-            continue;
-        if (std::strcmp((const char*) child->name, name.c_str()) == 0)
-        {
-            // add to output list
-            out.push_back(child);
-            ++count;
-        }
-    }
-    return count;
-}
-
-// get the text content from an attribute
-std::string
-xmlExGetTextContent (xmlAttrPtr attr)
-{
-    if (!attr)
-        return std::string();
-    if (attr->type != XML_ATTRIBUTE_NODE)
-        return std::string();
-    // check child is a text node
-    xmlNodePtr child = attr->children;
-    if (child->type != XML_TEXT_NODE)
-        return std::string();
-    // access the content
-    assert(child->content != nullptr);
-    return std::string((const char*) child->content);
-}
-
-// get the text content from an node
-std::string
-xmlExGetTextContent (xmlNodePtr node)
-{
-    if (!node)
-        return std::string();
-    if (node->type != XML_ELEMENT_NODE)
-        return std::string();
-    // check child is a text node
-    xmlNodePtr child = node->children;
-    if (child->type != XML_TEXT_NODE)
-        return std::string();
-    // access the content
-    assert(child->content != nullptr);
-    return std::string((const char*) child->content);
-}
-
-// compile a list of xml includes from the target file
-// input:   doc = target.xml
-// output:  includes = list of .xml names specified in target.xml
-// return:  number of .xml files specified in target.xml and added to includes
-int
-parseTargetIncludes (xmlDocPtr doc, stringVec & includes)
-{
-    if (!doc)
-        return 0;
-    int count = 0;
-    xmlNodePtr elm = xmlExFindElement(doc->children, {"target"});
-    if (!elm)
-        return 0;
-    xmlNodePtrVec nodes;
-    xmlExFindChildren(elm, "xi:include", nodes);
-    // iterate over all includes
-    for (uint32_t i = 0; i < nodes.size(); i++)
-    {
-        xmlAttrPtr attr = xmlExFindAttribute(nodes[i], "href");
-        if (attr != nullptr)
-        {
-            std::string text = xmlExGetTextContent(attr);
-            includes.push_back(text);
-            ++count;
-        }
-    }
-    return count;
-}
-
-// extract target arch information from the target.xml file
-// input:   doc = target.xml document
-// output:  out = remote target information
-// return:  'true'  on success
-//          'false' on failure
-bool
-parseTargetInfo (xmlDocPtr doc, GdbServerTargetInfo & out)
-{
-    if (!doc)
-        return false;
-    xmlNodePtr e1 = xmlExFindElement (doc->children, {"target", "architecture"});
-    if (!e1)
-        return false;
-    out.m_arch = xmlExGetTextContent (e1);
-
-    xmlNodePtr e2 = xmlExFindElement (doc->children, {"target", "osabi"});
-    if (!e2)
-        return false;
-    out.m_osabi = xmlExGetTextContent (e2);
-
-    return true;
-}
-
-// extract register information from one of the xml files specified in target.xml
-// input:   doc = xml document
-// output:  regList = list of extracted register info
-// return:  'true'  on success
-//          'false' on failure
+    
 bool
-parseRegisters (xmlDocPtr doc, GDBServerRegisterVec & regList)
+ParseRegisters (XMLNode feature_node, GdbServerTargetInfo &target_info, GDBRemoteDynamicRegisterInfo &dyn_reg_info)
 {
-
-    if (!doc)
-        return false;
-    xmlNodePtr elm = xmlExFindElement (doc->children, {"feature"});
-    if (!elm)
+    if (!feature_node)
         return false;
+    
+    uint32_t prev_reg_num = 0;
+    uint32_t reg_offset = 0;
 
-    xmlAttrPtr attr = nullptr;
-
-    xmlNodePtrVec regs;
-    xmlExFindChildren (elm, "reg", regs);
-    for (unsigned long i = 0; i < regs.size(); i++)
-    {
-
-        GdbServerRegisterInfo reg;
-        reg.clear();
-
-        if ((attr = xmlExFindAttribute(regs[i], "name")))
-        {
-            reg.m_name = xmlExGetTextContent(attr).c_str();
-            reg.m_flags.m_has_name = true;
-        }
-
-        if ((attr = xmlExFindAttribute( regs[i], "bitsize")))
-        {
-            const std::string v = xmlExGetTextContent(attr);
-            reg.m_bitSize = atoi(v.c_str());
-            reg.m_flags.m_has_bitSize = true;
-        }
-
-        if ((attr = xmlExFindAttribute(regs[i], "type")))
-        {
-            const std::string v = xmlExGetTextContent(attr);
-            reg.m_type = GdbServerRegisterInfo::eUnknown;
-
-            // search the type table for a match
-            for (int j = 0; RegTypeTable[j].m_name !=nullptr; ++j)
+    feature_node.ForEachChildElementWithName("reg", [&target_info, &dyn_reg_info, &prev_reg_num, &reg_offset](const XMLNode &reg_node) -> bool {
+        std::string name;
+        std::string gdb_group;
+        std::string gdb_type;
+        ConstString reg_name;
+        ConstString alt_name;
+        ConstString set_name;
+        std::vector<uint32_t> value_regs;
+        std::vector<uint32_t> invalidate_regs;
+        bool encoding_set = false;
+        bool format_set = false;
+        RegisterInfo reg_info = { NULL,                 // Name
+            NULL,                 // Alt name
+            0,                    // byte size
+            reg_offset,           // offset
+            eEncodingUint,        // encoding
+            eFormatHex,           // formate
+            {
+                LLDB_INVALID_REGNUM, // GCC reg num
+                LLDB_INVALID_REGNUM, // DWARF reg num
+                LLDB_INVALID_REGNUM, // generic reg num
+                prev_reg_num,        // GDB reg num
+                prev_reg_num         // native register number
+            },
+            NULL,
+            NULL
+        };
+        
+        reg_node.ForEachAttribute([&target_info, &name, &gdb_group, &gdb_type, &reg_name, &alt_name, &set_name, &value_regs, &invalidate_regs, &encoding_set, &format_set, &reg_info, &prev_reg_num, &reg_offset](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
+            if (name == "name")
+            {
+                reg_name.SetString(value);
+            }
+            else if (name == "bitsize")
+            {
+                reg_info.byte_size = StringConvert::ToUInt32(value.data(), 0, 0) / CHAR_BIT;
+            }
+            else if (name == "type")
+            {
+                gdb_type = value.str();
+            }
+            else if (name == "group")
             {
-                if (RegTypeTable[j].m_name == v)
+                gdb_group = value.str();
+            }
+            else if (name == "regnum")
+            {
+                const uint32_t regnum = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+                if (regnum != LLDB_INVALID_REGNUM)
                 {
-                    reg.m_type = RegTypeTable[j].m_type;
-                    break;
+                    reg_info.kinds[eRegisterKindGDB] = regnum;
+                    reg_info.kinds[eRegisterKindLLDB] = regnum;
+                    prev_reg_num = regnum;
                 }
             }
-
-            reg.m_flags.m_has_type = (reg.m_type != GdbServerRegisterInfo::eUnknown);
-        }
-
-        if ((attr = xmlExFindAttribute( regs[i], "group")))
-        {
-            reg.m_group = xmlExGetTextContent(attr);
-            reg.m_flags.m_has_group = true;
-        }
-
-        if ((attr = xmlExFindAttribute(regs[i], "regnum")))
-        {
-            const std::string v = xmlExGetTextContent(attr);
-            reg.m_regNum = atoi(v.c_str());
-            reg.m_flags.m_has_regNum = true;
-        }
-
-        regList.push_back(reg);
-    }
-
-    //TODO: there is also a "vector" element to parse
-    //TODO: there is also eflags to parse
-
-    return true;
-}
-
-// build lldb gdb-remote's dynamic register info from a vector of gdb provided registers
-// input:   regList = register information provided by gdbserver
-// output:  regInfo = dynamic register information required by gdb-remote
-void
-BuildRegisters (const GDBServerRegisterVec & regList,
-                GDBRemoteDynamicRegisterInfo & regInfo)
-{
-
-    using namespace lldb_private;
-
-    const uint32_t defSize    = 32;
-          uint32_t regNum     = 0;
-          uint32_t byteOffset = 0;
-
-    for (uint32_t i = 0; i < regList.size(); ++i)
-    {
-
-        const GdbServerRegisterInfo & gdbReg = regList[i];
-
-        std::string name     = gdbReg.m_flags.m_has_name    ? gdbReg.m_name        : "unknown";
-        std::string group    = gdbReg.m_flags.m_has_group   ? gdbReg.m_group       : "general";
-        uint32_t    byteSize = gdbReg.m_flags.m_has_bitSize ? (gdbReg.m_bitSize/8) : defSize;
-
-        if (gdbReg.m_flags.m_has_regNum)
-            regNum = gdbReg.m_regNum;
-
-        uint32_t regNumGcc     = LLDB_INVALID_REGNUM;
-        uint32_t regNumDwarf   = LLDB_INVALID_REGNUM;
-        uint32_t regNumGeneric = LLDB_INVALID_REGNUM;
-        uint32_t regNumGdb     = regNum;
-        uint32_t regNumNative  = regNum;
-
-        if (name == "eip" || name == "pc")
-        {
-            regNumGeneric = LLDB_REGNUM_GENERIC_PC;
-        }
-        if (name == "esp" || name == "sp")
+            else if (name == "offset")
+            {
+                reg_offset = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
+            }
+            else if (name == "altname")
+            {
+                alt_name.SetString(value);
+            }
+            else if (name == "encoding")
+            {
+                encoding_set = true;
+                reg_info.encoding = Args::StringToEncoding (value.data(), eEncodingUint);
+            }
+            else if (name == "format")
+            {
+                format_set = true;
+                Format format = eFormatInvalid;
+                if (Args::StringToFormat (value.data(), format, NULL).Success())
+                    reg_info.format = format;
+                else if (value == "vector-sint8")
+                    reg_info.format = eFormatVectorOfSInt8;
+                else if (value == "vector-uint8")
+                    reg_info.format = eFormatVectorOfUInt8;
+                else if (value == "vector-sint16")
+                    reg_info.format = eFormatVectorOfSInt16;
+                else if (value == "vector-uint16")
+                    reg_info.format = eFormatVectorOfUInt16;
+                else if (value == "vector-sint32")
+                    reg_info.format = eFormatVectorOfSInt32;
+                else if (value == "vector-uint32")
+                    reg_info.format = eFormatVectorOfUInt32;
+                else if (value == "vector-float32")
+                    reg_info.format = eFormatVectorOfFloat32;
+                else if (value == "vector-uint128")
+                    reg_info.format = eFormatVectorOfUInt128;
+            }
+            else if (name == "group_id")
+            {
+                const uint32_t set_id = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
+                RegisterSetMap::const_iterator pos = target_info.reg_set_map.find(set_id);
+                if (pos != target_info.reg_set_map.end())
+                    set_name = pos->second.name;
+            }
+            else if (name == "gcc_regnum")
+            {
+                reg_info.kinds[eRegisterKindGCC] = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+            }
+            else if (name == "dwarf_regnum")
+            {
+                reg_info.kinds[eRegisterKindDWARF] = StringConvert::ToUInt32(value.data(), LLDB_INVALID_REGNUM, 0);
+            }
+            else if (name == "generic")
+            {
+                reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister(value.data());
+            }
+            else if (name == "value_regnums")
+            {
+                SplitCommaSeparatedRegisterNumberString(value, value_regs, 0);
+            }
+            else if (name == "invalidate_regnums")
+            {
+                SplitCommaSeparatedRegisterNumberString(value, invalidate_regs, 0);
+            }
+            else
+            {
+                printf("unhandled attribute %s = %s\n", name.data(), value.data());
+            }
+            return true; // Keep iterating through all attributes
+        });
+        
+        if (!gdb_type.empty() && !(encoding_set || format_set))
         {
-            regNumGeneric = LLDB_REGNUM_GENERIC_SP;
+            if (gdb_type.find("int") == 0)
+            {
+                reg_info.format = eFormatHex;
+                reg_info.encoding = eEncodingUint;
+            }
+            else if (gdb_type == "data_ptr" || gdb_type == "code_ptr")
+            {
+                reg_info.format = eFormatAddressInfo;
+                reg_info.encoding = eEncodingUint;
+            }
+            else if (gdb_type == "i387_ext" || gdb_type == "float")
+            {
+                reg_info.format = eFormatFloat;
+                reg_info.encoding = eEncodingIEEE754;
+            }
         }
-        if (name == "ebp")
+        
+        // Only update the register set name if we didn't get a "reg_set" attribute.
+        // "set_name" will be empty if we didn't have a "reg_set" attribute.
+        if (!set_name && !gdb_group.empty())
+            set_name.SetCString(gdb_group.c_str());
+        
+        reg_info.byte_offset = reg_offset;
+        assert (reg_info.byte_size != 0);
+        reg_offset += reg_info.byte_size;
+        if (!value_regs.empty())
         {
-            regNumGeneric = LLDB_REGNUM_GENERIC_FP;
+            value_regs.push_back(LLDB_INVALID_REGNUM);
+            reg_info.value_regs = value_regs.data();
         }
-        if (name == "lr")
+        if (!invalidate_regs.empty())
         {
-            regNumGeneric = LLDB_REGNUM_GENERIC_RA;
+            invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+            reg_info.invalidate_regs = invalidate_regs.data();
         }
-
-        RegisterInfo info =
-        {
-            name.c_str(),
-            nullptr     ,
-            byteSize    ,
-            byteOffset  ,
-            lldb::Encoding::eEncodingUint,
-            lldb::Format::eFormatDefault,
-            { regNumGcc    ,
-              regNumDwarf  ,
-              regNumGeneric,
-              regNumGdb    ,
-              regNumNative },
-            nullptr,
-            nullptr
-        };
-
-        ConstString regName    = ConstString(gdbReg.m_name);
-        ConstString regAltName = ConstString();
-        ConstString regGroup   = ConstString(group);
-        regInfo.AddRegister(info, regName, regAltName, regGroup);
-
-        // advance register info
-        byteOffset += byteSize;
-        regNum     += 1;
-    }
-
-    regInfo.Finalize ();
+        
+        dyn_reg_info.AddRegister(reg_info, reg_name, alt_name, set_name);
+        
+        return true; // Keep iterating through all "reg" elements
+    });
+    return true;
 }
-
+    
 } // namespace {}
 
-void XMLCDECL
-libxml2NullErrorFunc (void *ctx, const char *msg, ...)
-{
-    // do nothing currently
-}
 
 // query the target of gdb-remote for extended target information
 // return:  'true'  on success
@@ -4016,13 +3800,13 @@ libxml2NullErrorFunc (void *ctx, const c
 bool
 ProcessGDBRemote::GetGDBServerRegisterInfo ()
 {
+    // Make sure LLDB has an XML parser it can use first
+    if (!XMLDocument::XMLEnabled())
+        return false;
 
     // redirect libxml2's error handler since the default prints to stdout
-    xmlGenericErrorFunc func = libxml2NullErrorFunc;
-    initGenericErrorDefaultFunc( &func );
 
     GDBRemoteCommunicationClient & comm = m_gdb_comm;
-    GDBRemoteDynamicRegisterInfo & regInfo = m_register_info;
 
     // check that we have extended feature read support
     if ( !comm.GetQXferFeaturesReadSupported( ) )
@@ -4038,66 +3822,102 @@ ProcessGDBRemote::GetGDBServerRegisterIn
     {
         return false;
     }
+    
 
-    // parse the xml file in memory
-    xmlDocPtr doc = xmlReadMemory(raw.c_str(), raw.size(), "noname.xml", nullptr, 0);
-    if (doc == nullptr)
-        return false;
-
-    // extract target info from target.xml
-    GdbServerTargetInfo gdbInfo;
-    if (parseTargetInfo(doc, gdbInfo))
-    {
-        // NOTE: We could deduce triple from gdbInfo if lldb doesn't already have one set
-    }
+    XMLDocument xml_document;
 
-    // collect registers from all of the includes
-    GDBServerRegisterVec regList;
-    stringVec includes;
-    if (parseTargetIncludes(doc, includes) > 0)
+    if (xml_document.ParseMemory(raw.c_str(), raw.size(), "target.xml"))
     {
-
-        for (uint32_t i = 0; i < includes.size(); ++i)
+        GdbServerTargetInfo target_info;
+        
+        XMLNode target_node = xml_document.GetRootElement("target");
+        if (target_node)
         {
+            XMLNode feature_node;
+            target_node.ForEachChildElement([&target_info, this, &feature_node](const XMLNode &node) -> bool
+            {
+                llvm::StringRef name = node.GetName();
+                if (name == "architecture")
+                {
+                    node.GetElementText(target_info.arch);
+                }
+                else if (name == "osabi")
+                {
+                    node.GetElementText(target_info.osabi);
+                }
+                else if (name == "xi:include")
+                {
+                    llvm::StringRef href = node.GetAttributeValue("href");
+                    if (!href.empty())
+                        target_info.includes.push_back(href.str());
+                }
+                else if (name == "feature")
+                {
+                    feature_node = node;
+                }
+                else if (name == "groups")
+                {
+                    node.ForEachChildElementWithName("group", [&target_info](const XMLNode &node) -> bool {
+                        uint32_t set_id = UINT32_MAX;
+                        RegisterSetInfo set_info;
+                        
+                        node.ForEachAttribute([&set_id, &set_info](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
+                            if (name == "id")
+                                set_id = StringConvert::ToUInt32(value.data(), UINT32_MAX, 0);
+                            if (name == "name")
+                                set_info.name = ConstString(value);
+                            return true; // Keep iterating through all attributes
+                        });
+                        
+                        if (set_id != UINT32_MAX)
+                            target_info.reg_set_map[set_id] = set_info;
+                        return true; // Keep iterating through all "group" elements
+                    });
+                }
+                return true; // Keep iterating through all children of the target_node
+            });
+            
+            if (feature_node)
+            {
+                ParseRegisters(feature_node, target_info, this->m_register_info);
+            }
+            
+            for (const auto &include : target_info.includes)
+            {
+                // request register file
+                std::string xml_data;
+                if (!comm.ReadExtFeature(ConstString("features"),
+                                         ConstString(include),
+                                         xml_data,
+                                         lldberr))
+                    continue;
 
-            // request register file
-            if (!comm.ReadExtFeature(ConstString("features"),
-                                     ConstString(includes[i]),
-                                     raw,
-                                     lldberr))
-                continue;
-
-            // parse register file
-            xmlDocPtr regXml = xmlReadMemory(raw.c_str(),
-                                             raw.size( ),
-                                             includes[i].c_str(),
-                                             nullptr,
-                                             0);
-            if (!regXml)
-                continue;
-
-            // pass registers to lldb
-            parseRegisters(regXml, regList);
+                XMLDocument include_xml_document;
+                include_xml_document.ParseMemory(xml_data.data(), xml_data.size(), include.c_str());
+                XMLNode include_feature_node = include_xml_document.GetRootElement("feature");
+                if (include_feature_node)
+                {
+                    ParseRegisters(include_feature_node, target_info, this->m_register_info);
+                }
+            }
+            this->m_register_info.Finalize(GetTarget().GetArchitecture());
         }
     }
 
-    // pass all of these registers to lldb
-    BuildRegisters(regList, regInfo);
-
-    return true;
+    return m_register_info.GetNumRegisters() > 0;
 }
 
 Error
 ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList & list)
 {
+    // Make sure LLDB has an XML parser it can use first
+    if (!XMLDocument::XMLEnabled())
+        return Error (0, ErrorType::eErrorTypeGeneric);
+
     Log *log = GetLogIfAnyCategoriesSet (LIBLLDB_LOG_PROCESS);
     if (log)
         log->Printf ("ProcessGDBRemote::%s", __FUNCTION__);
 
-    // redirect libxml2's error handler since the default prints to stdout
-    xmlGenericErrorFunc func = libxml2NullErrorFunc;
-    initGenericErrorDefaultFunc (&func);
-
     GDBRemoteCommunicationClient & comm = m_gdb_comm;
 
     // check that we have extended feature read support
@@ -4115,79 +3935,53 @@ ProcessGDBRemote::GetLoadedModuleList (G
     // parse the xml file in memory
     if (log)
         log->Printf ("parsing: %s", raw.c_str());
-    xmlDocPtr doc = xmlReadMemory (raw.c_str(), raw.size(), "noname.xml", nullptr, 0);
-    if (doc == nullptr)
+    XMLDocument doc;
+    
+    if (!doc.ParseMemory(raw.c_str(), raw.size(), "noname.xml"))
         return Error (0, ErrorType::eErrorTypeGeneric);
 
-    xmlNodePtr elm = xmlExFindElement (doc->children, {"library-list-svr4"});
-    if (!elm)
+    XMLNode root_element = doc.GetRootElement("library-list-svr4");
+    if (!root_element)
         return Error();
 
     // main link map structure
-    xmlAttr * attr = xmlExFindAttribute (elm, "main-lm");
-    if (attr)
+    llvm::StringRef main_lm = root_element.GetAttributeValue("main-lm");
+    if (!main_lm.empty())
     {
-        std::string val = xmlExGetTextContent (attr);
-        if (val.length() > 2)
-        {
-            uint32_t process_lm = std::stoul (val.c_str()+2, 0, 16);
-            list.m_link_map = process_lm;
-        }
+        list.m_link_map = StringConvert::ToUInt64(main_lm.data(), LLDB_INVALID_ADDRESS, 0);
     }
 
-    // parse individual library entries
-    for (xmlNode * child = elm->children; child; child=child->next)
-    {
-        if (!child->name)
-            continue;
-
-        if (strcmp ((const char*)child->name, "library") != 0)
-            continue;
+    root_element.ForEachChildElementWithName("library", [log, &list](const XMLNode &library) -> bool {
 
         GDBLoadedModuleInfoList::LoadedModuleInfo module;
 
-        for (xmlAttrPtr prop = child->properties; prop; prop=prop->next)
-        {
-            if (strcmp ((const char*)prop->name, "name") == 0)
-                module.set_name (xmlExGetTextContent (prop));
-
-            // the address of the link_map struct.
-            if (strcmp ((const char*)prop->name, "lm") == 0)
+        library.ForEachAttribute([log, &module](const llvm::StringRef &name, const llvm::StringRef &value) -> bool {
+            
+            if (name == "name")
+                module.set_name (value.str());
+            else if (name == "lm")
             {
-                std::string val = xmlExGetTextContent (prop);
-                if (val.length() > 2)
-                {
-                    uint32_t module_lm = std::stoul (val.c_str()+2, 0, 16);
-                    module.set_link_map (module_lm);
-                }
+                // the address of the link_map struct.
+                module.set_link_map(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
             }
-
-            // the displacement as read from the field 'l_addr' of the link_map struct.
-            if (strcmp ((const char*)prop->name, "l_addr") == 0)
+            else if (name == "l_addr")
             {
-                std::string val = xmlExGetTextContent (prop);
-                if (val.length() > 2)
-                {
-                    uint32_t module_base = std::stoul (val.c_str()+2, 0, 16);
-                    module.set_base (module_base);
-                }
+                // the displacement as read from the field 'l_addr' of the link_map struct.
+                module.set_base(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
+                
             }
-
-            // the memory address of the libraries PT_DYAMIC section.
-            if (strcmp ((const char*)prop->name, "l_ld") == 0)
+            else if (name == "l_ld")
             {
-                std::string val = xmlExGetTextContent (prop);
-                if (val.length() > 2)
-                {
-                    uint32_t module_dyn = std::stoul (val.c_str()+2, 0, 16);
-                    module.set_dynamic (module_dyn);
-                }
+                // the memory address of the libraries PT_DYAMIC section.
+                module.set_dynamic(StringConvert::ToUInt64(value.data(), LLDB_INVALID_ADDRESS, 0));
             }
-        }
+            
+            return true; // Keep iterating over all properties of "library"
+        });
 
         if (log)
         {
-            std::string name ("");
+            std::string name;
             lldb::addr_t lm=0, base=0, ld=0;
 
             module.get_name (name);
@@ -4199,7 +3993,8 @@ ProcessGDBRemote::GetLoadedModuleList (G
         }
 
         list.add (module);
-    }
+        return true; // Keep iterating over all "library" elements in the root node
+    });
 
     if (log)
         log->Printf ("found %" PRId32 " modules in total", (int) list.m_list.size());
@@ -4207,26 +4002,6 @@ ProcessGDBRemote::GetLoadedModuleList (G
     return Error();
 }
 
-#else // if defined( LIBXML2_DEFINED )
-
-Error
-ProcessGDBRemote::GetLoadedModuleList (GDBLoadedModuleInfoList &)
-{
-    // stub (libxml2 not present)
-    Error err;
-    err.SetError (0, ErrorType::eErrorTypeGeneric);
-    return err;
-}
-
-bool
-ProcessGDBRemote::GetGDBServerRegisterInfo ()
-{
-    // stub (libxml2 not present)
-    return false;
-}
-
-#endif // if defined( LIBXML2_DEFINED )
-
 lldb::ModuleSP
 ProcessGDBRemote::LoadModuleAtAddress (const FileSpec &file, lldb::addr_t base_addr)
 {

Modified: lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolVendor/MacOSX/SymbolVendorMacOSX.cpp Tue May 26 13:00:51 2015
@@ -9,11 +9,6 @@
 
 #include "SymbolVendorMacOSX.h"
 
-#if defined( LIBXML2_DEFINED )
-#include <libxml/parser.h>
-#include <libxml/tree.h>
-#endif // #if defined( LIBXML2_DEFINED )
-
 #include <string.h>
 
 #include "lldb/Core/Module.h"
@@ -24,6 +19,7 @@
 #include "lldb/Core/Timer.h"
 #include "lldb/Host/Host.h"
 #include "lldb/Host/Symbols.h"
+#include "lldb/Host/XML.h"
 #include "lldb/Symbol/ObjectFile.h"
 
 using namespace lldb;
@@ -177,111 +173,46 @@ SymbolVendorMacOSX::CreateInstance (cons
             dsym_objfile_sp = ObjectFile::FindPlugin(module_sp, &dsym_fspec, 0, dsym_fspec.GetByteSize(), dsym_file_data_sp, dsym_file_data_offset);
             if (UUIDsMatch(module_sp.get(), dsym_objfile_sp.get(), feedback_strm))
             {
-#if defined( LIBXML2_DEFINED )
-                char dsym_path[PATH_MAX];
-                if (module_sp->GetSourceMappingList().IsEmpty() && dsym_fspec.GetPath(dsym_path, sizeof(dsym_path)))
+                // We need a XML parser if we hope to parse a plist...
+                if (XMLDocument::XMLEnabled())
                 {
-                    lldb_private::UUID dsym_uuid;
-                    if (dsym_objfile_sp->GetUUID(&dsym_uuid))
+                    char dsym_path[PATH_MAX];
+                    if (module_sp->GetSourceMappingList().IsEmpty() && dsym_fspec.GetPath(dsym_path, sizeof(dsym_path)))
                     {
-                        std::string uuid_str = dsym_uuid.GetAsString ();
-                        if (!uuid_str.empty())
+                        lldb_private::UUID dsym_uuid;
+                        if (dsym_objfile_sp->GetUUID(&dsym_uuid))
                         {
-                            char *resources = strstr (dsym_path, "/Contents/Resources/");
-                            if (resources)
+                            std::string uuid_str = dsym_uuid.GetAsString ();
+                            if (!uuid_str.empty())
                             {
-                                char dsym_uuid_plist_path[PATH_MAX];
-                                resources[strlen("/Contents/Resources/")] = '\0';
-                                snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path), "%s%s.plist", dsym_path, uuid_str.c_str());
-                                FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path, false);
-                                if (dsym_uuid_plist_spec.Exists())
+                                char *resources = strstr (dsym_path, "/Contents/Resources/");
+                                if (resources)
                                 {
-                                    xmlDoc *doc = ::xmlReadFile (dsym_uuid_plist_path, NULL, 0);
-                                    if (doc)
+                                    char dsym_uuid_plist_path[PATH_MAX];
+                                    resources[strlen("/Contents/Resources/")] = '\0';
+                                    snprintf(dsym_uuid_plist_path, sizeof(dsym_uuid_plist_path), "%s%s.plist", dsym_path, uuid_str.c_str());
+                                    FileSpec dsym_uuid_plist_spec(dsym_uuid_plist_path, false);
+                                    if (dsym_uuid_plist_spec.Exists())
                                     {
-                                        char DBGBuildSourcePath[PATH_MAX];
-                                        char DBGSourcePath[PATH_MAX];
-                                        DBGBuildSourcePath[0] = '\0';
-                                        DBGSourcePath[0] = '\0';
-                                        for (xmlNode *node = doc->children; node; node = node ? node->next : NULL)
+                                        ApplePropertyList plist(dsym_uuid_plist_path);
+                                        if (plist)
                                         {
-                                            if (node->type == XML_ELEMENT_NODE)
+                                            std::string DBGBuildSourcePath;
+                                            std::string DBGSourcePath;
+                                            
+                                            plist.GetValueAsString("DBGBuildSourcePath", DBGBuildSourcePath);
+                                            plist.GetValueAsString("DBGSourcePath", DBGSourcePath);
+                                            if (DBGBuildSourcePath[0] && DBGSourcePath[0])
                                             {
-                                                if (node->name && strcmp((const char*)node->name, "plist") == 0)
-                                                {
-                                                    xmlNode *dict_node = node->children;
-                                                    while (dict_node && dict_node->type != XML_ELEMENT_NODE)
-                                                        dict_node = dict_node->next;
-                                                    if (dict_node && dict_node->name && strcmp((const char *)dict_node->name, "dict") == 0)
-                                                    {
-                                                        for (xmlNode *key_node = dict_node->children; key_node; key_node = key_node->next)
-                                                        {
-                                                            if (key_node && key_node->type == XML_ELEMENT_NODE && key_node->name)
-                                                            {
-                                                                if (strcmp((const char *)key_node->name, "key") == 0)
-                                                                {
-                                                                    const char *key_name = (const char *)::xmlNodeGetContent(key_node);
-                                                                    if (strcmp(key_name, "DBGBuildSourcePath") == 0)
-                                                                    {
-                                                                        xmlNode *value_node = key_node->next;
-                                                                        while (value_node && value_node->type != XML_ELEMENT_NODE)
-                                                                            value_node = value_node->next;
-                                                                        if (value_node && value_node->name)
-                                                                        {
-                                                                            if (strcmp((const char *)value_node->name, "string") == 0)
-                                                                            {
-                                                                                const char *node_content = (const char *)::xmlNodeGetContent(value_node);
-                                                                                if (node_content)
-                                                                                {
-                                                                                    ::snprintf(DBGBuildSourcePath, sizeof(DBGBuildSourcePath), "%s", node_content);
-                                                                                    xmlFree((void *) node_content);
-                                                                                }
-                                                                            }
-                                                                            key_node = value_node;
-                                                                        }
-                                                                    }
-                                                                    else if (strcmp(key_name, "DBGSourcePath") == 0)
-                                                                    {
-                                                                        xmlNode *value_node = key_node->next;
-                                                                        while (value_node && value_node->type != XML_ELEMENT_NODE)
-                                                                            value_node = value_node->next;
-                                                                        if (value_node && value_node->name)
-                                                                        {
-                                                                            if (strcmp((const char *)value_node->name, "string") == 0)
-                                                                            {
-                                                                                const char *node_content = (const char *)::xmlNodeGetContent(value_node);
-                                                                                if (node_content)
-                                                                                {
-                                                                                    FileSpec resolved_source_path(node_content, true);
-                                                                                    resolved_source_path.GetPath(DBGSourcePath, sizeof(DBGSourcePath));
-                                                                                    xmlFree ((void *) node_content);
-                                                                                }
-                                                                            }
-                                                                            key_node = value_node;
-                                                                        }
-                                                                    }
-                                                                    if (key_name != NULL)
-                                                                        xmlFree((void *) key_name);
-                                                                }
-                                                            }
-                                                        }
-                                                    }
-                                                }
+                                                module_sp->GetSourceMappingList().Append (ConstString(DBGBuildSourcePath), ConstString(DBGSourcePath), true);
                                             }
                                         }
-                                        ::xmlFreeDoc (doc);
-                                            
-                                        if (DBGBuildSourcePath[0] && DBGSourcePath[0])
-                                        {
-                                            module_sp->GetSourceMappingList().Append (ConstString(DBGBuildSourcePath), ConstString(DBGSourcePath), true);
-                                        }
                                     }
                                 }
                             }
                         }
                     }
                 }
-#endif // #if defined( LIBXML2_DEFINED )
 
                 symbol_vendor->AddSymbolFileRepresentation(dsym_objfile_sp);
                 return symbol_vendor;

Modified: lldb/trunk/tools/debugserver/source/DNB.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.cpp?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNB.cpp Tue May 26 13:00:51 2015
@@ -1482,6 +1482,12 @@ DNBProcessGetSharedLibraryInfo (nub_proc
     return 0;
 }
 
+uint32_t
+DNBGetRegisterCPUType()
+{
+    return DNBArchProtocol::GetRegisterCPUType ();
+
+}
 //----------------------------------------------------------------------
 // Get the register set information for a specific thread.
 //----------------------------------------------------------------------

Modified: lldb/trunk/tools/debugserver/source/DNB.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNB.h?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNB.h (original)
+++ lldb/trunk/tools/debugserver/source/DNB.h Tue May 26 13:00:51 2015
@@ -151,6 +151,7 @@ nub_bool_t      DNBWatchpointSet
 nub_bool_t      DNBWatchpointClear              (nub_process_t pid, nub_addr_t addr);
 uint32_t        DNBWatchpointGetNumSupportedHWP (nub_process_t pid); 
 
+uint32_t        DNBGetRegisterCPUType           ();
 const DNBRegisterSetInfo *
                 DNBGetRegisterSetInfo           (nub_size_t *num_reg_sets);
 nub_bool_t      DNBGetRegisterInfoByName        (const char *reg_name, DNBRegisterInfo* info);

Modified: lldb/trunk/tools/debugserver/source/DNBArch.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBArch.cpp?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBArch.cpp (original)
+++ lldb/trunk/tools/debugserver/source/DNBArch.cpp Tue May 26 13:00:51 2015
@@ -57,6 +57,15 @@ DNBArchProtocol::RegisterArchPlugin (con
         g_arch_plugins[arch_info.cpu_type] = arch_info;
 }
 
+uint32_t
+DNBArchProtocol::GetRegisterCPUType ()
+{
+    const DNBArchPluginInfo *arch_info = GetArchInfo ();
+    if (arch_info)
+        return arch_info->cpu_type;
+    return 0;
+}
+
 const DNBRegisterSetInfo *
 DNBArchProtocol::GetRegisterSetInfo (nub_size_t *num_reg_sets)
 {

Modified: lldb/trunk/tools/debugserver/source/DNBArch.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/DNBArch.h?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/DNBArch.h (original)
+++ lldb/trunk/tools/debugserver/source/DNBArch.h Tue May 26 13:00:51 2015
@@ -43,6 +43,9 @@ public:
     static DNBArchProtocol *
     Create (MachThread *thread);
 
+    static uint32_t
+    GetRegisterCPUType ();
+
     static const DNBRegisterSetInfo * 
     GetRegisterSetInfo (nub_size_t *num_reg_sets);
 

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.cpp?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.cpp (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.cpp Tue May 26 13:00:51 2015
@@ -210,6 +210,7 @@ RNBRemote::CreatePacketTable  ()
     t.push_back (Packet (set_process_event,             &RNBRemote::HandlePacket_QSetProcessEvent, NULL, "QSetProcessEvent:", "Set a process event, to be passed to the process, can be set before the process is started, or after."));
     t.push_back (Packet (set_detach_on_error,           &RNBRemote::HandlePacket_QSetDetachOnError, NULL, "QSetDetachOnError:", "Set whether debugserver will detach (1) or kill (0) from the process it is controlling if it loses connection to lldb."));
     t.push_back (Packet (speed_test,                    &RNBRemote::HandlePacket_qSpeedTest, NULL, "qSpeedTest:", "Test the maximum speed at which packet can be sent/received."));
+    t.push_back (Packet (query_transfer,                &RNBRemote::HandlePacket_qXfer, NULL, "qXfer:", "Support the qXfer packet."));
 }
 
 
@@ -3085,7 +3086,7 @@ RNBRemote::HandlePacket_qSupported (cons
 {
     uint32_t max_packet_size = 128 * 1024;  // 128KBytes is a reasonable max packet size--debugger can always use less
     char buf[64];
-    snprintf (buf, sizeof(buf), "PacketSize=%x", max_packet_size);
+    snprintf (buf, sizeof(buf), "qXfer:features:read+;PacketSize=%x", max_packet_size);
     return SendPacket (buf);
 }
 
@@ -3979,38 +3980,94 @@ RNBRemote::HandlePacket_S (const char *p
     return rnb_success;
 }
 
-rnb_err_t
-RNBRemote::HandlePacket_qHostInfo (const char *p)
+static const char *
+GetArchName (const uint32_t cputype, const uint32_t cpusubtype)
 {
-    std::ostringstream strm;
+    switch (cputype)
+    {
+    case CPU_TYPE_ARM:
+        switch (cpusubtype)
+        {
+        case 5:     return "armv4";
+        case 6:     return "armv6";
+        case 7:     return "armv5t";
+        case 8:     return "xscale";
+        case 9:     return "armv7";
+        case 10:    return "armv7f";
+        case 11:    return "armv7s";
+        case 12:    return "armv7k";
+        case 14:    return "armv6m";
+        case 15:    return "armv7m";
+        case 16:    return "armv7em";
+        default:    return "arm";
+        }
+        break;
+    case CPU_TYPE_ARM64:    return "arm64";
+    case CPU_TYPE_I386:     return "i386";
+    case CPU_TYPE_X86_64:
+        switch (cpusubtype)
+        {
+        default:    return "x86_64";
+        case 8:     return "x86_64h";
+        }
+        break;
+    }
+    return NULL;
+}
 
-    uint32_t cputype, is_64_bit_capable;
-    size_t len = sizeof(cputype);
-    bool promoted_to_64 = false;
-    if  (::sysctlbyname("hw.cputype", &cputype, &len, NULL, 0) == 0)
+static bool
+GetHostCPUType (uint32_t &cputype, uint32_t &cpusubtype, uint32_t &is_64_bit_capable, bool &promoted_to_64)
+{
+    static uint32_t g_host_cputype = 0;
+    static uint32_t g_host_cpusubtype = 0;
+    static uint32_t g_is_64_bit_capable = 0;
+    static bool g_promoted_to_64 = false;
+    
+    if (g_host_cputype == 0)
     {
-        len = sizeof (is_64_bit_capable);
-        if  (::sysctlbyname("hw.cpu64bit_capable", &is_64_bit_capable, &len, NULL, 0) == 0)
+        g_promoted_to_64 = false;
+        size_t len = sizeof(uint32_t);
+        if  (::sysctlbyname("hw.cputype", &g_host_cputype, &len, NULL, 0) == 0)
         {
-            if (is_64_bit_capable && ((cputype & CPU_ARCH_ABI64) == 0))
+            len = sizeof (uint32_t);
+            if  (::sysctlbyname("hw.cpu64bit_capable", &g_is_64_bit_capable, &len, NULL, 0) == 0)
             {
-                promoted_to_64 = true;
-                cputype |= CPU_ARCH_ABI64;
+                if (g_is_64_bit_capable && ((g_host_cputype & CPU_ARCH_ABI64) == 0))
+                {
+                    g_promoted_to_64 = true;
+                    g_host_cputype |= CPU_ARCH_ABI64;
+                }
             }
         }
         
-        strm << "cputype:" << std::dec << cputype << ';';
+        len = sizeof(uint32_t);
+        if (::sysctlbyname("hw.cpusubtype", &g_host_cpusubtype, &len, NULL, 0) == 0)
+        {
+            if (g_promoted_to_64 &&
+                g_host_cputype == CPU_TYPE_X86_64 && g_host_cpusubtype == CPU_SUBTYPE_486)
+                g_host_cpusubtype = CPU_SUBTYPE_X86_64_ALL;
+        }
     }
+    
+    cputype = g_host_cputype;
+    cpusubtype = g_host_cpusubtype;
+    is_64_bit_capable = g_is_64_bit_capable;
+    promoted_to_64 = g_promoted_to_64;
+    return g_host_cputype != 0;
+}
 
-    uint32_t cpusubtype;
-    len = sizeof(cpusubtype);
-    if (::sysctlbyname("hw.cpusubtype", &cpusubtype, &len, NULL, 0) == 0)
-    {
-        if (promoted_to_64 && 
-            cputype == CPU_TYPE_X86_64 && 
-            cpusubtype == CPU_SUBTYPE_486)
-            cpusubtype = CPU_SUBTYPE_X86_64_ALL;
+rnb_err_t
+RNBRemote::HandlePacket_qHostInfo (const char *p)
+{
+    std::ostringstream strm;
 
+    uint32_t cputype = 0;
+    uint32_t cpusubtype = 0;
+    uint32_t is_64_bit_capable = 0;
+    bool promoted_to_64 = false;
+    if (GetHostCPUType (cputype, cpusubtype, is_64_bit_capable, promoted_to_64))
+    {
+        strm << "cputype:" << std::dec << cputype << ';';
         strm << "cpusubtype:" << std::dec << cpusubtype << ';';
     }
 
@@ -4054,6 +4111,340 @@ RNBRemote::HandlePacket_qHostInfo (const
     return SendPacket (strm.str());
 }
 
+void
+XMLElementStart (std::ostringstream &s, uint32_t indent, const char *name, bool has_attributes)
+{
+    if (indent)
+        s << INDENT_WITH_SPACES(indent);
+    s << '<' << name;
+    if (!has_attributes)
+        s << '>' << std::endl;
+}
+
+void
+XMLElementStartEndAttributes (std::ostringstream &s, bool empty)
+{
+    if (empty)
+        s << '/';
+    s << '>' << std::endl;
+}
+
+void
+XMLElementEnd (std::ostringstream &s, uint32_t indent, const char *name)
+{
+    if (indent)
+        s << INDENT_WITH_SPACES(indent);
+    s << '<' << '/' << name << '>' << std::endl;
+}
+
+void
+XMLElementWithStringValue (std::ostringstream &s, uint32_t indent, const char *name, const char *value, bool close = true)
+{
+    if (value)
+    {
+        if (indent)
+            s << INDENT_WITH_SPACES(indent);
+        s << '<' << name << '>' << value;
+        if (close)
+            XMLElementEnd(s, 0, name);
+    }
+}
+
+void
+XMLElementWithUnsignedValue (std::ostringstream &s, uint32_t indent, const char *name, uint64_t value, bool close = true)
+{
+    if (indent)
+        s << INDENT_WITH_SPACES(indent);
+
+    s << '<' << name << '>' << DECIMAL << value;
+    if (close)
+        XMLElementEnd(s, 0, name);
+}
+
+void
+XMLAttributeString (std::ostringstream &s, const char *name, const char *value, const char *default_value = NULL)
+{
+    if (value)
+    {
+        if (default_value && strcmp(value, default_value) == 0)
+            return; // No need to emit the attribute because it matches the default value
+        s <<' ' << name << "=\"" << value << "\"";
+    }
+}
+
+void
+XMLAttributeUnsignedDecimal (std::ostringstream &s, const char *name, uint64_t value)
+{
+    s <<' ' << name << "=\"" << DECIMAL << value << "\"";
+}
+
+void
+GenerateTargetXMLRegister (std::ostringstream &s,
+                           const uint32_t reg_num,
+                           nub_size_t num_reg_sets,
+                           const DNBRegisterSetInfo *reg_set_info,
+                           const register_map_entry_t &reg)
+{
+    const char *default_lldb_encoding = "uint";
+    const char *lldb_encoding = default_lldb_encoding;
+    const char *gdb_group = "general";
+    const char *default_gdb_type = "int";
+    const char *gdb_type = default_gdb_type;
+    const char *default_lldb_format = "hex";
+    const char *lldb_format = default_lldb_format;
+    const char *lldb_set = NULL;
+
+    switch (reg.nub_info.type)
+    {
+        case Uint:      lldb_encoding = "uint"; break;
+        case Sint:      lldb_encoding = "sint"; break;
+        case IEEE754:   lldb_encoding = "ieee754";  if (reg.nub_info.set > 0) gdb_group = "float"; break;
+        case Vector:    lldb_encoding = "vector"; if (reg.nub_info.set > 0) gdb_group = "vector"; break;
+    }
+
+    switch (reg.nub_info.format)
+    {
+        case Binary:            lldb_format = "binary"; break;
+        case Decimal:           lldb_format = "decimal"; break;
+        case Hex:               lldb_format = "hex"; break;
+        case Float:             gdb_type = "float"; lldb_format = "float"; break;
+        case VectorOfSInt8:     gdb_type = "float"; lldb_format = "vector-sint8"; break;
+        case VectorOfUInt8:     gdb_type = "float"; lldb_format = "vector-uint8"; break;
+        case VectorOfSInt16:    gdb_type = "float"; lldb_format = "vector-sint16"; break;
+        case VectorOfUInt16:    gdb_type = "float"; lldb_format = "vector-uint16"; break;
+        case VectorOfSInt32:    gdb_type = "float"; lldb_format = "vector-sint32"; break;
+        case VectorOfUInt32:    gdb_type = "float"; lldb_format = "vector-uint32"; break;
+        case VectorOfFloat32:   gdb_type = "float"; lldb_format = "vector-float32"; break;
+        case VectorOfUInt128:   gdb_type = "float"; lldb_format = "vector-uint128"; break;
+    };
+    if (reg_set_info && reg.nub_info.set < num_reg_sets)
+        lldb_set = reg_set_info[reg.nub_info.set].name;
+
+    uint32_t indent = 2;
+
+    XMLElementStart(s, indent, "reg", true);
+    XMLAttributeString(s, "name", reg.nub_info.name);
+    XMLAttributeUnsignedDecimal(s, "regnum", reg_num);
+    XMLAttributeUnsignedDecimal(s, "offset", reg.offset);
+    XMLAttributeUnsignedDecimal(s, "bitsize", reg.nub_info.size * 8);
+    XMLAttributeString(s, "group", gdb_group);
+    XMLAttributeString(s, "type", gdb_type, default_gdb_type);
+    XMLAttributeString (s, "altname", reg.nub_info.alt);
+    XMLAttributeString(s, "encoding", lldb_encoding, default_lldb_encoding);
+    XMLAttributeString(s, "format", lldb_format, default_lldb_format);
+    XMLAttributeUnsignedDecimal(s, "group_id", reg.nub_info.set);
+    if (reg.nub_info.reg_gcc != INVALID_NUB_REGNUM)
+        XMLAttributeUnsignedDecimal(s, "gcc_regnum", reg.nub_info.reg_gcc);
+    if (reg.nub_info.reg_dwarf != INVALID_NUB_REGNUM)
+        XMLAttributeUnsignedDecimal(s, "dwarf_regnum", reg.nub_info.reg_dwarf);
+
+    const char *lldb_generic = NULL;
+    switch (reg.nub_info.reg_generic)
+    {
+        case GENERIC_REGNUM_FP:     lldb_generic = "fp"; break;
+        case GENERIC_REGNUM_PC:     lldb_generic = "pc"; break;
+        case GENERIC_REGNUM_SP:     lldb_generic = "sp"; break;
+        case GENERIC_REGNUM_RA:     lldb_generic = "ra"; break;
+        case GENERIC_REGNUM_FLAGS:  lldb_generic = "flags"; break;
+        case GENERIC_REGNUM_ARG1:   lldb_generic = "arg1"; break;
+        case GENERIC_REGNUM_ARG2:   lldb_generic = "arg2"; break;
+        case GENERIC_REGNUM_ARG3:   lldb_generic = "arg3"; break;
+        case GENERIC_REGNUM_ARG4:   lldb_generic = "arg4"; break;
+        case GENERIC_REGNUM_ARG5:   lldb_generic = "arg5"; break;
+        case GENERIC_REGNUM_ARG6:   lldb_generic = "arg6"; break;
+        case GENERIC_REGNUM_ARG7:   lldb_generic = "arg7"; break;
+        case GENERIC_REGNUM_ARG8:   lldb_generic = "arg8"; break;
+        default: break;
+    }
+    XMLAttributeString(s, "generic", lldb_generic);
+
+
+    bool empty = reg.value_regnums.empty() && reg.invalidate_regnums.empty();
+    if (!empty)
+    {
+        if (!reg.value_regnums.empty())
+        {
+            std::ostringstream regnums;
+            bool first = true;
+            regnums << DECIMAL;
+            for (auto regnum : reg.value_regnums)
+            {
+                if (!first)
+                    regnums << ',';
+                regnums << regnum;
+                first = false;
+            }
+            XMLAttributeString(s, "value_regnums", regnums.str().c_str());
+        }
+
+        if (!reg.invalidate_regnums.empty())
+        {
+            std::ostringstream regnums;
+            bool first = true;
+            regnums << DECIMAL;
+            for (auto regnum : reg.invalidate_regnums)
+            {
+                if (!first)
+                    regnums << ',';
+                regnums << regnum;
+                first = false;
+            }
+            XMLAttributeString(s, "invalidate_regnums", regnums.str().c_str());
+        }
+    }
+    XMLElementStartEndAttributes(s, true);
+}
+
+void
+GenerateTargetXMLRegisters (std::ostringstream &s)
+{
+    nub_size_t num_reg_sets = 0;
+    const DNBRegisterSetInfo *reg_sets = DNBGetRegisterSetInfo (&num_reg_sets);
+
+
+    uint32_t cputype = DNBGetRegisterCPUType();
+    if (cputype)
+    {
+        XMLElementStart(s, 0, "feature", true);
+        std::ostringstream name_strm;
+        name_strm << "com.apple.debugserver." << GetArchName (cputype, 0);
+        XMLAttributeString(s, "name", name_strm.str().c_str());
+        XMLElementStartEndAttributes(s, false);
+        for (uint32_t reg_num = 0; reg_num < g_num_reg_entries; ++reg_num)
+//        for (const auto &reg: g_dynamic_register_map)
+        {
+            GenerateTargetXMLRegister(s, reg_num, num_reg_sets, reg_sets, g_reg_entries[reg_num]);
+        }
+        XMLElementEnd(s, 0, "feature");
+
+        if (num_reg_sets > 0)
+        {
+            XMLElementStart(s, 0, "groups", false);
+            for (uint32_t set=1; set<num_reg_sets; ++set)
+            {
+                XMLElementStart(s, 2, "group", true);
+                XMLAttributeUnsignedDecimal(s, "id", set);
+                XMLAttributeString(s, "name", reg_sets[set].name);
+                XMLElementStartEndAttributes(s, true);
+            }
+            XMLElementEnd(s, 0, "groups");
+        }
+    }
+}
+
+static const char *g_target_xml_header = R"(<?xml version="1.0"?>
+<target version="1.0">)";
+
+static const char *g_target_xml_footer = "</target>";
+
+static std::string g_target_xml;
+
+void
+UpdateTargetXML ()
+{
+    std::ostringstream s;
+    s << g_target_xml_header << std::endl;
+    
+    // Set the architecture
+    //s << "<architecture>" << arch "</architecture>" << std::endl;
+    
+    // Set the OSABI
+    //s << "<osabi>abi-name</osabi>"
+
+    GenerateTargetXMLRegisters(s);
+    
+    s << g_target_xml_footer << std::endl;
+
+    // Save the XML output in case it gets retrieved in chunks
+    g_target_xml = s.str();
+}
+
+rnb_err_t
+RNBRemote::HandlePacket_qXfer (const char *command)
+{
+    const char *p = command;
+    p += strlen ("qXfer:");
+    const char *sep = strchr(p, ':');
+    if (sep)
+    {
+        std::string object(p, sep - p);     // "auxv", "backtrace", "features", etc
+        p = sep + 1;
+        sep = strchr(p, ':');
+        if (sep)
+        {
+            std::string rw(p, sep - p);    // "read" or "write"
+            p = sep + 1;
+            sep = strchr(p, ':');
+            if (sep)
+            {
+                std::string annex(p, sep - p);    // "read" or "write"
+
+                p = sep + 1;
+                sep = strchr(p, ',');
+                if (sep)
+                {
+                    std::string offset_str(p, sep - p); // read the length as a string
+                    p = sep + 1;
+                    std::string length_str(p); // read the offset as a string
+                    char *end = nullptr;
+                    const uint64_t offset = strtoul(offset_str.c_str(), &end, 16); // convert offset_str to a offset
+                    if (*end == '\0')
+                    {
+                        const uint64_t length = strtoul(length_str.c_str(), &end, 16); // convert length_str to a length
+                        if (*end == '\0')
+                        {
+                            if (object == "features"  &&
+                                rw     == "read"      &&
+                                annex  == "target.xml")
+                            {
+                                std::ostringstream xml_out;
+
+                                if (offset == 0)
+                                {
+                                    InitializeRegisters (true);
+
+                                    UpdateTargetXML();
+                                    if (g_target_xml.empty())
+                                        return SendPacket("E83");
+
+                                    if (length > g_target_xml.size())
+                                    {
+                                        xml_out << 'l'; // No more data
+                                        xml_out << binary_encode_string(g_target_xml);
+                                    }
+                                    else
+                                    {
+                                        xml_out << 'm'; // More data needs to be read with a subsequent call
+                                        xml_out << binary_encode_string(std::string(g_target_xml, offset, length));
+                                    }
+                                }
+                                else
+                                {
+                                    // Retrieving target XML in chunks
+                                    if (offset < g_target_xml.size())
+                                    {
+                                        std::string chunk(g_target_xml, offset, length);
+                                        if (chunk.size() < length)
+                                            xml_out << 'l'; // No more data
+                                        else
+                                            xml_out << 'm'; // More data needs to be read with a subsequent call
+                                        xml_out << binary_encode_string(chunk.data());
+                                    }
+                                }
+                                return SendPacket(xml_out.str());
+                            }
+                            // Well formed, put not supported
+                            return HandlePacket_UNIMPLEMENTED (command);
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return SendPacket ("E82");
+}
+
+
 rnb_err_t
 RNBRemote::HandlePacket_qGDBServerVersion (const char *p)
 {

Modified: lldb/trunk/tools/debugserver/source/RNBRemote.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/debugserver/source/RNBRemote.h?rev=238224&r1=238223&r2=238224&view=diff
==============================================================================
--- lldb/trunk/tools/debugserver/source/RNBRemote.h (original)
+++ lldb/trunk/tools/debugserver/source/RNBRemote.h Tue May 26 13:00:51 2015
@@ -127,6 +127,7 @@ public:
         restore_register_state,         // '_G'
         speed_test,                     // 'qSpeedTest:'
         set_detach_on_error,            // 'QSetDetachOnError:'
+        query_transfer,                 // 'qXfer:'
         unknown_type
     } PacketEnum;
 
@@ -234,6 +235,7 @@ public:
     rnb_err_t HandlePacket_SetEnableAsyncProfiling(const char *p);
     rnb_err_t HandlePacket_WatchpointSupportInfo (const char *p);
     rnb_err_t HandlePacket_qSpeedTest (const char *p);
+    rnb_err_t HandlePacket_qXfer (const char *p);
     rnb_err_t HandlePacket_stop_process (const char *p);
     rnb_err_t HandlePacket_QSetDetachOnError (const char *p);
 





More information about the lldb-commits mailing list