github.com/gagliardetto/golang-go@v0.0.0-20201020153340-53909ea70814/cmd/internal/goobj2/funcinfo.go (about) 1 // Copyright 2019 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 goobj2 6 7 import ( 8 "bytes" 9 "encoding/binary" 10 ) 11 12 // FuncInfo is serialized as a symbol (aux symbol). The symbol data is 13 // the binary encoding of the struct below. 14 // 15 // TODO: make each pcdata a separate symbol? 16 type FuncInfo struct { 17 NoSplit uint8 18 19 Args uint32 20 Locals uint32 21 22 Pcsp uint32 23 Pcfile uint32 24 Pcline uint32 25 Pcinline uint32 26 Pcdata []uint32 27 PcdataEnd uint32 28 Funcdataoff []uint32 29 File []SymRef // TODO: just use string? 30 31 InlTree []InlTreeNode 32 } 33 34 func (a *FuncInfo) Write(w *bytes.Buffer) { 35 w.WriteByte(a.NoSplit) 36 37 var b [4]byte 38 writeUint32 := func(x uint32) { 39 binary.LittleEndian.PutUint32(b[:], x) 40 w.Write(b[:]) 41 } 42 43 writeUint32(a.Args) 44 writeUint32(a.Locals) 45 46 writeUint32(a.Pcsp) 47 writeUint32(a.Pcfile) 48 writeUint32(a.Pcline) 49 writeUint32(a.Pcinline) 50 writeUint32(uint32(len(a.Pcdata))) 51 for _, x := range a.Pcdata { 52 writeUint32(x) 53 } 54 writeUint32(a.PcdataEnd) 55 writeUint32(uint32(len(a.Funcdataoff))) 56 for _, x := range a.Funcdataoff { 57 writeUint32(x) 58 } 59 writeUint32(uint32(len(a.File))) 60 for _, f := range a.File { 61 writeUint32(f.PkgIdx) 62 writeUint32(f.SymIdx) 63 } 64 writeUint32(uint32(len(a.InlTree))) 65 for i := range a.InlTree { 66 a.InlTree[i].Write(w) 67 } 68 } 69 70 func (a *FuncInfo) Read(b []byte) { 71 a.NoSplit = b[0] 72 b = b[1:] 73 74 readUint32 := func() uint32 { 75 x := binary.LittleEndian.Uint32(b) 76 b = b[4:] 77 return x 78 } 79 80 a.Args = readUint32() 81 a.Locals = readUint32() 82 83 a.Pcsp = readUint32() 84 a.Pcfile = readUint32() 85 a.Pcline = readUint32() 86 a.Pcinline = readUint32() 87 pcdatalen := readUint32() 88 a.Pcdata = make([]uint32, pcdatalen) 89 for i := range a.Pcdata { 90 a.Pcdata[i] = readUint32() 91 } 92 a.PcdataEnd = readUint32() 93 funcdataofflen := readUint32() 94 a.Funcdataoff = make([]uint32, funcdataofflen) 95 for i := range a.Funcdataoff { 96 a.Funcdataoff[i] = readUint32() 97 } 98 filelen := readUint32() 99 a.File = make([]SymRef, filelen) 100 for i := range a.File { 101 a.File[i] = SymRef{readUint32(), readUint32()} 102 } 103 inltreelen := readUint32() 104 a.InlTree = make([]InlTreeNode, inltreelen) 105 for i := range a.InlTree { 106 b = a.InlTree[i].Read(b) 107 } 108 } 109 110 // InlTreeNode is the serialized form of FileInfo.InlTree. 111 type InlTreeNode struct { 112 Parent int32 113 File SymRef 114 Line int32 115 Func SymRef 116 ParentPC int32 117 } 118 119 func (inl *InlTreeNode) Write(w *bytes.Buffer) { 120 var b [4]byte 121 writeUint32 := func(x uint32) { 122 binary.LittleEndian.PutUint32(b[:], x) 123 w.Write(b[:]) 124 } 125 writeUint32(uint32(inl.Parent)) 126 writeUint32(inl.File.PkgIdx) 127 writeUint32(inl.File.SymIdx) 128 writeUint32(uint32(inl.Line)) 129 writeUint32(inl.Func.PkgIdx) 130 writeUint32(inl.Func.SymIdx) 131 writeUint32(uint32(inl.ParentPC)) 132 } 133 134 // Read an InlTreeNode from b, return the remaining bytes. 135 func (inl *InlTreeNode) Read(b []byte) []byte { 136 readUint32 := func() uint32 { 137 x := binary.LittleEndian.Uint32(b) 138 b = b[4:] 139 return x 140 } 141 inl.Parent = int32(readUint32()) 142 inl.File = SymRef{readUint32(), readUint32()} 143 inl.Line = int32(readUint32()) 144 inl.Func = SymRef{readUint32(), readUint32()} 145 inl.ParentPC = int32(readUint32()) 146 return b 147 }