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 }