...

Source file src/pkg/debug/pe/symbol.go

     1	// Copyright 2016 The Go Authors. All rights reserved.
     2	// Use of this source code is governed by a BSD-style
     3	// license that can be found in the LICENSE file.
     4	
     5	package pe
     6	
     7	import (
     8		"encoding/binary"
     9		"fmt"
    10		"io"
    11	)
    12	
    13	const COFFSymbolSize = 18
    14	
    15	// COFFSymbol represents single COFF symbol table record.
    16	type COFFSymbol struct {
    17		Name               [8]uint8
    18		Value              uint32
    19		SectionNumber      int16
    20		Type               uint16
    21		StorageClass       uint8
    22		NumberOfAuxSymbols uint8
    23	}
    24	
    25	func readCOFFSymbols(fh *FileHeader, r io.ReadSeeker) ([]COFFSymbol, error) {
    26		if fh.PointerToSymbolTable == 0 {
    27			return nil, nil
    28		}
    29		if fh.NumberOfSymbols <= 0 {
    30			return nil, nil
    31		}
    32		_, err := r.Seek(int64(fh.PointerToSymbolTable), seekStart)
    33		if err != nil {
    34			return nil, fmt.Errorf("fail to seek to symbol table: %v", err)
    35		}
    36		syms := make([]COFFSymbol, fh.NumberOfSymbols)
    37		err = binary.Read(r, binary.LittleEndian, syms)
    38		if err != nil {
    39			return nil, fmt.Errorf("fail to read symbol table: %v", err)
    40		}
    41		return syms, nil
    42	}
    43	
    44	// isSymNameOffset checks symbol name if it is encoded as offset into string table.
    45	func isSymNameOffset(name [8]byte) (bool, uint32) {
    46		if name[0] == 0 && name[1] == 0 && name[2] == 0 && name[3] == 0 {
    47			return true, binary.LittleEndian.Uint32(name[4:])
    48		}
    49		return false, 0
    50	}
    51	
    52	// FullName finds real name of symbol sym. Normally name is stored
    53	// in sym.Name, but if it is longer then 8 characters, it is stored
    54	// in COFF string table st instead.
    55	func (sym *COFFSymbol) FullName(st StringTable) (string, error) {
    56		if ok, offset := isSymNameOffset(sym.Name); ok {
    57			return st.String(offset)
    58		}
    59		return cstring(sym.Name[:]), nil
    60	}
    61	
    62	func removeAuxSymbols(allsyms []COFFSymbol, st StringTable) ([]*Symbol, error) {
    63		if len(allsyms) == 0 {
    64			return nil, nil
    65		}
    66		syms := make([]*Symbol, 0)
    67		aux := uint8(0)
    68		for _, sym := range allsyms {
    69			if aux > 0 {
    70				aux--
    71				continue
    72			}
    73			name, err := sym.FullName(st)
    74			if err != nil {
    75				return nil, err
    76			}
    77			aux = sym.NumberOfAuxSymbols
    78			s := &Symbol{
    79				Name:          name,
    80				Value:         sym.Value,
    81				SectionNumber: sym.SectionNumber,
    82				Type:          sym.Type,
    83				StorageClass:  sym.StorageClass,
    84			}
    85			syms = append(syms, s)
    86		}
    87		return syms, nil
    88	}
    89	
    90	// Symbol is similar to COFFSymbol with Name field replaced
    91	// by Go string. Symbol also does not have NumberOfAuxSymbols.
    92	type Symbol struct {
    93		Name          string
    94		Value         uint32
    95		SectionNumber int16
    96		Type          uint16
    97		StorageClass  uint8
    98	}
    99	

View as plain text