Skip to content

Commit

Permalink
Merge pull request #342 from Washi1337/feature/pdb-image
Browse files Browse the repository at this point in the history
PDB Leaf and Type Records
  • Loading branch information
Washi1337 authored Aug 12, 2022
2 parents 17383f0 + 4f30643 commit 1c1768d
Show file tree
Hide file tree
Showing 106 changed files with 7,431 additions and 23 deletions.
7 changes: 7 additions & 0 deletions src/AsmResolver.Symbols.Pdb/AsmResolver.Symbols.Pdb.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,11 @@
<ProjectReference Include="..\AsmResolver\AsmResolver.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="Nullable" Version="1.3.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>

</Project>
66 changes: 66 additions & 0 deletions src/AsmResolver.Symbols.Pdb/Leaves/ArgumentListLeaf.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
using System.Collections.Generic;
using System.Threading;

namespace AsmResolver.Symbols.Pdb.Leaves;

/// <summary>
/// Represents a leaf containing a list of type arguments for a function or method.
/// </summary>
public class ArgumentListLeaf : CodeViewLeaf
{
private IList<CodeViewTypeRecord>? _types;

/// <summary>
/// Initializes an empty argument list.
/// </summary>
/// <param name="typeIndex">The type index to assign to the list.</param>
protected ArgumentListLeaf(uint typeIndex)
: base(typeIndex)
{
}

/// <summary>
/// Creates a new empty argument list.
/// </summary>
public ArgumentListLeaf()
: base(0)
{
}

/// <summary>
/// Creates a new argument list.
/// </summary>
public ArgumentListLeaf(params CodeViewTypeRecord[] argumentTypes)
: base(0)
{
_types = new List<CodeViewTypeRecord>(argumentTypes);
}

/// <inheritdoc />
public override CodeViewLeafKind LeafKind => CodeViewLeafKind.ArgList;

/// <summary>
/// Gets an ordered collection of types that correspond to the types of each parameter.
/// </summary>
public IList<CodeViewTypeRecord> Types
{
get
{
if (_types is null)
Interlocked.CompareExchange(ref _types, GetArgumentTypes(), null);
return _types;
}
}

/// <summary>
/// Obtains the argument types stored in the list.
/// </summary>
/// <returns>The types.</returns>
/// <remarks>
/// This method is called upon initialization of the <see cref="Types"/> property.
/// </remarks>
protected virtual IList<CodeViewTypeRecord> GetArgumentTypes() => new List<CodeViewTypeRecord>();

/// <inheritdoc />
public override string ToString() => string.Join(", ", Types);
}
123 changes: 123 additions & 0 deletions src/AsmResolver.Symbols.Pdb/Leaves/ArrayTypeRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
namespace AsmResolver.Symbols.Pdb.Leaves;

/// <summary>
/// Represents a type describing an array of elements.
/// </summary>
public class ArrayTypeRecord : CodeViewTypeRecord
{
private readonly LazyVariable<CodeViewTypeRecord?> _elementType;
private readonly LazyVariable<CodeViewTypeRecord?> _indexType;
private readonly LazyVariable<Utf8String> _name;

/// <summary>
/// Initializes a new empty array type.
/// </summary>
/// <param name="typeIndex">The type index to assign to the type.</param>
protected ArrayTypeRecord(uint typeIndex)
: base(typeIndex)
{
_elementType = new LazyVariable<CodeViewTypeRecord?>(GetElementType);
_indexType = new LazyVariable<CodeViewTypeRecord?>(GetIndexType);
_name = new LazyVariable<Utf8String>(GetName);
}

/// <summary>
/// Creates a new array type.
/// </summary>
/// <param name="elementType">The type of each element in the array.</param>
/// <param name="indexType">The type to use for indexing into the array.</param>
/// <param name="length">The number of elements in the array.</param>
public ArrayTypeRecord(CodeViewTypeRecord elementType, CodeViewTypeRecord indexType, ulong length)
: base(0)
{
_elementType = new LazyVariable<CodeViewTypeRecord?>(elementType);
_indexType = new LazyVariable<CodeViewTypeRecord?>(indexType);
Length = length;
_name = new LazyVariable<Utf8String>(Utf8String.Empty);
}

/// <summary>
/// Creates a new array type.
/// </summary>
/// <param name="elementType">The type of each element in the array.</param>
/// <param name="indexType">The type to use for indexing into the array.</param>
/// <param name="length">The number of elements in the array.</param>
/// <param name="name">The name of the array type.</param>
public ArrayTypeRecord(CodeViewTypeRecord elementType, CodeViewTypeRecord indexType, ulong length, Utf8String name)
: base(0)
{
_elementType = new LazyVariable<CodeViewTypeRecord?>(elementType);
_indexType = new LazyVariable<CodeViewTypeRecord?>(indexType);
Length = length;
_name = new LazyVariable<Utf8String>(Name);
}

/// <inheritdoc />
public override CodeViewLeafKind LeafKind => CodeViewLeafKind.Array;

/// <summary>
/// Gets or sets the type of each element in the array.
/// </summary>
public CodeViewTypeRecord? ElementType
{
get => _elementType.Value;
set => _elementType.Value = value;
}

/// <summary>
/// Gets or sets the type that is used to index into the array.
/// </summary>
public CodeViewTypeRecord? IndexType
{
get => _indexType.Value;
set => _indexType.Value = value;
}

/// <summary>
/// Gets or sets the number of elements in the array.
/// </summary>
public ulong Length
{
get;
set;
}

/// <summary>
/// Gets or sets the name of the type.
/// </summary>
public Utf8String Name
{
get => _name.Value;
set => _name.Value = value;
}

/// <summary>
/// Obtains the element type of the array.
/// </summary>
/// <returns>The element type.</returns>
/// <remarks>
/// This method is called upon initialization of the <see cref="ElementType"/> property.
/// </remarks>
protected virtual CodeViewTypeRecord? GetElementType() => null;

/// <summary>
/// Obtains the index type of the array.
/// </summary>
/// <returns>The index type.</returns>
/// <remarks>
/// This method is called upon initialization of the <see cref="IndexType"/> property.
/// </remarks>
protected virtual CodeViewTypeRecord? GetIndexType() => null;

/// <summary>
/// Obtains the name type of the array.
/// </summary>
/// <returns>The name.</returns>
/// <remarks>
/// This method is called upon initialization of the <see cref="Name"/> property.
/// </remarks>
protected virtual Utf8String GetName() => Utf8String.Empty;

/// <inheritdoc />
public override string ToString() => $"{ElementType}[{Length}]";
}
62 changes: 62 additions & 0 deletions src/AsmResolver.Symbols.Pdb/Leaves/BaseClassField.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
namespace AsmResolver.Symbols.Pdb.Leaves;

