diff --git a/src/cmd/go/testdata/script/link_syso_issue33139.txt b/src/cmd/go/testdata/script/link_syso_issue33139.txt new file mode 100644 index 0000000000000..7031860134114 --- /dev/null +++ b/src/cmd/go/testdata/script/link_syso_issue33139.txt @@ -0,0 +1,47 @@ +# Test that we can link a syso file that is embedded in a package, that is +# referenced by an assembly stub. See issue 33139. +# +# We use cgo only to enforce external linkage of the main executable. +[!cgo] stop +[!gc] stop +[linux] cc -c -o syso/test.syso syso/asm/test_linux.s +[darwin] cc -c -o syso/test.syso syso/asm/test_darwin.s +go build ./cmd/main.go + +-- syso/test.s -- +#include "textflag.h" + +TEXT ·Test(SB), NOSPLIT, $0 + JMP asmTest(SB) + +-- syso/test.go -- +package syso + +func Test() + +-- syso/asm/test_linux.s -- + .globl asmTest +asmTest: + ret + +-- syso/asm/test_darwin.s -- + .globl _asmTest +_asmTest: + ret + +-- cmd/main.go -- +package main + +/* + // Force use of external linker + #include + */ +import "C" + +import ( + "syso" +) + +func main() { + syso.Test() +} diff --git a/src/cmd/link/internal/ld/lib.go b/src/cmd/link/internal/ld/lib.go index 9c71a4f51eb4d..2f158e1c0b1b5 100644 --- a/src/cmd/link/internal/ld/lib.go +++ b/src/cmd/link/internal/ld/lib.go @@ -918,12 +918,13 @@ func loadobjfile(ctxt *Link, lib *sym.Library) { } type Hostobj struct { - ld func(*Link, *bio.Reader, string, int64, string) - pkg string - pn string - file string - off int64 - length int64 + ld func(*Link, *bio.Reader, string, int64, string) + pkg string + pn string + file string + off int64 + length int64 + internal bool } var hostobj []Hostobj @@ -972,14 +973,23 @@ func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), headType obja h.file = file h.off = f.Offset() h.length = length + h.internal = isinternal return h } func hostobjs(ctxt *Link) { + // load all hostobj + hostobjsExternalOnly(ctxt, false) +} + +func hostobjsExternalOnly(ctxt *Link, sel bool) { var h *Hostobj for i := 0; i < len(hostobj); i++ { h = &hostobj[i] + if sel && h.internal { + continue + } f, err := bio.Open(h.file) if err != nil { Exitf("cannot reopen %s: %v", h.pn, err) @@ -1002,6 +1012,10 @@ func hostlinksetup(ctxt *Link) { debug_s = *FlagS *FlagS = false + // load non-internal host objects, populating the symbol table so that + // reloc can work + hostobjsExternalOnly(ctxt, true) + // create temporary directory and arrange cleanup if *flagTmpdir == "" { dir, err := ioutil.TempDir("", "go-link-")