cmd/internal/archive: skip sentinel archive entries created by Go cmd

When reading an archive, check for the presence of sentinel entries
created by the Go command. These zero-sized marker entries don't contain
any useful symbols, but rather are there to communicate info to the
linker; ignore them during symbol dumping.

Fixes #62036.

Change-Id: Ied017b0c5b92a3cf6fd13bb9c9f3a9664e4f20f8
Reviewed-on: https://go-review.googlesource.com/c/go/+/519635
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
This commit is contained in:
Than McIntosh 2023-08-15 10:24:41 -04:00
parent fc212a9307
commit 1e245d21b8
3 changed files with 39 additions and 1 deletions

View file

@ -95,6 +95,9 @@ go build -ldflags=-tmpdir=tmp4 -o $devnull ./usesExplicitCgo &
[cgolinkext] go list ./usesInternalCgo
[!cgolinkext] go build '-ldflags=-tmpdir=tmp5 -linkmode=internal' -o $devnull ./usesInternalCgo &
# Sixth build: explicit CGO use in a non-main package.
go build -o p.a ./nonMainPackageUsesExplicitCgo &
wait
# Check first build: no external linking expected
@ -113,6 +116,10 @@ exists tmp4/go.o
# Fifth build: explicit CGO, -linkmode=internal.
! exists tmp5/go.o
# Sixth build: make sure that "go tool nm" doesn't get confused
# by the presence of the "preferlinkext" sentinel.
go tool nm p.a
-- go.mod --
module cgo.example
@ -153,3 +160,16 @@ import "C"
func main() {
println(C.meaningOfLife())
}
-- nonMainPackageUsesExplicitCgo/main.go --
package p
/*
int meaningOfLife() { return 42; }
*/
import "C"
func PrintIt() {
println(C.meaningOfLife())
}

View file

@ -70,6 +70,7 @@ const (
EntryPkgDef EntryType = iota
EntryGoObj
EntryNativeObj
EntrySentinelNonObj
)
func (e *Entry) String() string {
@ -357,6 +358,23 @@ func (r *objReader) parseArchive(verbose bool) error {
Data: Data{r.offset, size},
})
r.skip(size)
case "preferlinkext", "dynimportfail":
if size == 0 {
// These are not actual objects, but rather sentinel
// entries put into the archive by the Go command to
// be read by the linker. See #62036.
r.a.Entries = append(r.a.Entries, Entry{
Name: name,
Type: EntrySentinelNonObj,
Mtime: mtime,
Uid: uid,
Gid: gid,
Mode: mode,
Data: Data{r.offset, size},
})
break
}
fallthrough
default:
var typ EntryType
var o *GoObj

View file

@ -35,7 +35,7 @@ func openGoFile(f *os.File) (*File, error) {
L:
for _, e := range a.Entries {
switch e.Type {
case archive.EntryPkgDef:
case archive.EntryPkgDef, archive.EntrySentinelNonObj:
continue
case archive.EntryGoObj:
o := e.Obj