5.0.0
This marks the first major version bump since the rewrite of AsmResolver. A huge thanks to all the contributors and testers. Without them this release would not have been possible!
Summary
- Significant performance boost and memory consumption reductions across the board.
- Rudimentary read support for PDB files (both Windows PDB and Portable PDB).
- Various Quality-of-Life improvements of the API.
- Overall robustness improvements against malformed input binaries and/or edge-cases.
Full change log
New Features
- Add read / write support for PortablePDB metadata streams and tables (#348)
- Add a new WIP package called
AsmResolver.Symbols.Pdb
for reading and writing Windows PDB files using only managed code (#324, #326, #342, #368 (thanks @ds5678)) - Add the notion of
IMemberClonerListener
s, allowing for automatically post-processing cloned metadata (e.g., automatically injecting it into the target module) as the cloner is cloning metadata (#333, #337, #354, thanks @CursedLand) - Add
DotNetRuntimeInfo::IsNetCoreApp
,IsNetFramework
andIsNetStandard
properties for easily identifying whether a module targets .NET Core, .NET Framework or .NET Standard (505da7a). - Add
SignatureComparer::Default
(#366, thanks @ds5678) - Add
TypeDefinition::IsByRefLike
(#358, #362) - Make
AsmResolver.DotNet
trimmable (#304, thanks @ds5678) - Add
MetadataTable::IsSorted
property (#348) DynamicMethodDefinition
now has better support for dynamic methods that are initialized viaDynamicILInfo
(b0b13c8)- Add convenience constructors for
BinaryStreamReader
that take abyte[]
or aIDataSource
alone (54c65ee). - Add
OriginalMetadataTokenProvider
(#361) - Add
type.IsTypeOfUtf8
to avoid conversions fromUtf8String
tostring
(baf25ac)
Breaking Changes
- Make
SignatureComparer
immutable (#366, thanks @ds5678) - Refactor
class BlobReadContext
to a mutablestruct BlobReaderContext
(#356, c0283c7). - Change
ISegment::UpdateOffsets
's method signature (#236, #346) - Remove
ITlsDirectory::ImageBase
andCodeSegment::ImageBase
(#346) - Remove
SegmentReference::CanUpdateOffsets
andSegmentReference::UpdateOffsets
(#346) - Add setter to
TypeDefOrRefSignature::Type
andGenericInstanceTypeSignature::Type
(#338, thanks @JPaja) - Move
AsmResolver.DotNet.Dynamic
into a separate nuget package (#304). - Rename
Entrypoint
toEntryPoint
(b6fa3ed). - Rename
OptionalHeaderMagic::Pe32
andPe32Plus
toPE32
andPE32Plus
(d954be0). - Let
LazyVariable
lock on itself (16367c1) - Consolidate
ContinuousMetadataRange
andRedirectedMetadataRange
to a single structMetadataRange
(3bb6b6a) - Let
OneToManyRelation
return aValueSet
with a struct enumerator instead of a genericICollection
(07b09c3) - Change type of
MemberClonerContext::Importer
toCloneContextAwareReferenceImporter
. - Many constructors of metadata members taking a name parameter are now of type
Utf8String
instead ofstring
(baf25ac, 5d8cb88). - Rename
FullNameGenerator
toMemberNameGenerator
. This class has a new layout and is not API compatible with the old version (#386).
Performance Improvements
- Precomputing capacity properties for lists containing read metadata reduced memory consumption by roughly 5%-10% (#316)
- Many small buffers and temporary memory streams are being reused during the writing process where possible. This reduces the number of allocations by up to 20% (#317).
- Various reader context types are now stack allocated (#356, c0283c7).
- Custom attribute signatures are now only read when absolutely necessary, preventing many unnecessary expensive type resolutions and thus many allocations (#336, #351).
MethodImplementation
now implementsIEquatable<MethodImplementation>
, drastically reducing allocations and increasing performance for large binaries with lots of interface implementations (d10cf47).- Replace PE section lookup LINQ code with expanded for loop, drastically reducing allocations in general (1ff0a0f)
OneToManyRelation
now returns aValueSet
with a struct enumerator instead of an interface (07b09c3)- Avoid many string allocations from
Utf8String
instances when resolving types and members (baf25ac) - Avoid many allocations of traversed tokens during type signature parsing where possible, reducing memory consumption of the reader in general (c0283c7)
- Avoid duplication of
Utf8String
objects inStringStreamBuffer
(533a911) - Avoid allocation of many empty metadata value sets (especially for custom attributes), significantly reducing memory consumption (ce0a94f)
- Significantly improve performance of
member.FullName
and reduced memory consumption by up to 70% (#386)
Bug Fixes
- Modifications to a LazyList (and all its derivatives) are now guarded with locks to prevent concurrency issues (#364).
- Importing a nested type via
System.Reflection
now correctly imports the declaring type. This was especially a problem when convertingDynamicMethod
s to aDynamicMethodDefinition
. (#365) - Local variables are now properly resolved from
DynamicMethod
s initialized withDynamicILInfo
. - Reading and importing complex
COR_ELEMENT_TYPE_INTERNAL
types should be fixed. - Various CIL body parsing improvements, allowing for better recovery of invalid method body code / data (#361)
- Metadata stream selection is now properly reflecting the behavior of the runtime for both compressed and EnC metadata (#352)
- ExpandMacros correctly expands
ldarga.s
andbge.un.s
to their correct expanded forms (#322, thanks @N78750469) - Importing via Reflection of
MethodBase
s that use generic parameters of its declaring type in its signature should now be fixed. LPArrayMarshalDesriptor
now correctly respects signatures with anull
ArrayElementType (d9ef330).- Fix stack overflow when trying to compute a token of a full sized public key of an assembly reference (#381, #382)
- The
endfinally
opcode correctly clears the stack during stack analysis (eb41d58) - Sorted metadata tables are now stable sorts, ensuring order for metadata members such as custom attributes (#387)