Browse Source

Fix #3563: Add support for ildasm /caverbal format

pull/3579/head
Siegfried Pammer 10 months ago
parent
commit
61f82d0c2d
  1. 148
      ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs
  2. 19
      ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs
  3. 3
      ILSpy/Languages/CSharpILMixedLanguage.cs
  4. 3
      ILSpy/Languages/ILLanguage.cs
  5. 8
      ILSpy/Options/DisplaySettings.cs
  6. 1
      ILSpy/Options/DisplaySettingsPanel.xaml
  7. 11
      ILSpy/Properties/Resources.Designer.cs
  8. 3
      ILSpy/Properties/Resources.resx

148
ICSharpCode.Decompiler/Disassembler/ReflectionDisassembler.cs

@ -74,6 +74,12 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -74,6 +74,12 @@ namespace ICSharpCode.Decompiler.Disassembler
public bool ExpandMemberDefinitions { get; set; }
/// <summary>
/// Gets or sets whether custom attribute blobs should be decoded or dumped as raw bytes. Default is <see langword="false"/>.
/// Setting this value to <see langword="true"/> (roughly) corresponds to the <c>/CAVERBAL</c> switch of <c>ildasm</c>.
/// </summary>
public bool DecodeCustomAttributeBlobs { get; set; }
public IAssemblyResolver AssemblyResolver { get; set; }
public IEntityProcessor EntityProcessor { get; set; }
@ -476,7 +482,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -476,7 +482,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
class SecurityDeclarationDecoder : ICustomAttributeTypeProvider<(PrimitiveTypeCode, string)>
class SecurityDeclarationDecoder : ICustomAttributeTypeProvider<(PrimitiveTypeCode Code, string Name)>
{
readonly ITextOutput output;
readonly IAssemblyResolver resolver;
@ -506,12 +512,54 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -506,12 +512,54 @@ namespace ICSharpCode.Decompiler.Disassembler
public (PrimitiveTypeCode, string) GetTypeFromDefinition(MetadataReader reader, TypeDefinitionHandle handle, byte rawTypeKind)
{
throw new NotImplementedException();
string fullTypeName = handle.GetFullTypeName(reader).FullName;
if (handle.IsEnum(reader, out var typeCode))
return (typeCode, "enum " + fullTypeName);
return (0, fullTypeName);
}
public (PrimitiveTypeCode, string) GetTypeFromReference(MetadataReader reader, TypeReferenceHandle handle, byte rawTypeKind)
{
throw new NotImplementedException();
string fullTypeName = handle.GetFullTypeName(reader).FullName;
var containingModule = GetDeclaringModule(handle);
string assemblyQualifiedTypeName = containingModule != null
? fullTypeName + ", " + containingModule
: fullTypeName;
PrimitiveTypeCode typeCode = 0;
var (targetModule, resolvedType) = ResolveType(assemblyQualifiedTypeName, module);
if (targetModule != null)
{
if (!resolvedType.IsEnum(targetModule.Metadata, out typeCode))
{
typeCode = 0;
}
else
{
assemblyQualifiedTypeName = "enum " + assemblyQualifiedTypeName;
}
}
return (typeCode, assemblyQualifiedTypeName);
string GetDeclaringModule(TypeReferenceHandle handle)
{
var tr = reader.GetTypeReference(handle);
switch (tr.ResolutionScope.Kind)
{
case HandleKind.TypeReference:
return GetDeclaringModule((TypeReferenceHandle)tr.ResolutionScope);
case HandleKind.AssemblyReference:
var asmRef = reader.GetAssemblyReference((AssemblyReferenceHandle)tr.ResolutionScope);
return asmRef.TryGetFullAssemblyName(reader, out var assemblyName) ? assemblyName : null;
case HandleKind.ModuleReference:
var modRef = reader.GetModuleReference((ModuleReferenceHandle)tr.ResolutionScope);
return reader.GetString(modRef.Name);
default:
return null;
}
}
}
public (PrimitiveTypeCode, string) GetTypeFromSerializedName(string name)
@ -608,17 +656,6 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -608,17 +656,6 @@ namespace ICSharpCode.Decompiler.Disassembler
}
}
PrimitiveTypeCode ResolveEnumUnderlyingType(string typeName, PEFile module)
{
if (typeName.StartsWith("enum ", StringComparison.Ordinal))
typeName = typeName.Substring(5);
var (containingModule, typeDefHandle) = ResolveType(typeName, module);
if (typeDefHandle.IsNil || !typeDefHandle.IsEnum(containingModule.Metadata, out var typeCode))
throw new EnumUnderlyingTypeResolveException();
return typeCode;
}
MetadataFile mscorlib;
bool TryResolveMscorlib(out MetadataFile mscorlib)
@ -704,7 +741,7 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -704,7 +741,7 @@ namespace ICSharpCode.Decompiler.Disassembler
}
output.Write(argument.Type.Name ?? PrimitiveTypeCodeToString(argument.Type.Code));
output.Write(" " + argument.Name + " = ");
output.Write(" " + DisassemblerHelpers.Escape(argument.Name) + " = ");
WriteValue(output, argument.Type, argument.Value);
output.WriteLine();
@ -1824,12 +1861,62 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1824,12 +1861,62 @@ namespace ICSharpCode.Decompiler.Disassembler
if (!attr.Value.IsNil)
{
output.Write(" = ");
WriteBlob(attr.Value, metadata);
if (DecodeCustomAttributeBlobs)
WriteDecodedCustomAttributeBlob(attr, module);
else
WriteBlob(attr.Value, metadata);
}
output.WriteLine();
}
}
void WriteDecodedCustomAttributeBlob(CustomAttribute attr, MetadataFile module)
{
CustomAttributeValue<(PrimitiveTypeCode Code, string Name)> value;
try
{
var provider = new SecurityDeclarationDecoder(output, AssemblyResolver, module);
value = attr.DecodeValue(provider);
}
catch (BadImageFormatException)
{
output.Write("/* Could not decode attribute value */ ");
WriteBlob(attr.Value, module.Metadata);
return;
}
output.Write("{");
output.Indent();
foreach (var arg in value.FixedArguments)
{
output.WriteLine();
WriteValue(output, arg.Type, arg.Value);
}
foreach (var arg in value.NamedArguments)
{
output.WriteLine();
switch (arg.Kind)
{
case CustomAttributeNamedArgumentKind.Field:
output.Write("field ");
break;
case CustomAttributeNamedArgumentKind.Property:
output.Write("property ");
break;
}
output.Write(arg.Type.Name ?? PrimitiveTypeCodeToString(arg.Type.Code));
output.Write(" " + DisassemblerHelpers.Escape(arg.Name) + " = ");
WriteValue(output, arg.Type, arg.Value);
}
output.WriteLine();
output.Unindent();
output.Write("}");
}
void WriteBlob(BlobHandle blob, MetadataReader metadata)
{
var reader = metadata.GetBlobReader(blob);
@ -1839,23 +1926,26 @@ namespace ICSharpCode.Decompiler.Disassembler @@ -1839,23 +1926,26 @@ namespace ICSharpCode.Decompiler.Disassembler
void WriteBlob(BlobReader reader)
{
output.Write("(");
output.Indent();
for (int i = 0; i < reader.Length; i++)
if (reader.Length > 0)
{
if (i % 16 == 0 && i < reader.Length - 1)
{
output.WriteLine();
}
else
output.Indent();
for (int i = 0; i < reader.Length; i++)
{
output.Write(' ');
if (i % 16 == 0 && i < reader.Length - 1)
{
output.WriteLine();
}
else
{
output.Write(' ');
}
output.Write(reader.ReadByte().ToString("x2"));
}
output.Write(reader.ReadByte().ToString("x2"));
}
output.WriteLine();
output.Unindent();
output.WriteLine();
output.Unindent();
}
output.Write(")");
}

