Skip to content

Commit

Permalink
Merge pull request #9 from henriquegemignani/feature/merge-upstream
Browse files Browse the repository at this point in the history
Merge upstream
  • Loading branch information
henriquegemignani authored Mar 14, 2021
2 parents 93b921a + 5d7f81d commit 09dbb04
Show file tree
Hide file tree
Showing 10 changed files with 174 additions and 102 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,4 @@ $ python3 -m venv venv
$ source venv/bin/activate
$ python -m pip install Cython pytest
$ python setup.py build_ext -g --inplace --force
$ python -m pytest
$ python -m pytest
21 changes: 17 additions & 4 deletions Source/Common/CommonUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,26 @@ inline u64 bSwap64(u64 data)
}
#endif

inline u32 dolphinAddrToOffset(u32 addr)
inline u32 dolphinAddrToOffset(u32 addr, u32 mem2_offset)
{
return addr &= 0x7FFFFFFF;
addr &= 0x7FFFFFFF;
if (addr >= 0x10000000)
{
// MEM2, calculate correct address from MEM2 offset
addr -= 0x10000000;
addr += mem2_offset;
}
return addr;
}

inline u32 offsetToDolphinAddr(u32 offset)
inline u32 offsetToDolphinAddr(u32 offset, u32 mem2_offset)
{
return offset |= 0x80000000;
if (offset < 0 || offset >= 0x2000000)
{
// MEM2, calculate correct address from MEM2 offset
offset += 0x10000000;
offset -= mem2_offset;
}
return offset | 0x80000000;
}
} // namespace Common
25 changes: 18 additions & 7 deletions Source/DolphinProcess/DolphinAccessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ void DolphinAccessor::init()

void DolphinAccessor::free()
{
delete m_instance;
delete[] m_updatedRAMCache;
delete m_instance;
delete[] m_updatedRAMCache;
}

void DolphinAccessor::hook()
Expand Down Expand Up @@ -92,6 +92,15 @@ bool DolphinAccessor::isMEM2Present()
return m_instance->isMEM2Present();
}

u32 DolphinAccessor::getMEM1ToMEM2Distance()
{
if (m_instance == nullptr)
{
return 0;
}
return m_instance->getMEM1ToMEM2Distance();
}

