Skip to content

Commit 6006717

Browse files
committed
More custom debug records
1 parent cf2581b commit 6006717

File tree

9 files changed

+194
-5
lines changed

9 files changed

+194
-5
lines changed

src/AsmResolver.DotNet/PortablePdbs/CustomRecords/CustomDebugRecord.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ public static CustomDebugRecord FromRow(PdbReaderContext context, in CustomDebug
3535
{
3636
return SourceLinkRecord.FromReader(blobReaderContext, ref reader);
3737
}
38+
else if (kind == DefaultNamespaceRecord.KnownKind)
39+
{
40+
return DefaultNamespaceRecord.FromReader(blobReaderContext, ref reader);
41+
}
42+
else if (kind == DynamicLocalVariablesRecord.KnownKind)
43+
{
44+
return DynamicLocalVariablesRecord.FromReader(blobReaderContext, ref reader);
45+
}
3846

3947
if (hasBlob)
4048
{
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using System;
2+
using AsmResolver.DotNet.Signatures;
3+
using AsmResolver.IO;
4+
5+
namespace AsmResolver.DotNet.PortablePdbs.CustomRecords;
6+
7+
public class DefaultNamespaceRecord : CustomDebugRecord
8+
{
9+
public static Guid KnownKind { get; } = new("58b2eab6-209f-4e4e-a22c-b2d0f910c782");
10+
11+
public override Guid Kind => KnownKind;
12+
13+
public override bool HasBlob => true;
14+
15+
public Utf8String? Namespace { get; set; }
16+
17+
public static DefaultNamespaceRecord FromReader(in BlobReaderContext context, ref BinaryStreamReader reader)
18+
{
19+
return new DefaultNamespaceRecord
20+
{
21+
Namespace = new Utf8String(reader.ReadToEnd()),
22+
};
23+
}
24+
25+
protected override void WriteContents(in BlobSerializationContext context)
26+
{
27+
throw new NotImplementedException();
28+
}
29+
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
using System;
2+
using System.Collections;
3+
using AsmResolver.DotNet.Signatures;
4+
using AsmResolver.IO;
5+
using AsmResolver.PE.DotNet.Metadata.Tables;
6+
7+
namespace AsmResolver.DotNet.PortablePdbs.CustomRecords;
8+
9+
public class DynamicLocalVariablesRecord : CustomDebugRecord
10+
{
11+
public static Guid KnownKind { get; } = new("83C563C4-B4F3-47D5-B824-BA5441477EA8");
12+
13+
public override Guid Kind => KnownKind;
14+
15+
public override bool HasBlob => true;
16+
17+
public BitArray? BitSequence { get; set; }
18+
19+
public static DynamicLocalVariablesRecord FromReader(in BlobReaderContext context, ref BinaryStreamReader reader)
20+
{
21+
return new DynamicLocalVariablesRecord
22+
{
23+
BitSequence = new BitArray(reader.ReadToEnd()),
24+
};
25+
}
26+
27+
// TODO: decide whether these are wanted/figure out a better way to encode this
28+
public static TypeSignature DecodeDynamicBits(BitArray bitSequence, TypeSignature sig)
29+
{
30+
throw new NotImplementedException();
31+
}
32+
33+
public static BitArray EncodeDynamicBits(TypeSignature sig)
34+
{
35+
throw new NotImplementedException();
36+
}
37+
38+
public sealed class DynamicMarkerTypeSignature : TypeSignature
39+
{
40+
public CorLibTypeSignature ObjectType { get; }
41+
42+
public DynamicMarkerTypeSignature(CorLibTypeSignature objectType)
43+
{
44+
if (objectType.ElementType != ElementType.Object)
45+
{
46+
throw new ArgumentException("Object type must have ElementType == ElementType.Object", nameof(objectType));
47+
}
48+
49+
ObjectType = objectType;
50+
}
51+
52+
public override string Name => ObjectType.Name;
53+
54+
public override string Namespace => ObjectType.Namespace;
55+
56+
public override IResolutionScope? Scope => ObjectType.Scope;
57+
58+
public override bool IsValueType => false;
59+
60+
public override ElementType ElementType => ElementType.Object;
61+
62+
public override ITypeDefOrRef GetUnderlyingTypeDefOrRef() => ObjectType.GetUnderlyingTypeDefOrRef();
63+
64+
public override bool IsImportedInModule(ModuleDefinition module) => ObjectType.IsImportedInModule(module);
65+
66+
public override TResult AcceptVisitor<TResult>(ITypeSignatureVisitor<TResult> visitor) => visitor.VisitCorLibType(ObjectType);
67+
68+
public override TResult AcceptVisitor<TState, TResult>(ITypeSignatureVisitor<TState, TResult> visitor, TState state) => visitor.VisitCorLibType(ObjectType, state);
69+
70+
protected override void WriteContents(in BlobSerializationContext context) => context.Writer.WriteByte((byte)ElementType.Object);
71+
}
72+
73+
protected override void WriteContents(in BlobSerializationContext context)
74+
{
75+
throw new NotImplementedException();
76+
}
77+
}

src/AsmResolver.DotNet/PortablePdbs/LocalConstant.cs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
using AsmResolver.Collections;
1+
using System.Collections.Generic;
2+
using AsmResolver.Collections;
3+
using AsmResolver.DotNet.Collections;
24
using AsmResolver.PE.DotNet.Metadata.Tables;
35

46
namespace AsmResolver.DotNet.PortablePdbs;
57

6-
public partial class LocalConstant : IMetadataMember, IOwnedCollectionElement<LocalScope>
8+
public partial class LocalConstant : IMetadataMember, IOwnedCollectionElement<LocalScope>, IHasCustomDebugInformation
79
{
810
public LocalConstant(MetadataToken token)
911
{
@@ -36,9 +38,17 @@ public partial LocalConstantSignature? Signature
3638
set;
3739
}
3840

41+
[LazyProperty]
42+
public partial IList<CustomDebugInformation> CustomDebugInformations
43+
{
44+
get;
45+
}
46+
3947
protected virtual LocalScope? GetOwner() => null;
4048

4149
protected virtual Utf8String? GetName() => null;
4250

4351
protected virtual LocalConstantSignature? GetSignature() => null;
52+
53+
protected virtual IList<CustomDebugInformation> GetCustomDebugInformations() => new MemberCollection<IHasCustomDebugInformation, CustomDebugInformation>(this);
4454
}

src/AsmResolver.DotNet/PortablePdbs/Serialized/SerializedCustomDebugInformation.cs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System;
12
using AsmResolver.DotNet.PortablePdbs.CustomRecords;
23
using AsmResolver.PE.DotNet.Metadata.Tables;
34

@@ -16,4 +17,49 @@ public SerializedCustomDebugInformation(PdbReaderContext context, MetadataToken
1617
}
1718

1819
protected override CustomDebugRecord GetValue() => CustomDebugRecord.FromRow(_context, in _row);
20+
21+
protected override IHasCustomDebugInformation? GetOwner()
22+
{
23+
var encoder = _context.TablesStream.GetIndexEncoder(CodedIndex.HasCustomDebugInformation);
24+
var decoded = encoder.DecodeIndex(_row.Parent);
25+
IHasCustomDebugInformation? member;
26+
switch (decoded.Table)
27+
{
28+
case TableIndex.Method:
29+
case TableIndex.Field:
30+
case TableIndex.TypeRef:
31+
case TableIndex.TypeDef:
32+
case TableIndex.Param:
33+
case TableIndex.InterfaceImpl:
34+
case TableIndex.MemberRef:
35+
case TableIndex.Module:
36+
case TableIndex.DeclSecurity:
37+
case TableIndex.Property:
38+
case TableIndex.Event:
39+
case TableIndex.StandAloneSig:
40+
case TableIndex.ModuleRef:
41+
case TableIndex.TypeSpec:
42+
case TableIndex.Assembly:
43+
case TableIndex.AssemblyRef:
44+
case TableIndex.File:
45+
case TableIndex.ExportedType:
46+
case TableIndex.ManifestResource:
47+
case TableIndex.GenericParam:
48+
case TableIndex.GenericParamConstraint:
49+
case TableIndex.MethodSpec:
50+
_context.OwningModule.TryLookupMember<IHasCustomDebugInformation>(decoded, out member);
51+
break;
52+
case TableIndex.Document:
53+
case TableIndex.LocalScope:
54+
case TableIndex.LocalVariable:
55+
case TableIndex.LocalConstant:
56+
case TableIndex.ImportScope:
57+
_context.Pdb.TryLookupMember<IHasCustomDebugInformation>(decoded, out member);
58+
break;
59+
default:
60+
throw new ArgumentOutOfRangeException();
61+
}
62+
63+
return member;
64+
}
1965
}

src/AsmResolver.DotNet/PortablePdbs/Serialized/SerializedLocalConstant.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using System.Collections.Generic;
12
using AsmResolver.DotNet.Signatures;
23
using AsmResolver.PE.DotNet.Metadata.Tables;
34

@@ -28,4 +29,6 @@ public SerializedLocalConstant(PdbReaderContext context, MetadataToken token, in
2829
}
2930
return null;
3031
}
32+
33+
protected override IList<CustomDebugInformation> GetCustomDebugInformations() => _context.Pdb.GetCustomDebugInformations(this);
3134
}

