Skip to content

Commit

Permalink
cmd/link: load symbols from .syso in external link mode
Browse files Browse the repository at this point in the history
Fix linking with a package having a .syso file in external link mode,
that would otherwise cause an error before executing the external
linker because it can't find symbols that are exported in the said
.syso file.

Fixes #33139
  • Loading branch information
jpap committed Jul 17, 2019
1 parent a6a7b14 commit 128ec32
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 6 deletions.
47 changes: 47 additions & 0 deletions src/cmd/go/testdata/script/link_syso_issue33139.txt
Original file line number Diff line number Diff line change
@@ -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 <stdio.h>
*/
import "C"

import (
"syso"
)

func main() {
syso.Test()
}
26 changes: 20 additions & 6 deletions src/cmd/link/internal/ld/lib.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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-")
Expand Down

0 comments on commit 128ec32

Please sign in to comment.