DOL loader cleanup with std::vector and safety checks
This commit is contained in:
parent
268b8fd26f
commit
35c77abbc2
|
@ -233,7 +233,7 @@ bool CBoot::BootUp()
|
||||||
DVDInterface::SetVolumeName(_StartupPara.m_strFilename);
|
DVDInterface::SetVolumeName(_StartupPara.m_strFilename);
|
||||||
DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid());
|
DVDInterface::SetDiscInside(DVDInterface::VolumeIsValid());
|
||||||
if (!DVDInterface::VolumeIsValid())
|
if (!DVDInterface::VolumeIsValid())
|
||||||
break;
|
return false;
|
||||||
|
|
||||||
const DiscIO::IVolume& pVolume = DVDInterface::GetVolume();
|
const DiscIO::IVolume& pVolume = DVDInterface::GetVolume();
|
||||||
|
|
||||||
|
@ -296,6 +296,9 @@ bool CBoot::BootUp()
|
||||||
case SCoreStartupParameter::BOOT_DOL:
|
case SCoreStartupParameter::BOOT_DOL:
|
||||||
{
|
{
|
||||||
CDolLoader dolLoader(_StartupPara.m_strFilename);
|
CDolLoader dolLoader(_StartupPara.m_strFilename);
|
||||||
|
if (!dolLoader.IsValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
// Check if we have gotten a Wii file or not
|
// Check if we have gotten a Wii file or not
|
||||||
bool dolWii = dolLoader.IsWii();
|
bool dolWii = dolLoader.IsWii();
|
||||||
if (dolWii != _StartupPara.bWii)
|
if (dolWii != _StartupPara.bWii)
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// Refer to the license.txt file included.
|
// Refer to the license.txt file included.
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonFuncs.h"
|
#include "Common/CommonFuncs.h"
|
||||||
#include "Common/FileUtil.h"
|
#include "Common/FileUtil.h"
|
||||||
|
@ -11,106 +12,100 @@
|
||||||
#include "Core/HW/Memmap.h"
|
#include "Core/HW/Memmap.h"
|
||||||
#include "Core/PowerPC/PowerPC.h"
|
#include "Core/PowerPC/PowerPC.h"
|
||||||
|
|
||||||
CDolLoader::CDolLoader(u8* _pBuffer, u32 _Size)
|
CDolLoader::CDolLoader(u8* buffer, size_t size)
|
||||||
: m_isWii(false)
|
|
||||||
{
|
{
|
||||||
Initialize(_pBuffer, _Size);
|
m_is_valid = Initialize(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
CDolLoader::CDolLoader(const std::string& filename)
|
CDolLoader::CDolLoader(const std::string& filename)
|
||||||
: m_isWii(false)
|
|
||||||
{
|
{
|
||||||
const u64 size = File::GetSize(filename);
|
const u64 size = File::GetSize(filename);
|
||||||
u8* const tmpBuffer = new u8[(size_t)size];
|
std::vector<u8> temp_buffer(size);
|
||||||
|
|
||||||
{
|
{
|
||||||
File::IOFile pStream(filename, "rb");
|
File::IOFile pStream(filename, "rb");
|
||||||
pStream.ReadBytes(tmpBuffer, (size_t)size);
|
pStream.ReadBytes(temp_buffer.data(), temp_buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
Initialize(tmpBuffer, (u32)size);
|
m_is_valid = Initialize(temp_buffer.data(), temp_buffer.size());
|
||||||
delete[] tmpBuffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CDolLoader::~CDolLoader()
|
CDolLoader::~CDolLoader()
|
||||||
{
|
{
|
||||||
for (auto& sect : text_section)
|
|
||||||
{
|
|
||||||
delete [] sect;
|
|
||||||
sect = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto& sect : data_section)
|
|
||||||
{
|
|
||||||
delete [] sect;
|
|
||||||
sect = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDolLoader::Initialize(u8* _pBuffer, u32 _Size)
|
bool CDolLoader::Initialize(u8* buffer, size_t size)
|
||||||
{
|
{
|
||||||
memcpy(&m_dolheader, _pBuffer, sizeof(SDolHeader));
|
if (size < sizeof(SDolHeader))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
memcpy(&m_dolheader, buffer, sizeof(SDolHeader));
|
||||||
|
|
||||||
// swap memory
|
// swap memory
|
||||||
u32* p = (u32*)&m_dolheader;
|
u32* p = (u32*)&m_dolheader;
|
||||||
for (size_t i = 0; i < (sizeof(SDolHeader)/sizeof(u32)); i++)
|
for (size_t i = 0; i < (sizeof(SDolHeader) / sizeof(u32)); i++)
|
||||||
p[i] = Common::swap32(p[i]);
|
p[i] = Common::swap32(p[i]);
|
||||||
|
|
||||||
for (auto& sect : text_section)
|
const u32 HID4_pattern = Common::swap32(0x7c13fba6);
|
||||||
sect = nullptr;
|
const u32 HID4_mask = Common::swap32(0xfc1fffff);
|
||||||
for (auto& sect : data_section)
|
|
||||||
sect = nullptr;
|
|
||||||
|
|
||||||
u32 HID4_pattern = 0x7c13fba6;
|
m_is_wii = false;
|
||||||
u32 HID4_mask = 0xfc1fffff;
|
|
||||||
|
|
||||||
for (int i = 0; i < DOL_NUM_TEXT; i++)
|
m_text_sections.reserve(DOL_NUM_TEXT);
|
||||||
|
for (int i = 0; i < DOL_NUM_TEXT; ++i)
|
||||||
{
|
{
|
||||||
if (m_dolheader.textOffset[i] != 0)
|
if (m_dolheader.textSize[i] != 0)
|
||||||
{
|
{
|
||||||
text_section[i] = new u8[m_dolheader.textSize[i]];
|
if (size < m_dolheader.textOffset[i] + m_dolheader.textSize[i])
|
||||||
memcpy(text_section[i], _pBuffer + m_dolheader.textOffset[i], m_dolheader.textSize[i]);
|
return false;
|
||||||
for (unsigned int j = 0; j < (m_dolheader.textSize[i]/sizeof(u32)); j++)
|
|
||||||
|
u8* text_start = buffer + m_dolheader.textOffset[i];
|
||||||
|
m_text_sections.emplace_back(text_start, text_start + m_dolheader.textSize[i]);
|
||||||
|
|
||||||
|
for (unsigned int j = 0; !m_is_wii && j < (m_dolheader.textSize[i] / sizeof(u32)); ++j)
|
||||||
{
|
{
|
||||||
u32 word = Common::swap32(((u32*)text_section[i])[j]);
|
u32 word = ((u32*)text_start)[j];
|
||||||
if ((word & HID4_mask) == HID4_pattern)
|
if ((word & HID4_mask) == HID4_pattern)
|
||||||
{
|
m_is_wii = true;
|
||||||
m_isWii = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
|
|
||||||
for (int i = 0; i < DOL_NUM_DATA; i++)
|
|
||||||
{
|
|
||||||
if (m_dolheader.dataOffset[i] != 0)
|
|
||||||
{
|
{
|
||||||
data_section[i] = new u8[m_dolheader.dataSize[i]];
|
// Make sure that m_text_sections indexes match header indexes
|
||||||
memcpy(data_section[i], _pBuffer + m_dolheader.dataOffset[i], m_dolheader.dataSize[i]);
|
m_text_sections.emplace_back();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_data_sections.reserve(DOL_NUM_DATA);
|
||||||
|
for (int i = 0; i < DOL_NUM_DATA; ++i)
|
||||||
|
{
|
||||||
|
if (m_dolheader.dataSize[i] != 0)
|
||||||
|
{
|
||||||
|
if (size < m_dolheader.dataOffset[i] + m_dolheader.dataSize[i])
|
||||||
|
return false;
|
||||||
|
|
||||||
|
u8* data_start = buffer + m_dolheader.dataOffset[i];
|
||||||
|
m_data_sections.emplace_back(data_start, data_start + m_dolheader.dataSize[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Make sure that m_data_sections indexes match header indexes
|
||||||
|
m_data_sections.emplace_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDolLoader::Load()
|
void CDolLoader::Load() const
|
||||||
{
|
{
|
||||||
// load all text (code) sections
|
// load all text (code) sections
|
||||||
for (int i = 0; i < DOL_NUM_TEXT; i++)
|
for (size_t i = 0; i < m_text_sections.size(); ++i)
|
||||||
{
|
if (!m_text_sections[i].empty())
|
||||||
if (m_dolheader.textOffset[i] != 0)
|
Memory::CopyToEmu(m_dolheader.textAddress[i], m_text_sections[i].data(), m_text_sections[i].size());
|
||||||
{
|
|
||||||
for (u32 num = 0; num < m_dolheader.textSize[i]; num++)
|
|
||||||
Memory::Write_U8(text_section[i][num], m_dolheader.textAddress[i] + num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load all data sections
|
// load all data sections
|
||||||
for (int i = 0; i < DOL_NUM_DATA; i++)
|
for (size_t i = 0; i < m_data_sections.size(); ++i)
|
||||||
{
|
if (!m_data_sections[i].empty())
|
||||||
if (m_dolheader.dataOffset[i] != 0)
|
Memory::CopyToEmu(m_dolheader.dataAddress[i], m_data_sections[i].data(), m_data_sections[i].size());
|
||||||
{
|
|
||||||
for (u32 num = 0; num < m_dolheader.dataSize[i]; num++)
|
|
||||||
Memory::Write_U8(data_section[i][num], m_dolheader.dataAddress[i] + num);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
|
||||||
|
@ -12,14 +13,15 @@ class CDolLoader
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
CDolLoader(const std::string& filename);
|
CDolLoader(const std::string& filename);
|
||||||
CDolLoader(u8* _pBuffer, u32 _Size);
|
CDolLoader(u8* buffer, size_t size);
|
||||||
~CDolLoader();
|
~CDolLoader();
|
||||||
|
|
||||||
bool IsWii() const { return m_isWii; }
|
bool IsValid() const { return m_is_valid; }
|
||||||
|
bool IsWii() const { return m_is_wii; }
|
||||||
u32 GetEntryPoint() const { return m_dolheader.entryPoint; }
|
u32 GetEntryPoint() const { return m_dolheader.entryPoint; }
|
||||||
|
|
||||||
// Load into emulated memory
|
// Load into emulated memory
|
||||||
void Load();
|
void Load() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum
|
enum
|
||||||
|
@ -42,15 +44,15 @@ private:
|
||||||
u32 bssAddress;
|
u32 bssAddress;
|
||||||
u32 bssSize;
|
u32 bssSize;
|
||||||
u32 entryPoint;
|
u32 entryPoint;
|
||||||
u32 padd[7];
|
|
||||||
};
|
};
|
||||||
SDolHeader m_dolheader;
|
SDolHeader m_dolheader;
|
||||||
|
|
||||||
u8 *data_section[DOL_NUM_DATA];
|
std::vector<std::vector<u8>> m_data_sections;
|
||||||
u8 *text_section[DOL_NUM_TEXT];
|
std::vector<std::vector<u8>> m_text_sections;
|
||||||
|
|
||||||
bool m_isWii;
|
bool m_is_valid;
|
||||||
|
bool m_is_wii;
|
||||||
|
|
||||||
// Copy sections to internal buffers
|
// Copy sections to internal buffers
|
||||||
void Initialize(u8* _pBuffer, u32 _Size);
|
bool Initialize(u8* buffer, size_t size);
|
||||||
};
|
};
|
||||||
|
|
|
@ -106,6 +106,9 @@ bool CBoot::Boot_WiiWAD(const std::string& _pFilename)
|
||||||
{
|
{
|
||||||
pDolLoader = std::make_unique<CDolLoader>(pContent->m_Filename);
|
pDolLoader = std::make_unique<CDolLoader>(pContent->m_Filename);
|
||||||
}
|
}
|
||||||
|
if (!pDolLoader->IsValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
pDolLoader->Load();
|
pDolLoader->Load();
|
||||||
PC = pDolLoader->GetEntryPoint();
|
PC = pDolLoader->GetEntryPoint();
|
||||||
|
|
||||||
|
|
|
@ -924,10 +924,20 @@ IPCCommandResult CWII_IPC_HLE_Device_es::IOCtlV(u32 _CommandAddress)
|
||||||
{
|
{
|
||||||
pDolLoader = std::make_unique<CDolLoader>(pContent->m_Filename);
|
pDolLoader = std::make_unique<CDolLoader>(pContent->m_Filename);
|
||||||
}
|
}
|
||||||
pDolLoader->Load(); // TODO: Check why sysmenu does not load the DOL correctly
|
|
||||||
PC = pDolLoader->GetEntryPoint();
|
if (pDolLoader->IsValid())
|
||||||
|
{
|
||||||
|
pDolLoader->Load(); // TODO: Check why sysmenu does not load the DOL correctly
|
||||||
|
PC = pDolLoader->GetEntryPoint();
|
||||||
|
bSuccess = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PanicAlertT("IOCTL_ES_LAUNCH: The DOL file is invalid!");
|
||||||
|
bSuccess = false;
|
||||||
|
}
|
||||||
|
|
||||||
IOSv = ContentLoader.GetIosVersion();
|
IOSv = ContentLoader.GetIosVersion();
|
||||||
bSuccess = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue