github.com/saferwall/pe@v1.5.2/dotnet_metadata_tables.go (about)

     1  // Copyright 2018 Saferwall. All rights reserved.
     2  // Use of this source code is governed by Apache v2 license
     3  // license that can be found in the LICENSE file.
     4  
     5  package pe
     6  
     7  // the struct definition and comments are from the ECMA-335 spec 6th edition
     8  // https://www.ecma-international.org/wp-content/uploads/ECMA-335_6th_edition_june_2012.pdf
     9  
    10  // Module 0x00
    11  type ModuleTableRow struct {
    12  	// a 2-byte value, reserved, shall be zero
    13  	Generation uint16 `json:"generation"`
    14  	// an index into the String heap
    15  	Name uint32 `json:"name"`
    16  	// an index into the Guid heap; simply a Guid used to distinguish between
    17  	// two versions of the same module
    18  	Mvid uint32 `json:"mvid"`
    19  	// an index into the Guid heap; reserved, shall be zero
    20  	EncID uint32 `json:"enc_id"`
    21  	// an index into the Guid heap; reserved, shall be zero
    22  	EncBaseID uint32 `json:"enc_base_id"`
    23  }
    24  
    25  // Module 0x00
    26  func (pe *File) parseMetadataModuleTable(off uint32) ([]ModuleTableRow, uint32, error) {
    27  	var err error
    28  	var indexSize uint32
    29  	var n uint32
    30  
    31  	rowCount := int(pe.CLR.MetadataTables[Module].CountCols)
    32  	rows := make([]ModuleTableRow, rowCount)
    33  	for i := 0; i < rowCount; i++ {
    34  		if rows[i].Generation, err = pe.ReadUint16(off); err != nil {
    35  			return rows, n, err
    36  		}
    37  		off += 2
    38  		n += 2
    39  
    40  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
    41  			return rows, n, err
    42  		}
    43  		off += indexSize
    44  		n += indexSize
    45  
    46  		if indexSize, err = pe.readFromMetadataStream(idxGUID, off, &rows[i].Mvid); err != nil {
    47  			return rows, n, err
    48  		}
    49  		off += indexSize
    50  		n += indexSize
    51  
    52  		if indexSize, err = pe.readFromMetadataStream(idxGUID, off, &rows[i].EncID); err != nil {
    53  			return rows, n, err
    54  		}
    55  		off += indexSize
    56  		n += indexSize
    57  
    58  		if indexSize, err = pe.readFromMetadataStream(idxGUID, off, &rows[i].EncBaseID); err != nil {
    59  			return rows, n, err
    60  		}
    61  		off += indexSize
    62  		n += indexSize
    63  	}
    64  	return rows, n, nil
    65  }
    66  
    67  // TypeRef 0x01
    68  type TypeRefTableRow struct {
    69  	// an index into a Module, ModuleRef, AssemblyRef or TypeRef table, or null;
    70  	// more precisely, a ResolutionScope (§II.24.2.6) coded index.
    71  	ResolutionScope uint32 `json:"resolution_scope"`
    72  	// an index into the String heap
    73  	TypeName uint32 `json:"type_name"`
    74  	// an index into the String heap
    75  	TypeNamespace uint32 `json:"type_namespace"`
    76  }
    77  
    78  // TypeRef 0x01
    79  func (pe *File) parseMetadataTypeRefTable(off uint32) ([]TypeRefTableRow, uint32, error) {
    80  	var err error
    81  	var indexSize uint32
    82  	var n uint32
    83  
    84  	rowCount := int(pe.CLR.MetadataTables[TypeRef].CountCols)
    85  	rows := make([]TypeRefTableRow, rowCount)
    86  	for i := 0; i < rowCount; i++ {
    87  		if indexSize, err = pe.readFromMetadataStream(idxResolutionScope, off, &rows[i].ResolutionScope); err != nil {
    88  			return rows, n, err
    89  		}
    90  		off += indexSize
    91  		n += indexSize
    92  
    93  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].TypeName); err != nil {
    94  			return rows, n, err
    95  		}
    96  		off += indexSize
    97  		n += indexSize
    98  
    99  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].TypeNamespace); err != nil {
   100  			return rows, n, err
   101  		}
   102  		off += indexSize
   103  		n += indexSize
   104  	}
   105  	return rows, n, nil
   106  }
   107  
   108  // TypeDef 0x02
   109  type TypeDefTableRow struct {
   110  	// a 4-byte bitmask of type TypeAttributes, §II.23.1.15
   111  	Flags uint32 `json:"flags"`
   112  	// an index into the String heap
   113  	TypeName uint32 `json:"type_name"`
   114  	// an index into the String heap
   115  	TypeNamespace uint32 `json:"type_namespace"`
   116  	// an index into the TypeDef, TypeRef, or TypeSpec table; more precisely,
   117  	// a TypeDefOrRef (§II.24.2.6) coded index
   118  	Extends uint32 `json:"extends"`
   119  	// an index into the Field table; it marks the first of a contiguous run
   120  	// of Fields owned by this Type
   121  	FieldList uint32 `json:"field_list"`
   122  	// an index into the MethodDef table; it marks the first of a contiguous
   123  	// run of Methods owned by this Type
   124  	MethodList uint32 `json:"method_list"`
   125  }
   126  
   127  // TypeDef 0x02
   128  func (pe *File) parseMetadataTypeDefTable(off uint32) ([]TypeDefTableRow, uint32, error) {
   129  	var err error
   130  	var indexSize uint32
   131  	var n uint32
   132  
   133  	rowCount := int(pe.CLR.MetadataTables[TypeDef].CountCols)
   134  	rows := make([]TypeDefTableRow, rowCount)
   135  	for i := 0; i < rowCount; i++ {
   136  		if rows[i].Flags, err = pe.ReadUint32(off); err != nil {
   137  			return rows, n, err
   138  		}
   139  		off += 4
   140  		n += 4
   141  
   142  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].TypeName); err != nil {
   143  			return rows, n, err
   144  		}
   145  		off += indexSize
   146  		n += indexSize
   147  
   148  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].TypeNamespace); err != nil {
   149  			return rows, n, err
   150  		}
   151  		off += indexSize
   152  		n += indexSize
   153  
   154  		if indexSize, err = pe.readFromMetadataStream(idxTypeDefOrRef, off, &rows[i].Extends); err != nil {
   155  			return rows, n, err
   156  		}
   157  		off += indexSize
   158  		n += indexSize
   159  
   160  		if indexSize, err = pe.readFromMetadataStream(idxField, off, &rows[i].FieldList); err != nil {
   161  			return rows, n, err
   162  		}
   163  		off += indexSize
   164  		n += indexSize
   165  
   166  		if indexSize, err = pe.readFromMetadataStream(idxMethodDef, off, &rows[i].MethodList); err != nil {
   167  			return rows, n, err
   168  		}
   169  		off += indexSize
   170  		n += indexSize
   171  	}
   172  	return rows, n, nil
   173  }
   174  
   175  // Field 0x04
   176  type FieldTableRow struct {
   177  	// a 2-byte bitmask of type FieldAttributes, §II.23.1.5
   178  	Flags uint16 `json:"flags"`
   179  	// an index into the String heap
   180  	Name uint32 `json:"name"`
   181  	// an index into the Blob heap
   182  	Signature uint32 `json:"signature"`
   183  }
   184  
   185  // Field 0x04
   186  func (pe *File) parseMetadataFieldTable(off uint32) ([]FieldTableRow, uint32, error) {
   187  	var err error
   188  	var indexSize uint32
   189  	var n uint32
   190  
   191  	rowCount := int(pe.CLR.MetadataTables[Field].CountCols)
   192  	rows := make([]FieldTableRow, rowCount)
   193  	for i := 0; i < rowCount; i++ {
   194  		if rows[i].Flags, err = pe.ReadUint16(off); err != nil {
   195  			return rows, n, err
   196  		}
   197  		off += 2
   198  		n += 2
   199  
   200  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
   201  			return rows, n, err
   202  		}
   203  		off += indexSize
   204  		n += indexSize
   205  
   206  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].Signature); err != nil {
   207  			return rows, n, err
   208  		}
   209  		off += indexSize
   210  		n += indexSize
   211  	}
   212  	return rows, n, nil
   213  }
   214  
   215  // MethodDef 0x06
   216  type MethodDefTableRow struct {
   217  	// a 4-byte constant
   218  	RVA uint32 `json:"rva"`
   219  	// a 2-byte bitmask of type MethodImplAttributes, §II.23.1.10
   220  	ImplFlags uint16 `json:"impl_flags"`
   221  	// a 2-byte bitmask of type MethodAttributes, §II.23.1.10
   222  	Flags uint16 `json:"flags"`
   223  	// an index into the String heap
   224  	Name uint32 `json:"name"`
   225  	// an index into the Blob heap
   226  	Signature uint32 `json:"signature"`
   227  	// an index into the Param table
   228  	ParamList uint32 `json:"param_list"`
   229  }
   230  
   231  // MethodDef 0x06
   232  func (pe *File) parseMetadataMethodDefTable(off uint32) ([]MethodDefTableRow, uint32, error) {
   233  	var err error
   234  	var indexSize uint32
   235  	var n uint32
   236  
   237  	rowCount := int(pe.CLR.MetadataTables[MethodDef].CountCols)
   238  	rows := make([]MethodDefTableRow, rowCount)
   239  	for i := 0; i < rowCount; i++ {
   240  		if rows[i].RVA, err = pe.ReadUint32(off); err != nil {
   241  			return rows, n, err
   242  		}
   243  		off += 4
   244  		n += 4
   245  
   246  		if rows[i].ImplFlags, err = pe.ReadUint16(off); err != nil {
   247  			return rows, n, err
   248  		}
   249  		off += 2
   250  		n += 2
   251  
   252  		if rows[i].Flags, err = pe.ReadUint16(off); err != nil {
   253  			return rows, n, err
   254  		}
   255  		off += 2
   256  		n += 2
   257  
   258  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
   259  			return rows, n, err
   260  		}
   261  		off += indexSize
   262  		n += indexSize
   263  
   264  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].Signature); err != nil {
   265  			return rows, n, err
   266  		}
   267  		off += indexSize
   268  		n += indexSize
   269  
   270  		if indexSize, err = pe.readFromMetadataStream(idxParam, off, &rows[i].ParamList); err != nil {
   271  			return rows, n, err
   272  		}
   273  		off += indexSize
   274  		n += indexSize
   275  	}
   276  	return rows, n, nil
   277  }
   278  
   279  // Param 0x08
   280  type ParamTableRow struct {
   281  	// a 2-byte bitmask of type ParamAttributes, §II.23.1.13
   282  	Flags uint16 `json:"flags"`
   283  	// a 2-byte constant
   284  	Sequence uint16 `json:"sequence"`
   285  	// an index into the String heap
   286  	Name uint32 `json:"name"`
   287  }
   288  
   289  // Param 0x08
   290  func (pe *File) parseMetadataParamTable(off uint32) ([]ParamTableRow, uint32, error) {
   291  	var err error
   292  	var indexSize uint32
   293  	var n uint32
   294  
   295  	rowCount := int(pe.CLR.MetadataTables[Param].CountCols)
   296  	rows := make([]ParamTableRow, rowCount)
   297  	for i := 0; i < rowCount; i++ {
   298  		if rows[i].Flags, err = pe.ReadUint16(off); err != nil {
   299  			return rows, n, err
   300  		}
   301  		off += 2
   302  		n += 2
   303  
   304  		if rows[i].Sequence, err = pe.ReadUint16(off); err != nil {
   305  			return rows, n, err
   306  		}
   307  		off += 2
   308  		n += 2
   309  
   310  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
   311  			return rows, n, err
   312  		}
   313  		off += indexSize
   314  		n += indexSize
   315  	}
   316  	return rows, n, nil
   317  }
   318  
   319  // InterfaceImpl 0x09
   320  type InterfaceImplTableRow struct {
   321  	// an index into the TypeDef table
   322  	Class uint32 `json:"class"`
   323  	// an index into the TypeDef, TypeRef, or TypeSpec table; more precisely,
   324  	// a TypeDefOrRef (§II.24.2.6) coded index
   325  	Interface uint32 `json:"interface"`
   326  }
   327  
   328  // InterfaceImpl 0x09
   329  func (pe *File) parseMetadataInterfaceImplTable(off uint32) ([]InterfaceImplTableRow, uint32, error) {
   330  	var err error
   331  	var indexSize uint32
   332  	var n uint32
   333  
   334  	rowCount := int(pe.CLR.MetadataTables[InterfaceImpl].CountCols)
   335  	rows := make([]InterfaceImplTableRow, rowCount)
   336  	for i := 0; i < rowCount; i++ {
   337  		if indexSize, err = pe.readFromMetadataStream(idxTypeDef, off, &rows[i].Class); err != nil {
   338  			return rows, n, err
   339  		}
   340  		off += indexSize
   341  		n += indexSize
   342  
   343  		if indexSize, err = pe.readFromMetadataStream(idxTypeDefOrRef, off, &rows[i].Interface); err != nil {
   344  			return rows, n, err
   345  		}
   346  		off += indexSize
   347  		n += indexSize
   348  	}
   349  	return rows, n, nil
   350  }
   351  
   352  // MembersRef 0x0a
   353  type MemberRefTableRow struct {
   354  	// an index into the MethodDef, ModuleRef,TypeDef, TypeRef, or TypeSpec
   355  	// tables; more precisely, a MemberRefParent (§II.24.2.6) coded index
   356  	Class uint32 `json:"class"`
   357  	// // an index into the String heap
   358  	Name uint32 `json:"name"`
   359  	// an index into the Blob heap
   360  	Signature uint32 `json:"signature"`
   361  }
   362  
   363  // MembersRef 0x0a
   364  func (pe *File) parseMetadataMemberRefTable(off uint32) ([]MemberRefTableRow, uint32, error) {
   365  	var err error
   366  	var indexSize uint32
   367  	var n uint32
   368  
   369  	rowCount := int(pe.CLR.MetadataTables[MemberRef].CountCols)
   370  	rows := make([]MemberRefTableRow, rowCount)
   371  	for i := 0; i < rowCount; i++ {
   372  		if indexSize, err = pe.readFromMetadataStream(idxMemberRefParent, off, &rows[i].Class); err != nil {
   373  			return rows, n, err
   374  		}
   375  		off += indexSize
   376  		n += indexSize
   377  
   378  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
   379  			return rows, n, err
   380  		}
   381  		off += indexSize
   382  		n += indexSize
   383  
   384  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].Signature); err != nil {
   385  			return rows, n, err
   386  		}
   387  		off += indexSize
   388  		n += indexSize
   389  
   390  	}
   391  	return rows, n, nil
   392  }
   393  
   394  // Constant 0x0b
   395  type ConstantTableRow struct {
   396  	// a 1-byte constant, followed by a 1-byte padding zero
   397  	Type uint8 `json:"type"`
   398  	// padding zero
   399  	Padding uint8 `json:"padding"`
   400  	// padding zero
   401  	// an index into the Param, Field, or Property table; more precisely,
   402  	// a HasConstant (§II.24.2.6) coded index
   403  	Parent uint32 `json:"parent"`
   404  	// an index into the Blob heap
   405  	Value uint32 `json:"value"`
   406  }
   407  
   408  // Constant 0x0b
   409  func (pe *File) parseMetadataConstantTable(off uint32) ([]ConstantTableRow, uint32, error) {
   410  	var err error
   411  	var indexSize uint32
   412  	var n uint32
   413  
   414  	rowCount := int(pe.CLR.MetadataTables[Constant].CountCols)
   415  	rows := make([]ConstantTableRow, rowCount)
   416  	for i := 0; i < rowCount; i++ {
   417  		if rows[i].Type, err = pe.ReadUint8(off); err != nil {
   418  			return rows, n, err
   419  		}
   420  		off += 1
   421  		n += 1
   422  
   423  		if rows[i].Padding, err = pe.ReadUint8(off); err != nil {
   424  			return rows, n, err
   425  		}
   426  		off += 1
   427  		n += 1
   428  
   429  		if indexSize, err = pe.readFromMetadataStream(idxHasConstant, off, &rows[i].Parent); err != nil {
   430  			return rows, n, err
   431  		}
   432  		off += indexSize
   433  		n += indexSize
   434  
   435  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].Value); err != nil {
   436  			return rows, n, err
   437  		}
   438  		off += indexSize
   439  		n += indexSize
   440  	}
   441  	return rows, n, nil
   442  }
   443  
   444  // CustomAttribute 0x0c
   445  type CustomAttributeTableRow struct {
   446  	// an index into a metadata table that has an associated HasCustomAttribute
   447  	// (§II.24.2.6) coded index
   448  	Parent uint32 `json:"parent"`
   449  	// an index into the MethodDef or MemberRef table; more precisely,
   450  	// a CustomAttributeType (§II.24.2.6) coded index
   451  	Type uint32 `json:"type"`
   452  	// an index into the Blob heap
   453  	Value uint32 `json:"value"`
   454  }
   455  
   456  // CustomAttribute 0x0c
   457  func (pe *File) parseMetadataCustomAttributeTable(off uint32) ([]CustomAttributeTableRow, uint32, error) {
   458  	var err error
   459  	var indexSize uint32
   460  	var n uint32
   461  
   462  	rowCount := int(pe.CLR.MetadataTables[CustomAttribute].CountCols)
   463  	rows := make([]CustomAttributeTableRow, rowCount)
   464  	for i := 0; i < rowCount; i++ {
   465  		if indexSize, err = pe.readFromMetadataStream(idxHasCustomAttributes, off, &rows[i].Parent); err != nil {
   466  			return rows, n, err
   467  		}
   468  		off += indexSize
   469  		n += indexSize
   470  
   471  		if indexSize, err = pe.readFromMetadataStream(idxCustomAttributeType, off, &rows[i].Type); err != nil {
   472  			return rows, n, err
   473  		}
   474  		off += indexSize
   475  		n += indexSize
   476  
   477  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].Value); err != nil {
   478  			return rows, n, err
   479  		}
   480  		off += indexSize
   481  		n += indexSize
   482  	}
   483  	return rows, n, nil
   484  }
   485  
   486  // FieldMarshal 0x0d
   487  type FieldMarshalTableRow struct {
   488  	// an index into Field or Param table; more precisely,
   489  	// a HasFieldMarshal (§II.24.2.6) coded index
   490  	Parent uint32 `json:"parent"`
   491  	// an index into the Blob heap
   492  	NativeType uint32 `json:"native_type"`
   493  }
   494  
   495  // FieldMarshal 0x0d
   496  func (pe *File) parseMetadataFieldMarshalTable(off uint32) ([]FieldMarshalTableRow, uint32, error) {
   497  	var err error
   498  	var indexSize uint32
   499  	var n uint32
   500  
   501  	rowCount := int(pe.CLR.MetadataTables[FieldMarshal].CountCols)
   502  	rows := make([]FieldMarshalTableRow, rowCount)
   503  	for i := 0; i < rowCount; i++ {
   504  		if indexSize, err = pe.readFromMetadataStream(idxHasFieldMarshall, off, &rows[i].Parent); err != nil {
   505  			return rows, n, err
   506  		}
   507  		off += indexSize
   508  		n += indexSize
   509  
   510  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].NativeType); err != nil {
   511  			return rows, n, err
   512  		}
   513  		off += indexSize
   514  		n += indexSize
   515  	}
   516  	return rows, n, nil
   517  }
   518  
   519  // DeclSecurity 0x0e
   520  type DeclSecurityTableRow struct {
   521  	// a 2-byte value
   522  	Action uint16 `json:"action"`
   523  	// an index into the TypeDef, MethodDef, or Assembly table;
   524  	// more precisely, a HasDeclSecurity (§II.24.2.6) coded index
   525  	Parent uint32 `json:"parent"`
   526  	// // an index into the Blob heap
   527  	PermissionSet uint32 `json:"permission_set"`
   528  }
   529  
   530  // DeclSecurity 0x0e
   531  func (pe *File) parseMetadataDeclSecurityTable(off uint32) ([]DeclSecurityTableRow, uint32, error) {
   532  	var err error
   533  	var indexSize uint32
   534  	var n uint32
   535  
   536  	rowCount := int(pe.CLR.MetadataTables[DeclSecurity].CountCols)
   537  	rows := make([]DeclSecurityTableRow, rowCount)
   538  	for i := 0; i < rowCount; i++ {
   539  		if rows[i].Action, err = pe.ReadUint16(off); err != nil {
   540  			return rows, n, err
   541  		}
   542  		off += 2
   543  		n += 2
   544  
   545  		if indexSize, err = pe.readFromMetadataStream(idxHasDeclSecurity, off, &rows[i].Parent); err != nil {
   546  			return rows, n, err
   547  		}
   548  		off += indexSize
   549  		n += indexSize
   550  
   551  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].PermissionSet); err != nil {
   552  			return rows, n, err
   553  		}
   554  		off += indexSize
   555  		n += indexSize
   556  	}
   557  	return rows, n, nil
   558  }
   559  
   560  // ClassLayout 0x0f
   561  type ClassLayoutTableRow struct {
   562  	// a 2-byte constant
   563  	PackingSize uint16 `json:"packing_size"`
   564  	// a 4-byte constant
   565  	ClassSize uint32 `json:"class_size"`
   566  	// an index into the TypeDef table
   567  	Parent uint32 `json:"parent"`
   568  }
   569  
   570  // ClassLayout 0x0f
   571  func (pe *File) parseMetadataClassLayoutTable(off uint32) ([]ClassLayoutTableRow, uint32, error) {
   572  	var err error
   573  	var indexSize uint32
   574  	var n uint32
   575  
   576  	rowCount := int(pe.CLR.MetadataTables[ClassLayout].CountCols)
   577  	rows := make([]ClassLayoutTableRow, rowCount)
   578  	for i := 0; i < rowCount; i++ {
   579  		if rows[i].PackingSize, err = pe.ReadUint16(off); err != nil {
   580  			return rows, n, err
   581  		}
   582  		off += 2
   583  		n += 2
   584  
   585  		if rows[i].ClassSize, err = pe.ReadUint32(off); err != nil {
   586  			return rows, n, err
   587  		}
   588  		off += 4
   589  		n += 4
   590  
   591  		if indexSize, err = pe.readFromMetadataStream(idxTypeDef, off, &rows[i].Parent); err != nil {
   592  			return rows, n, err
   593  		}
   594  		off += indexSize
   595  		n += indexSize
   596  	}
   597  	return rows, n, nil
   598  }
   599  
   600  // FieldLayout 0x10
   601  type FieldLayoutTableRow struct {
   602  	Offset uint32 `json:"offset"` // a 4-byte constant
   603  	Field  uint32 `json:"field"`  // an index into the Field table
   604  }
   605  
   606  // FieldLayout 0x10
   607  func (pe *File) parseMetadataFieldLayoutTable(off uint32) ([]FieldLayoutTableRow, uint32, error) {
   608  	var err error
   609  	var indexSize uint32
   610  	var n uint32
   611  
   612  	rowCount := int(pe.CLR.MetadataTables[FieldLayout].CountCols)
   613  	rows := make([]FieldLayoutTableRow, rowCount)
   614  	for i := 0; i < rowCount; i++ {
   615  		if rows[i].Offset, err = pe.ReadUint32(off); err != nil {
   616  			return rows, n, err
   617  		}
   618  		off += 4
   619  		n += 4
   620  
   621  		if indexSize, err = pe.readFromMetadataStream(idxField, off, &rows[i].Field); err != nil {
   622  			return rows, n, err
   623  		}
   624  		off += indexSize
   625  		n += indexSize
   626  	}
   627  	return rows, n, nil
   628  }
   629  
   630  // StandAloneSig 0x11
   631  type StandAloneSigTableRow struct {
   632  	Signature uint32 `json:"signature"` // an index into the Blob heap
   633  }
   634  
   635  // StandAloneSig 0x11
   636  func (pe *File) parseMetadataStandAloneSignTable(off uint32) ([]StandAloneSigTableRow, uint32, error) {
   637  	var err error
   638  	var indexSize uint32
   639  	var n uint32
   640  
   641  	rowCount := int(pe.CLR.MetadataTables[StandAloneSig].CountCols)
   642  	rows := make([]StandAloneSigTableRow, rowCount)
   643  	for i := 0; i < rowCount; i++ {
   644  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].Signature); err != nil {
   645  			return rows, n, err
   646  		}
   647  		off += indexSize
   648  		n += indexSize
   649  	}
   650  	return rows, n, nil
   651  }
   652  
   653  // EventMap 0x12
   654  type EventMapTableRow struct {
   655  	// an index into the TypeDef table
   656  	Parent uint32 `json:"parent"`
   657  	// an index into the Event table
   658  	EventList uint32 `json:"event_list"`
   659  }
   660  
   661  // EventMap 0x12
   662  func (pe *File) parseMetadataEventMapTable(off uint32) ([]EventMapTableRow, uint32, error) {
   663  	var err error
   664  	var indexSize uint32
   665  	var n uint32
   666  
   667  	rowCount := int(pe.CLR.MetadataTables[EventMap].CountCols)
   668  	rows := make([]EventMapTableRow, rowCount)
   669  	for i := 0; i < rowCount; i++ {
   670  		if indexSize, err = pe.readFromMetadataStream(idxTypeDef, off, &rows[i].Parent); err != nil {
   671  			return rows, n, err
   672  		}
   673  		off += indexSize
   674  		n += indexSize
   675  
   676  		if indexSize, err = pe.readFromMetadataStream(idxEvent, off, &rows[i].EventList); err != nil {
   677  			return rows, n, err
   678  		}
   679  		off += indexSize
   680  		n += indexSize
   681  
   682  	}
   683  	return rows, n, nil
   684  }
   685  
   686  // Event 0x14
   687  type EventTableRow struct {
   688  	// a 2-byte bitmask of type EventAttributes, §II.23.1.4
   689  	EventFlags uint16 `json:"event_flags"`
   690  	// an index into the String heap
   691  	Name uint32 `json:"name"`
   692  	// an index into a TypeDef, a TypeRef, or TypeSpec table; more precisely,
   693  	// a TypeDefOrRef (§II.24.2.6) coded index)
   694  	EventType uint32 `json:"event_type"`
   695  }
   696  
   697  // Event 0x14
   698  func (pe *File) parseMetadataEventTable(off uint32) ([]EventTableRow, uint32, error) {
   699  	var err error
   700  	var indexSize uint32
   701  	var n uint32
   702  
   703  	rowCount := int(pe.CLR.MetadataTables[Event].CountCols)
   704  	rows := make([]EventTableRow, rowCount)
   705  	for i := 0; i < rowCount; i++ {
   706  		if rows[i].EventFlags, err = pe.ReadUint16(off); err != nil {
   707  			return rows, n, err
   708  		}
   709  		off += 2
   710  		n += 2
   711  
   712  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
   713  			return rows, n, err
   714  		}
   715  		off += indexSize
   716  		n += indexSize
   717  
   718  		if indexSize, err = pe.readFromMetadataStream(idxTypeDefOrRef, off, &rows[i].EventType); err != nil {
   719  			return rows, n, err
   720  		}
   721  		off += indexSize
   722  		n += indexSize
   723  	}
   724  	return rows, n, nil
   725  }
   726  
   727  // PropertyMap 0x15
   728  type PropertyMapTableRow struct {
   729  	// an index	into the TypeDef table
   730  	Parent uint32 `json:"parent"`
   731  	// an index into the Property table
   732  	PropertyList uint32 `json:"property_list"`
   733  }
   734  
   735  // PropertyMap 0x15
   736  func (pe *File) parseMetadataPropertyMapTable(off uint32) ([]PropertyMapTableRow, uint32, error) {
   737  	var err error
   738  	var indexSize uint32
   739  	var n uint32
   740  
   741  	rowCount := int(pe.CLR.MetadataTables[PropertyMap].CountCols)
   742  	rows := make([]PropertyMapTableRow, rowCount)
   743  	for i := 0; i < rowCount; i++ {
   744  		if indexSize, err = pe.readFromMetadataStream(idxTypeDef, off, &rows[i].Parent); err != nil {
   745  			return rows, n, err
   746  		}
   747  		off += indexSize
   748  		n += indexSize
   749  
   750  		if indexSize, err = pe.readFromMetadataStream(idxProperty, off, &rows[i].PropertyList); err != nil {
   751  			return rows, n, err
   752  		}
   753  		off += indexSize
   754  		n += indexSize
   755  	}
   756  	return rows, n, nil
   757  }
   758  
   759  // Property 0x17
   760  type PropertyTableRow struct {
   761  	// a 2-byte bitmask of type PropertyAttributes, §II.23.1.14
   762  	Flags uint16 `json:"flags"`
   763  	// an index into the String heap
   764  	Name uint32 `json:"name"`
   765  	// an index into the Blob heap
   766  	Type uint32 `json:"type"`
   767  }
   768  
   769  // Property 0x17
   770  func (pe *File) parseMetadataPropertyTable(off uint32) ([]PropertyTableRow, uint32, error) {
   771  	var err error
   772  	var indexSize uint32
   773  	var n uint32
   774  
   775  	rowCount := int(pe.CLR.MetadataTables[Property].CountCols)
   776  	rows := make([]PropertyTableRow, rowCount)
   777  	for i := 0; i < rowCount; i++ {
   778  		if rows[i].Flags, err = pe.ReadUint16(off); err != nil {
   779  			return rows, n, err
   780  		}
   781  		off += 2
   782  		n += 2
   783  
   784  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
   785  			return rows, n, err
   786  		}
   787  		off += indexSize
   788  		n += indexSize
   789  
   790  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].Type); err != nil {
   791  			return rows, n, err
   792  		}
   793  		off += indexSize
   794  		n += indexSize
   795  	}
   796  	return rows, n, nil
   797  }
   798  
   799  // MethodSemantics 0x18
   800  type MethodSemanticsTableRow struct {
   801  	// a 2-byte bitmask of type MethodSemanticsAttributes, §II.23.1.12
   802  	Semantics uint16 `json:"semantics"`
   803  	// an index into the MethodDef table
   804  	Method uint32 `json:"method"`
   805  	// an index into the Event or Property table; more precisely,
   806  	// a HasSemantics (§II.24.2.6) coded index
   807  	Association uint32 `json:"association"`
   808  }
   809  
   810  // MethodSemantics 0x18
   811  func (pe *File) parseMetadataMethodSemanticsTable(off uint32) ([]MethodSemanticsTableRow, uint32, error) {
   812  	var err error
   813  	var indexSize uint32
   814  	var n uint32
   815  
   816  	rowCount := int(pe.CLR.MetadataTables[MethodSemantics].CountCols)
   817  	rows := make([]MethodSemanticsTableRow, rowCount)
   818  	for i := 0; i < rowCount; i++ {
   819  		if rows[i].Semantics, err = pe.ReadUint16(off); err != nil {
   820  			return rows, n, err
   821  		}
   822  		off += 2
   823  		n += 2
   824  
   825  		if indexSize, err = pe.readFromMetadataStream(idxMethodDef, off, &rows[i].Method); err != nil {
   826  			return rows, n, err
   827  		}
   828  		off += indexSize
   829  		n += indexSize
   830  
   831  		if indexSize, err = pe.readFromMetadataStream(idxHasSemantics, off, &rows[i].Association); err != nil {
   832  			return rows, n, err
   833  		}
   834  		off += indexSize
   835  		n += indexSize
   836  	}
   837  	return rows, n, nil
   838  }
   839  
   840  // MethodImpl 0x19
   841  type MethodImplTableRow struct {
   842  	// an index into the TypeDef table
   843  	Class uint32 `json:"class"`
   844  	// an index into the MethodDef or MemberRef table; more precisely, a
   845  	// MethodDefOrRef (§II.24.2.6) coded index
   846  	MethodBody uint32 `json:"method_body"`
   847  	// // an index into the MethodDef or MemberRef table; more precisely, a
   848  	// MethodDefOrRef (§II.24.2.6) coded index
   849  	MethodDeclaration uint32 `json:"method_declaration"`
   850  }
   851  
   852  // MethodImpl 0x19
   853  func (pe *File) parseMetadataMethodImplTable(off uint32) ([]MethodImplTableRow, uint32, error) {
   854  	var err error
   855  	var indexSize uint32
   856  	var n uint32
   857  
   858  	rowCount := int(pe.CLR.MetadataTables[MethodImpl].CountCols)
   859  	rows := make([]MethodImplTableRow, rowCount)
   860  	for i := 0; i < rowCount; i++ {
   861  		if indexSize, err = pe.readFromMetadataStream(idxTypeDef, off, &rows[i].Class); err != nil {
   862  			return rows, n, err
   863  		}
   864  		off += indexSize
   865  		n += indexSize
   866  
   867  		if indexSize, err = pe.readFromMetadataStream(idxMethodDefOrRef, off, &rows[i].MethodBody); err != nil {
   868  			return rows, n, err
   869  		}
   870  		off += indexSize
   871  		n += indexSize
   872  
   873  		if indexSize, err = pe.readFromMetadataStream(idxMethodDefOrRef, off, &rows[i].MethodDeclaration); err != nil {
   874  			return rows, n, err
   875  		}
   876  		off += indexSize
   877  		n += indexSize
   878  	}
   879  	return rows, n, nil
   880  }
   881  
   882  // ModuleRef 0x1a
   883  type ModuleRefTableRow struct {
   884  	// an index into the String heap
   885  	Name uint32 `json:"name"`
   886  }
   887  
   888  // ModuleRef 0x1a
   889  func (pe *File) parseMetadataModuleRefTable(off uint32) ([]ModuleRefTableRow, uint32, error) {
   890  	var err error
   891  	var indexSize uint32
   892  	var n uint32
   893  
   894  	rowCount := int(pe.CLR.MetadataTables[ModuleRef].CountCols)
   895  	rows := make([]ModuleRefTableRow, rowCount)
   896  	for i := 0; i < rowCount; i++ {
   897  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
   898  			return rows, n, err
   899  		}
   900  		off += indexSize
   901  		n += indexSize
   902  	}
   903  	return rows, n, nil
   904  }
   905  
   906  // TypeSpec 0x1b
   907  type TypeSpecTableRow struct {
   908  	// an index into the Blob heap
   909  	Signature uint32 `json:"signature"`
   910  }
   911  
   912  // TypeSpec 0x1b
   913  func (pe *File) parseMetadataTypeSpecTable(off uint32) ([]TypeSpecTableRow, uint32, error) {
   914  	var err error
   915  	var indexSize uint32
   916  	var n uint32
   917  
   918  	rowCount := int(pe.CLR.MetadataTables[TypeSpec].CountCols)
   919  	rows := make([]TypeSpecTableRow, rowCount)
   920  	for i := 0; i < rowCount; i++ {
   921  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].Signature); err != nil {
   922  			return rows, n, err
   923  		}
   924  		off += indexSize
   925  		n += indexSize
   926  	}
   927  	return rows, n, nil
   928  }
   929  
   930  // ImplMap 0x1c
   931  type ImplMapTableRow struct {
   932  	// a 2-byte bitmask of type PInvokeAttributes, §23.1.8
   933  	MappingFlags uint16 `json:"mapping_flags"`
   934  	// an index into the Field or MethodDef table; more precisely,
   935  	// a MemberForwarded (§II.24.2.6) coded index)
   936  	MemberForwarded uint32 `json:"member_forwarded"`
   937  	// an index into the String heap
   938  	ImportName uint32 `json:"import_name"`
   939  	// an index into the ModuleRef table
   940  	ImportScope uint32 `json:"import_scope"`
   941  }
   942  
   943  // ImplMap 0x1c
   944  func (pe *File) parseMetadataImplMapTable(off uint32) ([]ImplMapTableRow, uint32, error) {
   945  	var err error
   946  	var indexSize uint32
   947  	var n uint32
   948  
   949  	rowCount := int(pe.CLR.MetadataTables[ImplMap].CountCols)
   950  	rows := make([]ImplMapTableRow, rowCount)
   951  	for i := 0; i < rowCount; i++ {
   952  		if rows[i].MappingFlags, err = pe.ReadUint16(off); err != nil {
   953  			return rows, n, err
   954  		}
   955  		off += 2
   956  		n += 2
   957  
   958  		if indexSize, err = pe.readFromMetadataStream(idxMemberForwarded, off, &rows[i].MemberForwarded); err != nil {
   959  			return rows, n, err
   960  		}
   961  		off += indexSize
   962  		n += indexSize
   963  
   964  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].ImportName); err != nil {
   965  			return rows, n, err
   966  		}
   967  		off += indexSize
   968  		n += indexSize
   969  
   970  		if indexSize, err = pe.readFromMetadataStream(idxModuleRef, off, &rows[i].ImportScope); err != nil {
   971  			return rows, n, err
   972  		}
   973  		off += indexSize
   974  		n += indexSize
   975  	}
   976  	return rows, n, nil
   977  }
   978  
   979  // FieldRVA 0x1d
   980  type FieldRVATableRow struct {
   981  	// 4-byte constant
   982  	RVA uint32 `json:"rva"`
   983  	// an index into Field table
   984  	Field uint32 `json:"field"`
   985  }
   986  
   987  // FieldRVA 0x1d
   988  func (pe *File) parseMetadataFieldRVATable(off uint32) ([]FieldRVATableRow, uint32, error) {
   989  	var err error
   990  	var indexSize uint32
   991  	var n uint32
   992  
   993  	rowCount := int(pe.CLR.MetadataTables[FieldRVA].CountCols)
   994  	rows := make([]FieldRVATableRow, rowCount)
   995  	for i := 0; i < rowCount; i++ {
   996  		if rows[i].RVA, err = pe.ReadUint32(off); err != nil {
   997  			return rows, n, err
   998  		}
   999  		off += 4
  1000  		n += 4
  1001  
  1002  		if indexSize, err = pe.readFromMetadataStream(idxField, off, &rows[i].Field); err != nil {
  1003  			return rows, n, err
  1004  		}
  1005  		off += indexSize
  1006  		n += indexSize
  1007  	}
  1008  	return rows, n, nil
  1009  }
  1010  
  1011  // Assembly 0x20
  1012  type AssemblyTableRow struct {
  1013  	// a 4-byte constant of type AssemblyHashAlgorithm, §II.23.1.1
  1014  	HashAlgId uint32 `json:"hash_alg_id"`
  1015  	// a 2-byte constant
  1016  	MajorVersion uint16 `json:"major_version"`
  1017  	// a 2-byte constant
  1018  	MinorVersion uint16 `json:"minor_version"`
  1019  	// a 2-byte constant
  1020  	BuildNumber uint16 `json:"build_number"`
  1021  	// a 2-byte constant
  1022  	RevisionNumber uint16 `json:"revision_number"`
  1023  	// a 4-byte bitmask of type AssemblyFlags, §II.23.1.2
  1024  	Flags uint32 `json:"flags"`
  1025  	// an index into the Blob heap
  1026  	PublicKey uint32 `json:"public_key"`
  1027  	// an index into the String heap
  1028  	Name uint32 `json:"name"`
  1029  	// an index into the String heap
  1030  	Culture uint32 `json:"culture"`
  1031  }
  1032  
  1033  // Assembly 0x20
  1034  func (pe *File) parseMetadataAssemblyTable(off uint32) ([]AssemblyTableRow, uint32, error) {
  1035  	var err error
  1036  	var indexSize uint32
  1037  	var n uint32
  1038  
  1039  	rowCount := int(pe.CLR.MetadataTables[Assembly].CountCols)
  1040  	rows := make([]AssemblyTableRow, rowCount)
  1041  	for i := 0; i < rowCount; i++ {
  1042  		if rows[i].HashAlgId, err = pe.ReadUint32(off); err != nil {
  1043  			return rows, n, err
  1044  		}
  1045  		off += 4
  1046  		n += 4
  1047  
  1048  		if rows[i].MajorVersion, err = pe.ReadUint16(off); err != nil {
  1049  			return rows, n, err
  1050  		}
  1051  		off += 2
  1052  		n += 2
  1053  
  1054  		if rows[i].MinorVersion, err = pe.ReadUint16(off); err != nil {
  1055  			return rows, n, err
  1056  		}
  1057  		off += 2
  1058  		n += 2
  1059  
  1060  		if rows[i].BuildNumber, err = pe.ReadUint16(off); err != nil {
  1061  			return rows, n, err
  1062  		}
  1063  		off += 2
  1064  		n += 2
  1065  
  1066  		if rows[i].RevisionNumber, err = pe.ReadUint16(off); err != nil {
  1067  			return rows, n, err
  1068  		}
  1069  		off += 2
  1070  		n += 2
  1071  
  1072  		if rows[i].Flags, err = pe.ReadUint32(off); err != nil {
  1073  			return rows, n, err
  1074  		}
  1075  		off += 4
  1076  		n += 4
  1077  
  1078  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].PublicKey); err != nil {
  1079  			return rows, n, err
  1080  		}
  1081  		off += indexSize
  1082  		n += indexSize
  1083  
  1084  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
  1085  			return rows, n, err
  1086  		}
  1087  		off += indexSize
  1088  		n += indexSize
  1089  
  1090  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Culture); err != nil {
  1091  			return rows, n, err
  1092  		}
  1093  		off += indexSize
  1094  		n += indexSize
  1095  	}
  1096  	return rows, n, nil
  1097  }
  1098  
  1099  // AssemblyProcessor 0x21
  1100  type AssemblyProcessorTableRow struct {
  1101  	Processor uint32 `json:"processor"` // a 4-byte constant
  1102  }
  1103  
  1104  // AssemblyOS 0x22
  1105  type AssemblyOSTableRow struct {
  1106  	OSPlatformID   uint32 `json:"os_platform_id"`   // a 4-byte constant
  1107  	OSMajorVersion uint32 `json:"os_major_version"` // a 4-byte constant
  1108  	OSMinorVersion uint32 `json:"os_minor_version"` // a 4-byte constant
  1109  }
  1110  
  1111  // AssemblyRef 0x23
  1112  type AssemblyRefTableRow struct {
  1113  	MajorVersion     uint16 `json:"major_version"`       // a 2-byte constant
  1114  	MinorVersion     uint16 `json:"minor_version"`       // a 2-byte constant
  1115  	BuildNumber      uint16 `json:"build_number"`        // a 2-byte constant
  1116  	RevisionNumber   uint16 `json:"revision_number"`     // a 2-byte constant
  1117  	Flags            uint32 `json:"flags"`               // a 4-byte bitmask of type AssemblyFlags, §II.23.1.2
  1118  	PublicKeyOrToken uint32 `json:"public_key_or_token"` // an index into the Blob heap, indicating the public key or token that identifies the author of this Assembly
  1119  	Name             uint32 `json:"name"`                // an index into the String heap
  1120  	Culture          uint32 `json:"culture"`             // an index into the String heap
  1121  	HashValue        uint32 `json:"hash_value"`          // an index into the Blob heap
  1122  }
  1123  
  1124  // AssemblyRef 0x23
  1125  func (pe *File) parseMetadataAssemblyRefTable(off uint32) ([]AssemblyRefTableRow, uint32, error) {
  1126  	var err error
  1127  	var indexSize uint32
  1128  	var n uint32
  1129  
  1130  	rowCount := int(pe.CLR.MetadataTables[AssemblyRef].CountCols)
  1131  	rows := make([]AssemblyRefTableRow, rowCount)
  1132  	for i := 0; i < rowCount; i++ {
  1133  		if rows[i].MajorVersion, err = pe.ReadUint16(off); err != nil {
  1134  			return rows, n, err
  1135  		}
  1136  		off += 2
  1137  		n += 2
  1138  
  1139  		if rows[i].MinorVersion, err = pe.ReadUint16(off); err != nil {
  1140  			return rows, n, err
  1141  		}
  1142  		off += 2
  1143  		n += 2
  1144  
  1145  		if rows[i].BuildNumber, err = pe.ReadUint16(off); err != nil {
  1146  			return rows, n, err
  1147  		}
  1148  		off += 2
  1149  		n += 2
  1150  
  1151  		if rows[i].RevisionNumber, err = pe.ReadUint16(off); err != nil {
  1152  			return rows, n, err
  1153  		}
  1154  		off += 2
  1155  		n += 2
  1156  
  1157  		if rows[i].Flags, err = pe.ReadUint32(off); err != nil {
  1158  			return rows, n, err
  1159  		}
  1160  		off += 4
  1161  		n += 4
  1162  
  1163  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].PublicKeyOrToken); err != nil {
  1164  			return rows, n, err
  1165  		}
  1166  		off += indexSize
  1167  		n += indexSize
  1168  
  1169  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
  1170  			return rows, n, err
  1171  		}
  1172  		off += indexSize
  1173  		n += indexSize
  1174  
  1175  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Culture); err != nil {
  1176  			return rows, n, err
  1177  		}
  1178  		off += indexSize
  1179  		n += indexSize
  1180  
  1181  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].HashValue); err != nil {
  1182  			return rows, n, err
  1183  		}
  1184  		off += indexSize
  1185  		n += indexSize
  1186  	}
  1187  	return rows, n, nil
  1188  }
  1189  
  1190  // AssemblyRefProcessor 0x24
  1191  type AssemblyRefProcessorTableRow struct {
  1192  	Processor   uint32 `json:"processor"`    // a 4-byte constant
  1193  	AssemblyRef uint32 `json:"assembly_ref"` // an index into the AssemblyRef table
  1194  }
  1195  
  1196  // AssemblyRefOS 0x25
  1197  type AssemblyRefOSTableRow struct {
  1198  	OSPlatformId   uint32 `json:"os_platform_id"`   // a 4-byte constant
  1199  	OSMajorVersion uint32 `json:"os_major_version"` // a 4-byte constant
  1200  	OSMinorVersion uint32 `json:"os_minor_version"` // a 4-byte constan)
  1201  	AssemblyRef    uint32 `json:"assembly_ref"`     // an index into the AssemblyRef table
  1202  }
  1203  
  1204  // File 0x26
  1205  type FileTableRow struct {
  1206  	Flags     uint32 `json:"flags"`      // a 4-byte bitmask of type FileAttributes, §II.23.1.6
  1207  	Name      uint32 `json:"name"`       // an index into the String heap
  1208  	HashValue uint32 `json:"hash_value"` // an index into the Blob heap
  1209  }
  1210  
  1211  // ExportedType 0x27
  1212  type ExportedTypeTableRow struct {
  1213  	Flags          uint32 `json:"flags"`          // a 4-byte bitmask of type TypeAttributes, §II.23.1.15
  1214  	TypeDefId      uint32 `json:"type_def_id"`    // a 4-byte index into a TypeDef table of another module in this Assembly
  1215  	TypeName       uint32 `json:"type_name"`      // an index into the String heap
  1216  	TypeNamespace  uint32 `json:"type_namespace"` // an index into the String heap
  1217  	Implementation uint32 `json:"implementation"` // an index (more precisely, an Implementation (§II.24.2.6) coded index
  1218  }
  1219  
  1220  // ExportedType 0x27
  1221  func (pe *File) parseMetadataExportedTypeTable(off uint32) ([]ExportedTypeTableRow, uint32, error) {
  1222  	var err error
  1223  	var indexSize uint32
  1224  	var n uint32
  1225  
  1226  	rowCount := int(pe.CLR.MetadataTables[ExportedType].CountCols)
  1227  	rows := make([]ExportedTypeTableRow, rowCount)
  1228  	for i := 0; i < rowCount; i++ {
  1229  		if rows[i].Flags, err = pe.ReadUint32(off); err != nil {
  1230  			return rows, n, err
  1231  		}
  1232  		off += 4
  1233  		n += 4
  1234  
  1235  		if rows[i].TypeDefId, err = pe.ReadUint32(off); err != nil {
  1236  			return rows, n, err
  1237  		}
  1238  		off += 4
  1239  		n += 4
  1240  
  1241  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].TypeName); err != nil {
  1242  			return rows, n, err
  1243  		}
  1244  		off += indexSize
  1245  		n += indexSize
  1246  
  1247  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].TypeNamespace); err != nil {
  1248  			return rows, n, err
  1249  		}
  1250  		off += indexSize
  1251  		n += indexSize
  1252  
  1253  		if indexSize, err = pe.readFromMetadataStream(idxImplementation, off, &rows[i].Implementation); err != nil {
  1254  			return rows, n, err
  1255  		}
  1256  		off += indexSize
  1257  		n += indexSize
  1258  	}
  1259  	return rows, n, nil
  1260  }
  1261  
  1262  // ManifestResource 0x28
  1263  type ManifestResourceTableRow struct {
  1264  	Offset         uint32 `json:"offset"`         // a 4-byte constant
  1265  	Flags          uint32 `json:"flags"`          // a 4-byte bitmask of type ManifestResourceAttributes, §II.23.1.9
  1266  	Name           uint32 `json:"name"`           // an index into the String heap
  1267  	Implementation uint32 `json:"implementation"` // an index into a File table, a AssemblyRef table, or null; more precisely, an Implementation (§II.24.2.6) coded index
  1268  }
  1269  
  1270  // ManifestResource 0x28
  1271  func (pe *File) parseMetadataManifestResourceTable(off uint32) ([]ManifestResourceTableRow, uint32, error) {
  1272  	var err error
  1273  	var indexSize uint32
  1274  	var n uint32
  1275  
  1276  	rowCount := int(pe.CLR.MetadataTables[ManifestResource].CountCols)
  1277  	rows := make([]ManifestResourceTableRow, rowCount)
  1278  	for i := 0; i < rowCount; i++ {
  1279  		if rows[i].Offset, err = pe.ReadUint32(off); err != nil {
  1280  			return rows, n, err
  1281  		}
  1282  		off += 4
  1283  		n += 4
  1284  
  1285  		if rows[i].Flags, err = pe.ReadUint32(off); err != nil {
  1286  			return rows, n, err
  1287  		}
  1288  		off += 4
  1289  		n += 4
  1290  
  1291  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
  1292  			return rows, n, err
  1293  		}
  1294  		off += indexSize
  1295  		n += indexSize
  1296  
  1297  		if indexSize, err = pe.readFromMetadataStream(idxImplementation, off, &rows[i].Implementation); err != nil {
  1298  			return rows, n, err
  1299  		}
  1300  		off += indexSize
  1301  		n += indexSize
  1302  	}
  1303  	return rows, n, nil
  1304  }
  1305  
  1306  // NestedClass 0x29
  1307  type NestedClassTableRow struct {
  1308  	NestedClass    uint32 `json:"nested_class"`    // an index into the TypeDef table
  1309  	EnclosingClass uint32 `json:"enclosing_class"` // an index into the TypeDef table
  1310  }
  1311  
  1312  // NestedClass 0x29
  1313  func (pe *File) parseMetadataNestedClassTable(off uint32) ([]NestedClassTableRow, uint32, error) {
  1314  	var err error
  1315  	var indexSize uint32
  1316  	var n uint32
  1317  
  1318  	rowCount := int(pe.CLR.MetadataTables[NestedClass].CountCols)
  1319  	rows := make([]NestedClassTableRow, rowCount)
  1320  	for i := 0; i < rowCount; i++ {
  1321  		if indexSize, err = pe.readFromMetadataStream(idxTypeDef, off, &rows[i].NestedClass); err != nil {
  1322  			return rows, n, err
  1323  		}
  1324  		off += indexSize
  1325  		n += indexSize
  1326  
  1327  		if indexSize, err = pe.readFromMetadataStream(idxTypeDef, off, &rows[i].EnclosingClass); err != nil {
  1328  			return rows, n, err
  1329  		}
  1330  		off += indexSize
  1331  		n += indexSize
  1332  	}
  1333  	return rows, n, nil
  1334  }
  1335  
  1336  // GenericParam 0x2a
  1337  type GenericParamTableRow struct {
  1338  	Number uint16 `json:"number"` // the 2-byte index of the generic parameter, numbered left-to-right, from zero
  1339  	Flags  uint16 `json:"flags"`  // a 2-byte bitmask of type GenericParamAttributes, §II.23.1.7
  1340  	Owner  uint32 `json:"owner"`  // an index into the TypeDef or MethodDef table, specifying the Type or Method to which this generic parameter applies; more precisely, a TypeOrMethodDef (§II.24.2.6) coded index
  1341  	Name   uint32 `json:"name"`   // a non-null index into the String heap, giving the name for the generic parameter
  1342  }
  1343  
  1344  // GenericParam 0x2a
  1345  func (pe *File) parseMetadataGenericParamTable(off uint32) ([]GenericParamTableRow, uint32, error) {
  1346  	var err error
  1347  	var indexSize uint32
  1348  	var n uint32
  1349  
  1350  	rowCount := int(pe.CLR.MetadataTables[GenericParam].CountCols)
  1351  	rows := make([]GenericParamTableRow, rowCount)
  1352  	for i := 0; i < rowCount; i++ {
  1353  		if rows[i].Number, err = pe.ReadUint16(off); err != nil {
  1354  			return rows, n, err
  1355  		}
  1356  		off += 2
  1357  		n += 2
  1358  		if rows[i].Flags, err = pe.ReadUint16(off); err != nil {
  1359  			return rows, n, err
  1360  		}
  1361  		off += 2
  1362  		n += 2
  1363  
  1364  		if indexSize, err = pe.readFromMetadataStream(idxTypeOrMethodDef, off, &rows[i].Owner); err != nil {
  1365  			return rows, n, err
  1366  		}
  1367  		off += indexSize
  1368  		n += indexSize
  1369  
  1370  		if indexSize, err = pe.readFromMetadataStream(idxString, off, &rows[i].Name); err != nil {
  1371  			return rows, n, err
  1372  		}
  1373  		off += indexSize
  1374  		n += indexSize
  1375  	}
  1376  	return rows, n, nil
  1377  }
  1378  
  1379  // MethodSpec 0x2b
  1380  type MethodSpecTableRow struct {
  1381  	Method        uint32 `json:"method"`        // an index into the MethodDef or MemberRef table, specifying to which generic method this row refers; that is, which generic method this row is an instantiation of; more precisely, a MethodDefOrRef (§II.24.2.6) coded index
  1382  	Instantiation uint32 `json:"instantiation"` // an index into the Blob heap
  1383  }
  1384  
  1385  // MethodSpec 0x2b
  1386  func (pe *File) parseMetadataMethodSpecTable(off uint32) ([]MethodSpecTableRow, uint32, error) {
  1387  	var err error
  1388  	var indexSize uint32
  1389  	var n uint32
  1390  
  1391  	rowCount := int(pe.CLR.MetadataTables[MethodSpec].CountCols)
  1392  	rows := make([]MethodSpecTableRow, rowCount)
  1393  	for i := 0; i < rowCount; i++ {
  1394  		if indexSize, err = pe.readFromMetadataStream(idxMethodDefOrRef, off, &rows[i].Method); err != nil {
  1395  			return rows, n, err
  1396  		}
  1397  		off += indexSize
  1398  		n += indexSize
  1399  
  1400  		if indexSize, err = pe.readFromMetadataStream(idxBlob, off, &rows[i].Instantiation); err != nil {
  1401  			return rows, n, err
  1402  		}
  1403  		off += indexSize
  1404  		n += indexSize
  1405  	}
  1406  	return rows, n, nil
  1407  }
  1408  
  1409  // GenericParamConstraint 0x2c
  1410  type GenericParamConstraintTableRow struct {
  1411  	Owner      uint32 `json:"owner"`      // an index into the GenericParam table, specifying to which generic parameter this row refers
  1412  	Constraint uint32 `json:"constraint"` // an index into the TypeDef, TypeRef, or TypeSpec tables, specifying from which class this generic parameter is constrained to derive; or which interface this generic parameter is constrained to implement; more precisely, a TypeDefOrRef (§II.24.2.6) coded index
  1413  }
  1414  
  1415  // GenericParamConstraint 0x2c
  1416  func (pe *File) parseMetadataGenericParamConstraintTable(off uint32) ([]GenericParamConstraintTableRow, uint32, error) {
  1417  	var err error
  1418  	var indexSize uint32
  1419  	var n uint32
  1420  
  1421  	rowCount := int(pe.CLR.MetadataTables[GenericParamConstraint].CountCols)
  1422  	rows := make([]GenericParamConstraintTableRow, rowCount)
  1423  	for i := 0; i < rowCount; i++ {
  1424  		if indexSize, err = pe.readFromMetadataStream(idxGenericParam, off, &rows[i].Owner); err != nil {
  1425  			return rows, n, err
  1426  		}
  1427  		off += indexSize
  1428  		n += indexSize
  1429  
  1430  		if indexSize, err = pe.readFromMetadataStream(idxTypeDefOrRef, off, &rows[i].Constraint); err != nil {
  1431  			return rows, n, err
  1432  		}
  1433  		off += indexSize
  1434  		n += indexSize
  1435  	}
  1436  	return rows, n, nil
  1437  }