diff --git a/CMakeLists.txt b/CMakeLists.txt
index d49d2a3..97a51a1 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -257,6 +257,11 @@ if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
   ${DEBUG_SYMBOLS_LIBRARY})
 endif()
 
+if (CMAKE_SYSTEM_NAME MATCHES "Linux")
+  set(LIBXML2_INCLUDE_DIR "/usr/include/libxml2")
+  list(APPEND system_libs xml2)
+endif()
+
 # On FreeBSD, link libexecinfo because libc is missing  backtrace()
 if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
   list(APPEND system_libs execinfo)
diff --git a/Makefile b/Makefile
index 19714cd..d476afd 100644
--- a/Makefile
+++ b/Makefile
@@ -50,6 +50,12 @@ CPP.Flags += -F$(SDKROOT)/System/Library/Frameworks
 CPP.Flags += -F$(SDKROOT)/System/Library/PrivateFrameworks
 CPP.Flags += -I$(SDKROOT)/usr/include/libxml2
 endif
+
+ifeq ($(HOST_OS),Linux)
+CPP.Flags += -I/usr/include/libxml2
+LIBS += $(LIBXML2_LIBS)
+endif
+
 ifdef LLDB_VENDOR
 CPP.Flags += -DLLDB_VENDOR='"$(LLDB_VENDOR) "'
 endif
diff --git a/source/Plugins/Process/gdb-remote/CMakeLists.txt b/source/Plugins/Process/gdb-remote/CMakeLists.txt
index 32f0d13..590abc3 100644
--- a/source/Plugins/Process/gdb-remote/CMakeLists.txt
+++ b/source/Plugins/Process/gdb-remote/CMakeLists.txt
@@ -1,5 +1,7 @@
 set(LLVM_NO_RTTI 1)
 
+include_directories(${LIBXML2_INCLUDE_DIR})
+
 add_lldb_library(lldbPluginProcessGDBRemote
   GDBRemoteCommunication.cpp
   GDBRemoteCommunicationClient.cpp
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
index 26055b0..072e31b 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -98,13 +98,15 @@ namespace {
     {
         { "packet-timeout" , OptionValue::eTypeUInt64 , true , 1, NULL, NULL, "Specify the default packet timeout in seconds." },
         { "adjust-breakpoint-pc" , OptionValue::eTypeUInt64 , true , 0, NULL, NULL, "How much to adjust PC after hitting a breakpoint." },
+        { "register-definition-file" , OptionValue::eTypeFileSpec , true, 0 , NULL, NULL, "The file that provides the description for remote target registers." },
         {  NULL            , OptionValue::eTypeInvalid, false, 0, NULL, NULL, NULL  }
     };
     
     enum
     {
         ePropertyPacketTimeout,
-        ePropertyAdjustPCAfterBreak
+        ePropertyAdjustPCAfterBreak,
+        ePropertyRegisterDefinitionFile
     };
     
     class PluginProperties : public Properties
@@ -142,6 +144,12 @@ namespace {
             const uint32_t idx = ePropertyAdjustPCAfterBreak;
             return m_collection_sp->GetPropertyAtIndexAsUInt64 (NULL, idx, g_properties[idx].default_uint_value);
         }
+        FileSpec
+        GetRegisterDescriptionFilePath () const
+        {
+            const uint32_t idx = ePropertyRegisterDefinitionFile;
+            return m_collection_sp->GetPropertyAtIndexAsFileSpec (NULL, idx);
+        }
     };
     
     typedef std::shared_ptr<PluginProperties> ProcessKDPPropertiesSP;
@@ -317,6 +325,226 @@ ProcessGDBRemote::GetPluginVersion()
     return 1;
 }
 
