diff options
Diffstat (limited to 'src/core/debugger/gdbstub.cpp')
| -rw-r--r-- | src/core/debugger/gdbstub.cpp | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/src/core/debugger/gdbstub.cpp b/src/core/debugger/gdbstub.cpp index 682651a86..f52d78829 100644 --- a/src/core/debugger/gdbstub.cpp +++ b/src/core/debugger/gdbstub.cpp | |||
| @@ -422,6 +422,18 @@ static std::string GetThreadState(const Kernel::KThread* thread) { | |||
| 422 | } | 422 | } |
| 423 | } | 423 | } |
| 424 | 424 | ||
| 425 | static std::string PaginateBuffer(std::string_view buffer, std::string_view request) { | ||
| 426 | const auto amount{request.substr(request.find(',') + 1)}; | ||
| 427 | const auto offset_val{static_cast<u64>(strtoll(request.data(), nullptr, 16))}; | ||
| 428 | const auto amount_val{static_cast<u64>(strtoll(amount.data(), nullptr, 16))}; | ||
| 429 | |||
| 430 | if (offset_val + amount_val > buffer.size()) { | ||
| 431 | return fmt::format("l{}", buffer.substr(offset_val)); | ||
| 432 | } else { | ||
| 433 | return fmt::format("m{}", buffer.substr(offset_val, amount_val)); | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 425 | void GDBStub::HandleQuery(std::string_view command) { | 437 | void GDBStub::HandleQuery(std::string_view command) { |
| 426 | if (command.starts_with("TStatus")) { | 438 | if (command.starts_with("TStatus")) { |
| 427 | // no tracepoint support | 439 | // no tracepoint support |
| @@ -430,18 +442,8 @@ void GDBStub::HandleQuery(std::string_view command) { | |||
| 430 | SendReply("PacketSize=4000;qXfer:features:read+;qXfer:threads:read+;qXfer:libraries:read+;" | 442 | SendReply("PacketSize=4000;qXfer:features:read+;qXfer:threads:read+;qXfer:libraries:read+;" |
| 431 | "vContSupported+;QStartNoAckMode+"); | 443 | "vContSupported+;QStartNoAckMode+"); |
| 432 | } else if (command.starts_with("Xfer:features:read:target.xml:")) { | 444 | } else if (command.starts_with("Xfer:features:read:target.xml:")) { |
| 433 | const auto offset{command.substr(30)}; | ||
| 434 | const auto amount{command.substr(command.find(',') + 1)}; | ||
| 435 | |||
| 436 | const auto offset_val{static_cast<u64>(strtoll(offset.data(), nullptr, 16))}; | ||
| 437 | const auto amount_val{static_cast<u64>(strtoll(amount.data(), nullptr, 16))}; | ||
| 438 | const auto target_xml{arch->GetTargetXML()}; | 445 | const auto target_xml{arch->GetTargetXML()}; |
| 439 | 446 | SendReply(PaginateBuffer(target_xml, command.substr(30))); | |
| 440 | if (offset_val + amount_val > target_xml.size()) { | ||
| 441 | SendReply("l" + target_xml.substr(offset_val)); | ||
| 442 | } else { | ||
| 443 | SendReply("m" + target_xml.substr(offset_val, amount_val)); | ||
| 444 | } | ||
| 445 | } else if (command.starts_with("Offsets")) { | 447 | } else if (command.starts_with("Offsets")) { |
| 446 | Loader::AppLoader::Modules modules; | 448 | Loader::AppLoader::Modules modules; |
| 447 | system.GetAppLoader().ReadNSOModules(modules); | 449 | system.GetAppLoader().ReadNSOModules(modules); |
| @@ -454,6 +456,20 @@ void GDBStub::HandleQuery(std::string_view command) { | |||
| 454 | SendReply(fmt::format("TextSeg={:x}", | 456 | SendReply(fmt::format("TextSeg={:x}", |
| 455 | system.CurrentProcess()->PageTable().GetCodeRegionStart())); | 457 | system.CurrentProcess()->PageTable().GetCodeRegionStart())); |
| 456 | } | 458 | } |
| 459 | } else if (command.starts_with("Xfer:libraries:read::")) { | ||
| 460 | Loader::AppLoader::Modules modules; | ||
| 461 | system.GetAppLoader().ReadNSOModules(modules); | ||
| 462 | |||
| 463 | std::string buffer; | ||
| 464 | buffer += R"(<?xml version="1.0"?>)"; | ||
| 465 | buffer += "<library-list>"; | ||
| 466 | for (const auto& [base, name] : modules) { | ||
| 467 | buffer += fmt::format(R"(<library name="{}"><segment address="{:#x}"/></library>)", | ||
| 468 | EscapeXML(name), base); | ||
| 469 | } | ||
| 470 | buffer += "</library-list>"; | ||
| 471 | |||
| 472 | SendReply(PaginateBuffer(buffer, command.substr(21))); | ||
| 457 | } else if (command.starts_with("fThreadInfo")) { | 473 | } else if (command.starts_with("fThreadInfo")) { |
| 458 | // beginning of list | 474 | // beginning of list |
| 459 | const auto& threads = system.GlobalSchedulerContext().GetThreadList(); | 475 | const auto& threads = system.GlobalSchedulerContext().GetThreadList(); |
| @@ -484,17 +500,7 @@ void GDBStub::HandleQuery(std::string_view command) { | |||
| 484 | 500 | ||
| 485 | buffer += "</threads>"; | 501 | buffer += "</threads>"; |
| 486 | 502 | ||
| 487 | const auto offset{command.substr(19)}; | 503 | SendReply(PaginateBuffer(buffer, command.substr(19))); |
| 488 | const auto amount{command.substr(command.find(',') + 1)}; | ||
| 489 | |||
| 490 | const auto offset_val{static_cast<u64>(strtoll(offset.data(), nullptr, 16))}; | ||
| 491 | const auto amount_val{static_cast<u64>(strtoll(amount.data(), nullptr, 16))}; | ||
| 492 | |||
| 493 | if (offset_val + amount_val > buffer.size()) { | ||
| 494 | SendReply("l" + buffer.substr(offset_val)); | ||
| 495 | } else { | ||
| 496 | SendReply("m" + buffer.substr(offset_val, amount_val)); | ||
| 497 | } | ||
| 498 | } else if (command.starts_with("Attached")) { | 504 | } else if (command.starts_with("Attached")) { |
| 499 | SendReply("0"); | 505 | SendReply("0"); |
| 500 | } else if (command.starts_with("StartNoAckMode")) { | 506 | } else if (command.starts_with("StartNoAckMode")) { |