github.com/Rookout/GoSDK@v0.1.48/pkg/services/collection/variable/reg_tracker.go (about)

     1  package variable
     2  
     3  import (
     4  	"github.com/Rookout/GoSDK/pkg/logger"
     5  	"github.com/Rookout/GoSDK/pkg/rookoutErrors"
     6  	"github.com/Rookout/GoSDK/pkg/services/assembler"
     7  	"github.com/Rookout/GoSDK/pkg/services/instrumentation/dwarf/godwarf"
     8  	"github.com/Rookout/GoSDK/pkg/services/instrumentation/dwarf/op"
     9  )
    10  
    11  
    12  const dummyVal = 100
    13  
    14  type regTracker struct {
    15  	regsUsed map[uint64]struct{}
    16  }
    17  
    18  func newRegTracker() *regTracker {
    19  	return &regTracker{regsUsed: make(map[uint64]struct{})}
    20  }
    21  
    22  func (r *regTracker) Reg(i uint64) *op.DwarfRegister {
    23  	return &op.DwarfRegister{
    24  		Uint64Val: dummyVal,
    25  		Bytes:     []byte{dummyVal},
    26  	}
    27  }
    28  
    29  func (r *regTracker) Uint64Val(i uint64) uint64 {
    30  	return dummyVal
    31  }
    32  
    33  func (r *regTracker) CFA() int64         { return dummyVal }
    34  func (r *regTracker) StaticBase() uint64 { return dummyVal }
    35  func (r *regTracker) FrameBase() int64   { return dummyVal }
    36  
    37  func (r *regTracker) ResolveRegsUsed(variableType godwarf.Type, pieces []op.Piece) ([]assembler.Reg, rookoutErrors.RookoutError) {
    38  	if len(pieces) == 0 {
    39  		return nil, nil
    40  	}
    41  
    42  	pointerPieces, _ := r.resolveRegsUsed(variableType, pieces)
    43  
    44  	var regs []assembler.Reg
    45  	for _, piece := range pointerPieces {
    46  		if piece.Kind != op.RegPiece {
    47  			continue
    48  		}
    49  
    50  		reg, ok := assembler.DwarfRegToAsmReg(piece.Val)
    51  		if !ok {
    52  			return nil, rookoutErrors.NewInvalidDwarfRegister(piece.Val)
    53  		}
    54  		regs = append(regs, reg)
    55  	}
    56  	return regs, nil
    57  }
    58  
    59  
    60  func (r *regTracker) resolveRegsUsed(variableType godwarf.Type, pieces []op.Piece) (pointerPieces []op.Piece, basicPieces []op.Piece) {
    61  	switch t := resolveTypedef(variableType).(type) {
    62  	
    63  	case *godwarf.StringType:
    64  		return pieces[:1], pieces[1:2]
    65  
    66  	
    67  	case *godwarf.InterfaceType:
    68  		return pieces[:2], nil
    69  
    70  	
    71  	case *godwarf.MapType, *godwarf.FuncType, *godwarf.PtrType, *godwarf.ChanType:
    72  		return pieces[:1], nil
    73  
    74  	
    75  	case *godwarf.SliceType, *godwarf.DotDotDotType:
    76  		return pieces[:1], pieces[1:3]
    77  
    78  	
    79  	case *godwarf.IntType, *godwarf.CharType, *godwarf.ComplexType, *godwarf.FloatType, *godwarf.BoolType, *godwarf.EnumType, *godwarf.UintType, *godwarf.UcharType:
    80  		return nil, pieces[:1]
    81  
    82  	
    83  	case *godwarf.StructType:
    84  		for _, field := range t.Field {
    85  			pointers, basics := r.resolveRegsUsed(field.Type, pieces)
    86  			pointerPieces = append(pointerPieces, pointers...)
    87  			basicPieces = append(basicPieces, basics...)
    88  			pieces = pieces[len(pointers)+len(basics):]
    89  		}
    90  		return pointerPieces, basicPieces
    91  
    92  	
    93  	case *godwarf.ParametricType:
    94  		return pieces, nil
    95  	}
    96  
    97  	logger.Logger().Warningf("Unknown type for regs used: %T\n", resolveTypedef(variableType))
    98  	return pieces, nil
    99  }