github.com/Rookout/GoSDK@v0.1.48/pkg/services/instrumentation/dwarf/op/regs.go (about) 1 // The MIT License (MIT) 2 3 // Copyright (c) 2014 Derek Parker 4 5 // Permission is hereby granted, free of charge, to any person obtaining a copy of 6 // this software and associated documentation files (the "Software"), to deal in 7 // the Software without restriction, including without limitation the rights to 8 // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 // the Software, and to permit persons to whom the Software is furnished to do so, 10 // subject to the following conditions: 11 12 // The above copyright notice and this permission notice shall be included in all 13 // copies or substantial portions of the Software. 14 15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22 package op 23 24 import ( 25 "bytes" 26 "encoding/binary" 27 ) 28 29 30 type DwarfRegisters struct { 31 staticBase uint64 32 33 cfa int64 34 frameBase int64 35 ObjBase int64 36 regs []*DwarfRegister 37 38 ByteOrder binary.ByteOrder 39 PCRegNum uint64 40 SPRegNum uint64 41 BPRegNum uint64 42 LRRegNum uint64 43 44 FloatLoadError error 45 loadMoreCallback func() 46 } 47 48 type DwarfRegister struct { 49 Uint64Val uint64 50 Bytes []byte 51 } 52 53 54 func NewDwarfRegisters(staticBase uint64, regs []*DwarfRegister, byteOrder binary.ByteOrder, pcRegNum, spRegNum, bpRegNum, lrRegNum uint64) *DwarfRegisters { 55 return &DwarfRegisters{ 56 staticBase: staticBase, 57 regs: regs, 58 ByteOrder: byteOrder, 59 PCRegNum: pcRegNum, 60 SPRegNum: spRegNum, 61 BPRegNum: bpRegNum, 62 LRRegNum: lrRegNum, 63 } 64 } 65 66 func (regs *DwarfRegisters) CFA() int64 { return regs.cfa } 67 func (regs *DwarfRegisters) StaticBase() uint64 { return regs.staticBase } 68 func (regs *DwarfRegisters) FrameBase() int64 { return regs.frameBase } 69 func (regs *DwarfRegisters) SetCFA(cfa int64) { regs.cfa = cfa } 70 func (regs *DwarfRegisters) SetStaticBase(staticBase uint64) { regs.staticBase = staticBase } 71 func (regs *DwarfRegisters) SetFrameBase(frameBase int64) { regs.frameBase = frameBase } 72 73 74 75 func (regs *DwarfRegisters) SetLoadMoreCallback(fn func()) { 76 regs.loadMoreCallback = fn 77 } 78 79 80 81 func (regs *DwarfRegisters) CurrentSize() int { 82 return len(regs.regs) 83 } 84 85 86 func (regs *DwarfRegisters) Uint64Val(idx uint64) uint64 { 87 reg := regs.Reg(idx) 88 if reg == nil { 89 return 0 90 } 91 return regs.regs[idx].Uint64Val 92 } 93 94 95 96 func (regs *DwarfRegisters) Bytes(idx uint64) []byte { 97 reg := regs.Reg(idx) 98 if reg == nil { 99 return nil 100 } 101 if reg.Bytes == nil { 102 var buf bytes.Buffer 103 binary.Write(&buf, regs.ByteOrder, reg.Uint64Val) 104 reg.Bytes = buf.Bytes() 105 } 106 return reg.Bytes 107 } 108 109 func (regs *DwarfRegisters) loadMore() { 110 if regs.loadMoreCallback == nil { 111 return 112 } 113 regs.loadMoreCallback() 114 regs.loadMoreCallback = nil 115 } 116 117 118 func (regs *DwarfRegisters) Reg(idx uint64) *DwarfRegister { 119 if idx >= uint64(len(regs.regs)) { 120 regs.loadMore() 121 if idx >= uint64(len(regs.regs)) { 122 return nil 123 } 124 } 125 if regs.regs[idx] == nil { 126 regs.loadMore() 127 } 128 return regs.regs[idx] 129 } 130 131 func (regs *DwarfRegisters) PC() uint64 { 132 return regs.Uint64Val(regs.PCRegNum) 133 } 134 135 func (regs *DwarfRegisters) SP() uint64 { 136 return regs.Uint64Val(regs.SPRegNum) 137 } 138 139 func (regs *DwarfRegisters) BP() uint64 { 140 return regs.Uint64Val(regs.BPRegNum) 141 } 142 143 144 func (regs *DwarfRegisters) AddReg(idx uint64, reg *DwarfRegister) { 145 if idx >= uint64(len(regs.regs)) { 146 newRegs := make([]*DwarfRegister, idx+1) 147 copy(newRegs, regs.regs) 148 regs.regs = newRegs 149 } 150 regs.regs[idx] = reg 151 } 152 153 154 func (regs *DwarfRegisters) ClearRegisters() { 155 regs.loadMoreCallback = nil 156 for regnum := range regs.regs { 157 regs.regs[regnum] = nil 158 } 159 } 160 161 func DwarfRegisterFromUint64(v uint64) *DwarfRegister { 162 return &DwarfRegister{Uint64Val: v} 163 } 164 165 func DwarfRegisterFromBytes(bytes []byte) *DwarfRegister { 166 var v uint64 167 switch len(bytes) { 168 case 1: 169 v = uint64(bytes[0]) 170 case 2: 171 x := binary.LittleEndian.Uint16(bytes) 172 v = uint64(x) 173 case 4: 174 x := binary.LittleEndian.Uint32(bytes) 175 v = uint64(x) 176 default: 177 if len(bytes) >= 8 { 178 v = binary.LittleEndian.Uint64(bytes[:8]) 179 } 180 } 181 return &DwarfRegister{Uint64Val: v, Bytes: bytes} 182 }