Implement a better heuristic to detect whether an ELF is for GC or Wii

This commit is contained in:
Pierre Bourdon 2012-05-12 01:48:56 +02:00
parent 04bde406d3
commit f567782b47
2 changed files with 32 additions and 6 deletions

View File

@ -34,12 +34,35 @@ bool CBoot::IsElfWii(const char *filename)
File::IOFile f(filename, "rb");
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;
}

View File

@ -59,7 +59,6 @@ public:
bool LoadInto(u32 vaddr);
bool LoadSymbols();
private:
int GetNumSegments() const { return (int)(header->e_phnum); }
int GetNumSections() const { return (int)(header->e_shnum); }
const u8 *GetPtr(int offset) const { return (u8*)base + offset; }
@ -73,6 +72,10 @@ private:
else
return 0;
}
bool IsCodeSection(int section) const
{
return sections[section].sh_type == SHT_PROGBITS;
}
const u8 *GetSegmentPtr(int segment)
{
return GetPtr(segments[segment].p_offset);