/// <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 partial) { int runtimeFunctionId = EntryPointRuntimeFunctionId; int runtimeFunctionSize = _readyToRunReader.CalculateRuntimeFunctionSize(); int runtimeFunctionOffset = _readyToRunReader.CompositeReader.GetOffset(_readyToRunReader.ReadyToRunHeader.Sections[ReadyToRunSectionType.RuntimeFunctions].RelativeVirtualAddress); int curOffset = runtimeFunctionOffset + runtimeFunctionId * runtimeFunctionSize; int codeOffset = 0; for (int i = 0; i < RuntimeFunctionCount; i++) { int startRva = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset); if (_readyToRunReader.Machine == Machine.ArmThumb2) { // The low bit of this address is set since the function contains thumb code. // Clear this bit in order to get the "real" RVA of the start of the function. startRva = (int)(startRva & ~1); } 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.I386) { unwindInfo = new x86.UnwindInfo(_readyToRunReader.Image, unwindOffset); } else if (_readyToRunReader.Machine == Machine.Amd64) { unwindInfo = new Amd64.UnwindInfo(_readyToRunReader.Image, unwindOffset); } else if (_readyToRunReader.Machine == Machine.ArmThumb2) { unwindInfo = new Arm.UnwindInfo(_readyToRunReader.Image, unwindOffset); } else if (_readyToRunReader.Machine == Machine.Arm64) { unwindInfo = new Arm64.UnwindInfo(_readyToRunReader.Image, unwindOffset); } if (i == 0 && unwindInfo != null) { if (_readyToRunReader.Machine == Machine.I386) { GcInfoRva = unwindRva; } else { GcInfoRva = unwindRva + unwindInfo.Size; } } if (partial) { return; } RuntimeFunction rtf = new RuntimeFunction( _readyToRunReader, runtimeFunctionId, startRva, endRva, unwindRva, codeOffset, this, unwindInfo); _runtimeFunctions.Add(rtf); runtimeFunctionId++; codeOffset += rtf.Size; } _size = codeOffset; }
/// <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; Func <BaseGcInfo> gcInfo = default(Func <BaseGcInfo>); int codeOffset = 0; for (int i = 0; i < RuntimeFunctionCount; i++) { int startRva = NativeReader.ReadInt32(_readyToRunReader.Image, ref curOffset); if (_readyToRunReader.Machine == Machine.ArmThumb2) { // The low bit of this address is set since the function contains thumb code. // Clear this bit in order to get the "real" RVA of the start of the function. startRva = (int)(startRva & ~1); } 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 Func <BaseGcInfo>(() => 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 Func <BaseGcInfo>(() => 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 Func <BaseGcInfo>(() => new Amd64.GcInfo(_readyToRunReader.Image, unwindOffset + unwindInfo.Size, _readyToRunReader.Machine, _readyToRunReader.ReadyToRunHeader.MajorVersion)); // Arm and Arm64 use the same GcInfo format as x6 } } else if (_readyToRunReader.Machine == Machine.Arm64) { unwindInfo = new Arm64.UnwindInfo(_readyToRunReader.Image, unwindOffset); if (i == 0) { gcInfo = new Func <BaseGcInfo>(() => 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; } }
/// <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; } }