github.com/Rookout/GoSDK@v0.1.48/pkg/services/collection/variable/read.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 variable
    23  
    24  import (
    25  	"encoding/binary"
    26  	"fmt"
    27  
    28  	"github.com/Rookout/GoSDK/pkg/config"
    29  	"github.com/Rookout/GoSDK/pkg/services/collection/memory"
    30  	"github.com/Rookout/GoSDK/pkg/services/instrumentation/binary_info"
    31  	"github.com/Rookout/GoSDK/pkg/services/instrumentation/dwarf/godwarf"
    32  )
    33  
    34  
    35  
    36  func readIntRaw(mem memory.MemoryReader, addr uint64, size int64) (int64, error) {
    37  	var n int64
    38  
    39  	val := make([]byte, int(size))
    40  	_, err := mem.ReadMemory(val, addr)
    41  	if err != nil {
    42  		return 0, err
    43  	}
    44  
    45  	switch size {
    46  	case 1:
    47  		n = int64(int8(val[0]))
    48  	case 2:
    49  		n = int64(int16(binary.LittleEndian.Uint16(val)))
    50  	case 4:
    51  		n = int64(int32(binary.LittleEndian.Uint32(val)))
    52  	case 8:
    53  		n = int64(binary.LittleEndian.Uint64(val))
    54  	}
    55  
    56  	return n, nil
    57  }
    58  
    59  func readUintRaw(mem memory.MemoryReader, addr uint64, size int64) (uint64, error) {
    60  	var n uint64
    61  
    62  	val := make([]byte, int(size))
    63  	_, err := mem.ReadMemory(val, addr)
    64  	if err != nil {
    65  		return 0, err
    66  	}
    67  
    68  	switch size {
    69  	case 1:
    70  		n = uint64(val[0])
    71  	case 2:
    72  		n = uint64(binary.LittleEndian.Uint16(val))
    73  	case 4:
    74  		n = uint64(binary.LittleEndian.Uint32(val))
    75  	case 8:
    76  		n = uint64(binary.LittleEndian.Uint64(val))
    77  	}
    78  
    79  	return n, nil
    80  }
    81  
    82  func readStringInfo(mem memory.MemoryReader, bi *binary_info.BinaryInfo, addr uint64, typ *godwarf.StringType) (uint64, int64, error) {
    83  	
    84  	
    85  
    86  	mem = memory.CacheMemory(mem, addr, bi.PointerSize*2)
    87  
    88  	var strlen int64
    89  	var outaddr uint64
    90  	var err error
    91  
    92  	for _, field := range typ.StructType.Field {
    93  		switch field.Name {
    94  		case "len":
    95  			strlen, err = readIntRaw(mem, addr+uint64(field.ByteOffset), int64(bi.PointerSize))
    96  			if err != nil {
    97  				return 0, 0, fmt.Errorf("could not read string len %s", err)
    98  			}
    99  			if strlen < 0 {
   100  				return 0, 0, fmt.Errorf("invalid length: %d", strlen)
   101  			}
   102  		case "str":
   103  			outaddr, err = readUintRaw(mem, addr+uint64(field.ByteOffset), int64(bi.PointerSize))
   104  			if err != nil {
   105  				return 0, 0, fmt.Errorf("could not read string pointer %s", err)
   106  			}
   107  			if addr == 0 {
   108  				return 0, 0, nil
   109  			}
   110  		}
   111  	}
   112  
   113  	return outaddr, strlen, nil
   114  }
   115  
   116  func readStringValue(mem memory.MemoryReader, addr uint64, strlen int64, cfg config.ObjectDumpConfig) (string, error) {
   117  	if strlen == 0 {
   118  		return "", nil
   119  	}
   120  
   121  	count := strlen
   122  	if count > int64(cfg.MaxString) {
   123  		count = int64(cfg.MaxString)
   124  	}
   125  
   126  	val := make([]byte, int(count))
   127  	_, err := mem.ReadMemory(val, addr)
   128  	if err != nil {
   129  		return "", fmt.Errorf("could not read string at %#v due to %s", addr, err)
   130  	}
   131  
   132  	return string(val), nil
   133  }
   134  
   135  func readCStringValue(mem memory.MemoryReader, addr uint64, cfg config.ObjectDumpConfig) (string, bool, error) {
   136  	buf := make([]byte, cfg.MaxString) 
   137  	val := buf[:0]                     
   138  
   139  	for len(buf) > 0 {
   140  		
   141  		
   142  		
   143  		
   144  		
   145  		
   146  		
   147  		curaddr := addr + uint64(len(val))
   148  		maxsize := int(alignAddr(int64(curaddr+1), 1024) - int64(curaddr))
   149  		size := len(buf)
   150  		if size > maxsize {
   151  			size = maxsize
   152  		}
   153  
   154  		_, err := mem.ReadMemory(buf[:size], curaddr)
   155  		if err != nil {
   156  			return "", false, fmt.Errorf("could not read string at %#v due to %s", addr, err)
   157  		}
   158  
   159  		done := false
   160  		for i := 0; i < size; i++ {
   161  			if buf[i] == 0 {
   162  				done = true
   163  				size = i
   164  				break
   165  			}
   166  		}
   167  
   168  		val = val[:len(val)+size]
   169  		buf = buf[size:]
   170  		if done {
   171  			return string(val), true, nil
   172  		}
   173  	}
   174  
   175  	return string(val), false, nil
   176  }