1 //===-- GDBRemoteCommunicationServerCommon.cpp ------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "GDBRemoteCommunicationServerCommon.h" 11 12 #include <errno.h> 13 14 // C Includes 15 // C++ Includes 16 #include <cstring> 17 #include <chrono> 18 19 // Other libraries and framework includes 20 #include "llvm/ADT/Triple.h" 21 #include "lldb/Core/Log.h" 22 #include "lldb/Core/ModuleSpec.h" 23 #include "lldb/Core/StreamGDBRemote.h" 24 #include "lldb/Core/StreamString.h" 25 #include "lldb/Host/Config.h" 26 #include "lldb/Host/Endian.h" 27 #include "lldb/Host/File.h" 28 #include "lldb/Host/FileSystem.h" 29 #include "lldb/Host/Host.h" 30 #include "lldb/Host/HostInfo.h" 31 #include "lldb/Host/StringConvert.h" 32 #include "lldb/Interpreter/Args.h" 33 #include "lldb/Symbol/ObjectFile.h" 34 #include "lldb/Target/FileAction.h" 35 #include "lldb/Target/Platform.h" 36 #include "lldb/Target/Process.h" 37 38 // Project includes 39 #include "ProcessGDBRemoteLog.h" 40 #include "Utility/StringExtractorGDBRemote.h" 41 42 #ifdef __ANDROID__ 43 #include "lldb/Host/android/HostInfoAndroid.h" 44 #endif 45 46 using namespace lldb; 47 using namespace lldb_private; 48 using namespace lldb_private::process_gdb_remote; 49 50 #ifdef __ANDROID__ 51 const static uint32_t g_default_packet_timeout_sec = 20; // seconds 52 #else 53 const static uint32_t g_default_packet_timeout_sec = 0; // not specified 54 #endif 55 56 //---------------------------------------------------------------------- 57 // GDBRemoteCommunicationServerCommon constructor 58 //---------------------------------------------------------------------- 59 GDBRemoteCommunicationServerCommon::GDBRemoteCommunicationServerCommon(const char *comm_name, const char *listener_name) : 60 GDBRemoteCommunicationServer (comm_name, listener_name), 61 m_process_launch_info (), 62 m_process_launch_error (), 63 m_proc_infos (), 64 m_proc_infos_index (0), 65 m_thread_suffix_supported (false), 66 m_list_threads_in_stop_reply (false) 67 { 68 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_A, 69 &GDBRemoteCommunicationServerCommon::Handle_A); 70 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QEnvironment, 71 &GDBRemoteCommunicationServerCommon::Handle_QEnvironment); 72 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QEnvironmentHexEncoded, 73 &GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded); 74 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qfProcessInfo, 75 &GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo); 76 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qGroupName, 77 &GDBRemoteCommunicationServerCommon::Handle_qGroupName); 78 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qHostInfo, 79 &GDBRemoteCommunicationServerCommon::Handle_qHostInfo); 80 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QLaunchArch, 81 &GDBRemoteCommunicationServerCommon::Handle_QLaunchArch); 82 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qLaunchSuccess, 83 &GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess); 84 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QListThreadsInStopReply, 85 &GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply); 86 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qEcho, 87 &GDBRemoteCommunicationServerCommon::Handle_qEcho); 88 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qModuleInfo, 89 &GDBRemoteCommunicationServerCommon::Handle_qModuleInfo); 90 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_chmod, 91 &GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod); 92 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_mkdir, 93 &GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir); 94 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qPlatform_shell, 95 &GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell); 96 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qProcessInfoPID, 97 &GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID); 98 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetDetachOnError, 99 &GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError); 100 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDERR, 101 &GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR); 102 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDIN, 103 &GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN); 104 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QSetSTDOUT, 105 &GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT); 106 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qSpeedTest, 107 &GDBRemoteCommunicationServerCommon::Handle_qSpeedTest); 108 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qsProcessInfo, 109 &GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo); 110 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QStartNoAckMode, 111 &GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode); 112 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qSupported, 113 &GDBRemoteCommunicationServerCommon::Handle_qSupported); 114 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_QThreadSuffixSupported, 115 &GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported); 116 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_qUserName, 117 &GDBRemoteCommunicationServerCommon::Handle_qUserName); 118 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_close, 119 &GDBRemoteCommunicationServerCommon::Handle_vFile_Close); 120 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_exists, 121 &GDBRemoteCommunicationServerCommon::Handle_vFile_Exists); 122 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_md5, 123 &GDBRemoteCommunicationServerCommon::Handle_vFile_MD5); 124 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_mode, 125 &GDBRemoteCommunicationServerCommon::Handle_vFile_Mode); 126 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_open, 127 &GDBRemoteCommunicationServerCommon::Handle_vFile_Open); 128 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_pread, 129 &GDBRemoteCommunicationServerCommon::Handle_vFile_pRead); 130 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_pwrite, 131 &GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite); 132 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_size, 133 &GDBRemoteCommunicationServerCommon::Handle_vFile_Size); 134 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_stat, 135 &GDBRemoteCommunicationServerCommon::Handle_vFile_Stat); 136 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_symlink, 137 &GDBRemoteCommunicationServerCommon::Handle_vFile_symlink); 138 RegisterMemberFunctionHandler(StringExtractorGDBRemote::eServerPacketType_vFile_unlink, 139 &GDBRemoteCommunicationServerCommon::Handle_vFile_unlink); 140 } 141 142 //---------------------------------------------------------------------- 143 // Destructor 144 //---------------------------------------------------------------------- 145 GDBRemoteCommunicationServerCommon::~GDBRemoteCommunicationServerCommon() 146 { 147 } 148 149 GDBRemoteCommunication::PacketResult 150 GDBRemoteCommunicationServerCommon::Handle_qHostInfo (StringExtractorGDBRemote &packet) 151 { 152 StreamString response; 153 154 // $cputype:16777223;cpusubtype:3;ostype:Darwin;vendor:apple;endian:little;ptrsize:8;#00 155 156 ArchSpec host_arch(HostInfo::GetArchitecture()); 157 const llvm::Triple &host_triple = host_arch.GetTriple(); 158 response.PutCString("triple:"); 159 response.PutCStringAsRawHex8(host_triple.getTriple().c_str()); 160 response.Printf (";ptrsize:%u;",host_arch.GetAddressByteSize()); 161 162 const char* distribution_id = host_arch.GetDistributionId ().AsCString (); 163 if (distribution_id) 164 { 165 response.PutCString("distribution_id:"); 166 response.PutCStringAsRawHex8(distribution_id); 167 response.PutCString(";"); 168 } 169 170 // Only send out MachO info when lldb-platform/llgs is running on a MachO host. 171 #if defined(__APPLE__) 172 uint32_t cpu = host_arch.GetMachOCPUType(); 173 uint32_t sub = host_arch.GetMachOCPUSubType(); 174 if (cpu != LLDB_INVALID_CPUTYPE) 175 response.Printf ("cputype:%u;", cpu); 176 if (sub != LLDB_INVALID_CPUTYPE) 177 response.Printf ("cpusubtype:%u;", sub); 178 179 if (cpu == ArchSpec::kCore_arm_any) 180 response.Printf("watchpoint_exceptions_received:before;"); // On armv7 we use "synchronous" watchpoints which means the exception is delivered before the instruction executes. 181 else 182 response.Printf("watchpoint_exceptions_received:after;"); 183 #else 184 if (host_arch.GetMachine() == llvm::Triple::aarch64 || 185 host_arch.GetMachine() == llvm::Triple::aarch64_be || 186 host_arch.GetMachine() == llvm::Triple::arm || 187 host_arch.GetMachine() == llvm::Triple::armeb || 188 host_arch.GetMachine() == llvm::Triple::mips64 || 189 host_arch.GetMachine() == llvm::Triple::mips64el || 190 host_arch.GetMachine() == llvm::Triple::mips || 191 host_arch.GetMachine() == llvm::Triple::mipsel) 192 response.Printf("watchpoint_exceptions_received:before;"); 193 else 194 response.Printf("watchpoint_exceptions_received:after;"); 195 #endif 196 197 switch (endian::InlHostByteOrder()) 198 { 199 case eByteOrderBig: response.PutCString ("endian:big;"); break; 200 case eByteOrderLittle: response.PutCString ("endian:little;"); break; 201 case eByteOrderPDP: response.PutCString ("endian:pdp;"); break; 202 default: response.PutCString ("endian:unknown;"); break; 203 } 204 205 uint32_t major = UINT32_MAX; 206 uint32_t minor = UINT32_MAX; 207 uint32_t update = UINT32_MAX; 208 if (HostInfo::GetOSVersion(major, minor, update)) 209 { 210 if (major != UINT32_MAX) 211 { 212 response.Printf("os_version:%u", major); 213 if (minor != UINT32_MAX) 214 { 215 response.Printf(".%u", minor); 216 if (update != UINT32_MAX) 217 response.Printf(".%u", update); 218 } 219 response.PutChar(';'); 220 } 221 } 222 223 std::string s; 224 if (HostInfo::GetOSBuildString(s)) 225 { 226 response.PutCString ("os_build:"); 227 response.PutCStringAsRawHex8(s.c_str()); 228 response.PutChar(';'); 229 } 230 if (HostInfo::GetOSKernelDescription(s)) 231 { 232 response.PutCString ("os_kernel:"); 233 response.PutCStringAsRawHex8(s.c_str()); 234 response.PutChar(';'); 235 } 236 237 #if defined(__APPLE__) 238 239 #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 240 // For iOS devices, we are connected through a USB Mux so we never pretend 241 // to actually have a hostname as far as the remote lldb that is connecting 242 // to this lldb-platform is concerned 243 response.PutCString ("hostname:"); 244 response.PutCStringAsRawHex8("127.0.0.1"); 245 response.PutChar(';'); 246 #else // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 247 if (HostInfo::GetHostname(s)) 248 { 249 response.PutCString ("hostname:"); 250 response.PutCStringAsRawHex8(s.c_str()); 251 response.PutChar(';'); 252 } 253 #endif // #if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) 254 255 #else // #if defined(__APPLE__) 256 if (HostInfo::GetHostname(s)) 257 { 258 response.PutCString ("hostname:"); 259 response.PutCStringAsRawHex8(s.c_str()); 260 response.PutChar(';'); 261 } 262 #endif // #if defined(__APPLE__) 263 264 if (g_default_packet_timeout_sec > 0) 265 response.Printf ("default_packet_timeout:%u;", g_default_packet_timeout_sec); 266 267 return SendPacketNoLock (response.GetData(), response.GetSize()); 268 } 269 270 GDBRemoteCommunication::PacketResult 271 GDBRemoteCommunicationServerCommon::Handle_qProcessInfoPID (StringExtractorGDBRemote &packet) 272 { 273 // Packet format: "qProcessInfoPID:%i" where %i is the pid 274 packet.SetFilePos (::strlen ("qProcessInfoPID:")); 275 lldb::pid_t pid = packet.GetU32 (LLDB_INVALID_PROCESS_ID); 276 if (pid != LLDB_INVALID_PROCESS_ID) 277 { 278 ProcessInstanceInfo proc_info; 279 if (Host::GetProcessInfo (pid, proc_info)) 280 { 281 StreamString response; 282 CreateProcessInfoResponse (proc_info, response); 283 return SendPacketNoLock (response.GetData(), response.GetSize()); 284 } 285 } 286 return SendErrorResponse (1); 287 } 288 289 GDBRemoteCommunication::PacketResult 290 GDBRemoteCommunicationServerCommon::Handle_qfProcessInfo (StringExtractorGDBRemote &packet) 291 { 292 m_proc_infos_index = 0; 293 m_proc_infos.Clear(); 294 295 ProcessInstanceInfoMatch match_info; 296 packet.SetFilePos(::strlen ("qfProcessInfo")); 297 if (packet.GetChar() == ':') 298 { 299 300 std::string key; 301 std::string value; 302 while (packet.GetNameColonValue(key, value)) 303 { 304 bool success = true; 305 if (key.compare("name") == 0) 306 { 307 StringExtractor extractor; 308 extractor.GetStringRef().swap(value); 309 extractor.GetHexByteString (value); 310 match_info.GetProcessInfo().GetExecutableFile().SetFile(value.c_str(), false); 311 } 312 else if (key.compare("name_match") == 0) 313 { 314 if (value.compare("equals") == 0) 315 { 316 match_info.SetNameMatchType (eNameMatchEquals); 317 } 318 else if (value.compare("starts_with") == 0) 319 { 320 match_info.SetNameMatchType (eNameMatchStartsWith); 321 } 322 else if (value.compare("ends_with") == 0) 323 { 324 match_info.SetNameMatchType (eNameMatchEndsWith); 325 } 326 else if (value.compare("contains") == 0) 327 { 328 match_info.SetNameMatchType (eNameMatchContains); 329 } 330 else if (value.compare("regex") == 0) 331 { 332 match_info.SetNameMatchType (eNameMatchRegularExpression); 333 } 334 else 335 { 336 success = false; 337 } 338 } 339 else if (key.compare("pid") == 0) 340 { 341 match_info.GetProcessInfo().SetProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); 342 } 343 else if (key.compare("parent_pid") == 0) 344 { 345 match_info.GetProcessInfo().SetParentProcessID (StringConvert::ToUInt32(value.c_str(), LLDB_INVALID_PROCESS_ID, 0, &success)); 346 } 347 else if (key.compare("uid") == 0) 348 { 349 match_info.GetProcessInfo().SetUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 350 } 351 else if (key.compare("gid") == 0) 352 { 353 match_info.GetProcessInfo().SetGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 354 } 355 else if (key.compare("euid") == 0) 356 { 357 match_info.GetProcessInfo().SetEffectiveUserID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 358 } 359 else if (key.compare("egid") == 0) 360 { 361 match_info.GetProcessInfo().SetEffectiveGroupID (StringConvert::ToUInt32(value.c_str(), UINT32_MAX, 0, &success)); 362 } 363 else if (key.compare("all_users") == 0) 364 { 365 match_info.SetMatchAllUsers(Args::StringToBoolean(value.c_str(), false, &success)); 366 } 367 else if (key.compare("triple") == 0) 368 { 369 match_info.GetProcessInfo().GetArchitecture().SetTriple (value.c_str(), NULL); 370 } 371 else 372 { 373 success = false; 374 } 375 376 if (!success) 377 return SendErrorResponse (2); 378 } 379 } 380 381 if (Host::FindProcesses (match_info, m_proc_infos)) 382 { 383 // We found something, return the first item by calling the get 384 // subsequent process info packet handler... 385 return Handle_qsProcessInfo (packet); 386 } 387 return SendErrorResponse (3); 388 } 389 390 GDBRemoteCommunication::PacketResult 391 GDBRemoteCommunicationServerCommon::Handle_qsProcessInfo (StringExtractorGDBRemote &packet) 392 { 393 if (m_proc_infos_index < m_proc_infos.GetSize()) 394 { 395 StreamString response; 396 CreateProcessInfoResponse (m_proc_infos.GetProcessInfoAtIndex(m_proc_infos_index), response); 397 ++m_proc_infos_index; 398 return SendPacketNoLock (response.GetData(), response.GetSize()); 399 } 400 return SendErrorResponse (4); 401 } 402 403 GDBRemoteCommunication::PacketResult 404 GDBRemoteCommunicationServerCommon::Handle_qUserName (StringExtractorGDBRemote &packet) 405 { 406 #if !defined(LLDB_DISABLE_POSIX) 407 Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); 408 if (log) 409 log->Printf("GDBRemoteCommunicationServerCommon::%s begin", __FUNCTION__); 410 411 // Packet format: "qUserName:%i" where %i is the uid 412 packet.SetFilePos(::strlen ("qUserName:")); 413 uint32_t uid = packet.GetU32 (UINT32_MAX); 414 if (uid != UINT32_MAX) 415 { 416 std::string name; 417 if (HostInfo::LookupUserName(uid, name)) 418 { 419 StreamString response; 420 response.PutCStringAsRawHex8 (name.c_str()); 421 return SendPacketNoLock (response.GetData(), response.GetSize()); 422 } 423 } 424 if (log) 425 log->Printf("GDBRemoteCommunicationServerCommon::%s end", __FUNCTION__); 426 #endif 427 return SendErrorResponse (5); 428 429 } 430 431 GDBRemoteCommunication::PacketResult 432 GDBRemoteCommunicationServerCommon::Handle_qGroupName (StringExtractorGDBRemote &packet) 433 { 434 #if !defined(LLDB_DISABLE_POSIX) 435 // Packet format: "qGroupName:%i" where %i is the gid 436 packet.SetFilePos(::strlen ("qGroupName:")); 437 uint32_t gid = packet.GetU32 (UINT32_MAX); 438 if (gid != UINT32_MAX) 439 { 440 std::string name; 441 if (HostInfo::LookupGroupName(gid, name)) 442 { 443 StreamString response; 444 response.PutCStringAsRawHex8 (name.c_str()); 445 return SendPacketNoLock (response.GetData(), response.GetSize()); 446 } 447 } 448 #endif 449 return SendErrorResponse (6); 450 } 451 452 GDBRemoteCommunication::PacketResult 453 GDBRemoteCommunicationServerCommon::Handle_qSpeedTest (StringExtractorGDBRemote &packet) 454 { 455 packet.SetFilePos(::strlen ("qSpeedTest:")); 456 457 std::string key; 458 std::string value; 459 bool success = packet.GetNameColonValue(key, value); 460 if (success && key.compare("response_size") == 0) 461 { 462 uint32_t response_size = StringConvert::ToUInt32(value.c_str(), 0, 0, &success); 463 if (success) 464 { 465 if (response_size == 0) 466 return SendOKResponse(); 467 StreamString response; 468 uint32_t bytes_left = response_size; 469 response.PutCString("data:"); 470 while (bytes_left > 0) 471 { 472 if (bytes_left >= 26) 473 { 474 response.PutCString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 475 bytes_left -= 26; 476 } 477 else 478 { 479 response.Printf ("%*.*s;", bytes_left, bytes_left, "ABCDEFGHIJKLMNOPQRSTUVWXYZ"); 480 bytes_left = 0; 481 } 482 } 483 return SendPacketNoLock (response.GetData(), response.GetSize()); 484 } 485 } 486 return SendErrorResponse (7); 487 } 488 489 GDBRemoteCommunication::PacketResult 490 GDBRemoteCommunicationServerCommon::Handle_vFile_Open (StringExtractorGDBRemote &packet) 491 { 492 packet.SetFilePos(::strlen("vFile:open:")); 493 std::string path; 494 packet.GetHexByteStringTerminatedBy(path,','); 495 if (!path.empty()) 496 { 497 if (packet.GetChar() == ',') 498 { 499 uint32_t flags = File::ConvertOpenOptionsForPOSIXOpen( 500 packet.GetHexMaxU32(false, 0)); 501 if (packet.GetChar() == ',') 502 { 503 mode_t mode = packet.GetHexMaxU32(false, 0600); 504 Error error; 505 const FileSpec path_spec{path, true}; 506 int fd = ::open(path_spec.GetCString(), flags, mode); 507 const int save_errno = fd == -1 ? errno : 0; 508 StreamString response; 509 response.PutChar('F'); 510 response.Printf("%i", fd); 511 if (save_errno) 512 response.Printf(",%i", save_errno); 513 return SendPacketNoLock(response.GetData(), response.GetSize()); 514 } 515 } 516 } 517 return SendErrorResponse(18); 518 } 519 520 GDBRemoteCommunication::PacketResult 521 GDBRemoteCommunicationServerCommon::Handle_vFile_Close (StringExtractorGDBRemote &packet) 522 { 523 packet.SetFilePos(::strlen("vFile:close:")); 524 int fd = packet.GetS32(-1); 525 Error error; 526 int err = -1; 527 int save_errno = 0; 528 if (fd >= 0) 529 { 530 err = close(fd); 531 save_errno = err == -1 ? errno : 0; 532 } 533 else 534 { 535 save_errno = EINVAL; 536 } 537 StreamString response; 538 response.PutChar('F'); 539 response.Printf("%i", err); 540 if (save_errno) 541 response.Printf(",%i", save_errno); 542 return SendPacketNoLock(response.GetData(), response.GetSize()); 543 } 544 545 GDBRemoteCommunication::PacketResult 546 GDBRemoteCommunicationServerCommon::Handle_vFile_pRead (StringExtractorGDBRemote &packet) 547 { 548 #ifdef _WIN32 549 // Not implemented on Windows 550 return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pRead() unimplemented"); 551 #else 552 StreamGDBRemote response; 553 packet.SetFilePos(::strlen("vFile:pread:")); 554 int fd = packet.GetS32(-1); 555 if (packet.GetChar() == ',') 556 { 557 uint64_t count = packet.GetU64(UINT64_MAX); 558 if (packet.GetChar() == ',') 559 { 560 uint64_t offset = packet.GetU64(UINT32_MAX); 561 if (count == UINT64_MAX) 562 { 563 response.Printf("F-1:%i", EINVAL); 564 return SendPacketNoLock(response.GetData(), response.GetSize()); 565 } 566 567 std::string buffer(count, 0); 568 const ssize_t bytes_read = ::pread (fd, &buffer[0], buffer.size(), offset); 569 const int save_errno = bytes_read == -1 ? errno : 0; 570 response.PutChar('F'); 571 response.Printf("%zi", bytes_read); 572 if (save_errno) 573 response.Printf(",%i", save_errno); 574 else 575 { 576 response.PutChar(';'); 577 response.PutEscapedBytes(&buffer[0], bytes_read); 578 } 579 return SendPacketNoLock(response.GetData(), response.GetSize()); 580 } 581 } 582 return SendErrorResponse(21); 583 584 #endif 585 } 586 587 GDBRemoteCommunication::PacketResult 588 GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite (StringExtractorGDBRemote &packet) 589 { 590 #ifdef _WIN32 591 return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_pWrite() unimplemented"); 592 #else 593 packet.SetFilePos(::strlen("vFile:pwrite:")); 594 595 StreamGDBRemote response; 596 response.PutChar('F'); 597 598 int fd = packet.GetU32(UINT32_MAX); 599 if (packet.GetChar() == ',') 600 { 601 off_t offset = packet.GetU64(UINT32_MAX); 602 if (packet.GetChar() == ',') 603 { 604 std::string buffer; 605 if (packet.GetEscapedBinaryData(buffer)) 606 { 607 const ssize_t bytes_written = ::pwrite (fd, buffer.data(), buffer.size(), offset); 608 const int save_errno = bytes_written == -1 ? errno : 0; 609 response.Printf("%zi", bytes_written); 610 if (save_errno) 611 response.Printf(",%i", save_errno); 612 } 613 else 614 { 615 response.Printf ("-1,%i", EINVAL); 616 } 617 return SendPacketNoLock(response.GetData(), response.GetSize()); 618 } 619 } 620 return SendErrorResponse(27); 621 #endif 622 } 623 624 GDBRemoteCommunication::PacketResult 625 GDBRemoteCommunicationServerCommon::Handle_vFile_Size (StringExtractorGDBRemote &packet) 626 { 627 packet.SetFilePos(::strlen("vFile:size:")); 628 std::string path; 629 packet.GetHexByteString(path); 630 if (!path.empty()) 631 { 632 lldb::user_id_t retcode = FileSystem::GetFileSize(FileSpec(path.c_str(), false)); 633 StreamString response; 634 response.PutChar('F'); 635 response.PutHex64(retcode); 636 if (retcode == UINT64_MAX) 637 { 638 response.PutChar(','); 639 response.PutHex64(retcode); // TODO: replace with Host::GetSyswideErrorCode() 640 } 641 return SendPacketNoLock(response.GetData(), response.GetSize()); 642 } 643 return SendErrorResponse(22); 644 } 645 646 GDBRemoteCommunication::PacketResult 647 GDBRemoteCommunicationServerCommon::Handle_vFile_Mode (StringExtractorGDBRemote &packet) 648 { 649 packet.SetFilePos(::strlen("vFile:mode:")); 650 std::string path; 651 packet.GetHexByteString(path); 652 if (!path.empty()) 653 { 654 Error error; 655 const uint32_t mode = File::GetPermissions(FileSpec{path, true}, error); 656 StreamString response; 657 response.Printf("F%u", mode); 658 if (mode == 0 || error.Fail()) 659 response.Printf(",%i", (int)error.GetError()); 660 return SendPacketNoLock(response.GetData(), response.GetSize()); 661 } 662 return SendErrorResponse(23); 663 } 664 665 GDBRemoteCommunication::PacketResult 666 GDBRemoteCommunicationServerCommon::Handle_vFile_Exists (StringExtractorGDBRemote &packet) 667 { 668 packet.SetFilePos(::strlen("vFile:exists:")); 669 std::string path; 670 packet.GetHexByteString(path); 671 if (!path.empty()) 672 { 673 bool retcode = FileSystem::GetFileExists(FileSpec(path.c_str(), false)); 674 StreamString response; 675 response.PutChar('F'); 676 response.PutChar(','); 677 if (retcode) 678 response.PutChar('1'); 679 else 680 response.PutChar('0'); 681 return SendPacketNoLock(response.GetData(), response.GetSize()); 682 } 683 return SendErrorResponse(24); 684 } 685 686 GDBRemoteCommunication::PacketResult 687 GDBRemoteCommunicationServerCommon::Handle_vFile_symlink (StringExtractorGDBRemote &packet) 688 { 689 packet.SetFilePos(::strlen("vFile:symlink:")); 690 std::string dst, src; 691 packet.GetHexByteStringTerminatedBy(dst, ','); 692 packet.GetChar(); // Skip ',' char 693 packet.GetHexByteString(src); 694 Error error = FileSystem::Symlink(FileSpec{src, true}, FileSpec{dst, false}); 695 StreamString response; 696 response.Printf("F%u,%u", error.GetError(), error.GetError()); 697 return SendPacketNoLock(response.GetData(), response.GetSize()); 698 } 699 700 GDBRemoteCommunication::PacketResult 701 GDBRemoteCommunicationServerCommon::Handle_vFile_unlink (StringExtractorGDBRemote &packet) 702 { 703 packet.SetFilePos(::strlen("vFile:unlink:")); 704 std::string path; 705 packet.GetHexByteString(path); 706 Error error = FileSystem::Unlink(FileSpec{path, true}); 707 StreamString response; 708 response.Printf("F%u,%u", error.GetError(), error.GetError()); 709 return SendPacketNoLock(response.GetData(), response.GetSize()); 710 } 711 712 GDBRemoteCommunication::PacketResult 713 GDBRemoteCommunicationServerCommon::Handle_qPlatform_shell (StringExtractorGDBRemote &packet) 714 { 715 packet.SetFilePos(::strlen("qPlatform_shell:")); 716 std::string path; 717 std::string working_dir; 718 packet.GetHexByteStringTerminatedBy(path,','); 719 if (!path.empty()) 720 { 721 if (packet.GetChar() == ',') 722 { 723 // FIXME: add timeout to qPlatform_shell packet 724 // uint32_t timeout = packet.GetHexMaxU32(false, 32); 725 uint32_t timeout = 10; 726 if (packet.GetChar() == ',') 727 packet.GetHexByteString(working_dir); 728 int status, signo; 729 std::string output; 730 Error err = Host::RunShellCommand(path.c_str(), 731 FileSpec{working_dir, true}, 732 &status, &signo, &output, timeout); 733 StreamGDBRemote response; 734 if (err.Fail()) 735 { 736 response.PutCString("F,"); 737 response.PutHex32(UINT32_MAX); 738 } 739 else 740 { 741 response.PutCString("F,"); 742 response.PutHex32(status); 743 response.PutChar(','); 744 response.PutHex32(signo); 745 response.PutChar(','); 746 response.PutEscapedBytes(output.c_str(), output.size()); 747 } 748 return SendPacketNoLock(response.GetData(), response.GetSize()); 749 } 750 } 751 return SendErrorResponse(24); 752 } 753 754 755 GDBRemoteCommunication::PacketResult 756 GDBRemoteCommunicationServerCommon::Handle_vFile_Stat (StringExtractorGDBRemote &packet) 757 { 758 return SendUnimplementedResponse("GDBRemoteCommunicationServerCommon::Handle_vFile_Stat() unimplemented"); 759 } 760 761 GDBRemoteCommunication::PacketResult 762 GDBRemoteCommunicationServerCommon::Handle_vFile_MD5 (StringExtractorGDBRemote &packet) 763 { 764 packet.SetFilePos(::strlen("vFile:MD5:")); 765 std::string path; 766 packet.GetHexByteString(path); 767 if (!path.empty()) 768 { 769 uint64_t a,b; 770 StreamGDBRemote response; 771 if (!FileSystem::CalculateMD5(FileSpec(path.c_str(), false), a, b)) 772 { 773 response.PutCString("F,"); 774 response.PutCString("x"); 775 } 776 else 777 { 778 response.PutCString("F,"); 779 response.PutHex64(a); 780 response.PutHex64(b); 781 } 782 return SendPacketNoLock(response.GetData(), response.GetSize()); 783 } 784 return SendErrorResponse(25); 785 } 786 787 GDBRemoteCommunication::PacketResult 788 GDBRemoteCommunicationServerCommon::Handle_qPlatform_mkdir (StringExtractorGDBRemote &packet) 789 { 790 packet.SetFilePos(::strlen("qPlatform_mkdir:")); 791 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 792 if (packet.GetChar() == ',') 793 { 794 std::string path; 795 packet.GetHexByteString(path); 796 Error error = FileSystem::MakeDirectory(FileSpec{path, false}, mode); 797 798 StreamGDBRemote response; 799 response.Printf("F%u", error.GetError()); 800 801 return SendPacketNoLock(response.GetData(), response.GetSize()); 802 } 803 return SendErrorResponse(20); 804 } 805 806 GDBRemoteCommunication::PacketResult 807 GDBRemoteCommunicationServerCommon::Handle_qPlatform_chmod (StringExtractorGDBRemote &packet) 808 { 809 packet.SetFilePos(::strlen("qPlatform_chmod:")); 810 811 mode_t mode = packet.GetHexMaxU32(false, UINT32_MAX); 812 if (packet.GetChar() == ',') 813 { 814 std::string path; 815 packet.GetHexByteString(path); 816 Error error = FileSystem::SetFilePermissions(FileSpec{path, true}, mode); 817 818 StreamGDBRemote response; 819 response.Printf("F%u", error.GetError()); 820 821 return SendPacketNoLock(response.GetData(), response.GetSize()); 822 } 823 return SendErrorResponse(19); 824 } 825 826 GDBRemoteCommunication::PacketResult 827 GDBRemoteCommunicationServerCommon::Handle_qSupported (StringExtractorGDBRemote &packet) 828 { 829 StreamGDBRemote response; 830 831 // Features common to lldb-platform and llgs. 832 uint32_t max_packet_size = 128 * 1024; // 128KBytes is a reasonable max packet size--debugger can always use less 833 response.Printf ("PacketSize=%x", max_packet_size); 834 835 response.PutCString (";QStartNoAckMode+"); 836 response.PutCString (";QThreadSuffixSupported+"); 837 response.PutCString (";QListThreadsInStopReply+"); 838 response.PutCString (";qEcho+"); 839 #if defined(__linux__) 840 response.PutCString (";qXfer:auxv:read+"); 841 #endif 842 843 return SendPacketNoLock(response.GetData(), response.GetSize()); 844 } 845 846 GDBRemoteCommunication::PacketResult 847 GDBRemoteCommunicationServerCommon::Handle_QThreadSuffixSupported (StringExtractorGDBRemote &packet) 848 { 849 m_thread_suffix_supported = true; 850 return SendOKResponse(); 851 } 852 853 GDBRemoteCommunication::PacketResult 854 GDBRemoteCommunicationServerCommon::Handle_QListThreadsInStopReply (StringExtractorGDBRemote &packet) 855 { 856 m_list_threads_in_stop_reply = true; 857 return SendOKResponse(); 858 } 859 860 GDBRemoteCommunication::PacketResult 861 GDBRemoteCommunicationServerCommon::Handle_QSetDetachOnError (StringExtractorGDBRemote &packet) 862 { 863 packet.SetFilePos(::strlen ("QSetDetachOnError:")); 864 if (packet.GetU32(0)) 865 m_process_launch_info.GetFlags().Set (eLaunchFlagDetachOnError); 866 else 867 m_process_launch_info.GetFlags().Clear (eLaunchFlagDetachOnError); 868 return SendOKResponse (); 869 } 870 871 GDBRemoteCommunication::PacketResult 872 GDBRemoteCommunicationServerCommon::Handle_QStartNoAckMode (StringExtractorGDBRemote &packet) 873 { 874 // Send response first before changing m_send_acks to we ack this packet 875 PacketResult packet_result = SendOKResponse (); 876 m_send_acks = false; 877 return packet_result; 878 } 879 880 GDBRemoteCommunication::PacketResult 881 GDBRemoteCommunicationServerCommon::Handle_QSetSTDIN (StringExtractorGDBRemote &packet) 882 { 883 packet.SetFilePos(::strlen ("QSetSTDIN:")); 884 FileAction file_action; 885 std::string path; 886 packet.GetHexByteString(path); 887 const bool read = false; 888 const bool write = true; 889 if (file_action.Open(STDIN_FILENO, FileSpec{path, false}, read, write)) 890 { 891 m_process_launch_info.AppendFileAction(file_action); 892 return SendOKResponse (); 893 } 894 return SendErrorResponse (15); 895 } 896 897 GDBRemoteCommunication::PacketResult 898 GDBRemoteCommunicationServerCommon::Handle_QSetSTDOUT (StringExtractorGDBRemote &packet) 899 { 900 packet.SetFilePos(::strlen ("QSetSTDOUT:")); 901 FileAction file_action; 902 std::string path; 903 packet.GetHexByteString(path); 904 const bool read = true; 905 const bool write = false; 906 if (file_action.Open(STDOUT_FILENO, FileSpec{path, false}, read, write)) 907 { 908 m_process_launch_info.AppendFileAction(file_action); 909 return SendOKResponse (); 910 } 911 return SendErrorResponse (16); 912 } 913 914 GDBRemoteCommunication::PacketResult 915 GDBRemoteCommunicationServerCommon::Handle_QSetSTDERR (StringExtractorGDBRemote &packet) 916 { 917 packet.SetFilePos(::strlen ("QSetSTDERR:")); 918 FileAction file_action; 919 std::string path; 920 packet.GetHexByteString(path); 921 const bool read = true; 922 const bool write = false; 923 if (file_action.Open(STDERR_FILENO, FileSpec{path, false}, read, write)) 924 { 925 m_process_launch_info.AppendFileAction(file_action); 926 return SendOKResponse (); 927 } 928 return SendErrorResponse (17); 929 } 930 931 GDBRemoteCommunication::PacketResult 932 GDBRemoteCommunicationServerCommon::Handle_qLaunchSuccess (StringExtractorGDBRemote &packet) 933 { 934 if (m_process_launch_error.Success()) 935 return SendOKResponse(); 936 StreamString response; 937 response.PutChar('E'); 938 response.PutCString(m_process_launch_error.AsCString("<unknown error>")); 939 return SendPacketNoLock (response.GetData(), response.GetSize()); 940 } 941 942 GDBRemoteCommunication::PacketResult 943 GDBRemoteCommunicationServerCommon::Handle_QEnvironment (StringExtractorGDBRemote &packet) 944 { 945 packet.SetFilePos(::strlen ("QEnvironment:")); 946 const uint32_t bytes_left = packet.GetBytesLeft(); 947 if (bytes_left > 0) 948 { 949 m_process_launch_info.GetEnvironmentEntries ().AppendArgument (packet.Peek()); 950 return SendOKResponse (); 951 } 952 return SendErrorResponse (12); 953 } 954 955 GDBRemoteCommunication::PacketResult 956 GDBRemoteCommunicationServerCommon::Handle_QEnvironmentHexEncoded (StringExtractorGDBRemote &packet) 957 { 958 packet.SetFilePos(::strlen("QEnvironmentHexEncoded:")); 959 const uint32_t bytes_left = packet.GetBytesLeft(); 960 if (bytes_left > 0) 961 { 962 std::string str; 963 packet.GetHexByteString(str); 964 m_process_launch_info.GetEnvironmentEntries().AppendArgument(str.c_str()); 965 return SendOKResponse(); 966 } 967 return SendErrorResponse(12); 968 } 969 970 GDBRemoteCommunication::PacketResult 971 GDBRemoteCommunicationServerCommon::Handle_QLaunchArch (StringExtractorGDBRemote &packet) 972 { 973 packet.SetFilePos(::strlen ("QLaunchArch:")); 974 const uint32_t bytes_left = packet.GetBytesLeft(); 975 if (bytes_left > 0) 976 { 977 const char* arch_triple = packet.Peek(); 978 ArchSpec arch_spec(arch_triple,NULL); 979 m_process_launch_info.SetArchitecture(arch_spec); 980 return SendOKResponse(); 981 } 982 return SendErrorResponse(13); 983 } 984 985 GDBRemoteCommunication::PacketResult 986 GDBRemoteCommunicationServerCommon::Handle_A (StringExtractorGDBRemote &packet) 987 { 988 // The 'A' packet is the most over designed packet ever here with 989 // redundant argument indexes, redundant argument lengths and needed hex 990 // encoded argument string values. Really all that is needed is a comma 991 // separated hex encoded argument value list, but we will stay true to the 992 // documented version of the 'A' packet here... 993 994 Log *log (GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); 995 int actual_arg_index = 0; 996 997 packet.SetFilePos(1); // Skip the 'A' 998 bool success = true; 999 while (success && packet.GetBytesLeft() > 0) 1000 { 1001 // Decode the decimal argument string length. This length is the 1002 // number of hex nibbles in the argument string value. 1003 const uint32_t arg_len = packet.GetU32(UINT32_MAX); 1004 if (arg_len == UINT32_MAX) 1005 success = false; 1006 else 1007 { 1008 // Make sure the argument hex string length is followed by a comma 1009 if (packet.GetChar() != ',') 1010 success = false; 1011 else 1012 { 1013 // Decode the argument index. We ignore this really because 1014 // who would really send down the arguments in a random order??? 1015 const uint32_t arg_idx = packet.GetU32(UINT32_MAX); 1016 if (arg_idx == UINT32_MAX) 1017 success = false; 1018 else 1019 { 1020 // Make sure the argument index is followed by a comma 1021 if (packet.GetChar() != ',') 1022 success = false; 1023 else 1024 { 1025 // Decode the argument string value from hex bytes 1026 // back into a UTF8 string and make sure the length 1027 // matches the one supplied in the packet 1028 std::string arg; 1029 if (packet.GetHexByteStringFixedLength(arg, arg_len) != (arg_len / 2)) 1030 success = false; 1031 else 1032 { 1033 // If there are any bytes left 1034 if (packet.GetBytesLeft()) 1035 { 1036 if (packet.GetChar() != ',') 1037 success = false; 1038 } 1039 1040 if (success) 1041 { 1042 if (arg_idx == 0) 1043 m_process_launch_info.GetExecutableFile().SetFile(arg.c_str(), false); 1044 m_process_launch_info.GetArguments().AppendArgument(arg.c_str()); 1045 if (log) 1046 log->Printf ("LLGSPacketHandler::%s added arg %d: \"%s\"", __FUNCTION__, actual_arg_index, arg.c_str ()); 1047 ++actual_arg_index; 1048 } 1049 } 1050 } 1051 } 1052 } 1053 } 1054 } 1055 1056 if (success) 1057 { 1058 m_process_launch_error = LaunchProcess (); 1059 if (m_process_launch_info.GetProcessID() != LLDB_INVALID_PROCESS_ID) 1060 { 1061 return SendOKResponse (); 1062 } 1063 else 1064 { 1065 Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_PROCESS)); 1066 if (log) 1067 log->Printf("LLGSPacketHandler::%s failed to launch exe: %s", 1068 __FUNCTION__, 1069 m_process_launch_error.AsCString()); 1070 1071 } 1072 } 1073 return SendErrorResponse (8); 1074 } 1075 1076 GDBRemoteCommunication::PacketResult 1077 GDBRemoteCommunicationServerCommon::Handle_qEcho (StringExtractorGDBRemote &packet) 1078 { 1079 // Just echo back the exact same packet for qEcho... 1080 return SendPacketNoLock(packet.GetStringRef().c_str(), packet.GetStringRef().size()); 1081 } 1082 1083 GDBRemoteCommunication::PacketResult 1084 GDBRemoteCommunicationServerCommon::Handle_qModuleInfo (StringExtractorGDBRemote &packet) 1085 { 1086 packet.SetFilePos(::strlen ("qModuleInfo:")); 1087 1088 std::string module_path; 1089 packet.GetHexByteStringTerminatedBy(module_path, ';'); 1090 if (module_path.empty()) 1091 return SendErrorResponse (1); 1092 1093 if (packet.GetChar() != ';') 1094 return SendErrorResponse (2); 1095 1096 std::string triple; 1097 packet.GetHexByteString(triple); 1098 ArchSpec arch(triple.c_str()); 1099 1100 const FileSpec req_module_path_spec(module_path.c_str(), true); 1101 const FileSpec module_path_spec = FindModuleFile(req_module_path_spec.GetPath(), arch); 1102 const ModuleSpec module_spec(module_path_spec, arch); 1103 1104 ModuleSpecList module_specs; 1105 if (!ObjectFile::GetModuleSpecifications(module_path_spec, 0, 0, module_specs)) 1106 return SendErrorResponse (3); 1107 1108 ModuleSpec matched_module_spec; 1109 if (!module_specs.FindMatchingModuleSpec(module_spec, matched_module_spec)) 1110 return SendErrorResponse (4); 1111 1112 const auto file_offset = matched_module_spec.GetObjectOffset(); 1113 const auto file_size = matched_module_spec.GetObjectSize(); 1114 const auto uuid_str = matched_module_spec.GetUUID().GetAsString(""); 1115 1116 StreamGDBRemote response; 1117 1118 if (uuid_str.empty()) 1119 { 1120 std::string md5_hash; 1121 if (!FileSystem::CalculateMD5AsString(matched_module_spec.GetFileSpec(), file_offset, file_size, md5_hash)) 1122 return SendErrorResponse (5); 1123 response.PutCString ("md5:"); 1124 response.PutCStringAsRawHex8(md5_hash.c_str()); 1125 } 1126 else{ 1127 response.PutCString ("uuid:"); 1128 response.PutCStringAsRawHex8(uuid_str.c_str()); 1129 } 1130 response.PutChar(';'); 1131 1132 const auto &module_arch = matched_module_spec.GetArchitecture(); 1133 response.PutCString("triple:"); 1134 response.PutCStringAsRawHex8( module_arch.GetTriple().getTriple().c_str()); 1135 response.PutChar(';'); 1136 1137 response.PutCString("file_path:"); 1138 response.PutCStringAsRawHex8(module_path_spec.GetCString()); 1139 response.PutChar(';'); 1140 response.PutCString("file_offset:"); 1141 response.PutHex64(file_offset); 1142 response.PutChar(';'); 1143 response.PutCString("file_size:"); 1144 response.PutHex64(file_size); 1145 response.PutChar(';'); 1146 1147 return SendPacketNoLock(response.GetData(), response.GetSize()); 1148 } 1149 1150 void 1151 GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse (const ProcessInstanceInfo &proc_info, 1152 StreamString &response) 1153 { 1154 response.Printf ("pid:%" PRIu64 ";ppid:%" PRIu64 ";uid:%i;gid:%i;euid:%i;egid:%i;", 1155 proc_info.GetProcessID(), 1156 proc_info.GetParentProcessID(), 1157 proc_info.GetUserID(), 1158 proc_info.GetGroupID(), 1159 proc_info.GetEffectiveUserID(), 1160 proc_info.GetEffectiveGroupID()); 1161 response.PutCString ("name:"); 1162 response.PutCStringAsRawHex8(proc_info.GetExecutableFile().GetCString()); 1163 response.PutChar(';'); 1164 const ArchSpec &proc_arch = proc_info.GetArchitecture(); 1165 if (proc_arch.IsValid()) 1166 { 1167 const llvm::Triple &proc_triple = proc_arch.GetTriple(); 1168 response.PutCString("triple:"); 1169 response.PutCStringAsRawHex8(proc_triple.getTriple().c_str()); 1170 response.PutChar(';'); 1171 } 1172 } 1173 1174 void 1175 GDBRemoteCommunicationServerCommon::CreateProcessInfoResponse_DebugServerStyle ( 1176 const ProcessInstanceInfo &proc_info, StreamString &response) 1177 { 1178 response.Printf ("pid:%" PRIx64 ";parent-pid:%" PRIx64 ";real-uid:%x;real-gid:%x;effective-uid:%x;effective-gid:%x;", 1179 proc_info.GetProcessID(), 1180 proc_info.GetParentProcessID(), 1181 proc_info.GetUserID(), 1182 proc_info.GetGroupID(), 1183 proc_info.GetEffectiveUserID(), 1184 proc_info.GetEffectiveGroupID()); 1185 1186 const ArchSpec &proc_arch = proc_info.GetArchitecture(); 1187 if (proc_arch.IsValid()) 1188 { 1189 const llvm::Triple &proc_triple = proc_arch.GetTriple(); 1190 #if defined(__APPLE__) 1191 // We'll send cputype/cpusubtype. 1192 const uint32_t cpu_type = proc_arch.GetMachOCPUType(); 1193 if (cpu_type != 0) 1194 response.Printf ("cputype:%" PRIx32 ";", cpu_type); 1195 1196 const uint32_t cpu_subtype = proc_arch.GetMachOCPUSubType(); 1197 if (cpu_subtype != 0) 1198 response.Printf ("cpusubtype:%" PRIx32 ";", cpu_subtype); 1199 1200 const std::string vendor = proc_triple.getVendorName (); 1201 if (!vendor.empty ()) 1202 response.Printf ("vendor:%s;", vendor.c_str ()); 1203 #else 1204 // We'll send the triple. 1205 response.PutCString("triple:"); 1206 response.PutCStringAsRawHex8(proc_triple.getTriple().c_str()); 1207 response.PutChar(';'); 1208 #endif 1209 std::string ostype = proc_triple.getOSName (); 1210 // Adjust so ostype reports ios for Apple/ARM and Apple/ARM64. 1211 if (proc_triple.getVendor () == llvm::Triple::Apple) 1212 { 1213 switch (proc_triple.getArch ()) 1214 { 1215 case llvm::Triple::arm: 1216 case llvm::Triple::thumb: 1217 case llvm::Triple::aarch64: 1218 ostype = "ios"; 1219 break; 1220 default: 1221 // No change. 1222 break; 1223 } 1224 } 1225 response.Printf ("ostype:%s;", ostype.c_str ()); 1226 1227 1228 switch (proc_arch.GetByteOrder ()) 1229 { 1230 case lldb::eByteOrderLittle: response.PutCString ("endian:little;"); break; 1231 case lldb::eByteOrderBig: response.PutCString ("endian:big;"); break; 1232 case lldb::eByteOrderPDP: response.PutCString ("endian:pdp;"); break; 1233 default: 1234 // Nothing. 1235 break; 1236 } 1237 1238 if (proc_triple.isArch64Bit ()) 1239 response.PutCString ("ptrsize:8;"); 1240 else if (proc_triple.isArch32Bit ()) 1241 response.PutCString ("ptrsize:4;"); 1242 else if (proc_triple.isArch16Bit ()) 1243 response.PutCString ("ptrsize:2;"); 1244 } 1245 } 1246 1247 FileSpec 1248 GDBRemoteCommunicationServerCommon::FindModuleFile(const std::string& module_path, 1249 const ArchSpec& arch) 1250 { 1251 #ifdef __ANDROID__ 1252 return HostInfoAndroid::ResolveLibraryPath(module_path, arch); 1253 #else 1254 return FileSpec(module_path.c_str(), true); 1255 #endif 1256 } 1257