diff options
| author | Evan Cheng <evan.cheng@apple.com> | 2009-09-09 01:56:29 +0000 |
|---|---|---|
| committer | Evan Cheng <evan.cheng@apple.com> | 2009-09-09 01:56:29 +0000 |
| commit | 4029b855676d2dac7ca7898b07e169059949ca40 (patch) | |
| tree | a3ac030ad587412c6deb4fc98579fe8e5d6d69e7 | |
| parent | 9fa8345b6581c713497982fddb43664042077be4 (diff) | |
| download | bcm5719-llvm-4029b855676d2dac7ca7898b07e169059949ca40.tar.gz bcm5719-llvm-4029b855676d2dac7ca7898b07e169059949ca40.zip | |
Make sure to make stub region writable before emission, executable after emission.
llvm-svn: 81311
| -rw-r--r-- | llvm/lib/Target/ARM/ARMJITInfo.cpp | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/llvm/lib/Target/ARM/ARMJITInfo.cpp b/llvm/lib/Target/ARM/ARMJITInfo.cpp index 0456f33ea26..754fafe0287 100644 --- a/llvm/lib/Target/ARM/ARMJITInfo.cpp +++ b/llvm/lib/Target/ARM/ARMJITInfo.cpp @@ -140,6 +140,10 @@ ARMJITInfo::getLazyResolverFunction(JITCompilerFn F) { void *ARMJITInfo::emitGlobalValueIndirectSym(const GlobalValue *GV, void *Ptr, JITCodeEmitter &JCE) { JCE.startGVStub(GV, 4, 4); + intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); + if (!sys::Memory::setRangeWritable((void*)Addr, 4)) { + llvm_unreachable("ERROR: Unable to mark indirect symbol writable"); + } JCE.emitWordLE((intptr_t)Ptr); void *PtrAddr = JCE.finishGVStub(GV); addIndirectSymAddr(Ptr, (intptr_t)PtrAddr); @@ -167,18 +171,30 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn, } JCE.startGVStub(F, 16, 4); intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); + if (!sys::Memory::setRangeWritable((void*)Addr, 16)) { + llvm_unreachable("ERROR: Unable to mark stub writable"); + } JCE.emitWordLE(0xe59fc004); // ldr pc, [pc, #+4] JCE.emitWordLE(0xe08fc00c); // L_func$scv: add ip, pc, ip JCE.emitWordLE(0xe59cf000); // ldr pc, [ip] JCE.emitWordLE(LazyPtr - (Addr+4+8)); // func - (L_func$scv+8) sys::Memory::InvalidateInstructionCache((void*)Addr, 16); + if (!sys::Memory::setRangeExecutable((void*)Addr, 16)) { + llvm_unreachable("ERROR: Unable to mark stub executable"); + } } else { // The stub is 8-byte size and 4-aligned. JCE.startGVStub(F, 8, 4); intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); + if (!sys::Memory::setRangeWritable((void*)Addr, 8)) { + llvm_unreachable("ERROR: Unable to mark stub writable"); + } JCE.emitWordLE(0xe51ff004); // ldr pc, [pc, #-4] JCE.emitWordLE((intptr_t)Fn); // addr of function sys::Memory::InvalidateInstructionCache((void*)Addr, 8); + if (!sys::Memory::setRangeExecutable((void*)Addr, 8)) { + llvm_unreachable("ERROR: Unable to mark stub executable"); + } } } else { // The compilation callback will overwrite the first two words of this @@ -190,6 +206,9 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn, // The stub is 16-byte size and 4-byte aligned. JCE.startGVStub(F, 16, 4); intptr_t Addr = (intptr_t)JCE.getCurrentPCValue(); + if (!sys::Memory::setRangeWritable((void*)Addr, 16)) { + llvm_unreachable("ERROR: Unable to mark stub writable"); + } // Save LR so the callback can determine which stub called it. // The compilation callback is responsible for popping this prior // to returning. @@ -201,6 +220,9 @@ void *ARMJITInfo::emitFunctionStub(const Function* F, void *Fn, // The address of the compilation callback. JCE.emitWordLE((intptr_t)ARMCompilationCallback); sys::Memory::InvalidateInstructionCache((void*)Addr, 16); + if (!sys::Memory::setRangeExecutable((void*)Addr, 16)) { + llvm_unreachable("ERROR: Unable to mark stub executable"); + } } return JCE.finishGVStub(F); |

