Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h =================================================================== --- source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h +++ source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.h @@ -89,6 +89,9 @@ uint32_t NumSupportedHardwareWatchpoints () override; + uint32_t + NumHardwareWatchRegisters (); + protected: Error DoReadRegisterValue(uint32_t offset, Index: source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp =================================================================== --- source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp +++ source/Plugins/Process/Linux/NativeRegisterContextLinux_mips64.cpp @@ -76,6 +76,7 @@ #define I (1 << 2) #define IRW (I | R | W) +#define RW (R | W) struct pt_watch_regs default_watch_regs; @@ -1117,7 +1118,7 @@ Error NativeRegisterContextLinux_mips64::IsWatchpointHit (uint32_t wp_index, bool &is_hit) { - if (wp_index >= NumSupportedHardwareWatchpoints()) + if (wp_index >= NumHardwareWatchRegisters()) return Error("Watchpoint index out of range"); // reading the current state of watch regs @@ -1139,7 +1140,7 @@ Error NativeRegisterContextLinux_mips64::GetWatchpointHitIndex(uint32_t &wp_index, lldb::addr_t trap_addr) { - uint32_t num_hw_wps = NumSupportedHardwareWatchpoints(); + uint32_t num_hw_wps = NumHardwareWatchRegisters(); for (wp_index = 0; wp_index < num_hw_wps; ++wp_index) { bool is_hit; @@ -1164,7 +1165,7 @@ bool NativeRegisterContextLinux_mips64::ClearHardwareWatchpoint(uint32_t wp_index) { - if (wp_index >= NumSupportedHardwareWatchpoints()) + if (wp_index >= NumHardwareWatchRegisters()) return false; struct pt_watch_regs regs; @@ -1218,7 +1219,7 @@ DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast(®s)); // Try if a new watch point fits in this state - int index = GetVacantWatchIndex (®s, addr, size, watch_flags, NumSupportedHardwareWatchpoints()); + int index = GetVacantWatchIndex (®s, addr, size, watch_flags, NumHardwareWatchRegisters()); // New watchpoint doesn't fit if (index == LLDB_INVALID_INDEX32) @@ -1236,7 +1237,7 @@ lldb::addr_t NativeRegisterContextLinux_mips64::GetWatchpointAddress (uint32_t wp_index) { - if (wp_index >= NumSupportedHardwareWatchpoints()) + if (wp_index >= NumHardwareWatchRegisters()) return LLDB_INVALID_ADDRESS; return hw_addr_map[wp_index]; @@ -1315,7 +1316,7 @@ lldb::addr_t NativeRegisterContextLinux_mips64::GetWatchpointHitAddress (uint32_t wp_index) { - if (wp_index >= NumSupportedHardwareWatchpoints()) + if (wp_index >= NumHardwareWatchRegisters()) return LLDB_INVALID_ADDRESS; lldb_private::ArchSpec arch; @@ -1343,6 +1344,32 @@ } uint32_t +NativeRegisterContextLinux_mips64::NumHardwareWatchRegisters () +{ + Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); + struct pt_watch_regs regs; + static int num_valid = 0; + if (!num_valid) + { + DoReadWatchPointRegisterValue(m_thread.GetID(), static_cast(®s)); + switch (regs.style) + { + case pt_watch_style_mips32: + num_valid = regs.mips32.num_valid; // Using num_valid as cache + return num_valid; + case pt_watch_style_mips64: + num_valid = regs.mips64.num_valid; + return num_valid; + default: + if(log) + log->Printf("NativeRegisterContextLinux_mips64::%s Error: Unrecognized watch register style", __FUNCTION__); + } + return 0; + } + return num_valid; +} + +uint32_t NativeRegisterContextLinux_mips64::NumSupportedHardwareWatchpoints () { Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_WATCHPOINTS)); @@ -1356,9 +1383,19 @@ { case pt_watch_style_mips32: num_valid = regs.mips32.num_valid; // Using num_valid as cache + for (int index = 0; index < num_valid; index++) + { + if ((regs.mips32.watch_masks[index] & RW)== 0) // check last 2 bits of mask(read, write) + num_valid--; + } return num_valid; case pt_watch_style_mips64: num_valid = regs.mips64.num_valid; + for (int index = 0; index < num_valid; index++) + { + if ((regs.mips64.watch_masks[index] & RW) == 0) + num_valid--; + } return num_valid; default: if(log)