...
Source file
src/debug/pe/symbol.go
1
2
3
4
5 package pe
6
7 import (
8 "encoding/binary"
9 "fmt"
10 "io"
11 )
12
13 const COFFSymbolSize = 18
14
15
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
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
53
54
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
91
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