Sunday, March 27, 2011

Anatomy of a .NET Assembly - Methods

Any close look at the method definitions in a .NET assembly has to start off with the method's information in the metadata tables - the MethodDef. So lets do that.

MethodDef
The MethodDef entry for the entrypoint method in my TinyAssembly example used in previous posts has the following bytes:

D0 20 00 00 00 00 91 00 47 00 0A 00 01 00

According to the CLR spec, the row is interpreted as follows:
  1. D0 20 00 00: RVA. The RVA of the method body within the assembly (0x20d0).
  2. 00 00: ImplFlags. Various flags indicating how the method is implemented. All-zeros indicate this is a pure-IL managed method.
  3. 91 00: Flags. In this example, these flags indicate this method is declared private static hidebysig.
  4. 47 00: Name. offset into #Strings heap ('Main').
  5. 0A 00: Signature. Offset into #Blob heap containing the signature (return type & parameter types) of the method. I might look at signature encodings in a later post. In this example, the bytes at this offset indicate a method with no parameters and a void return type.
  6. 01 00: ParamList. A RID to the ParamDef table with information on the method's parameters. As this method has no parameters, and there is no ParamDef table in the assembly, this is essentially ignored.
You'll notice there's no reference to the owning TypeDef within a MethodDef. In an assembly, associations like this are one-way - in order to find which type owns a particular method, you have to scan the TypeDef table until you find a type that includes the method in its method list.
Method bodies

So, a MethodDef describes the basic properties of a method - its name, signature, and implementation details. What about the actual body of a method?
Within the assembly, these are all located between the CLI header/strong name hash and the CLR metadata, as you can see:

Read more: Simple-talk