Repository: dotnet/runtime
File: src/coreclr/tools/Common/JitInterface/CorInfoImpl.cs (C#)

Code before:
                    {
                        offset = offset.AlignUp((int)chunk.alignment);
                        chunk.block = rwDataBlock + offset;
                        chunk.blockRW = chunk.block;
                        offset += (int)chunk.size;
                    }
                }

                Debug.Assert(offset <= rwDataSize);
            }

            if (_numFrameInfos > 0)
            {
                _frameInfos = new FrameInfo[_numFrameInfos];
            }

#if READYTORUN
            if (_numColdFrameInfos > 0)
            {
                _coldFrameInfos = new FrameInfo[_numColdFrameInfos];
            }
#endif
        }

        private void reserveUnwindInfo(bool isFunclet, bool isColdCode, uint unwindSize)
        {
#if READYTORUN
            if (isColdCode)
            {
                _numColdFrameInfos++;
            }
            else
#endif
            {
                _numFrameInfos++;
            }
        }

        private void allocUnwindInfo(byte* pHotCode, byte* pColdCode, uint startOffset, uint endOffset, uint unwindSize, byte* pUnwindBlock, CorJitFuncKind funcKind)
        {
            Debug.Assert(FrameInfoFlags.Filter == (FrameInfoFlags)CorJitFuncKind.CORJIT_FUNC_FILTER);
            Debug.Assert(FrameInfoFlags.Handler == (FrameInfoFlags)CorJitFuncKind.CORJIT_FUNC_HANDLER);

            FrameInfoFlags flags = (FrameInfoFlags)funcKind;

            if (funcKind == CorJitFuncKind.CORJIT_FUNC_ROOT)
            {
                if (this.MethodBeingCompiled.IsUnmanagedCallersOnly)
                    flags |= FrameInfoFlags.ReversePInvoke;
            }


Review comment (bug):
The read-only data block assignment loop (lines 3898-3909, not shown in diff) should skip chunks that need to be placed in the read-write section. Without this check, chunks with CORJIT_ALLOCMEM_HAS_POINTERS_TO_CODE on non-Windows platforms will be incorrectly assigned to both the RO and RW data blocks, leading to corruption. The loop should add a check similar to line 3927: if ChunkNeedsReadWriteSection returns true, the chunk should be skipped in the RO data loop.

Code after:
            }

            if (rwDataSize != 0)
            {
                _rwData = new byte[rwDataSize];
                _rwDataBlob = new MethodReadWriteDataNode(MethodBeingCompiled);
                byte* rwDataBlock = (byte*)GetPin(_rwData);
                int offset = 0;

                foreach (ref AllocMemChunk chunk in chunks)
                {
                    if ((chunk.flags & (CorJitAllocMemFlag.CORJIT_ALLOCMEM_HOT_CODE | CorJitAllocMemFlag.CORJIT_ALLOCMEM_COLD_CODE)) != 0)
                    {
                        continue;
                    }
                    if (ChunkNeedsReadWriteSection(chunk))
                    {
                        offset = offset.AlignUp((int)chunk.alignment);
                        chunk.block = rwDataBlock + offset;
                        chunk.blockRW = chunk.block;
                        offset += (int)chunk.size;
                    }
                }

                Debug.Assert(offset <= rwDataSize);
            }

            if (_numFrameInfos > 0)
            {
                _frameInfos = new FrameInfo[_numFrameInfos];
            }

#if READYTORUN
            if (_numColdFrameInfos > 0)
            {
                _coldFrameInfos = new FrameInfo[_numColdFrameInfos];
            }
#endif
        }

        private void reserveUnwindInfo(bool isFunclet, bool isColdCode, uint unwindSize)
        {
#if READYTORUN
            if (isColdCode)
            {
                _numColdFrameInfos++;
            }
            else
#endif
            {
                _numFrameInfos++;