Boot: Unify the ELF and DOL code paths

They're essentially the same. To achieve this, this commit unifies
DolReader and ElfReader into a common interface for boot executable
readers, so the only remaining difference between ELF and DOL is
how which volume is inserted.
This commit is contained in:
Léo Lam 2017-05-28 17:12:38 +02:00
parent 22992ae41e
commit 065261dbad
13 changed files with 195 additions and 233 deletions

View File

@ -21,7 +21,8 @@
#include "Common/MsgHandler.h" #include "Common/MsgHandler.h"
#include "Common/StringUtil.h" #include "Common/StringUtil.h"
#include "Core/Boot/Boot_DOL.h" #include "Core/Boot/DolReader.h"
#include "Core/Boot/ElfReader.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/Debugger/Debugger_SymbolMap.h" #include "Core/Debugger/Debugger_SymbolMap.h"
@ -86,11 +87,11 @@ std::unique_ptr<BootParameters> BootParameters::GenerateFromFile(const std::stri
return std::make_unique<BootParameters>(Disc{path, std::move(volume)}); return std::make_unique<BootParameters>(Disc{path, std::move(volume)});
} }
if (extension == ".elf" || extension == ".dol") if (extension == ".elf")
{ return std::make_unique<BootParameters>(Executable{path, std::make_unique<ElfReader>(path)});
return std::make_unique<BootParameters>(
Executable{path, extension == ".elf" ? Executable::Type::ELF : Executable::Type::DOL}); if (extension == ".dol")
} return std::make_unique<BootParameters>(Executable{path, std::make_unique<DolReader>(path)});
if (extension == ".dff") if (extension == ".dff")
return std::make_unique<BootParameters>(DFF{path}); return std::make_unique<BootParameters>(DFF{path});
@ -371,14 +372,13 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
{ {
NOTICE_LOG(BOOT, "Booting from executable: %s", executable.path.c_str()); NOTICE_LOG(BOOT, "Booting from executable: %s", executable.path.c_str());
// TODO: needs more cleanup. if (!executable.reader->IsValid())
if (executable.type == BootParameters::Executable::Type::DOL) return false;
{
CDolLoader dolLoader(executable.path);
if (!dolLoader.IsValid())
return false;
const DiscIO::Volume* volume = nullptr; const DiscIO::Volume* volume = nullptr;
// VolumeDirectory only works with DOLs.
if (StringEndsWith(executable.path, ".dol"))
{
if (!config.m_strDVDRoot.empty()) if (!config.m_strDVDRoot.empty())
{ {
NOTICE_LOG(BOOT, "Setting DVDRoot %s", config.m_strDVDRoot.c_str()); NOTICE_LOG(BOOT, "Setting DVDRoot %s", config.m_strDVDRoot.c_str());
@ -390,57 +390,41 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
NOTICE_LOG(BOOT, "Loading default ISO %s", config.m_strDefaultISO.c_str()); NOTICE_LOG(BOOT, "Loading default ISO %s", config.m_strDefaultISO.c_str());
volume = SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO)); volume = SetDisc(DiscIO::CreateVolumeFromFilename(config.m_strDefaultISO));
} }
// Poor man's bootup
if (config.bWii)
{
HID4.SBE = 1;
SetupMSR();
SetupBAT(config.bWii);
// Because there is no TMD to get the requested system (IOS) version from,
// we default to IOS58, which is the version used by the Homebrew Channel.
SetupWiiMemory(volume, 0x000000010000003a);
}
else
{
EmulatedBS2_GC(volume, true);
}
Load_FST(config.bWii, volume);
dolLoader.Load();
PC = dolLoader.GetEntryPoint();
if (LoadMapFromFilename())
HLE::PatchFunctions();
} }
else
if (executable.type == BootParameters::Executable::Type::ELF)
{ {
const DiscIO::Volume* volume = SetDefaultDisc(); volume = SetDefaultDisc();
// Poor man's bootup
if (config.bWii)
{
// Because there is no TMD to get the requested system (IOS) version from,
// we default to IOS58, which is the version used by the Homebrew Channel.
SetupWiiMemory(volume, 0x000000010000003a);
}
else
{
EmulatedBS2_GC(volume, true);
}
Load_FST(config.bWii, volume);
if (!Boot_ELF(executable.path))
return false;
// Note: Boot_ELF calls HLE::PatchFunctions()
UpdateDebugger_MapLoaded();
Dolphin_Debugger::AddAutoBreakpoints();
} }
if (!executable.reader->LoadIntoMemory())
{
PanicAlertT("Failed to load the executable to memory.");
return false;
}
// Poor man's bootup
if (config.bWii)
{
HID4.SBE = 1;
SetupMSR();
SetupBAT(config.bWii);
// Because there is no TMD to get the requested system (IOS) version from,
// we default to IOS58, which is the version used by the Homebrew Channel.
SetupWiiMemory(volume, 0x000000010000003a);
}
else
{
EmulatedBS2_GC(volume, true);
}
Load_FST(config.bWii, volume);
PC = executable.reader->GetEntryPoint();
if (executable.reader->LoadSymbols() || LoadMapFromFilename())
{
UpdateDebugger_MapLoaded();
HLE::PatchFunctions();
}
return true; return true;
} }
@ -495,3 +479,16 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
HLE::PatchFixedFunctions(); HLE::PatchFixedFunctions();
return true; return true;
} }
BootExecutableReader::BootExecutableReader(const std::string& file_name)
{
m_bytes.resize(File::GetSize(file_name));
File::IOFile file{file_name, "rb"};
file.ReadBytes(m_bytes.data(), m_bytes.size());
}
BootExecutableReader::BootExecutableReader(const std::vector<u8>& bytes) : m_bytes(bytes)
{
}
BootExecutableReader::~BootExecutableReader() = default;

