[LoongArch64] Part-5:add loongarch support in some files for LoongArch64. (#21769)
[mono-project.git] / mcs / tools / mono-symbolicate / SeqPointInfo.cs
blob22a3dae62fb043c49e03530147bd8a8d0846789c
1 using System;
2 using System.IO;
3 using System.Collections.Generic;
5 namespace Mono
7 static class BinaryReaderExtensions
9 public static int ReadVariableInt (this BinaryReader reader)
11 int val = 0;
12 for (var i = 0; i < 4; i++) {
13 var b = reader.ReadByte ();
14 val |= (b & 0x7f) << (7 * i);
15 if ((b & 0x80) == 0)
16 return val;
19 throw new Exception ("Invalid variable int");
22 public static int ReadVariableZigZagInt (this BinaryReader reader)
24 int enc = ReadVariableInt (reader);
25 int val = enc >> 1;
26 return ((enc & 1) == 0)? val : -val;
30 class SeqPointInfo
32 class MethodData
34 List<SeqPoint> seqPoints;
36 public static MethodData Read (BinaryReader reader)
38 var hasDebugData = reader.ReadVariableInt () != 0;
39 var dataSize = reader.ReadVariableInt ();
40 var dataEnd = reader.BaseStream.Position + dataSize;
42 var seqPoints = new List<SeqPoint> ();
43 SeqPoint prev = null;
44 while (reader.BaseStream.Position < dataEnd) {
45 var seqPoint = SeqPoint.Read (reader, prev, hasDebugData);
46 seqPoints.Add (seqPoint);
47 prev = seqPoint;
50 if (reader.BaseStream.Position != dataEnd)
51 throw new Exception ("Read more seq point than expected.");
53 return new MethodData () { seqPoints = seqPoints };
56 public bool TryGetILOffset (int nativeOffset, out int ilOffset)
58 ilOffset = 0;
59 SeqPoint prev = null;
60 foreach (var seqPoint in seqPoints) {
61 if (seqPoint.NativeOffset > nativeOffset)
62 break;
63 prev = seqPoint;
66 if (prev == null)
67 return false;
69 ilOffset = prev.ILOffset;
70 return true;
74 class SeqPoint
76 public readonly int ILOffset;
77 public readonly int NativeOffset;
79 public SeqPoint (int ilOffset, int nativeOffset)
81 ILOffset = ilOffset;
82 NativeOffset = nativeOffset;
85 public static SeqPoint Read (BinaryReader reader, SeqPoint prev, bool hasDebug)
87 var ilOffset = reader.ReadVariableZigZagInt ();
88 var nativeOffset = reader.ReadVariableZigZagInt ();
90 // Respect delta encoding
91 if (prev != null) {
92 ilOffset += prev.ILOffset;
93 nativeOffset += prev.NativeOffset;
96 //Read everything to ensure the buffer position is at the end of the seq point data.
97 if (hasDebug) {
98 reader.ReadVariableInt (); // flags
100 var next_length = reader.ReadVariableInt ();
101 for (var i = 0; i < next_length; ++i)
102 reader.ReadVariableInt ();
105 return new SeqPoint (ilOffset, nativeOffset);
109 Dictionary<Tuple<int,int>, MethodData> dataByIds;
110 Dictionary<int, MethodData> dataByTokens;
112 public static SeqPointInfo Read (string path)
114 using (var reader = new BinaryReader (File.Open (path, FileMode.Open)))
116 var dataByIds = new Dictionary<Tuple<int,int>, MethodData> ();
117 var dataByTokens = new Dictionary<int, MethodData> ();
119 var methodCount = reader.ReadVariableInt ();
121 for (var i = 0; i < methodCount; ++i) {
122 var methodToken = reader.ReadVariableInt ();
123 var methodIndex = reader.ReadVariableInt ();
124 var methodId = new Tuple<int, int> (methodToken, methodIndex);
126 var methodData = MethodData.Read (reader);
128 dataByIds.Add (methodId, methodData);
129 if (!dataByTokens.ContainsKey (methodToken))
130 dataByTokens.Add (methodToken, methodData);
133 return new SeqPointInfo { dataByIds = dataByIds, dataByTokens = dataByTokens };
137 public int GetILOffset (int methodToken, uint methodIndex, int nativeOffset)
139 MethodData methodData;
140 if (methodIndex == 0xffffff) {
141 if (!dataByTokens.TryGetValue (methodToken, out methodData))
142 throw new Exception (string.Format ("Could not find data for method token {0:X}", methodToken));
143 } else {
144 var methodId = new Tuple<int, int> (methodToken, (int)methodIndex);
145 if (!dataByIds.TryGetValue (methodId, out methodData))
146 throw new Exception (string.Format ("Could not find data for method token {0:X} with index {1:X}", methodToken, methodIndex));
149 int ilOffset;
150 if (!methodData.TryGetILOffset (nativeOffset, out ilOffset))
151 throw new Exception ("Could not retrieve IL offset");
153 return ilOffset;