Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.h @@ -18,6 +18,8 @@ #include // clang-format on +#include + #include "Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD.h" #include "Plugins/Process/Utility/RegisterContext_x86.h" #include "Plugins/Process/Utility/NativeRegisterContextWatchpoint_x86.h" @@ -55,14 +57,19 @@ private: // Private member types. - enum { GPRegSet, FPRegSet, XSaveRegSet, DBRegSet }; + enum RegSetKind { + GPRegSet, + FPRegSet, + XSaveRegSet, + DBRegSet, + }; enum { YMMXSaveSet, MaxXSaveSet = YMMXSaveSet, }; // Private member variables. - struct reg m_gpr; + std::array m_gpr; #if defined(__x86_64__) struct fpreg m_fpr; #else @@ -72,7 +79,7 @@ std::vector m_xsave; std::array m_xsave_offsets; - int GetSetForNativeRegNum(int reg_num) const; + llvm::Optional GetSetForNativeRegNum(int reg_num) const; int GetDR(int num) const; Status ReadRegisterSet(uint32_t set); Index: lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp =================================================================== --- lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp +++ lldb/source/Plugins/Process/FreeBSDRemote/NativeRegisterContextFreeBSD_x86_64.cpp @@ -248,14 +248,16 @@ const ArchSpec &target_arch, NativeThreadProtocol &native_thread) : NativeRegisterContextRegisterInfo( native_thread, CreateRegisterInfoInterface(target_arch)), - m_gpr(), m_fpr(), m_dbr() {} + m_fpr(), m_dbr() { + assert(m_gpr.size() == GetRegisterInfoInterface().GetGPRSize()); +} // CONSIDER after local and llgs debugging are merged, register set support can // be moved into a base x86-64 class with IsRegisterSetAvailable made virtual. uint32_t NativeRegisterContextFreeBSD_x86_64::GetRegisterSetCount() const { uint32_t sets = 0; for (uint32_t set_index = 0; set_index < k_num_register_sets; ++set_index) { - if (GetSetForNativeRegNum(set_index) != -1) + if (GetSetForNativeRegNum(set_index)) ++sets; } @@ -276,38 +278,6 @@ static constexpr int RegNumX86ToX86_64(int regnum) { switch (regnum) { - case lldb_eax_i386: - return lldb_rax_x86_64; - case lldb_ebx_i386: - return lldb_rbx_x86_64; - case lldb_ecx_i386: - return lldb_rcx_x86_64; - case lldb_edx_i386: - return lldb_rdx_x86_64; - case lldb_edi_i386: - return lldb_rdi_x86_64; - case lldb_esi_i386: - return lldb_rsi_x86_64; - case lldb_ebp_i386: - return lldb_rbp_x86_64; - case lldb_esp_i386: - return lldb_rsp_x86_64; - case lldb_eip_i386: - return lldb_rip_x86_64; - case lldb_eflags_i386: - return lldb_rflags_x86_64; - case lldb_cs_i386: - return lldb_cs_x86_64; - case lldb_fs_i386: - return lldb_fs_x86_64; - case lldb_gs_i386: - return lldb_gs_x86_64; - case lldb_ss_i386: - return lldb_ss_x86_64; - case lldb_ds_i386: - return lldb_ds_x86_64; - case lldb_es_i386: - return lldb_es_x86_64; case lldb_fctrl_i386: return lldb_fctrl_x86_64; case lldb_fstat_i386: @@ -387,9 +357,8 @@ } } -int NativeRegisterContextFreeBSD_x86_64::GetSetForNativeRegNum( - int reg_num) const { - +llvm::Optional +NativeRegisterContextFreeBSD_x86_64::GetSetForNativeRegNum(int reg_num) const { switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { case llvm::Triple::x86: if (reg_num >= k_first_gpr_i386 && reg_num <= k_last_gpr_i386) @@ -399,9 +368,9 @@ if (reg_num >= k_first_avx_i386 && reg_num <= k_last_avx_i386) return XSaveRegSet; // AVX if (reg_num >= k_first_mpxr_i386 && reg_num <= k_last_mpxr_i386) - return -1; // MPXR + return llvm::None; // MPXR if (reg_num >= k_first_mpxc_i386 && reg_num <= k_last_mpxc_i386) - return -1; // MPXC + return llvm::None; // MPXC if (reg_num >= k_first_dbr_i386 && reg_num <= k_last_dbr_i386) return DBRegSet; // DBR break; @@ -413,9 +382,9 @@ if (reg_num >= k_first_avx_x86_64 && reg_num <= k_last_avx_x86_64) return XSaveRegSet; // AVX if (reg_num >= k_first_mpxr_x86_64 && reg_num <= k_last_mpxr_x86_64) - return -1; // MPXR + return llvm::None; // MPXR if (reg_num >= k_first_mpxc_x86_64 && reg_num <= k_last_mpxc_x86_64) - return -1; // MPXC + return llvm::None; // MPXC if (reg_num >= k_first_dbr_x86_64 && reg_num <= k_last_dbr_x86_64) return DBRegSet; // DBR break; @@ -430,7 +399,7 @@ switch (set) { case GPRegSet: return NativeProcessFreeBSD::PtraceWrapper(PT_GETREGS, m_thread.GetID(), - &m_gpr); + m_gpr.data()); case FPRegSet: #if defined(__x86_64__) return NativeProcessFreeBSD::PtraceWrapper(PT_GETFPREGS, m_thread.GetID(), @@ -471,7 +440,7 @@ switch (set) { case GPRegSet: return NativeProcessFreeBSD::PtraceWrapper(PT_SETREGS, m_thread.GetID(), - &m_gpr); + m_gpr.data()); case FPRegSet: #if defined(__x86_64__) return NativeProcessFreeBSD::PtraceWrapper(PT_SETFPREGS, m_thread.GetID(), @@ -512,8 +481,8 @@ return error; } - int set = GetSetForNativeRegNum(reg); - if (set == -1) { + llvm::Optional opt_set = GetSetForNativeRegNum(reg); + if (!opt_set) { // This is likely an internal register for lldb use only and should not be // directly queried. error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", @@ -521,6 +490,23 @@ return error; } + enum RegSetKind set = opt_set.getValue(); + error = ReadRegisterSet(set); + if (error.Fail()) + return error; + + switch (set) { + case GPRegSet: + reg_value.SetBytes(m_gpr.data() + reg_info->byte_offset, + reg_info->byte_size, endian::InlHostByteOrder()); + return error; + case FPRegSet: + case XSaveRegSet: + case DBRegSet: + // legacy logic + break; + } + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { case llvm::Triple::x86_64: break; @@ -531,134 +517,7 @@ llvm_unreachable("Unhandled target architecture."); } - error = ReadRegisterSet(set); - if (error.Fail()) - return error; - switch (reg) { -#if defined(__x86_64__) - case lldb_rax_x86_64: - reg_value = (uint64_t)m_gpr.r_rax; - break; - case lldb_rbx_x86_64: - reg_value = (uint64_t)m_gpr.r_rbx; - break; - case lldb_rcx_x86_64: - reg_value = (uint64_t)m_gpr.r_rcx; - break; - case lldb_rdx_x86_64: - reg_value = (uint64_t)m_gpr.r_rdx; - break; - case lldb_rdi_x86_64: - reg_value = (uint64_t)m_gpr.r_rdi; - break; - case lldb_rsi_x86_64: - reg_value = (uint64_t)m_gpr.r_rsi; - break; - case lldb_rbp_x86_64: - reg_value = (uint64_t)m_gpr.r_rbp; - break; - case lldb_rsp_x86_64: - reg_value = (uint64_t)m_gpr.r_rsp; - break; - case lldb_r8_x86_64: - reg_value = (uint64_t)m_gpr.r_r8; - break; - case lldb_r9_x86_64: - reg_value = (uint64_t)m_gpr.r_r9; - break; - case lldb_r10_x86_64: - reg_value = (uint64_t)m_gpr.r_r10; - break; - case lldb_r11_x86_64: - reg_value = (uint64_t)m_gpr.r_r11; - break; - case lldb_r12_x86_64: - reg_value = (uint64_t)m_gpr.r_r12; - break; - case lldb_r13_x86_64: - reg_value = (uint64_t)m_gpr.r_r13; - break; - case lldb_r14_x86_64: - reg_value = (uint64_t)m_gpr.r_r14; - break; - case lldb_r15_x86_64: - reg_value = (uint64_t)m_gpr.r_r15; - break; - case lldb_rip_x86_64: - reg_value = (uint64_t)m_gpr.r_rip; - break; - case lldb_rflags_x86_64: - reg_value = (uint64_t)m_gpr.r_rflags; - break; - case lldb_cs_x86_64: - reg_value = (uint64_t)m_gpr.r_cs; - break; - case lldb_fs_x86_64: - reg_value = (uint16_t)m_gpr.r_fs; - break; - case lldb_gs_x86_64: - reg_value = (uint16_t)m_gpr.r_gs; - break; - case lldb_ss_x86_64: - reg_value = (uint64_t)m_gpr.r_ss; - break; - case lldb_ds_x86_64: - reg_value = (uint16_t)m_gpr.r_ds; - break; - case lldb_es_x86_64: - reg_value = (uint16_t)m_gpr.r_es; - break; -#else - case lldb_rax_x86_64: - reg_value = (uint32_t)m_gpr.r_eax; - break; - case lldb_rbx_x86_64: - reg_value = (uint32_t)m_gpr.r_ebx; - break; - case lldb_rcx_x86_64: - reg_value = (uint32_t)m_gpr.r_ecx; - break; - case lldb_rdx_x86_64: - reg_value = (uint32_t)m_gpr.r_edx; - break; - case lldb_rdi_x86_64: - reg_value = (uint32_t)m_gpr.r_edi; - break; - case lldb_rsi_x86_64: - reg_value = (uint32_t)m_gpr.r_esi; - break; - case lldb_rsp_x86_64: - reg_value = (uint32_t)m_gpr.r_esp; - break; - case lldb_rbp_x86_64: - reg_value = (uint32_t)m_gpr.r_ebp; - break; - case lldb_rip_x86_64: - reg_value = (uint32_t)m_gpr.r_eip; - break; - case lldb_rflags_x86_64: - reg_value = (uint32_t)m_gpr.r_eflags; - break; - case lldb_cs_x86_64: - reg_value = (uint32_t)m_gpr.r_cs; - break; - case lldb_fs_x86_64: - reg_value = (uint16_t)m_gpr.r_fs; - break; - case lldb_gs_x86_64: - reg_value = (uint16_t)m_gpr.r_gs; - break; - case lldb_ss_x86_64: - reg_value = (uint32_t)m_gpr.r_ss; - break; - case lldb_ds_x86_64: - reg_value = (uint16_t)m_gpr.r_ds; - break; - case lldb_es_x86_64: - reg_value = (uint16_t)m_gpr.r_es; - break; -#endif #if defined(__x86_64__) // the 32-bit field carries more detail, so we don't have to reinvent // the wheel @@ -822,8 +681,8 @@ return error; } - int set = GetSetForNativeRegNum(reg); - if (set == -1) { + llvm::Optional opt_set = GetSetForNativeRegNum(reg); + if (!opt_set) { // This is likely an internal register for lldb use only and should not be // directly queried. error.SetErrorStringWithFormat("register \"%s\" is in unrecognized set", @@ -831,6 +690,23 @@ return error; } + enum RegSetKind set = opt_set.getValue(); + error = ReadRegisterSet(set); + if (error.Fail()) + return error; + + switch (set) { + case GPRegSet: + ::memcpy(m_gpr.data() + reg_info->byte_offset, reg_value.GetBytes(), + reg_value.GetByteSize()); + return WriteRegisterSet(set); + case FPRegSet: + case XSaveRegSet: + case DBRegSet: + // legacy logic + break; + } + switch (GetRegisterInfoInterface().GetTargetArchitecture().GetMachine()) { case llvm::Triple::x86_64: break; @@ -841,134 +717,7 @@ llvm_unreachable("Unhandled target architecture."); } - error = ReadRegisterSet(set); - if (error.Fail()) - return error; - switch (reg) { -#if defined(__x86_64__) - case lldb_rax_x86_64: - m_gpr.r_rax = reg_value.GetAsUInt64(); - break; - case lldb_rbx_x86_64: - m_gpr.r_rbx = reg_value.GetAsUInt64(); - break; - case lldb_rcx_x86_64: - m_gpr.r_rcx = reg_value.GetAsUInt64(); - break; - case lldb_rdx_x86_64: - m_gpr.r_rdx = reg_value.GetAsUInt64(); - break; - case lldb_rdi_x86_64: - m_gpr.r_rdi = reg_value.GetAsUInt64(); - break; - case lldb_rsi_x86_64: - m_gpr.r_rsi = reg_value.GetAsUInt64(); - break; - case lldb_rbp_x86_64: - m_gpr.r_rbp = reg_value.GetAsUInt64(); - break; - case lldb_rsp_x86_64: - m_gpr.r_rsp = reg_value.GetAsUInt64(); - break; - case lldb_r8_x86_64: - m_gpr.r_r8 = reg_value.GetAsUInt64(); - break; - case lldb_r9_x86_64: - m_gpr.r_r9 = reg_value.GetAsUInt64(); - break; - case lldb_r10_x86_64: - m_gpr.r_r10 = reg_value.GetAsUInt64(); - break; - case lldb_r11_x86_64: - m_gpr.r_r11 = reg_value.GetAsUInt64(); - break; - case lldb_r12_x86_64: - m_gpr.r_r12 = reg_value.GetAsUInt64(); - break; - case lldb_r13_x86_64: - m_gpr.r_r13 = reg_value.GetAsUInt64(); - break; - case lldb_r14_x86_64: - m_gpr.r_r14 = reg_value.GetAsUInt64(); - break; - case lldb_r15_x86_64: - m_gpr.r_r15 = reg_value.GetAsUInt64(); - break; - case lldb_rip_x86_64: - m_gpr.r_rip = reg_value.GetAsUInt64(); - break; - case lldb_rflags_x86_64: - m_gpr.r_rflags = reg_value.GetAsUInt64(); - break; - case lldb_cs_x86_64: - m_gpr.r_cs = reg_value.GetAsUInt64(); - break; - case lldb_fs_x86_64: - m_gpr.r_fs = reg_value.GetAsUInt16(); - break; - case lldb_gs_x86_64: - m_gpr.r_gs = reg_value.GetAsUInt16(); - break; - case lldb_ss_x86_64: - m_gpr.r_ss = reg_value.GetAsUInt64(); - break; - case lldb_ds_x86_64: - m_gpr.r_ds = reg_value.GetAsUInt16(); - break; - case lldb_es_x86_64: - m_gpr.r_es = reg_value.GetAsUInt16(); - break; -#else - case lldb_rax_x86_64: - m_gpr.r_eax = reg_value.GetAsUInt32(); - break; - case lldb_rbx_x86_64: - m_gpr.r_ebx = reg_value.GetAsUInt32(); - break; - case lldb_rcx_x86_64: - m_gpr.r_ecx = reg_value.GetAsUInt32(); - break; - case lldb_rdx_x86_64: - m_gpr.r_edx = reg_value.GetAsUInt32(); - break; - case lldb_rdi_x86_64: - m_gpr.r_edi = reg_value.GetAsUInt32(); - break; - case lldb_rsi_x86_64: - m_gpr.r_esi = reg_value.GetAsUInt32(); - break; - case lldb_rsp_x86_64: - m_gpr.r_esp = reg_value.GetAsUInt32(); - break; - case lldb_rbp_x86_64: - m_gpr.r_ebp = reg_value.GetAsUInt32(); - break; - case lldb_rip_x86_64: - m_gpr.r_eip = reg_value.GetAsUInt32(); - break; - case lldb_rflags_x86_64: - m_gpr.r_eflags = reg_value.GetAsUInt32(); - break; - case lldb_cs_x86_64: - m_gpr.r_cs = reg_value.GetAsUInt32(); - break; - case lldb_fs_x86_64: - m_gpr.r_fs = reg_value.GetAsUInt16(); - break; - case lldb_gs_x86_64: - m_gpr.r_gs = reg_value.GetAsUInt16(); - break; - case lldb_ss_x86_64: - m_gpr.r_ss = reg_value.GetAsUInt32(); - break; - case lldb_ds_x86_64: - m_gpr.r_ds = reg_value.GetAsUInt16(); - break; - case lldb_es_x86_64: - m_gpr.r_es = reg_value.GetAsUInt16(); - break; -#endif case lldb_fctrl_x86_64: FPR_ENV(en_cw) = reg_value.GetAsUInt16(); break; @@ -1114,7 +863,7 @@ return error; uint8_t *dst = data_sp->GetBytes(); - ::memcpy(dst, &m_gpr, GetRegisterInfoInterface().GetGPRSize()); + ::memcpy(dst, m_gpr.data(), GetRegisterInfoInterface().GetGPRSize()); dst += GetRegisterInfoInterface().GetGPRSize(); return error; @@ -1147,7 +896,7 @@ __FUNCTION__); return error; } - ::memcpy(&m_gpr, src, GetRegisterInfoInterface().GetGPRSize()); + ::memcpy(m_gpr.data(), src, GetRegisterInfoInterface().GetGPRSize()); error = WriteRegisterSet(GPRegSet); if (error.Fail()) Index: lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp =================================================================== --- lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp +++ lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_i386.cpp @@ -9,6 +9,10 @@ #include "RegisterContextFreeBSD_i386.h" #include "RegisterContextPOSIX_x86.h" +#if defined(__FreeBSD__) && (defined(__x86_64__) || defined(__i386__)) +#include +#endif + using namespace lldb_private; using namespace lldb; @@ -35,7 +39,7 @@ uint32_t gs; }; -struct dbreg { +struct DBG { uint32_t dr[8]; /* debug registers */ /* Index 0-3: debug address registers */ /* Index 4-5: reserved */ @@ -50,8 +54,44 @@ FPR_i386 i387; }; +#if defined(__FreeBSD__) && (defined(__x86_64__) || defined(__i386__)) +#if defined(__i386__) +#define reg32 reg +#endif + +// if we're building natively, verify that the structs are correct +#define ASSERT_GPR(regname) \ + static_assert(offsetof(GPR, regname) == offsetof(reg32, r_##regname), \ + "GPR offset mismatch for " #regname); \ + static_assert(sizeof(GPR::regname) == sizeof(reg32::r_##regname), \ + "GPR size mismatch for " #regname); + +ASSERT_GPR(fs); +ASSERT_GPR(es); +ASSERT_GPR(ds); +ASSERT_GPR(edi); +ASSERT_GPR(esi); +ASSERT_GPR(ebp); +ASSERT_GPR(isp); +ASSERT_GPR(ebx); +ASSERT_GPR(edx); +ASSERT_GPR(ecx); +ASSERT_GPR(eax); +ASSERT_GPR(trapno); +ASSERT_GPR(err); +ASSERT_GPR(eip); +ASSERT_GPR(cs); +ASSERT_GPR(eflags); +ASSERT_GPR(esp); +ASSERT_GPR(ss); +ASSERT_GPR(gs); + +#undef reg32 +#undef ASSERT_GPR +#endif + #define DR_SIZE sizeof(uint32_t) -#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(dbreg, dr[reg_index])) +#define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(DBG, dr[reg_index])) // Include RegisterInfos_i386 to declare our g_register_infos_i386 structure. #define DECLARE_REGISTER_INFOS_I386_STRUCT Index: lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp =================================================================== --- lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp +++ lldb/source/Plugins/Process/Utility/RegisterContextFreeBSD_x86_64.cpp @@ -11,6 +11,10 @@ #include "RegisterContextPOSIX_x86.h" #include +#if defined(__FreeBSD__) && defined(__x86_64__) +#include +#endif + using namespace lldb_private; using namespace lldb; @@ -59,6 +63,44 @@ DBG dbg; }; +#if defined(__FreeBSD__) && defined(__x86_64__) +// if we're building natively, verify that the structs are correct +#define ASSERT_GPR(regname) \ + static_assert(offsetof(GPR, regname) == offsetof(reg, r_##regname), \ + "GPR offset mismatch for " #regname); \ + static_assert(sizeof(GPR::regname) == sizeof(reg::r_##regname), \ + "GPR size mismatch for " #regname); + +ASSERT_GPR(r15); +ASSERT_GPR(r14); +ASSERT_GPR(r13); +ASSERT_GPR(r12); +ASSERT_GPR(r11); +ASSERT_GPR(r10); +ASSERT_GPR(r9); +ASSERT_GPR(r8); +ASSERT_GPR(rdi); +ASSERT_GPR(rsi); +ASSERT_GPR(rbp); +ASSERT_GPR(rbx); +ASSERT_GPR(rdx); +ASSERT_GPR(rcx); +ASSERT_GPR(rax); +ASSERT_GPR(trapno); +ASSERT_GPR(fs); +ASSERT_GPR(gs); +ASSERT_GPR(err); +ASSERT_GPR(es); +ASSERT_GPR(ds); +ASSERT_GPR(rip); +ASSERT_GPR(cs); +ASSERT_GPR(rflags); +ASSERT_GPR(rsp); +ASSERT_GPR(ss); + +#undef ASSERT_GPR +#endif + #define DR_OFFSET(reg_index) (LLVM_EXTENSION offsetof(DBG, dr[reg_index])) // Include RegisterInfos_x86_64 to declare our g_register_infos_x86_64