[lldb-dev] [PATCH] support for obtaining auxv via gdbserver packet

Steve Pucci spucci at google.com
Mon Mar 3 15:44:50 PST 2014


Hi all,

This is a patch which allows ProcessGDBServer to obtain the auxv from a
remote gdbserver via GDBServerProcessRemote, returning the data as a
DataBufferSP.

The patch includes a small fix to
GDBRemoteCommunicationClient::SendPacketsAndConcatenateResponses() to
support binary file format packet returns (by not assuming each binary
packet is a null-terminated string when concatenating them).

I've also added a base-class Process::GetAuxvData which delegates to the
Host.

No code currently calls this method.

 - Steve

Index: include/lldb/Target/Process.h
===================================================================
--- include/lldb/Target/Process.h (revision 202766)
+++ include/lldb/Target/Process.h (working copy)
@@ -2063,6 +2063,9 @@
         return m_unix_signals;
     }

+    virtual const lldb::DataBufferSP
+    GetAuxvData();
+
     //==================================================================
     // Plug-in Process Control Overrides
     //==================================================================
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
(revision
202766)
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp (working
copy)
@@ -66,6 +66,7 @@
     m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
     m_supports_p (eLazyBoolCalculate),
     m_supports_QSaveRegisterState (eLazyBoolCalculate),
+    m_supports_qXfer_auxv_read (eLazyBoolCalculate),
     m_supports_qXfer_libraries_read (eLazyBoolCalculate),
     m_supports_qXfer_libraries_svr4_read (eLazyBoolCalculate),
     m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate),
@@ -187,6 +188,16 @@
     return (m_supports_qXfer_libraries_read == eLazyBoolYes);
 }

+bool
+GDBRemoteCommunicationClient::GetQXferAuxvReadSupported ()
+{
+    if (m_supports_qXfer_auxv_read == eLazyBoolCalculate)
+    {
+        GetRemoteQSupported();
+    }
+    return (m_supports_qXfer_auxv_read == eLazyBoolYes);
+}
+
 uint64_t
 GDBRemoteCommunicationClient::GetRemoteMaxPacketSize()
 {
@@ -294,6 +305,7 @@
     m_supports_memory_region_info = eLazyBoolCalculate;
     m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
     m_attach_or_wait_reply = eLazyBoolCalculate;
+    m_supports_qXfer_auxv_read = eLazyBoolCalculate;
     m_supports_qXfer_libraries_read = eLazyBoolCalculate;
     m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
     m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
@@ -320,8 +332,9 @@
 GDBRemoteCommunicationClient::GetRemoteQSupported ()
 {
     // Clear out any capabilities we expect to see in the qSupported
response
+    m_supports_qXfer_auxv_read = eLazyBoolNo;
+    m_supports_qXfer_libraries_read = eLazyBoolNo;
     m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
-    m_supports_qXfer_libraries_read = eLazyBoolNo;
     m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
     m_max_packet_size = UINT64_MAX;  // It's supposed to always be there,
but if not, we assume no limit

@@ -331,6 +344,8 @@
                                      /*send_async=*/false) ==
PacketResult::Success)
     {
         const char *response_cstr = response.GetStringRef().c_str();
+        if (::strstr (response_cstr, "qXfer:auxv:read+"))
+            m_supports_qXfer_auxv_read = eLazyBoolYes;
         if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
             m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
         if (::strstr (response_cstr, "augmented-libraries-svr4-read"))
@@ -502,11 +517,8 @@
         {
             return PacketResult::ErrorReplyInvalid;
         }
-        // Skip past m or l
-        const char *s = this_string.c_str() + 1;
-
-        // Concatenate the result so far
-        response_string += s;
+        // Concatenate the result so far (skipping 'm' or 'l')
+        response_string.append(this_string, 1, std::string::npos);
         if (first_char == 'l')
             // We're done
             return PacketResult::Success;
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (revision
202766)
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h (working
copy)
@@ -384,6 +384,9 @@
     SetCurrentThreadForRun (uint64_t tid);

     bool
+    GetQXferAuxvReadSupported ();
+
+    bool
     GetQXferLibrariesReadSupported ();

     bool
@@ -525,6 +528,7 @@
     lldb_private::LazyBool m_prepare_for_reg_writing_reply;
     lldb_private::LazyBool m_supports_p;
     lldb_private::LazyBool m_supports_QSaveRegisterState;
+    lldb_private::LazyBool m_supports_qXfer_auxv_read;
     lldb_private::LazyBool m_supports_qXfer_libraries_read;
     lldb_private::LazyBool m_supports_qXfer_libraries_svr4_read;
     lldb_private::LazyBool m_supports_augmented_libraries_svr4_read;
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (revision 202766)
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp (working copy)
@@ -281,7 +281,8 @@
     m_waiting_for_attach (false),
     m_destroy_tried_resuming (false),
     m_command_sp (),
-    m_breakpoint_pc_offset (0)
+    m_breakpoint_pc_offset (0),
+    m_breakpoint_trap_opcode_size (0)
 {
     m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit,
  "async thread should exit");
     m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue,
  "async thread continue");
