⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 271143 in webkit


Ignore:
Timestamp:
Jan 4, 2021, 11:19:24 PM (6 years ago)
Author:
Tadeu Zagallo
Message:

Validate every instruction in AssemblerBuffer
https://bugs.webkit.org/show_bug.cgi?id=218104
<rdar://problem/69433094>

Reviewed by Saam Barati.

  • assembler/AssemblerBuffer.cpp:

(JSC::threadSpecificAssemblerHashes):

  • assembler/AssemblerBuffer.h:

(JSC::AssemblerBuffer::AssemblerBuffer):
(JSC::AssemblerBuffer::~AssemblerBuffer):
(JSC::AssemblerBuffer::releaseAssemblerData):
(JSC::AssemblerBuffer::releaseAssemblerHashes):
(JSC::AssemblerBuffer::putIntegralUnchecked):
(JSC::AssemblerBuffer::grow):
(JSC::AssemblerBuffer::outOfLineGrow):
(JSC::ARM64EHash::update): Deleted.
(JSC::ARM64EHash::finalHash const): Deleted.
(): Deleted.
(JSC::AssemblerBuffer::hash const): Deleted.

  • assembler/LinkBuffer.cpp:

(JSC::LinkBuffer::copyCompactAndLinkCode):

  • assembler/LinkBuffer.h:
