/ src / ARMeilleure / Diagnostics / Symbols.cs
Symbols.cs
 1  using System.Collections.Concurrent;
 2  using System.Collections.Generic;
 3  using System.Diagnostics;
 4  using System.Text;
 5  
 6  namespace ARMeilleure.Diagnostics
 7  {
 8      static class Symbols
 9      {
10          private readonly struct RangedSymbol
11          {
12              public readonly ulong Start;
13              public readonly ulong End;
14              public readonly ulong ElementSize;
15              public readonly string Name;
16  
17              public RangedSymbol(ulong start, ulong end, ulong elemSize, string name)
18              {
19                  Start = start;
20                  End = end;
21                  ElementSize = elemSize;
22                  Name = name;
23              }
24          }
25  
26          private static readonly ConcurrentDictionary<ulong, string> _symbols;
27          private static readonly List<RangedSymbol> _rangedSymbols;
28  
29          static Symbols()
30          {
31              _symbols = new ConcurrentDictionary<ulong, string>();
32              _rangedSymbols = new List<RangedSymbol>();
33          }
34  
35          public static string Get(ulong address)
36          {
37              if (_symbols.TryGetValue(address, out string result))
38              {
39                  return result;
40              }
41  
42              lock (_rangedSymbols)
43              {
44                  foreach (RangedSymbol symbol in _rangedSymbols)
45                  {
46                      if (address >= symbol.Start && address <= symbol.End)
47                      {
48                          ulong diff = address - symbol.Start;
49                          ulong rem = diff % symbol.ElementSize;
50  
51                          StringBuilder resultBuilder = new();
52                          resultBuilder.Append($"{symbol.Name}_{diff / symbol.ElementSize}");
53  
54                          if (rem != 0)
55                          {
56                              resultBuilder.Append($"+{rem}");
57                          }
58  
59                          result = resultBuilder.ToString();
60                          _symbols.TryAdd(address, result);
61  
62                          return result;
63                      }
64                  }
65              }
66  
67              return null;
68          }
69  
70          [Conditional("M_DEBUG")]
71          public static void Add(ulong address, string name)
72          {
73              _symbols.TryAdd(address, name);
74          }
75  
76          [Conditional("M_DEBUG")]
77          public static void Add(ulong address, ulong size, ulong elemSize, string name)
78          {
79              lock (_rangedSymbols)
80              {
81                  _rangedSymbols.Add(new RangedSymbol(address, address + size, elemSize, name));
82              }
83          }
84      }
85  }