parser.go raw

   1  //go:generate stringer -trimprefix sec -type sectionID
   2  
   3  package wasm
   4  
   5  import (
   6  	"fmt"
   7  	"io"
   8  	"io/ioutil"
   9  )
  10  
  11  // magicnumber is a magic number which must appear as the very first bytes of a
  12  // wasm file.
  13  const magicnumber = 0x6d736100 // \0asm
  14  
  15  type sectionID uint8
  16  
  17  const (
  18  	secCustom    sectionID = iota // 0x00
  19  	secType                       // 0x01
  20  	secImport                     // 0x02
  21  	secFunction                   // 0x03
  22  	secTable                      // 0x04
  23  	secMemory                     // 0x05
  24  	secGlobal                     // 0x06
  25  	secExport                     // 0x07
  26  	secStart                      // 0x08
  27  	secElement                    // 0x09
  28  	secCode                       // 0x0A
  29  	secData                       // 0x0B
  30  	secDataCount                  // 0x0C
  31  )
  32  
  33  type parser struct {
  34  	r *reader
  35  }
  36  
  37  var errDone = fmt.Errorf("done")
  38  
  39  // Parse parses the input to a WASM module.
  40  func Parse(r io.Reader) (*Module, error) {
  41  	p := &parser{
  42  		r: newReader(r),
  43  	}
  44  
  45  	if err := p.parsePreamble(); err != nil {
  46  		return nil, err
  47  	}
  48  
  49  	// Parse file sections
  50  	var m Module
  51  	for {
  52  		err := p.parseSection(&m.Sections)
  53  		if err != nil {
  54  			if err == errDone {
  55  				break
  56  			}
  57  			return nil, fmt.Errorf("[0x%06x] parse section: %v", p.r.Index(), err)
  58  		}
  59  	}
  60  	return &m, nil
  61  }
  62  
  63  func (p *parser) parsePreamble() error {
  64  	var h, v uint32
  65  	if err := read(p.r, &h); err != nil {
  66  		return fmt.Errorf("could not read file header")
  67  	}
  68  	if h != magicnumber {
  69  		return fmt.Errorf("not a wasm file")
  70  	}
  71  	if err := read(p.r, &v); err != nil {
  72  		return fmt.Errorf("could not version")
  73  	}
  74  	if v != 1 {
  75  		return fmt.Errorf("unsupported version %d", v)
  76  	}
  77  	return nil
  78  }
  79  
  80  func (p *parser) parseSection(ss *[]Section) error {
  81  	var i uint8
  82  	if err := readVarUint7(p.r, &i); err != nil {
  83  		if err == io.EOF {
  84  			return errDone
  85  		}
  86  		return fmt.Errorf("read section id: %v", err)
  87  	}
  88  	sid := sectionID(i)
  89  
  90  	var s Section
  91  	var err error
  92  
  93  	base := &section{
  94  		id:   sid,
  95  		name: sid.String(),
  96  	}
  97  
  98  	if err := readVarUint32(p.r, &base.size); err != nil {
  99  		return fmt.Errorf("read type section payload length: %v", err)
 100  	}
 101  
 102  	switch sid {
 103  	case secCustom:
 104  		s, err = p.parseCustomSection(base)
 105  	case secType:
 106  		s, err = p.parseTypeSection(base)
 107  	case secImport:
 108  		s, err = p.parseImportSection(base)
 109  	case secFunction:
 110  		s, err = p.parseFunctionSection(base)
 111  	case secTable:
 112  		s, err = p.parseTableSection(base)
 113  	case secMemory:
 114  		s, err = p.parseMemorySection(base)
 115  	case secGlobal:
 116  		s, err = p.parseGlobalSection(base)
 117  	case secExport:
 118  		s, err = p.parseExportSection(base)
 119  	case secStart:
 120  		s, err = p.parseStartSection(base)
 121  	case secElement:
 122  		s, err = p.parseElementSection(base)
 123  	case secCode:
 124  		s, err = p.parseCodeSection(base)
 125  	case secData:
 126  		s, err = p.parseDataSection(base)
 127  	case secDataCount:
 128  		s, err = p.parseDataCountSection(base)
 129  	default:
 130  		if _, err := io.CopyN(ioutil.Discard, p.r, int64(base.size)); err != nil {
 131  			return fmt.Errorf("discard section payload, %d bytes: %v", base.size, err)
 132  		}
 133  		if sid > secData {
 134  			// This happens if the previous section was not read to the end,
 135  			// indicating a bug in that section parser.
 136  			return fmt.Errorf("data corrupted; section id 0x%02x not valid", uint8(sid))
 137  		}
 138  		// Skip unknown section
 139  		return nil
 140  	}
 141  	if err != nil {
 142  		return err
 143  	}
 144  
 145  	if s != nil {
 146  		*ss = append(*ss, s)
 147  	}
 148  
 149  	return nil
 150  }
 151  
 152  func (p *parser) parseCustomSection(base *section) (Section, error) {
 153  	var nl uint32
 154  	if err := readVarUint32(p.r, &nl); err != nil {
 155  		return nil, fmt.Errorf("read section name length: %v", err)
 156  	}
 157  
 158  	b := make([]byte, nl)
 159  	if err := read(p.r, &b); err != nil {
 160  		return nil, fmt.Errorf("read section name: %v", err)
 161  	}
 162  	name := string(b)
 163  
 164  	base.size -= uint32(nl)                // sizeof name
 165  	base.size -= uint32(varUint32Size(nl)) // sizeof name_len
 166  
 167  	if name == "name" {
 168  		// A name section is a special custom section meant for debugging
 169  		// purposes. It's defined in the spec so we'll parse it.
 170  		return p.parseNameSection(base, name, base.size)
 171  	}
 172  	if name == "linking" {
 173  		// A linking section is added to object files and used by the linker.
 174  		// It is defined here:
 175  		// https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md
 176  		return p.parseLinkingSection(base, name)
 177  	}
 178  
 179  	s := SectionCustom{
 180  		section:     base,
 181  		SectionName: name,
 182  	}
 183  
 184  	// set raw bytes
 185  	s.Payload = make([]byte, base.size)
 186  	if err := read(p.r, s.Payload); err != nil {
 187  		return nil, fmt.Errorf("read custom section %#v payload: %v", name, err)
 188  	}
 189  
 190  	return &s, nil
 191  }
 192  
 193  func (p *parser) parseTypeSection(base *section) (*SectionType, error) {
 194  	s := SectionType{section: base}
 195  
 196  	err := p.loopCount(func() error {
 197  		var e FuncType
 198  
 199  		if err := readVarInt7(p.r, &e.Form); err != nil {
 200  			return fmt.Errorf("read form: %v", err)
 201  		}
 202  
 203  		p.loopCount(func() error {
 204  			var param int8
 205  			if err := readVarInt7(p.r, &param); err != nil {
 206  				return fmt.Errorf("read function param type: %v", err)
 207  			}
 208  			e.Params = append(e.Params, param)
 209  			return nil
 210  		})
 211  
 212  		var rc uint8
 213  		if err := readVarUint1(p.r, &rc); err != nil {
 214  			return fmt.Errorf("read number of returns from function: %v", err)
 215  		}
 216  		e.ReturnTypes = make([]int8, rc)
 217  		for i := range e.ReturnTypes {
 218  			if err := readVarInt7(p.r, &e.ReturnTypes[i]); err != nil {
 219  				return fmt.Errorf("read function return type: %v", err)
 220  			}
 221  		}
 222  
 223  		s.Entries = append(s.Entries, e)
 224  		return nil
 225  	})
 226  	if err != nil {
 227  		return nil, err
 228  	}
 229  
 230  	return &s, nil
 231  }
 232  
 233  func (p *parser) parseImportSection(base *section) (*SectionImport, error) {
 234  	s := SectionImport{section: base}
 235  
 236  	err := p.loopCount(func() error {
 237  		var e ImportEntry
 238  
 239  		var ml uint32
 240  		if err := readVarUint32(p.r, &ml); err != nil {
 241  			return fmt.Errorf("read module length: %v", err)
 242  		}
 243  
 244  		mn := make([]byte, ml)
 245  		if err := read(p.r, mn); err != nil {
 246  			return fmt.Errorf("read module name: %v", err)
 247  		}
 248  		e.Module = string(mn)
 249  
 250  		var fl uint32
 251  		if err := readVarUint32(p.r, &fl); err != nil {
 252  			return fmt.Errorf("read field length: %v", err)
 253  		}
 254  
 255  		fn := make([]byte, fl)
 256  		if err := read(p.r, fn); err != nil {
 257  			return fmt.Errorf("read field name")
 258  		}
 259  		e.Field = string(fn)
 260  
 261  		var kind uint8
 262  		if err := read(p.r, &kind); err != nil {
 263  			return fmt.Errorf("read kind: %v", err)
 264  		}
 265  		e.Kind = ExternalKind(kind)
 266  
 267  		switch e.Kind {
 268  		case ExtKindFunction:
 269  			e.FunctionType = &FunctionType{}
 270  			if err := readVarUint32(p.r, &e.FunctionType.Index); err != nil {
 271  				return fmt.Errorf("read function type index: %v", err)
 272  			}
 273  		case ExtKindTable:
 274  			e.TableType = &TableType{}
 275  			if err := readVarInt7(p.r, &e.TableType.ElemType); err != nil {
 276  				return fmt.Errorf("read table element type: %v", err)
 277  			}
 278  
 279  			if err := p.parseResizableLimits(&e.TableType.Limits); err != nil {
 280  				return fmt.Errorf("read table resizable limits: %v", err)
 281  			}
 282  		case ExtKindMemory:
 283  			e.MemoryType = &MemoryType{}
 284  			if err := p.parseResizableLimits(&e.MemoryType.Limits); err != nil {
 285  				return fmt.Errorf("read memory resizable limits: %v", err)
 286  			}
 287  		case ExtKindGlobal:
 288  			e.GlobalType = &GlobalType{}
 289  			if err := readVarInt7(p.r, &e.GlobalType.ContentType); err != nil {
 290  				return fmt.Errorf("read global content type: %v", err)
 291  			}
 292  
 293  			var m uint8
 294  			if err := readVarUint1(p.r, &m); err != nil {
 295  				return fmt.Errorf("read global mutability: %v", err)
 296  			}
 297  			e.GlobalType.Mutable = m == 1
 298  		}
 299  
 300  		s.Entries = append(s.Entries, e)
 301  		return nil
 302  	})
 303  	if err != nil {
 304  		return nil, err
 305  	}
 306  
 307  	return &s, nil
 308  }
 309  
 310  func (p *parser) parseFunctionSection(base *section) (*SectionFunction, error) {
 311  	s := SectionFunction{section: base}
 312  
 313  	err := p.loopCount(func() error {
 314  		var t uint32
 315  		if err := readVarUint32(p.r, &t); err != nil {
 316  			return fmt.Errorf("read function type: %v", err)
 317  		}
 318  
 319  		s.Types = append(s.Types, t)
 320  		return nil
 321  	})
 322  	if err != nil {
 323  		return nil, err
 324  	}
 325  
 326  	return &s, nil
 327  }
 328  
 329  func (p *parser) parseTableSection(base *section) (*SectionTable, error) {
 330  	s := SectionTable{section: base}
 331  
 332  	err := p.loopCount(func() error {
 333  		var e TableType
 334  
 335  		if err := p.parseTableType(&e); err != nil {
 336  			return fmt.Errorf("read table type: %v", err)
 337  		}
 338  
 339  		s.Entries = append(s.Entries, e)
 340  		return nil
 341  	})
 342  	if err != nil {
 343  		return nil, err
 344  	}
 345  
 346  	return &s, nil
 347  }
 348  
 349  func (p *parser) parseMemorySection(base *section) (*SectionMemory, error) {
 350  	s := SectionMemory{section: base}
 351  
 352  	err := p.loopCount(func() error {
 353  		var e MemoryType
 354  
 355  		if err := p.parseResizableLimits(&e.Limits); err != nil {
 356  			return fmt.Errorf("read memory resizable limits: %v", err)
 357  		}
 358  
 359  		s.Entries = append(s.Entries, e)
 360  		return nil
 361  	})
 362  	if err != nil {
 363  		return nil, err
 364  	}
 365  
 366  	return &s, nil
 367  }
 368  
 369  func (p *parser) parseGlobalSection(base *section) (*SectionGlobal, error) {
 370  	s := SectionGlobal{section: base}
 371  
 372  	err := p.loopCount(func() error {
 373  		var e GlobalVariable
 374  
 375  		if err := readVarInt7(p.r, &e.Type.ContentType); err != nil {
 376  			return fmt.Errorf("read global content type: %v", err)
 377  		}
 378  
 379  		if err := read(p.r, &e.Type.Mutable); err != nil {
 380  			return fmt.Errorf("read global mutability: %v", err)
 381  		}
 382  
 383  		if err := readInitExpr(p.r, &e.Init); err != nil {
 384  			return fmt.Errorf("read global init expression: %v", err)
 385  		}
 386  
 387  		s.Globals = append(s.Globals, e)
 388  		return nil
 389  	})
 390  	if err != nil {
 391  		return nil, err
 392  	}
 393  
 394  	return &s, nil
 395  }
 396  
 397  func (p *parser) parseExportSection(base *section) (*SectionExport, error) {
 398  	s := SectionExport{section: base}
 399  
 400  	err := p.loopCount(func() error {
 401  		var e ExportEntry
 402  
 403  		var fl uint32
 404  		if err := readVarUint32(p.r, &fl); err != nil {
 405  			return fmt.Errorf("read field length: %v", err)
 406  		}
 407  
 408  		f := make([]byte, fl)
 409  		if err := read(p.r, f); err != nil {
 410  			return fmt.Errorf("read field")
 411  		}
 412  		e.Field = string(f)
 413  
 414  		var kind uint8
 415  		if err := readVarUint7(p.r, &kind); err != nil {
 416  			return fmt.Errorf("read kind: %v", err)
 417  		}
 418  		e.Kind = ExternalKind(kind)
 419  
 420  		if err := readVarUint32(p.r, &e.Index); err != nil {
 421  			return fmt.Errorf("read index: %v", err)
 422  		}
 423  
 424  		s.Entries = append(s.Entries, e)
 425  		return nil
 426  	})
 427  	if err != nil {
 428  		return nil, err
 429  	}
 430  
 431  	return &s, nil
 432  }
 433  
 434  func (p *parser) parseStartSection(base *section) (*SectionStart, error) {
 435  	s := SectionStart{section: base}
 436  
 437  	if err := readVarUint32(p.r, &s.Index); err != nil {
 438  		return nil, fmt.Errorf("read start index: %v", err)
 439  	}
 440  
 441  	return &s, nil
 442  }
 443  
 444  func (p *parser) parseElementSection(base *section) (*SectionElement, error) {
 445  	s := SectionElement{section: base}
 446  
 447  	err := p.loopCount(func() error {
 448  		var e ElemSegment
 449  
 450  		if err := readVarUint32(p.r, &e.Index); err != nil {
 451  			return fmt.Errorf("read element index: %v", err)
 452  		}
 453  
 454  		if err := readInitExpr(p.r, &e.Offset); err != nil {
 455  			return fmt.Errorf("read offset expression: %v", err)
 456  		}
 457  
 458  		var numElem uint32
 459  		if err := readVarUint32(p.r, &numElem); err != nil {
 460  			return fmt.Errorf("read number of elements: %v", err)
 461  		}
 462  		e.Elems = make([]uint32, int(numElem))
 463  		for i := range e.Elems {
 464  			if err := readVarUint32(p.r, &e.Elems[i]); err != nil {
 465  				return fmt.Errorf("read element function index %d: %v", i, err)
 466  			}
 467  		}
 468  
 469  		s.Entries = append(s.Entries, e)
 470  		return nil
 471  	})
 472  	if err != nil {
 473  		return nil, err
 474  	}
 475  
 476  	return &s, nil
 477  }
 478  
 479  func (p *parser) parseCodeSection(base *section) (*SectionCode, error) {
 480  	s := SectionCode{section: base}
 481  
 482  	err := p.loopCount(func() error {
 483  		var e FunctionBody
 484  
 485  		var bs uint32
 486  		if err := readVarUint32(p.r, &bs); err != nil {
 487  			return fmt.Errorf("read body size: %v", err)
 488  		}
 489  
 490  		end := p.r.Index() + int(bs)
 491  
 492  		p.loopCount(func() error {
 493  			var l LocalEntry
 494  
 495  			if err := readVarUint32(p.r, &l.Count); err != nil {
 496  				return fmt.Errorf("read local entry count: %v", err)
 497  			}
 498  			if err := read(p.r, &l.Type); err != nil {
 499  				return fmt.Errorf("read local entry value type: %v", err)
 500  			}
 501  
 502  			e.Locals = append(e.Locals, l)
 503  
 504  			return nil
 505  		})
 506  
 507  		numBytes := end - p.r.Index()
 508  		e.Code = make([]byte, numBytes)
 509  		if err := read(p.r, e.Code); err != nil {
 510  			return fmt.Errorf("read function bytecode: %v", err)
 511  		}
 512  
 513  		s.Bodies = append(s.Bodies, e)
 514  		return nil
 515  	})
 516  	if err != nil {
 517  		return nil, err
 518  	}
 519  
 520  	return &s, nil
 521  }
 522  
 523  func (p *parser) parseDataSection(base *section) (*SectionData, error) {
 524  	s := SectionData{section: base}
 525  
 526  	const (
 527  		isPassive   = 0x01
 528  		hasMemIndex = 0x02
 529  	)
 530  
 531  	err := p.loopCount(func() error {
 532  		var e DataSegment
 533  
 534  		var initFlags uint32
 535  		if err := readVarUint32(p.r, &initFlags); err != nil {
 536  			return fmt.Errorf("read data segment flags: %v", err)
 537  		}
 538  
 539  		if initFlags&hasMemIndex != 0 {
 540  			if err := readVarUint32(p.r, &e.Index); err != nil {
 541  				return fmt.Errorf("read data segment index: %v", err)
 542  			}
 543  		}
 544  
 545  		if initFlags&isPassive == 0 {
 546  			if err := readInitExpr(p.r, &e.Offset); err != nil {
 547  				return fmt.Errorf("read data section offset initializer: %v", err)
 548  			}
 549  		}
 550  
 551  		var size uint32
 552  		if err := readVarUint32(p.r, &size); err != nil {
 553  			return fmt.Errorf("read data section size: %v", err)
 554  		}
 555  
 556  		e.Data = make([]byte, size)
 557  		if err := read(p.r, e.Data); err != nil {
 558  			return fmt.Errorf("read data section data: %v", err)
 559  		}
 560  
 561  		s.Entries = append(s.Entries, e)
 562  		return nil
 563  	})
 564  	if err != nil {
 565  		return nil, err
 566  	}
 567  
 568  	return &s, nil
 569  }
 570  
 571  func (p *parser) parseDataCountSection(base *section) (*SectionDataCount, error) {
 572  	s := SectionDataCount{section: base}
 573  
 574  	if err := readVarUint32(p.r, &s.NumSegments); err != nil {
 575  		return nil, fmt.Errorf("read data count section: %v", err)
 576  	}
 577  
 578  	return &s, nil
 579  }
 580  
 581  // name types are used to identify the type in a Name section.
 582  const (
 583  	nameTypeModule   uint8 = iota // 0x00
 584  	nameTypeFunction              // 0x01
 585  	nameTypeLocal                 // 0x02
 586  )
 587  
 588  func (p *parser) parseNameSection(base *section, name string, n uint32) (*SectionName, error) {
 589  	s := SectionName{
 590  		section:     base,
 591  		SectionName: name,
 592  	}
 593  
 594  	end := p.r.Index() + int(n)
 595  	for p.r.Index() < end {
 596  		var t uint8
 597  		if err := read(p.r, &t); err != nil {
 598  			return nil, fmt.Errorf("read name type: %v", err)
 599  		}
 600  
 601  		var pl uint32
 602  		if err := readVarUint32(p.r, &pl); err != nil {
 603  			return nil, fmt.Errorf("read payload length: %v", err)
 604  		}
 605  
 606  		switch t {
 607  		case nameTypeModule:
 608  			var l uint32
 609  			if err := readVarUint32(p.r, &l); err != nil {
 610  				return nil, fmt.Errorf("read module name length: %v", err)
 611  			}
 612  
 613  			name := make([]byte, l)
 614  			if err := read(p.r, name); err != nil {
 615  				return nil, fmt.Errorf("read module name: %v", err)
 616  			}
 617  
 618  			s.Module = string(name)
 619  		case nameTypeFunction:
 620  			s.Functions = &NameMap{}
 621  			if err := p.parseNameMap(s.Functions); err != nil {
 622  				return nil, fmt.Errorf("read function name map: %v", err)
 623  			}
 624  		case nameTypeLocal:
 625  			s.Locals = &Locals{}
 626  			p.loopCount(func() error {
 627  				var l LocalName
 628  				if err := readVarUint32(p.r, &l.Index); err != nil {
 629  					return fmt.Errorf("read local func index: %v", err)
 630  				}
 631  				if err := p.parseNameMap(&l.LocalMap); err != nil {
 632  					return fmt.Errorf("read local name map: %v", err)
 633  				}
 634  				s.Locals.Funcs = append(s.Locals.Funcs, l)
 635  				return nil
 636  			})
 637  		default:
 638  			subsection := SectionNameUnknown{
 639  				ID:      t,
 640  				Payload: make([]byte, pl),
 641  			}
 642  			if err := read(p.r, subsection.Payload); err != nil {
 643  				return nil, fmt.Errorf("read name subsection payload: %v", err)
 644  			}
 645  			s.UnknownSections = append(s.UnknownSections, subsection)
 646  		}
 647  	}
 648  
 649  	if p.r.Index() != end {
 650  		return nil, fmt.Errorf("read %d bytes past the end of the name section", p.r.Index()-end)
 651  	}
 652  
 653  	return &s, nil
 654  }
 655  
 656  const (
 657  	linkingTypeSegment     = 5 // WASM_SEGMENT_INFO
 658  	linkingTypeSymbolTable = 8 // WASM_SYMBOL_TABLE
 659  )
 660  
 661  func (p *parser) parseLinkingSection(base *section, name string) (*SectionLinking, error) {
 662  	// Parse the linking section, as specified here:
 663  	// https://github.com/WebAssembly/tool-conventions/blob/main/Linking.md#linking-metadata-section
 664  	s := SectionLinking{
 665  		section:     base,
 666  		SectionName: name,
 667  	}
 668  
 669  	end := p.r.Index() + int(base.size)
 670  
 671  	// Check version of the linking section.
 672  	var version uint32
 673  	if err := readVarUint32(p.r, &version); err != nil {
 674  		return nil, fmt.Errorf("read linking section version: %v", err)
 675  	}
 676  	if version != 2 {
 677  		return nil, fmt.Errorf("unsupported linking section version %d (expected 2)", version)
 678  	}
 679  
 680  	// Read each subsection, and parse it if it is a known subsection kind.
 681  	for p.r.Index() < end {
 682  		var subsectionType uint8
 683  		if err := read(p.r, &subsectionType); err != nil {
 684  			return nil, fmt.Errorf("read subsection type: %v", err)
 685  		}
 686  
 687  		var subsectionLength uint32
 688  		if err := readVarUint32(p.r, &subsectionLength); err != nil {
 689  			return nil, fmt.Errorf("read subsection length: %v", err)
 690  		}
 691  
 692  		switch subsectionType {
 693  		case linkingTypeSegment:
 694  			// Read the segments of this object file.
 695  			var numSegments uint32
 696  			if err := readVarUint32(p.r, &numSegments); err != nil {
 697  				return nil, fmt.Errorf("read number of segments: %v", err)
 698  			}
 699  			for i := 0; i < int(numSegments); i++ {
 700  				var segment LinkingSegment
 701  				if err := readString(p.r, &segment.Name); err != nil {
 702  					return nil, fmt.Errorf("read segment name: %v", err)
 703  				}
 704  				if err := readVarUint32(p.r, &segment.Alignment); err != nil {
 705  					return nil, fmt.Errorf("read segment alignment: %v", err)
 706  				}
 707  				if err := readVarUint32(p.r, &segment.Flags); err != nil {
 708  					return nil, fmt.Errorf("read segment flags: %v", err)
 709  				}
 710  				s.Segments = append(s.Segments, segment)
 711  			}
 712  		case linkingTypeSymbolTable:
 713  			// Read the symbol table of this object file.
 714  			// Unfortunately, the specification isn't complete. I had to look at
 715  			// the LLVM implementation to figure out all the fields:
 716  			// https://github.com/llvm/llvm-project/blob/release/18.x/llvm/lib/Object/WasmObjectFile.cpp#L600
 717  			var numSymbols uint32
 718  			if err := readVarUint32(p.r, &numSymbols); err != nil {
 719  				return nil, fmt.Errorf("read number of symbols: %v", err)
 720  			}
 721  			for i := 0; i < int(numSymbols); i++ {
 722  				var kind uint8
 723  				if err := read(p.r, &kind); err != nil {
 724  					return nil, fmt.Errorf("read symbol kind: %v", err)
 725  				}
 726  				var flags uint32
 727  				if err := readVarUint32(p.r, &flags); err != nil {
 728  					return nil, fmt.Errorf("read symbol flags: %v", err)
 729  				}
 730  				symbol := LinkingSymbol{
 731  					Kind:  LinkingSymbolKind(kind),
 732  					Flags: LinkingSymbolFlags(flags),
 733  				}
 734  				isDefined := symbol.Flags&LinkingSymbolFlagUndefined == 0
 735  				isExplicitName := symbol.Flags&LinkingSymbolFlagExplicitName != 0
 736  				switch symbol.Kind {
 737  				case LinkingSymbolKindFunction, LinkingSymbolKindGlobal:
 738  					if err := readVarUint32(p.r, &symbol.Index); err != nil {
 739  						return nil, fmt.Errorf("read symbol index: %v", err)
 740  					}
 741  					if isDefined || isExplicitName {
 742  						if err := readString(p.r, &symbol.Name); err != nil {
 743  							return nil, fmt.Errorf("read symbol name: %v", err)
 744  						}
 745  					}
 746  				case LinkingSymbolKindData:
 747  					if err := readString(p.r, &symbol.Name); err != nil {
 748  						return nil, fmt.Errorf("read symbol name: %v", err)
 749  					}
 750  					if isDefined {
 751  						if err := readVarUint32(p.r, &symbol.Index); err != nil {
 752  							return nil, fmt.Errorf("read symbol index: %v", err)
 753  						}
 754  						if err := readVarUint64(p.r, &symbol.Offset); err != nil {
 755  							return nil, fmt.Errorf("read symbol offset: %v", err)
 756  						}
 757  						if err := readVarUint64(p.r, &symbol.Size); err != nil {
 758  							return nil, fmt.Errorf("read symbol size: %v", err)
 759  						}
 760  					}
 761  				case LinkingSymbolKindSection:
 762  					if err := readVarUint32(p.r, &symbol.Index); err != nil {
 763  						return nil, fmt.Errorf("read symbol index: %v", err)
 764  					}
 765  				case LinkingSymbolKindTable:
 766  					if err := readVarUint32(p.r, &symbol.Index); err != nil {
 767  						return nil, fmt.Errorf("read symbol index: %v", err)
 768  					}
 769  					if isDefined || isExplicitName {
 770  						if err := readString(p.r, &symbol.Name); err != nil {
 771  							return nil, fmt.Errorf("read symbol name: %v", err)
 772  						}
 773  					}
 774  				default:
 775  					return nil, fmt.Errorf("unknown symbol kind: %v", symbol.Kind)
 776  				}
 777  				s.Symbols = append(s.Symbols, symbol)
 778  			}
 779  		default:
 780  			// Unknown subsection, so store it as binary data.
 781  			subsection := SectionLinkingUnknown{
 782  				ID:      subsectionType,
 783  				Payload: make([]byte, subsectionLength),
 784  			}
 785  			if err := read(p.r, subsection.Payload); err != nil {
 786  				return nil, fmt.Errorf("read linking subsection payload: %v", err)
 787  			}
 788  			s.UnknownSections = append(s.UnknownSections, subsection)
 789  		}
 790  	}
 791  
 792  	return &s, nil
 793  }
 794  
 795  func (p *parser) parseResizableLimits(l *ResizableLimits) error {
 796  	var hasMax uint8
 797  	if err := readVarUint1(p.r, &hasMax); err != nil {
 798  		return fmt.Errorf("flags: %v", err)
 799  	}
 800  	if err := readVarUint32(p.r, &l.Initial); err != nil {
 801  		return fmt.Errorf("initial: %v", err)
 802  	}
 803  	if hasMax == 0 {
 804  		return nil
 805  	}
 806  	if err := readVarUint32(p.r, &l.Maximum); err != nil {
 807  		return fmt.Errorf("maximum: %v", err)
 808  	}
 809  	return nil
 810  }
 811  
 812  func (p *parser) parseTableType(t *TableType) error {
 813  	refType, err := readByte(p.r)
 814  	if err != nil {
 815  		return fmt.Errorf("read table type limits: %v", err)
 816  	}
 817  	t.ElemType = int8(refType)
 818  	if err := p.parseResizableLimits(&t.Limits); err != nil {
 819  		return fmt.Errorf("read memory resizable limits: %v", err)
 820  	}
 821  	return nil
 822  }
 823  
 824  // loopCount reads a varuint32 count and and calls the f n times. All sections
 825  // except custom start with this pattern.
 826  //
 827  // If f returns an error, further processing is not done and the error is
 828  // returned to the caller.
 829  func (p *parser) loopCount(f func() error) error {
 830  	var n uint32
 831  	if err := readVarUint32(p.r, &n); err != nil {
 832  		return fmt.Errorf("read section count: %v", err)
 833  	}
 834  
 835  	for i := uint32(0); i < n; i++ {
 836  		if err := f(); err != nil {
 837  			return fmt.Errorf("entry %d: %v", i, err)
 838  		}
 839  	}
 840  
 841  	return nil
 842  }
 843  
 844  func (p *parser) parseNameMap(v *NameMap) error {
 845  	p.loopCount(func() error {
 846  		var n Naming
 847  
 848  		if err := readVarUint32(p.r, &n.Index); err != nil {
 849  			return fmt.Errorf("read naming index: %v", err)
 850  		}
 851  
 852  		var l uint32
 853  		if err := readVarUint32(p.r, &l); err != nil {
 854  			return fmt.Errorf("read naming length: %v", err)
 855  		}
 856  
 857  		name := make([]byte, l)
 858  		if err := read(p.r, name); err != nil {
 859  			return fmt.Errorf("read name: %v", err)
 860  		}
 861  
 862  		n.Name = string(name)
 863  		v.Names = append(v.Names, n)
 864  
 865  		return nil
 866  	})
 867  
 868  	return nil
 869  }
 870