github.com/szmcdull/go-forceexport@v0.0.0-20230908151957-3dac42f564da/go_1_18.go (about)

     1  //go:build go1.18 && !go1.21
     2  // +build go1.18,!go1.21
     3  
     4  package forceexport
     5  
     6  import (
     7  	"runtime"
     8  	"unsafe"
     9  )
    10  
    11  type (
    12  
    13  	// pcHeader holds data used by the pclntab lookups.
    14  	pcHeader struct {
    15  		magic          uint32  // 0xFFFFFFF0
    16  		pad1, pad2     uint8   // 0,0
    17  		minLC          uint8   // min instruction size
    18  		ptrSize        uint8   // size of a ptr in bytes
    19  		nfunc          int     // number of functions in the module
    20  		nfiles         uint    // number of entries in the file tab
    21  		textStart      uintptr // base for function entry PC offsets in this module, equal to moduledata.text
    22  		funcnameOffset uintptr // offset to the funcnametab variable from pcHeader
    23  		cuOffset       uintptr // offset to the cutab variable from pcHeader
    24  		filetabOffset  uintptr // offset to the filetab variable from pcHeader
    25  		pctabOffset    uintptr // offset to the pctab variable from pcHeader
    26  		pclnOffset     uintptr // offset to the pclntab variable from pcHeader
    27  	}
    28  
    29  	newModuleWrapper moduledata
    30  
    31  	Moduledata struct {
    32  		pcHeader *pcHeader
    33  	}
    34  
    35  	Functab1_18 struct {
    36  		entry   uint32
    37  		funcoff uint32
    38  	}
    39  )
    40  
    41  // moduledata records information about the layout of the executable
    42  // image. It is written by the linker. Any changes here must be
    43  // matched changes to the code in cmd/link/internal/ld/symtab.go:symtab.
    44  // moduledata is stored in statically allocated non-pointer memory;
    45  // none of the pointers here are visible to the garbage collector.
    46  type moduledata struct {
    47  	pcHeader     *pcHeader
    48  	funcnametab  []byte
    49  	cutab        []uint32
    50  	filetab      []byte
    51  	pctab        []byte
    52  	pclntable    []byte
    53  	ftab         []functab
    54  	findfunctab  uintptr
    55  	minpc, maxpc uintptr
    56  
    57  	text, etext           uintptr
    58  	noptrdata, enoptrdata uintptr
    59  	data, edata           uintptr
    60  	bss, ebss             uintptr
    61  	noptrbss, enoptrbss   uintptr
    62  	end, gcdata, gcbss    uintptr
    63  	types, etypes         uintptr
    64  	rodata                uintptr
    65  	gofunc                uintptr // go.func.*
    66  
    67  	textsectmap []textsect
    68  	typelinks   []int32 // offsets from types
    69  	itablinks   []*itab
    70  
    71  	ptab []ptabEntry
    72  
    73  	pluginpath string
    74  	pkghashes  []modulehash
    75  
    76  	modulename   string
    77  	modulehashes []modulehash
    78  
    79  	hasmain uint8 // 1 if module contains the main function, 0 otherwise
    80  
    81  	gcdatamask, gcbssmask bitvector
    82  
    83  	typemap map[typeOff]*_type // offset to *_rtype in previous module
    84  
    85  	bad bool // module failed to load and should be ignored
    86  
    87  	next *moduledata
    88  }
    89  
    90  type functab struct {
    91  	entryoff uint32 // relative to runtime.text
    92  	funcoff  uint32
    93  }
    94  
    95  // Mapping information for secondary text sections
    96  
    97  type textsect struct {
    98  	vaddr    uintptr // prelinked section vaddr
    99  	end      uintptr // vaddr + section length
   100  	baseaddr uintptr // relocated section address
   101  }
   102  
   103  // layout of Itab known to compilers
   104  // allocated in non-garbage-collected memory
   105  // Needs to be in sync with
   106  // ../cmd/compile/internal/reflectdata/reflect.go:/^func.WriteTabs.
   107  type itab struct {
   108  	inter *interfacetype
   109  	_type *_type
   110  	hash  uint32 // copy of _type.hash. Used for type switches.
   111  	_     [4]byte
   112  	fun   [1]uintptr // variable sized. fun[0]==0 means _type does not implement inter.
   113  }
   114  
   115  type interfacetype struct {
   116  	typ     _type
   117  	pkgpath name
   118  	mhdr    []imethod
   119  }
   120  
   121  // Needs to be in sync with ../cmd/link/internal/ld/decodesym.go:/^func.commonsize,
   122  // ../cmd/compile/internal/reflectdata/reflect.go:/^func.dcommontype and
   123  // ../reflect/type.go:/^type.rtype.
   124  // ../internal/reflectlite/type.go:/^type.rtype.
   125  type _type struct {
   126  	size       uintptr
   127  	ptrdata    uintptr // size of memory prefix holding all pointers
   128  	hash       uint32
   129  	tflag      tflag
   130  	align      uint8
   131  	fieldAlign uint8
   132  	kind       uint8
   133  	// function for comparing objects of this type
   134  	// (ptr to object A, ptr to object B) -> ==?
   135  	equal func(unsafe.Pointer, unsafe.Pointer) bool
   136  	// gcdata stores the GC type data for the garbage collector.
   137  	// If the KindGCProg bit is set in kind, gcdata is a GC program.
   138  	// Otherwise it is a ptrmask bitmap. See mbitmap.go for details.
   139  	gcdata    *byte
   140  	str       nameOff
   141  	ptrToThis typeOff
   142  }
   143  
   144  type nameOff int32
   145  type typeOff int32
   146  type textOff int32
   147  
   148  // A ptabEntry is generated by the compiler for each exported function
   149  // and global variable in the main package of a plugin. It is used to
   150  // initialize the plugin module's symbol map.
   151  type ptabEntry struct {
   152  	name nameOff
   153  	typ  typeOff
   154  }
   155  
   156  // A modulehash is used to compare the ABI of a new module or a
   157  // package in a new module with the loaded program.
   158  //
   159  // For each shared library a module links against, the linker creates an entry in the
   160  // moduledata.modulehashes slice containing the name of the module, the abi hash seen
   161  // at link time and a pointer to the runtime abi hash. These are checked in
   162  // moduledataverify1 below.
   163  //
   164  // For each loaded plugin, the pkghashes slice has a modulehash of the
   165  // newly loaded package that can be used to check the plugin's version of
   166  // a package against any previously loaded version of the package.
   167  // This is done in plugin.lastmoduleinit.
   168  type modulehash struct {
   169  	modulename   string
   170  	linktimehash string
   171  	runtimehash  *string
   172  }
   173  
   174  // name is an encoded type name with optional extra data.
   175  // See reflect/type.go for details.
   176  type name struct {
   177  	bytes *byte
   178  }
   179  
   180  type imethod struct {
   181  	name nameOff
   182  	ityp typeOff
   183  }
   184  
   185  // tflag is documented in reflect/type.go.
   186  //
   187  // tflag values must be kept in sync with copies in:
   188  //
   189  //		cmd/compile/internal/reflectdata/reflect.go
   190  //		cmd/link/internal/ld/decodesym.go
   191  //		reflect/type.go
   192  //	     internal/reflectlite/type.go
   193  type tflag uint8
   194  
   195  func (me *newModuleWrapper) GetNext() moduleWrapper {
   196  	if me.next != nil {
   197  		return (*newModuleWrapper)(me.next)
   198  	}
   199  	return nil
   200  }
   201  
   202  func (me *newModuleWrapper) GetFtab() []functab {
   203  	return me.ftab
   204  }
   205  
   206  func (me *newModuleWrapper) GetFunc(ftab functab) *runtime.Func {
   207  	ftab1_18 := (*Functab1_18)(unsafe.Pointer(&ftab))
   208  	return (*runtime.Func)(unsafe.Pointer(uintptr(unsafe.Pointer(me.pcHeader)) + uintptr(me.pcHeader.pclnOffset) + uintptr(ftab1_18.funcoff)))
   209  	//return (*runtime.Func)(unsafe.Pointer(&(*pcIntable)[ftab.funcoff]))
   210  }
   211  
   212  func getModuleWrapper() moduleWrapper {
   213  	new1_18 := (*newModuleWrapper)(unsafe.Pointer(&Firstmoduledata))
   214  	return new1_18
   215  }
   216  
   217  //go:linkname Firstmoduledata runtime.firstmoduledata
   218  var Firstmoduledata Moduledata