Implement a better heuristic to detect whether an ELF is for GC or Wii
This commit is contained in:
parent
04bde406d3
commit
f567782b47
|
@ -34,12 +34,35 @@ bool CBoot::IsElfWii(const char *filename)
|
||||||
File::IOFile f(filename, "rb");
|
File::IOFile f(filename, "rb");
|
||||||
f.ReadBytes(mem, (size_t)filesize);
|
f.ReadBytes(mem, (size_t)filesize);
|
||||||
}
|
}
|
||||||
|
|
||||||
ElfReader reader(mem);
|
|
||||||
// TODO: Find a more reliable way to distinguish.
|
|
||||||
bool isWii = reader.GetEntryPoint() >= 0x80004000;
|
|
||||||
delete[] mem;
|
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
u32 HID4_pattern = 0x7c13fba6;
|
||||||
|
u32 HID4_mask = 0xfc1fffff;
|
||||||
|
ElfReader reader(mem);
|
||||||
|
bool isWii = false;
|
||||||
|
|
||||||
|
for (int i = 0; i < reader.GetNumSections(); ++i)
|
||||||
|
{
|
||||||
|
if (reader.IsCodeSection(i))
|
||||||
|
{
|
||||||
|
for (unsigned int j = 0; j < reader.GetSectionSize(i) / sizeof (u32); ++j)
|
||||||
|
{
|
||||||
|
u32 word = Common::swap32(((u32*)reader.GetSectionDataPtr(i))[j]);
|
||||||
|
if ((word & HID4_mask) == HID4_pattern)
|
||||||
|
{
|
||||||
|
isWii = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delete[] mem;
|
||||||
return isWii;
|
return isWii;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,6 @@ public:
|
||||||
bool LoadInto(u32 vaddr);
|
bool LoadInto(u32 vaddr);
|
||||||
bool LoadSymbols();
|
bool LoadSymbols();
|
||||||
|
|
||||||
private:
|
|
||||||
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); }
|
||||||
const u8 *GetPtr(int offset) const { return (u8*)base + offset; }
|
const u8 *GetPtr(int offset) const { return (u8*)base + offset; }
|
||||||
|
@ -73,6 +72,10 @@ private:
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
bool IsCodeSection(int section) const
|
||||||
|
{
|
||||||
|
return sections[section].sh_type == SHT_PROGBITS;
|
||||||
|
}
|
||||||
const u8 *GetSegmentPtr(int segment)
|
const u8 *GetSegmentPtr(int segment)
|
||||||
{
|
{
|
||||||
return GetPtr(segments[segment].p_offset);
|
return GetPtr(segments[segment].p_offset);
|
||||||
|
|
Loading…
Reference in New Issue