1// Copyright 2022 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 rtcov 6 7import "unsafe" 8 9// This package contains types whose structure is shared between 10// the runtime package and the "runtime/coverage" implementation. 11 12// CovMetaBlob is a container for holding the meta-data symbol (an 13// RODATA variable) for an instrumented Go package. Here "p" points to 14// the symbol itself, "len" is the length of the sym in bytes, and 15// "hash" is an md5sum for the sym computed by the compiler. When 16// the init function for a coverage-instrumented package executes, it 17// will make a call into the runtime which will create a covMetaBlob 18// object for the package and chain it onto a global list. 19type CovMetaBlob struct { 20 P *byte 21 Len uint32 22 Hash [16]byte 23 PkgPath string 24 PkgID int 25 CounterMode uint8 // coverage.CounterMode 26 CounterGranularity uint8 // coverage.CounterGranularity 27} 28 29// CovCounterBlob is a container for encapsulating a counter section 30// (BSS variable) for an instrumented Go module. Here "counters" 31// points to the counter payload and "len" is the number of uint32 32// entries in the section. 33type CovCounterBlob struct { 34 Counters *uint32 35 Len uint64 36} 37 38// Meta is the top-level container for bits of state related to 39// code coverage meta-data in the runtime. 40var Meta struct { 41 // List contains the list of currently registered meta-data 42 // blobs for the running program. 43 List []CovMetaBlob 44 45 // PkgMap records mappings from hard-coded package IDs to 46 // slots in the List above. 47 PkgMap map[int]int 48 49 // Set to true if we discover a package mapping glitch. 50 hardCodedListNeedsUpdating bool 51} 52 53// AddMeta is invoked during package "init" functions by the 54// compiler when compiling for coverage instrumentation; here 'p' is a 55// meta-data blob of length 'dlen' for the package in question, 'hash' 56// is a compiler-computed md5.sum for the blob, 'pkpath' is the 57// package path, 'pkid' is the hard-coded ID that the compiler is 58// using for the package (or -1 if the compiler doesn't think a 59// hard-coded ID is needed), and 'cmode'/'cgran' are the coverage 60// counter mode and granularity requested by the user. Return value is 61// the ID for the package for use by the package code itself, 62// or 0 for impossible errors. 63func AddMeta(p unsafe.Pointer, dlen uint32, hash [16]byte, pkgpath string, pkgid int, cmode uint8, cgran uint8) uint32 { 64 slot := len(Meta.List) 65 Meta.List = append(Meta.List, CovMetaBlob{ 66 P: (*byte)(p), 67 Len: dlen, 68 Hash: hash, 69 PkgPath: pkgpath, 70 PkgID: pkgid, 71 CounterMode: cmode, 72 CounterGranularity: cgran, 73 }) 74 if pkgid != -1 { 75 if Meta.PkgMap == nil { 76 Meta.PkgMap = make(map[int]int) 77 } 78 if _, ok := Meta.PkgMap[pkgid]; ok { 79 return 0 80 } 81 // Record the real slot (position on meta-list) for this 82 // package; we'll use the map to fix things up later on. 83 Meta.PkgMap[pkgid] = slot 84 } 85 86 // ID zero is reserved as invalid. 87 return uint32(slot + 1) 88} 89