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

Steve Pucci spucci at google.com
Tue Mar 4 11:26:06 PST 2014


Revised patch per Greg's request to remove interface from base class
Process.h/cpp.  I also caught and removed the added field
m_breakpoint_trap_opcode_size I had accidentally left in the sandbox I used
to create the original patch.

Thanks,
   Steve

PS, sorry, forgot to CC lldb-dev on my reply to Greg.  That exchange is
included below.

On Tue, Mar 4, 2014 at 10:57 AM, Greg Clayton <gclayton at apple.com> wrote:

> Thanks for the info. I would prefer to remove the code from Process.h/cpp
> and resubmit the patch.
>
> On Mar 4, 2014, at 7:31 AM, Steve Pucci <spucci at google.com> wrote:
>
> > Hi Greg,
> >
> > Thanks for the review.  The auxv data structure (which is apparently a
> feature of ELF-derived programs) seems to be common to at least linux and
> freebsd, as there are implementations of each. It's used to discover
> process information such as the program entry point and the program headers.
> >
> > To be honest I'm uncertain of the ultimate use of the code in this
> patch.  In one of my sandboxes I have it called from DynamicLoaderPOSIXDYLD
> because that seemed to be the place that wants to know the auxv, and it
> doesn't know the type of Process it has (I've run into issues with the lack
> of target architectural knowledge in my proposed DynamicLoaderGDBRemote
> class and this second sandbox was an experiment to see if it would be
> cleaner implemented without the custom dynamic loader for remote).
> >
> > I didn't change Host; it already had GetAuxvData() as an API,
> implemented only on the linux and freebsd versions. [ This seemed an odd
> place to have that function to me, as it seems to be a Target function
> rather than a Host one, but I might be missing something. ]  So my new API
> on Process delegates to the existing functionality except when working
> remotely.
> >
> > That said, I have no objection to removing the API on Process.cpp/h if
> you think that's best.  Mostly I just want this code in place for future
> use as I think it will ultimately be useful in some form for remote
> debugging on linux/freebsd; I'm going to be working on a different project
> for the forseeable future and I don't want it to be lost altogether.
> >
> > Let me know what you think.
> >
> >  - Steve
> >
> >
> > On Mon, Mar 3, 2014 at 5:02 PM, Greg Clayton <gclayton at apple.com> wrote:
> > Steve, what is the rationale for having Process::GetAuxvData()? Can we
> not just keep this as a ProcessGDBRemote only function? Is anyone else
> besides ProcessGDBRemote going to be able to do anything with this data? If
> the answer is no, I would prefer to keep this out of Process.cpp/Process.h.
> If it is only in there to keep from having to cast Process to
> ProcessGDBRemote, then it definitely should be removed from Process.cpp/.h.
> I am guessing you have some other idea for this because you added it to the
> host layer. I don't the see the host layer patch for those parts of the
> changes. I am not really familiar with the content of the auxv data and I
> don't know how standardized it is or isn't?
> >
> > Greg
> >
> > On Mar 3, 2014, at 3:44 PM, Steve Pucci <spucci at google.com> wrote:
> >
> > > 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)
> > >  {
> > >
> > >
> <patch-auxv-viaPacket.txt>_______________________________________________
> > > lldb-dev mailing list
> > > lldb-dev at cs.uiuc.edu
> > > http://lists.cs.uiuc.edu/mailman/listinfo/lldb-dev
> >
> >
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/lldb-dev/attachments/20140304/dcff3883/attachment.html>
-------------- next part --------------
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)
@@ -3060,7 +3060,20 @@
     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()));
+    }
+    return buf;
+}
 
+
 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.
     //------------------------------------------------------------------


More information about the lldb-dev mailing list