bool DolphinAccessor::isValidConsoleAddress(const u32 address)
{
if (getStatus() != DolphinStatus::hooked)
Expand All @@ -113,9 +122,9 @@ Common::MemOperationReturnCode DolphinAccessor::updateRAMCache()
{
m_updatedRAMCache = new char[Common::MEM1_SIZE + Common::MEM2_SIZE];
// Read Wii extra RAM
if (!DolphinComm::DolphinAccessor::readFromRAM(Common::dolphinAddrToOffset(Common::MEM2_START),
m_updatedRAMCache + Common::MEM1_SIZE,
Common::MEM2_SIZE, false))
if (!DolphinComm::DolphinAccessor::readFromRAM(
Common::dolphinAddrToOffset(Common::MEM2_START, getMEM1ToMEM2Distance()),
m_updatedRAMCache + Common::MEM1_SIZE, Common::MEM2_SIZE, false))
return Common::MemOperationReturnCode::operationFailed;
}
else
Expand Down Expand Up @@ -143,10 +152,12 @@ void DolphinAccessor::copyRawMemoryFromCache(char* dest, const u32 consoleAddres
if (isValidConsoleAddress(consoleAddress) &&
isValidConsoleAddress((consoleAddress + static_cast<u32>(byteCount)) - 1))
{
u32 offset = Common::dolphinAddrToOffset(consoleAddress);
u32 MEM2Distance = getMEM1ToMEM2Distance();
u32 offset = Common::dolphinAddrToOffset(consoleAddress, MEM2Distance);
u32 ramIndex = 0;
if (offset >= Common::MEM1_SIZE)
ramIndex = offset - (Common::MEM2_START - Common::MEM1_END);
// Need to account for the distance between the end of MEM1 and the start of MEM2
ramIndex = offset - (MEM2Distance - Common::MEM1_SIZE);
else
ramIndex = offset;
std::memcpy(dest, m_updatedRAMCache + ramIndex, byteCount);
Expand Down
1 change: 1 addition & 0 deletions Source/DolphinProcess/DolphinAccessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class DolphinAccessor
static u64 getEmuRAMAddressStart();
static DolphinStatus getStatus();
static bool isMEM2Present();
static u32 getMEM1ToMEM2Distance();
static Common::MemOperationReturnCode updateRAMCache();
static std::string getFormattedValueFromCache(const u32 ramIndex, Common::MemType memType,
size_t memSize, Common::MemBase memBase,
Expand Down
13 changes: 12 additions & 1 deletion Source/DolphinProcess/IDolphinProcess.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,25 @@ class IDolphinProcess
{
return m_emuRAMAddressStart;
};
u64 isMEM2Present() const
bool isMEM2Present() const
{
return m_MEM2Present;
};
u64 getMEM2AddressStart() const
{
return m_MEM2AddressStart;
};
u32 getMEM1ToMEM2Distance() const
{
if (!m_MEM2Present)
return 0;
return m_MEM2AddressStart - m_emuRAMAddressStart;
};

protected:
int m_PID = -1;
u64 m_emuRAMAddressStart = 0;
u64 m_MEM2AddressStart = 0;
bool m_MEM2Present = false;
};
} // namespace DolphinComm
83 changes: 50 additions & 33 deletions Source/DolphinProcess/Linux/LinuxDolphinProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <string>

#include <sys/uio.h>
#include <vector>

namespace DolphinComm
{
Expand All @@ -20,43 +21,59 @@ bool LinuxDolphinProcess::obtainEmuRAMInformations()
bool MEM1Found = false;
while (getline(theMapsFile, line))
{
if (line.length() > 73)
std::vector<std::string> lineData;
std::string token;
std::stringstream ss(line);
while (getline(ss, token, ' '))
{
if (line.substr(73, 19) == "/dev/shm/dolphinmem" ||
line.substr(73, 20) == "/dev/shm/dolphin-emu")
if (!token.empty())
lineData.push_back(token);
}

if (lineData.size() < 3)
continue;

bool foundDevShmDolphin = false;
for (auto str : lineData)
{
if (str.substr(0, 19) == "/dev/shm/dolphinmem" || str.substr(0, 20) == "/dev/shm/dolphin-emu")
{
u64 firstAddress = 0;
u64 SecondAddress = 0;
std::string firstAddressStr("0x" + line.substr(0, 12));
std::string secondAddressStr("0x" + line.substr(13, 12));

firstAddress = std::stoul(firstAddressStr, nullptr, 16);
SecondAddress = std::stoul(secondAddressStr, nullptr, 16);

if (MEM1Found)
{
if (firstAddress == m_emuRAMAddressStart + 0x10000000)
{
m_MEM2Present = true;
break;
}
else if (firstAddress > m_emuRAMAddressStart + 0x10000000)
{
m_MEM2Present = false;
break;
}
continue;
}

u64 test = SecondAddress - firstAddress;

if (SecondAddress - firstAddress == 0x2000000)
{
m_emuRAMAddressStart = firstAddress;
MEM1Found = true;
}
foundDevShmDolphin = true;
break;
}
}

if (!foundDevShmDolphin)
continue;

u32 offset = 0;
std::string offsetStr("0x" + lineData[2]);
offset = std::stoul(offsetStr, nullptr, 16);
if (offset != 0 && offset != 0x2040000)
continue;

u64 firstAddress = 0;
u64 SecondAddress = 0;
int indexDash = lineData[0].find('-');
std::string firstAddressStr("0x" + lineData[0].substr(0, indexDash));
std::string secondAddressStr("0x" + lineData[0].substr(indexDash + 1));

firstAddress = std::stoul(firstAddressStr, nullptr, 16);
SecondAddress = std::stoul(secondAddressStr, nullptr, 16);

if (SecondAddress - firstAddress == 0x4000000 && offset == 0x2040000)
{
m_MEM2AddressStart = firstAddress;
m_MEM2Present = true;
if (MEM1Found)
break;
}

if (SecondAddress - firstAddress == 0x2000000 && offset == 0x0)
{
m_emuRAMAddressStart = firstAddress;
MEM1Found = true;
}
}

if (m_emuRAMAddressStart != 0)
Expand Down
35 changes: 18 additions & 17 deletions Source/DolphinProcess/Windows/WindowsDolphinProcess.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,32 +51,31 @@ bool WindowsDolphinProcess::obtainEmuRAMInformations()
for (unsigned char* p = nullptr;
VirtualQueryEx(m_hDolphin, p, &info, sizeof(info)) == sizeof(info); p += info.RegionSize)
{
if (MEM1Found)
// Check region size so that we know it's MEM2
if (info.RegionSize == 0x4000000)
{
u64 regionBaseAddress = 0;
std::memcpy(&regionBaseAddress, &(info.BaseAddress), sizeof(info.BaseAddress));

if (regionBaseAddress == m_emuRAMAddressStart + 0x10000000)
if (MEM1Found && regionBaseAddress > m_emuRAMAddressStart + 0x10000000)
{
// View the comment for MEM1.
PSAPI_WORKING_SET_EX_INFORMATION wsInfo;
wsInfo.VirtualAddress = info.BaseAddress;
if (QueryWorkingSetEx(m_hDolphin, &wsInfo, sizeof(PSAPI_WORKING_SET_EX_INFORMATION)))
{
if (wsInfo.VirtualAttributes.Valid)
m_MEM2Present = true;
}
// In some cases MEM2 could actually be before MEM1. Once we find MEM1, ignore regions of
// this size that are too far away. There apparently are other non-MEM2 regions of size
// 0x4000000.
break;
}
else if (regionBaseAddress > m_emuRAMAddressStart + 0x10000000)
// View the comment for MEM1.
PSAPI_WORKING_SET_EX_INFORMATION wsInfo;
wsInfo.VirtualAddress = info.BaseAddress;
if (QueryWorkingSetEx(m_hDolphin, &wsInfo, sizeof(PSAPI_WORKING_SET_EX_INFORMATION)))
{
m_MEM2Present = false;
break;
if (wsInfo.VirtualAttributes.Valid)
{
std::memcpy(&m_MEM2AddressStart, &(regionBaseAddress), sizeof(regionBaseAddress));
m_MEM2Present = true;
}
}
continue;
}

if (info.RegionSize == 0x2000000 && info.Type == MEM_MAPPED)
else if (!MEM1Found && info.RegionSize == 0x2000000 && info.Type == MEM_MAPPED)
{
// Here, it's likely the right page, but it can happen that multiple pages with these criteria
// exists and have nothing to do with the emulated memory. Only the right page has valid
Expand All @@ -93,6 +92,8 @@ bool WindowsDolphinProcess::obtainEmuRAMInformations()
}
}
}
if (MEM1Found && m_MEM2Present)
break;
}
if (m_emuRAMAddressStart == 0)
{
Expand Down
Loading

0 comments on commit 09dbb04

Please sign in to comment.