diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 13:14:23 +0000 |
commit | 73df946d56c74384511a194dd01dbe099584fd1a (patch) | |
tree | fd0bcea490dd81327ddfbb31e215439672c9a068 /src/runtime/debug/mod.go | |
parent | Initial commit. (diff) | |
download | golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.tar.xz golang-1.16-73df946d56c74384511a194dd01dbe099584fd1a.zip |
Adding upstream version 1.16.10.upstream/1.16.10upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/runtime/debug/mod.go')
-rw-r--r-- | src/runtime/debug/mod.go | 114 |
1 files changed, 114 insertions, 0 deletions
diff --git a/src/runtime/debug/mod.go b/src/runtime/debug/mod.go new file mode 100644 index 0000000..0381bdc --- /dev/null +++ b/src/runtime/debug/mod.go @@ -0,0 +1,114 @@ +// Copyright 2018 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package debug + +import ( + "strings" +) + +// exported from runtime +func modinfo() string + +// ReadBuildInfo returns the build information embedded +// in the running binary. The information is available only +// in binaries built with module support. +func ReadBuildInfo() (info *BuildInfo, ok bool) { + return readBuildInfo(modinfo()) +} + +// BuildInfo represents the build information read from +// the running binary. +type BuildInfo struct { + Path string // The main package path + Main Module // The module containing the main package + Deps []*Module // Module dependencies +} + +// Module represents a module. +type Module struct { + Path string // module path + Version string // module version + Sum string // checksum + Replace *Module // replaced by this module +} + +func readBuildInfo(data string) (*BuildInfo, bool) { + if len(data) < 32 { + return nil, false + } + data = data[16 : len(data)-16] + + const ( + pathLine = "path\t" + modLine = "mod\t" + depLine = "dep\t" + repLine = "=>\t" + ) + + readEntryFirstLine := func(elem []string) (Module, bool) { + if len(elem) != 2 && len(elem) != 3 { + return Module{}, false + } + sum := "" + if len(elem) == 3 { + sum = elem[2] + } + return Module{ + Path: elem[0], + Version: elem[1], + Sum: sum, + }, true + } + + var ( + info = &BuildInfo{} + last *Module + line string + ok bool + ) + // Reverse of cmd/go/internal/modload.PackageBuildInfo + for len(data) > 0 { + i := strings.IndexByte(data, '\n') + if i < 0 { + break + } + line, data = data[:i], data[i+1:] + switch { + case strings.HasPrefix(line, pathLine): + elem := line[len(pathLine):] + info.Path = elem + case strings.HasPrefix(line, modLine): + elem := strings.Split(line[len(modLine):], "\t") + last = &info.Main + *last, ok = readEntryFirstLine(elem) + if !ok { + return nil, false + } + case strings.HasPrefix(line, depLine): + elem := strings.Split(line[len(depLine):], "\t") + last = new(Module) + info.Deps = append(info.Deps, last) + *last, ok = readEntryFirstLine(elem) + if !ok { + return nil, false + } + case strings.HasPrefix(line, repLine): + elem := strings.Split(line[len(repLine):], "\t") + if len(elem) != 3 { + return nil, false + } + if last == nil { + return nil, false + } + last.Replace = &Module{ + Path: elem[0], + Version: elem[1], + Sum: elem[2], + } + last = nil + } + } + return info, true +} |