diff options
| author | Russ Cox <rsc@golang.org> | 2024-05-15 18:39:01 -0400 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2024-05-22 09:57:47 +0000 |
| commit | df4e49366c25118e20fac51f834d3cf4864b163b (patch) | |
| tree | 886c5dcb97d7867548fb8445701a2530b639660b /src/internal/coverage | |
| parent | c96159c25217c84a252be5d74d48861af715ecf8 (diff) | |
| download | go-df4e49366c25118e20fac51f834d3cf4864b163b.tar.xz | |
internal/coverage/cfile: remove more //go:linkname usage
Move code so that basic imports work instead
of //go:linkname for metadata lists.
For #67401.
Change-Id: Id02075570befc45a9426559aad2137ab540928b2
Reviewed-on: https://go-review.googlesource.com/c/go/+/585915
Reviewed-by: Than McIntosh <thanm@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
Diffstat (limited to 'src/internal/coverage')
| -rw-r--r-- | src/internal/coverage/cfile/apis.go | 7 | ||||
| -rw-r--r-- | src/internal/coverage/cfile/emit.go | 24 | ||||
| -rw-r--r-- | src/internal/coverage/cfile/testsupport.go | 3 | ||||
| -rw-r--r-- | src/internal/coverage/rtcov/rtcov.go | 56 |
4 files changed, 67 insertions, 23 deletions
diff --git a/src/internal/coverage/cfile/apis.go b/src/internal/coverage/cfile/apis.go index efae20495b..ef23af0cf1 100644 --- a/src/internal/coverage/cfile/apis.go +++ b/src/internal/coverage/cfile/apis.go @@ -7,6 +7,7 @@ package cfile import ( "fmt" "internal/coverage" + "internal/coverage/rtcov" "io" "sync/atomic" "unsafe" @@ -17,7 +18,7 @@ func WriteMetaDir(dir string) error { if !finalHashComputed { return fmt.Errorf("error: no meta-data available (binary not built with -cover?)") } - return emitMetaDataToDirectory(dir, getCovMetaList()) + return emitMetaDataToDirectory(dir, rtcov.Meta.List) } // WriteMeta implements [runtime/coverage.WriteMeta]. @@ -28,7 +29,7 @@ func WriteMeta(w io.Writer) error { if !finalHashComputed { return fmt.Errorf("error: no meta-data available (binary not built with -cover?)") } - ml := getCovMetaList() + ml := rtcov.Meta.List return writeMetaData(w, ml, cmode, cgran, finalHash) } @@ -57,7 +58,7 @@ func WriteCounters(w io.Writer) error { return fmt.Errorf("meta-data not written yet, unable to write counter data") } - pm := getCovPkgMap() + pm := rtcov.Meta.PkgMap s := &emitState{ counterlist: cl, pkgmap: pm, diff --git a/src/internal/coverage/cfile/emit.go b/src/internal/coverage/cfile/emit.go index 68d77c5ae8..3993e9cb42 100644 --- a/src/internal/coverage/cfile/emit.go +++ b/src/internal/coverage/cfile/emit.go @@ -29,25 +29,13 @@ import ( // emitted at the end of code coverage testing runs, from instrumented // executables. -// getCovMetaList returns a list of meta-data blobs registered -// for the currently executing instrumented program. It is defined in the -// runtime. -//go:linkname getCovMetaList -func getCovMetaList() []rtcov.CovMetaBlob - // getCovCounterList returns a list of counter-data blobs registered // for the currently executing instrumented program. It is defined in the // runtime. +// //go:linkname getCovCounterList func getCovCounterList() []rtcov.CovCounterBlob -// getCovPkgMap returns a map storing the remapped package IDs for -// hard-coded runtime packages (see internal/coverage/pkgid.go for -// more on why hard-coded package IDs are needed). This function -// is defined in the runtime. -//go:linkname getCovPkgMap -func getCovPkgMap() map[int]int - // emitState holds useful state information during the emit process. // // When an instrumented program finishes execution and starts the @@ -180,7 +168,7 @@ func granClash(g coverage.CounterGranularity) bool { // all meta-data blobs and capturing os args. func prepareForMetaEmit() ([]rtcov.CovMetaBlob, error) { // Ask the runtime for the list of coverage meta-data symbols. - ml := getCovMetaList() + ml := rtcov.Meta.List // In the normal case (go build -o prog.exe ... ; ./prog.exe) // len(ml) will always be non-zero, but we check here since at @@ -210,7 +198,7 @@ func prepareForMetaEmit() ([]rtcov.CovMetaBlob, error) { } fmt.Fprintf(os.Stderr, "\n") } - pm := getCovPkgMap() + pm := rtcov.Meta.PkgMap fmt.Fprintf(os.Stderr, "=+= remap table:\n") for from, to := range pm { fmt.Fprintf(os.Stderr, "=+= from %d to %d\n", @@ -310,7 +298,7 @@ func emitCounterDataToDirectory(outdir string) error { } // Ask the runtime for the list of coverage counter symbols. - pm := getCovPkgMap() + pm := rtcov.Meta.PkgMap s := &emitState{ counterlist: cl, pkgmap: pm, @@ -591,8 +579,8 @@ func MarkProfileEmitted(val bool) { } func reportErrorInHardcodedList(slot, pkgID int32, fnID, nCtrs uint32) { - metaList := getCovMetaList() - pkgMap := getCovPkgMap() + metaList := rtcov.Meta.List + pkgMap := rtcov.Meta.PkgMap println("internal error in coverage meta-data tracking:") println("encountered bad pkgID:", pkgID, " at slot:", slot, diff --git a/src/internal/coverage/cfile/testsupport.go b/src/internal/coverage/cfile/testsupport.go index 2a64899e28..a5119187a2 100644 --- a/src/internal/coverage/cfile/testsupport.go +++ b/src/internal/coverage/cfile/testsupport.go @@ -14,6 +14,7 @@ import ( "internal/coverage/decodecounter" "internal/coverage/decodemeta" "internal/coverage/pods" + "internal/coverage/rtcov" "internal/runtime/atomic" "io" "os" @@ -33,7 +34,7 @@ func ProcessCoverTestDir(dir string, cfile string, cm string, cpkg string, w io. } // Emit meta-data and counter data. - ml := getCovMetaList() + ml := rtcov.Meta.List if len(ml) == 0 { // This corresponds to the case where we have a package that // contains test code but no functions (which is fine). In this diff --git a/src/internal/coverage/rtcov/rtcov.go b/src/internal/coverage/rtcov/rtcov.go index bbb93acced..9e30d67900 100644 --- a/src/internal/coverage/rtcov/rtcov.go +++ b/src/internal/coverage/rtcov/rtcov.go @@ -4,8 +4,10 @@ package rtcov +import "unsafe" + // This package contains types whose structure is shared between -// the runtime package and the "runtime/coverage" package. +// the runtime package and the "runtime/coverage" implementation. // CovMetaBlob is a container for holding the meta-data symbol (an // RODATA variable) for an instrumented Go package. Here "p" points to @@ -32,3 +34,55 @@ type CovCounterBlob struct { Counters *uint32 Len uint64 } + +// Meta is the top-level container for bits of state related to +// code coverage meta-data in the runtime. +var Meta struct { + // List contains the list of currently registered meta-data + // blobs for the running program. + List []CovMetaBlob + + // PkgMap records mappings from hard-coded package IDs to + // slots in the List above. + PkgMap map[int]int + + // Set to true if we discover a package mapping glitch. + hardCodedListNeedsUpdating bool +} + +// AddMeta is invoked during package "init" functions by the +// compiler when compiling for coverage instrumentation; here 'p' is a +// meta-data blob of length 'dlen' for the package in question, 'hash' +// is a compiler-computed md5.sum for the blob, 'pkpath' is the +// package path, 'pkid' is the hard-coded ID that the compiler is +// using for the package (or -1 if the compiler doesn't think a +// hard-coded ID is needed), and 'cmode'/'cgran' are the coverage +// counter mode and granularity requested by the user. Return value is +// the ID for the package for use by the package code itself, +// or 0 for impossible errors. +func AddMeta(p unsafe.Pointer, dlen uint32, hash [16]byte, pkgpath string, pkgid int, cmode uint8, cgran uint8) uint32 { + slot := len(Meta.List) + Meta.List = append(Meta.List, CovMetaBlob{ + P: (*byte)(p), + Len: dlen, + Hash: hash, + PkgPath: pkgpath, + PkgID: pkgid, + CounterMode: cmode, + CounterGranularity: cgran, + }) + if pkgid != -1 { + if Meta.PkgMap == nil { + Meta.PkgMap = make(map[int]int) + } + if _, ok := Meta.PkgMap[pkgid]; ok { + return 0 + } + // Record the real slot (position on meta-list) for this + // package; we'll use the map to fix things up later on. + Meta.PkgMap[pkgid] = slot + } + + // ID zero is reserved as invalid. + return uint32(slot + 1) +} |
