1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 19:12:56 +02:00

[ppc64] Patch in TOC restore code after all external function calls

When resolving a function call to an external routine, the dynamic
loader must patch the "nop" after the branch instruction to a load
that restores the TOC register.

Current code does that, but only with the *first* instance of a call
to any particular external routine, i.e. at the point where it also
allocates the call stub.  With subsequent calls to the same routine,
current code neglects to patch in the TOC restore code.  This is a
bug, and leads to corrupt TOC pointers in those cases.

Fixed by patching in restore code every time.

llvm-svn: 203580
This commit is contained in:
Ulrich Weigand 2014-03-11 15:26:27 +00:00
parent 878ae23fa9
commit 9cd3db6897

View File

@ -1206,11 +1206,11 @@ void RuntimeDyldELF::processRelocationRef(unsigned SectionID,
resolveRelocation(Section, Offset,
(uint64_t)Section.Address + Section.StubOffset,
RelType, 0);
if (SymType == SymbolRef::ST_Unknown)
// Restore the TOC for external calls
writeInt32BE(Target+4, 0xE8410028); // ld r2,40(r1)
Section.StubOffset += getMaxStubSize();
}
if (SymType == SymbolRef::ST_Unknown)
// Restore the TOC for external calls
writeInt32BE(Target+4, 0xE8410028); // ld r2,40(r1)
}
} else {
RelocationEntry RE(SectionID, Offset, RelType, Value.Addend);