+#ifdef CLANG_HAVE_LIBXML
+bool
+ProcessGDBRemote::ParseRegisterNode(xmlNode *registers_node)
+{
+    uint32_t regInStart = m_register_info.GetNumRegisters();
+    for (xmlNode *reg_node = registers_node->children; reg_node != NULL; reg_node = reg_node->next)
+    {
+        if (reg_node->type == XML_ELEMENT_NODE)
+        {
+            if (reg_node->name && strcmp((const char*)reg_node->name, "register") == 0)
+            {
+                std::string name;
+                ConstString reg_name;
+                ConstString alt_name;
+                ConstString set_name;
+                std::vector<uint32_t> value_regs;
+                std::vector<uint32_t> invalidate_regs;
+                RegisterInfo reg_info = {
+                    NULL,                 // Name
+                    NULL,                 // Alt name
+                    0,                    // byte size
+                    0,                    // offset
+                    eEncodingUint,        // encoding
+                    eFormatHex,           // formate
+                    {
+                        LLDB_INVALID_REGNUM, // GCC reg num
+                        LLDB_INVALID_REGNUM, // DWARF reg num
+                        LLDB_INVALID_REGNUM, // generic reg num
+                        LLDB_INVALID_REGNUM, // GDB reg num
+                        LLDB_INVALID_REGNUM  // native register number
+                    },
+                    NULL,
+                    NULL
+                };
+
+                for (xmlNode *node = reg_node->children; node; node = node->next)
+                {
+                    if (node->type == XML_ELEMENT_NODE)
+                    {
+                        if (node->name != 0)
+                        {
+                            const char *value = (const char *)xmlNodeGetContent(node);
+                            if (strcmp((const char*)node->name, "name") == 0)
+                            {
+                                reg_name.SetCString(value);
+                            }
+                            else if (strcmp((const char*)node->name, "alt-name") == 0)
+                            {
+                                alt_name.SetCString(value);
+                            }
+                            else if (strcmp((const char*)node->name, "bitsize") == 0)
+                            {
+                                reg_info.byte_size = Args::StringToUInt32(value, 0, 0) / CHAR_BIT;
+                            }
+                            else if (strcmp((const char*)node->name, "offset") == 0)
+                            {
+                                reg_info.byte_offset = Args::StringToUInt32(value, UINT32_MAX, 0);
+                            }
+                            else if (strcmp((const char*)node->name, "encoding") == 0)
+                            {
+                                const Encoding encoding = Args::StringToEncoding (value);
+                                if (encoding != eEncodingInvalid)
+                                    reg_info.encoding = encoding;
+                            }
+                            else if (strcmp((const char*)node->name, "format") == 0)
+                            {
+                                Format format = eFormatInvalid;
+                                if (Args::StringToFormat (value, format, NULL).Success())
+                                    reg_info.format = format;
+                                else if (strcmp(value,"binary") == 0)
+                                    reg_info.format = eFormatBinary;
+                                else if (strcmp(value,"decimal") == 0)
+                                    reg_info.format = eFormatDecimal;
+                                else if (strcmp(value,"hex") == 0)
+                                    reg_info.format = eFormatHex;
+                                else if (strcmp(value,"float") == 0)
+                                    reg_info.format = eFormatFloat;
+                                else if (strcmp(value,"vector-sint8") == 0)
+                                    reg_info.format = eFormatVectorOfSInt8;
+                                else if (strcmp(value,"vector-uint8") == 0)
+                                    reg_info.format = eFormatVectorOfUInt8;
+                                else if (strcmp(value,"vector-sint16") == 0)
+                                    reg_info.format = eFormatVectorOfSInt16;
+                                else if (strcmp(value,"vector-uint16") == 0)
+                                    reg_info.format = eFormatVectorOfUInt16;
+                                else if (strcmp(value,"vector-sint32") == 0)
+                                    reg_info.format = eFormatVectorOfSInt32;
+                                else if (strcmp(value,"vector-uint32") == 0)
+                                    reg_info.format = eFormatVectorOfUInt32;
+                                else if (strcmp(value,"vector-float32") == 0)
+                                    reg_info.format = eFormatVectorOfFloat32;
+                                else if (strcmp(value,"vector-uint128") == 0)
+                                    reg_info.format = eFormatVectorOfUInt128;
+                            }
+                            else if (strcmp((const char*)node->name, "set") == 0)
+                            {
+                                set_name.SetCString(value);
+                            }
+                            else if (strcmp((const char*)node->name, "compiler_regnum") == 0)
+                            {
+                                reg_info.kinds[eRegisterKindGCC] = Args::StringToUInt32(value, LLDB_INVALID_REGNUM, 0);
+                            }
+                            else if (strcmp((const char*)node->name, "dwarf_regnum") == 0)
+                            {
+                                reg_info.kinds[eRegisterKindDWARF] = Args::StringToUInt32(value, LLDB_INVALID_REGNUM, 0);
+                            }
+                            else if (strcmp((const char*)node->name, "gdb_regnum") == 0)
+                            {
+                                reg_info.kinds[eRegisterKindGDB] = Args::StringToUInt32(value, LLDB_INVALID_REGNUM, 0);
+                            }
+                            else if (strcmp((const char*)node->name, "lldb_regnum") == 0)
+                            {
+                                reg_info.kinds[eRegisterKindLLDB] = Args::StringToUInt32(value, LLDB_INVALID_REGNUM, 0);
+                            }
+                            else if (strcmp((const char*)node->name, "generic") == 0)
+                            {
+                                reg_info.kinds[eRegisterKindGeneric] = Args::StringToGenericRegister (value);
+                            }
+                            else if (strcmp((const char*)node->name, "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 = Args::StringToUInt32 (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());
+                            }
+                            else if (strcmp((const char*)node->name, "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 = Args::StringToUInt32 (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());
+                            }
+                            xmlFree((void *) value);
+                        }
+
+                        if (!value_regs.empty())
+                        {
+                            value_regs.push_back(LLDB_INVALID_REGNUM);
+                            reg_info.value_regs = value_regs.data();
+                        }
+                        if (!invalidate_regs.empty())
+                        {
+                            invalidate_regs.push_back(LLDB_INVALID_REGNUM);
+                            reg_info.invalidate_regs = invalidate_regs.data();
+                        }
+                    }
+                }
+                // TODO: Check if XML has provided us the required information about the register.
+                m_register_info.AddRegister(reg_info, reg_name, alt_name, set_name);
+            }
+        }
+    }
+    uint32_t regAtFinish = m_register_info.GetNumRegisters();
+    return (regAtFinish > regInStart);
+}
+
+bool
+ProcessGDBRemote::ParseXMLRegisterInfo(const char* filename)
+{
+    bool bXmlFileHasRegisters = false;
+    xmlDoc *doc = ::xmlReadFile (filename, NULL, 0);
+    if (doc)
+    {
+        for (xmlNode *node = doc->children; node; node = node ? node->next : NULL)
+        {
+            if (node->type == XML_ELEMENT_NODE)
+            {
+                if (node->name && strcmp((const char*)node->name, "target_definition") == 0)
+                {
+                    xmlNode *node1;
+                    for (node1 = node->children; node1 != NULL; node1 = node1->next)
+                    {
+                        if (node1->type == XML_ELEMENT_NODE)
+                        {
+                            if (node1->name && strcmp((const char*)node1->name, "triple") == 0)
+                            {
+                                // TODO: Match it against the target triplet.
+                            }
+                            else if (node1->name && strcmp((const char*)node1->name, "g_packet_size") == 0)
+                            {
+                            }
+                            else if (node1->name && strcmp((const char*)node1->name, "registers") == 0)
+                            {
+                                bXmlFileHasRegisters = ParseRegisterNode (node1);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        ::xmlFreeDoc (doc);
+    }
+    return bXmlFileHasRegisters;
+}
+#else
+// Dummy implementation when libXML is not available
+bool
+ProcessGDBRemote::ParseXMLRegisterInfo(const char* filename)
+{
+    return false;
+}
+#endif //CLANG_HAVE_LIBXML
+
+
 void
 ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
 {
@@ -492,6 +720,23 @@ ProcessGDBRemote::BuildDynamicRegisterInfo (bool force)
         }
     }
 
+    if(reg_num == 0)
+    {
+        FileSpec fs = GetGlobalPluginProperties()->GetRegisterDescriptionFilePath ();
+
+        if (fs.Exists())
+        {
+            char path[PATH_MAX];
+            fs.GetPath (path, sizeof(path));
+            // If some registers are found in the xml then we can return.
+            if (ParseXMLRegisterInfo (path))
+            {
+                m_register_info.Finalize ();
+                return;
+            }
+        }
+    }
+
     // We didn't get anything if the accumulated reg_num is zero.  See if we are
     // debugging ARM and fill with a hard coded register set until we can get an
     // updated debugserver down on the devices.
diff --git a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
index c8bd42b..6a691f9 100644
--- a/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ b/source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -10,6 +10,7 @@
 #ifndef liblldb_ProcessGDBRemote_h_
 #define liblldb_ProcessGDBRemote_h_
 
+#include "llvm/Config/config.h"
 // C Includes
 
 // C++ Includes
@@ -32,6 +33,11 @@
 #include "Utility/StringExtractor.h"
 #include "GDBRemoteRegisterContext.h"
 
+#ifdef CLANG_HAVE_LIBXML
+#include <libxml/parser.h>
+#include <libxml/tree.h>
+#endif
+
 class ThreadGDBRemote;
 
 class ProcessGDBRemote : public lldb_private::Process
@@ -291,6 +297,11 @@ protected:
     void
     SetLastStopPacket (const StringExtractorGDBRemote &response);
 
+    bool ParseXMLRegisterInfo(const char* filename);
+#ifdef CLANG_HAVE_LIBXML
+    bool ParseRegisterNode(xmlNode *registers_node);
+#endif
+
     //------------------------------------------------------------------
     /// Broadcaster event bits definitions.
     //------------------------------------------------------------------
