break_points.cpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright 2013 Dolphin Emulator Project
  2. // Licensed under GPLv2
  3. // Refer to the license.txt file included.
  4. #include "common/common.h"
  5. #include "common/debug_interface.h"
  6. #include "common/break_points.h"
  7. #include <sstream>
  8. #include <algorithm>
  9. bool BreakPoints::IsAddressBreakPoint(u32 iAddress)
  10. {
  11. auto cond = [&iAddress](const TBreakPoint& bp) { return bp.iAddress == iAddress; };
  12. auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond);
  13. return it != m_BreakPoints.end();
  14. }
  15. bool BreakPoints::IsTempBreakPoint(u32 iAddress)
  16. {
  17. auto cond = [&iAddress](const TBreakPoint& bp) { return bp.iAddress == iAddress && bp.bTemporary; };
  18. auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond);
  19. return it != m_BreakPoints.end();
  20. }
  21. BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const
  22. {
  23. TBreakPointsStr bps;
  24. for (auto breakpoint : m_BreakPoints)
  25. {
  26. if (!breakpoint.bTemporary)
  27. {
  28. std::stringstream bp;
  29. bp << std::hex << breakpoint.iAddress << " " << (breakpoint.bOn ? "n" : "");
  30. bps.push_back(bp.str());
  31. }
  32. }
  33. return bps;
  34. }
  35. void BreakPoints::AddFromStrings(const TBreakPointsStr& bps)
  36. {
  37. for (auto bps_item : bps)
  38. {
  39. TBreakPoint bp;
  40. std::stringstream bpstr;
  41. bpstr << std::hex << bps_item;
  42. bpstr >> bp.iAddress;
  43. bp.bOn = bps_item.find("n") != bps_item.npos;
  44. bp.bTemporary = false;
  45. Add(bp);
  46. }
  47. }
  48. void BreakPoints::Add(const TBreakPoint& bp)
  49. {
  50. if (!IsAddressBreakPoint(bp.iAddress))
  51. {
  52. m_BreakPoints.push_back(bp);
  53. //if (jit)
  54. // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
  55. }
  56. }
  57. void BreakPoints::Add(u32 em_address, bool temp)
  58. {
  59. if (!IsAddressBreakPoint(em_address)) // only add new addresses
  60. {
  61. TBreakPoint pt; // breakpoint settings
  62. pt.bOn = true;
  63. pt.bTemporary = temp;
  64. pt.iAddress = em_address;
  65. m_BreakPoints.push_back(pt);
  66. //if (jit)
  67. // jit->GetBlockCache()->InvalidateICache(em_address, 4);
  68. }
  69. }
  70. void BreakPoints::Remove(u32 em_address)
  71. {
  72. auto cond = [&em_address](const TBreakPoint& bp) { return bp.iAddress == em_address; };
  73. auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond);
  74. if (it != m_BreakPoints.end())
  75. m_BreakPoints.erase(it);
  76. }
  77. void BreakPoints::Clear()
  78. {
  79. //if (jit)
  80. //{
  81. // std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(),
  82. // [](const TBreakPoint& bp)
  83. // {
  84. // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4);
  85. // }
  86. // );
  87. //}
  88. m_BreakPoints.clear();
  89. }
  90. MemChecks::TMemChecksStr MemChecks::GetStrings() const
  91. {
  92. TMemChecksStr mcs;
  93. for (auto memcheck : m_MemChecks)
  94. {
  95. std::stringstream mc;
  96. mc << std::hex << memcheck.StartAddress;
  97. mc << " " << (memcheck.bRange ? memcheck.EndAddress : memcheck.StartAddress) << " "
  98. << (memcheck.bRange ? "n" : "")
  99. << (memcheck.OnRead ? "r" : "")
  100. << (memcheck.OnWrite ? "w" : "")
  101. << (memcheck.Log ? "l" : "")
  102. << (memcheck.Break ? "p" : "");
  103. mcs.push_back(mc.str());
  104. }
  105. return mcs;
  106. }
  107. void MemChecks::AddFromStrings(const TMemChecksStr& mcs)
  108. {
  109. for (auto mcs_item : mcs)
  110. {
  111. TMemCheck mc;
  112. std::stringstream mcstr;
  113. mcstr << std::hex << mcs_item;
  114. mcstr >> mc.StartAddress;
  115. mc.bRange = mcs_item.find("n") != mcs_item.npos;
  116. mc.OnRead = mcs_item.find("r") != mcs_item.npos;
  117. mc.OnWrite = mcs_item.find("w") != mcs_item.npos;
  118. mc.Log = mcs_item.find("l") != mcs_item.npos;
  119. mc.Break = mcs_item.find("p") != mcs_item.npos;
  120. if (mc.bRange)
  121. mcstr >> mc.EndAddress;
  122. else
  123. mc.EndAddress = mc.StartAddress;
  124. Add(mc);
  125. }
  126. }
  127. void MemChecks::Add(const TMemCheck& rMemoryCheck)
  128. {
  129. if (GetMemCheck(rMemoryCheck.StartAddress) == 0)
  130. m_MemChecks.push_back(rMemoryCheck);
  131. }
  132. void MemChecks::Remove(u32 Address)
  133. {
  134. auto cond = [&Address](const TMemCheck& mc) { return mc.StartAddress == Address; };
  135. auto it = std::find_if(m_MemChecks.begin(), m_MemChecks.end(), cond);
  136. if (it != m_MemChecks.end())
  137. m_MemChecks.erase(it);
  138. }
  139. TMemCheck *MemChecks::GetMemCheck(u32 address)
  140. {
  141. for (auto i = m_MemChecks.begin(); i != m_MemChecks.end(); ++i)
  142. {
  143. if (i->bRange)
  144. {
  145. if (address >= i->StartAddress && address <= i->EndAddress)
  146. return &(*i);
  147. }
  148. else if (i->StartAddress == address)
  149. return &(*i);
  150. }
  151. // none found
  152. return 0;
  153. }
  154. void TMemCheck::Action(DebugInterface *debug_interface, u32 iValue, u32 addr,
  155. bool write, int size, u32 pc)
  156. {
  157. if ((write && OnWrite) || (!write && OnRead))
  158. {
  159. if (Log)
  160. {
  161. INFO_LOG(MEMMAP, "CHK %08x (%s) %s%i %0*x at %08x (%s)",
  162. pc, debug_interface->getDescription(pc).c_str(),
  163. write ? "Write" : "Read", size*8, size*2, iValue, addr,
  164. debug_interface->getDescription(addr).c_str()
  165. );
  166. }
  167. if (Break)
  168. debug_interface->breakNow();
  169. }
  170. }