...
Run Format

Source file src/debug/pe/symbol.go

Documentation: debug/pe

  // Copyright 2016 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package pe
  
  import (
  	"encoding/binary"
  	"fmt"
  	"io"
  )
  
  const COFFSymbolSize = 18
  
  // COFFSymbol represents single COFF symbol table record.
  type COFFSymbol struct {
  	Name               [8]uint8
  	Value              uint32
  	SectionNumber      int16
  	Type               uint16
  	StorageClass       uint8
  	NumberOfAuxSymbols uint8
  }
  
  func readCOFFSymbols(fh *FileHeader, r io.ReadSeeker) ([]COFFSymbol, error) {
  	if fh.PointerToSymbolTable == 0 {
  		return nil, nil
  	}
  	if fh.NumberOfSymbols <= 0 {
  		return nil, nil
  	}
  	_, err := r.Seek(int64(fh.PointerToSymbolTable), seekStart)
  	if err != nil {
  		return nil, fmt.Errorf("fail to seek to symbol table: %v", err)
  	}
  	syms := make([]COFFSymbol, fh.NumberOfSymbols)
  	err = binary.Read(r, binary.LittleEndian, syms)
  	if err != nil {
  		return nil, fmt.Errorf("fail to read symbol table: %v", err)
  	}
  	return syms, nil
  }
  
  // isSymNameOffset checks symbol name if it is encoded as offset into string table.
  func isSymNameOffset(name [8]byte) (bool, uint32) {
  	if name[0] == 0 && name[1] == 0 && name[2] == 0 && name[3] == 0 {
  		return true, binary.LittleEndian.Uint32(name[4:])
  	}
  	return false, 0
  }
  
  // FullName finds real name of symbol sym. Normally name is stored
  // in sym.Name, but if it is longer then 8 characters, it is stored
  // in COFF string table st instead.
  func (sym *COFFSymbol) FullName(st StringTable) (string, error) {
  	if ok, offset := isSymNameOffset(sym.Name); ok {
  		return st.String(offset)
  	}
  	return cstring(sym.Name[:]), nil
  }
  
  func removeAuxSymbols(allsyms []COFFSymbol, st StringTable) ([]*Symbol, error) {
  	if len(allsyms) == 0 {
  		return nil, nil
  	}
  	syms := make([]*Symbol, 0)
  	aux := uint8(0)
  	for _, sym := range allsyms {
  		if aux > 0 {
  			aux--
  			continue
  		}
  		name, err := sym.FullName(st)
  		if err != nil {
  			return nil, err
  		}
  		aux = sym.NumberOfAuxSymbols
  		s := &Symbol{
  			Name:          name,
  			Value:         sym.Value,
  			SectionNumber: sym.SectionNumber,
  			Type:          sym.Type,
  			StorageClass:  sym.StorageClass,
  		}
  		syms = append(syms, s)
  	}
  	return syms, nil
  }
  
  // Symbol is similar to COFFSymbol with Name field replaced
  // by Go string. Symbol also does not have NumberOfAuxSymbols.
  type Symbol struct {
  	Name          string
  	Value         uint32
  	SectionNumber int16
  	Type          uint16
  	StorageClass  uint8
  }
  

View as plain text