jbevain / cecil

Cecil is a library to inspect, modify and create .NET programs and libraries.
MIT License
2.77k stars 630 forks source link

Preserve custom debug information on types #948

Closed sbomer closed 2 months ago

sbomer commented 5 months ago

Upstreaming change from https://github.com/dotnet/cecil/pull/185:

Portable PDBs may have CustomDebugInformation on many metadata entities (see HasCustomDebugInformation in https://github.com/dotnet/runtime/blob/main/docs/design/specs/PortablePdb-Metadata.md#customdebuginformation-table-0x37).

For a select few of the CustomDebugInformation kinds (for example state machine hoisted local scopes), cecil has dedicated types to represent these in the object model. For the rest, cecil just reads the custom debug info out of the blob heap as a byte[].

When writing back a module, cecil walks the metadata as represented in its object model, building the debug information as it goes.

So to support custom debug information for a new metadata token type:

  • the corresponding cecil type should be made to implement ICustomDebugInformationProvider,
  • the backing data for these getters should be populated on-demand, and also by the top-down walk in the immediate module reader, and
  • the top-down walk of metadata for writing should visit the cecil object and write its debug information.

This change implements the above for TypeDefinition. It extends the ISymbolReader/ISymbolWriter interfaces with a new method for reading/writing custom debug info for any ICustomDebugInformationProvider, and provides helpers for calling the symbol reader that can be used when adding custom debug information to other types in the future.

It doesn't include support for decoding the TypeDefinitionDocument debug info - it continues representing these as BinaryCustomDebugInformation.

Fixes https://github.com/dotnet/runtime/issues/100051.

sbomer commented 5 months ago

@jbevain note this is adding methods to the ISymbolReader and ISymbolWriter interfaces which is a breaking change for any implementors. I see we touched ISymbolWriter before (https://github.com/jbevain/cecil/pull/810#issuecomment-1012515406), but wanted to check with you if this is an OK change.

sbomer commented 5 months ago

I found an example of an implementation of ISymbolWriter outside of cecil: https://github.com/rolfbjarne/xamarin-macios/commit/53874c863996656eaba43a5582731b93eb6f53b7.

That one should be easy to fix if we update the interface, but still might change the tradeoffs here. Here's where it was updated in response to the last breaking change: https://github.com/xamarin/xamarin-macios/commit/727a29d8c9d3f52a2ed39d4e5d4548ecab2a74bc#diff-8ee2a110d03b4775ffc5e0a0fd4fdb4354cbea264f8671191ecc6e86609a232fR80

jbevain commented 2 months ago

Thanks!