Merge pull request #12357 from AdmiralCurtiss/ipl-bounds
Core/Boot: Check bounds in Load_BS2().
This commit is contained in:
commit
2ece642cf8
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cmath>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <numeric>
|
||||
|
@ -400,12 +401,20 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename)
|
|||
constexpr u32 PAL_v1_0 = 0x4F319F43;
|
||||
constexpr u32 PAL_v1_2 = 0xAD1B7F16;
|
||||
|
||||
// Load the whole ROM dump
|
||||
std::string data;
|
||||
if (!File::ReadFileToString(boot_rom_filename, data))
|
||||
return false;
|
||||
// Load the IPL ROM dump, limited to 2MiB which is the size of the official IPLs.
|
||||
constexpr size_t max_ipl_size = 2 * 1024 * 1024;
|
||||
std::vector<u8> data;
|
||||
{
|
||||
File::IOFile file(boot_rom_filename, "rb");
|
||||
if (!file)
|
||||
return false;
|
||||
|
||||
const u32 ipl_hash = Common::ComputeCRC32(data);
|
||||
data.resize(static_cast<size_t>(std::min<u64>(file.GetSize(), max_ipl_size)));
|
||||
if (!file.ReadArray(data.data(), data.size()))
|
||||
return false;
|
||||
}
|
||||
|
||||
const u32 ipl_hash = Common::ComputeCRC32(data.data(), data.size());
|
||||
bool known_ipl = false;
|
||||
bool pal_ipl = false;
|
||||
switch (ipl_hash)
|
||||
|
@ -434,15 +443,26 @@ bool CBoot::Load_BS2(Core::System& system, const std::string& boot_rom_filename)
|
|||
}
|
||||
|
||||
// Run the descrambler over the encrypted section containing BS1/BS2
|
||||
ExpansionInterface::CEXIIPL::Descrambler((u8*)data.data() + 0x100, 0x1AFE00);
|
||||
if (data.size() > 0x100)
|
||||
{
|
||||
ExpansionInterface::CEXIIPL::Descrambler(
|
||||
data.data() + 0x100, static_cast<u32>(std::min<size_t>(data.size() - 0x100, 0x1AFE00)));
|
||||
}
|
||||
|
||||
// TODO: Execution is supposed to start at 0xFFF00000, not 0x81200000;
|
||||
// copying the initial boot code to 0x81200000 is a hack.
|
||||
// For now, HLE the first few instructions and start at 0x81200150
|
||||
// to work around this.
|
||||
auto& memory = system.GetMemory();
|
||||
memory.CopyToEmu(0x01200000, data.data() + 0x100, 0x700);
|
||||
memory.CopyToEmu(0x01300000, data.data() + 0x820, 0x1AFE00);
|
||||
if (data.size() > 0x100)
|
||||
{
|
||||
memory.CopyToEmu(0x01200000, data.data() + 0x100, std::min<size_t>(data.size() - 0x100, 0x700));
|
||||
}
|
||||
if (data.size() > 0x820)
|
||||
{
|
||||
memory.CopyToEmu(0x01300000, data.data() + 0x820,
|
||||
std::min<size_t>(data.size() - 0x820, 0x1AFE00));
|
||||
}
|
||||
|
||||
auto& ppc_state = system.GetPPCState();
|
||||
ppc_state.gpr[3] = 0xfff0001f;
|
||||
|
|
Loading…
Reference in New Issue