mirror of
https://github.com/hrydgard/ppsspp.git
synced 2024-11-23 05:19:56 +00:00
Loader: Support HI16/16 pairs, not just LO16.
Motorstorm: Arctic Edge US uses these pairs for some VFPU loads. Without relocating these, strange shadows show underneath vehicles. It appears as if actual firmware pairs with any non-HI16 relocation.
This commit is contained in:
parent
a9668bdb60
commit
b2b61d58d4
@ -154,26 +154,41 @@ bool ElfReader::LoadRelocations(const Elf32_Rel *rels, int numRelocs) {
|
||||
u16 hi = 0;
|
||||
bool found = false;
|
||||
for (int t = r + 1; t < numRelocs; t++) {
|
||||
if ((rels[t].r_info & 0xF) == R_MIPS_LO16) {
|
||||
u32 corrLoAddr = rels[t].r_offset + segmentVAddr[readwrite];
|
||||
// Should have matching index and segment info, according to llvm, which makes sense.
|
||||
if ((rels[t].r_info >> 8) != (rels[r].r_info >> 8)) {
|
||||
WARN_LOG_REPORT(LOADER, "ELF relocation HI16/LO16 with mismatching r_info lo=%08x, hi=%08x", rels[t].r_info, rels[r].r_info);
|
||||
}
|
||||
if (log) {
|
||||
DEBUG_LOG(LOADER, "Corresponding lo found at %08x", corrLoAddr);
|
||||
}
|
||||
if (Memory::IsValidAddress(corrLoAddr)) {
|
||||
s16 lo = (s16)relocOps[t];
|
||||
cur += lo;
|
||||
cur += relocateTo;
|
||||
addrToHiLo(cur, hi, lo);
|
||||
found = true;
|
||||
break;
|
||||
int t_type = rels[t].r_info & 0xF;
|
||||
if (t_type == R_MIPS_HI16)
|
||||
continue;
|
||||
|
||||
u32 corrLoAddr = rels[t].r_offset + segmentVAddr[readwrite];
|
||||
|
||||
// In MotorStorm: Arctic Edge (US), these are sometimes R_MIPS_16 (instead of LO16.)
|
||||
// It appears the PSP takes any relocation that is not a HI16.
|
||||
if (t_type != R_MIPS_LO16) {
|
||||
if (t_type != R_MIPS_16) {
|
||||
// Let's play it safe for now and skip. We've only seen this type.
|
||||
ERROR_LOG_REPORT(LOADER, "ELF relocation HI16/%d pair (instead of LO16) at %08x / %08x", t_type, addr, corrLoAddr);
|
||||
continue;
|
||||
} else {
|
||||
ERROR_LOG(LOADER, "Bad corrLoAddr %08x", corrLoAddr);
|
||||
WARN_LOG_REPORT(LOADER, "ELF relocation HI16/%d(16) pair (instead of LO16) at %08x / %08x", t_type, addr, corrLoAddr);
|
||||
}
|
||||
}
|
||||
|
||||
// Should have matching index and segment info, according to llvm, which makes sense.
|
||||
if ((rels[t].r_info >> 8) != (rels[r].r_info >> 8)) {
|
||||
WARN_LOG_REPORT(LOADER, "ELF relocation HI16/LO16 with mismatching r_info lo=%08x, hi=%08x", rels[t].r_info, rels[r].r_info);
|
||||
}
|
||||
if (log) {
|
||||
DEBUG_LOG(LOADER, "Corresponding lo found at %08x", corrLoAddr);
|
||||
}
|
||||
if (Memory::IsValidAddress(corrLoAddr)) {
|
||||
s16 lo = (s16)relocOps[t];
|
||||
cur += lo;
|
||||
cur += relocateTo;
|
||||
addrToHiLo(cur, hi, lo);
|
||||
found = true;
|
||||
break;
|
||||
} else {
|
||||
ERROR_LOG(LOADER, "Bad corrLoAddr %08x", corrLoAddr);
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
ERROR_LOG_REPORT(LOADER, "R_MIPS_HI16: could not find R_MIPS_LO16 (r=%d of %d, addr=%08x)", r, numRelocs, addr);
|
||||
|
Loading…
Reference in New Issue
Block a user