Merge pull request #14056 from unknownbrackets/debugger-mem

Track memory allocations and writes for debug info
This commit is contained in:
Henrik Rydgård 2021-02-21 10:18:11 +01:00 committed by GitHub
commit 2f3bc2d373
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
55 changed files with 1052 additions and 368 deletions

View file

@ -1485,6 +1485,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

View file

@ -429,6 +429,7 @@
<ClCompile Include="..\ext\udis86\syn.c" />
<ClCompile Include="..\ext\udis86\udis86.c" />
<ClCompile Include="AVIDump.cpp" />
<ClCompile Include="Debugger\MemBlockInfo.cpp" />
<ClCompile Include="Debugger\WebSocket.cpp" />
<ClCompile Include="Debugger\WebSocket\BreakpointSubscriber.cpp" />
<ClCompile Include="Debugger\WebSocket\CPUCoreSubscriber.cpp" />
@ -977,6 +978,7 @@
<ClInclude Include="..\ext\udis86\udis86.h" />
<ClInclude Include="AVIDump.h" />
<ClInclude Include="ConfigValues.h" />
<ClInclude Include="Debugger\MemBlockInfo.h" />
<ClInclude Include="Debugger\WebSocket.h" />
<ClInclude Include="Debugger\WebSocket\BreakpointSubscriber.h" />
<ClInclude Include="Debugger\WebSocket\GameSubscriber.h" />

View file

@ -977,6 +977,9 @@
<ClCompile Include="MIPS\fake\FakeJit.cpp">
<Filter>MIPS\fake</Filter>
</ClCompile>
<ClCompile Include="Debugger\MemBlockInfo.cpp">
<Filter>Debugger</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ELF\ElfReader.h">
@ -1670,6 +1673,9 @@
<ClInclude Include="MIPS\fake\FakeJit.h">
<Filter>MIPS\fake</Filter>
</ClInclude>
<ClInclude Include="Debugger\MemBlockInfo.h">
<Filter>Debugger</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />

View file

@ -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;

View file

@ -40,14 +40,15 @@ static std::mutex memCheckMutex_;
std::vector<MemCheck> CBreakPoints::memChecks_;
std::vector<MemCheck *> 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;

View file

@ -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 @@ public:
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.

View file

@ -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 <mutex>
#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<MemBlockInfo> &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<Slab *> 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<PendingNotifyMem> 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<MemBlockInfo> &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<std::mutex> 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<std::mutex> 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<MemBlockInfo> FindMemInfo(uint32_t start, uint32_t size) {
FlushPendingMemInfo();
start &= ~0xC0000000;
std::vector<MemBlockInfo> 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<MemBlockInfo> FindMemInfoByFlag(MemBlockFlags flags, uint32_t start, uint32_t size) {
FlushPendingMemInfo();
start &= ~0xC0000000;
std::vector<MemBlockInfo> 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<std::mutex> guard(pendingMutex);
pendingNotifies.reserve(MAX_PENDING_NOTIFIES);
}
void MemBlockInfoShutdown() {
std::lock_guard<std::mutex> 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);
}

View file

@ -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 <cstdint>
#include <string>
#include <vector>
#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<MemBlockInfo> FindMemInfo(uint32_t start, uint32_t size);
std::vector<MemBlockInfo> FindMemInfoByFlag(MemBlockFlags flags, uint32_t start, uint32_t size);
void MemBlockInfoInit();
void MemBlockInfoShutdown();
void MemBlockInfoDoState(PointerWrap &p);

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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");
}
}

View file

@ -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);
}

View file

@ -25,6 +25,7 @@
#include "Common/Swap.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"
@ -154,8 +155,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
}
@ -196,8 +197,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..
}
@ -224,8 +225,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
}
@ -262,8 +263,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
}
@ -290,8 +291,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
}
@ -312,7 +313,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
}
@ -343,7 +344,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..)
}
@ -603,9 +604,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]);
@ -653,7 +654,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;
}
@ -667,7 +668,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;
}
@ -684,7 +685,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;
}
@ -693,7 +694,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;
}
@ -703,7 +704,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;
}
@ -724,7 +725,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;
}
@ -735,7 +736,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;
}
@ -746,7 +747,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;
}
@ -755,7 +756,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;
}
@ -764,7 +765,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;
}
@ -773,7 +774,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;
}
@ -782,7 +783,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;
}
@ -791,7 +792,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;
}
@ -800,7 +801,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;
}
@ -811,7 +812,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;
}
@ -820,7 +821,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;
}
@ -829,7 +830,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;
}
@ -850,7 +851,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;
}
@ -859,7 +860,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;
}
@ -871,7 +872,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;
}
@ -883,7 +884,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;
}
@ -895,7 +896,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;
}
@ -909,7 +910,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;
}
@ -918,7 +919,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;
}
@ -927,7 +928,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;
}
@ -936,7 +937,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;
}
@ -945,7 +946,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;
}
@ -954,7 +955,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;
}
@ -963,7 +964,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;
}
@ -972,7 +973,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;
}
@ -981,7 +982,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;
}
@ -990,7 +991,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;
}
@ -999,7 +1000,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;
}
@ -1008,7 +1009,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;
}
@ -1017,7 +1018,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;
}
@ -1026,7 +1027,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;
}
@ -1035,7 +1036,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;
}
@ -1044,7 +1045,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;
}
@ -1053,7 +1054,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;
}
@ -1062,7 +1063,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;
}
@ -1093,7 +1094,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;
}
@ -1103,7 +1104,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;
}
@ -1113,7 +1114,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;
}
@ -1122,7 +1123,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;
}
@ -1131,7 +1132,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;
}
@ -1141,7 +1142,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;
}
@ -1150,7 +1151,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;
}
@ -1159,7 +1160,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;
}
@ -1179,7 +1180,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;
}
@ -1188,7 +1189,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;
}
@ -1211,7 +1212,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;
}
@ -1222,14 +1223,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;
}
@ -1262,7 +1263,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;
}
@ -1272,7 +1273,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;
}

View file

@ -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"
@ -1226,7 +1226,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);
@ -1248,7 +1248,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");
}
}
}
@ -2314,7 +2314,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);
}
@ -2451,7 +2451,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);
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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) {

View file

@ -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);
}

View file

@ -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;
}

View file

