buildid

Imports

Imports #

"bytes"
"debug/elf"
"fmt"
"internal/xcoff"
"io"
"io/fs"
"os"
"strconv"
"strings"
"bytes"
"debug/elf"
"debug/macho"
"encoding/binary"
"fmt"
"io"
"io/fs"
"os"
"bytes"
"cmd/internal/codesign"
imacho "cmd/internal/macho"
"crypto/sha256"
"debug/elf"
"debug/macho"
"fmt"
"io"

Constants & Variables

bangArch var #

var bangArch = *ast.CallExpr

buildid var #

var buildid = *ast.CallExpr

elfGNUNote var #

var elfGNUNote = *ast.CallExpr

elfGoNote var #

var elfGoNote = *ast.CallExpr

elfPrefix var #

var elfPrefix = *ast.CallExpr

errBuildIDMalformed var #

var errBuildIDMalformed = *ast.CallExpr

goBuildEnd var #

var goBuildEnd = *ast.CallExpr

goBuildPrefix var #

var goBuildPrefix = *ast.CallExpr

goobject var #

var goobject = *ast.CallExpr

machoPrefixes var #

var machoPrefixes = [][]byte{...}

pkgdef var #

var pkgdef = *ast.CallExpr

readSize var #

var readSize = *ast.BinaryExpr

Structs

excludedReader struct #

excludedReader wraps an io.Reader. Reading from it returns the bytes from the underlying reader, except that when the byte offset is within the range between start and end, it returns zero bytes.

type excludedReader struct {
r io.Reader
off int64
start int64
end int64
}

Functions

FindAndHash function #

FindAndHash reads all of r and returns the offsets of occurrences of id. While reading, findAndHash also computes and returns a hash of the content of r, but with occurrences of id replaced by zeros. FindAndHash reads bufSize bytes from r at a time. If bufSize == 0, FindAndHash uses a reasonable default.

func FindAndHash(r io.Reader, id string, bufSize int) (matches []int64, hash [32]byte, err error)

HashToString function #

HashToString converts the hash h to a string to be recorded in package archives and binaries as part of the build ID. We use the first 120 bits of the hash (5 chunks of 24 bits each) and encode it in base64, resulting in a 20-byte string. Because this is only used for detecting the need to rebuild installed files (not for lookups in the object file cache), 120 bits are sufficient to drive the probability of a false "do not need to rebuild" decision to effectively zero. We embed two different hashes in archives and four in binaries, so cutting to 20 bytes is a significant savings when build IDs are displayed. (20*4+3 = 83 bytes compared to 64*4+3 = 259 bytes for the more straightforward option of printing the entire h in base64).

func HashToString(h [32]byte) string

Read method #

func (r *excludedReader) Read(p []byte) (int, error)

ReadELFNote function #

func ReadELFNote(filename string, name string, typ int32) ([]byte, error)

ReadFile function #

ReadFile reads the build ID from an archive or executable file.

func ReadFile(name string) (id string, err error)

Rewrite function #

func Rewrite(w io.WriterAt, pos []int64, id string) error

excludeHostBuildID function #

func excludeHostBuildID(r io.Reader, r0 io.Reader) io.Reader

excludeMachoCodeSignature function #

func excludeMachoCodeSignature(r io.Reader) io.Reader

findHostBuildID function #

func findHostBuildID(r io.Reader) (offset int64, size int64, ok bool)

findMachoCodeSignature function #

func findMachoCodeSignature(r any) (*macho.File, codesign.CodeSigCmd, bool)

readAligned4 function #

func readAligned4(r io.Reader, sz int32) ([]byte, error)

readBinary function #

readBinary reads the build ID from a binary. ELF binaries store the build ID in a proper PT_NOTE section. Other binary formats are not so flexible. For those, the linker stores the build ID as non-instruction bytes at the very beginning of the text segment, which should appear near the beginning of the file. This is clumsy but fairly portable. Custom locations can be added for other binary types as needed, like we did for ELF.

func readBinary(name string, f *os.File) (id string, err error)

readELF function #

The Go build ID is stored in a note described by an ELF PT_NOTE prog header. The caller has already opened filename, to get f, and read at least 4 kB out, in data.

func readELF(name string, f *os.File, data []byte) (buildid string, err error)

readGccgoArchive function #

readGccgoArchive tries to parse the archive as a standard Unix archive file, and fetch the build ID from the _buildid.o entry. The _buildid.o entry is written by (*Builder).gccgoBuildIDELFFile in cmd/go/internal/work/exec.go.

func readGccgoArchive(name string, f *os.File) (string, error)

readGccgoBigArchive function #

readGccgoBigArchive tries to parse the archive as an AIX big archive file, and fetch the build ID from the _buildid.o entry. The _buildid.o entry is written by (*Builder).gccgoBuildIDXCOFFFile in cmd/go/internal/work/exec.go.

func readGccgoBigArchive(name string, f *os.File) (string, error)

readMacho function #

The Go build ID is stored at the beginning of the Mach-O __text segment. The caller has already opened filename, to get f, and read a few kB out, in data. Sadly, that's not guaranteed to hold the note, because there is an arbitrary amount of other junk placed in the file ahead of the main text.

func readMacho(name string, f *os.File, data []byte) (buildid string, err error)

readRaw function #

readRaw finds the raw build ID stored in text segment data.

func readRaw(name string, data []byte) (id string, err error)

Generated with Arrow