public DebugInfo(byte[] image, int offset, Machine machine) { _machine = machine; // Get the id of the runtime function from the NativeArray uint lookback = 0; uint debugInfoOffset = NativeReader.DecodeUnsigned(image, (uint)offset, ref lookback); if (lookback != 0) { System.Diagnostics.Debug.Assert(0 < lookback && lookback < offset); debugInfoOffset = (uint)offset - lookback; } NibbleReader reader = new NibbleReader(image, (int)debugInfoOffset); uint boundsByteCount = reader.ReadUInt(); uint variablesByteCount = reader.ReadUInt(); int boundsOffset = reader.GetNextByteOffset(); int variablesOffset = (int)(boundsOffset + boundsByteCount); if (boundsByteCount > 0) { ParseBounds(image, boundsOffset); } if (variablesByteCount > 0) { ParseNativeVarInfo(image, variablesOffset); } }
public override string ToString() { StringBuilder sb = new StringBuilder(); int iiOffset = _startOffset; int sizeOfInlineIndex = NativeReader.ReadInt32(_r2r.Image, ref iiOffset); int inlineIndexEndOffset = iiOffset + sizeOfInlineIndex; while (iiOffset < inlineIndexEndOffset) { int inlineeRid = NativeReader.ReadInt32(_r2r.Image, ref iiOffset); int inlinersOffset = NativeReader.ReadInt32(_r2r.Image, ref iiOffset); sb.AppendLine($"Inliners for inlinee {RidToMethodDef(inlineeRid):X8}:"); var inlinersReader = new NibbleReader(_r2r.Image, inlineIndexEndOffset + inlinersOffset); uint sameModuleCount = inlinersReader.ReadUInt(); int baseRid = 0; for (uint i = 0; i < sameModuleCount; i++) { int currentRid = baseRid + (int)inlinersReader.ReadUInt(); sb.AppendLine($" {RidToMethodDef(currentRid):X8}"); baseRid = currentRid; } } return(sb.ToString()); }
private int ReadEncodedStackOffset(NibbleReader reader) { int offset = reader.ReadInt(); if (_machine == Machine.I386) { offset *= 4; // sizeof(DWORD) } return(offset); }
private void EnsureFixupCells() { if (_fixupCells != null) { return; } if (!_fixupOffset.HasValue) { return; } _fixupCells = new List <FixupCell>(); NibbleReader reader = new NibbleReader(_readyToRunReader.Image, _fixupOffset.Value); // The following algorithm has been loosely ported from CoreCLR, // src\vm\ceeload.inl, BOOL Module::FixupDelayListAux uint curTableIndex = reader.ReadUInt(); while (true) { uint fixupIndex = reader.ReadUInt(); // Accumulate the real rva from the delta encoded rva while (true) { ReadyToRunImportSection importSection = _readyToRunReader.ImportSections[(int)curTableIndex]; ReadyToRunImportSection.ImportSectionEntry entry = importSection.Entries[(int)fixupIndex]; _fixupCells.Add(new FixupCell(_fixupCells.Count, curTableIndex, fixupIndex, entry.Signature)); uint delta = reader.ReadUInt(); // Delta of 0 means end of entries in this table if (delta == 0) { break; } fixupIndex += delta; } uint tableIndex = reader.ReadUInt(); if (tableIndex == 0) { break; } curTableIndex = curTableIndex + tableIndex; } // Done with all entries in this table }
private FixupCell[] DecodeFixupCells(int offset) { List <FixupCell> cells = new List <FixupCell>(); NibbleReader reader = new NibbleReader(Image, offset); // The following algorithm has been loosely ported from CoreCLR, // src\vm\ceeload.inl, BOOL Module::FixupDelayListAux uint curTableIndex = reader.ReadUInt(); while (true) { uint fixupIndex = reader.ReadUInt(); // Accumulate the real rva from the delta encoded rva while (true) { R2RImportSection importSection = ImportSections[(int)curTableIndex]; R2RImportSection.ImportSectionEntry entry = importSection.Entries[(int)fixupIndex]; cells.Add(new FixupCell(cells.Count, curTableIndex, fixupIndex, entry.Signature)); uint delta = reader.ReadUInt(); // Delta of 0 means end of entries in this table if (delta == 0) { break; } fixupIndex += delta; } uint tableIndex = reader.ReadUInt(); if (tableIndex == 0) { break; } curTableIndex = curTableIndex + tableIndex; } // Done with all entries in this table return(cells.ToArray()); }
private void EnsureInitialized() { if (_boundsList != null) { return; } ReadyToRunReader _readyToRunReader = _runtimeFunction.ReadyToRunReader; int offset = _offset; _boundsList = new List <DebugInfoBoundsEntry>(); _variablesList = new List <NativeVarInfo>(); Machine machine = _readyToRunReader.Machine; byte[] image = _readyToRunReader.Image; _machine = machine; // Get the id of the runtime function from the NativeArray uint lookback = 0; uint debugInfoOffset = NativeReader.DecodeUnsigned(image, (uint)offset, ref lookback); if (lookback != 0) { System.Diagnostics.Debug.Assert(0 < lookback && lookback < offset); debugInfoOffset = (uint)offset - lookback; } NibbleReader reader = new NibbleReader(image, (int)debugInfoOffset); uint boundsByteCount = reader.ReadUInt(); uint variablesByteCount = reader.ReadUInt(); int boundsOffset = reader.GetNextByteOffset(); int variablesOffset = (int)(boundsOffset + boundsByteCount); if (boundsByteCount > 0) { ParseBounds(image, boundsOffset); } if (variablesByteCount > 0) { ParseNativeVarInfo(image, variablesOffset); } }
private void ParseBounds(byte[] image, int offset) { // Bounds info contains (Native Offset, IL Offset, flags) // - Sorted by native offset (so use a delta encoding for that). // - IL offsets aren't sorted, but they should be close to each other (so a signed delta encoding) // They may also include a sentinel value from MappingTypes. // - flags is 3 independent bits. NibbleReader reader = new NibbleReader(image, offset); uint boundsEntryCount = reader.ReadUInt(); Debug.Assert(boundsEntryCount > 0); uint previousNativeOffset = 0; for (int i = 0; i < boundsEntryCount; ++i) { var entry = new DebugInfoBoundsEntry(); previousNativeOffset += reader.ReadUInt(); entry.NativeOffset = previousNativeOffset; entry.ILOffset = reader.ReadUInt() + (uint)DebugInfoBoundsType.MaxMappingValue; entry.SourceTypes = (SourceTypes)reader.ReadUInt(); _boundsList.Add(entry); } }
private void ParseNativeVarInfo(byte[] image, int offset) { // Each Varinfo has a: // - native start +End offset. We can use a delta for the end offset. // - Il variable number. These are usually small. // - VarLoc information. This is a tagged variant. // The entries aren't sorted in any particular order. NibbleReader reader = new NibbleReader(image, offset); uint nativeVarCount = reader.ReadUInt(); for (int i = 0; i < nativeVarCount; ++i) { var entry = new NativeVarInfo(); entry.StartOffset = reader.ReadUInt(); entry.EndOffset = entry.StartOffset + reader.ReadUInt(); entry.VariableNumber = (uint)(reader.ReadUInt() + (int)ImplicitILArguments.Max); entry.Variable = new Variable(); // TODO: This is probably incomplete // This does not handle any implicit arguments or var args if (entry.VariableNumber < this._runtimeFunction.Method.Signature.ParameterTypes.Length) { entry.Variable.Type = VariableType.Parameter; entry.Variable.Index = (int)entry.VariableNumber; } else { entry.Variable.Type = VariableType.Local; entry.Variable.Index = (int)entry.VariableNumber - this._runtimeFunction.Method.Signature.ParameterTypes.Length; } var varLoc = new VarLoc(); varLoc.VarLocType = (VarLocType)reader.ReadUInt(); switch (varLoc.VarLocType) { case VarLocType.VLT_REG: case VarLocType.VLT_REG_FP: case VarLocType.VLT_REG_BYREF: varLoc.Data1 = (int)reader.ReadUInt(); break; case VarLocType.VLT_STK: case VarLocType.VLT_STK_BYREF: varLoc.Data1 = (int)reader.ReadUInt(); varLoc.Data2 = ReadEncodedStackOffset(reader); break; case VarLocType.VLT_REG_REG: varLoc.Data1 = (int)reader.ReadUInt(); varLoc.Data2 = (int)reader.ReadUInt(); break; case VarLocType.VLT_REG_STK: varLoc.Data1 = (int)reader.ReadUInt(); varLoc.Data2 = (int)reader.ReadUInt(); varLoc.Data3 = ReadEncodedStackOffset(reader); break; case VarLocType.VLT_STK_REG: varLoc.Data1 = ReadEncodedStackOffset(reader); varLoc.Data2 = (int)reader.ReadUInt(); varLoc.Data3 = (int)reader.ReadUInt(); break; case VarLocType.VLT_STK2: varLoc.Data1 = (int)reader.ReadUInt(); varLoc.Data2 = ReadEncodedStackOffset(reader); break; case VarLocType.VLT_FPSTK: varLoc.Data1 = (int)reader.ReadUInt(); break; case VarLocType.VLT_FIXED_VA: varLoc.Data1 = (int)reader.ReadUInt(); break; default: throw new BadImageFormatException("Unexpected var loc type"); } entry.VariableLocation = varLoc; _variablesList.Add(entry); } }
private void ParseNativeVarInfo(byte[] image, int offset) { // Each Varinfo has a: // - native start +End offset. We can use a delta for the end offset. // - Il variable number. These are usually small. // - VarLoc information. This is a tagged variant. // The entries aren't sorted in any particular order. NibbleReader reader = new NibbleReader(image, offset); uint nativeVarCount = reader.ReadUInt(); for (int i = 0; i < nativeVarCount; ++i) { var entry = new NativeVarInfo(); entry.StartOffset = reader.ReadUInt(); entry.EndOffset = entry.StartOffset + reader.ReadUInt(); entry.VariableNumber = (uint)(reader.ReadUInt() + (int)ImplicitILArguments.Max); var varLoc = new VarLoc(); varLoc.VarLocType = (VarLocType)reader.ReadUInt(); switch (varLoc.VarLocType) { case VarLocType.VLT_REG: case VarLocType.VLT_REG_FP: case VarLocType.VLT_REG_BYREF: varLoc.Data1 = (int)reader.ReadUInt(); break; case VarLocType.VLT_STK: case VarLocType.VLT_STK_BYREF: varLoc.Data1 = (int)reader.ReadUInt(); varLoc.Data2 = ReadEncodedStackOffset(reader); break; case VarLocType.VLT_REG_REG: varLoc.Data1 = (int)reader.ReadUInt(); varLoc.Data2 = (int)reader.ReadUInt(); break; case VarLocType.VLT_REG_STK: varLoc.Data1 = (int)reader.ReadUInt(); varLoc.Data2 = (int)reader.ReadUInt(); varLoc.Data3 = ReadEncodedStackOffset(reader); break; case VarLocType.VLT_STK_REG: varLoc.Data1 = ReadEncodedStackOffset(reader); varLoc.Data2 = (int)reader.ReadUInt(); varLoc.Data3 = (int)reader.ReadUInt(); break; case VarLocType.VLT_STK2: varLoc.Data1 = (int)reader.ReadUInt(); varLoc.Data2 = ReadEncodedStackOffset(reader); break; case VarLocType.VLT_FPSTK: varLoc.Data1 = (int)reader.ReadUInt(); break; case VarLocType.VLT_FIXED_VA: varLoc.Data1 = (int)reader.ReadUInt(); break; default: throw new BadImageFormatException("Unexpected var loc type"); } entry.VariableLocation = varLoc; _variablesList.Add(entry); } }