@@ -3060,7 +3061,22 @@
     return m_dyld_ap.get();
 }

+const DataBufferSP
+ProcessGDBRemote::GetAuxvData()
+{
+    DataBufferSP buf;
+    if (m_gdb_comm.GetQXferAuxvReadSupported())
+    {
+        std::string response_string;
+        if
(m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::",
response_string) == GDBRemoteCommunication::PacketResult::Success)
+            buf.reset(new DataBufferHeap(response_string.c_str(),
response_string.length()));
+    }
+    if (buf.get() != NULL)
+        return buf;
+    return Process::GetAuxvData();
+}

+
 class CommandObjectProcessGDBRemotePacketHistory : public
CommandObjectParsed
 {
 private:
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (revision 202766)
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.h (working copy)
@@ -299,6 +299,9 @@
     bool
     ParseRegisters(lldb_private::ScriptInterpreterObject *registers_array);

+    virtual const lldb::DataBufferSP
+    GetAuxvData();
+
     //------------------------------------------------------------------
     /// Broadcaster event bits definitions.
     //------------------------------------------------------------------
@@ -341,7 +344,8 @@
     bool m_destroy_tried_resuming;
     lldb::CommandObjectSP m_command_sp;
     int64_t m_breakpoint_pc_offset;
-
+    size_t m_breakpoint_trap_opcode_size;  // If set by Python
+
     bool
     StartAsyncThread ();

Index: source/Target/Process.cpp
===================================================================
--- source/Target/Process.cpp (revision 202766)
+++ source/Target/Process.cpp (working copy)
@@ -5973,6 +5973,12 @@
     target.DidExec();
 }

+const DataBufferSP
+Process::GetAuxvData()
+{
+    return lldb_private::Host::GetAuxvData(this);
+}
+
 addr_t
 Process::ResolveIndirectFunction(const Address *address, Error &error)
 {
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140303/0dfd30fe/attachment.html>
-------------- next part --------------
Index: include/lldb/Target/Process.h
===================================================================
--- include/lldb/Target/Process.h	(revision 202766)
+++ include/lldb/Target/Process.h	(working copy)
@@ -2063,6 +2063,9 @@
         return m_unix_signals;
     }
 
+    virtual const lldb::DataBufferSP
+    GetAuxvData();
+
     //==================================================================
     // Plug-in Process Control Overrides
     //==================================================================
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp	(revision 202766)
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.cpp	(working copy)
@@ -66,6 +66,7 @@
     m_prepare_for_reg_writing_reply (eLazyBoolCalculate),
     m_supports_p (eLazyBoolCalculate),
     m_supports_QSaveRegisterState (eLazyBoolCalculate),
+    m_supports_qXfer_auxv_read (eLazyBoolCalculate),
     m_supports_qXfer_libraries_read (eLazyBoolCalculate),
     m_supports_qXfer_libraries_svr4_read (eLazyBoolCalculate),
     m_supports_augmented_libraries_svr4_read (eLazyBoolCalculate),
@@ -187,6 +188,16 @@
     return (m_supports_qXfer_libraries_read == eLazyBoolYes);
 }
 
