GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite(
    StringExtractorGDBRemote &packet) {
#ifdef _WIN32
  return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_"
                                   "vFile_pWrite() unimplemented");
#else
  packet.SetFilePos(::strlen("vFile:pwrite:"));

  StreamGDBRemote response;
  response.PutChar('F');

  int fd = packet.GetU32(UINT32_MAX);
  if (packet.GetChar() == ',') {
    off_t offset = packet.GetU64(UINT32_MAX);
    if (packet.GetChar() == ',') {
      std::string buffer;
      if (packet.GetEscapedBinaryData(buffer)) {
        const ssize_t bytes_written =
            ::pwrite(fd, buffer.data(), buffer.size(), offset);
        const int save_errno = bytes_written == -1 ? errno : 0;
        response.Printf("%zi", bytes_written);
        if (save_errno)
          response.Printf(",%i", save_errno);
      } else {
        response.Printf("-1,%i", EINVAL);
      }
      return SendPacketNoLock(response.GetString());
    }
  }
  return SendErrorResponse(27);
#endif
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerPlatform::Handle_qLaunchGDBServer (StringExtractorGDBRemote &packet)
{
#ifdef _WIN32
    return SendErrorResponse(9);
#else
    // Spawn a local debugserver as a platform so we can then attach or launch
    // a process...

    Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PLATFORM));
    if (log)
        log->Printf ("GDBRemoteCommunicationServerPlatform::%s() called", __FUNCTION__);

    ConnectionFileDescriptor file_conn;
    std::string hostname;
    packet.SetFilePos(::strlen ("qLaunchGDBServer;"));
    std::string name;
    std::string value;
    uint16_t port = UINT16_MAX;
    while (packet.GetNameColonValue(name, value))
    {
        if (name.compare ("host") == 0)
            hostname.swap(value);
        else if (name.compare ("port") == 0)
            port = StringConvert::ToUInt32(value.c_str(), 0, 0);
    }

    lldb::pid_t debugserver_pid = LLDB_INVALID_PROCESS_ID;
    std::string socket_name;
    Error error = LaunchGDBServer(Args(), hostname, debugserver_pid, port, socket_name);
    if (error.Fail())
    {
        if (log)
            log->Printf("GDBRemoteCommunicationServerPlatform::%s() debugserver launch failed: %s", __FUNCTION__, error.AsCString ());
        return SendErrorResponse(9);
    }

    if (log)
        log->Printf ("GDBRemoteCommunicationServerPlatform::%s() debugserver launched successfully as pid %" PRIu64, __FUNCTION__, debugserver_pid);

    StreamGDBRemote response;
    response.Printf("pid:%" PRIu64 ";port:%u;", debugserver_pid, port + m_port_offset);
    if (!socket_name.empty())
    {
        response.PutCString("socket_name:");
        response.PutCStringAsRawHex8(socket_name.c_str());
        response.PutChar(';');
    }

    PacketResult packet_result = SendPacketNoLock(response.GetData(), response.GetSize());
    if (packet_result != PacketResult::Success)
    {
        if (debugserver_pid != LLDB_INVALID_PROCESS_ID)
            ::kill (debugserver_pid, SIGINT);
    }
    return packet_result;
#endif
}
Esempio n. 3
0
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServer::Handle_vFile_pRead (StringExtractorGDBRemote &packet)
{
#ifdef _WIN32
    // Not implemented on Windows
    return SendUnimplementedResponse("GDBRemoteCommunicationServer::Handle_vFile_pRead() unimplemented");
#else
    StreamGDBRemote response;
    packet.SetFilePos(::strlen("vFile:pread:"));
    int fd = packet.GetS32(-1);
    if (packet.GetChar() == ',')
    {
        uint64_t count = packet.GetU64(UINT64_MAX);
        if (packet.GetChar() == ',')
        {
            uint64_t offset = packet.GetU64(UINT32_MAX);
            if (count == UINT64_MAX)
            {
                response.Printf("F-1:%i", EINVAL);
                return SendPacketNoLock(response.GetData(), response.GetSize());
            }
            
            std::string buffer(count, 0);
            const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset);
            const int save_errno = bytes_read == -1 ? errno : 0;
            response.PutChar('F');
            response.Printf("%zi", bytes_read);
            if (save_errno)
                response.Printf(",%i", save_errno);
            else
            {
                response.PutChar(';');
                response.PutEscapedBytes(&buffer[0], bytes_read);
            }
            return SendPacketNoLock(response.GetData(), response.GetSize());
        }
    }
    return SendErrorResponse(21);

#endif
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir(
    StringExtractorGDBRemote &packet) {
  packet.SetFilePos(::strlen("qPlatform_mkdir:"));
  mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
  if (packet.GetChar() == ',') {
    std::string path;
    packet.GetHexByteString(path);
    Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode);

    StreamGDBRemote response;
    response.Printf("F%u", error.GetError());

    return SendPacketNoLock(response.GetString());
  }
  return SendErrorResponse(20);
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_qSupported (StringExtractorGDBRemote &packet)
{
    StreamGDBRemote response;

    // Features common to lldb-platform and llgs.
    uint32_t max_packet_size = 128 * 1024;  // 128KBytes is a reasonable max packet size--debugger can always use less
    response.Printf ("PacketSize=%x", max_packet_size);

    response.PutCString (";QStartNoAckMode+");
    response.PutCString (";QThreadSuffixSupported+");
    response.PutCString (";QListThreadsInStopReply+");
    response.PutCString (";qEcho+");
#if defined(__linux__)
    response.PutCString (";qXfer:auxv:read+");
#endif

    return SendPacketNoLock(response.GetData(), response.GetSize());
}
GDBRemoteCommunication::PacketResult
GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet)
{
    packet.SetFilePos(::strlen("qPlatform_chmod:"));

    mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX);
    if (packet.GetChar() == ',')
    {
        std::string path;
        packet.GetHexByteString(path);
        Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode);

        StreamGDBRemote response;
        response.Printf("F%u", error.GetError());

        return SendPacketNoLock(response.GetData(), response.GetSize());
    }
    return SendErrorResponse(19);
}