예제 #1
0
 private void EnsureInitialized()
 {
     if (_gcInfo == null)
     {
         ParseRuntimeFunctions(true);
         if (GcInfoRva != 0)
         {
             int gcInfoOffset = _readyToRunReader.CompositeReader.GetOffset(GcInfoRva);
             if (_readyToRunReader.Machine == Machine.I386)
             {
                 _gcInfo = new x86.GcInfo(_readyToRunReader.Image, gcInfoOffset, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion);
             }
             else
             {
                 // Arm and Arm64 use the same GcInfo format as Amd64
                 _gcInfo = new Amd64.GcInfo(_readyToRunReader.Image, gcInfoOffset, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion);
             }
         }
     }
     if (_pgoInfo == null)
     {
         _pgoInfo = _readyToRunReader.GetPgoInfoByKey(PgoInfoKey.FromReadyToRunMethod(this));
         if (_pgoInfo == null)
         {
             _pgoInfo = PgoInfo.EmptySingleton;
         }
     }
 }
예제 #2
0
 private void EnsureInitialized()
 {
     if (_gcInfo == null && GetGcInfo != null)
     {
         _gcInfo = GetGcInfo();
     }
 }
예제 #3
0
 private void EnsureInitialized()
 {
     if (_gcInfo == null && GcInfoRva != 0)
     {
         int gcInfoOffset = _readyToRunReader.CompositeReader.GetOffset(GcInfoRva);
         if (_readyToRunReader.Machine == Machine.I386)
         {
             _gcInfo = new x86.GcInfo(_readyToRunReader.Image, gcInfoOffset, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion);
         }
         else
         {
             // Arm and Arm64 use the same GcInfo format as Amd64
             _gcInfo = new Amd64.GcInfo(_readyToRunReader.Image, gcInfoOffset, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion);
         }
     }
 }
예제 #4
0
        public RuntimeFunction(
            int id,
            int startRva,
            int endRva,
            int unwindRva,
            int codeOffset,
            R2RMethod method,
            BaseUnwindInfo unwindInfo,
            BaseGcInfo gcInfo,
            EHInfo ehInfo,
            DebugInfo debugInfo)
        {
            Id           = id;
            StartAddress = startRva;
            UnwindRVA    = unwindRva;
            Method       = method;
            UnwindInfo   = unwindInfo;
            DebugInfo    = debugInfo;

            if (endRva != -1)
            {
                Size = endRva - startRva;
            }
            else if (unwindInfo is x86.UnwindInfo)
            {
                Size = (int)((x86.UnwindInfo)unwindInfo).FunctionLength;
            }
            else if (unwindInfo is Arm.UnwindInfo)
            {
                Size = (int)((Arm.UnwindInfo)unwindInfo).FunctionLength;
            }
            else if (unwindInfo is Arm64.UnwindInfo)
            {
                Size = (int)((Arm64.UnwindInfo)unwindInfo).FunctionLength;
            }
            else if (gcInfo != null)
            {
                Size = gcInfo.CodeLength;
            }
            else
            {
                Size = -1;
            }
            CodeOffset    = codeOffset;
            method.GcInfo = gcInfo;
            EHInfo        = ehInfo;
        }
예제 #5
0
        public RuntimeFunction(
            ReadyToRunReader readyToRunReader,
            int id,
            int startRva,
            int endRva,
            int unwindRva,
            int codeOffset,
            ReadyToRunMethod method,
            BaseUnwindInfo unwindInfo,
            BaseGcInfo gcInfo)
        {
            _readyToRunReader = readyToRunReader;
            Id           = id;
            StartAddress = startRva;
            UnwindRVA    = unwindRva;
            Method       = method;
            UnwindInfo   = unwindInfo;

            if (endRva != -1)
            {
                Size = endRva - startRva;
            }
            else if (unwindInfo is x86.UnwindInfo)
            {
                Size = (int)((x86.UnwindInfo)unwindInfo).FunctionLength;
            }
            else if (unwindInfo is Arm.UnwindInfo)
            {
                Size = (int)((Arm.UnwindInfo)unwindInfo).FunctionLength;
            }
            else if (unwindInfo is Arm64.UnwindInfo)
            {
                Size = (int)((Arm64.UnwindInfo)unwindInfo).FunctionLength;
            }
            else if (gcInfo != null)
            {
                Size = gcInfo.CodeLength;
            }
            else
            {
                Size = -1;
            }
            CodeOffset    = codeOffset;
            method.GcInfo = gcInfo;
        }
