|
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"
|
@@ -769,6 +770,147 @@ class RegisterContextDarwin_arm64_Mach : public RegisterContextDarwin_arm64 {
|
769 | 770 | }
|
770 | 771 | };
|
771 | 772 |
|
| 773 | +class RegisterContextDarwin_riscv32_Mach |
| 774 | + : public RegisterContextDarwin_riscv32 { |
| 775 | +public: |
| 776 | + RegisterContextDarwin_riscv32_Mach(lldb_private::Thread &thread, |
| 777 | + const DataExtractor &data) |
| 778 | + : RegisterContextDarwin_riscv32(thread, 0) { |
| 779 | + SetRegisterDataFrom_LC_THREAD(data); |
| 780 | + } |
| 781 | + |
| 782 | + void InvalidateAllRegisters() override { |
| 783 | + // Do nothing... registers are always valid... |
| 784 | + } |
| 785 | + |
| 786 | + void SetRegisterDataFrom_LC_THREAD(const DataExtractor &data) { |
| 787 | + lldb::offset_t offset = 0; |
| 788 | + SetError(GPRRegSet, Read, -1); |
| 789 | + SetError(FPURegSet, Read, -1); |
| 790 | + SetError(EXCRegSet, Read, -1); |
| 791 | + SetError(CSRRegSet, Read, -1); |
| 792 | + bool done = false; |
| 793 | + while (!done) { |
| 794 | + int flavor = data.GetU32(&offset); |
| 795 | + uint32_t count = data.GetU32(&offset); |
| 796 | + lldb::offset_t next_thread_state = offset + (count * 4); |
| 797 | + switch (flavor) { |
| 798 | + case GPRRegSet: |
| 799 | + // x0-x31 + pc |
| 800 | + if (count >= 32) { |
| 801 | + for (uint32_t i = 0; i < 32; ++i) |
| 802 | + ((uint32_t *)&gpr.x0)[i] = data.GetU32(&offset); |
| 803 | + gpr.pc = data.GetU32(&offset); |
| 804 | + SetError(GPRRegSet, Read, 0); |
| 805 | + } |
| 806 | + offset = next_thread_state; |
| 807 | + break; |
| 808 | + case FPURegSet: { |
| 809 | + // f0-f31 + fcsr |
| 810 | + if (count >= 32) { |
| 811 | + for (uint32_t i = 0; i < 32; ++i) |
| 812 | + ((uint32_t *)&fpr.f0)[i] = data.GetU32(&offset); |
| 813 | + fpr.fcsr = data.GetU32(&offset); |
| 814 | + SetError(FPURegSet, Read, 0); |
| 815 | + } |
| 816 | + } |
| 817 | + offset = next_thread_state; |
| 818 | + break; |
| 819 | + case EXCRegSet: |
| 820 | + if (count == 3) { |
| 821 | + exc.exception = data.GetU32(&offset); |
| 822 | + exc.fsr = data.GetU32(&offset); |
| 823 | + exc.far = data.GetU32(&offset); |
| 824 | + SetError(EXCRegSet, Read, 0); |
| 825 | + } |
| 826 | + offset = next_thread_state; |
| 827 | + break; |
| 828 | + default: |
| 829 | + done = true; |
| 830 | + break; |
| 831 | + } |
| 832 | + } |
| 833 | + } |
| 834 | + |
| 835 | + static bool Create_LC_THREAD(Thread *thread, Stream &data) { |
| 836 | + RegisterContextSP reg_ctx_sp(thread->GetRegisterContext()); |
| 837 | + if (reg_ctx_sp) { |
| 838 | + RegisterContext *reg_ctx = reg_ctx_sp.get(); |
| 839 | + |
| 840 | + data.PutHex32(GPRRegSet); // Flavor |
| 841 | + data.PutHex32(GPRWordCount); |
| 842 | + PrintRegisterValue(reg_ctx, "x0", nullptr, 4, data); |
| 843 | + PrintRegisterValue(reg_ctx, "x1", nullptr, 4, data); |
| 844 | + PrintRegisterValue(reg_ctx, "x2", nullptr, 4, data); |
| 845 | + PrintRegisterValue(reg_ctx, "x3", nullptr, 4, data); |
| 846 | + PrintRegisterValue(reg_ctx, "x4", nullptr, 4, data); |
| 847 | + PrintRegisterValue(reg_ctx, "x5", nullptr, 4, data); |
| 848 | + PrintRegisterValue(reg_ctx, "x6", nullptr, 4, data); |
| 849 | + PrintRegisterValue(reg_ctx, "x7", nullptr, 4, data); |
| 850 | + PrintRegisterValue(reg_ctx, "x8", nullptr, 4, data); |
| 851 | + PrintRegisterValue(reg_ctx, "x9", nullptr, 4, data); |
| 852 | + PrintRegisterValue(reg_ctx, "x10", nullptr, 4, data); |
| 853 | + PrintRegisterValue(reg_ctx, "x11", nullptr, 4, data); |
| 854 | + PrintRegisterValue(reg_ctx, "x12", nullptr, 4, data); |
| 855 | + PrintRegisterValue(reg_ctx, "x13", nullptr, 4, data); |
| 856 | + PrintRegisterValue(reg_ctx, "x14", nullptr, 4, data); |
| 857 | + PrintRegisterValue(reg_ctx, "x15", nullptr, 4, data); |
| 858 | + PrintRegisterValue(reg_ctx, "x16", nullptr, 4, data); |
| 859 | + PrintRegisterValue(reg_ctx, "x17", nullptr, 4, data); |
| 860 | + PrintRegisterValue(reg_ctx, "x18", nullptr, 4, data); |
| 861 | + PrintRegisterValue(reg_ctx, "x19", nullptr, 4, data); |
| 862 | + PrintRegisterValue(reg_ctx, "x20", nullptr, 4, data); |
| 863 | + PrintRegisterValue(reg_ctx, "x21", nullptr, 4, data); |
| 864 | + PrintRegisterValue(reg_ctx, "x22", nullptr, 4, data); |
| 865 | + PrintRegisterValue(reg_ctx, "x23", nullptr, 4, data); |
| 866 | + PrintRegisterValue(reg_ctx, "x24", nullptr, 4, data); |
| 867 | + PrintRegisterValue(reg_ctx, "x25", nullptr, 4, data); |
| 868 | + PrintRegisterValue(reg_ctx, "x26", nullptr, 4, data); |
| 869 | + PrintRegisterValue(reg_ctx, "x27", nullptr, 4, data); |
| 870 | + PrintRegisterValue(reg_ctx, "x28", nullptr, 4, data); |
| 871 | + PrintRegisterValue(reg_ctx, "x29", nullptr, 4, data); |
| 872 | + PrintRegisterValue(reg_ctx, "x30", nullptr, 4, data); |
| 873 | + PrintRegisterValue(reg_ctx, "x31", nullptr, 4, data); |
| 874 | + PrintRegisterValue(reg_ctx, "pc", nullptr, 4, data); |
| 875 | + data.PutHex32(0); // uint32_t pad at the end |
| 876 | + |
| 877 | + // Write out the EXC registers |
| 878 | + data.PutHex32(EXCRegSet); |
| 879 | + data.PutHex32(EXCWordCount); |
| 880 | + PrintRegisterValue(reg_ctx, "exception", nullptr, 4, data); |
| 881 | + PrintRegisterValue(reg_ctx, "fsr", nullptr, 4, data); |
| 882 | + PrintRegisterValue(reg_ctx, "far", nullptr, 4, data); |
| 883 | + return true; |
| 884 | + } |
| 885 | + return false; |
| 886 | + } |
| 887 | + |
| 888 | +protected: |
| 889 | + int DoReadGPR(lldb::tid_t tid, int flavor, GPR &gpr) override { return -1; } |
| 890 | + |
| 891 | + int DoReadFPU(lldb::tid_t tid, int flavor, FPU &fpu) override { return -1; } |
| 892 | + |
| 893 | + int DoReadEXC(lldb::tid_t tid, int flavor, EXC &exc) override { return -1; } |
| 894 | + |
| 895 | + int DoReadCSR(lldb::tid_t tid, int flavor, CSR &csr) override { return -1; } |
| 896 | + |
| 897 | + int DoWriteGPR(lldb::tid_t tid, int flavor, const GPR &gpr) override { |
| 898 | + return 0; |
| 899 | + } |
| 900 | + |
| 901 | + int DoWriteFPU(lldb::tid_t tid, int flavor, const FPU &fpu) override { |
| 902 | + return 0; |
| 903 | + } |
| 904 | + |
| 905 | + int DoWriteEXC(lldb::tid_t tid, int flavor, const EXC &exc) override { |
| 906 | + return 0; |
| 907 | + } |
| 908 | + |
| 909 | + int DoWriteCSR(lldb::tid_t tid, int flavor, const CSR &csr) override { |
| 910 | + return 0; |
| 911 | + } |
| 912 | +}; |
| 913 | + |
772 | 914 | static uint32_t MachHeaderSizeFromMagic(uint32_t magic) {
|
773 | 915 | switch (magic) {
|
774 | 916 | case MH_MAGIC:
|
@@ -5827,6 +5969,11 @@ ObjectFileMachO::GetThreadContextAtIndex(uint32_t idx,
|
5827 | 5969 | reg_ctx_sp =
|
5828 | 5970 | std::make_shared<RegisterContextDarwin_x86_64_Mach>(thread, data);
|
5829 | 5971 | break;
|
| 5972 | + |
| 5973 | + case llvm::MachO::CPU_TYPE_RISCV: |
| 5974 | + reg_ctx_sp = |
| 5975 | + std::make_shared<RegisterContextDarwin_riscv32_Mach>(thread, data); |
| 5976 | + break; |
5830 | 5977 | }
|
5831 | 5978 | }
|
5832 | 5979 | }
|
@@ -6695,6 +6842,11 @@ bool ObjectFileMachO::SaveCore(const lldb::ProcessSP &process_sp,
|
6695 | 6842 | RegisterContextDarwin_x86_64_Mach::Create_LC_THREAD(
|
6696 | 6843 | thread_sp.get(), LC_THREAD_datas[thread_idx]);
|
6697 | 6844 | break;
|
| 6845 | + |
| 6846 | + case llvm::MachO::CPU_TYPE_RISCV: |
| 6847 | + RegisterContextDarwin_riscv32_Mach::Create_LC_THREAD( |
| 6848 | + thread_sp.get(), LC_THREAD_datas[thread_idx]); |
| 6849 | + break; |
6698 | 6850 | }
|
6699 | 6851 | }
|
6700 | 6852 | }
|
|
0 commit comments