Skip to content

Commit

Permalink
Support RVA fields in type disassembler
Browse files Browse the repository at this point in the history
Fixes #145
  • Loading branch information
MSDN-WhiteKnight committed Jun 25, 2023
1 parent 2d3b1b9 commit db899a4
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 0 deletions.
8 changes: 8 additions & 0 deletions CilTools.BytecodeAnalysis/Syntax/Disassembler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,14 @@ static void ArrayBytesToText(byte[] arr, TextWriter target)
target.Flush();
}

internal static string ArrayBytesToString(byte[] arr)
{
StringBuilder sb = new StringBuilder(arr.Length * 3);
StringWriter wr = new StringWriter(sb);
ArrayBytesToText(arr, wr);
return sb.ToString();
}

static CommentSyntax OnReflectionError(object sender, string msg, Exception ex)
{
CommentSyntax cs = CommentSyntax.Create(string.Empty,
Expand Down
42 changes: 42 additions & 0 deletions CilTools.BytecodeAnalysis/Syntax/Generation/SyntaxGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -904,6 +904,8 @@ string MethodRefToString(MethodBase m)
//fields
TypeSyntaxGenerator tgen = new TypeSyntaxGenerator(this.containingAssembly);
FieldInfo[] fields = t.GetFields(ReflectionUtils.AllMembers | BindingFlags.DeclaredOnly);
List<string> rva_labels = new List<string>(fields.Length);
List<byte[]> rva_arrays = new List<byte[]>(fields.Length);

if (isModuleType && fields.Length > 0)
{
Expand Down Expand Up @@ -973,8 +975,29 @@ string MethodRefToString(MethodBase m)
SyntaxNode[] ftNodes = tgen.GetTypeNameSyntax(fields[i].FieldType).ToArray();
inner.Add(new MemberRefSyntax(ftNodes, fields[i].FieldType));

// Field name
inner.Add(new IdentifierSyntax(" ", fields[i].Name, string.Empty, true, fields[i]));

// RVA field data label
if ((fields[i].Attributes & FieldAttributes.HasFieldRVA) != 0)
{
object val = ReflectionProperties.Get(fields[i], ReflectionProperties.FieldRva);

if (val != null)
{
int rva = (int)val;
inner.Add(new KeywordSyntax(" ", "at", " ", KeywordKind.Other));
string label = "I_" + rva.ToString("X", CultureInfo.InvariantCulture);
inner.Add(new IdentifierSyntax(string.Empty, label, string.Empty, ismember: false, target: null));
rva_labels.Add(label);
byte[] arr = ReflectionProperties.Get(fields[i], ReflectionProperties.RvaFieldValue) as byte[];

if (arr == null) rva_arrays.Add(new byte[0]);
else rva_arrays.Add(arr);
}
}

// Constant value
object constval = DBNull.Value;

try { constval = fields[i].GetRawConstantValue(); }
Expand Down Expand Up @@ -1311,6 +1334,25 @@ string MethodRefToString(MethodBase m)
yield return content[i];
}
}

if (rva_labels.Count > 0) yield return new GenericSyntax(Environment.NewLine);

// RVA field values
for (int i = 0; i < rva_labels.Count; i++)
{
List<SyntaxNode> nodes = new List<SyntaxNode>();
nodes.Add(new KeywordSyntax("cil", " "));
nodes.Add(new IdentifierSyntax(string.Empty, rva_labels[i], " ", ismember: false, target: null));
nodes.Add(new PunctuationSyntax(string.Empty, "=", " "));
nodes.Add(new KeywordSyntax("bytearray", " "));
nodes.Add(new PunctuationSyntax(string.Empty, "(", " "));

string val_str = Disassembler.ArrayBytesToString(rva_arrays[i]);
nodes.Add(new GenericSyntax(val_str));

nodes.Add(new PunctuationSyntax(string.Empty, ")", Environment.NewLine));
yield return new DirectiveSyntax(SyntaxUtils.GetIndentString(startIndent), "data", nodes.ToArray());
}
}
}
}

0 comments on commit db899a4

Please sign in to comment.