Skip to content

Commit

Permalink
internal/gcimporter: require archive files
Browse files Browse the repository at this point in the history
Proposal golang/go#68898 was accepted. gcexportdata.Read now supports
tip and the latest two releases. FindExportData is needed only
to support Read and can thus have the same support policy.

Since go1.21, the only files the compiler produces with
the header "go object " are either in archive files or do
not contain exportdata (cmd/asm). It is therefore safe for
FindExportData to require the files to be ar files.

Updates golang/go#70651

Change-Id: Iec6703da6768198524e174824b0b05f95b96db90
Reviewed-on: https://go-review.googlesource.com/c/tools/+/633115
Reviewed-by: Alan Donovan <adonovan@google.com>
Reviewed-by: Robert Findley <rfindley@google.com>
Commit-Queue: Tim King <taking@google.com>
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
  • Loading branch information
timothy-king authored and Go LUCI committed Dec 3, 2024
1 parent 2f73c61 commit 7a4f3b0
Showing 1 changed file with 27 additions and 19 deletions.
46 changes: 27 additions & 19 deletions internal/gcimporter/exportdata.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,11 +39,15 @@ func readGopackHeader(r *bufio.Reader) (name string, size int64, err error) {
}

// FindExportData positions the reader r at the beginning of the
// export data section of an underlying GC-created object/archive
// export data section of an underlying cmd/compile created archive
// file by reading from it. The reader must be positioned at the
// start of the file before calling this function. The hdr result
// is the string before the export data, either "$$" or "$$B".
// The size result is the length of the export data in bytes, or -1 if not known.
//
// This function is needed by [gcexportdata.Read], which must
// accept inputs produced by the last two releases of cmd/compile,
// plus tip.
func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) {
// Read first line to make sure this is an object file.
line, err := r.ReadSlice('\n')
Expand All @@ -52,27 +56,31 @@ func FindExportData(r *bufio.Reader) (hdr string, size int64, err error) {
return
}

if string(line) == "!<arch>\n" {
// Archive file. Scan to __.PKGDEF.
var name string
if name, size, err = readGopackHeader(r); err != nil {
return
}
// Is the first line an archive file signature?
if string(line) != "!<arch>\n" {
err = fmt.Errorf("not the start of an archive file (%q)", line)
return
}

// First entry should be __.PKGDEF.
if name != "__.PKGDEF" {
err = fmt.Errorf("go archive is missing __.PKGDEF")
return
}
// Archive file. Scan to __.PKGDEF.
var name string
if name, size, err = readGopackHeader(r); err != nil {
return
}

// Read first line of __.PKGDEF data, so that line
// is once again the first line of the input.
if line, err = r.ReadSlice('\n'); err != nil {
err = fmt.Errorf("can't find export data (%v)", err)
return
}
size -= int64(len(line))
// First entry should be __.PKGDEF.
if name != "__.PKGDEF" {
err = fmt.Errorf("go archive is missing __.PKGDEF")
return
}

// Read first line of __.PKGDEF data, so that line
// is once again the first line of the input.
if line, err = r.ReadSlice('\n'); err != nil {
err = fmt.Errorf("can't find export data (%v)", err)
return
}
size -= int64(len(line))

// Now at __.PKGDEF in archive or still at beginning of file.
// Either way, line should begin with "go object ".
Expand Down

0 comments on commit 7a4f3b0

Please sign in to comment.