view lldb/docs/lldb-platform-packets.txt @ 214:0cf2d4ade63d

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 13 Jul 2021 09:53:52 +0900
parents 2e18cbf3894f
children c4bab56944e8
line wrap: on
line source

Here is a brief overview of the packets that an lldb platform server
needs to implement for the lldb testsuite to be run on a remote
target device/system.

These are almost all lldb extensions to the gdb-remote serial
protocol.  Many of the vFile: packets are described to the "Host
I/O Packets" detailed in the gdb-remote protocol documentation,
although the lldb platform extensions include packets that are not
defined there (vFile:size:, vFile:mode:, vFile:symlink, vFile:chmod:).
Most importantly, the flags that lldb passes to vFile:open: are 
incompatible with the flags that gdb specifies.


//----------------------------------------------------------------------
// QStartNoAckMode
//
// BRIEF
//   A request to stop sending ACK packets for each properly formatted packet.
//
// EXAMPLE 
//   A platform session will typically start like this:
//
//   receive: +$QStartNoAckMode#b0
//   send:    +       <-- ACKing the properly formatted QStartNoAckMode packet
//   send:    $OK#9a
//   receive: +       <-- Our OK packet getting ACKed
//
//   ACK mode is now disabled.

//----------------------------------------------------------------------
// qHostInfo
//
// BRIEF
//   Describe the hardware and OS of the target system
//
// EXAMPLE
//
//  receive: qHostInfo
//  send:    cputype:16777228;cpusubtype:1;ostype:ios;watchpoint_exceptions_received:before;os_version:12.1;vendor:apple;default_packet_timeout:5;
//
//  All numbers are base 10, os_version is a string that will be parsed as major.minor.patch.

//----------------------------------------------------------------------
// qModuleInfo
//
// BRIEF
//   Report information about a binary on the target system
//
// EXAMPLE
//  receive: qModuleInfo:2f62696e2f6c73;
//
// FIXME finish this packet description, v. GDBRemoteCommunicationServerCommon::Handle_qModuleInfo


//----------------------------------------------------------------------
// qGetWorkingDir
//
// BRIEF
//   Get the current working directory of the platform stub in
//   ASCII hex encoding.
//
// EXAMPLE
// 
//  receive: qGetWorkingDir
//  send:    2f4170706c65496e7465726e616c2f6c6c64622f73657474696e67732f342f5465737453657474696e67732e746573745f646973617373656d626c65725f73657474696e6773 



//----------------------------------------------------------------------
// QSetWorkingDir:
//
// BRIEF
//   Set the current working directory of the platform stub in
//   ASCII hex encoding.
//
// EXAMPLE
// 
//  receive: QSetWorkingDir:2f4170706c65496e7465726e616c2f6c6c64622f73657474696e67732f342f5465737453657474696e67732e746573745f646973617373656d626c65725f73657474696e6773 
//  send:    OK

//----------------------------------------------------------------------
// qPlatform_mkdir:
//
// BRIEF
//   Create a directory on the target system.
//
// EXAMPLE
// 
//  receive: qPlatform_mkdir:000001fd,2f746d702f6131
//  send:    F0
//
//  request packet has the fields:
//     1. mode bits in base 16
//     2. file path in ascii-hex encoding
//
//  response is F followed by the return value of the mkdir() call,
//  base 10 encoded.

//----------------------------------------------------------------------
// qPlatform_shell:
//
// BRIEF
//   Run a shell command on the target system, return the output.
//
// EXAMPLE
// 
//  receive: qPlatform_shell:6c73202f746d702f,0000000a
//  send:    F,0,0,<OUTPUT>
//
//  request packet has the fields:
//     1. shell command ascii-hex encoded
//     2. timeout 
//     3. {optional} working directory ascii-hex encoded
//
//  Response is F followed by the return value of the command (base 16),
//  followed by another number, followed by the output of the command
/   in binary-escaped-data encoding.

//----------------------------------------------------------------------
// qLaunchGDBServer
//
// BRIEF
//   Start a gdbserver process (gdbserver, debugserver, lldb-server)
//   on the target system.
//
// EXAMPLE
// 
//  receive: qLaunchGDBServer;host:<HOSTNAME_LLDB_IS_ON>;
//  send:    pid:1337;port:43001;
//
//  request packet hostname field is not ascii-hex encoded. Hostnames 
//  don't have $ or # characters in them.
//
//  response to the packet is the pid of the newly launched gdbserver,
//  and the port it is listening for a connection on.
//
//  When the testsuite is running, lldb may use the pid to kill off a 
//  debugserver that doesn't seem to be responding, etc.

//----------------------------------------------------------------------
// qKillSpawnedProcess:
//
// BRIEF
//   Kill a process running on the target system.
//
// EXAMPLE
// 
//  receive: qKillSpawnedProcess:1337
//  send:    OK
//
//  The request packet has the process ID in base 10.

