GameList: Fix scanning of ELF files
This commit is contained in:
parent
9dec34c8c0
commit
145ad2db27
|
@ -11,6 +11,7 @@
|
||||||
#include "system.h"
|
#include "system.h"
|
||||||
|
|
||||||
#include "util/cd_image.h"
|
#include "util/cd_image.h"
|
||||||
|
#include "util/elf_file.h"
|
||||||
#include "util/http_downloader.h"
|
#include "util/http_downloader.h"
|
||||||
#include "util/image.h"
|
#include "util/image.h"
|
||||||
#include "util/ini_settings_interface.h"
|
#include "util/ini_settings_interface.h"
|
||||||
|
@ -199,6 +200,18 @@ bool GameList::GetExeListEntry(const std::string& path, GameList::Entry* entry)
|
||||||
// Who knows
|
// Who knows
|
||||||
entry->region = DiscRegion::Other;
|
entry->region = DiscRegion::Other;
|
||||||
}
|
}
|
||||||
|
else if (StringUtil::EndsWithNoCase(filename, ".elf"))
|
||||||
|
{
|
||||||
|
ELFFile::Elf32_Ehdr header;
|
||||||
|
if (std::fread(&header, sizeof(header), 1, fp.get()) != 1 || !ELFFile::IsValidElfHeader(header))
|
||||||
|
{
|
||||||
|
WARNING_LOG("{} is not a valid ELF.", path);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Who knows
|
||||||
|
entry->region = DiscRegion::Other;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
BIOS::PSEXEHeader header;
|
BIOS::PSEXEHeader header;
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
LOG_CHANNEL(FileLoader);
|
LOG_CHANNEL(FileLoader);
|
||||||
|
|
||||||
|
static constexpr const u8 EXPECTED_ELF_HEADER[4] = {'\177', 'E', 'L', 'F'};
|
||||||
static constexpr s64 MAX_ELF_FILE_SIZE = 32 * 1024 * 1024;
|
static constexpr s64 MAX_ELF_FILE_SIZE = 32 * 1024 * 1024;
|
||||||
|
|
||||||
ELFFile::ELFFile() = default;
|
ELFFile::ELFFile() = default;
|
||||||
|
@ -113,9 +114,8 @@ bool ELFFile::Open(DataArray data, Error* error)
|
||||||
{
|
{
|
||||||
m_data = std::move(data);
|
m_data = std::move(data);
|
||||||
|
|
||||||
static constexpr const u8 EXPECTED_HEADER[4] = {'\177', 'E', 'L', 'F'};
|
if (m_data.size() < sizeof(Elf32_Ehdr) ||
|
||||||
|
std::memcmp(m_data.data(), EXPECTED_ELF_HEADER, sizeof(EXPECTED_ELF_HEADER)) != 0)
|
||||||
if (m_data.size() < sizeof(Elf32_Ehdr) || std::memcmp(m_data.data(), EXPECTED_HEADER, sizeof(EXPECTED_HEADER)) != 0)
|
|
||||||
{
|
{
|
||||||
Error::SetStringView(error, "Invalid header.");
|
Error::SetStringView(error, "Invalid header.");
|
||||||
return false;
|
return false;
|
||||||
|
@ -202,3 +202,32 @@ bool ELFFile::LoadExecutableSections(const LoadExecutableSectionCallback& callba
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ELFFile::IsValidElfHeader(const std::span<const u8> data, Error* error /*= nullptr*/)
|
||||||
|
{
|
||||||
|
if (data.size() < sizeof(Elf32_Ehdr))
|
||||||
|
{
|
||||||
|
Error::SetStringView(error, "Invalid header.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsValidElfHeader(reinterpret_cast<const Elf32_Ehdr&>(*data.data()), error);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ELFFile::IsValidElfHeader(const Elf32_Ehdr& header, Error* error /* = nullptr */)
|
||||||
|
{
|
||||||
|
if (std::memcmp(header.e_ident, EXPECTED_ELF_HEADER, sizeof(EXPECTED_ELF_HEADER)) != 0)
|
||||||
|
{
|
||||||
|
Error::SetStringView(error, "Invalid header.");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.e_machine != EM_MIPS)
|
||||||
|
{
|
||||||
|
Error::SetStringFmt(error, "Unsupported machine type {}.", header.e_machine);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// probably fine
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
|
@ -94,6 +94,9 @@ public:
|
||||||
ELFFile();
|
ELFFile();
|
||||||
~ELFFile();
|
~ELFFile();
|
||||||
|
|
||||||
|
static bool IsValidElfHeader(const std::span<const u8> data, Error* error = nullptr);
|
||||||
|
static bool IsValidElfHeader(const Elf32_Ehdr& header, Error* error = nullptr);
|
||||||
|
|
||||||
const Elf32_Ehdr& GetELFHeader() const;
|
const Elf32_Ehdr& GetELFHeader() const;
|
||||||
u32 GetEntryPoint() const;
|
u32 GetEntryPoint() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue