...

Source file src/debug/pe/symbol.go

Documentation: debug/pe

		 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