View File

@ -5,9 +5,11 @@
#pragma once #pragma once
#include <cstdlib> #include <cstdlib>
#include <memory>
#include <optional> #include <optional>
#include <string> #include <string>
#include <variant> #include <variant>
#include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "DiscIO/Enums.h" #include "DiscIO/Enums.h"
@ -21,6 +23,8 @@ struct RegionSetting
const std::string code; const std::string code;
}; };
class BootExecutableReader;
struct BootParameters struct BootParameters
{ {
struct Disc struct Disc
@ -31,13 +35,8 @@ struct BootParameters
struct Executable struct Executable
{ {
enum class Type
{
DOL,
ELF,
};
std::string path; std::string path;
Type type; std::unique_ptr<BootExecutableReader> reader;
}; };
struct NAND struct NAND
@ -72,7 +71,6 @@ class CBoot
{ {
public: public:
static bool BootUp(std::unique_ptr<BootParameters> boot); static bool BootUp(std::unique_ptr<BootParameters> boot);
static bool IsElfWii(const std::string& filename);
// Tries to find a map file for the current game by looking first in the // Tries to find a map file for the current game by looking first in the
// local user directory, then in the shared user directory. // local user directory, then in the shared user directory.
@ -97,7 +95,6 @@ private:
static void UpdateDebugger_MapLoaded(); static void UpdateDebugger_MapLoaded();
static bool Boot_ELF(const std::string& filename);
static bool Boot_WiiWAD(const std::string& filename); static bool Boot_WiiWAD(const std::string& filename);
static void SetupMSR(); static void SetupMSR();
@ -111,3 +108,20 @@ private:
static bool SetupWiiMemory(const DiscIO::Volume* volume, u64 ios_title_id); static bool SetupWiiMemory(const DiscIO::Volume* volume, u64 ios_title_id);
}; };
class BootExecutableReader
{
public:
BootExecutableReader(const std::string& file_name);
BootExecutableReader(const std::vector<u8>& buffer);
virtual ~BootExecutableReader();
virtual u32 GetEntryPoint() const = 0;
virtual bool IsValid() const = 0;
virtual bool IsWii() const = 0;
virtual bool LoadIntoMemory(bool only_in_mem1 = false) const = 0;
virtual bool LoadSymbols() const = 0;
protected:
std::vector<u8> m_bytes;
};

View File

@ -1,89 +0,0 @@
// Copyright 2008 Dolphin Emulator Project
// Licensed under GPLv2+
// Refer to the license.txt file included.
#include <memory>
#include "Common/FileUtil.h"
#include "Common/Swap.h"
#include "Core/Boot/Boot.h"
#include "Core/Boot/ElfReader.h"
#include "Core/HLE/HLE.h"
#include "Core/PowerPC/PowerPC.h"
bool CBoot::IsElfWii(const std::string& filename)
{
/* We already check if filename existed before we called this function, so
there is no need for another check, just read the file right away */
size_t filesize = File::GetSize(filename);
auto elf = std::make_unique<u8[]>(filesize);
{
File::IOFile f(filename, "rb");
f.ReadBytes(elf.get(), filesize);
}
// Use the same method as the DOL loader uses: search for mfspr from HID4,
// which should only be used in Wii ELFs.
//
// Likely to have some false positives/negatives, patches implementing a
// better heuristic are welcome.
// Swap these once, instead of swapping every word in the file.
u32 HID4_pattern = Common::swap32(0x7c13fba6);
u32 HID4_mask = Common::swap32(0xfc1fffff);
ElfReader reader(elf.get());
for (int i = 0; i < reader.GetNumSegments(); ++i)
{
if (reader.IsCodeSegment(i))
{
u32* code = (u32*)reader.GetSegmentPtr(i);
for (u32 j = 0; j < reader.GetSegmentSize(i) / sizeof(u32); ++j)
{
if ((code[j] & HID4_mask) == HID4_pattern)
return true;
}
}
}
return false;
}
bool CBoot::Boot_ELF(const std::string& filename)
{
// Read ELF from file
size_t filesize = File::GetSize(filename);
auto elf = std::make_unique<u8[]>(filesize);
{
File::IOFile f(filename, "rb");
f.ReadBytes(elf.get(), filesize);
}
// Load ELF into GameCube Memory
ElfReader reader(elf.get());
if (!reader.LoadIntoMemory())
return false;
const bool is_wii = IsElfWii(filename);
if (is_wii)
HID4.SBE = 1;
SetupMSR();
SetupBAT(is_wii);
if (!reader.LoadSymbols())
{
if (LoadMapFromFilename())
HLE::PatchFunctions();
}
else
{
HLE::PatchFunctions();
}
PC = reader.GetEntryPoint();
return true;
}

View File

@ -2,7 +2,7 @@
// Licensed under GPLv2+ // Licensed under GPLv2+
// Refer to the license.txt file included. // Refer to the license.txt file included.
#include "Core/Boot/Boot_DOL.h" #include "Core/Boot/DolReader.h"
#include <cstring> #include <cstring>
#include <string> #include <string>
@ -12,29 +12,19 @@
#include "Common/Swap.h" #include "Common/Swap.h"
#include "Core/HW/Memmap.h" #include "Core/HW/Memmap.h"
CDolLoader::CDolLoader(const std::vector<u8>& buffer) DolReader::DolReader(const std::vector<u8>& buffer) : BootExecutableReader(buffer)
{ {
m_is_valid = Initialize(buffer); m_is_valid = Initialize(buffer);
} }
CDolLoader::CDolLoader(const std::string& filename) DolReader::DolReader(const std::string& filename) : BootExecutableReader(filename)
{ {
const u64 size = File::GetSize(filename); m_is_valid = Initialize(m_bytes);
std::vector<u8> temp_buffer(size);
{
File::IOFile pStream(filename, "rb");
pStream.ReadBytes(temp_buffer.data(), temp_buffer.size());
}
m_is_valid = Initialize(temp_buffer);
} }
CDolLoader::~CDolLoader() DolReader::~DolReader() = default;
{
}
bool CDolLoader::Initialize(const std::vector<u8>& buffer) bool DolReader::Initialize(const std::vector<u8>& buffer)
{ {
if (buffer.size() < sizeof(SDolHeader)) if (buffer.size() < sizeof(SDolHeader))
return false; return false;
@ -97,17 +87,30 @@ bool CDolLoader::Initialize(const std::vector<u8>& buffer)
return true; return true;
} }
void CDolLoader::Load() const bool DolReader::LoadIntoMemory(bool only_in_mem1) const
{ {
if (!m_is_valid)
return false;
// load all text (code) sections // load all text (code) sections
for (size_t i = 0; i < m_text_sections.size(); ++i) for (size_t i = 0; i < m_text_sections.size(); ++i)
if (!m_text_sections[i].empty()) if (!m_text_sections[i].empty() &&
!(only_in_mem1 &&
m_dolheader.textAddress[i] + m_text_sections[i].size() >= Memory::REALRAM_SIZE))
{
Memory::CopyToEmu(m_dolheader.textAddress[i], m_text_sections[i].data(), Memory::CopyToEmu(m_dolheader.textAddress[i], m_text_sections[i].data(),
m_text_sections[i].size()); m_text_sections[i].size());
}
// load all data sections // load all data sections
for (size_t i = 0; i < m_data_sections.size(); ++i) for (size_t i = 0; i < m_data_sections.size(); ++i)
if (!m_data_sections[i].empty()) if (!m_data_sections[i].empty() &&
!(only_in_mem1 &&
m_dolheader.dataAddress[i] + m_data_sections[i].size() >= Memory::REALRAM_SIZE))
{
Memory::CopyToEmu(m_dolheader.dataAddress[i], m_data_sections[i].data(), Memory::CopyToEmu(m_dolheader.dataAddress[i], m_data_sections[i].data(),
m_data_sections[i].size()); m_data_sections[i].size());
}
return true;
} }

View File

@ -8,20 +8,20 @@
#include <vector> #include <vector>
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Core/Boot/Boot.h"
class CDolLoader class DolReader final : public BootExecutableReader
{ {
public: public:
CDolLoader(const std::string& filename); DolReader(const std::string& filename);
CDolLoader(const std::vector<u8>& buffer); DolReader(const std::vector<u8>& buffer);
~CDolLoader(); ~DolReader();
bool IsValid() const { return m_is_valid; }
bool IsWii() const { return m_is_wii; }
u32 GetEntryPoint() const { return m_dolheader.entryPoint; }
// Load into emulated memory
void Load() const;
bool IsValid() const override { return m_is_valid; }
bool IsWii() const override { return m_is_wii; }
u32 GetEntryPoint() const override { return m_dolheader.entryPoint; }
bool LoadIntoMemory(bool only_in_mem1 = false) const override;
bool LoadSymbols() const override { return false; }
private: private:
enum enum
{ {

View File

@ -66,7 +66,17 @@ static void byteswapSection(Elf32_Shdr& sec)
bswap(sec.sh_type); bswap(sec.sh_type);
} }
ElfReader::ElfReader(void* ptr) ElfReader::ElfReader(const std::vector<u8>& buffer) : BootExecutableReader(buffer)
{
Initialize(m_bytes.data());
}
ElfReader::ElfReader(const std::string& filename) : BootExecutableReader(filename)
{
Initialize(m_bytes.data());
}
void ElfReader::Initialize(u8* ptr)
{ {
base = (char*)ptr; base = (char*)ptr;
base32 = (u32*)ptr; base32 = (u32*)ptr;
@ -86,6 +96,8 @@ ElfReader::ElfReader(void* ptr)
byteswapSection(sections[i]); byteswapSection(sections[i]);
} }
entryPoint = header->e_entry; entryPoint = header->e_entry;
bRelocate = (header->e_type != ET_EXEC);
} }
const char* ElfReader::GetSectionName(int section) const const char* ElfReader::GetSectionName(int section) const
@ -103,13 +115,10 @@ const char* ElfReader::GetSectionName(int section) const
} }
// This is just a simple elf loader, good enough to load elfs generated by devkitPPC // This is just a simple elf loader, good enough to load elfs generated by devkitPPC
bool ElfReader::LoadIntoMemory(bool only_in_mem1) bool ElfReader::LoadIntoMemory(bool only_in_mem1) const
{ {
INFO_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx); INFO_LOG(MASTER_LOG, "String section: %i", header->e_shstrndx);
// Should we relocate?
bRelocate = (header->e_type != ET_EXEC);
if (bRelocate) if (bRelocate)
{ {
PanicAlert("Error: Dolphin doesn't know how to load a relocatable elf."); PanicAlert("Error: Dolphin doesn't know how to load a relocatable elf.");
@ -160,7 +169,7 @@ SectionID ElfReader::GetSectionByName(const char* name, int firstSection) const
return -1; return -1;
} }
bool ElfReader::LoadSymbols() bool ElfReader::LoadSymbols() const
{ {
bool hasSymbols = false; bool hasSymbols = false;
SectionID sec = GetSectionByName(".symtab"); SectionID sec = GetSectionByName(".symtab");
@ -205,3 +214,31 @@ bool ElfReader::LoadSymbols()
g_symbolDB.Index(); g_symbolDB.Index();
return hasSymbols; return hasSymbols;
} }
bool ElfReader::IsWii() const
{
// Use the same method as the DOL loader uses: search for mfspr from HID4,
// which should only be used in Wii ELFs.
//
// Likely to have some false positives/negatives, patches implementing a
// better heuristic are welcome.
// Swap these once, instead of swapping every word in the file.
u32 HID4_pattern = Common::swap32(0x7c13fba6);
u32 HID4_mask = Common::swap32(0xfc1fffff);
for (int i = 0; i < GetNumSegments(); ++i)
{
if (IsCodeSegment(i))
{
u32* code = (u32*)GetSegmentPtr(i);
for (u32 j = 0; j < GetSegmentSize(i) / sizeof(u32); ++j)
{
if ((code[j] & HID4_mask) == HID4_pattern)
return true;
}
}
}
return false;
}

View File

@ -5,6 +5,7 @@
#pragma once #pragma once
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Core/Boot/Boot.h"
#include "Core/Boot/ElfTypes.h" #include "Core/Boot/ElfTypes.h"
enum KnownElfTypes enum KnownElfTypes
@ -17,31 +18,23 @@ enum KnownElfTypes
typedef int SectionID; typedef int SectionID;
class ElfReader class ElfReader final : public BootExecutableReader
{ {
private:
char* base;
u32* base32;
Elf32_Ehdr* header;
Elf32_Phdr* segments;
Elf32_Shdr* sections;
u32* sectionAddrs;
bool bRelocate;
u32 entryPoint;
public: public:
explicit ElfReader(void* ptr); ElfReader(const std::string& filename);
ElfReader(const std::vector<u8>& buffer);
~ElfReader() {} ~ElfReader() {}
u32 Read32(int off) const { return base32[off >> 2]; } u32 Read32(int off) const { return base32[off >> 2]; }
// Quick accessors // Quick accessors
ElfType GetType() const { return (ElfType)(header->e_type); } ElfType GetType() const { return (ElfType)(header->e_type); }
ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); } ElfMachine GetMachine() const { return (ElfMachine)(header->e_machine); }
u32 GetEntryPoint() const { return entryPoint; } u32 GetEntryPoint() const override { return entryPoint; }
u32 GetFlags() const { return (u32)(header->e_flags); } u32 GetFlags() const { return (u32)(header->e_flags); }
bool LoadIntoMemory(bool only_in_mem1 = false); bool LoadIntoMemory(bool only_in_mem1 = false) const override;
bool LoadSymbols(); bool LoadSymbols() const override;
// TODO: actually check for validity.
bool IsValid() const override { return true; }
bool IsWii() const override;
int GetNumSegments() const { return (int)(header->e_phnum); } int GetNumSegments() const { return (int)(header->e_phnum); }
int GetNumSections() const { return (int)(header->e_shnum); } int GetNumSections() const { return (int)(header->e_shnum); }
@ -57,11 +50,24 @@ public:
return nullptr; return nullptr;
} }
bool IsCodeSegment(int segment) const { return segments[segment].p_flags & PF_X; } bool IsCodeSegment(int segment) const { return segments[segment].p_flags & PF_X; }
const u8* GetSegmentPtr(int segment) { return GetPtr(segments[segment].p_offset); } const u8* GetSegmentPtr(int segment) const { return GetPtr(segments[segment].p_offset); }
int GetSegmentSize(int segment) const { return segments[segment].p_filesz; } int GetSegmentSize(int segment) const { return segments[segment].p_filesz; }
u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; } u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
int GetSectionSize(SectionID section) const { return sections[section].sh_size; } int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
SectionID GetSectionByName(const char* name, int firstSection = 0) const; //-1 for not found SectionID GetSectionByName(const char* name, int firstSection = 0) const; //-1 for not found
bool DidRelocate() const { return bRelocate; } bool DidRelocate() const { return bRelocate; }
private:
void Initialize(u8* bytes);
char* base;
u32* base32;
Elf32_Ehdr* header;
Elf32_Phdr* segments;
Elf32_Shdr* sections;
u32* sectionAddrs;
bool bRelocate;
u32 entryPoint;
}; };

