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  }