+bool
+GDBRemoteCommunicationClient::GetQXferAuxvReadSupported ()
+{
+    if (m_supports_qXfer_auxv_read == eLazyBoolCalculate)
+    {
+        GetRemoteQSupported();
+    }
+    return (m_supports_qXfer_auxv_read == eLazyBoolYes);
+}
+
 uint64_t
 GDBRemoteCommunicationClient::GetRemoteMaxPacketSize()
 {
@@ -294,6 +305,7 @@
     m_supports_memory_region_info = eLazyBoolCalculate;
     m_prepare_for_reg_writing_reply = eLazyBoolCalculate;
     m_attach_or_wait_reply = eLazyBoolCalculate;
+    m_supports_qXfer_auxv_read = eLazyBoolCalculate;
     m_supports_qXfer_libraries_read = eLazyBoolCalculate;
     m_supports_qXfer_libraries_svr4_read = eLazyBoolCalculate;
     m_supports_augmented_libraries_svr4_read = eLazyBoolCalculate;
@@ -320,8 +332,9 @@
 GDBRemoteCommunicationClient::GetRemoteQSupported ()
 {
     // Clear out any capabilities we expect to see in the qSupported response
+    m_supports_qXfer_auxv_read = eLazyBoolNo;
+    m_supports_qXfer_libraries_read = eLazyBoolNo;
     m_supports_qXfer_libraries_svr4_read = eLazyBoolNo;
-    m_supports_qXfer_libraries_read = eLazyBoolNo;
     m_supports_augmented_libraries_svr4_read = eLazyBoolNo;
     m_max_packet_size = UINT64_MAX;  // It's supposed to always be there, but if not, we assume no limit
 
@@ -331,6 +344,8 @@
                                      /*send_async=*/false) == PacketResult::Success)
     {
         const char *response_cstr = response.GetStringRef().c_str();
+        if (::strstr (response_cstr, "qXfer:auxv:read+"))
+            m_supports_qXfer_auxv_read = eLazyBoolYes;
         if (::strstr (response_cstr, "qXfer:libraries-svr4:read+"))
             m_supports_qXfer_libraries_svr4_read = eLazyBoolYes;
         if (::strstr (response_cstr, "augmented-libraries-svr4-read"))
@@ -502,11 +517,8 @@
         {
             return PacketResult::ErrorReplyInvalid;
         }
-        // Skip past m or l
-        const char *s = this_string.c_str() + 1;
-
-        // Concatenate the result so far
-        response_string += s;
+        // Concatenate the result so far (skipping 'm' or 'l')
+        response_string.append(this_string, 1, std::string::npos);
         if (first_char == 'l')
             // We're done
             return PacketResult::Success;
Index: source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h
===================================================================
--- source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h	(revision 202766)
+++ source/Plugins/Process/gdb-remote/GDBRemoteCommunicationClient.h	(working copy)
@@ -384,6 +384,9 @@
     SetCurrentThreadForRun (uint64_t tid);
 
     bool
+    GetQXferAuxvReadSupported ();
+
+    bool
     GetQXferLibrariesReadSupported ();
 
     bool
@@ -525,6 +528,7 @@
     lldb_private::LazyBool m_prepare_for_reg_writing_reply;
     lldb_private::LazyBool m_supports_p;
     lldb_private::LazyBool m_supports_QSaveRegisterState;
+    lldb_private::LazyBool m_supports_qXfer_auxv_read;
     lldb_private::LazyBool m_supports_qXfer_libraries_read;
     lldb_private::LazyBool m_supports_qXfer_libraries_svr4_read;
     lldb_private::LazyBool m_supports_augmented_libraries_svr4_read;
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp	(revision 202766)
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp	(working copy)
@@ -281,7 +281,8 @@
     m_waiting_for_attach (false),
     m_destroy_tried_resuming (false),
     m_command_sp (),
-    m_breakpoint_pc_offset (0)
+    m_breakpoint_pc_offset (0),
+    m_breakpoint_trap_opcode_size (0)
 {
     m_async_broadcaster.SetEventName (eBroadcastBitAsyncThreadShouldExit,   "async thread should exit");
     m_async_broadcaster.SetEventName (eBroadcastBitAsyncContinue,           "async thread continue");
@@ -3060,7 +3061,22 @@
     return m_dyld_ap.get();
 }
 
+const DataBufferSP
+ProcessGDBRemote::GetAuxvData()
+{
+    DataBufferSP buf;
+    if (m_gdb_comm.GetQXferAuxvReadSupported())
+    {
+        std::string response_string;
+        if (m_gdb_comm.SendPacketsAndConcatenateResponses("qXfer:auxv:read::", response_string) == GDBRemoteCommunication::PacketResult::Success)
+            buf.reset(new DataBufferHeap(response_string.c_str(), response_string.length()));
+    }
+    if (buf.get() != NULL)
+        return buf;
+    return Process::GetAuxvData();
+}
 
+
 class CommandObjectProcessGDBRemotePacketHistory : public CommandObjectParsed
 {
 private:
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.h	(revision 202766)
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.h	(working copy)
@@ -299,6 +299,9 @@
     bool
     ParseRegisters(lldb_private::ScriptInterpreterObject *registers_array);
 
+    virtual const lldb::DataBufferSP
+    GetAuxvData();
+
     //------------------------------------------------------------------
     /// Broadcaster event bits definitions.
     //------------------------------------------------------------------
@@ -341,7 +344,8 @@
     bool m_destroy_tried_resuming;
     lldb::CommandObjectSP m_command_sp;
     int64_t m_breakpoint_pc_offset;
-    
+    size_t m_breakpoint_trap_opcode_size;  // If set by Python
+
     bool
     StartAsyncThread ();
 
Index: source/Target/Process.cpp
===================================================================
--- source/Target/Process.cpp	(revision 202766)
+++ source/Target/Process.cpp	(working copy)
@@ -5973,6 +5973,12 @@
     target.DidExec();
 }
 
+const DataBufferSP
+Process::GetAuxvData()
+{
+    return lldb_private::Host::GetAuxvData(this);
+}
+
 addr_t
 Process::ResolveIndirectFunction(const Address *address, Error &error)
 {


More information about the lldb-dev mailing list