예제 #6
0
        /// <summary>
        /// Get the RVAs of the runtime functions for each method
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/zap/zapcode.cpp">ZapUnwindInfo::Save</a>
        /// </summary>
        private void ParseRuntimeFunctions(bool[] isEntryPoint, int runtimeFunctionOffset, int runtimeFunctionSize)
        {
            int curOffset = 0;

            foreach (R2RMethod method in R2RMethods)
            {
                int runtimeFunctionId = method.EntryPointRuntimeFunctionId;
                if (runtimeFunctionId == -1)
                {
                    continue;
                }
                curOffset = runtimeFunctionOffset + runtimeFunctionId * runtimeFunctionSize;
                BaseGcInfo gcInfo     = null;
                int        codeOffset = 0;
                do
                {
                    int startRva = NativeReader.ReadInt32(Image, ref curOffset);
                    int endRva   = -1;
                    if (Machine == Machine.Amd64)
                    {
                        endRva = NativeReader.ReadInt32(Image, ref curOffset);
                    }
                    int unwindRva    = NativeReader.ReadInt32(Image, ref curOffset);
                    int unwindOffset = GetOffset(unwindRva);

                    BaseUnwindInfo unwindInfo = null;
                    if (Machine == Machine.Amd64)
                    {
                        unwindInfo = new Amd64.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, R2RHeader.MajorVersion);
                        }
                    }
                    else if (Machine == Machine.I386)
                    {
                        unwindInfo = new x86.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new x86.GcInfo(Image, unwindOffset, Machine, R2RHeader.MajorVersion);
                        }
                    }
                    else if (Machine == Machine.ArmThumb2)
                    {
                        unwindInfo = new Arm.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, R2RHeader.MajorVersion); // Arm and Arm64 use the same GcInfo format as x64
                        }
                    }
                    else if (Machine == Machine.Arm64)
                    {
                        unwindInfo = new Arm64.UnwindInfo(Image, unwindOffset);
                        if (isEntryPoint[runtimeFunctionId])
                        {
                            gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, R2RHeader.MajorVersion);
                        }
                    }

                    EHInfo         ehInfo = null;
                    EHInfoLocation ehInfoLocation;
                    if (EHLookupTable != null && EHLookupTable.RuntimeFunctionToEHInfoMap.TryGetValue(startRva, out ehInfoLocation))
                    {
                        ehInfo = new EHInfo(this, ehInfoLocation.EHInfoRVA, startRva, GetOffset(ehInfoLocation.EHInfoRVA), ehInfoLocation.ClauseCount);
                    }

                    DebugInfo debugInfo;
                    _runtimeFunctionToDebugInfo.TryGetValue(runtimeFunctionId, out debugInfo);

                    RuntimeFunction rtf = new RuntimeFunction(
                        runtimeFunctionId,
                        startRva,
                        endRva,
                        unwindRva,
                        codeOffset,
                        method,
                        unwindInfo,
                        gcInfo,
                        ehInfo,
                        debugInfo);

                    method.RuntimeFunctions.Add(rtf);
                    runtimeFunctionId++;
                    codeOffset += rtf.Size;
                }while (runtimeFunctionId < isEntryPoint.Length && !isEntryPoint[runtimeFunctionId]);
            }
        }
예제 #7
0
        private void ParseRuntimeFunctionsForMethod(bool[] isEntryPoint, int curOffset, ReadyToRunMethod method, int runtimeFunctionId)
        {
            BaseGcInfo gcInfo     = null;
            int        codeOffset = 0;

            do
            {
                int startRva = NativeReader.ReadInt32(Image, ref curOffset);
                int endRva   = -1;
                if (Machine == Machine.Amd64)
                {
                    endRva = NativeReader.ReadInt32(Image, ref curOffset);
                }
                int unwindRva    = NativeReader.ReadInt32(Image, ref curOffset);
                int unwindOffset = GetOffset(unwindRva);

                BaseUnwindInfo unwindInfo = null;
                if (Machine == Machine.Amd64)
                {
                    unwindInfo = new Amd64.UnwindInfo(Image, unwindOffset);
                    if (isEntryPoint[runtimeFunctionId])
                    {
                        gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, ReadyToRunHeader.MajorVersion);
                    }
                }
                else if (Machine == Machine.I386)
                {
                    unwindInfo = new x86.UnwindInfo(Image, unwindOffset);
                    if (isEntryPoint[runtimeFunctionId])
                    {
                        gcInfo = new x86.GcInfo(Image, unwindOffset, Machine, ReadyToRunHeader.MajorVersion);
                    }
                }
                else if (Machine == Machine.ArmThumb2)
                {
                    unwindInfo = new Arm.UnwindInfo(Image, unwindOffset);
                    if (isEntryPoint[runtimeFunctionId])
                    {
                        gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, ReadyToRunHeader.MajorVersion); // Arm and Arm64 use the same GcInfo format as x64
                    }
                }
                else if (Machine == Machine.Arm64)
                {
                    unwindInfo = new Arm64.UnwindInfo(Image, unwindOffset);
                    if (isEntryPoint[runtimeFunctionId])
                    {
                        gcInfo = new Amd64.GcInfo(Image, unwindOffset + unwindInfo.Size, Machine, ReadyToRunHeader.MajorVersion);
                    }
                }

                RuntimeFunction rtf = new RuntimeFunction(
                    this,
                    runtimeFunctionId,
                    startRva,
                    endRva,
                    unwindRva,
                    codeOffset,
                    method,
                    unwindInfo,
                    gcInfo);

                method.RuntimeFunctions.Add(rtf);
                runtimeFunctionId++;
                codeOffset += rtf.Size;
            }while (runtimeFunctionId < isEntryPoint.Length && !isEntryPoint[runtimeFunctionId]);
        }
