github.com/Rookout/GoSDK@v0.1.48/pkg/services/instrumentation/module/module_patcher1.21.go (about)

     1  //go:build go1.21 && !go1.22
     2  // +build go1.21,!go1.22
     3  
     4  package module
     5  
     6  import (
     7  	"os"
     8  	"unsafe"
     9  
    10  	"github.com/Rookout/GoSDK/pkg/rookoutErrors"
    11  )
    12  
    13  type pclntableInfo struct {
    14  	pcDataTables    [][]byte
    15  	funcDataOffsets []uint32
    16  	pcLine          []byte
    17  	pcFile          []byte
    18  	pcsp            []byte
    19  }
    20  
    21  func (m *moduleDataPatcher) getPCDataTable(offset uintptr) []byte {
    22  	if offset == 0 {
    23  		return nil
    24  	}
    25  	return m.origModule.pctab[offset:]
    26  }
    27  
    28  func (m *moduleDataPatcher) funcDataOffset(table uint8) uint32 {
    29  	p := uintptr(unsafe.Pointer(&m.origFunction.nfuncdata)) + unsafe.Sizeof(m.origFunction.nfuncdata) + uintptr(m.origFunction.npcdata)*4 + uintptr(table)*4
    30  	return *(*uint32)(unsafe.Pointer(p))
    31  }
    32  
    33  func (m *moduleDataPatcher) buildFunc(pcspOffset uint32, pcfileOffset uint32, pclnOffset uint32) _func {
    34  	return _func{
    35  		entryoff: 0,
    36  		nameoff:  m.origFunction.nameoff,
    37  
    38  		args:        m.origFunction.args,
    39  		deferreturn: m.getDeferreturn(),
    40  
    41  		pcsp:      pcspOffset,
    42  		pcfile:    pcfileOffset,
    43  		pcln:      pclnOffset,
    44  		npcdata:   uint32(len(m.info.pcDataTables)),
    45  		cuOffset:  m.origFunction.cuOffset,
    46  		funcID:    m.origFunction.funcID,
    47  		flag:      m.origFunction.flag,
    48  		nfuncdata: uint8(len(m.info.funcDataOffsets)),
    49  	}
    50  }
    51  
    52  func (m *moduleDataPatcher) buildPCFile(patcher *PCDataPatcher) error {
    53  	newPCFile, _, err := patcher.CreatePCFile(decodePCDataEntries(m.getPCDataTable(uintptr(m.origFunction.pcfile))))
    54  	if err != nil {
    55  		return err
    56  	}
    57  	newPCFileBytes, err := encodePCDataEntries(newPCFile)
    58  	if _, ok := os.LookupEnv("ROOKOUT_DEV_DEBUG"); ok {
    59  		dumpPCData(m.getPCDataTable(uintptr(m.origFunction.pcfile)), "Old pcfile")
    60  		dumpPCData(newPCFileBytes, "New pcfile")
    61  	}
    62  
    63  	m.info.pcFile = newPCFileBytes
    64  	return nil
    65  }
    66  
    67  
    68  func (m *moduleDataPatcher) createPCHeader() {
    69  	m.pcHeader.nfunc = len(m.origModule.ftab)
    70  	m.pcHeader.nfiles = (uint)(len(m.origModule.filetab))
    71  	m.pcHeader.textStart = m.newFuncEntryAddress
    72  }
    73  
    74  
    75  func (m *moduleDataPatcher) getModuleData() (moduledata, error) {
    76  	return moduledata{
    77  		pcHeader:    &m.pcHeader,
    78  		funcnametab: m.origModule.funcnametab, 
    79  		filetab:     m.origModule.filetab,     
    80  		cutab:       m.origModule.cutab,
    81  		ftab:        m.ftab,
    82  		pctab:       m.newPclntable,
    83  		pclntable:   m.newPclntable,
    84  		findfunctab: uintptr(unsafe.Pointer(m.findFuncBucketTable)),
    85  		minpc:       m.newFuncEntryAddress,
    86  		maxpc:       m.newFuncEndAddress,
    87  		text:        m.newFuncEntryAddress,
    88  		etext:       m.newFuncEndAddress,
    89  		noptrdata:   m.origModule.noptrdata,
    90  		enoptrdata:  m.origModule.enoptrdata,
    91  		data:        m.origModule.data,
    92  		edata:       m.origModule.edata,
    93  		bss:         m.origModule.bss,
    94  		ebss:        m.origModule.ebss,
    95  		noptrbss:    m.origModule.noptrbss,
    96  		enoptrbss:   m.origModule.enoptrbss,
    97  		end:         m.origModule.end,
    98  		gcdata:      m.origModule.gcdata,
    99  		gcbss:       m.origModule.gcbss,
   100  		types:       m.origModule.types,
   101  		etypes:      m.origModule.etypes,
   102  		gofunc:      m.origModule.gofunc,
   103  		rodata:      m.origModule.noptrdata,
   104  
   105  		modulename: m.name,
   106  
   107  		hasmain: 0, 
   108  
   109  		gcdatamask: m.origModule.gcdatamask,
   110  		gcbssmask:  m.origModule.gcbssmask,
   111  
   112  		typemap:   m.origModule.typemap,
   113  		inittasks: m.origModule.inittasks,
   114  
   115  		bad: false, 
   116  
   117  		next: nil,
   118  	}, nil
   119  }
   120  
   121  func (m *moduleDataPatcher) isPCDataStartValid(pcDataStart uint32) bool {
   122  	return int(pcDataStart) < len(m.origModule.pctab)
   123  }
   124  
   125  func (m *moduleDataPatcher) newFuncTab(funcOff uintptr, entry uintptr) functab {
   126  	entryOff := entry - m.newFuncEntryAddress
   127  	return functab{funcoff: uint32(funcOff), entryoff: uint32(entryOff)}
   128  }
   129  
   130  func (m *moduleDataPatcher) createPclnTable() rookoutErrors.RookoutError {
   131  	
   132  	m.newPclntable = make([]byte, 1)
   133  
   134  	pcDataOffsets := make([]uint32, len(m.info.pcDataTables))
   135  	for i, table := range m.info.pcDataTables {
   136  		if table == nil {
   137  			continue
   138  		}
   139  		pcDataOffsets[i] = uint32(len(m.newPclntable))
   140  		m.writeObjectToPclnTable(unsafe.Pointer(&table[0]), len(table))
   141  	}
   142  
   143  	pcspOffset := uint32(len(m.newPclntable))
   144  	m.writeBytesToPclnTable(m.info.pcsp)
   145  	pcfileOffset := uint32(len(m.newPclntable))
   146  	m.writeBytesToPclnTable(m.info.pcFile)
   147  	pclnOffset := uint32(len(m.newPclntable))
   148  	m.writeBytesToPclnTable(m.info.pcLine)
   149  
   150  	f := m.buildFunc(pcspOffset, pcfileOffset, pclnOffset)
   151  	m.funcOffset = uintptr(len(m.newPclntable))
   152  	
   153  	m.writeObjectToPclnTable(unsafe.Pointer(&f), int(unsafe.Offsetof(f.nfuncdata)+unsafe.Sizeof(f.nfuncdata)))
   154  
   155  	if len(pcDataOffsets) > 0 {
   156  		m.writeObjectToPclnTable(unsafe.Pointer(&pcDataOffsets[0]), len(pcDataOffsets)*4)
   157  	}
   158  
   159  	if len(m.info.funcDataOffsets) > 0 {
   160  		m.writeObjectToPclnTable(unsafe.Pointer(&m.info.funcDataOffsets[0]), len(m.info.funcDataOffsets)*4)
   161  	}
   162  
   163  	return nil
   164  }