/// <summary>
/// Represents a reference to a base class object in a structure.
/// </summary>
public class BaseClassField : CodeViewField
{
private readonly LazyVariable<CodeViewTypeRecord?> _type;

/// <summary>
/// Initializes an empty base class.
/// </summary>
/// <param name="typeIndex">The type index to assign to the base class field.</param>
protected BaseClassField(uint typeIndex)
: base(typeIndex)
{
_type = new LazyVariable<CodeViewTypeRecord?>(GetBaseType);
}

/// <summary>
/// Creates a new base class field.
/// </summary>
/// <param name="type">The base type to reference.</param>
public BaseClassField(CodeViewTypeRecord type)
: base(0)
{
_type = new LazyVariable<CodeViewTypeRecord?>(type);
}

/// <inheritdoc />
public override CodeViewLeafKind LeafKind => CodeViewLeafKind.BClass;

/// <summary>
/// Gets or sets the base type that this base class is referencing.
/// </summary>
public CodeViewTypeRecord? Type
{
get => _type.Value;
set => _type.Value = value;
}

/// <summary>
/// Gets or sets the offset of the base within the class.
/// </summary>
public ulong Offset
{
get;
set;
}

/// <summary>
/// Obtains the base type that the class is referencing.
/// </summary>
/// <returns>The base type.</returns>
/// <remarks>
/// This method is called upon initialization of the <see cref="Type"/> property.
/// </remarks>
protected virtual CodeViewTypeRecord? GetBaseType() => null;

/// <inheritdoc />
public override string ToString() => Type?.ToString() ?? "<<<?>>>";
}
75 changes: 75 additions & 0 deletions src/AsmResolver.Symbols.Pdb/Leaves/BitFieldTypeRecord.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
namespace AsmResolver.Symbols.Pdb.Leaves;

/// <summary>
/// Represents a bit field type.
/// </summary>
public class BitFieldTypeRecord : CodeViewTypeRecord
{
private readonly LazyVariable<CodeViewTypeRecord?> _type;

/// <summary>
/// Initializes an empty bit field record.
/// </summary>
/// <param name="typeIndex">The type index to assign to the bit field type.</param>
protected BitFieldTypeRecord(uint typeIndex)
: base(typeIndex)
{
_type = new LazyVariable<CodeViewTypeRecord?>(GetBaseType);
}

/// <summary>
/// Creates a new bit field record.
/// </summary>
/// <param name="type">The type of the bit field.</param>
/// <param name="position">The bit index the bit field starts at.</param>
/// <param name="length">The number of bits the bit field spans.</param>
public BitFieldTypeRecord(CodeViewTypeRecord type, byte position, byte length)
: base(0)
{
_type = new LazyVariable<CodeViewTypeRecord?>(type);
Position = position;
Length = length;
}

/// <inheritdoc />
public override CodeViewLeafKind LeafKind => CodeViewLeafKind.BitField;

/// <summary>
/// Gets or sets the base type that this bit field is referencing.
/// </summary>
public CodeViewTypeRecord? Type
{
get => _type.Value;
set => _type.Value = value;
}

/// <summary>
/// Gets or sets the bit index that this bit fields starts at.
/// </summary>
public byte Position
{
get;
set;
}

/// <summary>
/// Gets or sets the number of bits that this bit fields spans.
/// </summary>
public byte Length
{
get;
set;
}

/// <summary>
/// Obtains the base type that the bit field is referencing.
/// </summary>
/// <returns>The base type.</returns>
/// <remarks>
/// This method is called upon initialization of the <see cref="Type"/> property.
/// </remarks>
protected virtual CodeViewTypeRecord? GetBaseType() => null;

/// <inheritdoc />
public override string ToString() => $"{Type} : {Length}";
}
Loading

0 comments on commit 1c1768d

Please sign in to comment.