1// Copyright 2023 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 5package objabi 6 7import "sync" 8 9// PkgSpecial indicates special build properties of a given runtime-related 10// package. 11type PkgSpecial struct { 12 // Runtime indicates that this package is "runtime" or imported by 13 // "runtime". This has several effects (which maybe should be split out): 14 // 15 // - Implicit allocation is disallowed. 16 // 17 // - Various runtime pragmas are enabled. 18 // 19 // - Optimizations are always enabled. 20 // 21 // - Checkptr is always disabled. 22 // 23 // This should be set for runtime and all packages it imports, and may be 24 // set for additional packages. 25 Runtime bool 26 27 // NoInstrument indicates this package should not receive sanitizer 28 // instrumentation. In many of these, instrumentation could cause infinite 29 // recursion. This is all runtime packages, plus those that support the 30 // sanitizers. 31 NoInstrument bool 32 33 // NoRaceFunc indicates functions in this package should not get 34 // racefuncenter/racefuncexit instrumentation Memory accesses in these 35 // packages are either uninteresting or will cause false positives. 36 NoRaceFunc bool 37 38 // AllowAsmABI indicates that assembly in this package is allowed to use ABI 39 // selectors in symbol names. Generally this is needed for packages that 40 // interact closely with the runtime package or have performance-critical 41 // assembly. 42 AllowAsmABI bool 43} 44 45var runtimePkgs = []string{ 46 "runtime", 47 48 "internal/runtime/atomic", 49 "internal/runtime/exithook", 50 "runtime/internal/math", 51 "runtime/internal/sys", 52 "internal/runtime/syscall", 53 54 "internal/abi", 55 "internal/bytealg", 56 "internal/byteorder", 57 "internal/chacha8rand", 58 "internal/coverage/rtcov", 59 "internal/cpu", 60 "internal/goarch", 61 "internal/godebugs", 62 "internal/goexperiment", 63 "internal/goos", 64 "internal/profilerecord", 65 "internal/stringslite", 66} 67 68// extraNoInstrumentPkgs is the set of packages in addition to runtimePkgs that 69// should have NoInstrument set. 70var extraNoInstrumentPkgs = []string{ 71 "runtime/race", 72 "runtime/msan", 73 "runtime/asan", 74 // We omit bytealg even though it's imported by runtime because it also 75 // backs a lot of package bytes. Currently we don't have a way to omit race 76 // instrumentation when used from the runtime while keeping race 77 // instrumentation when used from user code. Somehow this doesn't seem to 78 // cause problems, though we may be skating on thin ice. See #61204. 79 "-internal/bytealg", 80} 81 82var noRaceFuncPkgs = []string{"sync", "sync/atomic", "internal/runtime/atomic"} 83 84var allowAsmABIPkgs = []string{ 85 "runtime", 86 "reflect", 87 "syscall", 88 "internal/bytealg", 89 "internal/chacha8rand", 90 "internal/runtime/syscall", 91 "runtime/internal/startlinetest", 92} 93 94var ( 95 pkgSpecials map[string]PkgSpecial 96 pkgSpecialsOnce sync.Once 97) 98 99// LookupPkgSpecial returns special build properties for the given package path. 100func LookupPkgSpecial(pkgPath string) PkgSpecial { 101 pkgSpecialsOnce.Do(func() { 102 // Construct pkgSpecials from various package lists. This lets us use 103 // more flexible logic, while keeping the final map simple, and avoids 104 // the init-time cost of a map. 105 pkgSpecials = make(map[string]PkgSpecial) 106 set := func(elt string, f func(*PkgSpecial)) { 107 s := pkgSpecials[elt] 108 f(&s) 109 pkgSpecials[elt] = s 110 } 111 for _, pkg := range runtimePkgs { 112 set(pkg, func(ps *PkgSpecial) { ps.Runtime = true; ps.NoInstrument = true }) 113 } 114 for _, pkg := range extraNoInstrumentPkgs { 115 if pkg[0] == '-' { 116 set(pkg[1:], func(ps *PkgSpecial) { ps.NoInstrument = false }) 117 } else { 118 set(pkg, func(ps *PkgSpecial) { ps.NoInstrument = true }) 119 } 120 } 121 for _, pkg := range noRaceFuncPkgs { 122 set(pkg, func(ps *PkgSpecial) { ps.NoRaceFunc = true }) 123 } 124 for _, pkg := range allowAsmABIPkgs { 125 set(pkg, func(ps *PkgSpecial) { ps.AllowAsmABI = true }) 126 } 127 }) 128 return pkgSpecials[pkgPath] 129} 130