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  	tracebackcrash           int32
   324  	updatemaxprocs           int32
   325  	asyncpreemptoff          int32
   326  	harddecommit             int32
   327  	adaptivestackstart       int32
   328  	tracefpunwindoff         int32
   329  	traceadvanceperiod       int32
   330  	traceCheckStackOwnership int32
   331  	profstackdepth           int32
   332  	dataindependenttiming    int32
   333  
   334  	// debug.malloc is used as a combined debug check
   335  	// in the malloc function and should be set
   336  	// if any of the below debug options is != 0.
   337  	malloc          bool
   338  	inittrace       int32
   339  	sbrk            int32
   340  	checkfinalizers int32
   341  	// traceallocfree controls whether execution traces contain
   342  	// detailed trace data about memory allocation. This value
   343  	// affects debug.malloc only if it is != 0 and the execution
   344  	// tracer is enabled, in which case debug.malloc will be
   345  	// set to "true" if it isn't already while tracing is enabled.
   346  	// It will be set while the world is stopped, so it's safe.
   347  	// The value of traceallocfree can be changed any time in response
   348  	// to os.Setenv("GODEBUG").
   349  	traceallocfree atomic.Int32
   350  
   351  	panicnil atomic.Int32
   352  
   353  	// tracebacklabels controls the inclusion of goroutine labels in the
   354  	// goroutine status header line.
   355  	tracebacklabels atomic.Int32
   356  }
   357  
   358  var dbgvars = []*dbgVar{
   359  	{name: "adaptivestackstart", value: &debug.adaptivestackstart},
   360  	{name: "asyncpreemptoff", value: &debug.asyncpreemptoff},
   361  	{name: "cgocheck", value: &debug.cgocheck},
   362  	{name: "clobberfree", value: &debug.clobberfree},
   363  	{name: "containermaxprocs", value: &debug.containermaxprocs, def: 1},
   364  	{name: "dataindependenttiming", value: &debug.dataindependenttiming},
   365  	{name: "decoratemappings", value: &debug.decoratemappings, def: 1},
   366  	{name: "disablethp", value: &debug.disablethp},
   367  	{name: "dontfreezetheworld", value: &debug.dontfreezetheworld},
   368  	{name: "checkfinalizers", value: &debug.checkfinalizers},
   369  	{name: "efence", value: &debug.efence},
   370  	{name: "gccheckmark", value: &debug.gccheckmark},
   371  	{name: "gcpacertrace", value: &debug.gcpacertrace},
   372  	{name: "gcshrinkstackoff", value: &debug.gcshrinkstackoff},
   373  	{name: "gcstoptheworld", value: &debug.gcstoptheworld},
   374  	{name: "gctrace", value: &debug.gctrace},
   375  	{name: "harddecommit", value: &debug.harddecommit},
   376  	{name: "inittrace", value: &debug.inittrace},
   377  	{name: "invalidptr", value: &debug.invalidptr},
   378  	{name: "madvdontneed", value: &debug.madvdontneed},
   379  	{name: "panicnil", atomic: &debug.panicnil},
   380  	{name: "profstackdepth", value: &debug.profstackdepth, def: 128},
   381  	{name: "sbrk", value: &debug.sbrk},
   382  	{name: "scavtrace", value: &debug.scavtrace},
   383  	{name: "scheddetail", value: &debug.scheddetail},
   384  	{name: "schedtrace", value: &debug.schedtrace},
   385  	{name: "traceadvanceperiod", value: &debug.traceadvanceperiod},
   386  	{name: "traceallocfree", atomic: &debug.traceallocfree},
   387  	{name: "tracecheckstackownership", value: &debug.traceCheckStackOwnership},
   388  	{name: "tracebackancestors", value: &debug.tracebackancestors},
   389  	{name: "tracebackcrash", value: &debug.tracebackcrash},
   390  	{name: "tracebacklabels", atomic: &debug.tracebacklabels, def: 1},
   391  	{name: "tracefpunwindoff", value: &debug.tracefpunwindoff},
   392  	{name: "updatemaxprocs", value: &debug.updatemaxprocs, def: 1},
   393  }
   394  
   395  func parseRuntimeDebugVars(godebug string) {
   396  	// defaults
   397  	debug.cgocheck = 1
   398  	debug.invalidptr = 1
   399  	debug.adaptivestackstart = 1 // set this to 0 to turn larger initial goroutine stacks off
   400  	if GOOS == "linux" {
   401  		// On Linux, MADV_FREE is faster than MADV_DONTNEED,
   402  		// but doesn't affect many of the statistics that
   403  		// MADV_DONTNEED does until the memory is actually
   404  		// reclaimed. This generally leads to poor user
   405  		// experience, like confusing stats in top and other
   406  		// monitoring tools; and bad integration with
   407  		// management systems that respond to memory usage.
   408  		// Hence, default to MADV_DONTNEED.
   409  		debug.madvdontneed = 1
   410  	}
   411  	debug.traceadvanceperiod = defaultTraceAdvancePeriod
   412  
   413  	// apply runtime defaults, if any
   414  	for _, v := range dbgvars {
   415  		if v.def != 0 {
   416  			// Every var should have either v.value or v.atomic set.
   417  			if v.value != nil {
   418  				*v.value = v.def
   419  			} else if v.atomic != nil {
   420  				v.atomic.Store(v.def)
   421  			}
   422  		}
   423  	}
   424  	// apply compile-time GODEBUG settings
   425  	parsegodebug(godebugDefault, nil)
   426  
   427  	// apply environment settings
   428  	parsegodebug(godebug, nil)
   429  
   430  	debug.malloc = (debug.inittrace | debug.sbrk | debug.checkfinalizers) != 0
   431  	debug.profstackdepth = min(debug.profstackdepth, maxProfStackDepth)
   432  
   433  	// Disable async preemption in checkmark mode. The following situation is
   434  	// problematic with checkmark mode:
   435  	//
   436  	// - The GC doesn't mark object A because it is truly dead.
   437  	// - The GC stops the world, asynchronously preempting G1 which has a reference
   438  	//   to A in its top stack frame
   439  	// - During the stop the world, we run the second checkmark GC. It marks the roots
   440  	//   and discovers A through G1.
   441  	// - Checkmark mode reports a failure since there's a discrepancy in mark metadata.
   442  	//
   443  	// We could disable just conservative scanning during the checkmark scan, which is
   444  	// safe but makes checkmark slightly less powerful, but that's a lot more invasive
   445  	// than just disabling async preemption altogether.
   446  	if debug.gccheckmark > 0 {
   447  		debug.asyncpreemptoff = 1
   448  	}
   449  }
   450  
   451  func finishDebugVarsSetup() {
   452  	p := new(string)
   453  	*p = gogetenv("GODEBUG")
   454  	godebugEnv.Store(p)
   455  
   456  	setTraceback(gogetenv("GOTRACEBACK"))
   457  	traceback_env = traceback_cache
   458  }
   459  
   460  // reparsedebugvars reparses the runtime's debug variables
   461  // because the environment variable has been changed to env.
   462  func reparsedebugvars(env string) {
   463  	seen := make(map[string]bool)
   464  	// apply environment settings
   465  	parsegodebug(env, seen)
   466  	// apply compile-time GODEBUG settings for as-yet-unseen variables
   467  	parsegodebug(godebugDefault, seen)
   468  	// apply defaults for as-yet-unseen variables
   469  	for _, v := range dbgvars {
   470  		if v.atomic != nil && !seen[v.name] {
   471  			v.atomic.Store(0)
   472  		}
   473  	}
   474  }
   475  
   476  // If an invalid GODEBUG setting is found during startup time,
   477  // invalidGODEBUG is set to that setting so it can be reported
   478  // when initialization has progressed sufficiently.
   479  var invalidGODEBUG struct {
   480  	key, value string
   481  	removed    int
   482  }
   483  
   484  // parsegodebug parses the godebug string, updating variables listed in dbgvars.
   485  // If seen == nil, this is startup time and we process the string left to right
   486  // overwriting older settings with newer ones.
   487  // If seen != nil, $GODEBUG has changed and we are doing an
   488  // incremental update. To avoid flapping in the case where a value is
   489  // set multiple times (perhaps in the default and the environment,
   490  // or perhaps twice in the environment), we process the string right-to-left
   491  // and only change values not already seen. After doing this for both
   492  // the environment and the default settings, the caller must also call
   493  // cleargodebug(seen) to reset any now-unset values back to their defaults.
   494  func parsegodebug(godebug string, seen map[string]bool) {
   495  	for p := godebug; p != ""; {
   496  		var field string
   497  		if seen == nil {
   498  			// startup: process left to right, overwriting older settings with newer
   499  			i := bytealg.IndexByteString(p, ',')
   500  			if i < 0 {
   501  				field, p = p, ""
   502  			} else {
   503  				field, p = p[:i], p[i+1:]
   504  			}
   505  		} else {
   506  			// incremental update: process right to left, updating and skipping seen
   507  			i := len(p) - 1
   508  			for i >= 0 && p[i] != ',' {
   509  				i--
   510  			}
   511  			if i < 0 {
   512  				p, field = "", p
   513  			} else {
   514  				p, field = p[:i], p[i+1:]
   515  			}
   516  		}
   517  		i := bytealg.IndexByteString(field, '=')
   518  		if i < 0 {
   519  			continue
   520  		}
   521  		key, value := field[:i], field[i+1:]
   522  
   523  		// Setting a removed GODEBUG is ok unless it's set to an old value.
   524  		// We only check at startup time per go.dev/issue/76163.
   525  		if seen == nil {
   526  			for _, info := range godebugs.Removed {
   527  				if info.Name == key {
   528  					if info.Old(value) {
   529  						invalidGODEBUG.key = key
   530  						invalidGODEBUG.value = value
   531  						invalidGODEBUG.removed = info.Removed
   532  						return // this skips the cgocheck below but we're about to fatal anyway
   533  					}
   534  					break
   535  				}
   536  			}
   537  		}
   538  
   539  		if seen[key] {
   540  			continue
   541  		}
   542  		if seen != nil {
   543  			seen[key] = true
   544  		}
   545  
   546  		// Update MemProfileRate directly here since it
   547  		// is int, not int32, and should only be updated
   548  		// if specified in GODEBUG.
   549  		if seen == nil && key == "memprofilerate" {
   550  			if n, err := strconv.Atoi(value); err == nil {
   551  				MemProfileRate = n
   552  			}
   553  		} else {
   554  			for _, v := range dbgvars {
   555  				if v.name == key {
   556  					if n, err := strconv.ParseInt(value, 10, 32); err == nil {
   557  						if seen == nil && v.value != nil {
   558  							*v.value = int32(n)
   559  						} else if v.atomic != nil {
   560  							v.atomic.Store(int32(n))
   561  						}
   562  					}
   563  				}
   564  			}
   565  		}
   566  	}
   567  
   568  	if debug.cgocheck > 1 {
   569  		throw("cgocheck > 1 mode is no longer supported at runtime. Use GOEXPERIMENT=cgocheck2 at build time instead.")
   570  	}
   571  }
   572  
   573  //go:linkname setTraceback runtime/debug.SetTraceback
   574  func setTraceback(level string) {
   575  	var t uint32
   576  	switch level {
   577  	case "none":
   578  		t = 0
   579  	case "single", "":
   580  		t = 1 << tracebackShift
   581  	case "all":
   582  		t = 1<<tracebackShift | tracebackAll
   583  	case "system":
   584  		t = 2<<tracebackShift | tracebackAll
   585  	case "crash":
   586  		t = 2<<tracebackShift | tracebackAll | tracebackCrash
   587  	case "wer":
   588  		if GOOS == "windows" {
   589  			t = 2<<tracebackShift | tracebackAll | tracebackCrash
   590  			enableWER()
   591  			break
   592  		}
   593  		fallthrough
   594  	default:
   595  		t = tracebackAll
   596  		if n, err := strconv.Atoi(level); err == nil && n == int(uint32(n)) {
   597  			t |= uint32(n) << tracebackShift
   598  		}
   599  	}
   600  	// when C owns the process, simply exit'ing the process on fatal errors
   601  	// and panics is surprising. Be louder and abort instead.
   602  	if islibrary || isarchive {
   603  		t |= tracebackCrash
   604  	}
   605  
   606  	t |= traceback_env
   607  
   608  	atomic.Store(&traceback_cache, t)
   609  }
   610  
   611  // Helpers for Go. Must be NOSPLIT, must only call NOSPLIT functions, and must not block.
   612  
   613  //go:nosplit
   614  func acquirem() *m {
   615  	gp := getg()
   616  	gp.m.locks++
   617  	return gp.m
   618  }
   619  
   620  //go:nosplit
   621  func releasem(mp *m) {
   622  	gp := getg()
   623  	mp.locks--
   624  	if mp.locks == 0 && gp.preempt {
   625  		// restore the preemption request in case we've cleared it in newstack
   626  		gp.stackguard0 = stackPreempt
   627  	}
   628  }
   629  
   630  // reflect_typelinks is meant for package reflect,
   631  // but widely used packages access it using linkname.
   632  // Notable members of the hall of shame include:
   633  //   - gitee.com/quant1x/gox
   634  //   - github.com/goccy/json
   635  //   - github.com/modern-go/reflect2
   636  //   - github.com/vmware/govmomi
   637  //   - github.com/pinpoint-apm/pinpoint-go-agent
   638  //   - github.com/timandy/routine
   639  //   - github.com/v2pro/plz
   640  //
   641  // Do not remove or change the type signature.
   642  // See go.dev/issue/67401.
   643  //
   644  // This is obsolete and only remains for external packages.
   645  // New code should use reflect_compiledTypelinks.
   646  //
   647  //go:linkname reflect_typelinks reflect.typelinks
   648  func reflect_typelinks() ([]unsafe.Pointer, [][]int32) {
   649  	modules := activeModules()
   650  
   651  	typesToOffsets := func(md *moduledata) []int32 {
   652  		types := moduleTypelinks(md)
   653  		ret := make([]int32, 0, len(types))
   654  		for _, typ := range types {
   655  			ret = append(ret, int32(uintptr(unsafe.Pointer(typ))-md.types))
   656  		}
   657  		return ret
   658  	}
   659  
   660  	sections := []unsafe.Pointer{unsafe.Pointer(modules[0].types)}
   661  	ret := [][]int32{typesToOffsets(modules[0])}
   662  	for _, md := range modules[1:] {
   663  		sections = append(sections, unsafe.Pointer(md.types))
   664  		ret = append(ret, typesToOffsets(md))
   665  	}
   666  	return sections, ret
   667  }
   668  
   669  // reflect_compiledTypelinks returns the typelink types
   670  // generated by the compiler for all current modules.
   671  // The normal case is a single module, so this returns one
   672  // slice for the main module, and a slice of slices, normally nil,
   673  // for other modules.
   674  //
   675  //go:linknamestd reflect_compiledTypelinks reflect.compiledTypelinks
   676  func reflect_compiledTypelinks() ([]*abi.Type, [][]*abi.Type) {
   677  	modules := activeModules()
   678  	firstTypes := moduleTypelinks(modules[0])
   679  	var rest [][]*abi.Type
   680  	for _, md := range modules[1:] {
   681  		rest = append(rest, moduleTypelinks(md))
   682  	}
   683  	return firstTypes, rest
   684  }
   685  
   686  // reflect_resolveNameOff resolves a name offset from a base pointer.
   687  //
   688  // reflect_resolveNameOff is for package reflect,
   689  // but widely used packages access it using linkname.
   690  // Notable members of the hall of shame include:
   691  //   - github.com/agiledragon/gomonkey/v2
   692  //
   693  // Do not remove or change the type signature.
   694  // See go.dev/issue/67401.
   695  //
   696  //go:linkname reflect_resolveNameOff reflect.resolveNameOff
   697  func reflect_resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer {
   698  	return unsafe.Pointer(resolveNameOff(ptrInModule, nameOff(off)).Bytes)
   699  }
   700  
   701  // reflect_resolveTypeOff resolves an *rtype offset from a base type.
   702  //
   703  // reflect_resolveTypeOff is meant for package reflect,
   704  // but widely used packages access it using linkname.
   705  // Notable members of the hall of shame include:
   706  //   - gitee.com/quant1x/gox
   707  //   - github.com/modern-go/reflect2
   708  //   - github.com/v2pro/plz
   709  //   - github.com/timandy/routine
   710  //
   711  // Do not remove or change the type signature.
   712  // See go.dev/issue/67401.
   713  //
   714  //go:linkname reflect_resolveTypeOff reflect.resolveTypeOff
   715  func reflect_resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
   716  	return unsafe.Pointer(toRType((*_type)(rtype)).typeOff(typeOff(off)))
   717  }
   718  
   719  // reflect_resolveTextOff resolves a function pointer offset from a base type.
   720  //
   721  // reflect_resolveTextOff is for package reflect,
   722  // but widely used packages access it using linkname.
   723  // Notable members of the hall of shame include:
   724  //   - github.com/agiledragon/gomonkey/v2
   725  //
   726  // Do not remove or change the type signature.
   727  // See go.dev/issue/67401.
   728  //
   729  //go:linkname reflect_resolveTextOff reflect.resolveTextOff
   730  func reflect_resolveTextOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
   731  	return toRType((*_type)(rtype)).textOff(textOff(off))
   732  }
   733  
   734  // reflectlite_resolveNameOff resolves a name offset from a base pointer.
   735  //
   736  //go:linkname reflectlite_resolveNameOff internal/reflectlite.resolveNameOff
   737  func reflectlite_resolveNameOff(ptrInModule unsafe.Pointer, off int32) unsafe.Pointer {
   738  	return unsafe.Pointer(resolveNameOff(ptrInModule, nameOff(off)).Bytes)
   739  }
   740  
   741  // reflectlite_resolveTypeOff resolves an *rtype offset from a base type.
   742  //
   743  //go:linkname reflectlite_resolveTypeOff internal/reflectlite.resolveTypeOff
   744  func reflectlite_resolveTypeOff(rtype unsafe.Pointer, off int32) unsafe.Pointer {
   745  	return unsafe.Pointer(toRType((*_type)(rtype)).typeOff(typeOff(off)))
   746  }
   747  
   748  // reflect_addReflectOff adds a pointer to the reflection offset lookup map.
   749  //
   750  //go:linkname reflect_addReflectOff reflect.addReflectOff
   751  func reflect_addReflectOff(ptr unsafe.Pointer) int32 {
   752  	reflectOffsLock()
   753  	if reflectOffs.m == nil {
   754  		reflectOffs.m = make(map[int32]unsafe.Pointer)
   755  		reflectOffs.minv = make(map[unsafe.Pointer]int32)
   756  		reflectOffs.next = -1
   757  	}
   758  	id, found := reflectOffs.minv[ptr]
   759  	if !found {
   760  		id = reflectOffs.next
   761  		reflectOffs.next-- // use negative offsets as IDs to aid debugging
   762  		reflectOffs.m[id] = ptr
   763  		reflectOffs.minv[ptr] = id
   764  	}
   765  	reflectOffsUnlock()
   766  	return id
   767  }
   768  
   769  // reflect_adjustAIXGCDataForRuntime takes a type.GCData address and returns
   770  // the new address to use. This is only called on AIX.
   771  // See getGCMaskOnDemand.
   772  //
   773  //go:linknamestd reflect_adjustAIXGCDataForRuntime reflect.adjustAIXGCDataForRuntime
   774  func reflect_adjustAIXGCDataForRuntime(addr *byte) *byte {
   775  	return (*byte)(add(unsafe.Pointer(addr), aixStaticDataBase-firstmoduledata.data))
   776  }
   777  
   778  //go:linkname fips_getIndicator crypto/internal/fips140.getIndicator
   779  func fips_getIndicator() uint8 {
   780  	return getg().fipsIndicator
   781  }
   782  
   783  //go:linkname fips_setIndicator crypto/internal/fips140.setIndicator
   784  func fips_setIndicator(indicator uint8) {
   785  	getg().fipsIndicator = indicator
   786  }
   787  

View as plain text