[Scummvm-cvs-logs] SF.net SVN: scummvm:[52750] scummvm/branches/gsoc2010-plugins/backends/ plugins/elf/mips-loader.cpp
Bluddy at users.sourceforge.net
Bluddy at users.sourceforge.net
Thu Sep 16 19:37:54 CEST 2010
Revision: 52750
http://scummvm.svn.sourceforge.net/scummvm/?rev=52750&view=rev
Author: Bluddy
Date: 2010-09-16 17:37:54 +0000 (Thu, 16 Sep 2010)
Log Message:
-----------
PLUGINS: fixed issue with R_MIPS_32 relocations
Caused crash in some games. The problem was referring to the right segment. R_MIPS_32 relocations can be found in the Shorts segment, but still need to refer to the main segment if the symbol is found there.
Modified Paths:
--------------
scummvm/branches/gsoc2010-plugins/backends/plugins/elf/mips-loader.cpp
Modified: scummvm/branches/gsoc2010-plugins/backends/plugins/elf/mips-loader.cpp
===================================================================
--- scummvm/branches/gsoc2010-plugins/backends/plugins/elf/mips-loader.cpp 2010-09-16 17:37:31 UTC (rev 52749)
+++ scummvm/branches/gsoc2010-plugins/backends/plugins/elf/mips-loader.cpp 2010-09-16 17:37:54 UTC (rev 52750)
@@ -54,6 +54,8 @@
debug(2, "elfloader: Loaded relocation table. %d entries. base address=%p", cnt, relSegment);
+ Elf32_Addr adjustedMainSegment = Elf32_Addr(_segment) - _segmentVMA; // adjust for VMA offset
+
bool seenHi16 = false; // For treating HI/LO16 commands
int32 firstHi16 = -1; // Mark the point of the first hi16 seen
Elf32_Addr ahl = 0; // Calculated addend
@@ -121,7 +123,7 @@
if (lo16InShorts)
relocation = ahl + _shortsSegment->getOffset(); // Add in the short segment offset
else // It's in the regular segment
- relocation = ahl + Elf32_Addr(relSegment); // Add in the new offset for the segment
+ relocation = ahl + adjustedMainSegment; // Add in the new offset for the segment
if (firstHi16 >= 0) { // We haven't treated the HI16s yet so do it now
for (uint32 j = firstHi16; j < i; j++) {
@@ -159,7 +161,7 @@
if (sym->st_shndx < SHN_LOPROC) { // Only relocate for main segment
a = *target & 0x03ffffff; // Get 26 bits' worth of the addend
a = (a << 6) >> 6; // Sign extend a
- relocation = ((a << 2) + Elf32_Addr(relSegment)) >> 2; // a already points to the target. Subtract our offset
+ relocation = ((a << 2) + adjustedMainSegment) >> 2; // a already points to the target. Add our offset
*target &= 0xfc000000; // Clean lower 26 target bits
*target |= (relocation & 0x03ffffff);
@@ -201,7 +203,7 @@
if (ShortsMan.inGeneralSegment((char *)sym->st_value)) // Check if we're in the shorts segment
relocation = a + _shortsSegment->getOffset(); // Shift by shorts offset
else // We're in the main section
- relocation = a + Elf32_Addr(relSegment); // Shift by main offset
+ relocation = a + adjustedMainSegment; // Shift by main offset
*target = relocation;
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
More information about the Scummvm-git-logs
mailing list