diff --git a/CMakeLists.txt b/CMakeLists.txt
index 56f617ae1fb9..2f2a9cd8d7ba 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1482,6 +1482,8 @@ add_library(${CoreLibName} ${CoreLinkType}
Core/Debugger/Breakpoints.cpp
Core/Debugger/Breakpoints.h
Core/Debugger/DebugInterface.h
+ Core/Debugger/MemBlockInfo.cpp
+ Core/Debugger/MemBlockInfo.h
Core/Debugger/SymbolMap.cpp
Core/Debugger/SymbolMap.h
Core/Debugger/DisassemblyManager.cpp
diff --git a/Core/Core.vcxproj b/Core/Core.vcxproj
index 065a61aff354..c0c9051d7fc8 100644
--- a/Core/Core.vcxproj
+++ b/Core/Core.vcxproj
@@ -429,6 +429,7 @@
+
@@ -977,6 +978,7 @@
+
diff --git a/Core/Core.vcxproj.filters b/Core/Core.vcxproj.filters
index 51d07653fd1e..f66273cddd48 100644
--- a/Core/Core.vcxproj.filters
+++ b/Core/Core.vcxproj.filters
@@ -977,6 +977,9 @@
MIPS\fake
+
+ Debugger
+
@@ -1670,6 +1673,9 @@
MIPS\fake
+
+ Debugger
+
diff --git a/Core/CwCheat.cpp b/Core/CwCheat.cpp
index c886d3c369e2..8243d2fcc290 100644
--- a/Core/CwCheat.cpp
+++ b/Core/CwCheat.cpp
@@ -11,6 +11,7 @@
#include "Core/CwCheat.h"
#include "Core/Config.h"
#include "Core/Host.h"
+#include "Core/MemMapHelpers.h"
#include "Core/MIPS/MIPS.h"
#include "Core/ELF/ParamSFO.h"
#include "Core/System.h"
@@ -924,7 +925,7 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat,
InvalidateICache(op.addr, op.val);
InvalidateICache(op.copyBytesFrom.destAddr, op.val);
- Memory::MemcpyUnchecked(op.copyBytesFrom.destAddr, op.addr, op.val);
+ Memory::Memcpy(op.copyBytesFrom.destAddr, op.addr, op.val, "CwCheat");
}
break;
@@ -1106,7 +1107,7 @@ void CWCheatEngine::ExecuteOp(const CheatOperation &op, const CheatCode &cheat,
if (Memory::IsValidRange(dstAddr, val) && Memory::IsValidRange(srcAddr, val)) {
InvalidateICache(dstAddr, val);
InvalidateICache(srcAddr, val);
- Memory::MemcpyUnchecked(dstAddr, srcAddr, val);
+ Memory::Memcpy(dstAddr, srcAddr, val, "CwCheat");
}
// Don't perform any further action.
type = -1;
diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp
index c988712be35d..ddb2d2baf650 100644
--- a/Core/Debugger/Breakpoints.cpp
+++ b/Core/Debugger/Breakpoints.cpp
@@ -40,14 +40,15 @@ static std::mutex memCheckMutex_;
std::vector CBreakPoints::memChecks_;
std::vector CBreakPoints::cleanupMemChecks_;
-void MemCheck::Log(u32 addr, bool write, int size, u32 pc) {
+void MemCheck::Log(u32 addr, bool write, int size, u32 pc, const char *reason) {
if (result & BREAK_ACTION_LOG) {
+ const char *type = write ? "Write" : "Read";
if (logFormat.empty()) {
- NOTICE_LOG(MEMMAP, "CHK %s%i at %08x (%s), PC=%08x (%s)", write ? "Write" : "Read", size * 8, addr, g_symbolMap->GetDescription(addr).c_str(), pc, g_symbolMap->GetDescription(pc).c_str());
+ NOTICE_LOG(MEMMAP, "CHK %s%i(%s) at %08x (%s), PC=%08x (%s)", type, size * 8, reason, addr, g_symbolMap->GetDescription(addr).c_str(), pc, g_symbolMap->GetDescription(pc).c_str());
} else {
std::string formatted;
CBreakPoints::EvaluateLogFormat(currentDebugMIPS, logFormat, formatted);
- NOTICE_LOG(MEMMAP, "CHK %s%i at %08x: %s", write ? "Write" : "Read", size * 8, addr, formatted.c_str());
+ NOTICE_LOG(MEMMAP, "CHK %s%i(%s) at %08x: %s", type, size * 8, reason, addr, formatted.c_str());
}
}
}
@@ -62,10 +63,10 @@ BreakAction MemCheck::Apply(u32 addr, bool write, int size, u32 pc) {
return BREAK_ACTION_IGNORE;
}
-BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc) {
+BreakAction MemCheck::Action(u32 addr, bool write, int size, u32 pc, const char *reason) {
int mask = write ? MEMCHECK_WRITE : MEMCHECK_READ;
if (cond & mask) {
- Log(addr, write, size, pc);
+ Log(addr, write, size, pc, reason);
if ((result & BREAK_ACTION_PAUSE) && coreState != CORE_POWERUP) {
Core_EnableStepping(true);
host->SetDebugMode(true);
@@ -94,7 +95,7 @@ void MemCheck::JitBeforeAction(u32 addr, bool write, int size, u32 pc) {
// We have to break to find out if it changed.
Core_EnableStepping(true);
} else {
- Action(addr, write, size, pc);
+ Action(addr, write, size, pc, "CPU");
}
}
@@ -116,7 +117,7 @@ void MemCheck::JitCleanup(bool changed)
return;
if (changed)
- Log(lastAddr, true, lastSize, lastPC);
+ Log(lastAddr, true, lastSize, lastPC, "CPU");
// Resume if it should not have gone to stepping, or if it did not change.
if ((!(result & BREAK_ACTION_PAUSE) || !changed) && coreState == CORE_STEPPING)
@@ -504,7 +505,7 @@ MemCheck *CBreakPoints::GetMemCheckLocked(u32 address, int size) {
return 0;
}
-BreakAction CBreakPoints::ExecMemCheck(u32 address, bool write, int size, u32 pc)
+BreakAction CBreakPoints::ExecMemCheck(u32 address, bool write, int size, u32 pc, const char *reason)
{
if (!anyMemChecks_)
return BREAK_ACTION_IGNORE;
@@ -514,7 +515,7 @@ BreakAction CBreakPoints::ExecMemCheck(u32 address, bool write, int size, u32 pc
check->Apply(address, write, size, pc);
auto copy = *check;
guard.unlock();
- return copy.Action(address, write, size, pc);
+ return copy.Action(address, write, size, pc, reason);
}
return BREAK_ACTION_IGNORE;
}
@@ -547,7 +548,7 @@ BreakAction CBreakPoints::ExecOpMemCheck(u32 address, u32 pc)
check->Apply(address, write, size, pc);
auto copy = *check;
guard.unlock();
- return copy.Action(address, write, size, pc);
+ return copy.Action(address, write, size, pc, "CPU");
}
}
return BREAK_ACTION_IGNORE;
diff --git a/Core/Debugger/Breakpoints.h b/Core/Debugger/Breakpoints.h
index bd3dd670e487..c2a7d81b6a46 100644
--- a/Core/Debugger/Breakpoints.h
+++ b/Core/Debugger/Breakpoints.h
@@ -96,13 +96,13 @@ struct MemCheck {
// Called on the stored memcheck (affects numHits, etc.)
BreakAction Apply(u32 addr, bool write, int size, u32 pc);
// Called on a copy.
- BreakAction Action(u32 addr, bool write, int size, u32 pc);
+ BreakAction Action(u32 addr, bool write, int size, u32 pc, const char *reason);
void JitBeforeApply(u32 addr, bool write, int size, u32 pc);
void JitBeforeAction(u32 addr, bool write, int size, u32 pc);
bool JitApplyChanged();
void JitCleanup(bool changed);
- void Log(u32 addr, bool write, int size, u32 pc);
+ void Log(u32 addr, bool write, int size, u32 pc, const char *reason);
bool IsEnabled() const {
return (result & BREAK_ACTION_PAUSE) != 0;
@@ -151,7 +151,7 @@ class CBreakPoints
static bool GetMemCheck(u32 start, u32 end, MemCheck *check);
static bool GetMemCheckInRange(u32 address, int size, MemCheck *check);
- static BreakAction ExecMemCheck(u32 address, bool write, int size, u32 pc);
+ static BreakAction ExecMemCheck(u32 address, bool write, int size, u32 pc, const char *reason);
static BreakAction ExecOpMemCheck(u32 address, u32 pc);
// Executes memchecks but used by the jit. Cleanup finalizes after jit is done.
diff --git a/Core/Debugger/MemBlockInfo.cpp b/Core/Debugger/MemBlockInfo.cpp
new file mode 100644
index 000000000000..ef3f1ec2390c
--- /dev/null
+++ b/Core/Debugger/MemBlockInfo.cpp
@@ -0,0 +1,438 @@
+// Copyright (c) 2021- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#include
+#include "Common/Log.h"
+#include "Common/Serialize/Serializer.h"
+#include "Common/Serialize/SerializeFuncs.h"
+#include "Core/CoreTiming.h"
+#include "Core/Debugger/Breakpoints.h"
+#include "Core/Debugger/MemBlockInfo.h"
+#include "Core/MIPS/MIPS.h"
+
+class MemSlabMap {
+public:
+ MemSlabMap();
+ ~MemSlabMap();
+
+ bool Mark(uint32_t addr, uint32_t size, uint64_t ticks, uint32_t pc, bool allocated, const std::string &tag);
+ bool Find(MemBlockFlags flags, uint32_t addr, uint32_t size, std::vector &results);
+ void Reset();
+ void DoState(PointerWrap &p);
+
+private:
+ struct Slab {
+ uint32_t start = 0;
+ uint32_t end = 0;
+ uint64_t ticks = 0;
+ uint32_t pc = 0;
+ bool allocated = false;
+ std::string tag;
+ Slab *prev = nullptr;
+ Slab *next = nullptr;
+
+ void DoState(PointerWrap &p);
+ };
+
+ static constexpr uint32_t MAX_SIZE = 0x40000000;
+ static constexpr uint32_t SLICES = 16384;
+ static constexpr uint32_t SLICE_SIZE = MAX_SIZE / SLICES;
+
+ Slab *FindSlab(uint32_t addr);
+ void Clear();
+ // Returns the new slab after size.
+ Slab *Split(Slab *slab, uint32_t size);
+ void MergeAdjacent(Slab *slab);
+ bool Same(const Slab *a, const Slab *b) const;
+ void Merge(Slab *a, Slab *b);
+ void FillHeads(Slab *slab);
+
+ Slab *first_ = nullptr;
+ Slab *lastFind_ = nullptr;
+ std::vector heads_;
+};
+
+struct PendingNotifyMem {
+ MemBlockFlags flags;
+ uint32_t start;
+ uint32_t size;
+ uint64_t ticks;
+ uint32_t pc;
+ std::string tag;
+};
+
+static constexpr size_t MAX_PENDING_NOTIFIES = 512;
+static MemSlabMap allocMap;
+static MemSlabMap suballocMap;
+static MemSlabMap writeMap;
+static MemSlabMap textureMap;
+static std::vector pendingNotifies;
+static std::mutex pendingMutex;
+
+MemSlabMap::MemSlabMap() {
+ Reset();
+}
+
+MemSlabMap::~MemSlabMap() {
+ Clear();
+}
+
+bool MemSlabMap::Mark(uint32_t addr, uint32_t size, uint64_t ticks, uint32_t pc, bool allocated, const std::string &tag) {
+ uint32_t end = addr + size;
+ Slab *slab = FindSlab(addr);
+ Slab *firstMatch = nullptr;
+ while (slab != nullptr && slab->start < end) {
+ if (slab->start < addr)
+ slab = Split(slab, addr - slab->start);
+ // Don't replace slab, the return is the after part.
+ if (slab->end > end) {
+ Split(slab, end - slab->start);
+ }
+
+ slab->allocated = allocated;
+ if (pc != 0) {
+ slab->ticks = ticks;
+ slab->pc = pc;
+ }
+ if (!tag.empty())
+ slab->tag = tag;
+
+ // Move on to the next one.
+ if (firstMatch == nullptr)
+ firstMatch = slab;
+ slab = slab->next;
+ }
+
+ if (firstMatch != nullptr) {
+ // This will merge all those blocks to one.
+ MergeAdjacent(firstMatch);
+ return true;
+ }
+ return false;
+}
+
+bool MemSlabMap::Find(MemBlockFlags flags, uint32_t addr, uint32_t size, std::vector &results) {
+ uint32_t end = addr + size;
+ Slab *slab = FindSlab(addr);
+ bool found = false;
+ while (slab != nullptr && slab->start < end) {
+ if (slab->pc != 0 || !slab->tag.empty()) {
+ results.push_back({ flags, slab->start, slab->end - slab->start, slab->ticks, slab->pc, slab->tag, slab->allocated });
+ found = true;
+ }
+ slab = slab->next;
+ }
+ return found;
+}
+
+void MemSlabMap::Reset() {
+ Clear();
+
+ first_ = new Slab();
+ first_->end = MAX_SIZE;
+ lastFind_ = first_;
+
+ heads_.resize(SLICES, first_);
+}
+
+void MemSlabMap::DoState(PointerWrap &p) {
+ auto s = p.Section("MemSlabMap", 1);
+ if (!s)
+ return;
+
+ int count = 0;
+ if (p.mode == p.MODE_READ) {
+ Clear();
+ Do(p, count);
+
+ first_ = new Slab();
+ first_->DoState(p);
+ lastFind_ = first_;
+ --count;
+
+ heads_.resize(SLICES, nullptr);
+ FillHeads(first_);
+
+ Slab *slab = first_;
+ for (int i = 0; i < count; ++i) {
+ slab->next = new Slab();
+ slab->next->DoState(p);
+
+ slab->next->prev = slab;
+ slab = slab->next;
+
+ FillHeads(slab);
+ }
+ } else {
+ for (Slab *slab = first_; slab != nullptr; slab = slab->next)
+ ++count;
+ Do(p, count);
+
+ first_->DoState(p);
+ --count;
+
+ Slab *slab = first_;
+ for (int i = 0; i < count; ++i) {
+ slab->next->DoState(p);
+ slab = slab->next;
+ }
+ }
+}
+
+void MemSlabMap::Slab::DoState(PointerWrap &p) {
+ auto s = p.Section("MemSlabMapSlab", 1);
+ if (!s)
+ return;
+
+ Do(p, start);
+ Do(p, end);
+ Do(p, ticks);
+ Do(p, pc);
+ Do(p, allocated);
+ Do(p, tag);
+}
+
+void MemSlabMap::Clear() {
+ Slab *s = first_;
+ while (s != nullptr) {
+ Slab *next = s->next;
+ delete s;
+ s = next;
+ }
+ first_ = nullptr;
+ lastFind_ = nullptr;
+ heads_.clear();
+}
+
+MemSlabMap::Slab *MemSlabMap::FindSlab(uint32_t addr) {
+ // Jump ahead using our index.
+ Slab *slab = heads_[addr / SLICE_SIZE];
+ // We often move forward, so check the last find.
+ if (lastFind_->start > slab->start && lastFind_->start <= addr)
+ slab = lastFind_;
+
+ while (slab != nullptr && slab->start <= addr) {
+ if (slab->end > addr) {
+ lastFind_ = slab;
+ return slab;
+ }
+ slab = slab->next;
+ }
+ return nullptr;
+}
+
+MemSlabMap::Slab *MemSlabMap::Split(Slab *slab, uint32_t size) {
+ Slab *next = new Slab();
+ next->start = slab->start + size;
+ next->end = slab->end;
+ next->ticks = slab->ticks;
+ next->pc = slab->pc;
+ next->allocated = slab->allocated;
+ next->tag = slab->tag;
+ next->prev = slab;
+ next->next = slab->next;
+
+ slab->next = next;
+ if (next->next)
+ next->next->prev = next;
+
+ // If the split is big, we might have to update our index.
+ FillHeads(next);
+
+ slab->end = slab->start + size;
+ return next;
+}
+
+void MemSlabMap::MergeAdjacent(Slab *slab) {
+ while (slab->next != nullptr && Same(slab, slab->next)) {
+ Merge(slab, slab->next);
+ }
+ while (slab->prev != nullptr && Same(slab, slab->prev)) {
+ Merge(slab, slab->prev);
+ }
+}
+
+bool MemSlabMap::Same(const Slab *a, const Slab *b) const {
+ if (a->allocated != b->allocated)
+ return false;
+ if (a->pc != b->pc)
+ return false;
+ if (a->tag != b->tag)
+ return false;
+ return true;
+}
+
+void MemSlabMap::Merge(Slab *a, Slab *b) {
+ if (a->next == b) {
+ _assert_(a->end == b->start);
+ a->end = b->end;
+ a->next = b->next;
+
+ if (a->next)
+ a->next->prev = a;
+ } else if (a->prev == b) {
+ _assert_(b->end == a->start);
+ a->start = b->start;
+ a->prev = b->prev;
+
+ if (a->prev)
+ a->prev->next = a;
+ else if (first_ == b)
+ first_ = a;
+ } else {
+ _assert_(false);
+ }
+ // Take over index entries b had.
+ FillHeads(a);
+ if (b->ticks > a->ticks) {
+ a->ticks = b->ticks;
+ // In case we ignore PC for same.
+ a->pc = b->pc;
+ }
+ if (lastFind_ == b)
+ lastFind_ = a;
+ delete b;
+}
+
+void MemSlabMap::FillHeads(Slab *slab) {
+ uint32_t slice = slab->start / SLICE_SIZE;
+ uint32_t endSlice = (slab->end - 1) / SLICE_SIZE;
+
+ // For the first slice, only replace if it's the one we're removing.
+ if (slab->start == slice * SLICE_SIZE) {
+ heads_[slice] = slab;
+ }
+
+ // Now replace all the rest - we definitely cover the start of them.
+ for (uint32_t i = slice + 1; i <= endSlice; ++i) {
+ heads_[i] = slab;
+ }
+}
+
+void FlushPendingMemInfo() {
+ std::lock_guard guard(pendingMutex);
+ for (auto info : pendingNotifies) {
+ if (info.flags & MemBlockFlags::ALLOC) {
+ allocMap.Mark(info.start, info.size, info.ticks, info.pc, true, info.tag);
+ } else if (info.flags & MemBlockFlags::FREE) {
+ // Maintain the previous allocation tag for debugging.
+ allocMap.Mark(info.start, info.size, info.ticks, 0, false, "");
+ suballocMap.Mark(info.start, info.size, info.ticks, 0, false, "");
+ }
+ if (info.flags & MemBlockFlags::SUB_ALLOC) {
+ suballocMap.Mark(info.start, info.size, info.ticks, info.pc, true, info.tag);
+ } else if (info.flags & MemBlockFlags::SUB_FREE) {
+ // Maintain the previous allocation tag for debugging.
+ suballocMap.Mark(info.start, info.size, info.ticks, 0, false, "");
+ }
+ if (info.flags & MemBlockFlags::TEXTURE) {
+ textureMap.Mark(info.start, info.size, info.ticks, info.pc, true, info.tag);
+ }
+ if (info.flags & MemBlockFlags::WRITE) {
+ writeMap.Mark(info.start, info.size, info.ticks, info.pc, true, info.tag);
+ }
+ }
+ pendingNotifies.clear();
+}
+
+void NotifyMemInfo(MemBlockFlags flags, uint32_t start, uint32_t size, const std::string &tag) {
+ NotifyMemInfoPC(flags, start, size, currentMIPS->pc, tag);
+}
+
+void NotifyMemInfoPC(MemBlockFlags flags, uint32_t start, uint32_t size, uint32_t pc, const std::string &tag) {
+ if (size == 0) {
+ return;
+ }
+ // Clear the uncached and kernel bits.
+ start &= ~0xC0000000;
+
+ PendingNotifyMem info{ flags, start, size };
+ info.ticks = CoreTiming::GetTicks();
+ info.pc = pc;
+ info.tag = tag;
+
+ bool needFlush = false;
+ {
+ std::lock_guard guard(pendingMutex);
+ pendingNotifies.push_back(info);
+ needFlush = pendingNotifies.size() > MAX_PENDING_NOTIFIES;
+ }
+
+ if (needFlush) {
+ FlushPendingMemInfo();
+ }
+
+ if (flags & MemBlockFlags::WRITE) {
+ CBreakPoints::ExecMemCheck(start, true, size, pc, tag.c_str());
+ } else if (flags & MemBlockFlags::READ) {
+ CBreakPoints::ExecMemCheck(start, false, size, pc, tag.c_str());
+ }
+}
+
+std::vector FindMemInfo(uint32_t start, uint32_t size) {
+ FlushPendingMemInfo();
+ start &= ~0xC0000000;
+
+ std::vector results;
+ allocMap.Find(MemBlockFlags::ALLOC, start, size, results);
+ suballocMap.Find(MemBlockFlags::SUB_ALLOC, start, size, results);
+ writeMap.Find(MemBlockFlags::WRITE, start, size, results);
+ textureMap.Find(MemBlockFlags::TEXTURE, start, size, results);
+ return results;
+}
+
+std::vector FindMemInfoByFlag(MemBlockFlags flags, uint32_t start, uint32_t size) {
+ FlushPendingMemInfo();
+ start &= ~0xC0000000;
+
+ std::vector results;
+ if (flags & MemBlockFlags::ALLOC)
+ allocMap.Find(MemBlockFlags::ALLOC, start, size, results);
+ if (flags & MemBlockFlags::SUB_ALLOC)
+ suballocMap.Find(MemBlockFlags::SUB_ALLOC, start, size, results);
+ if (flags & MemBlockFlags::WRITE)
+ writeMap.Find(MemBlockFlags::WRITE, start, size, results);
+ if (flags & MemBlockFlags::TEXTURE)
+ textureMap.Find(MemBlockFlags::TEXTURE, start, size, results);
+ return results;
+}
+
+void MemBlockInfoInit() {
+ std::lock_guard guard(pendingMutex);
+ pendingNotifies.reserve(MAX_PENDING_NOTIFIES);
+}
+
+void MemBlockInfoShutdown() {
+ std::lock_guard guard(pendingMutex);
+ allocMap.Reset();
+ suballocMap.Reset();
+ writeMap.Reset();
+ textureMap.Reset();
+ pendingNotifies.clear();
+}
+
+void MemBlockInfoDoState(PointerWrap &p) {
+ auto s = p.Section("MemBlockInfo", 0, 1);
+ if (!s)
+ return;
+
+ FlushPendingMemInfo();
+ allocMap.DoState(p);
+ suballocMap.DoState(p);
+ writeMap.DoState(p);
+ textureMap.DoState(p);
+}
diff --git a/Core/Debugger/MemBlockInfo.h b/Core/Debugger/MemBlockInfo.h
new file mode 100644
index 000000000000..fa851ffdfe33
--- /dev/null
+++ b/Core/Debugger/MemBlockInfo.h
@@ -0,0 +1,57 @@
+// Copyright (c) 2021- PPSSPP Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0 or later versions.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official git repository and contact information can be found at
+// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
+
+#pragma once
+
+#include
+#include
+#include
+#include "Common/Common.h"
+
+class PointerWrap;
+
+enum class MemBlockFlags {
+ ALLOC = 0x0001,
+ SUB_ALLOC = 0x0002,
+ WRITE = 0x0004,
+ TEXTURE = 0x0008,
+ // Not actually logged.
+ READ = 0x0800,
+ FREE = 0x1000,
+ SUB_FREE = 0x2000,
+};
+ENUM_CLASS_BITOPS(MemBlockFlags);
+
+struct MemBlockInfo {
+ MemBlockFlags flags;
+ uint32_t start;
+ uint32_t size;
+ uint64_t ticks;
+ uint32_t pc;
+ std::string tag;
+ bool allocated;
+};
+
+void NotifyMemInfo(MemBlockFlags flags, uint32_t start, uint32_t size, const std::string &tag);
+void NotifyMemInfoPC(MemBlockFlags flags, uint32_t start, uint32_t size, uint32_t pc, const std::string &tag);
+
+std::vector FindMemInfo(uint32_t start, uint32_t size);
+std::vector FindMemInfoByFlag(MemBlockFlags flags, uint32_t start, uint32_t size);
+
+void MemBlockInfoInit();
+void MemBlockInfoShutdown();
+void MemBlockInfoDoState(PointerWrap &p);
diff --git a/Core/Dialog/PSPMsgDialog.cpp b/Core/Dialog/PSPMsgDialog.cpp
index 8361adbc3e9e..abfe39d7a085 100755
--- a/Core/Dialog/PSPMsgDialog.cpp
+++ b/Core/Dialog/PSPMsgDialog.cpp
@@ -344,7 +344,7 @@ int PSPMsgDialog::Update(int animSpeed) {
messageDialog.result = 0;
}
- Memory::Memcpy(messageDialogAddr, &messageDialog ,messageDialog.common.size);
+ Memory::Memcpy(messageDialogAddr, &messageDialog, messageDialog.common.size, "MsgDialogParam");
return 0;
}
diff --git a/Core/Dialog/PSPNetconfDialog.cpp b/Core/Dialog/PSPNetconfDialog.cpp
index f92385de0eb1..ee3bb1b739be 100644
--- a/Core/Dialog/PSPNetconfDialog.cpp
+++ b/Core/Dialog/PSPNetconfDialog.cpp
@@ -465,7 +465,7 @@ int PSPNetconfDialog::Update(int animSpeed) {
}
if (GetStatus() == SCE_UTILITY_STATUS_FINISHED || pendingStatus == SCE_UTILITY_STATUS_FINISHED)
- Memory::Memcpy(requestAddr, &request, request.common.size);
+ Memory::Memcpy(requestAddr, &request, request.common.size, "NetConfDialogParam");
return 0;
}
diff --git a/Core/Dialog/PSPSaveDialog.cpp b/Core/Dialog/PSPSaveDialog.cpp
index 43877f69fc79..7dd52c896579 100755
--- a/Core/Dialog/PSPSaveDialog.cpp
+++ b/Core/Dialog/PSPSaveDialog.cpp
@@ -1032,7 +1032,7 @@ int PSPSaveDialog::Update(int animSpeed)
}
if (ReadStatus() == SCE_UTILITY_STATUS_FINISHED || pendingStatus == SCE_UTILITY_STATUS_FINISHED)
- Memory::Memcpy(requestAddr, &request, request.common.size);
+ Memory::Memcpy(requestAddr, &request, request.common.size, "SaveDialogParam");
return 0;
}
diff --git a/Core/ELF/ElfReader.cpp b/Core/ELF/ElfReader.cpp
index eec53a3c2f72..917bcb48f1ce 100644
--- a/Core/ELF/ElfReader.cpp
+++ b/Core/ELF/ElfReader.cpp
@@ -19,7 +19,7 @@
#include "Core/Reporting.h"
#include "Core/MIPS/MIPSTables.h"
#include "Core/ELF/ElfReader.h"
-#include "Core/Debugger/Breakpoints.h"
+#include "Core/Debugger/MemBlockInfo.h"
#include "Core/Debugger/SymbolMap.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/HLE/sceKernelModule.h"
@@ -170,11 +170,7 @@ bool ElfReader::LoadRelocations(const Elf32_Rel *rels, int numRelocs)
break;
case R_MIPS_16:
- {
- char temp[256];
- op = (op & 0xFFFF0000) | (((int)(op & 0xFFFF) + (int)relocateTo) & 0xFFFF);
- MIPSDisAsm(MIPSOpcode(op), 0, temp);
- }
+ op = (op & 0xFFFF0000) | (((int)(op & 0xFFFF) + (int)relocateTo) & 0xFFFF);
break;
case R_MIPS_NONE:
@@ -190,6 +186,7 @@ bool ElfReader::LoadRelocations(const Elf32_Rel *rels, int numRelocs)
break;
}
Memory::Write_U32(op, addr);
+ NotifyMemInfo(MemBlockFlags::WRITE, addr, 4, "Relocation");
}
if (numErrors) {
WARN_LOG(LOADER, "%i bad relocations found!!!", numErrors);
@@ -348,6 +345,7 @@ void ElfReader::LoadRelocations2(int rel_seg)
}
Memory::Write_U32(op, rel_offset);
+ NotifyMemInfo(MemBlockFlags::WRITE, addr, 4, "Relocation2");
rcount += 1;
}
}
@@ -475,10 +473,11 @@ int ElfReader::LoadInto(u32 loadAddress, bool fromTop)
if (srcSize < dstSize)
{
memset(dst + srcSize, 0, dstSize - srcSize); //zero out bss
+ NotifyMemInfo(MemBlockFlags::WRITE, writeAddr + srcSize, dstSize - srcSize, "ELFZero");
}
memcpy(dst, src, srcSize);
- CBreakPoints::ExecMemCheck(writeAddr, true, dstSize, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, writeAddr, srcSize, "ELFLoad");
DEBUG_LOG(LOADER,"Loadable Segment Copied to %08x, size %08x", writeAddr, (u32)p->p_memsz);
}
}
diff --git a/Core/HLE/HLE.cpp b/Core/HLE/HLE.cpp
index 4427c6bd6c44..d31007beffcf 100644
--- a/Core/HLE/HLE.cpp
+++ b/Core/HLE/HLE.cpp
@@ -630,7 +630,7 @@ inline void CallSyscallWithFlags(const HLEFunction *info)
if (flags & HLE_CLEAR_STACK_BYTES) {
u32 stackStart = __KernelGetCurThreadStackStart();
if (currentMIPS->r[MIPS_REG_SP] - info->stackBytesToClear >= stackStart) {
- Memory::Memset(currentMIPS->r[MIPS_REG_SP] - info->stackBytesToClear, 0, info->stackBytesToClear);
+ Memory::Memset(currentMIPS->r[MIPS_REG_SP] - info->stackBytesToClear, 0, info->stackBytesToClear, "HLEStackClear");
}
}
diff --git a/Core/HLE/HLEHelperThread.cpp b/Core/HLE/HLEHelperThread.cpp
index a142820b9222..5c8a0278fbb2 100644
--- a/Core/HLE/HLEHelperThread.cpp
+++ b/Core/HLE/HLEHelperThread.cpp
@@ -33,7 +33,7 @@ HLEHelperThread::HLEHelperThread(const char *threadName, u32 instructions[], u32
u32 instrBytes = instrCount * sizeof(u32);
u32 totalBytes = instrBytes + sizeof(u32) * 2;
AllocEntry(totalBytes);
- Memory::Memcpy(entry_, instructions, instrBytes);
+ Memory::Memcpy(entry_, instructions, instrBytes, "HelperMIPS");
// Just to simplify things, we add the return here.
Memory::Write_U32(MIPS_MAKE_JR_RA(), entry_ + instrBytes + 0);
@@ -59,8 +59,8 @@ HLEHelperThread::~HLEHelperThread() {
}
void HLEHelperThread::AllocEntry(u32 size) {
- entry_ = kernelMemory.Alloc(size);
- Memory::Memset(entry_, 0, size);
+ entry_ = kernelMemory.Alloc(size, false, "HLEHelper");
+ Memory::Memset(entry_, 0, size, "HLEHelperClear");
currentMIPS->InvalidateICache(entry_, size);
}
diff --git a/Core/HLE/ReplaceTables.cpp b/Core/HLE/ReplaceTables.cpp
index 86f696e9949f..9e30cad0dccc 100644
--- a/Core/HLE/ReplaceTables.cpp
+++ b/Core/HLE/ReplaceTables.cpp
@@ -24,6 +24,7 @@
#include "Common/Log.h"
#include "Core/Config.h"
#include "Core/Debugger/Breakpoints.h"
+#include "Core/Debugger/MemBlockInfo.h"
#include "Core/Debugger/SymbolMap.h"
#include "Core/MemMap.h"
#include "Core/MIPS/JitCommon/JitCommon.h"
@@ -153,8 +154,8 @@ static int Replace_memcpy() {
}
RETURN(destPtr);
- CBreakPoints::ExecMemCheck(srcPtr, false, bytes, currentMIPS->pc);
- CBreakPoints::ExecMemCheck(destPtr, true, bytes, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, "ReplaceMemcpy");
+ NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemcpy");
return 10 + bytes / 4; // approximation
}
@@ -195,8 +196,8 @@ static int Replace_memcpy_jak() {
currentMIPS->r[MIPS_REG_A3] = destPtr + bytes;
RETURN(destPtr);
- CBreakPoints::ExecMemCheck(srcPtr, false, bytes, currentMIPS->pc);
- CBreakPoints::ExecMemCheck(destPtr, true, bytes, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, "ReplaceMemcpy");
+ NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemcpy");
return 5 + bytes * 8 + 2; // approximation. This is a slow memcpy - a byte copy loop..
}
@@ -223,8 +224,8 @@ static int Replace_memcpy16() {
}
RETURN(destPtr);
- CBreakPoints::ExecMemCheck(srcPtr, false, bytes, currentMIPS->pc);
- CBreakPoints::ExecMemCheck(destPtr, true, bytes, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, "ReplaceMemcpy16");
+ NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemcpy16");
return 10 + bytes / 4; // approximation
}
@@ -261,8 +262,8 @@ static int Replace_memcpy_swizzled() {
RETURN(0);
- CBreakPoints::ExecMemCheck(srcPtr, false, pitch * h, currentMIPS->pc);
- CBreakPoints::ExecMemCheck(destPtr, true, pitch * h, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcPtr, pitch * h, "ReplaceMemcpySwizzle");
+ NotifyMemInfo(MemBlockFlags::WRITE, destPtr, pitch * h, "ReplaceMemcpySwizzle");
return 10 + (pitch * h) / 4; // approximation
}
@@ -289,8 +290,8 @@ static int Replace_memmove() {
}
RETURN(destPtr);
- CBreakPoints::ExecMemCheck(srcPtr, false, bytes, currentMIPS->pc);
- CBreakPoints::ExecMemCheck(destPtr, true, bytes, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcPtr, bytes, "ReplaceMemmove");
+ NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemmove");
return 10 + bytes / 4; // approximation
}
@@ -311,7 +312,7 @@ static int Replace_memset() {
}
RETURN(destPtr);
- CBreakPoints::ExecMemCheck(destPtr, true, bytes, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemset");
return 10 + bytes / 4; // approximation
}
@@ -342,7 +343,7 @@ static int Replace_memset_jak() {
currentMIPS->r[MIPS_REG_A3] = -1;
RETURN(destPtr);
- CBreakPoints::ExecMemCheck(destPtr, true, bytes, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, destPtr, bytes, "ReplaceMemset");
return 5 + bytes * 6 + 2; // approximation (hm, inspecting the disasm this should be 5 + 6 * bytes + 2, but this is what works..)
}
@@ -590,9 +591,9 @@ static int Replace_dl_write_matrix() {
#endif
}
- CBreakPoints::ExecMemCheck(PARAM(2), false, count * sizeof(float), currentMIPS->pc);
- CBreakPoints::ExecMemCheck(PARAM(0) + 2 * sizeof(u32), true, sizeof(u32), currentMIPS->pc);
- CBreakPoints::ExecMemCheck(dlStruct[2], true, (count + 1) * sizeof(u32), currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, PARAM(2), count * sizeof(float), "ReplaceDLWriteMatrix");
+ NotifyMemInfo(MemBlockFlags::WRITE, PARAM(0) + 2 * sizeof(u32), sizeof(u32), "ReplaceDLWriteMatrix");
+ NotifyMemInfo(MemBlockFlags::WRITE, dlStruct[2], (count + 1) * sizeof(u32), "ReplaceDLWriteMatrix");
dlStruct[2] += (1 + count) * 4;
RETURN(dlStruct[2]);
@@ -640,7 +641,7 @@ static int Hook_godseaterburst_blit_texture() {
const u32 fb_address = Memory::Read_U32(fb_info);
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "godseaterburst_blit_texture");
}
return 0;
}
@@ -654,7 +655,7 @@ static int Hook_hexyzforce_monoclome_thread() {
const u32 fb_address = Memory::Read_U32(fb_info);
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "hexyzforce_monoclome_thread");
}
return 0;
}
@@ -671,7 +672,7 @@ static int Hook_topx_create_saveicon() {
const u32 fb_address = currentMIPS->r[MIPS_REG_V0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "topx_create_saveicon");
}
return 0;
}
@@ -680,7 +681,7 @@ static int Hook_ff1_battle_effect() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A1];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "ff1_battle_effect");
}
return 0;
}
@@ -690,7 +691,7 @@ static int Hook_dissidia_recordframe_avi() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A1];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "dissidia_recordframe_avi");
}
return 0;
}
@@ -711,7 +712,7 @@ static int Hook_brandish_download_frame() {
const u32 dest_address = currentMIPS->r[MIPS_REG_A1];
if (Memory::IsRAMAddress(dest_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "brandish_download_frame");
}
return 0;
}
@@ -722,7 +723,7 @@ static int Hook_growlanser_create_saveicon() {
const u32 sz = fmt == GE_FORMAT_8888 ? 0x00088000 : 0x00044000;
if (Memory::IsVRAMAddress(fb_address) && fmt <= 3) {
gpu->PerformMemoryDownload(fb_address, sz);
- CBreakPoints::ExecMemCheck(fb_address, true, sz, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, sz, "growlanser_create_saveicon");
}
return 0;
}
@@ -733,7 +734,7 @@ static int Hook_sd_gundam_g_generation_download_frame() {
const u32 sz = fmt == GE_FORMAT_8888 ? 0x00088000 : 0x00044000;
if (Memory::IsVRAMAddress(fb_address) && fmt <= 3) {
gpu->PerformMemoryDownload(fb_address, sz);
- CBreakPoints::ExecMemCheck(fb_address, true, sz, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, sz, "sd_gundam_g_generation_download_frame");
}
return 0;
}
@@ -742,7 +743,7 @@ static int Hook_narisokonai_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_V0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "narisokonai_download_frame");
}
return 0;
}
@@ -751,7 +752,7 @@ static int Hook_kirameki_school_life_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A2];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "kirameki_school_life_download_frame");
}
return 0;
}
@@ -760,7 +761,7 @@ static int Hook_orenoimouto_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A4];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "orenoimouto_download_frame");
}
return 0;
}
@@ -769,7 +770,7 @@ static int Hook_sakurasou_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_V0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "sakurasou_download_frame");
}
return 0;
}
@@ -778,7 +779,7 @@ static int Hook_suikoden1_and_2_download_frame_1() {
const u32 fb_address = currentMIPS->r[MIPS_REG_S4];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "suikoden1_and_2_download_frame_1");
}
return 0;
}
@@ -787,7 +788,7 @@ static int Hook_suikoden1_and_2_download_frame_2() {
const u32 fb_address = currentMIPS->r[MIPS_REG_S2];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "suikoden1_and_2_download_frame_2");
}
return 0;
}
@@ -798,7 +799,7 @@ static int Hook_rezel_cross_download_frame() {
const u32 sz = fmt == GE_FORMAT_8888 ? 0x00088000 : 0x00044000;
if (Memory::IsVRAMAddress(fb_address) && fmt <= 3) {
gpu->PerformMemoryDownload(fb_address, sz);
- CBreakPoints::ExecMemCheck(fb_address, true, sz, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, sz, "rezel_cross_download_frame");
}
return 0;
}
@@ -807,7 +808,7 @@ static int Hook_kagaku_no_ensemble_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_V0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "kagaku_no_ensemble_download_frame");
}
return 0;
}
@@ -816,7 +817,7 @@ static int Hook_soranokiseki_fc_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A2];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "soranokiseki_fc_download_frame");
}
return 0;
}
@@ -837,7 +838,7 @@ static int Hook_soranokiseki_sc_download_frame() {
const u32 dest_address = currentMIPS->r[MIPS_REG_A1];
if (Memory::IsRAMAddress(dest_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "soranokiseki_sc_download_frame");
}
return 0;
}
@@ -846,7 +847,7 @@ static int Hook_bokunonatsuyasumi4_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A3];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "bokunonatsuyasumi4_download_frame");
}
return 0;
}
@@ -858,7 +859,7 @@ static int Hook_danganronpa2_1_download_frame() {
const u32 fb_address = fb_base + fb_offset_fix;
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "danganronpa2_1_download_frame");
}
return 0;
}
@@ -870,7 +871,7 @@ static int Hook_danganronpa2_2_download_frame() {
const u32 fb_address = fb_base + fb_offset_fix;
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "danganronpa2_2_download_frame");
}
return 0;
}
@@ -882,7 +883,7 @@ static int Hook_danganronpa1_1_download_frame() {
const u32 fb_address = fb_base + fb_offset_fix;
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "danganronpa1_1_download_frame");
}
return 0;
}
@@ -896,7 +897,7 @@ static int Hook_danganronpa1_2_download_frame() {
const u32 fb_address = fb_base + fb_offset_fix;
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "danganronpa1_2_download_frame");
}
return 0;
}
@@ -905,7 +906,7 @@ static int Hook_kankabanchoutbr_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A1];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "kankabanchoutbr_download_frame");
}
return 0;
}
@@ -914,7 +915,7 @@ static int Hook_orenoimouto_download_frame_2() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A4];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "orenoimouto_download_frame_2");
}
return 0;
}
@@ -923,7 +924,7 @@ static int Hook_rewrite_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "rewrite_download_frame");
}
return 0;
}
@@ -932,7 +933,7 @@ static int Hook_kudwafter_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "kudwafter_download_frame");
}
return 0;
}
@@ -941,7 +942,7 @@ static int Hook_kumonohatateni_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "kumonohatateni_download_frame");
}
return 0;
}
@@ -950,7 +951,7 @@ static int Hook_otomenoheihou_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "otomenoheihou_download_frame");
}
return 0;
}
@@ -959,7 +960,7 @@ static int Hook_grisaianokajitsu_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "grisaianokajitsu_download_frame");
}
return 0;
}
@@ -968,7 +969,7 @@ static int Hook_kokoroconnect_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A3];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "kokoroconnect_download_frame");
}
return 0;
}
@@ -977,7 +978,7 @@ static int Hook_toheart2_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A1];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "toheart2_download_frame");
}
return 0;
}
@@ -986,7 +987,7 @@ static int Hook_toheart2_download_frame_2() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "toheart2_download_frame_2");
}
return 0;
}
@@ -995,7 +996,7 @@ static int Hook_flowers_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "flowers_download_frame");
}
return 0;
}
@@ -1004,7 +1005,7 @@ static int Hook_motorstorm_download_frame() {
const u32 fb_address = Memory::Read_U32(currentMIPS->r[MIPS_REG_A1] + 0x18);
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "motorstorm_download_frame");
}
return 0;
}
@@ -1013,7 +1014,7 @@ static int Hook_utawarerumono_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "utawarerumono_download_frame");
}
return 0;
}
@@ -1022,7 +1023,7 @@ static int Hook_photokano_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A1];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "photokano_download_frame");
}
return 0;
}
@@ -1031,7 +1032,7 @@ static int Hook_photokano_download_frame_2() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A1];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "photokano_download_frame_2");
}
return 0;
}
@@ -1040,7 +1041,7 @@ static int Hook_gakuenheaven_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "gakuenheaven_download_frame");
}
return 0;
}
@@ -1049,7 +1050,7 @@ static int Hook_youkosohitsujimura_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_V0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "youkosohitsujimura_download_frame");
}
return 0;
}
@@ -1080,7 +1081,7 @@ static int Hook_sdgundamggenerationportable_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A3];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "sdgundamggenerationportable_download_frame");
}
return 0;
}
@@ -1090,7 +1091,7 @@ static int Hook_atvoffroadfurypro_download_frame() {
const u32 fb_size = (currentMIPS->r[MIPS_REG_S4] >> 3) * currentMIPS->r[MIPS_REG_S3];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, fb_size);
- CBreakPoints::ExecMemCheck(fb_address, true, fb_size, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_size, "atvoffroadfurypro_download_frame");
}
return 0;
}
@@ -1100,7 +1101,7 @@ static int Hook_atvoffroadfuryblazintrails_download_frame() {
const u32 fb_size = (currentMIPS->r[MIPS_REG_S3] >> 3) * currentMIPS->r[MIPS_REG_S2];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, fb_size);
- CBreakPoints::ExecMemCheck(fb_address, true, fb_size, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_size, "atvoffroadfuryblazintrails_download_frame");
}
return 0;
}
@@ -1109,7 +1110,7 @@ static int Hook_littlebustersce_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_A0];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "littlebustersce_download_frame");
}
return 0;
}
@@ -1118,7 +1119,7 @@ static int Hook_shinigamitoshoujo_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_S2];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "shinigamitoshoujo_download_frame");
}
return 0;
}
@@ -1128,7 +1129,7 @@ static int Hook_atvoffroadfuryprodemo_download_frame() {
const u32 fb_size = ((currentMIPS->r[MIPS_REG_A0] + currentMIPS->r[MIPS_REG_A1]) >> 3) * currentMIPS->r[MIPS_REG_S2];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, fb_size);
- CBreakPoints::ExecMemCheck(fb_address, true, fb_size, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_size, "atvoffroadfuryprodemo_download_frame");
}
return 0;
}
@@ -1137,7 +1138,7 @@ static int Hook_unendingbloodycall_download_frame() {
const u32 fb_address = currentMIPS->r[MIPS_REG_T3];
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00088000, "unendingbloodycall_download_frame");
}
return 0;
}
@@ -1146,7 +1147,7 @@ static int Hook_omertachinmokunookitethelegacy_download_frame() {
const u32 fb_address = Memory::Read_U32(currentMIPS->r[MIPS_REG_SP] + 4);
if (Memory::IsVRAMAddress(fb_address)) {
gpu->PerformMemoryDownload(fb_address, 0x00044000);
- CBreakPoints::ExecMemCheck(fb_address, true, 0x00044000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, 0x00044000, "omertachinmokunookitethelegacy_download_frame");
}
return 0;
}
@@ -1166,7 +1167,7 @@ static int Hook_katamari_render_check() {
const u32 totalBytes = width * heightBlocks * heightBlockCount;
gpu->PerformMemoryDownload(fb_address, totalBytes);
- CBreakPoints::ExecMemCheck(fb_address, true, totalBytes, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, totalBytes, "katamari_render_check");
}
return 0;
}
@@ -1175,7 +1176,7 @@ static int Hook_katamari_screenshot_to_565() {
u32 fb_address;
if (GetMIPSStaticAddress(fb_address, 0x0040, 0x0044)) {
gpu->PerformMemoryDownload(0x04000000 | fb_address, 0x00088000);
- CBreakPoints::ExecMemCheck(0x04000000 | fb_address, true, 0x00088000, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, 0x04000000 | fb_address, 0x00088000, "katamari_screenshot_to_565");
}
return 0;
}
@@ -1198,7 +1199,7 @@ static int Hook_marvelalliance1_copy_a1_before() {
marvelalliance1_copy_size = currentMIPS->r[MIPS_REG_V0] - currentMIPS->r[MIPS_REG_V1];
gpu->PerformMemoryDownload(marvelalliance1_copy_src, marvelalliance1_copy_size);
- CBreakPoints::ExecMemCheck(marvelalliance1_copy_src, true, marvelalliance1_copy_size, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, marvelalliance1_copy_src, marvelalliance1_copy_size, "marvelalliance1_copy_a1_before");
return 0;
}
@@ -1209,14 +1210,14 @@ static int Hook_marvelalliance1_copy_a2_before() {
marvelalliance1_copy_size = currentMIPS->r[MIPS_REG_A1] - currentMIPS->r[MIPS_REG_A2];
gpu->PerformMemoryDownload(marvelalliance1_copy_src, marvelalliance1_copy_size);
- CBreakPoints::ExecMemCheck(marvelalliance1_copy_src, true, marvelalliance1_copy_size, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, marvelalliance1_copy_src, marvelalliance1_copy_size, "marvelalliance1_copy_a2_before");
return 0;
}
static int Hook_marvelalliance1_copy_after() {
gpu->PerformMemoryUpload(marvelalliance1_copy_dst, marvelalliance1_copy_size);
- CBreakPoints::ExecMemCheck(marvelalliance1_copy_dst, false, marvelalliance1_copy_size, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, marvelalliance1_copy_dst, marvelalliance1_copy_size, "marvelalliance1_copy_after");
return 0;
}
@@ -1249,7 +1250,7 @@ static int Hook_motorstorm_pixel_read() {
u32 fb_height = Memory::Read_U16(currentMIPS->r[MIPS_REG_A0] + 0x26);
u32 fb_stride = Memory::Read_U16(currentMIPS->r[MIPS_REG_A0] + 0x28);
gpu->PerformMemoryDownload(fb_address, fb_height * fb_stride);
- CBreakPoints::ExecMemCheck(fb_address, true, fb_height * fb_stride, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_height * fb_stride, "motorstorm_pixel_read");
return 0;
}
@@ -1259,7 +1260,7 @@ static int Hook_worms_copy_normalize_alpha() {
u32 fb_size = currentMIPS->r[MIPS_REG_A2];
if (Memory::IsVRAMAddress(fb_address) && Memory::IsValidRange(fb_address, fb_size)) {
gpu->PerformMemoryDownload(fb_address, fb_size);
- CBreakPoints::ExecMemCheck(fb_address, true, fb_size, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_size, "worms_copy_normalize_alpha");
}
return 0;
}
diff --git a/Core/HLE/sceAtrac.cpp b/Core/HLE/sceAtrac.cpp
index bdaeea8b98bf..1b3758507cb2 100644
--- a/Core/HLE/sceAtrac.cpp
+++ b/Core/HLE/sceAtrac.cpp
@@ -26,7 +26,7 @@
#include "Core/MemMapHelpers.h"
#include "Core/Reporting.h"
#include "Core/Config.h"
-#include "Core/Debugger/Breakpoints.h"
+#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HW/MediaEngine.h"
#include "Core/HW/BufferQueue.h"
@@ -1222,7 +1222,7 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3
int avret = swr_convert(atrac->swrCtx_, &out, numSamples, inbuf, numSamples);
if (outbufPtr != 0) {
u32 outBytes = numSamples * atrac->outputChannels_ * sizeof(s16);
- CBreakPoints::ExecMemCheck(outbufPtr, true, outBytes, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, "AtracDecode");
}
if (avret < 0) {
ERROR_LOG(ME, "swr_convert: Error while converting %d", avret);
@@ -1244,7 +1244,7 @@ u32 _AtracDecodeData(int atracID, u8 *outbuf, u32 outbufPtr, u32 *SamplesNum, u3
u32 outBytes = numSamples * atrac->outputChannels_ * sizeof(s16);
if (outbuf != nullptr) {
memset(outbuf, 0, outBytes);
- CBreakPoints::ExecMemCheck(outbufPtr, true, outBytes, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, outbufPtr, outBytes, "AtracDecode");
}
}
}
@@ -2310,7 +2310,7 @@ static u32 _sceAtracGetContextAddress(int atracID) {
u32 contextsize = 256;
atrac->context_ = kernelMemory.Alloc(contextsize, false, "Atrac Context");
if (atrac->context_.IsValid())
- Memory::Memset(atrac->context_.ptr, 0, 256);
+ Memory::Memset(atrac->context_.ptr, 0, 256, "AtracContextClear");
WARN_LOG(ME, "%08x=_sceAtracGetContextAddress(%i): allocated new context", atrac->context_.ptr, atracID);
}
@@ -2447,7 +2447,7 @@ static int sceAtracLowLevelDecode(int atracID, u32 sourceAddr, u32 sourceBytesCo
int avret = swr_convert(atrac->swrCtx_, &out, numSamples,
(const u8**)atrac->frame_->extended_data, numSamples);
u32 outBytes = numSamples * atrac->outputChannels_ * sizeof(s16);
- CBreakPoints::ExecMemCheck(samplesAddr, true, outBytes, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, outBytes, "AtracLowLevelDecode");
if (avret < 0) {
ERROR_LOG(ME, "swr_convert: Error while converting %d", avret);
}
diff --git a/Core/HLE/sceCcc.cpp b/Core/HLE/sceCcc.cpp
index 51da54829114..b47d805573c8 100644
--- a/Core/HLE/sceCcc.cpp
+++ b/Core/HLE/sceCcc.cpp
@@ -21,7 +21,7 @@
#include "Common/Serialize/Serializer.h"
#include "Common/Serialize/SerializeFuncs.h"
-#include "Core/Debugger/Breakpoints.h"
+#include "Core/Debugger/MemBlockInfo.h"
#include "Core/MemMap.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/FunctionWrappers.h"
@@ -118,8 +118,8 @@ static int sceCccUTF8toUTF16(u32 dstAddr, u32 dstSize, u32 srcAddr)
if (dst < dstEnd)
*dst++ = 0;
- CBreakPoints::ExecMemCheck(srcAddr, false, utf.byteIndex(), currentMIPS->pc);
- CBreakPoints::ExecMemCheck(dstAddr, true, dst.ptr - dstAddr, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcAddr, utf.byteIndex(), "sceCcc");
+ NotifyMemInfo(MemBlockFlags::WRITE, dstAddr, dst.ptr - dstAddr, "sceCcc");
return n;
}
@@ -154,8 +154,8 @@ static int sceCccUTF8toSJIS(u32 dstAddr, u32 dstSize, u32 srcAddr)
if (dst < dstEnd)
*dst++ = 0;
- CBreakPoints::ExecMemCheck(srcAddr, false, utf.byteIndex(), currentMIPS->pc);
- CBreakPoints::ExecMemCheck(dstAddr, true, dst.ptr - dstAddr, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcAddr, utf.byteIndex(), "sceCcc");
+ NotifyMemInfo(MemBlockFlags::WRITE, dstAddr, dst.ptr - dstAddr, "sceCcc");
return n;
}
@@ -185,8 +185,8 @@ static int sceCccUTF16toUTF8(u32 dstAddr, u32 dstSize, u32 srcAddr)
if (dst < dstEnd)
*dst++ = 0;
- CBreakPoints::ExecMemCheck(srcAddr, false, utf.shortIndex() * sizeof(uint16_t), currentMIPS->pc);
- CBreakPoints::ExecMemCheck(dstAddr, true, dst.ptr - dstAddr, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcAddr, utf.shortIndex() * sizeof(uint16_t), "sceCcc");
+ NotifyMemInfo(MemBlockFlags::WRITE, dstAddr, dst.ptr - dstAddr, "sceCcc");
return n;
}
@@ -221,8 +221,8 @@ static int sceCccUTF16toSJIS(u32 dstAddr, u32 dstSize, u32 srcAddr)
if (dst < dstEnd)
*dst++ = 0;
- CBreakPoints::ExecMemCheck(srcAddr, false, utf.shortIndex() * sizeof(uint16_t), currentMIPS->pc);
- CBreakPoints::ExecMemCheck(dstAddr, true, dst.ptr - dstAddr, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcAddr, utf.shortIndex() * sizeof(uint16_t), "sceCcc");
+ NotifyMemInfo(MemBlockFlags::WRITE, dstAddr, dst.ptr - dstAddr, "sceCcc");
return n;
}
@@ -257,8 +257,8 @@ static int sceCccSJIStoUTF8(u32 dstAddr, u32 dstSize, u32 srcAddr)
if (dst < dstEnd)
*dst++ = 0;
- CBreakPoints::ExecMemCheck(srcAddr, false, sjis.byteIndex(), currentMIPS->pc);
- CBreakPoints::ExecMemCheck(dstAddr, true, dst.ptr - dstAddr, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcAddr, sjis.byteIndex(), "sceCcc");
+ NotifyMemInfo(MemBlockFlags::WRITE, dstAddr, dst.ptr - dstAddr, "sceCcc");
return n;
}
@@ -293,8 +293,8 @@ static int sceCccSJIStoUTF16(u32 dstAddr, u32 dstSize, u32 srcAddr)
if (dst < dstEnd)
*dst++ = 0;
- CBreakPoints::ExecMemCheck(srcAddr, false, sjis.byteIndex(), currentMIPS->pc);
- CBreakPoints::ExecMemCheck(dstAddr, true, dst.ptr - dstAddr, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, srcAddr, sjis.byteIndex(), "sceCcc");
+ NotifyMemInfo(MemBlockFlags::WRITE, dstAddr, dst.ptr - dstAddr, "sceCcc");
return n;
}
diff --git a/Core/HLE/sceDmac.cpp b/Core/HLE/sceDmac.cpp
index 4f186facfe7b..4defe951cac7 100644
--- a/Core/HLE/sceDmac.cpp
+++ b/Core/HLE/sceDmac.cpp
@@ -50,7 +50,8 @@ static int __DmacMemcpy(u32 dst, u32 src, u32 size) {
skip = gpu->PerformMemoryCopy(dst, src, size);
}
if (!skip) {
- Memory::Memcpy(dst, Memory::GetPointer(src), size);
+ // TODO: InvalidateICache src before copy?
+ Memory::Memcpy(dst, Memory::GetPointer(src), size, "DmacMemcpy");
currentMIPS->InvalidateICache(dst, size);
}
diff --git a/Core/HLE/sceHeap.cpp b/Core/HLE/sceHeap.cpp
index e1c802b1498b..e51f6b1d8326 100644
--- a/Core/HLE/sceHeap.cpp
+++ b/Core/HLE/sceHeap.cpp
@@ -202,7 +202,7 @@ static int sceHeapCreateHeap(const char* name, u32 heapSize, int attr, u32 param
heap->address = addr;
// Some of the heap is reserved by the implementation (the first 128 bytes, and 8 after each block.)
- heap->alloc.Init(heap->address + 128, heap->size - 128);
+ heap->alloc.Init(heap->address + 128, heap->size - 128, true);
heapList[heap->address] = heap;
DEBUG_LOG(HLE, "%08x=sceHeapCreateHeap(%s, %08x, %08x, %08x)", heap->address, name, heapSize, attr, paramsPtr);
return heap->address;
diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp
index 9abfd60f5168..401c1e1a8f0f 100644
--- a/Core/HLE/sceIo.cpp
+++ b/Core/HLE/sceIo.cpp
@@ -29,7 +29,7 @@
#include "Core/Core.h"
#include "Core/Config.h"
#include "Core/ConfigValues.h"
-#include "Core/Debugger/Breakpoints.h"
+#include "Core/Debugger/MemBlockInfo.h"
#include "Core/ELF/ParamSFO.h"
#include "Core/MemMapHelpers.h"
#include "Core/System.h"
@@ -1026,7 +1026,7 @@ static bool __IoRead(int &result, int id, u32 data_addr, int size, int &us) {
result = SCE_KERNEL_ERROR_ILLEGAL_ADDR;
return true;
} else if (Memory::IsValidAddress(data_addr)) {
- CBreakPoints::ExecMemCheck(data_addr, true, size, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::WRITE, data_addr, size, "IoRead");
u8 *data = (u8 *)Memory::GetPointer(data_addr);
u32 validSize = Memory::ValidSize(data_addr, size);
if (f->npdrm) {
@@ -1162,7 +1162,7 @@ static bool __IoWrite(int &result, int id, u32 data_addr, int size, int &us) {
return true;
}
- CBreakPoints::ExecMemCheck(data_addr, false, size, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, data_addr, size, "IoWrite");
bool useThread = __KernelIsDispatchEnabled() && ioManagerThreadEnabled && size > IO_THREAD_MIN_DATA_SIZE;
if (useThread) {
diff --git a/Core/HLE/sceKernelHeap.cpp b/Core/HLE/sceKernelHeap.cpp
index af2cbdff1d0c..f584684cbbb9 100644
--- a/Core/HLE/sceKernelHeap.cpp
+++ b/Core/HLE/sceKernelHeap.cpp
@@ -60,7 +60,7 @@ static int sceKernelCreateHeap(int partitionId, int size, int flags, const char
heap->name = Name ? Name : ""; // Not sure if this needs validation.
heap->size = allocSize;
heap->address = addr;
- heap->alloc.Init(heap->address + 128, heap->size - 128);
+ heap->alloc.Init(heap->address + 128, heap->size - 128, true);
heap->uid = uid;
return hleLogSuccessInfoX(SCEKERNEL, uid);
}
diff --git a/Core/HLE/sceKernelInterrupt.cpp b/Core/HLE/sceKernelInterrupt.cpp
index 8d8e4124db02..adaabd362fad 100644
--- a/Core/HLE/sceKernelInterrupt.cpp
+++ b/Core/HLE/sceKernelInterrupt.cpp
@@ -29,7 +29,7 @@
#include "Core/HLE/FunctionWrappers.h"
#include "Core/MIPS/MIPS.h"
-#include "Core/Debugger/Breakpoints.h"
+#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HLE/sceKernel.h"
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceKernelInterrupt.h"
@@ -618,6 +618,7 @@ static u32 sceKernelMemset(u32 addr, u32 fillc, u32 n)
Memory::Memset(addr, c, n);
}
}
+ NotifyMemInfo(MemBlockFlags::WRITE, addr, n, "KernelMemset");
return addr;
}
@@ -657,8 +658,8 @@ static u32 sceKernelMemcpy(u32 dst, u32 src, u32 size)
}
}
- CBreakPoints::ExecMemCheck(src, false, size, currentMIPS->pc);
- CBreakPoints::ExecMemCheck(dst, true, size, currentMIPS->pc);
+ NotifyMemInfo(MemBlockFlags::READ, src, size, "KernelMemcpy");
+ NotifyMemInfo(MemBlockFlags::WRITE, dst, size, "KernelMemcpy");
return dst;
}
@@ -689,6 +690,8 @@ static u32 sysclib_memcpy(u32 dst, u32 src, u32 size) {
if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) {
memcpy(Memory::GetPointer(dst), Memory::GetPointer(src), size);
}
+ NotifyMemInfo(MemBlockFlags::READ, src, size, "KernelMemcpy");
+ NotifyMemInfo(MemBlockFlags::WRITE, dst, size, "KernelMemcpy");
return dst;
}
@@ -754,6 +757,7 @@ static u32 sysclib_memset(u32 destAddr, int data, int size) {
if (Memory::IsValidRange(destAddr, size)) {
memset(Memory::GetPointer(destAddr), data, size);
}
+ NotifyMemInfo(MemBlockFlags::WRITE, destAddr, size, "KernelMemset");
return 0;
}
@@ -786,6 +790,8 @@ static u32 sysclib_memmove(u32 dst, u32 src, u32 size) {
if (Memory::IsValidRange(dst, size) && Memory::IsValidRange(src, size)) {
memmove(Memory::GetPointer(dst), Memory::GetPointer(src), size);
}
+ NotifyMemInfo(MemBlockFlags::READ, src, size, "KernelMemmove");
+ NotifyMemInfo(MemBlockFlags::WRITE, dst, size, "KernelMemmove");
return 0;
}
diff --git a/Core/HLE/sceKernelMemory.cpp b/Core/HLE/sceKernelMemory.cpp
index 50b0b75fdfb6..fa8a80b61fec 100644
--- a/Core/HLE/sceKernelMemory.cpp
+++ b/Core/HLE/sceKernelMemory.cpp
@@ -20,16 +20,17 @@
#include
#include