View File

@ -21,9 +21,8 @@ set(SRCS
WiiRoot.cpp WiiRoot.cpp
Boot/Boot_BS2Emu.cpp Boot/Boot_BS2Emu.cpp
Boot/Boot.cpp Boot/Boot.cpp
Boot/Boot_DOL.cpp
Boot/Boot_ELF.cpp
Boot/Boot_WiiWAD.cpp Boot/Boot_WiiWAD.cpp
Boot/DolReader.cpp
Boot/ElfReader.cpp Boot/ElfReader.cpp
Config/Config.cpp Config/Config.cpp
Config/GraphicsSettings.cpp Config/GraphicsSettings.cpp

View File

@ -23,7 +23,6 @@
#include "Core/Analytics.h" #include "Core/Analytics.h"
#include "Core/Boot/Boot.h" #include "Core/Boot/Boot.h"
#include "Core/Boot/Boot_DOL.h"
#include "Core/Config/Config.h" #include "Core/Config/Config.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/Core.h" #include "Core/Core.h"
@ -896,10 +895,10 @@ struct SetGameMetadata
bool operator()(const BootParameters::Executable& executable) const bool operator()(const BootParameters::Executable& executable) const
{ {
if (executable.type == BootParameters::Executable::Type::DOL) if (!executable.reader->IsValid())
config->bWii = CDolLoader{executable.path}.IsWii(); return false;
if (executable.type == BootParameters::Executable::Type::ELF)
config->bWii = CBoot::IsElfWii(executable.path); config->bWii = executable.reader->IsWii();
// TODO: Right now GC homebrew boots in NTSC and Wii homebrew in PAL. // TODO: Right now GC homebrew boots in NTSC and Wii homebrew in PAL.
// This is intentional so that Wii homebrew can boot in both 50Hz and 60Hz, // This is intentional so that Wii homebrew can boot in both 50Hz and 60Hz,

View File

@ -52,9 +52,8 @@
<ClCompile Include="BootManager.cpp" /> <ClCompile Include="BootManager.cpp" />
<ClCompile Include="Boot\Boot.cpp" /> <ClCompile Include="Boot\Boot.cpp" />
<ClCompile Include="Boot\Boot_BS2Emu.cpp" /> <ClCompile Include="Boot\Boot_BS2Emu.cpp" />
<ClCompile Include="Boot\Boot_DOL.cpp" />
<ClCompile Include="Boot\Boot_ELF.cpp" />
<ClCompile Include="Boot\Boot_WiiWAD.cpp" /> <ClCompile Include="Boot\Boot_WiiWAD.cpp" />
<ClCompile Include="Boot\DolReader.cpp" />
<ClCompile Include="Boot\ElfReader.cpp" /> <ClCompile Include="Boot\ElfReader.cpp" />
<ClCompile Include="Config\Config.cpp" /> <ClCompile Include="Config\Config.cpp" />
<ClCompile Include="Config\GraphicsSettings.cpp" /> <ClCompile Include="Config\GraphicsSettings.cpp" />
@ -308,7 +307,7 @@
<ClInclude Include="ARDecrypt.h" /> <ClInclude Include="ARDecrypt.h" />
<ClInclude Include="BootManager.h" /> <ClInclude Include="BootManager.h" />
<ClInclude Include="Boot\Boot.h" /> <ClInclude Include="Boot\Boot.h" />
<ClInclude Include="Boot\Boot_DOL.h" /> <ClInclude Include="Boot\DolReader.h" />
<ClInclude Include="Boot\ElfReader.h" /> <ClInclude Include="Boot\ElfReader.h" />
<ClInclude Include="Boot\ElfTypes.h" /> <ClInclude Include="Boot\ElfTypes.h" />
<ClInclude Include="Config\Config.h" /> <ClInclude Include="Config\Config.h" />
@ -583,4 +582,4 @@
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets"> <ImportGroup Label="ExtensionTargets">
</ImportGroup> </ImportGroup>
</Project> </Project>

View File

@ -182,15 +182,12 @@
<ClCompile Include="Boot\Boot_BS2Emu.cpp"> <ClCompile Include="Boot\Boot_BS2Emu.cpp">
<Filter>Boot</Filter> <Filter>Boot</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Boot\Boot_DOL.cpp">
<Filter>Boot</Filter>
</ClCompile>
<ClCompile Include="Boot\Boot_ELF.cpp">
<Filter>Boot</Filter>
</ClCompile>
<ClCompile Include="Boot\Boot_WiiWAD.cpp"> <ClCompile Include="Boot\Boot_WiiWAD.cpp">
<Filter>Boot</Filter> <Filter>Boot</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Boot\DolReader.cpp">
<Filter>Boot</Filter>
</ClCompile>
<ClCompile Include="Boot\ElfReader.cpp"> <ClCompile Include="Boot\ElfReader.cpp">
<Filter>Boot</Filter> <Filter>Boot</Filter>
</ClCompile> </ClCompile>
@ -888,7 +885,7 @@
<ClInclude Include="Boot\Boot.h"> <ClInclude Include="Boot\Boot.h">
<Filter>Boot</Filter> <Filter>Boot</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Boot\Boot_DOL.h"> <ClInclude Include="Boot\DolReader.h">
<Filter>Boot</Filter> <Filter>Boot</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Boot\ElfReader.h"> <ClInclude Include="Boot\ElfReader.h">

View File

@ -18,7 +18,7 @@
#include "Common/ChunkFile.h" #include "Common/ChunkFile.h"
#include "Common/CommonTypes.h" #include "Common/CommonTypes.h"
#include "Common/Logging/Log.h" #include "Common/Logging/Log.h"
#include "Core/Boot/Boot_DOL.h" #include "Core/Boot/DolReader.h"
#include "Core/ConfigManager.h" #include "Core/ConfigManager.h"
#include "Core/Core.h" #include "Core/Core.h"
#include "Core/CoreTiming.h" #include "Core/CoreTiming.h"
@ -282,14 +282,15 @@ bool Kernel::BootstrapPPC(const DiscIO::NANDContentLoader& content_loader)
if (!content) if (!content)
return false; return false;
const auto dol_loader = std::make_unique<CDolLoader>(content->m_Data->Get()); const auto dol_loader = std::make_unique<DolReader>(content->m_Data->Get());
if (!dol_loader->IsValid()) if (!dol_loader->IsValid())
return false; return false;
if (!SetupMemory(m_title_id, MemorySetupType::Full)) if (!SetupMemory(m_title_id, MemorySetupType::Full))
return false; return false;
dol_loader->Load(); if (!dol_loader->LoadIntoMemory())
return false;
// NAND titles start with address translation off at 0x3400 (via the PPC bootstub) // NAND titles start with address translation off at 0x3400 (via the PPC bootstub)
// The state of other CPU registers (like the BAT registers) doesn't matter much // The state of other CPU registers (like the BAT registers) doesn't matter much

View File

@ -134,8 +134,7 @@ bool Load()
return false; return false;
} }
std::vector<u8> elf_bytes = mios.GetElf(); ElfReader elf{mios.GetElf()};
ElfReader elf{elf_bytes.data()};
if (!elf.LoadIntoMemory(true)) if (!elf.LoadIntoMemory(true))
{ {
PanicAlertT("Failed to load MIOS ELF into memory."); PanicAlertT("Failed to load MIOS ELF into memory.");