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:
parent
22992ae41e
commit
065261dbad
|
@ -21,7 +21,8 @@
|
|||
#include "Common/MsgHandler.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/Core.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)});
|
||||
}
|
||||
|
||||
if (extension == ".elf" || extension == ".dol")
|
||||
{
|
||||
return std::make_unique<BootParameters>(
|
||||
Executable{path, extension == ".elf" ? Executable::Type::ELF : Executable::Type::DOL});
|
||||
}
|
||||
if (extension == ".elf")
|
||||
return std::make_unique<BootParameters>(Executable{path, std::make_unique<ElfReader>(path)});
|
||||
|
||||
if (extension == ".dol")
|
||||
return std::make_unique<BootParameters>(Executable{path, std::make_unique<DolReader>(path)});
|
||||
|
||||
if (extension == ".dff")
|
||||
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());
|
||||
|
||||
// TODO: needs more cleanup.
|
||||
if (executable.type == BootParameters::Executable::Type::DOL)
|
||||
{
|
||||
CDolLoader dolLoader(executable.path);
|
||||
if (!dolLoader.IsValid())
|
||||
return false;
|
||||
if (!executable.reader->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())
|
||||
{
|
||||
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());
|
||||
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();
|
||||
}
|
||||
|
||||
if (executable.type == BootParameters::Executable::Type::ELF)
|
||||
else
|
||||
{
|
||||
const DiscIO::Volume* 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();
|
||||
volume = SetDefaultDisc();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -495,3 +479,16 @@ bool CBoot::BootUp(std::unique_ptr<BootParameters> boot)
|
|||
HLE::PatchFixedFunctions();
|
||||
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;
|
||||
|
|
|
@ -5,9 +5,11 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdlib>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "DiscIO/Enums.h"
|
||||
|
@ -21,6 +23,8 @@ struct RegionSetting
|
|||
const std::string code;
|
||||
};
|
||||
|
||||
class BootExecutableReader;
|
||||
|
||||
struct BootParameters
|
||||
{
|
||||
struct Disc
|
||||
|
@ -31,13 +35,8 @@ struct BootParameters
|
|||
|
||||
struct Executable
|
||||
{
|
||||
enum class Type
|
||||
{
|
||||
DOL,
|
||||
ELF,
|
||||
};
|
||||
std::string path;
|
||||
Type type;
|
||||
std::unique_ptr<BootExecutableReader> reader;
|
||||
};
|
||||
|
||||
struct NAND
|
||||
|
@ -72,7 +71,6 @@ class CBoot
|
|||
{
|
||||
public:
|
||||
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
|
||||
// local user directory, then in the shared user directory.
|
||||
|
@ -97,7 +95,6 @@ private:
|
|||
|
||||
static void UpdateDebugger_MapLoaded();
|
||||
|
||||
static bool Boot_ELF(const std::string& filename);
|
||||
static bool Boot_WiiWAD(const std::string& filename);
|
||||
|
||||
static void SetupMSR();
|
||||
|
@ -111,3 +108,20 @@ private:
|
|||
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -2,7 +2,7 @@
|
|||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "Core/Boot/Boot_DOL.h"
|
||||
#include "Core/Boot/DolReader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
@ -12,29 +12,19 @@
|
|||
#include "Common/Swap.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);
|
||||
}
|
||||
|
||||
CDolLoader::CDolLoader(const std::string& filename)
|
||||
DolReader::DolReader(const std::string& filename) : BootExecutableReader(filename)
|
||||
{
|
||||
const u64 size = File::GetSize(filename);
|
||||
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);
|
||||
m_is_valid = Initialize(m_bytes);
|
||||
}
|
||||
|
||||
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))
|
||||
return false;
|
||||
|
@ -97,17 +87,30 @@ bool CDolLoader::Initialize(const std::vector<u8>& buffer)
|
|||
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
|
||||
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(),
|
||||
m_text_sections[i].size());
|
||||
}
|
||||
|
||||
// load all data sections
|
||||
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(),
|
||||
m_data_sections[i].size());
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
|
@ -8,20 +8,20 @@
|
|||
#include <vector>
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/Boot/Boot.h"
|
||||
|
||||
class CDolLoader
|
||||
class DolReader final : public BootExecutableReader
|
||||
{
|
||||
public:
|
||||
CDolLoader(const std::string& filename);
|
||||
CDolLoader(const std::vector<u8>& buffer);
|
||||
~CDolLoader();
|
||||
|
||||
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;
|
||||
DolReader(const std::string& filename);
|
||||
DolReader(const std::vector<u8>& buffer);
|
||||
~DolReader();
|
||||
|
||||
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:
|
||||
enum
|
||||
{
|
|
@ -66,7 +66,17 @@ static void byteswapSection(Elf32_Shdr& sec)
|
|||
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;
|
||||
base32 = (u32*)ptr;
|
||||
|
@ -86,6 +96,8 @@ ElfReader::ElfReader(void* ptr)
|
|||
byteswapSection(sections[i]);
|
||||
}
|
||||
entryPoint = header->e_entry;
|
||||
|
||||
bRelocate = (header->e_type != ET_EXEC);
|
||||
}
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
// Should we relocate?
|
||||
bRelocate = (header->e_type != ET_EXEC);
|
||||
|
||||
if (bRelocate)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
bool ElfReader::LoadSymbols()
|
||||
bool ElfReader::LoadSymbols() const
|
||||
{
|
||||
bool hasSymbols = false;
|
||||
SectionID sec = GetSectionByName(".symtab");
|
||||
|
@ -205,3 +214,31 @@ bool ElfReader::LoadSymbols()
|
|||
g_symbolDB.Index();
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Core/Boot/Boot.h"
|
||||
#include "Core/Boot/ElfTypes.h"
|
||||
|
||||
enum KnownElfTypes
|
||||
|
@ -17,31 +18,23 @@ enum KnownElfTypes
|
|||
|
||||
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:
|
||||
explicit ElfReader(void* ptr);
|
||||
ElfReader(const std::string& filename);
|
||||
ElfReader(const std::vector<u8>& buffer);
|
||||
~ElfReader() {}
|
||||
u32 Read32(int off) const { return base32[off >> 2]; }
|
||||
// Quick accessors
|
||||
ElfType GetType() const { return (ElfType)(header->e_type); }
|
||||
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); }
|
||||
bool LoadIntoMemory(bool only_in_mem1 = false);
|
||||
bool LoadSymbols();
|
||||
bool LoadIntoMemory(bool only_in_mem1 = false) const override;
|
||||
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 GetNumSections() const { return (int)(header->e_shnum); }
|
||||
|
@ -57,11 +50,24 @@ public:
|
|||
return nullptr;
|
||||
}
|
||||
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; }
|
||||
u32 GetSectionAddr(SectionID section) const { return sectionAddrs[section]; }
|
||||
int GetSectionSize(SectionID section) const { return sections[section].sh_size; }
|
||||
SectionID GetSectionByName(const char* name, int firstSection = 0) const; //-1 for not found
|
||||
|
||||
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;
|
||||
};
|
||||
|
|
|
@ -21,9 +21,8 @@ set(SRCS
|
|||
WiiRoot.cpp
|
||||
Boot/Boot_BS2Emu.cpp
|
||||
Boot/Boot.cpp
|
||||
Boot/Boot_DOL.cpp
|
||||
Boot/Boot_ELF.cpp
|
||||
Boot/Boot_WiiWAD.cpp
|
||||
Boot/DolReader.cpp
|
||||
Boot/ElfReader.cpp
|
||||
Config/Config.cpp
|
||||
Config/GraphicsSettings.cpp
|
||||
|
|
|
@ -23,7 +23,6 @@
|
|||
|
||||
#include "Core/Analytics.h"
|
||||
#include "Core/Boot/Boot.h"
|
||||
#include "Core/Boot/Boot_DOL.h"
|
||||
#include "Core/Config/Config.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
|
@ -896,10 +895,10 @@ struct SetGameMetadata
|
|||
|
||||
bool operator()(const BootParameters::Executable& executable) const
|
||||
{
|
||||
if (executable.type == BootParameters::Executable::Type::DOL)
|
||||
config->bWii = CDolLoader{executable.path}.IsWii();
|
||||
if (executable.type == BootParameters::Executable::Type::ELF)
|
||||
config->bWii = CBoot::IsElfWii(executable.path);
|
||||
if (!executable.reader->IsValid())
|
||||
return false;
|
||||
|
||||
config->bWii = executable.reader->IsWii();
|
||||
|
||||
// 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,
|
||||
|
|
|
@ -52,9 +52,8 @@
|
|||
<ClCompile Include="BootManager.cpp" />
|
||||
<ClCompile Include="Boot\Boot.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\DolReader.cpp" />
|
||||
<ClCompile Include="Boot\ElfReader.cpp" />
|
||||
<ClCompile Include="Config\Config.cpp" />
|
||||
<ClCompile Include="Config\GraphicsSettings.cpp" />
|
||||
|
@ -308,7 +307,7 @@
|
|||
<ClInclude Include="ARDecrypt.h" />
|
||||
<ClInclude Include="BootManager.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\ElfTypes.h" />
|
||||
<ClInclude Include="Config\Config.h" />
|
||||
|
@ -583,4 +582,4 @@
|
|||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
@ -182,15 +182,12 @@
|
|||
<ClCompile Include="Boot\Boot_BS2Emu.cpp">
|
||||
<Filter>Boot</Filter>
|
||||
</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">
|
||||
<Filter>Boot</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Boot\DolReader.cpp">
|
||||
<Filter>Boot</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Boot\ElfReader.cpp">
|
||||
<Filter>Boot</Filter>
|
||||
</ClCompile>
|
||||
|
@ -888,7 +885,7 @@
|
|||
<ClInclude Include="Boot\Boot.h">
|
||||
<Filter>Boot</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Boot\Boot_DOL.h">
|
||||
<ClInclude Include="Boot\DolReader.h">
|
||||
<Filter>Boot</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Boot\ElfReader.h">
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
#include "Common/ChunkFile.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
#include "Core/Boot/Boot_DOL.h"
|
||||
#include "Core/Boot/DolReader.h"
|
||||
#include "Core/ConfigManager.h"
|
||||
#include "Core/Core.h"
|
||||
#include "Core/CoreTiming.h"
|
||||
|
@ -282,14 +282,15 @@ bool Kernel::BootstrapPPC(const DiscIO::NANDContentLoader& content_loader)
|
|||
if (!content)
|
||||
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())
|
||||
return false;
|
||||
|
||||
if (!SetupMemory(m_title_id, MemorySetupType::Full))
|
||||
return false;
|
||||
|
||||
dol_loader->Load();
|
||||
if (!dol_loader->LoadIntoMemory())
|
||||
return false;
|
||||
|
||||
// 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
|
||||
|
|
|
@ -134,8 +134,7 @@ bool Load()
|
|||
return false;
|
||||
}
|
||||
|
||||
std::vector<u8> elf_bytes = mios.GetElf();
|
||||
ElfReader elf{elf_bytes.data()};
|
||||
ElfReader elf{mios.GetElf()};
|
||||
if (!elf.LoadIntoMemory(true))
|
||||
{
|
||||
PanicAlertT("Failed to load MIOS ELF into memory.");
|
||||
|
|
Loading…
Reference in New Issue