From cc49fa3d7402ab063fbb0ee3bc7c55238de448d6 Mon Sep 17 00:00:00 2001 From: Amy Yu Date: Wed, 6 Jun 2018 14:42:16 -0700 Subject: [PATCH] Fix unwindInfo bug caused by missing alignmentPad, dump raw byes of unwindInfo and gcInfo --- src/tools/r2rdump/GCInfo.cs | 17 +++++++++++------ src/tools/r2rdump/NativeReader.cs | 5 ++--- src/tools/r2rdump/R2RDump.cs | 8 ++++++++ src/tools/r2rdump/UnwindInfo.cs | 4 +++- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/tools/r2rdump/GCInfo.cs b/src/tools/r2rdump/GCInfo.cs index c225fe4..8464e08 100644 --- a/src/tools/r2rdump/GCInfo.cs +++ b/src/tools/r2rdump/GCInfo.cs @@ -82,6 +82,7 @@ namespace R2RDump public IEnumerable SafePointOffsets { get; } public IEnumerable InterruptibleRanges { get; } public GcSlotTable SlotTable { get; } + public int Size { get; } public GcInfo(byte[] image, int offset, Machine machine, ushort majorVersion) { @@ -99,7 +100,7 @@ namespace R2RDump GcInfoHeaderFlags headerFlags; Version = ReadyToRunVersionToGcInfoVersion(majorVersion); int bitOffset = offset * 8; - int initOffset = bitOffset; + int startBitOffset = bitOffset; bool slimHeader = (NativeReader.ReadBits(image, 1, ref bitOffset) == 0); if (slimHeader) @@ -196,7 +197,7 @@ namespace R2RDump SizeOfStackOutgoingAndScratchArea = DenormalizeSizeOfStackArea(machine, NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.SIZE_OF_STACK_AREA_ENCBASE, ref bitOffset)); } - // PARTIALLY_intERRUPTIBLE_GC_SUPPORTED + // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED NumSafePoints = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_SAFE_POINTS_ENCBASE, ref bitOffset); if (slimHeader) @@ -208,15 +209,17 @@ namespace R2RDump NumInterruptibleRanges = NativeReader.DecodeVarLengthUnsigned(image, gcInfoTypes.NUM_INTERRUPTIBLE_RANGES_ENCBASE, ref bitOffset); } - // PARTIALLY_intERRUPTIBLE_GC_SUPPORTED + // PARTIALLY_INTERRUPTIBLE_GC_SUPPORTED SafePointOffsets = EnumerateSafePoints(image, ref bitOffset); uint numBitsPerOffset = CeilOfLog2(CodeLength); bitOffset += (int)(NumSafePoints * numBitsPerOffset); - InterruptibleRanges = EnumerateinterruptibleRanges(image, gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA1_ENCBASE, gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA2_ENCBASE, ref bitOffset); + InterruptibleRanges = EnumerateInterruptibleRanges(image, gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA1_ENCBASE, gcInfoTypes.INTERRUPTIBLE_RANGE_DELTA2_ENCBASE, ref bitOffset); SlotTable = new GcSlotTable(image, machine, gcInfoTypes, ref bitOffset); + + Size = (int)Math.Ceiling((bitOffset - startBitOffset) / 8.0); } public override string ToString() @@ -251,7 +254,7 @@ namespace R2RDump { sb.AppendLine($"{tab}{tab}{offset}"); } - sb.AppendLine($"{tab}SafePointOffsets:"); + sb.AppendLine($"{tab}InterruptibleRanges:"); foreach (InterruptibleRange range in InterruptibleRanges) { sb.AppendLine($"{tab}{tab}start:{range.StartOffset}, end:{range.StopOffset}"); @@ -318,6 +321,8 @@ namespace R2RDump private uint CeilOfLog2(int x) { + if (x == 0) + return 0; uint result = (uint)((x & (x - 1)) != 0 ? 1 : 0); while (x != 1) { @@ -339,7 +344,7 @@ namespace R2RDump return safePoints; } - private IEnumerable EnumerateinterruptibleRanges(byte[] image, int interruptibleRangeDelta1EncBase, int interruptibleRangeDelta2EncBase, ref int bitOffset) + private IEnumerable EnumerateInterruptibleRanges(byte[] image, int interruptibleRangeDelta1EncBase, int interruptibleRangeDelta2EncBase, ref int bitOffset) { List ranges = new List(); uint lastinterruptibleRangeStopOffset = 0; diff --git a/src/tools/r2rdump/NativeReader.cs b/src/tools/r2rdump/NativeReader.cs index bcd3d48..cfc9a68 100644 --- a/src/tools/r2rdump/NativeReader.cs +++ b/src/tools/r2rdump/NativeReader.cs @@ -107,7 +107,7 @@ namespace R2RDump int bits = bitOffset % BITS_PER_BYTE; int val = image[start] >> bits; bits += numBits; - while (bits > BITS_PER_BYTE) + if (bits > BITS_PER_BYTE) { start++; bits -= BITS_PER_BYTE; @@ -117,8 +117,7 @@ namespace R2RDump val ^= extraBits; } } - int mask = (1 << numBits) - 1; - val &= mask; + val &= (1 << numBits) - 1; bitOffset += numBits; return val; } diff --git a/src/tools/r2rdump/R2RDump.cs b/src/tools/r2rdump/R2RDump.cs index 06ae90f..cc43fbf 100644 --- a/src/tools/r2rdump/R2RDump.cs +++ b/src/tools/r2rdump/R2RDump.cs @@ -175,11 +175,19 @@ namespace R2RDump { _writer.WriteLine("UnwindInfo:"); _writer.Write(rtf.UnwindInfo); + if (_raw) + { + DumpBytes(r2r, rtf.UnwindRVA, (uint)rtf.UnwindInfo.Size); + } } if (_gc) { _writer.WriteLine("GcInfo:"); _writer.Write(rtf.GcInfo); + if (_raw) + { + DumpBytes(r2r, rtf.UnwindRVA + rtf.UnwindInfo.Size, (uint)rtf.GcInfo.Size); + } } _writer.WriteLine(); } diff --git a/src/tools/r2rdump/UnwindInfo.cs b/src/tools/r2rdump/UnwindInfo.cs index ae7952e..dd95756 100644 --- a/src/tools/r2rdump/UnwindInfo.cs +++ b/src/tools/r2rdump/UnwindInfo.cs @@ -88,7 +88,9 @@ namespace R2RDump PersonalityRoutineRVA = NativeReader.ReadUInt32(image, ref offset); - Size = _offsetofUnwindCode + CountOfUnwindCodes * _sizeofUnwindCode + sizeof(uint); + Size = _offsetofUnwindCode + CountOfUnwindCodes * _sizeofUnwindCode; + int alignmentPad = ((Size + sizeof(int) - 1) & ~(sizeof(int) - 1)) - Size; + Size += (alignmentPad + sizeof(uint)); } public override string ToString() -- 2.7.4