@ -20,16 +20,17 @@
#include <vector>
#include <map>
#include "Common/Serialize/Serializer.h"
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/Serialize/SerializeMap.h"
#include "Core/CoreTiming.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/System.h"
#include "Core/MIPS/MIPS.h"
#include "Core/MemMapHelpers.h"
#include "Core/CoreTiming.h"
#include "Core/Reporting.h"
#include "Common/Serialize/Serializer.h"
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/Serialize/SerializeMap.h"
#include "Core/HLE/sceKernel.h"
#include "Core/HLE/sceKernelThread.h"
@ -426,10 +427,11 @@ void __KernelFplEndCallback(SceUID threadID, SceUID prevCallbackId);
void __KernelMemoryInit()
{
kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase());
userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase());
Memory::Memset(PSP_GetKernelMemoryBase(), 0, PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase());
Memory::Memset(PSP_GetUserMemoryBase(), 0, PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase());
MemBlockInfoInit();
kernelMemory.Init(PSP_GetKernelMemoryBase(), PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase(), false);
userMemory.Init(PSP_GetUserMemoryBase(), PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase(), false);
Memory::Memset(PSP_GetKernelMemoryBase(), 0, PSP_GetKernelMemoryEnd() - PSP_GetKernelMemoryBase(), "MemInit");
Memory::Memset(PSP_GetUserMemoryBase(), 0, PSP_GetUserMemoryEnd() - PSP_GetUserMemoryBase(), "MemInit");
INFO_LOG(SCEKERNEL, "Kernel and user memory pools initialized");
vplWaitTimer = CoreTiming::RegisterEvent("VplTimeout", __KernelVplTimeout);
@ -471,6 +473,8 @@ void __KernelMemoryDoState(PointerWrap &p)
if (s >= 2) {
Do(p, tlsplThreadEndChecks);
}
MemBlockInfoDoState(p);
}
void __KernelMemoryShutdown()
@ -486,6 +490,7 @@ void __KernelMemoryShutdown()
#endif
kernelMemory.Shutdown();
tlsplThreadEndChecks.clear();
MemBlockInfoShutdown();
}
enum SceKernelFplAttr
@ -510,6 +515,7 @@ static bool __KernelUnlockFplForThread(FPL *fpl, FplWaitingThread &threadInfo, u
{
u32 blockPtr = fpl->address + fpl->alignedSize * blockNum;
Memory::Write_U32(blockPtr, threadInfo.addrPtr);
NotifyMemInfo(MemBlockFlags::SUB_ALLOC, blockPtr, fpl->alignedSize, "FplAllocate");
}
else
return false;
@ -722,6 +728,7 @@ int sceKernelAllocateFpl(SceUID uid, u32 blockPtrAddr, u32 timeoutPtr)
if (blockNum >= 0) {
u32 blockPtr = fpl->address + fpl->alignedSize * blockNum;
Memory::Write_U32(blockPtr, blockPtrAddr);
NotifyMemInfo(MemBlockFlags::SUB_ALLOC, blockPtr, fpl->alignedSize, "FplAllocate");
} else {
SceUID threadID = __KernelGetCurThread();
HLEKernel::RemoveWaitingThread(fpl->waitingThreads, threadID);
@ -753,6 +760,7 @@ int sceKernelAllocateFplCB(SceUID uid, u32 blockPtrAddr, u32 timeoutPtr)
if (blockNum >= 0) {
u32 blockPtr = fpl->address + fpl->alignedSize * blockNum;
Memory::Write_U32(blockPtr, blockPtrAddr);
NotifyMemInfo(MemBlockFlags::SUB_ALLOC, blockPtr, fpl->alignedSize, "FplAllocate");
} else {
SceUID threadID = __KernelGetCurThread();
HLEKernel::RemoveWaitingThread(fpl->waitingThreads, threadID);
@ -784,6 +792,7 @@ int sceKernelTryAllocateFpl(SceUID uid, u32 blockPtrAddr)
if (blockNum >= 0) {
u32 blockPtr = fpl->address + fpl->alignedSize * blockNum;
Memory::Write_U32(blockPtr, blockPtrAddr);
NotifyMemInfo(MemBlockFlags::SUB_ALLOC, blockPtr, fpl->alignedSize, "FplAllocate");
return 0;
} else {
return SCE_KERNEL_ERROR_NO_MEMORY;
@ -812,6 +821,9 @@ int sceKernelFreeFpl(SceUID uid, u32 blockPtr)
return SCE_KERNEL_ERROR_ILLEGAL_MEMBLOCK;
} else {
if (fpl->freeBlock(blockNum)) {
u32 blockPtr = fpl->address + fpl->alignedSize * blockNum;
NotifyMemInfo(MemBlockFlags::SUB_FREE, blockPtr, fpl->alignedSize, "FplFree");
DEBUG_LOG(SCEKERNEL, "sceKernelFreeFpl(%i, %08x)", uid, blockPtr);
__KernelSortFplThreads(fpl);
@ -1503,7 +1515,7 @@ SceUID sceKernelCreateVpl(const char *name, int partition, u32 attr, u32 vplSize
// A vpl normally has accounting stuff in the first 32 bytes.
vpl->address = memBlockPtr + 0x20;
vpl->alloc.Init(vpl->address, vpl->nv.poolSize);
vpl->alloc.Init(vpl->address, vpl->nv.poolSize, true);
vpl->header = PSPPointer<SceKernelVplHeader>::Create(memBlockPtr);
vpl->header->Init(memBlockPtr, vplSize);
@ -1572,7 +1584,7 @@ static bool __KernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 &error, b
} else {
// Padding (normally used to track the allocation.)
u32 allocSize = size + 8;
addr = vpl->alloc.Alloc(allocSize, true);
addr = vpl->alloc.Alloc(allocSize, true, "VplAllocate");
}
if (addr != (u32) -1) {
Memory::Write_U32(addr, addrPtr);
@ -1953,9 +1965,10 @@ int __KernelFreeTls(TLSPL *tls, SceUID threadID)
u32 alignedSize = (tls->ntls.blockSize + tls->alignment - 1) & ~(tls->alignment - 1);
u32 freedAddress = tls->address + freeBlock * alignedSize;
NotifyMemInfo(MemBlockFlags::SUB_ALLOC, freedAddress, tls->ntls.blockSize, "TlsFree");
// Whenever freeing a block, clear it (even if it's not going to wake anyone.)
Memory::Memset(freedAddress, 0, tls->ntls.blockSize);
Memory::Memset(freedAddress, 0, tls->ntls.blockSize, "TlsFree");
// First, let's remove the end check for the freeing thread.
auto freeingLocked = tlsplThreadEndChecks.equal_range(threadID);
@ -2227,10 +2240,12 @@ int sceKernelGetTlsAddr(SceUID uid)
u32 alignedSize = (tls->ntls.blockSize + tls->alignment - 1) & ~(tls->alignment - 1);
u32 allocAddress = tls->address + allocBlock * alignedSize;
NotifyMemInfo(MemBlockFlags::SUB_ALLOC, allocAddress, tls->ntls.blockSize, "TlsAddr");
// We clear the blocks upon first allocation (and also when they are freed, both are necessary.)
if (needsClear)
Memory::Memset(allocAddress, 0, tls->ntls.blockSize);
if (needsClear) {
Memory::Memset(allocAddress, 0, tls->ntls.blockSize, "TlsAddr");
}
return allocAddress;
}

View file

@ -861,7 +861,7 @@ void PSPModule::Cleanup() {
for (u32 i = 0; i < (u32)(nm.text_size + 3); i += 4) {
Memory::Write_U32(MIPS_MAKE_BREAK(1), nm.text_addr + i);
}
Memory::Memset(nm.text_addr + nm.text_size, -1, nm.data_size + nm.bss_size);
Memory::Memset(nm.text_addr + nm.text_size, -1, nm.data_size + nm.bss_size, "ModuleClear");
// Let's also invalidate, just to make sure it's cleared out for any future data.
currentMIPS->InvalidateICache(memoryBlockAddr, memoryBlockSize);
@ -1743,13 +1743,13 @@ bool __KernelLoadExec(const char *filename, u32 paramPtr, std::string *error_str
if (param.args > 0) {
u32 argpAddr = param.argp;
param_argp = new u8[param.args];
Memory::Memcpy(param_argp, argpAddr, param.args);
Memory::Memcpy(param_argp, argpAddr, param.args, "KernelLoadParam");
}
if (param.keyp != 0) {
u32 keyAddr = param.keyp;
size_t keylen = strlen(Memory::GetCharPointer(keyAddr))+1;
param_key = new u8[keylen];
Memory::Memcpy(param_key, keyAddr, (u32)keylen);
Memory::Memcpy(param_key, keyAddr, (u32)keylen, "KernelLoadParam");
}
__KernelLoadReset();

View file

@ -105,7 +105,7 @@ struct MsgPipeWaitingThread
void ReadBuffer(u32 destPtr, u32 len)
{
Memory::Memcpy(destPtr, bufAddr + bufSize - freeSize, len);
Memory::Memcpy(destPtr, bufAddr + bufSize - freeSize, len, "MsgPipeReadBuffer");
freeSize -= len;
if (transferredBytes.IsValid())
*transferredBytes += len;
@ -113,7 +113,7 @@ struct MsgPipeWaitingThread
void WriteBuffer(u32 srcPtr, u32 len)
{
Memory::Memcpy(bufAddr + (bufSize - freeSize), srcPtr, len);
Memory::Memcpy(bufAddr + (bufSize - freeSize), srcPtr, len, "MsgPipeWriteBuffer");
freeSize -= len;
if (transferredBytes.IsValid())
*transferredBytes += len;
@ -399,7 +399,7 @@ static int __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int wa
if (bytesToSend != 0)
{
Memory::Memcpy(m->buffer + (m->nmp.bufSize - m->nmp.freeSize), sendBufAddr, bytesToSend);
Memory::Memcpy(m->buffer + (m->nmp.bufSize - m->nmp.freeSize), sendBufAddr, bytesToSend, "MsgPipeSend");
m->nmp.freeSize -= bytesToSend;
curSendAddr += bytesToSend;
sendSize -= bytesToSend;
@ -492,7 +492,7 @@ static int __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSiz
u32 bytesToReceive = std::min(receiveSize, m->GetUsedSize());
if (bytesToReceive != 0)
{
Memory::Memcpy(curReceiveAddr, m->buffer, bytesToReceive);
Memory::Memcpy(curReceiveAddr, m->buffer, bytesToReceive, "MsgPipeReceive");
m->nmp.freeSize += bytesToReceive;
memmove(Memory::GetPointer(m->buffer), Memory::GetPointer(m->buffer) + bytesToReceive, m->GetUsedSize());
curReceiveAddr += bytesToReceive;

View file

@ -426,7 +426,7 @@ public:
bool FillStack() {
// Fill the stack.
if ((nt.attr & PSP_THREAD_ATTR_NO_FILLSTACK) == 0) {
Memory::Memset(currentStack.start, 0xFF, nt.stackSize);
Memory::Memset(currentStack.start, 0xFF, nt.stackSize, "ThreadFillStack");
}
context.r[MIPS_REG_SP] = currentStack.start + nt.stackSize;
currentStack.end = context.r[MIPS_REG_SP];
@ -434,7 +434,7 @@ public:
context.r[MIPS_REG_SP] -= 256;
context.r[MIPS_REG_K0] = context.r[MIPS_REG_SP];
u32 k0 = context.r[MIPS_REG_K0];
Memory::Memset(k0, 0, 0x100);
Memory::Memset(k0, 0, 0x100, "ThreadK0");
Memory::Write_U32(GetUID(), k0 + 0xc0);
Memory::Write_U32(nt.initialStack, k0 + 0xc8);
Memory::Write_U32(0xffffffff, k0 + 0xf8);
@ -450,7 +450,7 @@ public:
DEBUG_LOG(SCEKERNEL, "Freeing thread stack %s", nt.name);
if ((nt.attr & PSP_THREAD_ATTR_CLEAR_STACK) != 0 && nt.initialStack != 0) {
Memory::Memset(nt.initialStack, 0, nt.stackSize);
Memory::Memset(nt.initialStack, 0, nt.stackSize, "ThreadFreeStack");
}
if (nt.attr & PSP_THREAD_ATTR_KERNEL) {
@ -475,7 +475,7 @@ public:
nt.stackSize = currentStack.end - currentStack.start;
// We still drop the threadID at the bottom and fill it, but there's no k0.
Memory::Memset(currentStack.start, 0xFF, nt.stackSize);
Memory::Memset(currentStack.start, 0xFF, nt.stackSize, "ThreadExtendStack");
Memory::Write_U32(GetUID(), nt.initialStack);
return true;
}
@ -934,7 +934,7 @@ void __KernelThreadingInit()
lastSwitchCycles = 0;
idleThreadHackAddr = kernelMemory.Alloc(blockSize, false, "threadrethack");
Memory::Memcpy(idleThreadHackAddr, idleThreadCode, sizeof(idleThreadCode));
Memory::Memcpy(idleThreadHackAddr, idleThreadCode, sizeof(idleThreadCode), "ThreadMIPS");
u32 pos = idleThreadHackAddr + sizeof(idleThreadCode);
for (size_t i = 0; i < ARRAY_SIZE(threadHacks); ++i) {
@ -1282,15 +1282,15 @@ u32 sceKernelReferThreadStatus(u32 threadID, u32 statusPtr)
t->nt.nativeSize = THREADINFO_SIZE_AFTER_260;
if (wantedSize != 0)
Memory::Memcpy(statusPtr, &t->nt, std::min(wantedSize, (u32)sizeof(t->nt)));
Memory::Memcpy(statusPtr, &t->nt, std::min(wantedSize, (u32)sizeof(t->nt)), "ThreadStatus");
// TODO: What is this value? Basic tests show 0...
if (wantedSize > sizeof(t->nt))
Memory::Memset(statusPtr + sizeof(t->nt), 0, wantedSize - sizeof(t->nt));
Memory::Memset(statusPtr + sizeof(t->nt), 0, wantedSize - sizeof(t->nt), "ThreadStatus");
} else {
t->nt.nativeSize = THREADINFO_SIZE;
u32 sz = std::min(THREADINFO_SIZE, wantedSize);
if (sz != 0)
Memory::Memcpy(statusPtr, &t->nt, sz);
Memory::Memcpy(statusPtr, &t->nt, sz, "ThreadStatus");
}
hleEatCycles(1400);
@ -1933,7 +1933,7 @@ SceUID __KernelSetupRootThread(SceUID moduleID, int args, const char *argp, int
u32 location = currentMIPS->r[MIPS_REG_SP];
currentMIPS->r[MIPS_REG_A1] = location;
if (argp)
Memory::Memcpy(location, argp, args);
Memory::Memcpy(location, argp, args, "ThreadParam");
// Let's assume same as starting a new thread, 64 bytes for safety/kernel.
currentMIPS->r[MIPS_REG_SP] -= 64;
@ -2037,8 +2037,9 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo
}
// Now copy argument to stack.
if (!forceArgs && Memory::IsValidAddress(argBlockPtr))
Memory::Memcpy(sp, argBlockPtr, argSize);
if (!forceArgs && Memory::IsValidAddress(argBlockPtr)) {
Memory::Memcpy(sp, argBlockPtr, argSize, "ThreadStartArgs");
}
// On the PSP, there's an extra 64 bytes of stack eaten after the args.
// This could be stack overflow safety, or just stack eaten by the kernel entry func.

View file

@ -514,7 +514,7 @@ u32 sceKernelReferVTimerStatus(SceUID uid, u32 statusAddr) {
NativeVTimer status = vt->nvt;
u32 size = Memory::Read_U32(statusAddr);
status.current = __getVTimerCurrentTime(vt);
Memory::Memcpy(statusAddr, &status, std::min(size, (u32)sizeof(status)));
Memory::Memcpy(statusAddr, &status, std::min(size, (u32)sizeof(status)), "VTimerStatus");
}
return 0;

View file

@ -18,17 +18,18 @@
#include <map>
#include <algorithm>
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/Serialize/SerializeMap.h"
#include "Core/Config.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HLE/HLE.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/HLE/sceKernelMemory.h"
#include "Core/HLE/sceMp3.h"
#include "Core/HW/MediaEngine.h"
#include "Core/HW/SimpleAudioDec.h"
#include "Core/MemMap.h"
#include "Core/Reporting.h"
#include "Core/HW/SimpleAudioDec.h"
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/Serialize/SerializeMap.h"
static const u32 ERROR_MP3_INVALID_HANDLE = 0x80671001;
static const u32 ERROR_MP3_UNRESERVED_HANDLE = 0x80671102;
@ -698,6 +699,7 @@ static u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumed
int outpcmbytes = 0;
ctx->decoder->Decode((void*)inbuff, 4096, outbuff, &outpcmbytes);
NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, outpcmbytes, "Mp3LowLevelDecode");
Memory::Write_U32(ctx->decoder->GetSourcePos(), sourceBytesConsumedAddr);
Memory::Write_U32(outpcmbytes, sampleBytesAddr);

View file

@ -528,8 +528,8 @@ static u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr
Memory::Write_U32(mpegHandle, mpegAddr);
// Initialize fake mpeg struct.
Memory::Memcpy(mpegHandle, "LIBMPEG\0", 8);
Memory::Memcpy(mpegHandle + 8, "001\0", 4);
Memory::Memcpy(mpegHandle, "LIBMPEG\0", 8, "Mpeg");
Memory::Memcpy(mpegHandle + 8, "001\0", 4, "Mpeg");
Memory::Write_U32(-1, mpegHandle + 12);
if (ringbuffer.IsValid()) {
Memory::Write_U32(ringbufferAddr, mpegHandle + 16);
@ -1985,7 +1985,7 @@ static u32 sceMpegAtracDecode(u32 mpeg, u32 auAddr, u32 bufferAddr, int init)
// We kept track of the stream number here in sceMpegGetAtracAu().
ctx->mediaengine->setAudioStream(atracAu.esBuffer);
Memory::Memset(bufferAddr, 0, MPEG_ATRAC_ES_OUTPUT_SIZE);
Memory::Memset(bufferAddr, 0, MPEG_ATRAC_ES_OUTPUT_SIZE, "MpegAtracClear");
ctx->mediaengine->getAudioSamples(bufferAddr);
atracAu.pts = ctx->mediaengine->getAudioTimeStamp() + ctx->mpegFirstTimestamp;

View file

@ -678,15 +678,14 @@ static u32 sceWlanGetEtherAddr(u32 addrAddr) {
Memory::Memset(addrAddr, PPSSPP_ID, 6);
// Making sure the 1st 2-bits on the 1st byte of OUI are zero to prevent issue with some games (ie. Gran Turismo)
addr[0] &= 0xfc;
}
else
// Read MAC Address from config
if (!ParseMacAddress(g_Config.sMACAddress.c_str(), addr)) {
ERROR_LOG(SCENET, "Error parsing mac address %s", g_Config.sMACAddress.c_str());
Memory::Memset(addrAddr, 0, 6);
} else {
CBreakPoints::ExecMemCheck(addrAddr, true, 6, currentMIPS->pc);
// Read MAC Address from config
if (!ParseMacAddress(g_Config.sMACAddress.c_str(), addr)) {
ERROR_LOG(SCENET, "Error parsing mac address %s", g_Config.sMACAddress.c_str());
Memory::Memset(addrAddr, 0, 6);
}
}
NotifyMemInfo(MemBlockFlags::WRITE, addrAddr, 6, "WlanEtherAddr");
return hleLogSuccessI(SCENET, hleDelayResult(0, "get ether mac", 200));
}

View file

@ -965,7 +965,7 @@ static u32 scePsmfVerifyPsmf(u32 psmfAddr)
}
// Kurohyou 2 (at least the demo) uses an uninitialized value that happens to be zero on the PSP.
// It appears to be written by scePsmfVerifyPsmf(), so we write some bytes into the stack here.
Memory::Memset(currentMIPS->r[MIPS_REG_SP] - 0x20, 0, 0x20);
Memory::Memset(currentMIPS->r[MIPS_REG_SP] - 0x20, 0, 0x20, "PsmfStack");
DEBUG_LOG(ME, "scePsmfVerifyPsmf(%08x)", psmfAddr);
return 0;
}
@ -1656,7 +1656,7 @@ static int scePsmfPlayerGetAudioData(u32 psmfPlayer, u32 audioDataAddr)
if (psmfplayer->mediaengine->getAudioSamples(audioDataAddr) == 0) {
if (psmfplayer->totalAudioStreams > 0 && (s64)psmfplayer->psmfPlayerAvcAu.pts < (s64)psmfplayer->totalDurationTimestamp - VIDEO_FRAME_DURATION_TS) {
// Write zeros for any missing trailing frames so it syncs with the video.
Memory::Memset(audioDataAddr, 0, audioSamplesBytes);
Memory::Memset(audioDataAddr, 0, audioSamplesBytes, "PsmfAudioClear");
} else {
ret = (int)ERROR_PSMFPLAYER_NO_MORE_DATA;
}

View file

@ -17,7 +17,7 @@
#include "Common/Serialize/SerializeFuncs.h"
#include "Core/Config.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HW/MediaEngine.h"
#include "Core/MemMap.h"
#include "Core/MIPS/MIPS.h"
@ -862,7 +862,7 @@ int MediaEngine::writeVideoImage(u32 bufferPtr, int frameWidth, int videoPixelMo
delete [] imgbuf;
}
CBreakPoints::ExecMemCheck(bufferPtr, true, videoImageSize, currentMIPS->pc);
NotifyMemInfo(MemBlockFlags::WRITE, bufferPtr, videoImageSize, "VideoDecode");
return videoImageSize;
#endif // USE_FFMPEG
@ -917,7 +917,6 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
writeVideoLineRGBA(imgbuf, data, width);
data += m_desWidth * sizeof(u32);
imgbuf += videoLineSize;
CBreakPoints::ExecMemCheck(bufferPtr + y * frameWidth * sizeof(u32), true, width * sizeof(u32), currentMIPS->pc);
}
break;
@ -927,7 +926,6 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
writeVideoLineABGR5650(imgbuf, data, width);
data += m_desWidth * sizeof(u16);
imgbuf += videoLineSize;
CBreakPoints::ExecMemCheck(bufferPtr + y * frameWidth * sizeof(u16), true, width * sizeof(u16), currentMIPS->pc);
}
break;
@ -937,7 +935,6 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
writeVideoLineABGR5551(imgbuf, data, width);
data += m_desWidth * sizeof(u16);
imgbuf += videoLineSize;
CBreakPoints::ExecMemCheck(bufferPtr + y * frameWidth * sizeof(u16), true, width * sizeof(u16), currentMIPS->pc);
}
break;
@ -947,7 +944,6 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
writeVideoLineABGR4444(imgbuf, data, width);
data += m_desWidth * sizeof(u16);
imgbuf += videoLineSize;
CBreakPoints::ExecMemCheck(bufferPtr + y * frameWidth * sizeof(u16), true, width * sizeof(u16), currentMIPS->pc);
}
break;
@ -967,9 +963,9 @@ int MediaEngine::writeVideoImageWithRange(u32 bufferPtr, int frameWidth, int vid
DoSwizzleTex16((const u32 *)imgbuf, buffer, bxc, byc, videoLineSize);
delete [] imgbuf;
}
NotifyMemInfo(MemBlockFlags::WRITE, bufferPtr, videoImageSize, "VideoDecodeRange");
// Account for the y offset as well.
return videoImageSize + videoLineSize * ypos;
return videoImageSize;
#endif // USE_FFMPEG
return 0;
}
@ -1042,7 +1038,7 @@ int MediaEngine::getAudioSamples(u32 bufferPtr) {
ERROR_LOG(ME, "Audio (%s) decode failed during video playback", GetCodecName(m_audioType));
}
CBreakPoints::ExecMemCheck(bufferPtr, true, outbytes, currentMIPS->pc);
NotifyMemInfo(MemBlockFlags::WRITE, bufferPtr, outbytes, "VideoDecodeAudio");
}
return 0x2000;

View file

@ -19,6 +19,7 @@
#include "Common/Serialize/SerializeFuncs.h"
#include "Core/Config.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HLE/FunctionWrappers.h"
#include "Core/HW/SimpleAudioDec.h"
#include "Core/HW/MediaEngine.h"
@ -397,6 +398,7 @@ u32 AuCtx::AuDecode(u32 pcmAddr) {
memset(outbuf + outpcmbufsize, 0, PCMBufSize - outpcmbufsize);
}
NotifyMemInfo(MemBlockFlags::WRITE, pcmAddr, outpcmbufsize, "AuDecode");
if (pcmAddr)
Memory::Write_U32(PCMBuf, pcmAddr);
return outpcmbufsize;

View file

@ -38,7 +38,7 @@
#include "Core/Core.h"
#include "Core/Debugger/SymbolMap.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/Config.h"
#include "Core/ConfigValues.h"
#include "Core/HLE/ReplaceTables.h"
@ -459,7 +459,7 @@ void Write_Opcode_JIT(const u32 _Address, const Opcode& _Value)
Memory::WriteUnchecked_U32(_Value.encoding, _Address);
}
void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength) {
void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength, const std::string &tag) {
if (IsValidRange(_Address, _iLength)) {
uint8_t *ptr = GetPointerUnchecked(_Address);
memset(ptr, _iValue, _iLength);
@ -468,7 +468,7 @@ void Memset(const u32 _Address, const u8 _iValue, const u32 _iLength) {
Write_U8(_iValue, (u32)(_Address + i));
}
CBreakPoints::ExecMemCheck(_Address, true, _iLength, currentMIPS->pc);
NotifyMemInfo(MemBlockFlags::WRITE, _Address, _iLength, tag);
}
} // namespace

View file

@ -18,7 +18,7 @@
#pragma once
#include "Common/CommonTypes.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/MemMap.h"
#include "Core/MIPS/MIPS.h"
@ -28,33 +28,31 @@ extern MIPSState *currentMIPS;
namespace Memory
{
inline void Memcpy(const u32 to_address, const void *from_data, const u32 len)
{
inline void Memcpy(const u32 to_address, const void *from_data, const u32 len, const std::string &tag = "Memcpy") {
u8 *to = GetPointer(to_address);
if (to) {
memcpy(to, from_data, len);
CBreakPoints::ExecMemCheck(to_address, true, len, currentMIPS->pc);
NotifyMemInfo(MemBlockFlags::WRITE, to_address, len, tag);
}
// if not, GetPointer will log.
}
inline void Memcpy(void *to_data, const u32 from_address, const u32 len)
{
inline void Memcpy(void *to_data, const u32 from_address, const u32 len, const std::string &tag = "Memcpy") {
const u8 *from = GetPointer(from_address);
if (from) {
memcpy(to_data, from, len);
CBreakPoints::ExecMemCheck(from_address, false, len, currentMIPS->pc);
NotifyMemInfo(MemBlockFlags::READ, from_address, len, tag);
}
// if not, GetPointer will log.
}
inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len)
{
inline void Memcpy(const u32 to_address, const u32 from_address, const u32 len, const std::string &tag = "Memcpy") {
Memcpy(GetPointer(to_address), from_address, len);
CBreakPoints::ExecMemCheck(to_address, true, len, currentMIPS->pc);
NotifyMemInfo(MemBlockFlags::READ, from_address, len, tag);
NotifyMemInfo(MemBlockFlags::WRITE, to_address, len, tag);
}
void Memset(const u32 _Address, const u8 _Data, const u32 _iLength);
void Memset(const u32 _Address, const u8 _Data, const u32 _iLength, const std::string &tag = "Memset");
template<class T>
void ReadStruct(u32 address, T *ptr)

View file

@ -21,6 +21,7 @@
#include "Common/Serialize/Serializer.h"
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/StringUtils.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/Util/BlockAllocator.h"
#include "Core/Reporting.h"
@ -35,14 +36,14 @@ BlockAllocator::~BlockAllocator()
Shutdown();
}
void BlockAllocator::Init(u32 rangeStart, u32 rangeSize)
{
void BlockAllocator::Init(u32 rangeStart, u32 rangeSize, bool suballoc) {
Shutdown();
rangeStart_ = rangeStart;
rangeSize_ = rangeSize;
//Initial block, covering everything
top_ = new Block(rangeStart_, rangeSize_, false, NULL, NULL);
bottom_ = top_;
suballoc_ = suballoc;
}
void BlockAllocator::Shutdown()
@ -90,7 +91,7 @@ u32 BlockAllocator::AllocAligned(u32 &size, u32 sizeGrain, u32 grain, bool fromT
if (offset >= grain_)
InsertFreeBefore(&b, offset);
b.taken = true;
b.SetTag(tag);
b.SetAllocated(tag, suballoc_);
return b.start;
}
else
@ -99,7 +100,7 @@ u32 BlockAllocator::AllocAligned(u32 &size, u32 sizeGrain, u32 grain, bool fromT
if (offset >= grain_)
InsertFreeBefore(&b, offset);
b.taken = true;
b.SetTag(tag);
b.SetAllocated(tag, suballoc_);
return b.start;
}
}
@ -120,7 +121,7 @@ u32 BlockAllocator::AllocAligned(u32 &size, u32 sizeGrain, u32 grain, bool fromT
if (offset >= grain_)
InsertFreeAfter(&b, offset);
b.taken = true;
b.SetTag(tag);
b.SetAllocated(tag, suballoc_);
return b.start;
}
else
@ -129,7 +130,7 @@ u32 BlockAllocator::AllocAligned(u32 &size, u32 sizeGrain, u32 grain, bool fromT
if (offset >= grain_)
InsertFreeAfter(&b, offset);
b.taken = true;
b.SetTag(tag);
b.SetAllocated(tag, suballoc_);
return b.start;
}
}
@ -195,7 +196,7 @@ u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag)
if (b.size != alignedSize)
InsertFreeAfter(&b, b.size - alignedSize);
b.taken = true;
b.SetTag(tag);
b.SetAllocated(tag, suballoc_);
CheckBlocks();
return position;
}
@ -205,7 +206,7 @@ u32 BlockAllocator::AllocAt(u32 position, u32 size, const char *tag)
if (b.size > alignedSize)
InsertFreeAfter(&b, b.size - alignedSize);
b.taken = true;
b.SetTag(tag);
b.SetAllocated(tag, suballoc_);
return position;
}
@ -268,6 +269,7 @@ bool BlockAllocator::Free(u32 position)
Block *b = GetBlockFromAddress(position);
if (b && b->taken)
{
NotifyMemInfo(suballoc_ ? MemBlockFlags::SUB_FREE : MemBlockFlags::FREE, b->start, b->size, "");
b->taken = false;
MergeFreeBlocks(b);
return true;
@ -284,6 +286,7 @@ bool BlockAllocator::FreeExact(u32 position)
Block *b = GetBlockFromAddress(position);
if (b && b->taken && b->start == position)
{
NotifyMemInfo(suballoc_ ? MemBlockFlags::SUB_FREE : MemBlockFlags::FREE, b->start, b->size, "");
b->taken = false;
MergeFreeBlocks(b);
return true;
@ -485,8 +488,8 @@ BlockAllocator::Block::Block(u32 _start, u32 _size, bool _taken, Block *_prev, B
truncate_cpy(tag, "(untitled)");
}
void BlockAllocator::Block::SetTag(const char *_tag)
{
void BlockAllocator::Block::SetAllocated(const char *_tag, bool suballoc) {
NotifyMemInfo(suballoc ? MemBlockFlags::SUB_ALLOC : MemBlockFlags::ALLOC, start, size, _tag ? _tag : "");
if (_tag)
truncate_cpy(tag, _tag);
else

View file

@ -27,7 +27,7 @@ public:
BlockAllocator(int grain = 16); // 16 byte granularity by default.
~BlockAllocator();
void Init(u32 _rangeStart, u32 _rangeSize);
void Init(u32 _rangeStart, u32 _rangeSize, bool suballoc);
void Shutdown();
void ListBlocks() const;
@ -62,7 +62,7 @@ private:
struct Block
{
Block(u32 _start, u32 _size, bool _taken, Block *_prev, Block *_next);
void SetTag(const char *_tag);
void SetAllocated(const char *_tag, bool suballoc);
void DoState(PointerWrap &p);
u32 start;
u32 size;
@ -78,6 +78,7 @@ private:
u32 rangeSize_;
u32 grain_;
bool suballoc_;
void MergeFreeBlocks(Block *fromBlock);
Block *GetBlockFromAddress(u32 addr);

View file

@ -1264,8 +1264,8 @@ bool PPGeImage::Load() {
return false;
}
Memory::Memcpy(texture_, textureData, dataSize);
Memory::Memset(texture_ + dataSize, 0, texSize - dataSize);
Memory::Memcpy(texture_, textureData, dataSize, "PPGeTex");
Memory::Memset(texture_ + dataSize, 0, texSize - dataSize, "PPGeTexClear");
free(textureData);
lastFrame_ = gpuStats.numFlips;

View file

@ -28,7 +28,7 @@
#include "Core/ConfigValues.h"
#include "Core/Core.h"
#include "Core/CoreParameter.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/Host.h"
#include "Core/MIPS/MIPS.h"
#include "Core/Reporting.h"
@ -1290,8 +1290,14 @@ void FramebufferManagerCommon::ResizeFramebufFBO(VirtualFramebuffer *vfb, int w,
shaderManager_->DirtyLastShader();
char tag[256];
snprintf(tag, sizeof(tag), "%08x_%08x_%dx%d_%s", vfb->fb_address, vfb->z_address, w, h, GeBufferFormatToString(vfb->format));
snprintf(tag, sizeof(tag), "FB_%08x_%08x_%dx%d_%s", vfb->fb_address, vfb->z_address, w, h, GeBufferFormatToString(vfb->format));
vfb->fbo = draw_->CreateFramebuffer({ vfb->renderWidth, vfb->renderHeight, 1, 1, true, tag });
if (Memory::IsVRAMAddress(vfb->fb_address) && vfb->fb_stride != 0) {
NotifyMemInfo(MemBlockFlags::ALLOC, vfb->fb_address, ColorBufferByteSize(vfb), tag);
}
if (Memory::IsVRAMAddress(vfb->z_address) && vfb->z_stride != 0) {
NotifyMemInfo(MemBlockFlags::ALLOC, vfb->z_address, vfb->fb_stride * vfb->height * sizeof(uint16_t), std::string("Z_") + tag);
}
if (old.fbo) {
INFO_LOG(FRAMEBUF, "Resizing FBO for %08x : %dx%dx%s", vfb->fb_address, w, h, GeBufferFormatToString(vfb->format));
if (vfb->fbo) {
@ -1680,10 +1686,14 @@ void FramebufferManagerCommon::ApplyClearToMemory(int x1, int y1, int x2, int y2
const int stride = gstate.FrameBufStride();
const int width = x2 - x1;
const int byteStride = stride * bpp;
const int byteWidth = width * bpp;
for (int y = y1; y < y2; ++y) {
NotifyMemInfo(MemBlockFlags::WRITE, gstate.getFrameBufAddress() + x1 * bpp + y * byteStride, byteWidth, "FramebufferClear");
}
// Can use memset for simple cases. Often alpha is different and gums up the works.
if (singleByteClear) {
const int byteStride = stride * bpp;
const int byteWidth = width * bpp;
addr += x1 * bpp;
for (int y = y1; y < y2; ++y) {
memset(addr + y * byteStride, clearBits, byteWidth);
@ -2162,7 +2172,7 @@ void FramebufferManagerCommon::PackFramebufferSync_(VirtualFramebuffer *vfb, int
if (destPtr) {
draw_->CopyFramebufferToMemorySync(vfb->fbo, Draw::FB_COLOR_BIT, x, y, w, h, destFormat, destPtr, vfb->fb_stride, "PackFramebufferSync_");
CBreakPoints::ExecMemCheck(fb_address + dstByteOffset, true, dstSize, currentMIPS->pc);
NotifyMemInfo(MemBlockFlags::WRITE, fb_address + dstByteOffset, dstSize, "FramebufferPack");
} else {
ERROR_LOG(G3D, "PackFramebufferSync_: Tried to readback to bad address %08x (stride = %d)", fb_address + dstByteOffset, vfb->fb_stride);
}

View file

@ -21,7 +21,9 @@
#include "Common/Profiler/Profiler.h"
#include "Common/ColorConv.h"
#include "Common/MemoryUtil.h"
#include "Common/StringUtils.h"
#include "Core/Config.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/Reporting.h"
#include "Core/System.h"
#include "GPU/Common/FramebufferManagerCommon.h"
@ -1121,6 +1123,8 @@ void TextureCacheCommon::LoadClut(u32 clutAddr, u32 loadBytes) {
}
}
}
NotifyMemInfo(MemBlockFlags::ALLOC, clutAddr, loadBytes, "CLUT");
}
// It's possible for a game to (successfully) access outside valid memory.
@ -1305,6 +1309,9 @@ void TextureCacheCommon::DecodeTextureLevel(u8 *out, int outPitch, GETextureForm
int w = gstate.getTextureWidth(level);
int h = gstate.getTextureHeight(level);
const u8 *texptr = Memory::GetPointer(texaddr);
const uint32_t byteSize = (textureBitsPerPixel[format] * bufw * h) / 8;
NotifyMemInfo(MemBlockFlags::TEXTURE, texaddr, byteSize, StringFromFormat("Texture_%08x_%dx%d_%s", texaddr, w, h, GeTextureFormatToString(format, clutformat)));
switch (format) {
case GE_TFMT_CLUT4:

View file

@ -330,7 +330,7 @@ void DumpExecute::SyncStall() {
bool DumpExecute::SubmitCmds(const void *p, u32 sz) {
if (execListBuf == 0) {
u32 allocSize = LIST_BUF_SIZE;
execListBuf = userMemory.Alloc(allocSize, "List buf");
execListBuf = userMemory.Alloc(allocSize, true, "List buf");
if (execListBuf == -1) {
execListBuf = 0;
}

View file

@ -17,6 +17,7 @@
#include "GPU/GPUState.h"
#include "Core/Config.h"
#include "Core/CoreTiming.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/MemMap.h"
#include "Core/Host.h"
#include "Core/Reporting.h"
@ -25,7 +26,6 @@
#include "Core/HLE/sceKernelInterrupt.h"
#include "Core/HLE/sceKernelThread.h"
#include "Core/HLE/sceGe.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/MemMapHelpers.h"
#include "Core/Util/PPGeDraw.h"
#include "GPU/Common/DrawEngineCommon.h"
@ -2720,8 +2720,8 @@ void GPUCommon::DoBlockTransfer(u32 skipDrawReason) {
framebufferManager_->NotifyBlockTransferAfter(dstBasePtr, dstStride, dstX, dstY, srcBasePtr, srcStride, srcX, srcY, width, height, bpp, skipDrawReason);
}
CBreakPoints::ExecMemCheck(srcBasePtr + (srcY * srcStride + srcX) * bpp, false, height * srcStride * bpp, currentMIPS->pc);
CBreakPoints::ExecMemCheck(dstBasePtr + (dstY * dstStride + dstX) * bpp, true, height * dstStride * bpp, currentMIPS->pc);
NotifyMemInfo(MemBlockFlags::READ, srcBasePtr + (srcY * srcStride + srcX) * bpp, height * srcStride * bpp, "GPUBlockTransfer");
NotifyMemInfo(MemBlockFlags::WRITE, dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, "GPUBlockTransfer");
// TODO: Correct timing appears to be 1.9, but erring a bit low since some of our other timing is inaccurate.
cyclesExecuted += ((height * width * bpp) * 16) / 10;
@ -2731,9 +2731,7 @@ bool GPUCommon::PerformMemoryCopy(u32 dest, u32 src, int size) {
// Track stray copies of a framebuffer in RAM. MotoGP does this.
if (framebufferManager_->MayIntersectFramebuffer(src) || framebufferManager_->MayIntersectFramebuffer(dest)) {
if (!framebufferManager_->NotifyFramebufferCopy(src, dest, size, false, gstate_c.skipDrawReason)) {
// TODO: What? Why would a game copy between the mirrors? This check seems entirely
// superfluous.
// We use a little hack for Download/Upload using a VRAM mirror.
// We use a little hack for PerformMemoryDownload/PerformMemoryUpload using a VRAM mirror.
// Since they're identical we don't need to copy.
if (!Memory::IsVRAMAddress(dest) || (dest ^ 0x00400000) != src) {
Memory::Memcpy(dest, src, size);
@ -2743,6 +2741,8 @@ bool GPUCommon::PerformMemoryCopy(u32 dest, u32 src, int size) {
return true;
}
NotifyMemInfo(MemBlockFlags::READ, src, size, "GPUMemcpy");
NotifyMemInfo(MemBlockFlags::WRITE, dest, size, "GPUMemcpy");
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
GPURecord::NotifyMemcpy(dest, src, size);
return false;
@ -2751,13 +2751,14 @@ bool GPUCommon::PerformMemoryCopy(u32 dest, u32 src, int size) {
bool GPUCommon::PerformMemorySet(u32 dest, u8 v, int size) {
// This may indicate a memset, usually to 0, of a framebuffer.
if (framebufferManager_->MayIntersectFramebuffer(dest)) {
Memory::Memset(dest, v, size);
Memory::Memset(dest, v, size, "GPUMemset");
if (!framebufferManager_->NotifyFramebufferCopy(dest, dest, size, true, gstate_c.skipDrawReason)) {
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
}
return true;
}
NotifyMemInfo(MemBlockFlags::WRITE, dest, size, "GPUMemset");
// Or perhaps a texture, let's invalidate.
InvalidateCache(dest, size, GPU_INVALIDATE_HINT);
GPURecord::NotifyMemset(dest, v, size);

View file

@ -10,6 +10,16 @@ const char *GeBufferFormatToString(GEBufferFormat fmt) {
}
}
const char *GEPaletteFormatToString(GEPaletteFormat pfmt) {
switch (pfmt) {
case GE_CMODE_16BIT_BGR5650: return "565";
case GE_CMODE_16BIT_ABGR5551: return "5551";
case GE_CMODE_16BIT_ABGR4444: return "4444";
case GE_CMODE_32BIT_ABGR8888: return "8888";
default: return "N/A";
}
}
const char *GeTextureFormatToString(GETextureFormat fmt) {
switch (fmt) {
case GE_TFMT_5650: return "565";
@ -26,3 +36,41 @@ const char *GeTextureFormatToString(GETextureFormat fmt) {
default: return "N/A";
}
}
const char *GeTextureFormatToString(GETextureFormat tfmt, GEPaletteFormat pfmt) {
switch (tfmt) {
case GE_TFMT_CLUT4:
switch (pfmt) {
case GE_CMODE_16BIT_BGR5650: return "CLUT4_565";
case GE_CMODE_16BIT_ABGR5551: return "CLUT4_5551";
case GE_CMODE_16BIT_ABGR4444: return "CLUT4_4444";
case GE_CMODE_32BIT_ABGR8888: return "CLUT4_8888";
default: return "N/A";
}
case GE_TFMT_CLUT8:
switch (pfmt) {
case GE_CMODE_16BIT_BGR5650: return "CLUT8_565";
case GE_CMODE_16BIT_ABGR5551: return "CLUT8_5551";
case GE_CMODE_16BIT_ABGR4444: return "CLUT8_4444";
case GE_CMODE_32BIT_ABGR8888: return "CLUT8_8888";
default: return "N/A";
}
case GE_TFMT_CLUT16:
switch (pfmt) {
case GE_CMODE_16BIT_BGR5650: return "CLUT16_565";
case GE_CMODE_16BIT_ABGR5551: return "CLUT16_5551";
case GE_CMODE_16BIT_ABGR4444: return "CLUT16_4444";
case GE_CMODE_32BIT_ABGR8888: return "CLUT16_8888";
default: return "N/A";
}
case GE_TFMT_CLUT32:
switch (pfmt) {
case GE_CMODE_16BIT_BGR5650: return "CLUT32_565";
case GE_CMODE_16BIT_ABGR5551: return "CLUT32_5551";
case GE_CMODE_16BIT_ABGR4444: return "CLUT32_4444";
case GE_CMODE_32BIT_ABGR8888: return "CLUT32_8888";
default: return "N/A";
}
default: return GeTextureFormatToString(tfmt);
}
}

View file

@ -26,7 +26,7 @@
#include "Core/Config.h"
#include "Core/ConfigValues.h"
#include "Core/Core.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/MemMap.h"
#include "Core/HLE/sceKernelInterrupt.h"
#include "Core/HLE/sceGe.h"
@ -653,8 +653,8 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff) {
memcpy(dst, src, width * bpp);
}
CBreakPoints::ExecMemCheck(srcBasePtr + (srcY * srcStride + srcX) * bpp, false, height * srcStride * bpp, currentMIPS->pc);
CBreakPoints::ExecMemCheck(dstBasePtr + (srcY * dstStride + srcX) * bpp, true, height * dstStride * bpp, currentMIPS->pc);
NotifyMemInfo(MemBlockFlags::READ, srcBasePtr + (srcY * srcStride + srcX) * bpp, height * srcStride * bpp, "GPUBlockTransfer");
NotifyMemInfo(MemBlockFlags::WRITE, dstBasePtr + (dstY * dstStride + dstX) * bpp, height * dstStride * bpp, "GPUBlockTransfer");
// TODO: Correct timing appears to be 1.9, but erring a bit low since some of our other timing is inaccurate.
cyclesExecuted += ((height * width * bpp) * 16) / 10;

View file

@ -862,7 +862,7 @@ void TextureCacheVulkan::BuildTexture(TexCacheEntry *const entry) {
}
char texName[128]{};
snprintf(texName, sizeof(texName), "texture_%08x_%s", entry->addr, GeTextureFormatToString((GETextureFormat)entry->format));
snprintf(texName, sizeof(texName), "texture_%08x_%s", entry->addr, GeTextureFormatToString((GETextureFormat)entry->format, gstate.getClutPaletteFormat()));
image->SetTag(texName);
bool allocSuccess = image->CreateDirect(cmdInit, allocator_, w * scaleFactor, h * scaleFactor, maxLevelToGenerate + 1, actualFmt, imageLayout, usage, mapping);

View file

@ -419,7 +419,6 @@ enum GETextureFormat
GE_TFMT_DXT5 = 10,
};
const char *GeTextureFormatToString(GETextureFormat tfmt);
inline bool IsClutFormat(GETextureFormat tfmt) {
return tfmt == GE_TFMT_CLUT4 || tfmt == GE_TFMT_CLUT8 || tfmt == GE_TFMT_CLUT16 || tfmt == GE_TFMT_CLUT32;
}
@ -609,3 +608,7 @@ enum GEPaletteFormat
GE_CMODE_16BIT_ABGR4444,
GE_CMODE_32BIT_ABGR8888,
};
const char *GEPaletteFormatToString(GEPaletteFormat pfmt);
const char *GeTextureFormatToString(GETextureFormat tfmt);
const char *GeTextureFormatToString(GETextureFormat tfmt, GEPaletteFormat pfmt);

View file

@ -389,6 +389,7 @@
<ClInclude Include="..\..\Core\Debugger\Breakpoints.h" />
<ClInclude Include="..\..\Core\Debugger\DebugInterface.h" />
<ClInclude Include="..\..\Core\Debugger\DisassemblyManager.h" />
<ClInclude Include="..\..\Core\Debugger\MemBlockInfo.h" />
<ClInclude Include="..\..\Core\Debugger\SymbolMap.h" />
<ClInclude Include="..\..\Core\Debugger\WebSocket.h" />
<ClInclude Include="..\..\Core\Debugger\WebSocket\BreakpointSubscriber.h" />
@ -621,6 +622,7 @@
<ClCompile Include="..\..\Core\CwCheat.cpp" />
<ClCompile Include="..\..\Core\Debugger\Breakpoints.cpp" />
<ClCompile Include="..\..\Core\Debugger\DisassemblyManager.cpp" />
<ClCompile Include="..\..\Core\Debugger\MemBlockInfo.cpp" />
<ClCompile Include="..\..\Core\Debugger\SymbolMap.cpp" />
<ClCompile Include="..\..\Core\Debugger\WebSocket.cpp" />
<ClCompile Include="..\..\Core\Debugger\WebSocket\BreakpointSubscriber.cpp" />

View file

@ -563,6 +563,9 @@
<ClCompile Include="..\..\Core\Debugger\DisassemblyManager.cpp">
<Filter>Debugger</Filter>
</ClCompile>
<ClCompile Include="..\..\Core\Debugger\MemBlockInfo.cpp">
<Filter>Debugger</Filter>
</ClCompile>
<ClCompile Include="..\..\Core\Debugger\SymbolMap.cpp">
<Filter>Debugger</Filter>
</ClCompile>
@ -1372,6 +1375,9 @@
<ClInclude Include="..\..\Core\Debugger\DisassemblyManager.h">
<Filter>Debugger</Filter>
</ClInclude>
<ClInclude Include="..\..\Core\Debugger\MemBlockInfo.h">
<Filter>Debugger</Filter>
</ClInclude>
<ClInclude Include="..\..\Core\Debugger\SymbolMap.h">
<Filter>Debugger</Filter>
</ClInclude>

View file

@ -3,6 +3,7 @@
#include <tchar.h>
#include <math.h>
#include <iomanip>
#include "ext/xxhash.h"
#include "Core/Config.h"
#include "Windows/resource.h"
#include "Core/MemMap.h"
@ -173,8 +174,7 @@ CtrlMemView *CtrlMemView::getFrom(HWND hwnd)
}
void CtrlMemView::onPaint(WPARAM wParam, LPARAM lParam)
{
void CtrlMemView::onPaint(WPARAM wParam, LPARAM lParam) {
auto memLock = Memory::Lock();
// draw to a bitmap for double buffering
@ -187,6 +187,7 @@ void CtrlMemView::onPaint(WPARAM wParam, LPARAM lParam)
SetBkMode(hdc,OPAQUE);
HPEN standardPen = CreatePen(0,0,0xFFFFFF);
HBRUSH standardBrush = CreateSolidBrush(0xFFFFFF);
COLORREF standardBG = GetBkColor(hdc);
HPEN oldPen = (HPEN) SelectObject(hdc,standardPen);
HBRUSH oldBrush = (HBRUSH) SelectObject(hdc,standardBrush);
@ -199,88 +200,124 @@ void CtrlMemView::onPaint(WPARAM wParam, LPARAM lParam)
if (displayOffsetScale)
drawOffsetScale(hdc);
std::vector<MemBlockInfo> memRangeInfo = FindMemInfoByFlag(highlightFlags_, windowStart, (visibleRows + 1) * rowSize);
COLORREF lastTextCol = 0x000000;
COLORREF lastBGCol = standardBG;
auto setTextColors = [&](COLORREF fg, COLORREF bg) {
if (lastTextCol != fg) {
SetTextColor(hdc, fg);
lastTextCol = fg;
}
if (lastBGCol != bg) {
SetBkColor(hdc, bg);
lastBGCol = bg;
}
};
// draw one extra row that may be partially visible
for (int i = 0; i < visibleRows+1; i++)
{
char temp[32];
unsigned int address=windowStart + i*rowSize;
int rowY = rowHeight*i;
for (int i = 0; i < visibleRows + 1; i++) {
int rowY = rowHeight * i;
// Skip the first X rows to make space for the offsets.
if (displayOffsetScale)
rowY += rowHeight * offsetSpace; // skip the first X rows to make space for the offsets
sprintf(temp,"%08X",address);
SetTextColor(hdc,0x600000);
TextOutA(hdc,addressStart,rowY,temp,(int)strlen(temp));
rowY += rowHeight * offsetSpace;
SetTextColor(hdc,0x000000);
char temp[32];
uint32_t address = windowStart + i * rowSize;
sprintf(temp, "%08X", address);
u32 memory[4];
bool valid = debugger != NULL && debugger->isAlive() && Memory::IsValidAddress(address);
if (valid)
{
memory[0] = debugger->readMemory(address);
memory[1] = debugger->readMemory(address+4);
memory[2] = debugger->readMemory(address+8);
memory[3] = debugger->readMemory(address+12);
setTextColors(0x600000, standardBG);
TextOutA(hdc, addressStart, rowY, temp, (int)strlen(temp));
union {
uint32_t words[4];
uint8_t bytes[16];
} memory;
bool valid = debugger != nullptr && debugger->isAlive() && Memory::IsValidAddress(address);
for (int i = 0; valid && i < 4; ++i) {
memory.words[i] = debugger->readMemory(address + i * 4);
}
u8* m = (u8*) memory;
for (int j = 0; j < rowSize; j++)
{
if (valid) sprintf(temp,"%02X",m[j]);
else strcpy(temp,"??");
unsigned char c = m[j];
if (c < 32 || c >= 128 || valid == false) c = '.';
if (address+j == curAddress && searching == false)
{
COLORREF oldBkColor = GetBkColor(hdc);
COLORREF oldTextColor = GetTextColor(hdc);
if (hasFocus && !asciiSelected)
{
SetTextColor(hdc,0xFFFFFF);
SetBkColor(hdc,0xFF9933);
if (selectedNibble == 0) SelectObject(hdc,(HGDIOBJ)underlineFont);
} else {
SetTextColor(hdc,0);
SetBkColor(hdc,0xC0C0C0);
for (int j = 0; j < rowSize; j++) {
const uint32_t byteAddress = (address + j) & ~0xC0000000;
std::string tag;
bool tagContinues = false;
for (auto info : memRangeInfo) {
if (info.start <= byteAddress && info.start + info.size > byteAddress) {
tag = info.tag;
tagContinues = byteAddress + 1 < info.start + info.size;
}
TextOutA(hdc,hexStart+j*3*charWidth,rowY,&temp[0],1);
if (hasFocus && !asciiSelected)
{
if (selectedNibble == 1) SelectObject(hdc,(HGDIOBJ)underlineFont);
else SelectObject(hdc,(HGDIOBJ)font);
}
TextOutA(hdc,hexStart+j*3*charWidth+charWidth,rowY,&temp[1],1);
if (hasFocus && asciiSelected)
{
SetTextColor(hdc,0xFFFFFF);
SetBkColor(hdc,0xFF9933);
} else {
SetTextColor(hdc,0);
SetBkColor(hdc,0xC0C0C0);
SelectObject(hdc,(HGDIOBJ)font);
}
TextOutA(hdc,asciiStart+j*(charWidth+2),rowY,(char*)&c,1);
SetTextColor(hdc,oldTextColor);
SetBkColor(hdc,oldBkColor);
} else {
TextOutA(hdc,hexStart+j*3*charWidth,rowY,temp,2);
TextOutA(hdc,asciiStart+j*(charWidth+2),rowY,(char*)&c,1);
}
int hexX = hexStart + j * 3 * charWidth;
int hexLen = 2;
int asciiX = asciiStart + j * (charWidth + 2);
char c;
if (valid) {
sprintf(temp, "%02X ", memory.bytes[j]);
c = (char)memory.bytes[j];
if (memory.bytes[j] < 32 || memory.bytes[j] >= 128)
c = '.';
} else {
strcpy(temp, "??");
c = '.';
}
COLORREF hexBGCol = standardBG;
COLORREF hexTextCol = 0x000000;
COLORREF continueBGCol = standardBG;
COLORREF asciiBGCol = standardBG;
COLORREF asciiTextCol = 0x000000;
int underline = -1;
if (address + j == curAddress && searching == false) {
if (asciiSelected) {
hexBGCol = 0xC0C0C0;
hexTextCol = 0x000000;
asciiBGCol = hasFocus ? 0xFF9933 : 0xC0C0C0;
asciiTextCol = hasFocus ? 0xFFFFFF : 0x000000;
} else {
hexBGCol = hasFocus ? 0xFF9933 : 0xC0C0C0;
hexTextCol = hasFocus ? 0xFFFFFF : 0x000000;
asciiBGCol = 0xC0C0C0;
asciiTextCol = 0x000000;
underline = selectedNibble;
}
if (!tag.empty() && tagContinues) {
continueBGCol = pickTagColor(tag);
}
} else if (!tag.empty()) {
hexBGCol = pickTagColor(tag);
continueBGCol = hexBGCol;
asciiBGCol = pickTagColor(tag);
hexLen = tagContinues ? 3 : 2;
}
setTextColors(hexTextCol, hexBGCol);
if (underline >= 0) {
SelectObject(hdc, underline == 0 ? (HGDIOBJ)underlineFont : (HGDIOBJ)font);
TextOutA(hdc, hexX, rowY, &temp[0], 1);
SelectObject(hdc, underline == 0 ? (HGDIOBJ)font : (HGDIOBJ)underlineFont);
TextOutA(hdc, hexX + charWidth, rowY, &temp[1], 1);
SelectObject(hdc, (HGDIOBJ)font);
// If the tag keeps going, draw the BG too.
if (continueBGCol != standardBG) {
setTextColors(0x000000, continueBGCol);
TextOutA(hdc, hexX + charWidth * 2, rowY, &temp[2], 1);
}
} else {
TextOutA(hdc, hexX, rowY, temp, hexLen);
}
setTextColors(asciiTextCol, asciiBGCol);
TextOutA(hdc, asciiX, rowY, &c, 1);
}
}
setTextColors(0x000000, standardBG);
SelectObject(hdc,oldFont);
SelectObject(hdc,oldPen);
SelectObject(hdc,oldBrush);
@ -518,11 +555,17 @@ void CtrlMemView::onMouseMove(WPARAM wParam, LPARAM lParam, int button)
}
void CtrlMemView::updateStatusBarText()
{
char text[64];
sprintf(text,"%08X",curAddress);
SendMessage(GetParent(wnd),WM_DEB_SETSTATUSBARTEXT,0,(LPARAM)text);
void CtrlMemView::updateStatusBarText() {
std::vector<MemBlockInfo> memRangeInfo = FindMemInfoByFlag(highlightFlags_, curAddress, 1);
char text[512];
snprintf(text, sizeof(text), "%08X", curAddress);
// There should only be one.
for (MemBlockInfo info : memRangeInfo) {
snprintf(text, sizeof(text), "%08X - %s %08X-%08X (at PC %08X / %lld ticks)", curAddress, info.tag.c_str(), info.start, info.start + info.size, info.pc, info.ticks);
}
SendMessage(GetParent(wnd), WM_DEB_SETSTATUSBARTEXT, 0, (LPARAM)text);
}
void CtrlMemView::gotoPoint(int x, int y)
@ -591,6 +634,7 @@ void CtrlMemView::scrollWindow(int lines)
{
windowStart += lines*rowSize;
curAddress += lines*rowSize;
updateStatusBarText();
redraw();
}
@ -642,6 +686,10 @@ std::vector<u32> CtrlMemView::searchString(std::string searchQuery)
return searchResAddrs;
size_t queryLength = searchQuery.length();
if (queryLength == 0)
return searchResAddrs;
// TODO: Scratchpad, VRAM?
u32 segmentStart = PSP_GetKernelMemoryBase(); //RAM start
const u32 segmentEnd = PSP_GetUserMemoryEnd() - (u32)queryLength; //RAM end
u8* ptr;
@ -793,3 +841,16 @@ void CtrlMemView::toggleOffsetScale(CommonToggles toggle)
updateStatusBarText();
redraw();
}
void CtrlMemView::setHighlightType(MemBlockFlags flags) {
if (highlightFlags_ != flags) {
highlightFlags_ = flags;
redraw();
}
}
uint32_t CtrlMemView::pickTagColor(const std::string &tag) {
int colors[6] = { 0xe0FFFF, 0xFFE0E0, 0xE8E8FF, 0xFFE0FF, 0xE0FFE0, 0xFFFFE0 };
int which = XXH3_64bits(tag.c_str(), tag.length()) % ARRAY_SIZE(colors);
return colors[which];
}

View file

@ -17,7 +17,9 @@
//
//To get a class instance to be able to access it, just use getFrom(HWND wnd).
#include "../../Core/Debugger/DebugInterface.h"
#include <cstdint>
#include "Core/Debugger/DebugInterface.h"
#include "Core/Debugger/MemBlockInfo.h"
enum OffsetSpacing {
offsetSpace = 3, // the number of blank lines that should be left to make space for the offsets
@ -63,8 +65,12 @@ class CtrlMemView
bool hasFocus;
static wchar_t szClassName[];
DebugInterface *debugger;
MemBlockFlags highlightFlags_ = MemBlockFlags::ALLOC;
void updateStatusBarText();
void search(bool continueSearch);
uint32_t pickTagColor(const std::string &tag);
public:
CtrlMemView(HWND _wnd);
~CtrlMemView();
@ -99,4 +105,5 @@ public:
void drawOffsetScale(HDC hdc);
void toggleOffsetScale(CommonToggles toggle);
void toggleStringSearch(CommonToggles toggle);
void setHighlightType(MemBlockFlags flags);
};

View file

@ -2,13 +2,15 @@
#include "Windows/stdafx.h"
#include <windowsx.h>
#include <commctrl.h>
#include "..\resource.h"
#include "Common/System/Display.h"
#include "Common/Data/Encoding/Utf8.h"
#include "Common/System/Display.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/Debugger/SymbolMap.h"
#include "Core/MIPS/MIPSDebugInterface.h" // BAD
#include "Core/MIPS/MIPSDebugInterface.h"
#include "Debugger_MemoryDlg.h"
#include "CtrlMemView.h"
@ -68,6 +70,20 @@ CMemoryDlg::CMemoryDlg(HINSTANCE _hInstance, HWND _hParent, DebugInterface *_cpu
searchBoxHdl = GetDlgItem(m_hDlg, IDC_SEARCH_BOX);
srcListHdl = GetDlgItem(m_hDlg, IDC_SEARCH_RESULTS);
layerDropdown_ = GetDlgItem(m_hDlg, IDC_REGIONS);
ComboBox_ResetContent(layerDropdown_);
ComboBox_AddString(layerDropdown_, L"Show allocations");
ComboBox_SetItemData(layerDropdown_, 0, MemBlockFlags::ALLOC);
ComboBox_AddString(layerDropdown_, L"Show sub allocations");
ComboBox_SetItemData(layerDropdown_, 1, MemBlockFlags::SUB_ALLOC);
ComboBox_AddString(layerDropdown_, L"Show writes");
ComboBox_SetItemData(layerDropdown_, 2, MemBlockFlags::WRITE);
ComboBox_AddString(layerDropdown_, L"Show textures");
ComboBox_SetItemData(layerDropdown_, 3, MemBlockFlags::TEXTURE);
ComboBox_SetCurSel(layerDropdown_, 0);
status_ = GetDlgItem(m_hDlg, IDC_MEMVIEW_STATUS);
memView = CtrlMemView::getFrom(memViewHdl);
memView->setDebugger(_cpu);
@ -118,66 +134,53 @@ void CMemoryDlg::searchBoxRedraw(std::vector<u32> results) {
void CMemoryDlg::NotifyMapLoaded()
{
if (m_hDlg)
{
g_symbolMap->FillSymbolListBox(symListHdl,ST_DATA);
int sel = ComboBox_GetCurSel(memViewHdl);
ComboBox_ResetContent(memViewHdl);
/*
for (int i = 0; i < cpu->getMemMap()->numRegions; i++)
{
// TODO: wchar_t
int n = ComboBox_AddString(lb,cpu->getMemMap()->regions[i].name);
ComboBox_SetItemData(lb,n,cpu->getMemMap()->regions[i].start);
}*/
ComboBox_SetCurSel(memViewHdl,sel>=0?sel:0);
}
g_symbolMap->FillSymbolListBox(symListHdl, ST_DATA);
Update();
}
BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch(message){
case WM_COMMAND:{
BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
wchar_t temp[256]{};
int n;
switch (message) {
case WM_COMMAND: {
HWND lb = GetDlgItem(m_hDlg, LOWORD(wParam));
switch (LOWORD(wParam)){
switch (LOWORD(wParam)) {
case IDC_REGIONS:
switch (HIWORD(wParam)) {
case LBN_DBLCLK:{
int n = ComboBox_GetCurSel(lb);
if (n != -1) {
unsigned int addr = (unsigned int)ComboBox_GetItemData(lb,n);
memView->gotoAddr(addr);
}
case CBN_SELENDOK:
n = ComboBox_GetCurSel(lb);
if (n != CB_ERR) {
MemBlockFlags flags = (MemBlockFlags)ComboBox_GetItemData(lb, n);
memView->setHighlightType(MemBlockFlags(flags));
}
break;
};
break;
}
break;
case IDC_SYMBOLS:
switch (HIWORD(wParam)) {
case LBN_DBLCLK:{
int n = ListBox_GetCurSel(lb);
if (n != -1) {
unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n);
memView->gotoAddr(addr);
}
case LBN_DBLCLK:
n = ListBox_GetCurSel(lb);
if (n != -1) {
unsigned int addr = (unsigned int)ListBox_GetItemData(lb,n);
memView->gotoAddr(addr);
}
break;
}
break;
};
case IDC_SEARCH_RESULTS:
switch (HIWORD(wParam)) {
case LBN_DBLCLK: {
int n = ListBox_GetCurSel(lb);
if (n != -1) {
unsigned int addr = (unsigned int)ListBox_GetItemData(lb, n);
memView->gotoAddr(addr);
}
case LBN_DBLCLK:
n = ListBox_GetCurSel(lb);
if (n != -1) {
unsigned int addr = (unsigned int)ListBox_GetItemData(lb, n);
memView->gotoAddr(addr);
}
break;
}
break;
};
break;
case IDC_SHOWOFFSETS:
switch (HIWORD(wParam))
{
switch (HIWORD(wParam)) {
case BN_CLICKED:
if (SendDlgItemMessage(m_hDlg, IDC_SHOWOFFSETS, BM_GETCHECK, 0, 0))
memView->toggleOffsetScale(On);
@ -187,10 +190,8 @@ BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
}
break;
case IDC_BUTTON_SEARCH:
switch (HIWORD(wParam))
{
switch (HIWORD(wParam)) {
case BN_CLICKED:
wchar_t temp[256];
GetWindowText(searchBoxHdl, temp, 255);
std::vector<u32> results = memView->searchString(ConvertWStringToUTF8(temp).c_str());
if (results.size() > 0){
@ -198,14 +199,14 @@ BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
}
break;
}
break;
}
}
break;
case WM_DEB_MAPLOADED:
NotifyMapLoaded();
break;
case WM_DEB_GOTOADDRESSEDIT:{
wchar_t temp[256];
case WM_DEB_GOTOADDRESSEDIT: {
u32 addr;
GetWindowText(editWnd,temp,255);
@ -222,12 +223,13 @@ BOOL CMemoryDlg::DlgProc(UINT message, WPARAM wParam, LPARAM lParam)
Update();
return TRUE;
case WM_INITDIALOG:
{
return TRUE;
}
case WM_DEB_SETSTATUSBARTEXT:
SendMessage(status_, SB_SETTEXT, 0, (LPARAM)ConvertUTF8ToWString((const char *)lParam).c_str());
break;
case WM_INITDIALOG:
return TRUE;
case WM_SIZE:
Size();
break;
@ -255,11 +257,11 @@ void CMemoryDlg::Size()
int dlg_w = winRect.right - winRect.left;
int dlg_h = winRect.bottom - winRect.top;
int wf = slRect.right-slRect.left;
int w = dlg_w - 3 * fontScale - wf*2;
int top = 48 * fontScale;
int height = dlg_h - top;
int top = 40 * fontScale;
int bottom = 24 * fontScale;
int height = dlg_h - top - bottom;
//HWND, X, Y, width, height, repaint
MoveWindow(symListHdl, 0 ,top, wf, height, TRUE);
MoveWindow(memViewHdl, wf+4 ,top, w, height, TRUE);

View file

@ -17,6 +17,8 @@ private:
RECT winRect, srRect;
CtrlMemView *memView;
HWND memViewHdl, symListHdl, editWnd, searchBoxHdl, srcListHdl;
HWND layerDropdown_;
HWND status_;
BOOL DlgProc(UINT message, WPARAM wParam, LPARAM lParam);
public:

View file

@ -307,7 +307,7 @@ END
#include "aboutbox.rc"
#endif
IDD_MEMORY DIALOGEX 0, 0, 700, 287
IDD_MEMORY DIALOGEX 0, 0, 700, 310
STYLE DS_SETFONT | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME
EXSTYLE WS_EX_TOOLWINDOW
CAPTION "Memory View"
@ -321,14 +321,16 @@ BEGIN
CONTROL "Normal",IDC_MODENORMAL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,198,9,40,9
CONTROL "Symbols",IDC_MODESYMBOLS,"Button",BS_AUTORADIOBUTTON,241,9,43,8
GROUPBOX "Mode",IDC_STATIC,191,0,104,22
AUTOCHECKBOX "Show Offsets",IDC_SHOWOFFSETS,300,9,55,8
COMBOBOX IDC_REGIONS,87,5,88,139,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
AUTOCHECKBOX "Show Offsets",IDC_SHOWOFFSETS,300,9,55,8
COMBOBOX IDC_REGIONS,95,5,88,139,CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LISTBOX IDC_SEARCH_RESULTS,557,14,140,272,LBS_SORT | LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_SEARCH_BOX,397,6,100,13,ES_AUTOHSCROLL
PUSHBUTTON "Search",IDC_BUTTON_SEARCH,504,5,50,14
LTEXT "Search:",IDC_STATIC,369,6,27,8
LTEXT "Search:",IDC_STATIC,369,8,27,8
CONTROL "",IDC_MEMVIEW_STATUS,"msctls_statusbar32",WS_CHILD | WS_VISIBLE,0,286,700,24
END
IDD_INPUTBOX DIALOGEX 0, 0, 163, 55

View file

@ -375,6 +375,7 @@
#define IDC_GEDBG_STEPCOUNT_COMBO 40203
#define ID_FILE_DUMP_VIDEO_OUTPUT 40204
#define ID_EMULATION_CHAT 40205
#define IDC_MEMVIEW_STATUS 40206
// Dummy option to let the buffered rendering hotkey cycle through all the options.
#define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500
@ -387,7 +388,7 @@
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 256
#define _APS_NEXT_COMMAND_VALUE 40200
#define _APS_NEXT_COMMAND_VALUE 40207
#define _APS_NEXT_CONTROL_VALUE 1202
#define _APS_NEXT_SYMED_VALUE 101
#endif

View file

@ -403,6 +403,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/Core/WebServer.cpp \
$(SRC)/Core/Debugger/Breakpoints.cpp \
$(SRC)/Core/Debugger/DisassemblyManager.cpp \
$(SRC)/Core/Debugger/MemBlockInfo.cpp \
$(SRC)/Core/Debugger/SymbolMap.cpp \
$(SRC)/Core/Debugger/WebSocket.cpp \
$(SRC)/Core/Debugger/WebSocket/BreakpointSubscriber.cpp \