github.com/Rookout/GoSDK@v0.1.48/pkg/services/collection/memory/composite_memory.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 memory 23 24 import ( 25 "encoding/binary" 26 "errors" 27 "fmt" 28 29 "github.com/Rookout/GoSDK/pkg/services/instrumentation/dwarf/op" 30 ) 31 32 33 34 35 36 37 38 39 type CompositeMemory struct { 40 realmem MemoryReader 41 regs op.DwarfRegisters 42 pieces []op.Piece 43 data []byte 44 } 45 46 func NewCompositeMemory(mem MemoryReader, regs op.DwarfRegisters, pieces []op.Piece, pointerSize int) (*CompositeMemory, error) { 47 cmem := &CompositeMemory{realmem: mem, regs: regs, pieces: pieces, data: []byte{}} 48 for i := range pieces { 49 piece := &pieces[i] 50 switch piece.Kind { 51 case op.RegPiece: 52 reg := regs.Bytes(piece.Val) 53 if piece.Size == 0 && i == len(pieces)-1 { 54 piece.Size = len(reg) 55 } 56 if piece.Size > len(reg) { 57 if regs.FloatLoadError != nil { 58 return nil, fmt.Errorf("could not read %d bytes from register %d (size: %d), also error loading floating point registers: %v", piece.Size, piece.Val, len(reg), regs.FloatLoadError) 59 } 60 return nil, fmt.Errorf("could not read %d bytes from register %d (size: %d)", piece.Size, piece.Val, len(reg)) 61 } 62 cmem.data = append(cmem.data, reg[:piece.Size]...) 63 case op.AddrPiece: 64 buf := make([]byte, piece.Size) 65 _, err := mem.ReadMemory(buf, piece.Val) 66 if err != nil { 67 return nil, err 68 } 69 cmem.data = append(cmem.data, buf...) 70 case op.ImmPiece: 71 buf := piece.Bytes 72 if buf == nil { 73 sz := 8 74 if piece.Size > sz { 75 sz = piece.Size 76 } 77 if piece.Size == 0 && i == len(pieces)-1 { 78 piece.Size = pointerSize 79 } 80 buf = make([]byte, sz) 81 binary.LittleEndian.PutUint64(buf, piece.Val) 82 } 83 cmem.data = append(cmem.data, buf[:piece.Size]...) 84 default: 85 panic("unsupported piece kind") 86 } 87 } 88 return cmem, nil 89 } 90 91 func (m *CompositeMemory) ReadMemory(data []byte, addr uint64) (int, error) { 92 addr -= FakeAddress 93 if addr >= uint64(len(m.data)) || addr+uint64(len(data)) > uint64(len(m.data)) { 94 return 0, errors.New("read out of bounds") 95 } 96 copy(data, m.data[addr:addr+uint64(len(data))]) 97 return len(data), nil 98 } 99 100 101 102 103 104 105 106 func DereferenceMemory(m MemoryReader) MemoryReader { 107 if cmem, ok := m.(*CompositeMemory); ok { 108 return cmem.realmem 109 } 110 111 return m 112 } 113 114 func (m *CompositeMemory) ID() string { 115 return string(m.data) 116 }