{"id":3317,"date":"2011-05-27T12:31:00","date_gmt":"2011-05-27T12:31:00","guid":{"rendered":"https:\/\/test.simple-talk.com\/uncategorized\/anatomy-of-a-net-assembly-signature-encodings\/"},"modified":"2016-07-28T10:50:26","modified_gmt":"2016-07-28T10:50:26","slug":"anatomy-of-a-net-assembly-signature-encodings","status":"publish","type":"post","link":"https:\/\/www.red-gate.com\/simple-talk\/blogs\/anatomy-of-a-net-assembly-signature-encodings\/","title":{"rendered":"Anatomy of a .NET Assembly &#8211; Signature encodings"},"content":{"rendered":"<p>If you&#8217;ve just joined this series, I highly recommend you read the previous posts in this series, starting <a href=\"https:\/\/www.simple-talk.com\/community\/blogs\/simonc\/archive\/2011\/03\/15\/100802.aspx\">here<\/a>, or at least <a href=\"https:\/\/www.simple-talk.com\/community\/blogs\/simonc\/archive\/2011\/03\/16\/100839.aspx\">these<\/a> <a href=\"https:\/\/www.simple-talk.com\/community\/blogs\/simonc\/archive\/2011\/03\/18\/100867.aspx\">posts<\/a>, covering the CLR metadata tables.<\/p>\n<p>Before we look at custom attribute encoding, we first need to have a brief look at how signatures are encoded in an assembly in general.<\/p>\n<h4>Signature types<\/h4>\n<p>There are several types of signatures in an assembly, all of which share a common base representation, and are all stored as binary blobs in the <code>#Blob<\/code> heap, referenced by an offset from various metadata tables.<\/p>\n<p>The types of signatures are: <\/p>\n<ul>\n<li>Method definition and method reference signatures.<\/li>\n<li>Field signatures<\/li>\n<li>Property signatures<\/li>\n<li>Method local variables. These are referenced from the <code>StandAloneSig<\/code> table, which is then referenced by method body headers.<\/li>\n<li>Generic type specifications. These represent a particular instantiation of a generic type.<\/li>\n<li>Generic method specifications. Similarly, these represent a particular instantiation of a generic method.<\/li>\n<\/ul>\n<p> All these signatures share the same underlying mechanism to represent a type<\/p>\n<h4>Representing a type<\/h4>\n<p>All metadata signatures are based around the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms232600.aspx\"><code>ELEMENT_TYPE<\/code><\/a> structure. This assigns a number to each &#8216;built-in&#8217; type in the framework; for example, <code>Uint16<\/code> is <code>0x07<\/code>, <code>String<\/code> is <code>0x0e<\/code>, and <code>Object<\/code> is <code>0x1c<\/code>. Byte codes are also used to indicate SzArrays, multi-dimensional arrays, custom types, and generic type and method variables. However, these require some further information.<\/p>\n<p>Firstly, custom types (ie not one of the built-in types). These require you to specify the 4-byte <code>TypeDefOrRef<\/code> coded token after the <code>CLASS<\/code> (<code>0x12<\/code>) or <code>VALUETYPE<\/code> (<code>0x11<\/code>) element type. This 4-byte value is stored in a compressed format before being written out to disk (for more excruciating details, you can refer to the CLI specification).<\/p>\n<p>SzArrays simply have the array item type after the <code>SZARRAY<\/code> byte (<code>0x1d<\/code>). Multidimensional arrays follow the <code>ARRAY<\/code> element type with a series of compressed integers indicating the number of dimensions, and the size and lower bound of each dimension.<\/p>\n<p>Generic variables are simply followed by the index of the generic variable they refer to.<\/p>\n<p>There are other additions as well, for example, a specific byte value indicates a method parameter passed by reference (<code>BYREF<\/code>), and other values indicating <a href=\"https:\/\/www.simple-talk.com\/community\/blogs\/simonc\/archive\/2010\/11\/26\/95864.aspx\">custom modifiers<\/a>.  <\/p>\n<h4>Some examples&#8230;<\/h4>\n<p>To demonstrate, here&#8217;s a few examples and what the resulting blobs in the <code>#Blob<\/code> heap will look like. Each name in capitals corresponds to a particular byte value in the <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms232600.aspx\"><code>ELEMENT_TYPE<\/code><\/a> or <a href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/ms231239.aspx\"><code>CALLCONV<\/code><\/a> structure, and coded tokens to custom types are represented by the type name in curly brackets.<\/p>\n<ul>\n<li>A simple field:\n<pre>int intField;\n\nFIELD I4<\/pre>\n<\/li>\n<li>A field of an array of a generic type parameter (assuming <code>T<\/code> is the first generic parameter of the containing type):\n<pre>T[] genArrayField\n\nFIELD SZARRAY VAR 0<\/pre>\n<\/li>\n<li>An instance method signature (note how the number of parameters does not include the return type):\n<pre>instance string MyMethod(MyType, int&amp;, bool[][]);\n\nHASTHIS DEFAULT 3\n    STRING\n    CLASS {MyType}\n    BYREF I4\n    SZARRAY SZARRAY BOOLEAN<\/pre>\n<\/li>\n<li>A generic type instantiation:\n<pre>MyGenericType&lt;MyType, MyStruct&gt;\n\nGENERICINST CLASS {MyGenericType} 2\n    CLASS {MyType}\n    VALUETYPE {MyStruct}<\/pre>\n<\/li>\n<li>For more complicated examples, in the following C# type declaration:\n<pre>GenericType&lt;T&gt; : GenericBaseType&lt;object[], T, GenericType&lt;T&gt;&gt; { ... }<\/pre>\n<p> the Extends field of the <code>TypeDef<\/code> for GenericType will point to a <code>TypeSpec<\/code> with the following blob: <\/p>\n<pre>GENERICINST CLASS {GenericBaseType} 3\n    SZARRAY OBJECT\n    VAR 0\n    GENERICINST CLASS {GenericType} 1\n        VAR 0<\/pre>\n<\/li>\n<li>And a static generic method signature (generic parameters on types are referenced using <code>VAR<\/code>, generic parameters on methods using <code>MVAR<\/code>):\n<pre>TResult[] GenericMethod&lt;TInput, TResult&gt;(\n    TInput,\n    System.Converter&lt;TInput, TOutput&gt;);\n\nGENERIC 2 2\n    SZARRAY MVAR 1\n    MVAR 0\n    GENERICINST CLASS {System.Converter} 2\n        MVAR 0\n        MVAR 1<\/pre>\n<\/li>\n<\/ul>\n<p>As you can see, complicated signatures are recursively built up out of quite simple building blocks to represent all the possible variations in a .NET assembly.<\/p>\n<p>Now we&#8217;ve looked at the basics of normal method signatures, in my next post I&#8217;ll look at custom attribute application signatures, and how they are different to normal signatures.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>If you&#8217;ve just joined this series, I highly recommend you read the previous posts in this series, starting here, or at least these posts, covering the CLR metadata tables. Before we look at custom attribute encoding, we first need to have a brief look at how signatures are encoded in an assembly in general. Signature&#8230;&hellip;<\/p>\n","protected":false},"author":186659,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[2],"tags":[],"coauthors":[],"class_list":["post-3317","post","type-post","status-publish","format-standard","hentry","category-blogs"],"acf":[],"_links":{"self":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3317","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/users\/186659"}],"replies":[{"embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/comments?post=3317"}],"version-history":[{"count":2,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3317\/revisions"}],"predecessor-version":[{"id":42040,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/posts\/3317\/revisions\/42040"}],"wp:attachment":[{"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/media?parent=3317"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/categories?post=3317"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/tags?post=3317"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.red-gate.com\/simple-talk\/wp-json\/wp\/v2\/coauthors?post=3317"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}