Source file src/internal/coverage/rtcov/rtcov.go

     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  
     5  package rtcov
     6  
     7  import "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.
    19  type 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.
    33  type 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.
    40  var 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.
    63  func 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  

View as plain text