Ignore:
Timestamp:
Jun 1, 2009, 6:20:35 PM (16 years ago)
Author:
[email protected]
Message:

2009-06-01 Gavin Barraclough <[email protected]>

Reviewed by Sam "WX" Weinig.

Allow the JIT to operate without relying on use of RWX memory, on platforms where this is supported.

This patch adds a switch to Platform.h (ENABLE_ASSEMBLER_WX_EXCLUSIVE) which enables this mode of operation.
When this flag is set, all executable memory will be allocated RX, and switched to RW only whilst being
modified. Upon completion of code generation the protection is switched back to RX to allow execution.

Further optimization will be required before it is desirable to enable this mode of operation by default;
enabling this presently incurs a 5%-10% regression.

(Submitting disabled - no performance impact).

  • assembler/AbstractMacroAssembler.h: (JSC::AbstractMacroAssembler::CodeLocationInstruction::repatchLoadToLEA): (JSC::AbstractMacroAssembler::CodeLocationLabel::fromFunctionPointer): (JSC::AbstractMacroAssembler::CodeLocationJump::relink): (JSC::AbstractMacroAssembler::CodeLocationCall::relink): (JSC::AbstractMacroAssembler::CodeLocationNearCall::relink): (JSC::AbstractMacroAssembler::CodeLocationDataLabel32::repatch): (JSC::AbstractMacroAssembler::CodeLocationDataLabelPtr::repatch): (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkCallerToTrampoline): (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkCallerToFunction): (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkNearCallerToTrampoline): (JSC::AbstractMacroAssembler::ProcessorReturnAddress::relinkNearCallerToFunction): (JSC::AbstractMacroAssembler::PatchBuffer::PatchBuffer): (JSC::AbstractMacroAssembler::PatchBuffer::~PatchBuffer): (JSC::AbstractMacroAssembler::PatchBuffer::link): (JSC::AbstractMacroAssembler::PatchBuffer::patch): (JSC::AbstractMacroAssembler::PatchBuffer::performFinalization): (JSC::::CodeLocationCommon::nearCallAtOffset): (JSC::::CodeLocationCall::CodeLocationCall): (JSC::::CodeLocationNearCall::CodeLocationNearCall):
  • assembler/AssemblerBuffer.h: (JSC::AssemblerBuffer::executableCopy):
  • assembler/X86Assembler.h: (JSC::CAN_SIGN_EXTEND_U32_64): (JSC::X86Assembler::linkJump): (JSC::X86Assembler::linkCall): (JSC::X86Assembler::patchPointer): (JSC::X86Assembler::relinkJump): (JSC::X86Assembler::relinkCall): (JSC::X86Assembler::repatchInt32): (JSC::X86Assembler::repatchPointer): (JSC::X86Assembler::repatchLoadToLEA): (JSC::X86Assembler::patchInt32): (JSC::X86Assembler::patchRel32):
  • jit/ExecutableAllocator.h: (JSC::ExecutableAllocator::): (JSC::ExecutableAllocator::makeWritable): (JSC::ExecutableAllocator::makeExecutable):
  • jit/ExecutableAllocatorFixedVMPool.cpp: (JSC::FixedVMPoolAllocator::FixedVMPoolAllocator):
  • jit/ExecutableAllocatorPosix.cpp: (JSC::ExecutablePool::systemAlloc): (JSC::ExecutablePool::systemRelease): (JSC::ExecutableAllocator::reprotectRegion):
  • jit/ExecutableAllocatorWin.cpp:
  • jit/JITPropertyAccess.cpp: (JSC::JIT::patchGetByIdSelf): (JSC::JIT::patchPutByIdReplace):
  • wtf/Platform.h:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/assembler/X86Assembler.h

    r43781 r44341  
    4242inline bool CAN_SIGN_EXTEND_32_64(intptr_t value) { return value == (intptr_t)(int32_t)value; }
    4343inline bool CAN_SIGN_EXTEND_U32_64(intptr_t value) { return value == (intptr_t)(uint32_t)value; }
    44 
    45 #define REPTACH_OFFSET_CALL_R11 3
    4644#endif
    4745
     
    13561354
    13571355    // Linking & patching:
     1356    //
     1357    // 'link' and 'patch' methods are for use on unprotected code - such as the code
     1358    // within the AssemblerBuffer, and code being patched by the patch buffer.  Once
     1359    // code has been finalized it is (platform support permitting) within a non-
     1360    // writable region of memory; to modify the code in an execute-only execuable
     1361    // pool the 'repatch' and 'relink' methods should be used.
    13581362
    13591363    void linkJump(JmpSrc from, JmpDst to)
    13601364    {
     1365        ASSERT(from.m_offset != -1);
    13611366        ASSERT(to.m_offset != -1);
     1367
     1368        char* code = reinterpret_cast<char*>(m_formatter.data());
     1369        patchRel32(code + from.m_offset, code + to.m_offset);
     1370    }
     1371   
     1372    void linkCall(JmpSrc from, JmpDst to)
     1373    {
    13621374        ASSERT(from.m_offset != -1);
     1375        ASSERT(to.m_offset != -1);
    13631376       
    1364         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
     1377        char* code = reinterpret_cast<char*>(m_formatter.data());
     1378        patchRel32(code + from.m_offset, code + to.m_offset);
    13651379    }
    13661380   
     
    13681382    {
    13691383        ASSERT(from.m_offset != -1);
    1370         ptrdiff_t linkOffset = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
    1371         ASSERT(linkOffset == static_cast<int>(linkOffset));
    1372         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = linkOffset;
    1373     }
    1374 
    1375     static void patchLoadToLEA(intptr_t where)
    1376     {
    1377         unsigned char* ptr = reinterpret_cast<unsigned char*>(where);
    1378         ptr[0] = static_cast<unsigned char>(OP_LEA);
    1379     }
    1380    
    1381     static void patchJump(intptr_t where, void* destination)
    1382     {
    1383         intptr_t offset = reinterpret_cast<intptr_t>(destination) - where;
    1384         ASSERT(offset == static_cast<int32_t>(offset));
    1385         reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset);
    1386     }
    1387    
    1388 #if PLATFORM(X86_64)
    1389     // FIXME: transition these functions out of here - the assembler
    1390     // shouldn't know that that this is mov/call pair using r11. :-/
    1391     static void patchMacroAssemblerCall(intptr_t where, void* destination)
    1392     {
    1393         patchAddress(reinterpret_cast<void*>(where - REPTACH_OFFSET_CALL_R11), JmpDst(0), destination);
    1394     }
    1395 #else
    1396     static void patchMacroAssemblerCall(intptr_t where, void* destination)
    1397     {
    1398         intptr_t offset = reinterpret_cast<intptr_t>(destination) - where;
    1399         ASSERT(offset == static_cast<int32_t>(offset));
    1400         reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset);
    1401     }
    1402 #endif
    1403 
    1404     void linkCall(JmpSrc from, JmpDst to)
    1405     {
    1406         ASSERT(to.m_offset != -1);
     1384
     1385        patchRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
     1386    }
     1387
     1388    static void linkCall(void* code, JmpSrc from, void* to)
     1389    {
    14071390        ASSERT(from.m_offset != -1);
    1408        
    1409         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(m_formatter.data()) + from.m_offset)[-1] = to.m_offset - from.m_offset;
    1410     }
    1411    
    1412     static void linkCall(void* code, JmpSrc from, void* to)
    1413     {
    1414         ASSERT(from.m_offset != -1);
    1415         ptrdiff_t linkOffset = reinterpret_cast<ptrdiff_t>(to) - (reinterpret_cast<ptrdiff_t>(code) + from.m_offset);
    1416         ASSERT(linkOffset == static_cast<int>(linkOffset));
    1417         reinterpret_cast<int*>(reinterpret_cast<ptrdiff_t>(code) + from.m_offset)[-1] = linkOffset;
    1418     }
    1419 
    1420     static void patchCall(intptr_t where, void* destination)
    1421     {
    1422         intptr_t offset = reinterpret_cast<intptr_t>(destination) - where;
    1423         ASSERT(offset == static_cast<int32_t>(offset));
    1424         reinterpret_cast<int32_t*>(where)[-1] = static_cast<int32_t>(offset);
    1425     }
    1426 
    1427     static void patchAddress(void* code, JmpDst position, void* value)
    1428     {
    1429         ASSERT(position.m_offset != -1);
    1430        
    1431         reinterpret_cast<void**>(reinterpret_cast<ptrdiff_t>(code) + position.m_offset)[-1] = value;
     1391
     1392        patchRel32(reinterpret_cast<char*>(code) + from.m_offset, to);
     1393    }
     1394
     1395    static void patchPointer(void* where, void* value)
     1396    {
     1397        reinterpret_cast<void**>(where)[-1] = value;
     1398    }
     1399
     1400    static void patchPointer(void* code, JmpDst where, void* value)
     1401    {
     1402        ASSERT(where.m_offset != -1);
     1403
     1404        patchPointer(reinterpret_cast<char*>(code) + where.m_offset, value);
     1405    }
     1406
     1407    static void relinkJump(void* from, void* to)
     1408    {
     1409        ExecutableAllocator::MakeWritable unprotect(reinterpret_cast<char*>(from) - sizeof(int32_t), sizeof(int32_t));
     1410        patchRel32(from, to);
     1411    }
     1412   
     1413    static void relinkCall(void* from, void* to)
     1414    {
     1415        ExecutableAllocator::MakeWritable unprotect(reinterpret_cast<char*>(from) - sizeof(int32_t), sizeof(int32_t));
     1416        patchRel32(from, to);
     1417    }
     1418
     1419    static void repatchInt32(void* where, int32_t value)
     1420    {
     1421        ExecutableAllocator::MakeWritable unprotect(reinterpret_cast<char*>(where) - sizeof(int32_t), sizeof(int32_t));
     1422        patchInt32(where, value);
     1423    }
     1424
     1425    static void repatchPointer(void* where, void* value)
     1426    {
     1427        ExecutableAllocator::MakeWritable unprotect(reinterpret_cast<char*>(where) - sizeof(void*), sizeof(void*));
     1428        patchPointer(where, value);
     1429    }
     1430
     1431    static void repatchLoadToLEA(void* where)
     1432    {
     1433        ExecutableAllocator::MakeWritable unprotect(where, 1);
     1434        *reinterpret_cast<unsigned char*>(where) = static_cast<unsigned char>(OP_LEA);
    14321435    }
    14331436   
     
    14631466    {
    14641467        return dst.m_offset - src.m_offset;
    1465     }
    1466    
    1467     static void patchImmediate(intptr_t where, int32_t value)
    1468     {
    1469         reinterpret_cast<int32_t*>(where)[-1] = value;
    1470     }
    1471    
    1472     static void patchPointer(intptr_t where, intptr_t value)
    1473     {
    1474         reinterpret_cast<intptr_t*>(where)[-1] = value;
    14751468    }
    14761469   
     
    14831476
    14841477private:
     1478
     1479    static void patchInt32(void* where, int32_t value)
     1480    {
     1481        reinterpret_cast<int32_t*>(where)[-1] = value;
     1482    }
     1483
     1484    static void patchRel32(void* from, void* to)
     1485    {
     1486        intptr_t offset = reinterpret_cast<intptr_t>(to) - reinterpret_cast<intptr_t>(from);
     1487        ASSERT(offset == static_cast<int32_t>(offset));
     1488
     1489        patchInt32(from, offset);
     1490    }
    14851491
    14861492    class X86InstructionFormatter {
Note: See TracChangeset for help on using the changeset viewer.