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, // // 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 a 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:; // 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:, // 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.