//----------------------------------------------------------------------
// qProcessInfoPID:
//
// BRIEF
//   Gather information about a process running on the target
//
// EXAMPLE
// 
//  receive: qProcessInfoPID:71964
//  send:    pid:71964;name:612e6f7574;
//
//  The request packet has the pid encoded in base 10.
//
//  The reply has semicolon-separated name:value fields, two are
//  shown here.  pid is base 10 encoded.  name is ascii hex encoded.
//  lldb-server can reply with many additional fields, but I think
//  this is enough for the testsuite.

//----------------------------------------------------------------------
// qfProcessInfo:
//
// BRIEF
//   Search the process table for processes matching criteria, 
//   respond with them in multiple packets.
//
// EXAMPLE
// 
//  receive: qfProcessInfo:name_match:equals;name:6e6f70726f6365737365786973747377697468746869736e616d65;
//  send:    pid:3500;name:612e6f7574;
//
//  The request packet has a criteria to search for, followed by
//  a specific name.  
//
//  KEY           VALUE     DESCRIPTION
//  ===========   ========  ================================================
//  "name"        ascii-hex An ASCII hex string that contains the name of 
//                          the process that will be matched.
//  "name_match"  enum      One of: "equals", "starts_with", "ends_with", 
//                          "contains" or "regex"
//  "pid"         integer   A string value containing the decimal process ID
//  "parent_pid"  integer   A string value containing the decimal parent 
//                          process ID
//  "uid"         integer   A string value containing the decimal user ID
//  "gid"         integer   A string value containing the decimal group ID
//  "euid"        integer   A string value containing the decimal effective user ID
//  "egid"        integer   A string value containing the decimal effective group ID
//  "all_users"   bool      A boolean value that specifies if processes should
//                          be listed for all users, not just the user that the 
//                          platform is running as
//  "triple"      ascii-hex An ASCII hex target triple string ("x86_64", 
//                          "x86_64-apple-macosx", "armv7-apple-ios")
//
//  If no criteria is given, qfProcessInfo will request a list of every process.
//
//  The lldb testsuite currently only uses name_match:equals and the
//  no-criteria mode to list every process.
//
//  The response should include any information about the process that
//  can be retrieved in semicolon-separated name:value fields.
//  In this example, pid is base 10, name is ascii-hex encoded.
//  The testsuite seems to only require these two.
//
//  This packet only responds with one process.  To get further matches to
//  the search, qsProcessInfo should be sent.
//
//  If no process match is found, Exx should be returned.
//
//  Sample packet/response:
//  send packet: $qfProcessInfo#00
//  read packet: $pid:60001;ppid:59948;uid:7746;gid:11;euid:7746;egid:11;name:6c6c6462;triple:7838365f36342d6170706c652d6d61636f7378;#00
//  send packet: $qsProcessInfo#00
//  read packet: $pid:59992;ppid:192;uid:7746;gid:11;euid:7746;egid:11;name:6d64776f726b6572;triple:7838365f36342d6170706c652d6d61636f7378;#00
//  send packet: $qsProcessInfo#00
//  read packet: $E04#00

//----------------------------------------------------------------------
// qsProcessInfo
//
// BRIEF
//   Return the next process info found by the most recent qfProcessInfo:
//   packet.
//
// EXAMPLE
// 
//  Continues to return the results of the qfProcessInfo.  Once all matches
//  have been sent, Exx is returned to indicate end of matches.

//----------------------------------------------------------------------
// qPathComplete
//
// BRIEF
//   Get a list of matched disk files/directories by passing a boolean flag
//   and a partial path.
//
// EXAMPLE
//
//   receive: qPathComplete:0,6d61696e
//   send:    M6d61696e2e637070
//   receive: qPathComplete:1,746573
//   send:    M746573742f,74657374732f
//
//   If the first argument is zero, the result should contain all
//   files (including directories) starting with the given path. If the
//   argument is one, the result should contain only directories.
//
//   The result should be a comma-separated list of hex-encoded paths.
//   Paths denoting a directory should end with a directory separator ('/' or '\').

//----------------------------------------------------------------------
// vFile:size:
//
// BRIEF
//   Get the size of a file on the target system, filename in ASCII hex.
//
// EXAMPLE
// 
//  receive: vFile:size:2f746d702f61
//  send:    Fc008
//
//  response is "F" followed by the file size in base 16.
//  "F-1,errno" with the errno if an error occurs.


//----------------------------------------------------------------------
// vFile:mode:
//
// BRIEF
//   Get the mode bits of a file on the target system, filename in ASCII hex.
//
// EXAMPLE
// 
//  receive: vFile:mode:2f746d702f61
//  send:    F1ed
//
//  response is "F" followed by the mode bits in base 16, this 0x1ed would 
//  correspond to 0755 in octal.  
//  "F-1,errno" with the errno if an error occurs.

