Source file src/internal/platform/supported.go

     1  // Copyright 2018 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  //go:generate go test . -run=^TestGenerated$ -fix
     6  
     7  package platform
     8  
     9  // An OSArch is a pair of GOOS and GOARCH values indicating a platform.
    10  type OSArch struct {
    11  	GOOS, GOARCH string
    12  }
    13  
    14  func (p OSArch) String() string {
    15  	return p.GOOS + "/" + p.GOARCH
    16  }
    17  
    18  // RaceDetectorSupported reports whether goos/goarch supports the race
    19  // detector. There is a copy of this function in cmd/dist/test.go.
    20  // Race detector only supports 48-bit VMA on arm64. But it will always
    21  // return true for arm64, because we don't have VMA size information during
    22  // the compile time.
    23  func RaceDetectorSupported(goos, goarch string) bool {
    24  	switch goos {
    25  	case "linux":
    26  		return goarch == "amd64" || goarch == "arm64" || goarch == "loong64" || goarch == "ppc64le" || goarch == "riscv64" || goarch == "s390x"
    27  	case "darwin":
    28  		return goarch == "amd64" || goarch == "arm64"
    29  	case "freebsd", "netbsd", "windows":
    30  		return goarch == "amd64"
    31  	default:
    32  		return false
    33  	}
    34  }
    35  
    36  // MSanSupported reports whether goos/goarch supports the memory
    37  // sanitizer option.
    38  func MSanSupported(goos, goarch string) bool {
    39  	switch goos {
    40  	case "linux":
    41  		return goarch == "amd64" || goarch == "arm64" || goarch == "loong64"
    42  	case "freebsd":
    43  		return goarch == "amd64"
    44  	default:
    45  		return false
    46  	}
    47  }
    48  
    49  // ASanSupported reports whether goos/goarch supports the address
    50  // sanitizer option.
    51  func ASanSupported(goos, goarch string) bool {
    52  	switch goos {
    53  	case "linux":
    54  		return goarch == "arm64" || goarch == "amd64" || goarch == "loong64" || goarch == "riscv64" || goarch == "ppc64le"
    55  	default:
    56  		return false
    57  	}
    58  }
    59  
    60  // FuzzSupported reports whether goos/goarch supports fuzzing
    61  // ('go test -fuzz=.').
    62  func FuzzSupported(goos, goarch string) bool {
    63  	switch goos {
    64  	case "darwin", "freebsd", "linux", "openbsd", "windows":
    65  		return true
    66  	default:
    67  		return false
    68  	}
    69  }
    70  
    71  // FuzzInstrumented reports whether fuzzing on goos/goarch uses coverage
    72  // instrumentation. (FuzzInstrumented implies FuzzSupported.)
    73  func FuzzInstrumented(goos, goarch string) bool {
    74  	switch goarch {
    75  	case "amd64", "arm64", "loong64":
    76  		// TODO(#14565): support more architectures.
    77  		return FuzzSupported(goos, goarch)
    78  	default:
    79  		return false
    80  	}
    81  }
    82  
    83  // MustLinkExternal reports whether goos/goarch requires external linking
    84  // with or without cgo dependencies.
    85  func MustLinkExternal(goos, goarch string, withCgo bool) bool {
    86  	if withCgo {
    87  		switch goarch {
    88  		case "mips", "mipsle", "mips64", "mips64le":
    89  			// Internally linking cgo is incomplete on some architectures.
    90  			// https://go.dev/issue/14449
    91  			return true
    92  		case "ppc64":
    93  			// Big Endian PPC64 cgo internal linking is not implemented for aix or linux.
    94  			// https://go.dev/issue/8912
    95  			if goos == "aix" || goos == "linux" {
    96  				return true
    97  			}
    98  		}
    99  
   100  		switch goos {
   101  		case "android":
   102  			return true
   103  		case "dragonfly":
   104  			// It seems that on Dragonfly thread local storage is
   105  			// set up by the dynamic linker, so internal cgo linking
   106  			// doesn't work. Test case is "go test runtime/cgo".
   107  			return true
   108  		}
   109  	}
   110  
   111  	switch goos {
   112  	case "android":
   113  		if goarch != "arm64" {
   114  			return true
   115  		}
   116  	case "ios":
   117  		if goarch == "arm64" {
   118  			return true
   119  		}
   120  	}
   121  	return false
   122  }
   123  
   124  // BuildModeSupported reports whether goos/goarch supports the given build mode
   125  // using the given compiler.
   126  // There is a copy of this function in cmd/dist/test.go.
   127  func BuildModeSupported(compiler, buildmode, goos, goarch string) bool {
   128  	if compiler == "gccgo" {
   129  		return true
   130  	}
   131  
   132  	if _, ok := distInfo[OSArch{goos, goarch}]; !ok {
   133  		return false // platform unrecognized
   134  	}
   135  
   136  	platform := goos + "/" + goarch
   137  	switch buildmode {
   138  	case "archive":
   139  		return true
   140  
   141  	case "c-archive":
   142  		switch goos {
   143  		case "aix", "darwin", "ios", "windows":
   144  			return true
   145  		case "linux":
   146  			switch goarch {
   147  			case "386", "amd64", "arm", "armbe", "arm64", "arm64be", "loong64", "ppc64le", "riscv64", "s390x":
   148  				// linux/ppc64 not supported because it does
   149  				// not support external linking mode yet.
   150  				return true
   151  			default:
   152  				// Other targets do not support -shared,
   153  				// per ParseFlags in
   154  				// cmd/compile/internal/base/flag.go.
   155  				// For c-archive the Go tool passes -shared,
   156  				// so that the result is suitable for inclusion
   157  				// in a PIE or shared library.
   158  				return false
   159  			}
   160  		case "freebsd":
   161  			return goarch == "amd64"
   162  		}
   163  		return false
   164  
   165  	case "c-shared":
   166  		switch platform {
   167  		case "linux/amd64", "linux/arm", "linux/arm64", "linux/loong64", "linux/386", "linux/ppc64le", "linux/riscv64", "linux/s390x",
   168  			"android/amd64", "android/arm", "android/arm64", "android/386",
   169  			"freebsd/amd64",
   170  			"darwin/amd64", "darwin/arm64",
   171  			"windows/amd64", "windows/386", "windows/arm64",
   172  			"wasip1/wasm":
   173  			return true
   174  		}
   175  		return false
   176  
   177  	case "default":
   178  		return true
   179  
   180  	case "exe":
   181  		return true
   182  
   183  	case "pie":
   184  		switch platform {
   185  		case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/loong64", "linux/ppc64le", "linux/riscv64", "linux/s390x",
   186  			"android/amd64", "android/arm", "android/arm64", "android/386",
   187  			"freebsd/amd64",
   188  			"darwin/amd64", "darwin/arm64",
   189  			"ios/amd64", "ios/arm64",
   190  			"aix/ppc64",
   191  			"openbsd/arm64",
   192  			"windows/386", "windows/amd64", "windows/arm64":
   193  			return true
   194  		}
   195  		return false
   196  
   197  	case "shared":
   198  		switch platform {
   199  		case "linux/386", "linux/amd64", "linux/arm", "linux/arm64", "linux/ppc64le", "linux/s390x":
   200  			return true
   201  		}
   202  		return false
   203  
   204  	case "plugin":
   205  		switch platform {
   206  		case "linux/amd64", "linux/arm", "linux/arm64", "linux/386", "linux/loong64", "linux/riscv64", "linux/s390x", "linux/ppc64le",
   207  			"android/amd64", "android/386",
   208  			"darwin/amd64", "darwin/arm64",
   209  			"freebsd/amd64":
   210  			return true
   211  		}
   212  		return false
   213  
   214  	default:
   215  		return false
   216  	}
   217  }
   218  
   219  func InternalLinkPIESupported(goos, goarch string) bool {
   220  	switch goos + "/" + goarch {
   221  	case "android/arm64",
   222  		"darwin/amd64", "darwin/arm64",
   223  		"linux/amd64", "linux/arm64", "linux/loong64", "linux/ppc64le",
   224  		"windows/386", "windows/amd64", "windows/arm64":
   225  		return true
   226  	}
   227  	return false
   228  }
   229  
   230  // DefaultPIE reports whether goos/goarch produces a PIE binary when using the
   231  // "default" buildmode. On Windows this is affected by -race,
   232  // so force the caller to pass that in to centralize that choice.
   233  func DefaultPIE(goos, goarch string, isRace bool) bool {
   234  	switch goos {
   235  	case "android", "ios":
   236  		return true
   237  	case "windows":
   238  		if isRace {
   239  			// PIE is not supported with -race on windows;
   240  			// see https://go.dev/cl/416174.
   241  			return false
   242  		}
   243  		return true
   244  	case "darwin":
   245  		return true
   246  	}
   247  	return false
   248  }
   249  
   250  // ExecutableHasDWARF reports whether the linked executable includes DWARF
   251  // symbols on goos/goarch.
   252  func ExecutableHasDWARF(goos, goarch string) bool {
   253  	switch goos {
   254  	case "plan9", "ios":
   255  		return false
   256  	}
   257  	return true
   258  }
   259  
   260  // osArchInfo describes information about an OSArch extracted from cmd/dist and
   261  // stored in the generated distInfo map.
   262  type osArchInfo struct {
   263  	CgoSupported bool
   264  	FirstClass   bool
   265  	Broken       bool
   266  }
   267  
   268  // CgoSupported reports whether goos/goarch supports cgo.
   269  func CgoSupported(goos, goarch string) bool {
   270  	return distInfo[OSArch{goos, goarch}].CgoSupported
   271  }
   272  
   273  // FirstClass reports whether goos/goarch is considered a “first class” port.
   274  // (See https://go.dev/wiki/PortingPolicy#first-class-ports.)
   275  func FirstClass(goos, goarch string) bool {
   276  	return distInfo[OSArch{goos, goarch}].FirstClass
   277  }
   278  
   279  // Broken reports whether goos/goarch is considered a broken port.
   280  // (See https://go.dev/wiki/PortingPolicy#broken-ports.)
   281  func Broken(goos, goarch string) bool {
   282  	return distInfo[OSArch{goos, goarch}].Broken
   283  }
   284  

View as plain text