예제 #8
0
        /// <summary>
        /// Get the RVAs of the runtime functions for each method
        /// based on <a href="https://github.com/dotnet/coreclr/blob/master/src/zap/zapcode.cpp">ZapUnwindInfo::Save</a>
        /// </summary>
        private void ParseRuntimeFunctions()
        {
            int        runtimeFunctionId     = EntryPointRuntimeFunctionId;
            int        runtimeFunctionSize   = _readyToRunReader.CalculateRuntimeFunctionSize();
            int        runtimeFunctionOffset = _readyToRunReader.CompositeReader.GetOffset(_readyToRunReader.ReadyToRunHeader.Sections[ReadyToRunSectionType.RuntimeFunctions].RelativeVirtualAddress);
            int        curOffset             = runtimeFunctionOffset + runtimeFunctionId * runtimeFunctionSize;
            BaseGcInfo gcInfo     = null;
            int        codeOffset = 0;

            for (int i = 0; i < RuntimeFunctionCount; i++)
            {
                int startRva = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset);
                int endRva   = -1;
                if (_readyToRunReader.Machine == Machine.Amd64)
                {
                    endRva = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset);
                }
                int unwindRva    = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset);
                int unwindOffset = _readyToRunReader.CompositeReader.GetOffset(unwindRva);

                BaseUnwindInfo unwindInfo = null;
                if (_readyToRunReader.Machine == Machine.Amd64)
                {
                    unwindInfo = new Amd64.UnwindInfo(_readyToRunReader.Image, unwindOffset);
                    if (i == 0)
                    {
                        gcInfo = new Amd64.GcInfo(_readyToRunReader.Image, unwindOffset + unwindInfo.Size, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion);
                    }
                }
                else if (_readyToRunReader.Machine == Machine.I386)
                {
                    unwindInfo = new x86.UnwindInfo(_readyToRunReader.Image, unwindOffset);
                    if (i == 0)
                    {
                        gcInfo = new x86.GcInfo(_readyToRunReader.Image, unwindOffset, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion);
                    }
                }
                else if (_readyToRunReader.Machine == Machine.ArmThumb2)
                {
                    unwindInfo = new Arm.UnwindInfo(_readyToRunReader.Image, unwindOffset);
                    if (i == 0)
                    {
                        gcInfo = new Amd64.GcInfo(_readyToRunReader.Image, unwindOffset + unwindInfo.Size, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion); // Arm and Arm64 use the same GcInfo format as x64
                    }
                }
                else if (_readyToRunReader.Machine == Machine.Arm64)
                {
                    unwindInfo = new Arm64.UnwindInfo(_readyToRunReader.Image, unwindOffset);
                    if (i == 0)
                    {
                        gcInfo = new Amd64.GcInfo(_readyToRunReader.Image, unwindOffset + unwindInfo.Size, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion);
                    }
                }

                RuntimeFunction rtf = new RuntimeFunction(
                    _readyToRunReader,
                    runtimeFunctionId,
                    startRva,
                    endRva,
                    unwindRva,
                    codeOffset,
                    this,
                    unwindInfo,
                    gcInfo);

                _runtimeFunctions.Add(rtf);
                runtimeFunctionId++;
                codeOffset += rtf.Size;
            }
        }