From fa84ac9d8a36fb92fbaeafe76d05e475b22c9c82 Mon Sep 17 00:00:00 2001 From: Ulrich Weigand Date: Tue, 11 Mar 2014 15:26:27 +0000 Subject: [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 --- llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'llvm/lib/ExecutionEngine/RuntimeDyld') diff --git a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp index 0a593e60f2d..96b4e127aa6 100644 --- a/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp +++ b/llvm/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp @@ -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); -- cgit v1.2.3