Skip to content

Commit 128ec32

Browse files
committed
cmd/link: load symbols from .syso in external link mode
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
1 parent a6a7b14 commit 128ec32

File tree

2 files changed

+67
-6
lines changed

2 files changed

+67
-6
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
# Test that we can link a syso file that is embedded in a package, that is
2+
# referenced by an assembly stub. See issue 33139.
3+
#
4+
# We use cgo only to enforce external linkage of the main executable.
5+
[!cgo] stop
6+
[!gc] stop
7+
[linux] cc -c -o syso/test.syso syso/asm/test_linux.s
8+
[darwin] cc -c -o syso/test.syso syso/asm/test_darwin.s
9+
go build ./cmd/main.go
10+
11+
-- syso/test.s --
12+
#include "textflag.h"
13+
14+
TEXT ·Test(SB), NOSPLIT, $0
15+
JMP asmTest(SB)
16+
17+
-- syso/test.go --
18+
package syso
19+
20+
func Test()
21+
22+
-- syso/asm/test_linux.s --
23+
.globl asmTest
24+
asmTest:
25+
ret
26+
27+
-- syso/asm/test_darwin.s --
28+
.globl _asmTest
29+
_asmTest:
30+
ret
31+
32+
-- cmd/main.go --
33+
package main
34+
35+
/*
36+
// Force use of external linker
37+
#include <stdio.h>
38+
*/
39+
import "C"
40+
41+
import (
42+
"syso"
43+
)
44+
45+
func main() {
46+
syso.Test()
47+
}

src/cmd/link/internal/ld/lib.go

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -918,12 +918,13 @@ func loadobjfile(ctxt *Link, lib *sym.Library) {
918918
}
919919

920920
type Hostobj struct {
921-
ld func(*Link, *bio.Reader, string, int64, string)
922-
pkg string
923-
pn string
924-
file string
925-
off int64
926-
length int64
921+
ld func(*Link, *bio.Reader, string, int64, string)
922+
pkg string
923+
pn string
924+
file string
925+
off int64
926+
length int64
927+
internal bool
927928
}
928929

929930
var hostobj []Hostobj
@@ -972,14 +973,23 @@ func ldhostobj(ld func(*Link, *bio.Reader, string, int64, string), headType obja
972973
h.file = file
973974
h.off = f.Offset()
974975
h.length = length
976+
h.internal = isinternal
975977
return h
976978
}
977979

978980
func hostobjs(ctxt *Link) {
981+
// load all hostobj
982+
hostobjsExternalOnly(ctxt, false)
983+
}
984+
985+
func hostobjsExternalOnly(ctxt *Link, sel bool) {
979986
var h *Hostobj
980987

981988
for i := 0; i < len(hostobj); i++ {
982989
h = &hostobj[i]
990+
if sel && h.internal {
991+
continue
992+
}
983993
f, err := bio.Open(h.file)
984994
if err != nil {
985995
Exitf("cannot reopen %s: %v", h.pn, err)
@@ -1002,6 +1012,10 @@ func hostlinksetup(ctxt *Link) {
10021012
debug_s = *FlagS
10031013
*FlagS = false
10041014

1015+
// load non-internal host objects, populating the symbol table so that
1016+
// reloc can work
1017+
hostobjsExternalOnly(ctxt, true)
1018+
10051019
// create temporary directory and arrange cleanup
10061020
if *flagTmpdir == "" {
10071021
dir, err := ioutil.TempDir("", "go-link-")

0 commit comments

Comments
 (0)