src/AsmResolver.DotNet/PortablePdbs/Serialized/SerializedPortablePdb.cs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,18 @@ public override bool TryLookupMember<T>(MetadataToken token, [MaybeNullWhen(fals
3939
return false;
4040
}
4141

42-
public IList<CustomDebugInformation> GetCustomDebugInformations(IHasCustomDebugInformation owner)
42+
public IEnumerable<IMetadataMember> EnumerateTableMembers(TableIndex tableIndex)
43+
{
44+
var table = PdbReaderContext.TablesStream.GetTable(tableIndex);
45+
46+
for (uint rid = 1; rid <= table.Count; rid++)
47+
{
48+
if (TryLookupMember<IMetadataMember>(new MetadataToken(tableIndex, rid), out var member))
49+
yield return member;
50+
}
51+
}
52+
53+
internal IList<CustomDebugInformation> GetCustomDebugInformations(IHasCustomDebugInformation owner)
4354
{
4455
var rids = GetCustomDebugInformations(owner.MetadataToken);
4556
var customDebugInformations = new MemberCollection<IHasCustomDebugInformation, CustomDebugInformation>(owner, rids.Count);

src/AsmResolver.DotNet/Signatures/CorLibTypeSignature.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public ITypeDefOrRef Type
3939
}
4040

4141
/// <inheritdoc />
42-
public override string? Name
42+
public override string Name
4343
{
4444
get;
4545
}

test/AsmResolver.DotNet.Tests/PortablePdbs/PortablePdbTest.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
using System.Linq;
2+
using AsmResolver.DotNet.PortablePdbs;
3+
using AsmResolver.DotNet.Serialized;
4+
using AsmResolver.PE.DotNet.Metadata.Tables;
15
using Xunit;
26

37
namespace AsmResolver.DotNet.Tests.PortablePdbs;
@@ -7,6 +11,7 @@ public class PortablePdbTest
711
[Fact]
812
public void Test()
913
{
10-
var mod = ModuleDefinition.FromFile("/home/aaronr/.nuget/packages/microsoft.codeanalysis.csharp/5.3.0-1.25619.109/lib/net9.0/Microsoft.CodeAnalysis.CSharp.dll");
14+
var mod = ModuleDefinition.FromFile(typeof(PortablePdbTest).Assembly.Location);
15+
var pdb = ((PortablePdbSymbolReader)((SerializedModuleDefinition)mod).SymbolReader).Pdb.EnumerateTableMembers(TableIndex.CustomDebugInformation).Cast<CustomDebugInformation>().ToArray();
1116
}
1217
}

0 commit comments

Comments
 (0)