Location:
trunk/Source/JavaScriptCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r271141 r271143  
     12020-11-17  Tadeu Zagallo  <tzagallo@apple.com>
     2
     3        Validate every instruction in AssemblerBuffer
     4        https://bugs.webkit.org/show_bug.cgi?id=218104
     5        <rdar://problem/69433094>
     6
     7        Reviewed by Saam Barati.
     8
     9        * assembler/AssemblerBuffer.cpp:
     10        (JSC::threadSpecificAssemblerHashes):
     11        * assembler/AssemblerBuffer.h:
     12        (JSC::AssemblerBuffer::AssemblerBuffer):
     13        (JSC::AssemblerBuffer::~AssemblerBuffer):
     14        (JSC::AssemblerBuffer::releaseAssemblerData):
     15        (JSC::AssemblerBuffer::releaseAssemblerHashes):
     16        (JSC::AssemblerBuffer::putIntegralUnchecked):
     17        (JSC::AssemblerBuffer::grow):
     18        (JSC::AssemblerBuffer::outOfLineGrow):
     19        (JSC::ARM64EHash::update): Deleted.
     20        (JSC::ARM64EHash::finalHash const): Deleted.
     21        (): Deleted.
     22        (JSC::AssemblerBuffer::hash const): Deleted.
     23        * assembler/LinkBuffer.cpp:
     24        (JSC::LinkBuffer::copyCompactAndLinkCode):
     25        * assembler/LinkBuffer.h:
     26
    1272021-01-04  Dmitry Bezhetskov  <dbezhetskov@igalia.com>
    228
  • trunk/Source/JavaScriptCore/assembler/AssemblerBuffer.cpp

    r262402 r271143  
    4646}
    4747
     48#if CPU(ARM64E)
     49static ThreadSpecificAssemblerData* threadSpecificAssemblerHashesPtr;
     50ThreadSpecificAssemblerData& threadSpecificAssemblerHashes()
     51{
     52    static std::once_flag flag;
     53    std::call_once(
     54        flag,
     55        [] () {
     56            threadSpecificAssemblerHashesPtr = new ThreadSpecificAssemblerData();
     57        });
     58    return *threadSpecificAssemblerHashesPtr;
     59}
     60#endif // CPU(ARM64E)
     61
    4862#endif // ENABLE(ASSEMBLER)
    4963
  • trunk/Source/JavaScriptCore/assembler/AssemblerBuffer.h

    r268247 r271143  
    4747
    4848    JS_EXPORT_PRIVATE ThreadSpecificAssemblerData& threadSpecificAssemblerData();
     49    JS_EXPORT_PRIVATE ThreadSpecificAssemblerData& threadSpecificAssemblerHashes();
    4950
    5051    class LinkBuffer;
     
    184185    class ARM64EHash {
    185186    public:
    186         ARM64EHash() = default;
    187         ALWAYS_INLINE void update(uint32_t value)
     187        ARM64EHash(uint32_t initialHash)
     188            : m_hash(initialHash)
     189        {
     190        }
     191
     192        ALWAYS_INLINE uint32_t update(uint32_t value)
    188193        {
    189194            uint64_t input = value ^ m_hash;
    190             uint64_t a = static_cast<uint32_t>(tagInt<static_cast<PtrTag>(0)>(input) >> 39);
    191             uint64_t b = tagInt<static_cast<PtrTag>(0xb7e151628aed2a6a)>(input) >> 23;
     195            uint64_t a = static_cast<uint32_t>(tagInt(input, static_cast<PtrTag>(0)) >> 39);
     196            uint64_t b = tagInt(input, static_cast<PtrTag>(0xb7e151628aed2a6a)) >> 23;
    192197            m_hash = a ^ b;
    193         }
    194         uint32_t finalHash() const
    195         {
    196             uint64_t hash = m_hash;
    197             uint64_t a = static_cast<uint32_t>(tagInt<static_cast<PtrTag>(0xbf7158809cf4f3c7)>(hash) >> 39);
    198             uint64_t b = tagInt<static_cast<PtrTag>(0x62e7160f38b4da56)>(hash) >> 23;
    199             return static_cast<uint32_t>(a ^ b);
    200         }
     198            return m_hash;
     199        }
     200
    201201    private:
    202         uint32_t m_hash { 0 };
     202        uint32_t m_hash;
    203203    };
    204204#endif
     
    209209            : m_storage()
    210210            , m_index(0)
    211         {
    212             auto& threadSpecific = threadSpecificAssemblerData();
    213             m_storage.takeBufferIfLarger(WTFMove(*threadSpecific));
     211#if CPU(ARM64E)
     212            , m_hash(static_cast<uint32_t>(bitwise_cast<uint64_t>(this)))
     213            , m_hashes()
     214#endif
     215        {
     216            auto& threadSpecificData = threadSpecificAssemblerData();
     217            m_storage.takeBufferIfLarger(WTFMove(*threadSpecificData));
     218#if CPU(ARM64E)
     219            auto& threadSpecificHashes = threadSpecificAssemblerHashes();
     220            m_hashes.takeBufferIfLarger(WTFMove(*threadSpecificHashes));
     221            ASSERT(m_storage.capacity() == m_hashes.capacity());
     222#endif
    214223        }
    215224
    216225        ~AssemblerBuffer()
    217226        {
    218             auto& threadSpecific = threadSpecificAssemblerData();
    219             threadSpecific->takeBufferIfLarger(WTFMove(m_storage));
     227#if CPU(ARM64E)
     228            ASSERT(m_storage.capacity() == m_hashes.capacity());
     229            auto& threadSpecificHashes = threadSpecificAssemblerHashes();
     230            threadSpecificHashes->takeBufferIfLarger(WTFMove(m_hashes));
     231#endif
     232            auto& threadSpecificData = threadSpecificAssemblerData();
     233            threadSpecificData->takeBufferIfLarger(WTFMove(m_storage));
    220234        }
    221235
     
    270284        unsigned debugOffset() { return m_index; }
    271285
    272         AssemblerData&& releaseAssemblerData() { return WTFMove(m_storage); }
     286        AssemblerData&& releaseAssemblerData()
     287        {
     288            return WTFMove(m_storage);
     289        }
     290
     291#if CPU(ARM64E)
     292        AssemblerData&& releaseAssemblerHashes()
     293        {
     294            return WTFMove(m_hashes);
     295        }
     296#endif
    273297
    274298        // LocalWriter is a trick to keep the storage buffer and the index
     
    324348#endif // !CPU(ARM64)
    325349
    326 #if CPU(ARM64E)
    327         ARM64EHash hash() const { return m_hash; }
    328 #endif
    329 
    330350#if !CPU(ARM64) // If we were to define this on arm64e, we'd need a way to update the hash as we write directly into the buffer.
    331351        void* data() const { return m_storage.buffer(); }
    332352#endif
    333 
    334353
    335354    protected:
     
    349368            static_assert(sizeof(value) == 4, "");
    350369#if CPU(ARM64E)
    351             m_hash.update(value);
     370            uint32_t hash = m_hash.update(value);
     371            WTF::unalignedStore<uint32_t>(m_hashes.buffer() + m_index, hash);
    352372#endif
    353373#endif
     
    361381        {
    362382            m_storage.grow(extraCapacity);
     383#if CPU(ARM64E)
     384            m_hashes.grow(extraCapacity);
     385#endif
    363386        }
    364387
     
    366389        {
    367390            m_storage.grow();
     391#if CPU(ARM64E)
     392            m_hashes.grow();
     393#endif
    368394        }
    369395
     
    377403#if CPU(ARM64E)
    378404        ARM64EHash m_hash;
     405        AssemblerData m_hashes;
    379406#endif
    380407    };
  • trunk/Source/JavaScriptCore/assembler/LinkBuffer.cpp

    r270377 r271143  
    121121#if ENABLE(BRANCH_COMPACTION)
    122122
    123 #if CPU(ARM64E)
    124 #define ENABLE_VERIFY_JIT_HASH 1
    125 #else
    126 #define ENABLE_VERIFY_JIT_HASH 0
    127 #endif
    128 
    129123class BranchCompactionLinkBuffer;
    130124
     
    241235    Vector<LinkRecord, 0, UnsafeVectorOverflow>& jumpsToLink = macroAssembler.jumpsToLink();
    242236    m_assemblerStorage = macroAssembler.m_assembler.buffer().releaseAssemblerData();
    243     uint8_t* inData = reinterpret_cast<uint8_t*>(m_assemblerStorage.buffer());
     237    uint8_t* inData = bitwise_cast<uint8_t*>(m_assemblerStorage.buffer());
     238#if CPU(ARM64E)
     239    ARM64EHash verifyUncompactedHash { static_cast<uint32_t>(bitwise_cast<uint64_t>(&macroAssembler.m_assembler.buffer())) };
     240    m_assemblerHashesStorage = macroAssembler.m_assembler.buffer().releaseAssemblerHashes();
     241    uint32_t* inHashes = bitwise_cast<uint32_t*>(m_assemblerHashesStorage.buffer());
     242#endif
    244243
    245244    uint8_t* codeOutData = m_code.dataLocation<uint8_t*>();
    246 
    247 #if ENABLE(VERIFY_JIT_HASH)
    248     const uint32_t expectedFinalHash = macroAssembler.m_assembler.buffer().hash().finalHash();
    249     ARM64EHash verifyUncompactedHash;
    250 #endif
    251245
    252246    BranchCompactionLinkBuffer outBuffer(m_size, useFastJITPermissions() ? codeOutData : 0);
     
    261255    int writePtr = 0;
    262256    unsigned jumpCount = jumpsToLink.size();
     257
     258    auto read = [&](const InstructionType* ptr) -> InstructionType {
     259        InstructionType value = *ptr;
     260#if CPU(ARM64E)
     261        uint32_t hash = verifyUncompactedHash.update(value);
     262        unsigned index = (bitwise_cast<uint8_t*>(ptr) - inData) / 4;
     263        RELEASE_ASSERT(inHashes[index] == hash);
     264#endif
     265        return value;
     266    };
    263267
    264268    if (useFastJITPermissions())
     
    279283            ASSERT(!(writePtr % 2));
    280284            while (copySource != copyEnd) {
    281                 InstructionType insn = *copySource++;
    282 #if ENABLE(VERIFY_JIT_HASH)
    283                 static_assert(sizeof(InstructionType) == 4, "");
    284                 verifyUncompactedHash.update(insn);
    285 #endif
     285                InstructionType insn = read(copySource++);
    286286                *copyDst++ = insn;
    287287            }
     
    337337
    338338        for (size_t i = 0; i < bytes; i += sizeof(InstructionType)) {
    339             InstructionType insn = *src++;
    340 #if ENABLE(VERIFY_JIT_HASH)
    341             verifyUncompactedHash.update(insn);
    342 #endif
     339            InstructionType insn = read(src++);
    343340            *dst++ = insn;
    344341        }
    345342    }
    346343
    347 #if ENABLE(VERIFY_JIT_HASH)
    348     if (verifyUncompactedHash.finalHash() != expectedFinalHash) {
    349 #ifndef NDEBUG
    350         dataLogLn("Hashes don't match: ", RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(verifyUncompactedHash.finalHash()))), " ", RawPointer(bitwise_cast<void*>(static_cast<uintptr_t>(expectedFinalHash))));
    351         dataLogLn("Crashing!");
    352 #endif
    353         CRASH();
    354     }
    355 #endif
    356344
    357345    recordLinkOffsets(m_assemblerStorage, readPtr, initialSize, readPtr - writePtr);
  • trunk/Source/JavaScriptCore/assembler/LinkBuffer.h

    r269016 r271143  
    361361#if ENABLE(BRANCH_COMPACTION)
    362362    AssemblerData m_assemblerStorage;
     363#if CPU(ARM64E)
     364    AssemblerData m_assemblerHashesStorage;
     365#endif
    363366    bool m_shouldPerformBranchCompaction { true };
    364367#endif
Note: See TracChangeset for help on using the changeset viewer.