19
ICSharpCode.Decompiler/Metadata/MetadataExtensions.cs

@ -210,25 +210,6 @@ namespace ICSharpCode.Decompiler.Metadata @@ -210,25 +210,6 @@ namespace ICSharpCode.Decompiler.Metadata
return Disassembler.DisassemblerHelpers.Escape(name);
}
[Obsolete("Use MetadataModule.GetDeclaringModule() instead")]
public static IModuleReference GetDeclaringModule(this TypeReferenceHandle handle, MetadataReader reader)
{
var tr = reader.GetTypeReference(handle);
switch (tr.ResolutionScope.Kind)
{
case HandleKind.TypeReference:
return ((TypeReferenceHandle)tr.ResolutionScope).GetDeclaringModule(reader);
case HandleKind.AssemblyReference:
var asmRef = reader.GetAssemblyReference((AssemblyReferenceHandle)tr.ResolutionScope);
return new DefaultAssemblyReference(reader.GetString(asmRef.Name));
case HandleKind.ModuleReference:
var modRef = reader.GetModuleReference((ModuleReferenceHandle)tr.ResolutionScope);
return new DefaultAssemblyReference(reader.GetString(modRef.Name));
default:
return DefaultAssemblyReference.CurrentAssembly;
}
}
internal static readonly TypeProvider minimalCorlibTypeProvider =
new TypeProvider(new SimpleCompilation(MinimalCorlib.Instance));

3
ILSpy/Languages/CSharpILMixedLanguage.cs

@ -60,7 +60,8 @@ namespace ICSharpCode.ILSpy @@ -60,7 +60,8 @@ namespace ICSharpCode.ILSpy
ShowMetadataTokens = displaySettings.ShowMetadataTokens,
ShowMetadataTokensInBase10 = displaySettings.ShowMetadataTokensInBase10,
ShowRawRVAOffsetAndBytes = displaySettings.ShowRawOffsetsAndBytesBeforeInstruction,
ExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions
ExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions,
DecodeCustomAttributeBlobs = displaySettings.DecodeCustomAttributeBlobs
};
}

