Source file src/runtime/runtime1.go

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package runtime
     6  
     7  import (
     8  	"internal/abi"
     9  	"internal/bytealg"
    10  	"internal/goarch"
    11  	"internal/godebugs"
    12  	"internal/runtime/atomic"
    13  	"internal/strconv"
    14  	"unsafe"
    15  )
    16  
    17  // Keep a cached value to make gotraceback fast,
    18  // since we call it on every call to gentraceback.
    19  // The cached value is a uint32 in which the low bits
    20  // are the "crash" and "all" settings and the remaining
    21  // bits are the traceback value (0 off, 1 on, 2 include system).
    22  const (
    23  	tracebackCrash = 1 << iota
    24  	tracebackAll
    25  	tracebackShift = iota
    26  )
    27  
    28  var traceback_cache uint32 = 2 << tracebackShift
    29  var traceback_env uint32
    30  
    31  // gotraceback returns the current traceback settings.
    32  //
    33  // If level is 0, suppress all tracebacks.
    34  // If level is 1, show tracebacks, but exclude runtime frames.
    35  // If level is 2, show tracebacks including runtime frames.
    36  // If all is set, print all goroutine stacks. Otherwise, print just the current goroutine.
    37  // If crash is set, crash (core dump, etc) after tracebacking.
    38  //
    39  //go:nosplit
    40  func gotraceback() (level int32, all, crash bool) {
    41  	gp := getg()
    42  	t := atomic.Load(&traceback_cache)
    43  	crash = t&tracebackCrash != 0
    44  	all = gp.m.throwing > throwTypeUser || t&tracebackAll != 0
    45  	if gp.m.traceback != 0 {
    46  		level = int32(gp.m.traceback)
    47  	} else if gp.m.throwing >= throwTypeRuntime {
    48  		// Always include runtime frames in runtime throws unless
    49  		// otherwise overridden by m.traceback.
    50  		level = 2
    51  	} else {
    52  		level = int32(t >> tracebackShift)
    53  	}
    54  	return
    55  }
    56  
    57  var (
    58  	argc int32
    59  	argv **byte
    60  )
    61  
    62  // nosplit for use in linux startup sysargs.
    63  //
    64  //go:nosplit
    65  func argv_index(argv **byte, i int32) *byte {
    66  	return *(**byte)(add(unsafe.Pointer(argv), uintptr(i)*goarch.PtrSize))
    67  }
    68  
    69  func args(c int32, v **byte) {
    70  	argc = c
    71  	argv = v
    72  	sysargs(c, v)
    73  }
    74  
    75  func goargs() {
    76  	if GOOS == "windows" {
    77  		return
    78  	}
    79  	argslice = make([]string, argc)
    80  	for i := int32(0); i < argc; i++ {
    81  		argslice[i] = gostringnocopy(argv_index(argv, i))
    82  	}
    83  }
    84  
    85  func goenvs_unix() {
    86  	// TODO(austin): ppc64 in dynamic linking mode doesn't
    87  	// guarantee env[] will immediately follow argv. Might cause
    88  	// problems.
    89  	n := int32(0)
    90  	for argv_index(argv, argc+1+n) != nil {
    91  		n++
    92  	}
    93  
    94  	envs = make([]string, n)
    95  	for i := int32(0); i < n; i++ {
    96  		envs[i] = gostring(argv_index(argv, argc+1+i))
    97  	}
    98  }
    99  
   100  func environ() []string {
   101  	return envs
   102  }
   103  
   104  // TODO: These should be locals in testAtomic64, but we don't 8-byte
   105  // align stack variables on 386.
   106  var test_z64, test_x64 uint64
   107  
   108  func testAtomic64() {
   109  	test_z64 = 42
   110  	test_x64 = 0
   111  	if atomic.Cas64(&test_z64, test_x64, 1) {
   112  		throw("cas64 failed")
   113  	}
   114  	if test_x64 != 0 {
   115  		throw("cas64 failed")
   116  	}
   117  	test_x64 = 42
   118  	if !atomic.Cas64(&test_z64, test_x64, 1) {
   119  		throw("cas64 failed")
   120  	}
   121  	if test_x64 != 42 || test_z64 != 1 {
   122  		throw("cas64 failed")
   123  	}
   124  	if atomic.Load64(&test_z64) != 1 {
   125  		throw("load64 failed")
   126  	}
   127  	atomic.Store64(&test_z64, (1<<40)+1)
   128  	if atomic.Load64(&test_z64) != (1<<40)+1 {
   129  		throw("store64 failed")
   130  	}
   131  	if atomic.Xadd64(&test_z64, (1<<40)+1) != (2<<40)+2 {
   132  		throw("xadd64 failed")
   133  	}
   134  	if atomic.Load64(&test_z64) != (2<<40)+2 {
   135  		throw("xadd64 failed")
   136  	}
   137  	if atomic.Xchg64(&test_z64, (3<<40)+3) != (2<<40)+2 {
   138  		throw("xchg64 failed")
   139  	}
   140  	if atomic.Load64(&test_z64) != (3<<40)+3 {
   141  		throw("xchg64 failed")
   142  	}
   143  }
   144  
   145  func check() {
   146  	var (
   147  		a     int8
   148  		b     uint8
   149  		c     int16
   150  		d     uint16
   151  		e     int32
   152  		f     uint32
   153  		g     int64
   154  		h     uint64
   155  		i, i1 float32
   156  		j, j1 float64
   157  		k     unsafe.Pointer
   158  		l     *uint16
   159  		m     [4]byte
   160  	)
   161  	type x1t struct {
   162  		x uint8
   163  	}
   164  	type y1t struct {
   165  		x1 x1t
   166  		y  uint8
   167  	}
   168  	var x1 x1t
   169  	var y1 y1t
   170  
   171  	if unsafe.Sizeof(a) != 1 {
   172  		throw("bad a")
   173  	}
   174  	if unsafe.Sizeof(b) != 1 {
   175  		throw("bad b")
   176  	}
   177  	if unsafe.Sizeof(c) != 2 {
   178  		throw("bad c")
   179  	}
   180  	if unsafe.Sizeof(d) != 2 {
   181  		throw("bad d")
   182  	}
   183  	if unsafe.Sizeof(e) != 4 {
   184  		throw("bad e")
   185  	}
   186  	if unsafe.Sizeof(f) != 4 {
   187  		throw("bad f")
   188  	}
   189  	if unsafe.Sizeof(g) != 8 {
   190  		throw("bad g")
   191  	}
   192  	if unsafe.Sizeof(h) != 8 {
   193  		throw("bad h")
   194  	}
   195  	if unsafe.Sizeof(i) != 4 {
   196  		throw("bad i")
   197  	}
   198  	if unsafe.Sizeof(j) != 8 {
   199  		throw("bad j")
   200  	}
   201  	if unsafe.Sizeof(k) != goarch.PtrSize {
   202  		throw("bad k")
   203  	}
   204  	if unsafe.Sizeof(l) != goarch.PtrSize {
   205  		throw("bad l")
   206  	}
   207  	if unsafe.Sizeof(x1) != 1 {
   208  		throw("bad unsafe.Sizeof x1")
   209  	}
   210  	if unsafe.Offsetof(y1.y) != 1 {
   211  		throw("bad offsetof y1.y")
   212  	}
   213  	if unsafe.Sizeof(y1) != 2 {
   214  		throw("bad unsafe.Sizeof y1")
   215  	}
   216  
   217  	var z uint32
   218  	z = 1
   219  	if !atomic.Cas(&z, 1, 2) {
   220  		throw("cas1")
   221  	}
   222  	if z != 2 {
   223  		throw("cas2")
   224  	}
   225  
   226  	z = 4
   227  	if atomic.Cas(&z, 5, 6) {
   228  		throw("cas3")
   229  	}
   230  	if z != 4 {
   231  		throw("cas4")
   232  	}
   233  
   234  	z = 0xffffffff
   235  	if !atomic.Cas(&z, 0xffffffff, 0xfffffffe) {
   236  		throw("cas5")
   237  	}
   238  	if z != 0xfffffffe {
   239  		throw("cas6")
   240  	}
   241  
   242  	m = [4]byte{1, 1, 1, 1}
   243  	atomic.Or8(&m[1], 0xf0)
   244  	if m[0] != 1 || m[1] != 0xf1 || m[2] != 1 || m[3] != 1 {
   245  		throw("atomicor8")
   246  	}
   247  
   248  	m = [4]byte{0xff, 0xff, 0xff, 0xff}
   249  	atomic.And8(&m[1], 0x1)
   250  	if m[0] != 0xff || m[1] != 0x1 || m[2] != 0xff || m[3] != 0xff {
   251  		throw("atomicand8")
   252  	}
   253  
   254  	*(*uint64)(unsafe.Pointer(&j)) = ^uint64(0)
   255  	if j == j {
   256  		throw("float64nan")
   257  	}
   258  	if !(j != j) {
   259  		throw("float64nan1")
   260  	}
   261  
   262  	*(*uint64)(unsafe.Pointer(&j1)) = ^uint64(1)
   263  	if j == j1 {
   264  		throw("float64nan2")
   265  	}
   266  	if !(j != j1) {
   267  		throw("float64nan3")
   268  	}
   269  
   270  	*(*uint32)(unsafe.Pointer(&i)) = ^uint32(0)
   271  	if i == i {
   272  		throw("float32nan")
   273  	}
   274  	if i == i {
   275  		throw("float32nan1")
   276  	}
   277  
   278  	*(*uint32)(unsafe.Pointer(&i1)) = ^uint32(1)
   279  	if i == i1 {
   280  		throw("float32nan2")
   281  	}
   282  	if i == i1 {
   283  		throw("float32nan3")
   284  	}
   285  
   286  	testAtomic64()
   287  
   288  	if fixedStack != round2(fixedStack) {
   289  		throw("FixedStack is not power-of-2")
   290  	}
   291  }
   292  
   293  type dbgVar struct {
   294  	name   string
   295  	value  *int32        // for variables that can only be set at startup
   296  	atomic *atomic.Int32 // for variables that can be changed during execution
   297  	def    int32         // default value (ideally zero)
   298  }
   299  
   300  // Holds variables parsed from GODEBUG env var,
   301  // except for "memprofilerate" since there is an
   302  // existing int var for that value, which may
   303  // already have an initial value.
   304  var debug struct {
   305  	cgocheck                 int32
   306  	clobberfree              int32
   307  	containermaxprocs        int32
   308  	decoratemappings         int32
   309  	disablethp               int32
   310  	dontfreezetheworld       int32
   311  	efence                   int32
   312  	gccheckmark              int32
   313  	gcpacertrace             int32
   314  	gcshrinkstackoff         int32
   315  	gcstoptheworld           int32
   316  	gctrace                  int32
   317  	invalidptr               int32
   318  	madvdontneed             int32 // for Linux; issue 28466
   319  	scavtrace                int32
   320  	scheddetail              int32
   321  	schedtrace               int32
   322  	tracebackancestors       int32
   323  	updatemaxprocs           int32
   324  	asyncpreemptoff          int32
   325  	harddecommit             int32
   326  	adaptivestackstart       int32
   327  	tracefpunwindoff         int32
   328  	traceadvanceperiod       int32
   329  	traceCheckStackOwnership int32
   330  	profstackdepth           int32
   331  	dataindependenttiming    int32
   332  
   333  	// debug.malloc is used as a combined debug check
   334  	// in the malloc function and should be set
   335  	// if any of the below debug options is != 0.
   336  	malloc          bool
   337  	inittrace       int32
   338  	sbrk            int32
   339  	checkfinalizers int32
   340  	// traceallocfree controls whether execution traces contain
   341  	// detailed trace data about memory allocation. This value
   342  	// affects debug.malloc only if it is != 0 and the execution
   343  	// tracer is enabled, in which case debug.malloc will be
   344  	// set to "true" if it isn't already while tracing is enabled.
   345  	// It will be set while the world is stopped, so it's safe.
   346  	// The value of traceallocfree can be changed any time in response
   347  	// to os.Setenv("GODEBUG").
   348  	traceallocfree atomic.Int32
   349  
   350  	panicnil atomic.Int32
   351  
   352  	// tracebacklabels controls the inclusion of goroutine labels in the
   353  	// goroutine status header line.
   354  	tracebacklabels atomic.Int32
   355  }
   356  
   357  var dbgvars = []*dbgVar{
   358  	{name: "adaptivestackstart", value: &debug.adaptivestackstart},
   359  	{name: "asyncpreemptoff", value: &debug.asyncpreemptoff},
   360  	{name: "cgocheck", value: &debug.cgocheck},
   361  	{name: "clobberfree", value: &debug.clobberfree},
   362  	{name: "containermaxprocs", value: &debug.containermaxprocs, def: 1},
   363  	{name: "dataindependenttiming", value: &debug.dataindependenttiming},
   364  	{name: "decoratemappings", value: &debug.decoratemappings, def: 1},
   365  	{name: "disablethp", value: &debug.disablethp},
   366  	{name: "dontfreezetheworld", value: &debug.dontfreezetheworld},
   367  	{name: "checkfinalizers", value: &debug.checkfinalizers},
   368  	{name: "efence", value: &debug.efence},
   369  	{name: "gccheckmark", value: &debug.gccheckmark},
   370  	{name: "gcpacertrace", value: &debug.gcpacertrace},
   371  	{name: "gcshrinkstackoff", value: &debug.gcshrinkstackoff},
   372  	{name: "gcstoptheworld", value: &debug.gcstoptheworld},
   373  	{name: "gctrace", value: &debug.gctrace},
   374  	{name: "harddecommit", value: &debug.harddecommit},
   375  	{name: "inittrace", value: &debug.inittrace},
   376  	{name: "invalidptr", value: &debug.invalidptr},
   377  	{name: "madvdontneed", value: &debug.madvdontneed},
   378  	{name: "panicnil", atomic: &debug.panicnil},
   379  	{name: "profstackdepth", value: &debug.profstackdepth, def: 128},
   380  	{name: "sbrk", value: &debug.sbrk},
   381  	{name: "scavtrace", value: &debug.scavtrace},
   382  	{name: "scheddetail", value: &debug.scheddetail},
   383  	{name: "schedtrace", value: &debug.schedtrace},
   384  	{name: "traceadvanceperiod", value: &debug.traceadvanceperiod},
   385  	{name: "traceallocfree", atomic: &debug.traceallocfree},
   386  	{name: "tracecheckstackownership", value: &debug.traceCheckStackOwnership},
   387  	{name: "tracebackancestors", value: &debug.tracebackancestors},
   388  	{name: "tracebacklabels", atomic: &debug.tracebacklabels, def: 1},
   389  	{name: "tracefpunwindoff", value: &debug.tracefpunwindoff},
   390  	{name: "updatemaxprocs", value: &debug.updatemaxprocs, def: 1},
   391  }
   392  
   393  func parseRuntimeDebugVars(godebug string) {
   394  	// defaults
   395  	debug.cgocheck = 1
   396  	debug.invalidptr = 1
   397  	debug.adaptivestackstart = 1 // set this to 0 to turn larger initial goroutine stacks off
   398  	if GOOS == "linux" {
   399  		// On Linux, MADV_FREE is faster than MADV_DONTNEED,
   400  		// but doesn't affect many of the statistics that
   401  		// MADV_DONTNEED does until the memory is actually
   402  		// reclaimed. This generally leads to poor user
   403  		// experience, like confusing stats in top and other
   404  		// monitoring tools; and bad integration with
   405  		// management systems that respond to memory usage.
   406  		// Hence, default to MADV_DONTNEED.
   407  		debug.madvdontneed = 1
   408  	}
   409  	debug.traceadvanceperiod = defaultTraceAdvancePeriod
   410  
   411  	// apply runtime defaults, if any
   412  	for _, v := range dbgvars {
   413  		if v.def != 0 {
   414  			// Every var should have either v.value or v.atomic set.
   415  			if v.value != nil {
   416  				*v.value = v.def
   417  			} else if v.atomic != nil {
   418  				v.atomic.Store(v.def)
   419  			}
   420  		}
   421  	}
   422  	// apply compile-time GODEBUG settings
   423  	parsegodebug(godebugDefault, nil)
   424  
   425  	// apply environment settings
   426  	parsegodebug(godebug, nil)
   427  
   428  	debug.malloc = (debug.inittrace | debug.sbrk | debug.checkfinalizers) != 0
   429  	debug.profstackdepth = min(debug.profstackdepth, maxProfStackDepth)
   430  
   431  	// Disable async preemption in checkmark mode. The following situation is
   432  	// problematic with checkmark mode:
   433  	//
   434  	// - The GC doesn't mark object A because it is truly dead.
   435  	// - The GC stops the world, asynchronously preempting G1 which has a reference
   436  	//   to A in its top stack frame
   437  	// - During the stop the world, we run the second checkmark GC. It marks the roots
   438  	//   and discovers A through G1.
   439  	// - Checkmark mode reports a failure since there's a discrepancy in mark metadata.
   440  	//
   441  	// We could disable just conservative scanning during the checkmark scan, which is
   442  	// safe but makes checkmark slightly less powerful, but that's a lot more invasive
   443  	// than just disabling async preemption altogether.
   444  	if debug.gccheckmark > 0 {
   445  		debug.asyncpreemptoff = 1
   446  	}
   447  }
   448  
   449  func finishDebugVarsSetup() {
   450  	p := new(string)
   451  	*p = gogetenv("GODEBUG")
   452  	godebugEnv.Store(p)
   453  
   454  	setTraceback(gogetenv("GOTRACEBACK"))
   455  	traceback_env = traceback_cache
   456  }
   457  
   458  // reparsedebugvars reparses the runtime's debug variables
   459  // because the environment variable has been changed to env.
   460  func reparsedebugvars(env string) {
   461  	seen := make(map[string]bool)
   462  	// apply environment settings
   463  	parsegodebug(env, seen)
   464  	// apply compile-time GODEBUG settings for as-yet-unseen variables
   465  	parsegodebug(godebugDefault, seen)
   466  	// apply defaults for as-yet-unseen variables
   467  	for _, v := range dbgvars {
   468  		if v.atomic != nil && !seen[v.name] {
   469  			v.atomic.Store(0)
   470  		}
   471  	}
   472  }
   473  
   474  // If an invalid GODEBUG setting is found during startup time,
   475  // invalidGODEBUG is set to that setting so it can be reported
   476  // when initialization has progressed sufficiently.
   477  var invalidGODEBUG struct {
   478  	key, value string
   479  }
   480  
   481  // parsegodebug parses the godebug string, updating variables listed in dbgvars.
   482  // If seen == nil, this is startup time and we process the string left to right
   483  // overwriting older settings with newer ones.
   484  // If seen != nil, $GODEBUG has changed and we are doing an
   485  // incremental update. To avoid flapping in the case where a value is
   486  // set multiple times (perhaps in the default and the environment,
   487  // or perhaps twice in the environment), we process the string right-to-left
   488  // and only change values not already seen. After doing this for both
   489  // the environment and the default settings, the caller must also call
   490  // cleargodebug(seen) to reset any now-unset values back to their defaults.
   491  func parsegodebug(godebug string, seen map[string]bool) {
   492  	for p := godebug; p != ""; {
   493  		var field string
   494  		if seen == nil {
   495  			// startup: process left to right, overwriting older settings with newer
   496  			i := bytealg.IndexByteString(p, ',')
   497  			if i < 0 {
   498  				field, p = p, ""
   499  			} else {
   500  				field, p = p[:i], p[i+1:]
   501  			}
   502  		} else {
   503  			// incremental update: process right to left, updating and skipping seen
   504  			i := len(p) - 1
   505  			for i >= 0 && p[i] != ',' {
   506  				i--
   507  			}
   508  			if i < 0 {
   509  				p, field = "", p
   510  			} else {
   511  				p, field = p[:i], p[i+1:]
   512  			}
   513  		}
   514  		i := bytealg.IndexByteString(field, '=')
   515  		if i < 0 {
   516  			continue
   517  		}
   518  		key, value := field[:i], field[i+1:]
   519  
   520  		// Setting a removed GODEBUG is ok unless it's set to an old value.
   521  		// We only check at startup time per go.dev/issue/76163.
   522  		if seen == nil {
   523  			for _, info := range godebugs.Removed {
   524  				if info.Name == key {
   525  					if info.Old(value) {
   526  						invalidGODEBUG.key = key
   527  						invalidGODEBUG.value = value
   528  						return // this skips the cgocheck below but we're about to fatal anyway
   529  					}
   530  					break
   531  				}
   532  			}
   533  		}
   534  
   535  		if seen[key] {
   536  			continue
   537  		}
   538  		if seen != nil {
   539  			seen[key] = true
   540  		}
   541  
   542  		// Update MemProfileRate directly here since it
   543  		// is int, not int32, and should only be updated
   544  		// if specified in GODEBUG.
   545  		if seen == nil && key == "memprofilerate" {
   546  			if n, err := strconv.Atoi(value); err == nil {
   547  				MemProfileRate = n
   548  			}
   549  		} else {
   550  			for _, v := range dbgvars {
   551  				if v.name == key {
   552  					if n, err := strconv.ParseInt(value, 10, 32); err == nil {
   553  						if seen == nil && v.value != nil {
   554  							*v.value = int32(n)
   555  						} else if v.atomic != nil {
   556  							v.atomic.Store(int32(n))
   557  						}
   558  					}
   559  				}
   560  			}
   561  		}
   562  	}
   563  
   564  	if debug.cgocheck > 1 {
   565  		throw("cgocheck > 1 mode is no longer supported at runtime. Use GOEXPERIMENT=cgocheck2 at build time instead.")
   566  	}
   567  }
   568  
   569  //go:linkname setTraceback runtime/debug.SetTraceback
   570  func setTraceback(level string) {
   571  	var t uint32
   572  	switch level {
   573  	case "none":
   574  		t = 0
   575  	case "single", "":
   576  		t = 1 << tracebackShift
   577  	case "all":
   578  		t = 1<<tracebackShift | tracebackAll
   579  	case "system":
   580  		t = 2<<tracebackShift | tracebackAll
   581  	case "crash":
   582  		t = 2<<tracebackShift | tracebackAll | tracebackCrash
   583  	case "wer":
   584  		if GOOS == "windows" {
   585  			t = 2<<tracebackShift | tracebackAll | tracebackCrash
   586  			enableWER()
   587  			break
   588  		}
   589  		fallthrough
   590  	default:
   591  		t = tracebackAll
   592  		if n, err := strconv.Atoi(level); err == nil && n == int(uint32(n)) {
   593  			t |= uint32(n) << tracebackShift
   594  		}
   595  	}
   596  	// when C owns the process, simply exit'ing the process on fatal errors
   597  	// and panics is surprising. Be louder and abort instead.
   598  	if islibrary || isarchive {
   599  		t |= tracebackCrash
   600  	}
   601  
   602  	t |= traceback_env
   603  
   604  	atomic.Store(&traceback_cache, t)
   605  }
   606  
   607  // Helpers for Go. Must be NOSPLIT, must only call NOSPLIT functions, and must not block.
   608  
   609  //go:nosplit
   610  func acquirem() *m {
   611  	gp := getg()
   612  	gp.m.locks++
   613  	return gp.m
   614  }
   615  
   616  //go:nosplit
   617  func releasem(mp *m) {
   618  	gp := getg()
   619  	mp.locks--
   620  	if mp.locks == 0 && gp.preempt {
   621  		// restore the preemption request in case we've cleared it in newstack
   622  		gp.stackguard0 = stackPreempt
   623  	}
   624  }
   625  
   626  // reflect_typelinks is meant for package reflect,
   627  // but widely used packages access it using linkname.
   628  // Notable members of the hall of shame include:
   629  //   - gitee.com/quant1x/gox
   630  //   - github.com/goccy/json
   631  //   - github.com/modern-go/reflect2
   632  //   - github.com/vmware/govmomi
   633  //   - github.com/pinpoint-apm/pinpoint-go-agent
   634  //   - github.com/timandy/routine
   635  //   - github.com/v2pro/plz
   636  //
   637  // Do not remove or change the type signature.
   638  // See go.dev/issue/67401.
   639  //
   640  // This is obsolete and only remains for external packages.
   641  // New code should use reflect_compiledTypelinks.
   642  //
   643  //go:linkname reflect_typelinks reflect.typelinks
   644  func reflect_typelinks() ([]unsafe.Pointer, [][]int32) {
   645  	modules := activeModules()
   646  
   647  	typesToOffsets := func(md *moduledata) []int32 {
   648  		types := moduleTypelinks(md)
   649  		ret := make([]int32, 0, len(types))
   650  		for _, typ := range types {
   651  			ret = append(ret, int32(uintptr(unsafe.Pointer(typ))-md.types))
   652  		}
   653  		return ret
   654  	}
   655  
   656  	sections := []unsafe.Pointer{unsafe.Pointer(modules[0].types)}
   657  	ret := [][]int32{typesToOffsets(modules[0])}
   658  	for _, md := range modules[1:] {
   659  		sections = append(sections, unsafe.Pointer(md.types))
   660  		ret = append(ret, typesToOffsets(md))
   661  	}
   662  	return sections, ret
   663  }
   664  
   665  // reflect_compiledTypelinks returns the typelink types
   666  // generated by the compiler for all current modules.
   667  // The normal case is a single module, so this returns one
   668  // slice for the main module, and a slice of slices, normally nil,
   669  // for other modules.
   670  //
   671  //go:linknamestd reflect_compiledTypelinks reflect.compiledTypelinks
   672  func reflect_compiledTypelinks() ([]*abi.Type, [][]*abi.Type) {
   673  	modules := activeModules()
   674  	firstTypes := moduleTypelinks(modules[0])
   675  	var rest [][]*abi.Type
   676  	for _, md := range modules[1:] {
   677  		rest = append(rest, moduleTypelinks(md))
   678  	}
   679  	return firstTypes, rest
   680  }
   681  
   682  // reflect_resolveNameOff resolves a name offset from a base pointer.
   683  //
   684  // reflect_resolveNameOff is for package reflect,
   685  // but widely used packages access it using linkname.
   686  // Notable members of the hall of shame include:
   687  //   - github.com/agiledragon/gomonkey/v2
   688  //
   689  // Do not remove or change the type signature.
   690  // See go.dev/issue/67401.
   691  //
   692  //go:linkname reflect_resolveNameOff reflect.resolveNameOff
   693  func reflect_resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer {
   694  	return unsafe.Pointer(resolveNameOff(ptrInModule, nameOff(off)).Bytes)
   695  }
   696  
   697  // reflect_resolveTypeOff resolves an *rtype offset from a base type.
   698  //
   699  // reflect_resolveTypeOff is meant for package reflect,
   700  // but widely used packages access it using linkname.
   701  // Notable members of the hall of shame include:
   702  //   - gitee.com/quant1x/gox
   703  //   - github.com/modern-go/reflect2
   704  //   - github.com/v2pro/plz
   705  //   - github.com/timandy/routine
   706  //
   707  // Do not remove or change the type signature.
   708  // See go.dev/issue/67401.
   709  //
   710  //go:linkname reflect_resolveTypeOff reflect.resolveTypeOff
   711  func reflect_resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
   712  	return unsafe.Pointer(toRType((*_type)(rtype)).typeOff(typeOff(off)))
   713  }
   714  
   715  // reflect_resolveTextOff resolves a function pointer offset from a base type.
   716  //
   717  // reflect_resolveTextOff is for package reflect,
   718  // but widely used packages access it using linkname.
   719  // Notable members of the hall of shame include:
   720  //   - github.com/agiledragon/gomonkey/v2
   721  //
   722  // Do not remove or change the type signature.
   723  // See go.dev/issue/67401.
   724  //
   725  //go:linkname reflect_resolveTextOff reflect.resolveTextOff
   726  func reflect_resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
   727  	return toRType((*_type)(rtype)).textOff(textOff(off))
   728  }
   729  
   730  // reflectlite_resolveNameOff resolves a name offset from a base pointer.
   731  //
   732  //go:linkname reflectlite_resolveNameOff internal/reflectlite.resolveNameOff
   733  func reflectlite_resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer {
   734  	return unsafe.Pointer(resolveNameOff(ptrInModule, nameOff(off)).Bytes)
   735  }
   736  
   737  // reflectlite_resolveTypeOff resolves an *rtype offset from a base type.
   738  //
   739  //go:linkname reflectlite_resolveTypeOff internal/reflectlite.resolveTypeOff
   740  func reflectlite_resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
   741  	return unsafe.Pointer(toRType((*_type)(rtype)).typeOff(typeOff(off)))
   742  }
   743  
   744  // reflect_addReflectOff adds a pointer to the reflection offset lookup map.
   745  //
   746  //go:linkname reflect_addReflectOff reflect.addReflectOff
   747  func reflect_addReflectOff(ptr unsafe.Pointer) int32 {
   748  	reflectOffsLock()
   749  	if reflectOffs.m == nil {
   750  		reflectOffs.m = make(map[int32]unsafe.Pointer)
   751  		reflectOffs.minv = make(map[unsafe.Pointer]int32)
   752  		reflectOffs.next = -1
   753  	}
   754  	id, found := reflectOffs.minv[ptr]
   755  	if !found {
   756  		id = reflectOffs.next
   757  		reflectOffs.next-- // use negative offsets as IDs to aid debugging
   758  		reflectOffs.m[id] = ptr
   759  		reflectOffs.minv[ptr] = id
   760  	}
   761  	reflectOffsUnlock()
   762  	return id
   763  }
   764  
   765  // reflect_adjustAIXGCDataForRuntime takes a type.GCData address and returns
   766  // the new address to use. This is only called on AIX.
   767  // See getGCMaskOnDemand.
   768  //
   769  //go:linknamestd reflect_adjustAIXGCDataForRuntime reflect.adjustAIXGCDataForRuntime
   770  func reflect_adjustAIXGCDataForRuntime(addr *byte) *byte {
   771  	return (*byte)(add(unsafe.Pointer(addr), aixStaticDataBase-firstmoduledata.data))
   772  }
   773  
   774  //go:linkname fips_getIndicator crypto/internal/fips140.getIndicator
   775  func fips_getIndicator() uint8 {
   776  	return getg().fipsIndicator
   777  }
   778  
   779  //go:linkname fips_setIndicator crypto/internal/fips140.setIndicator
   780  func fips_setIndicator(indicator uint8) {
   781  	getg().fipsIndicator = indicator
   782  }
   783  

View as plain text