summaryrefslogtreecommitdiff
path: root/lib/ExecutionEngine/RuntimeDyld
diff options
context:
space:
mode:
authorUlrich Weigand <ulrich.weigand@de.ibm.com>2014-03-11 15:26:27 +0000
committerUlrich Weigand <ulrich.weigand@de.ibm.com>2014-03-11 15:26:27 +0000
commit4f45d04c6f65c3456713db05d6e38b8f57c616d7 (patch)
treeebbf4e6eb78afbd012b811f10128af5f7ab87523 /lib/ExecutionEngine/RuntimeDyld
parent90d0ed297fabb373a29222b18f127dc853557bc8 (diff)
downloadllvm-4f45d04c6f65c3456713db05d6e38b8f57c616d7.tar.gz
llvm-4f45d04c6f65c3456713db05d6e38b8f57c616d7.tar.bz2
llvm-4f45d04c6f65c3456713db05d6e38b8f57c616d7.tar.xz
[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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@203580 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/ExecutionEngine/RuntimeDyld')
-rw-r--r--lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp6
1 files changed, 3 insertions, 3 deletions
diff --git a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp b/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
index 0a593e60f2..96b4e127aa 100644
--- a/lib/ExecutionEngine/RuntimeDyld/RuntimeDyldELF.cpp
+++ b/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);