|
31 | 31 | #include "lldb/Target/MemoryRegionInfo.h" |
32 | 32 | #include "lldb/Utility/Args.h" |
33 | 33 | #include "lldb/Utility/DataBuffer.h" |
34 | | -#include "lldb/Utility/DataExtractor.h" |
35 | 34 | #include "lldb/Utility/Endian.h" |
36 | 35 | #include "lldb/Utility/LLDBAssert.h" |
37 | 36 | #include "lldb/Utility/Log.h" |
@@ -563,119 +562,6 @@ GetRegistersAsJSON(NativeThreadProtocol &thread) { |
563 | 562 | return register_object; |
564 | 563 | } |
565 | 564 |
|
566 | | -static llvm::Optional<RegisterValue> |
567 | | -GetRegisterValue(NativeRegisterContext ®_ctx, uint32_t generic_regnum) { |
568 | | - Log *log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_THREAD)); |
569 | | - uint32_t reg_num = reg_ctx.ConvertRegisterKindToRegisterNumber( |
570 | | - eRegisterKindGeneric, generic_regnum); |
571 | | - const RegisterInfo *const reg_info_p = |
572 | | - reg_ctx.GetRegisterInfoAtIndex(reg_num); |
573 | | - |
574 | | - if (reg_info_p == nullptr || reg_info_p->value_regs != nullptr) { |
575 | | - LLDB_LOGF(log, "%s failed to get register info for register index %" PRIu32, |
576 | | - __FUNCTION__, reg_num); |
577 | | - return {}; |
578 | | - } |
579 | | - |
580 | | - RegisterValue reg_value; |
581 | | - Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); |
582 | | - if (error.Fail()) { |
583 | | - LLDB_LOGF(log, "%s failed to read register '%s' index %" PRIu32 ": %s", |
584 | | - __FUNCTION__, |
585 | | - reg_info_p->name ? reg_info_p->name : "<unnamed-register>", |
586 | | - reg_num, error.AsCString()); |
587 | | - return {}; |
588 | | - } |
589 | | - return reg_value; |
590 | | -} |
591 | | - |
592 | | -static json::Object CreateMemoryChunk(json::Array &stack_memory_chunks, |
593 | | - addr_t address, |
594 | | - std::vector<uint8_t> &bytes) { |
595 | | - json::Object chunk; |
596 | | - chunk.try_emplace("address", static_cast<int64_t>(address)); |
597 | | - StreamString stream; |
598 | | - for (uint8_t b : bytes) |
599 | | - stream.PutHex8(b); |
600 | | - chunk.try_emplace("bytes", stream.GetString().str()); |
601 | | - return chunk; |
602 | | -} |
603 | | - |
604 | | -static json::Array GetStackMemoryAsJSON(NativeProcessProtocol &process, |
605 | | - NativeThreadProtocol &thread) { |
606 | | - uint32_t address_size = process.GetArchitecture().GetAddressByteSize(); |
607 | | - const size_t kStackTopMemoryInfoWordSize = 12; |
608 | | - size_t stack_top_memory_info_byte_size = |
609 | | - kStackTopMemoryInfoWordSize * address_size; |
610 | | - const size_t kMaxStackSize = 128 * 1024; |
611 | | - const size_t kMaxFrameSize = 4 * 1024; |
612 | | - size_t fp_and_ra_size = 2 * address_size; |
613 | | - const size_t kMaxFrameCount = 128; |
614 | | - |
615 | | - NativeRegisterContext ®_ctx = thread.GetRegisterContext(); |
616 | | - |
617 | | - json::Array stack_memory_chunks; |
618 | | - |
619 | | - lldb::addr_t sp_value; |
620 | | - if (llvm::Optional<RegisterValue> optional_sp_value = |
621 | | - GetRegisterValue(reg_ctx, LLDB_REGNUM_GENERIC_SP)) { |
622 | | - sp_value = optional_sp_value->GetAsUInt64(); |
623 | | - } else { |
624 | | - return stack_memory_chunks; |
625 | | - } |
626 | | - lldb::addr_t fp_value; |
627 | | - if (llvm::Optional<RegisterValue> optional_fp_value = |
628 | | - GetRegisterValue(reg_ctx, LLDB_REGNUM_GENERIC_FP)) { |
629 | | - fp_value = optional_fp_value->GetAsUInt64(); |
630 | | - } else { |
631 | | - return stack_memory_chunks; |
632 | | - } |
633 | | - |
634 | | - // First, make sure we copy the top stack_top_memory_info_byte_size bytes |
635 | | - // from the stack. |
636 | | - size_t byte_count = std::min(stack_top_memory_info_byte_size, |
637 | | - static_cast<size_t>(fp_value - sp_value)); |
638 | | - std::vector<uint8_t> buf(byte_count, 0); |
639 | | - |
640 | | - size_t bytes_read = 0; |
641 | | - Status error = process.ReadMemoryWithoutTrap(sp_value, buf.data(), byte_count, |
642 | | - bytes_read); |
643 | | - if (error.Success() && bytes_read > 0) { |
644 | | - buf.resize(bytes_read); |
645 | | - stack_memory_chunks.push_back( |
646 | | - CreateMemoryChunk(stack_memory_chunks, sp_value, buf)); |
647 | | - } |
648 | | - |
649 | | - // Additionally, try to walk the frame pointer link chain. If the frame |
650 | | - // is too big or if the frame pointer points too far, stop the walk. |
651 | | - addr_t max_frame_pointer = sp_value + kMaxStackSize; |
652 | | - for (size_t i = 0; i < kMaxFrameCount; i++) { |
653 | | - if (fp_value < sp_value || fp_value > sp_value + kMaxFrameSize || |
654 | | - fp_value > max_frame_pointer) |
655 | | - break; |
656 | | - |
657 | | - std::vector<uint8_t> fp_ra_buf(fp_and_ra_size, 0); |
658 | | - bytes_read = 0; |
659 | | - error = process.ReadMemoryWithoutTrap(fp_value, fp_ra_buf.data(), |
660 | | - fp_and_ra_size, bytes_read); |
661 | | - if (error.Fail() || bytes_read != fp_and_ra_size) |
662 | | - break; |
663 | | - |
664 | | - stack_memory_chunks.push_back( |
665 | | - CreateMemoryChunk(stack_memory_chunks, fp_value, fp_ra_buf)); |
666 | | - |
667 | | - // Advance the stack pointer and the frame pointer. |
668 | | - sp_value = fp_value; |
669 | | - lldb_private::DataExtractor extractor( |
670 | | - fp_ra_buf.data(), fp_and_ra_size, |
671 | | - process.GetArchitecture().GetByteOrder(), address_size); |
672 | | - offset_t offset = 0; |
673 | | - fp_value = extractor.GetAddress(&offset); |
674 | | - } |
675 | | - |
676 | | - return stack_memory_chunks; |
677 | | -} |
678 | | - |
679 | 565 | static const char *GetStopReasonString(StopReason stop_reason) { |
680 | 566 | switch (stop_reason) { |
681 | 567 | case eStopReasonTrace: |
@@ -740,9 +626,6 @@ GetJSONThreadsInfo(NativeProcessProtocol &process, bool abridged) { |
740 | 626 | } else { |
741 | 627 | return registers.takeError(); |
742 | 628 | } |
743 | | - json::Array stack_memory = GetStackMemoryAsJSON(process, *thread); |
744 | | - if (!stack_memory.empty()) |
745 | | - thread_obj.try_emplace("memory", std::move(stack_memory)); |
746 | 629 | } |
747 | 630 |
|
748 | 631 | thread_obj.try_emplace("tid", static_cast<int64_t>(tid)); |
@@ -947,7 +830,7 @@ GDBRemoteCommunicationServerLLGS::SendStopReplyPacketForThread( |
947 | 830 | reg_set_p->name ? reg_set_p->name : "<unnamed-set>", |
948 | 831 | *reg_num_p); |
949 | 832 | } else if (reg_info_p->value_regs == nullptr) { |
950 | | - // Only expedite registers that are not contained in other registers. |
| 833 | + // Only expediate registers that are not contained in other registers. |
951 | 834 | RegisterValue reg_value; |
952 | 835 | Status error = reg_ctx.ReadRegister(reg_info_p, reg_value); |
953 | 836 | if (error.Success()) { |
|
0 commit comments