//----------------------------------------------------------------------
// vFile:unlink:
//
// BRIEF
//   Remove a file on the target system.
//
// EXAMPLE
// 
//  receive: vFile:unlink:2f746d702f61
//  send:    F0
//
//  Argument is a file path in ascii-hex encoding.
//  Response is "F" plus the return value of unlink(), base 10 encoding.

//----------------------------------------------------------------------
// vFile:symlink:
//
// BRIEF
//   Create a symbolic link (symlink, soft-link) on the target system.
//
// EXAMPLE
// 
//  receive: vFile:symlink:<SRC-FILE>,<DST-NAME>
//  send:    F0,0
//
//  Argument file paths are in ascii-hex encoding.
//  Response is "F" plus the return value of symlink(), base 10 encoding, twice.

//----------------------------------------------------------------------
// vFile:chmod:
// qPlatform_chmod:
//
// BRIEF
//   Change the permission mode bits on a file on the target
//
// EXAMPLE
// 
//  receive: vFile:chmod:180,2f746d702f61
//  send:    F0
//
//  Arguments are the mode bits to set, base 16, and a file path in 
//  ascii-hex encoding.
//  Response is "F" plus the return value of chmod(), base 10 encoding.
//
//  I don't know why there are two packets for the same thing, v.
//  vFile:chmod:.

//----------------------------------------------------------------------
// vFile:chmod:
//
// BRIEF
//   Change the permission mode bits on a file on the target
//
// EXAMPLE
// 
//  receive: vFile:chmod:180,2f746d702f61
//  send:    F0
//
//  Arguments are the mode bits to set, base 16, and a file path in 
//  ascii-hex encoding.
//  Response is "F" plus the return value of chmod(), base 10 encoding.


//----------------------------------------------------------------------
// vFile:open:
//
// BRIEF
//   Open a file on the remote system and return the file descriptor of it.
//
// EXAMPLE
// 
//  receive: vFile:open:2f746d702f61,00000001,00000180
//  send:    F8
//
//  request packet has the fields:
//     1. ASCII hex encoded filename
//     2. flags passed to the open call, base 16.
//        Note that these are not the oflags that open(2) takes, but
//        are the constant values in enum OpenOptions from lldb's File.h
//     3. mode bits, base 16
//  
//  response is F followed by the opened file descriptor in base 10.
//  "F-1,errno" with the errno if an error occurs.
//
//  COMPATIBILITY
//    The gdb-remote serial protocol documentatio defines a vFile:open:
//    packet which uses incompatible flag values, e.g. 1 means O_WRONLY
//    in gdb's vFile:open:, but it means eOpenOptionRead to lldb's
//    implementation.

//----------------------------------------------------------------------
// vFile:close:
//
// BRIEF
//   Close a previously opened file descriptor.
//
// EXAMPLE
// 
//  receive: vFile:close:7
//  send:    F0
//
//  File descriptor is in base 10.
//  "F-1,errno" with the errno if an error occurs.


//----------------------------------------------------------------------
// vFile:pread:
//
// BRIEF
//   Read data from an opened file descriptor.
//
// EXAMPLE
// 
//  receive: vFile:pread:7,1024,0
//  send:    F4;a'b\00
//
//  request packet has the fields:
//     1. file descriptor, base 10
//     2. number of bytes to be read, base 10
//     3. offset into file to start from, base 10
//
//  Response is F, followed by the number of bytes read (base 10), a
//  semicolon, followed by the data in the binary-escaped-data encoding.
//
//  COMPATIBILITY
//    The gdb-remote serial protocol documentation says that numbers
//    in "vFile:" packets should be hexadecimal. Instead lldb uses
//    decimal.


//----------------------------------------------------------------------
// vFile:pwrite:
//
// BRIEF
//   Write data to a previously opened file descriptor.
//
// EXAMPLE
// 
//  receive: vFile:pwrite:8,0,\cf\fa\ed\fe\0c\00\00
//  send:    F1024
//
//  request packet has the fields:
//     1. file descriptor, base 10
//     2. offset into file to start from, base 10
//     3. binary-escaped-data to be written
//
//  Response is F, followed by the number of bytes written (base 10)
//
//  COMPATIBILITY
//    The gdb-remote serial protocol documentation says that numbers
//    in "vFile:" packets should be hexadecimal. Instead lldb uses
//    decimal.





Finally, the platform must be able to launch processes so that debugserver
can attach to them.  To do this, the following packets should be handled:

QSetDisableASLR
QSetDetachOnError
QSetSTDOUT
QSetSTDERR
QSetSTDIN
QEnvironment
QEnvironmentHexEncoded
A
qLaunchSuccess
qProcessInfo

Most of these are documented in the standard gdb-remote protocol
and/or the lldb-gdb-remote.txt documentation.