|
12 | 12 | #include "Plugins/Process/Utility/RegisterContextDarwin_arm.h"
|
13 | 13 | #include "Plugins/Process/Utility/RegisterContextDarwin_arm64.h"
|
14 | 14 | #include "Plugins/Process/Utility/RegisterContextDarwin_i386.h"
|
| 15 | +#include "Plugins/Process/Utility/RegisterContextDarwin_riscv32.h" |
15 | 16 | #include "Plugins/Process/Utility/RegisterContextDarwin_x86_64.h"
|
16 | 17 | #include "lldb/Core/Debugger.h"
|
17 | 18 | #include "lldb/Core/Module.h"
|
@@ -772,6 +773,147 @@ class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64 {
|
772 | 773 | }
|
773 | 774 | };
|
774 | 775 |
|
| 776 | +class RegisterContextDarwin_riscv32_Mach |
| 777 | + : public RegisterContextDarwin_riscv32 { |
| 778 | +public: |
| 779 | + RegisterContextDarwin_riscv32_Mach(lldb_private::Thread &thread, |
| 780 | + const DataExtractor &data) |
| 781 | + : RegisterContextDarwin_riscv32(thread, 0) { |
| 782 | + SetRegisterDataFrom_LC_THREAD(data); |
| 783 | + } |
| 784 | + |
| 785 | + void InvalidateAllRegisters() override { |
| 786 | + // Do nothing... registers are always valid... |
| 787 | + } |
| 788 | + |
| 789 | + void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) { |
| 790 | + lldb::offset_t offset = 0; |
| 791 | + SetError(GPRRegSet, Read, -1); |
| 792 | + SetError(FPURegSet, Read, -1); |
| 793 | + SetError(EXCRegSet, Read, -1); |
| 794 | + SetError(CSRRegSet, Read, -1); |
| 795 | + bool done = false; |
| 796 | + while (!done) { |
| 797 | + int flavor = data.GetU32(&offset); |
| 798 | + uint32_t count = data.GetU32(&offset); |
| 799 | + lldb::offset_t next_thread_state = offset + (count * 4); |
| 800 | + switch (flavor) { |
| 801 | + case GPRRegSet: |
| 802 | + // x0-x31 + pc |
| 803 | + if (count >= 32) { |
| 804 | + for (uint32_t i = 0; i < 32; ++i) |
| 805 | + ((uint32_t *)&gpr.x0)[i] = data.GetU32(&offset); |
| 806 | + gpr.pc = data.GetU32(&offset); |
| 807 | + SetError(GPRRegSet, Read, 0); |
| 808 | + } |
| 809 | + offset = next_thread_state; |
| 810 | + break; |
| 811 | + case FPURegSet: { |
| 812 | + // f0-f31 + fcsr |
| 813 | + if (count >= 32) { |
| 814 | + for (uint32_t i = 0; i < 32; ++i) |
| 815 | + ((uint32_t *)&fpr.f0)[i] = data.GetU32(&offset); |
| 816 | + fpr.fcsr = data.GetU32(&offset); |
| 817 | + SetError(FPURegSet, Read, 0); |
| 818 | + } |
| 819 | + } |
| 820 | + offset = next_thread_state; |
| 821 | + break; |
| 822 | + case EXCRegSet: |
| 823 | + if (count == 3) { |
| 824 | + exc.exception = data.GetU32(&offset); |
| 825 | + exc.fsr = data.GetU32(&offset); |
| 826 | + exc.far = data.GetU32(&offset); |
| 827 | + SetError(EXCRegSet, Read, 0); |
| 828 | + } |
| 829 | + offset = next_thread_state; |
| 830 | + break; |
| 831 | + default: |
| 832 | + done = true; |
| 833 | + break; |
| 834 | + } |
| 835 | + } |
| 836 | + } |
| 837 | + |
| 838 | + static bool Create_LC_THREAD(Thread *thread, Stream &data) { |
| 839 | + RegisterContextSP reg_ctx_sp(thread->GetRegisterContext()); |
| 840 | + if (reg_ctx_sp) { |
| 841 | + RegisterContext *reg_ctx = reg_ctx_sp.get(); |
| 842 | + |
| 843 | + data.PutHex32(GPRRegSet); // Flavor |
| 844 | + data.PutHex32(GPRWordCount); |
| 845 | + PrintRegisterValue(reg_ctx, "x0", nullptr, 4, data); |
| 846 | + PrintRegisterValue(reg_ctx, "x1", nullptr, 4, data); |
| 847 | + PrintRegisterValue(reg_ctx, "x2", nullptr, 4, data); |
| 848 | + PrintRegisterValue(reg_ctx, "x3", nullptr, 4, data); |
| 849 | + PrintRegisterValue(reg_ctx, "x4", nullptr, 4, data); |
| 850 | + PrintRegisterValue(reg_ctx, "x5", nullptr, 4, data); |
| 851 | + PrintRegisterValue(reg_ctx, "x6", nullptr, 4, data); |
| 852 | + PrintRegisterValue(reg_ctx, "x7", nullptr, 4, data); |
| 853 | + PrintRegisterValue(reg_ctx, "x8", nullptr, 4, data); |
| 854 | + PrintRegisterValue(reg_ctx, "x9", nullptr, 4, data); |
| 855 | + PrintRegisterValue(reg_ctx, "x10", nullptr, 4, data); |
| 856 | + PrintRegisterValue(reg_ctx, "x11", nullptr, 4, data); |
| 857 | + PrintRegisterValue(reg_ctx, "x12", nullptr, 4, data); |
| 858 | + PrintRegisterValue(reg_ctx, "x13", nullptr, 4, data); |
| 859 | + PrintRegisterValue(reg_ctx, "x14", nullptr, 4, data); |
| 860 | + PrintRegisterValue(reg_ctx, "x15", nullptr, 4, data); |
| 861 | + PrintRegisterValue(reg_ctx, "x16", nullptr, 4, data); |
| 862 | + PrintRegisterValue(reg_ctx, "x17", nullptr, 4, data); |
| 863 | + PrintRegisterValue(reg_ctx, "x18", nullptr, 4, data); |
| 864 | + PrintRegisterValue(reg_ctx, "x19", nullptr, 4, data); |
| 865 | + PrintRegisterValue(reg_ctx, "x20", nullptr, 4, data); |
| 866 | + PrintRegisterValue(reg_ctx, "x21", nullptr, 4, data); |
| 867 | + PrintRegisterValue(reg_ctx, "x22", nullptr, 4, data); |
| 868 | + PrintRegisterValue(reg_ctx, "x23", nullptr, 4, data); |
| 869 | + PrintRegisterValue(reg_ctx, "x24", nullptr, 4, data); |
| 870 | + PrintRegisterValue(reg_ctx, "x25", nullptr, 4, data); |
| 871 | + PrintRegisterValue(reg_ctx, "x26", nullptr, 4, data); |
| 872 | + PrintRegisterValue(reg_ctx, "x27", nullptr, 4, data); |
| 873 | + PrintRegisterValue(reg_ctx, "x28", nullptr, 4, data); |
| 874 | + PrintRegisterValue(reg_ctx, "x29", nullptr, 4, data); |
| 875 | + PrintRegisterValue(reg_ctx, "x30", nullptr, 4, data); |
| 876 | + PrintRegisterValue(reg_ctx, "x31", nullptr, 4, data); |
| 877 | + PrintRegisterValue(reg_ctx, "pc", nullptr, 4, data); |
| 878 | + data.PutHex32(0); // uint32_t pad at the end |
| 879 | + |
| 880 | + // Write out the EXC registers |
| 881 | + data.PutHex32(EXCRegSet); |
| 882 | + data.PutHex32(EXCWordCount); |
| 883 | + PrintRegisterValue(reg_ctx, "exception", nullptr, 4, data); |
| 884 | + PrintRegisterValue(reg_ctx, "fsr", nullptr, 4, data); |
| 885 | + PrintRegisterValue(reg_ctx, "far", nullptr, 4, data); |
| 886 | + return true; |
| 887 | + } |
| 888 | + return false; |
| 889 | + } |
| 890 | + |
| 891 | +protected: |
| 892 | + int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; } |
| 893 | + |
| 894 | + int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; } |
| 895 | + |
| 896 | + int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; } |
| 897 | + |
| 898 | + int DoReadCSR(lldb::tid_t tid, int flavor, CSR &csr) override { return -1; } |
| 899 | + |
| 900 | + int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override { |
| 901 | + return 0; |
| 902 | + } |
| 903 | + |
| 904 | + int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override { |
| 905 | + return 0; |
| 906 | + } |
| 907 | + |
| 908 | + int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override { |
| 909 | + return 0; |
| 910 | + } |
| 911 | + |
| 912 | + int DoWriteCSR(lldb::tid_t tid, int flavor, const CSR &csr) override { |
| 913 | + return 0; |
| 914 | + } |
| 915 | +}; |
| 916 | + |
775 | 917 | static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {
|
776 | 918 | switch (magic) {
|
777 | 919 | case MH_MAGIC:
|
@@ -5853,6 +5995,11 @@ ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx,
|
5853 | 5995 | reg_ctx_sp =
|
5854 | 5996 | std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);
|
5855 | 5997 | break;
|
| 5998 | + |
| 5999 | + case llvm::MachO::CPU_TYPE_RISCV: |
| 6000 | + reg_ctx_sp = |
| 6001 | + std::make_shared<RegisterContextDarwin_riscv32_Mach>(thread, data); |
| 6002 | + break; |
5856 | 6003 | }
|
5857 | 6004 | }
|
5858 | 6005 | }
|
@@ -6720,6 +6867,11 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
|
6720 | 6867 | RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(
|
6721 | 6868 | thread_sp.get(), LC_THREAD_datas[thread_idx]);
|
6722 | 6869 | break;
|
| 6870 | + |
| 6871 | + case llvm::MachO::CPU_TYPE_RISCV: |
| 6872 | + RegisterContextDarwin_riscv32_Mach::Create_LC_THREAD( |
| 6873 | + thread_sp.get(), LC_THREAD_datas[thread_idx]); |
| 6874 | + break; |
6723 | 6875 | }
|
6724 | 6876 | }
|
6725 | 6877 | }
|
|
0 commit comments