3
ILSpy/Languages/ILLanguage.cs

@ -67,7 +67,8 @@ namespace ICSharpCode.ILSpy @@ -67,7 +67,8 @@ namespace ICSharpCode.ILSpy
ShowMetadataTokens = displaySettings.ShowMetadataTokens,
ShowMetadataTokensInBase10 = displaySettings.ShowMetadataTokensInBase10,
ShowRawRVAOffsetAndBytes = displaySettings.ShowRawOffsetsAndBytesBeforeInstruction,
ExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions
ExpandMemberDefinitions = options.DecompilerSettings.ExpandMemberDefinitions,
DecodeCustomAttributeBlobs = displaySettings.DecodeCustomAttributeBlobs
};
}

8
ILSpy/Options/DisplaySettings.cs

@ -156,6 +156,12 @@ namespace ICSharpCode.ILSpy.Options @@ -156,6 +156,12 @@ namespace ICSharpCode.ILSpy.Options
set => SetProperty(ref enableSmoothScrolling, value);
}
private bool decodeCustomAttributeBlobs;
public bool DecodeCustomAttributeBlobs {
get => decodeCustomAttributeBlobs;
set => SetProperty(ref decodeCustomAttributeBlobs, value);
}
public XName SectionName => "DisplaySettings";
public void LoadFromXml(XElement section)
@ -181,6 +187,7 @@ namespace ICSharpCode.ILSpy.Options @@ -181,6 +187,7 @@ namespace ICSharpCode.ILSpy.Options
ShowRawOffsetsAndBytesBeforeInstruction = (bool?)section.Attribute("ShowRawOffsetsAndBytesBeforeInstruction") ?? false;
StyleWindowTitleBar = (bool?)section.Attribute("StyleWindowTitleBar") ?? false;
EnableSmoothScrolling = (bool?)section.Attribute("EnableSmoothScrolling") ?? true;
DecodeCustomAttributeBlobs = (bool?)section.Attribute("DecodeCustomAttributeBlobs") ?? false;
}
public XElement SaveToXml()
@ -208,6 +215,7 @@ namespace ICSharpCode.ILSpy.Options @@ -208,6 +215,7 @@ namespace ICSharpCode.ILSpy.Options
section.SetAttributeValue("ShowRawOffsetsAndBytesBeforeInstruction", ShowRawOffsetsAndBytesBeforeInstruction);
section.SetAttributeValue("StyleWindowTitleBar", StyleWindowTitleBar);
section.SetAttributeValue("EnableSmoothScrolling", EnableSmoothScrolling);
section.SetAttributeValue("DecodeCustomAttributeBlobs", DecodeCustomAttributeBlobs);
return section;
}

1
ILSpy/Options/DisplaySettingsPanel.xaml

@ -64,6 +64,7 @@ @@ -64,6 +64,7 @@
<CheckBox IsChecked="{Binding Settings.ExpandUsingDeclarations}" Content="{x:Static properties:Resources.ExpandUsingDeclarationsAfterDecompilation}"></CheckBox>
<CheckBox IsChecked="{Binding Settings.ShowDebugInfo}" Content="{x:Static properties:Resources.ShowInfoFromDebugSymbolsAvailable}"></CheckBox>
<CheckBox IsChecked="{Binding Settings.ShowRawOffsetsAndBytesBeforeInstruction}" Content="{x:Static properties:Resources.ShowRawOffsetsAndBytesBeforeInstruction}"></CheckBox>
<CheckBox IsChecked="{Binding Settings.DecodeCustomAttributeBlobs}" Content="{x:Static properties:Resources.DecodeCustomAttributeBlobs}"></CheckBox>
</StackPanel>
</GroupBox>
<GroupBox Header="{x:Static properties:Resources.TreeViewOptions}">

11
ILSpy/Properties/Resources.Designer.cs generated

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
@ -648,6 +648,15 @@ namespace ICSharpCode.ILSpy.Properties { @@ -648,6 +648,15 @@ namespace ICSharpCode.ILSpy.Properties {
}
}
/// <summary>
/// Looks up a localized string similar to Decode custom attribute blobs.
/// </summary>
public static string DecodeCustomAttributeBlobs {
get {
return ResourceManager.GetString("DecodeCustomAttributeBlobs", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Decompilation complete in {0:F1} seconds..
/// </summary>

3
ILSpy/Properties/Resources.resx

@ -234,6 +234,9 @@ Are you sure you want to continue?</value> @@ -234,6 +234,9 @@ Are you sure you want to continue?</value>
<data name="DebugThisStep" xml:space="preserve">
<value>Debug this step</value>
</data>
<data name="DecodeCustomAttributeBlobs" xml:space="preserve">
<value>Decode custom attribute blobs</value>
</data>
<data name="DecompilationCompleteInF1Seconds" xml:space="preserve">
<value>Decompilation complete in {0:F1} seconds.</value>
</data>

Loading…
Cancel
Save